# radar_data_reader/gui/rec_config_window.py """ GUI Window for editing the configuration for the g_reconvert.exe runner. """ import tkinter as tk from tkinter import ttk, filedialog from typing import Dict, Any import os class RecConfigWindow(tk.Toplevel): """A Toplevel window for managing g_reconvert.exe parameters.""" def __init__(self, master, controller, current_config: Dict[str, Any]): super().__init__(master) self.controller = controller self.config_data = current_config.copy() self._init_window() self._init_vars() self._populate_vars_from_config() self._create_widgets() self.protocol("WM_DELETE_WINDOW", self._on_cancel) def _init_window(self): self.title("g_reconverter Advanced Configuration") self.geometry("800x650") # Increased height slightly self.transient(self.master) self.grab_set() def _init_vars(self): """Initializes all Tkinter variables for the parameters.""" self.vars = { "cpp_executable_path": tk.StringVar(), "analyze_only": tk.BooleanVar(), "no_sign": tk.BooleanVar(), "use_fw_header": tk.BooleanVar(), "fix_dsp_bug": tk.BooleanVar(), "sync_signal_flows": tk.BooleanVar(), "extract_sw_only": tk.BooleanVar(), "extract_dsp_only": tk.BooleanVar(), "stop_on_discontinuity": tk.BooleanVar(), "dry_run": tk.BooleanVar(), "start_from_stby": tk.BooleanVar(), "fix_sata_date": tk.BooleanVar(), "examine_data": tk.BooleanVar(), "post_process": tk.BooleanVar(), "post_process_level": tk.StringVar(), "output_format": tk.StringVar(), "json_config_file": tk.StringVar(), "max_batches": tk.StringVar(), "pri_number": tk.StringVar(), "rbin_number": tk.StringVar(), "video_out_to_rec": tk.BooleanVar(), "video_show": tk.BooleanVar(), "video_save": tk.BooleanVar(), "video_fix_framerate": tk.BooleanVar(), "gps_save_track": tk.BooleanVar(), "fix_hr_debug": tk.BooleanVar(), "sar_save_only": tk.BooleanVar(), "video_add_subtitles": tk.BooleanVar(), "verbose": tk.BooleanVar(), "debug_messages": tk.BooleanVar(), "quiet": tk.BooleanVar(), "mask_warnings": tk.BooleanVar(), "mask_errors": tk.BooleanVar(), "silent_overwrite": tk.BooleanVar(), } def _populate_vars_from_config(self): for key, var in self.vars.items(): if key in self.config_data: var.set(self.config_data[key]) def _create_widgets(self): main_frame = ttk.Frame(self, padding="10") main_frame.pack(fill=tk.BOTH, expand=True) # --- Executable Path Frame --- exe_frame = ttk.LabelFrame(main_frame, text="Executable Path") exe_frame.pack(fill=tk.X, pady=(0, 10)) exe_frame.columnconfigure(0, weight=1) exe_entry = ttk.Entry(exe_frame, textvariable=self.vars["cpp_executable_path"]) exe_entry.grid(row=0, column=0, sticky="ew", padx=5, pady=5) browse_button = ttk.Button(exe_frame, text="Browse...", command=self._select_executable_path) browse_button.grid(row=0, column=1, padx=5, pady=5) # --- Notebook for other parameters --- notebook = ttk.Notebook(main_frame) notebook.pack(fill=tk.BOTH, expand=True, pady=5) processing_tab = ttk.Frame(notebook, padding="10") advanced_tab = ttk.Frame(notebook, padding="10") video_tab = ttk.Frame(notebook, padding="10") debug_tab = ttk.Frame(notebook, padding="10") notebook.add(processing_tab, text="Processing") notebook.add(advanced_tab, text="Advanced") notebook.add(video_tab, text="Video") notebook.add(debug_tab, text="Debug/Control") self._setup_processing_widgets(processing_tab) self._setup_advanced_widgets(advanced_tab) self._setup_video_widgets(video_tab) self._setup_debug_control_widgets(debug_tab) button_frame = ttk.Frame(main_frame) button_frame.pack(fill=tk.X, pady=(10, 0)) ttk.Button(button_frame, text="Save & Close", command=self._on_save).pack(side=tk.RIGHT, padx=5) ttk.Button(button_frame, text="Cancel", command=self._on_cancel).pack(side=tk.RIGHT) def _select_executable_path(self): """Opens a file dialog to select the g_reconvert.exe executable.""" filetypes = [("Executable", "*.exe"), ("All files", "*.*")] if os.name == 'nt' else [("All files", "*")] filepath = filedialog.askopenfilename( title="Select g_reconvert Executable", filetypes=filetypes ) if filepath: self.vars["cpp_executable_path"].set(filepath) def _on_save(self): new_config = {key: var.get() for key, var in self.vars.items()} self.controller.save_rec_config(new_config) self.destroy() def _on_cancel(self): self.destroy() def _setup_processing_widgets(self, parent): parent.columnconfigure((0, 1, 2), weight=1) flags = [ ("analyze_only", "Analyze Only (/a)"), ("no_sign", "Don't Save Signal (/nosign)"), ("use_fw_header", "Use FW Header (/hfw)"), ("fix_dsp_bug", "Fix DSP Geopos Bug (/$pbug)"), ("sync_signal_flows", "Sync Signal Flows (/h)"), ("extract_sw_only", "Extract Only SW Data (/sw)"), ("extract_dsp_only", "Extract Only DSP Data (/dsp)"), ("stop_on_discontinuity", "Stop on Discontinuity (/ss)"), ("dry_run", "Dry Run (/dryrun)"), ("start_from_stby", "Start Save from STBY (/z)"), ("fix_sata_date", "Fix SATA File Date (/d)"), ("examine_data", "Examine Some Data (/x)") ] row, col = 0, 0 for key, text in flags: ttk.Checkbutton(parent, text=text, variable=self.vars[key]).grid(row=row, column=col, sticky="w", padx=5, pady=2) row += 1 if row > 4: row, col = 0, col + 1 pp_frame = ttk.Frame(parent) pp_frame.grid(row=row, column=col, sticky='w', columnspan=2, pady=2) ttk.Checkbutton(pp_frame, text="Post Process History (/p)", variable=self.vars["post_process"]).pack(side=tk.LEFT) ttk.Label(pp_frame, text="Level:").pack(side=tk.LEFT, padx=(10, 2)) ttk.Entry(pp_frame, textvariable=self.vars["post_process_level"], width=5).pack(side=tk.LEFT) def _setup_advanced_widgets(self, parent): parent.columnconfigure(1, weight=1) ttk.Label(parent, text="JSON Config File (/j):").grid(row=0, column=0, sticky="w", padx=5, pady=5) ttk.Entry(parent, textvariable=self.vars["json_config_file"]).grid(row=0, column=1, sticky="ew", padx=5) ttk.Label(parent, text="Max Batches (/m):").grid(row=1, column=0, sticky="w", padx=5, pady=5) ttk.Entry(parent, textvariable=self.vars["max_batches"], width=10).grid(row=1, column=1, sticky="w", padx=5) ttk.Label(parent, text="PRI Number (/r):").grid(row=2, column=0, sticky="w", padx=5, pady=5) ttk.Entry(parent, textvariable=self.vars["pri_number"], width=10).grid(row=2, column=1, sticky="w", padx=5) ttk.Label(parent, text="RBIN Number (/c):").grid(row=3, column=0, sticky="w", padx=5, pady=5) ttk.Entry(parent, textvariable=self.vars["rbin_number"], width=10).grid(row=3, column=1, sticky="w", padx=5) def _setup_video_widgets(self, parent): parent.columnconfigure((0, 1), weight=1) flags = [ ("video_out_to_rec", "Output to Rec Results (/vout)"), ("video_show", "Show Video (/vshow)"), ("video_save", "Save Video (/vsave)"), ("video_fix_framerate", "Fix Frame Rate (/vframe)"), ("gps_save_track", "GPS: Save Track (/gps)"), ("fix_hr_debug", "HR: Fix Debug Data (/fixhr)"), ("sar_save_only", "SAR: Save Only SAR (/sar)"), ("video_add_subtitles", "Add AVI Subtitles (/vst)") ] row, col = 0, 0 for key, text in flags: ttk.Checkbutton(parent, text=text, variable=self.vars[key]).grid(row=row, column=col, sticky="w", padx=5, pady=2) row += 1 if row > 4: row, col = 0, col + 1 def _setup_debug_control_widgets(self, parent): parent.columnconfigure((0, 1), weight=1) flags = [ ("verbose", "Verbose Output (//v)"), ("debug_messages", "Debug Messages (//d)"), ("quiet", "Quiet Mode (//q)"), ("mask_warnings", "Mask Warnings (//w)"), ("mask_errors", "Mask Errors (//e)"), ("silent_overwrite", "Silently Overwrite Output (//o)") ] row, col = 0, 0 for key, text in flags: ttk.Checkbutton(parent, text=text, variable=self.vars[key]).grid(row=row, column=col, sticky="w", padx=5, pady=2) row += 1 if row > 3: row, col = 0, col + 1