SXXXXXXX_RadarDataReader/radar_data_reader/gui/rec_config_window.py
2025-06-24 13:41:26 +02:00

251 lines
9.5 KiB
Python

# 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