From 28b30afb871597d7b0c718a1e360a227a1a40693 Mon Sep 17 00:00:00 2001 From: VALLONGOL Date: Wed, 6 Aug 2025 16:00:21 +0200 Subject: [PATCH] unified progress bar --- radar_data_reader/gui/main_window.py | 206 ++++++++---------- .../gui/segment_processor_tab.py | 84 +++---- 2 files changed, 114 insertions(+), 176 deletions(-) diff --git a/radar_data_reader/gui/main_window.py b/radar_data_reader/gui/main_window.py index 4091841..96432e0 100644 --- a/radar_data_reader/gui/main_window.py +++ b/radar_data_reader/gui/main_window.py @@ -48,7 +48,7 @@ class MainWindow(tk.Frame): self.master.title( f"Radar Data Reader & Processor - {WRAPPER_APP_VERSION_STRING}" ) - self.master.geometry("1280x1024") + self.master.geometry("1280x800") self._create_widgets() self._setup_gui_logging(logging_config) @@ -60,6 +60,7 @@ class MainWindow(tk.Frame): """Initialize all Tkinter variables.""" self.status_bar_var = tk.StringVar(value="Ready") + # --- Variabili per "Single OUT Processor" --- self.out_filepath_var = tk.StringVar() self.out_output_dir_var = tk.StringVar() self.out_basename_var = tk.StringVar() @@ -69,41 +70,36 @@ class MainWindow(tk.Frame): self.out_use_full_path_var = tk.BooleanVar(value=False) self.out_csv_profile_var = tk.StringVar() self.out_json_profile_var = tk.StringVar() - + self.out_analysis_only_var = tk.BooleanVar(value=False) + + # --- Variabili per "REC Converter" --- self.rec_filepath_var = tk.StringVar() self.rec_file_count_var = tk.IntVar(value=1) self.rec_output_dir_var = tk.StringVar() self.rec_basename_var = tk.StringVar() - self.progress_text_var = tk.StringVar(value="N/A") - self.batches_found_var = tk.StringVar(value="N/A") - self.progress_bar_var = tk.DoubleVar(value=0) - + # --- Variabili per "Flight Analyzer" --- self.analyzer_rec_folder_var = tk.StringVar() self.analyzer_flight_name_var = tk.StringVar() self.analyzer_workspace_dir_var = tk.StringVar() - self.analyzer_info_var = tk.StringVar( - value="Please select a folder and a flight name." - ) - self.analyzer_progress_var = tk.DoubleVar(value=0) - self.analyzer_progress_text_var = tk.StringVar(value="N/A") - + self.analyzer_info_var = tk.StringVar(value="Please select a folder and a flight name.") self.aggregate_by_scale_var = tk.BooleanVar(value=True) self.aggregate_by_waveform_var = tk.BooleanVar(value=True) - self.out_analysis_only_var = tk.BooleanVar(value=False) - + # --- MODIFICA: Variabili per la barra di progresso GLOBALE --- + self.global_progress_text_var = tk.StringVar(value="N/A") + self.global_progress_bar_var = tk.DoubleVar(value=0) + self.global_batches_found_var = tk.StringVar(value="N/A") + def _on_analysis_only_toggle(self): is_analysis_only = self.out_analysis_only_var.get() state = tk.DISABLED if is_analysis_only else tk.NORMAL - # Disables standard output options when analysis only is selected self.out_csv_check.config(state=state) self.out_json_check.config(state=state) self.out_csv_profile_combobox.config(state=state) self.out_json_profile_combobox.config(state=state) - # Re-enables comboboxes only if their corresponding checkbox was already active if not is_analysis_only: if self.out_output_csv_var.get(): self.out_csv_profile_combobox.config(state="readonly") @@ -125,11 +121,20 @@ class MainWindow(tk.Frame): main_frame = tk.Frame(self) main_frame.pack(padx=10, pady=10, fill=tk.BOTH, expand=True) main_frame.columnconfigure(0, weight=1) - main_frame.rowconfigure(1, weight=1) + # --- MODIFICA: Aggiunta una riga per la progress bar globale --- + main_frame.rowconfigure(2, weight=1) self.notebook = ttk.Notebook(main_frame) self.notebook.grid(row=0, column=0, sticky="nsew", pady=(0, 10)) + # --- MODIFICA: Creazione e posizionamento del frame di progresso globale --- + global_progress_frame = self._create_global_progress_frame(main_frame) + global_progress_frame.grid(row=1, column=0, sticky="ew", pady=5) + + # --- MODIFICA: Posizionamento della console di log nella riga corretta --- + self._create_log_console_frame(main_frame).grid(row=2, column=0, sticky="nsew", pady=(5, 0)) + + # Creazione dei tab self.flight_analyzer_tab = ttk.Frame(self.notebook, padding="10") self.segment_processor_tab = SegmentProcessorTab(self.notebook, self.controller) self.out_processor_tab = ttk.Frame(self.notebook, padding="10") @@ -140,12 +145,11 @@ class MainWindow(tk.Frame): self.notebook.add(self.out_processor_tab, text="3. Single OUT Processor") self.notebook.add(self.rec_converter_tab, text="4. REC to OUT Converter") + # Popolamento dei tab (ora senza le loro barre di progresso) self._create_flight_analyzer_tab(self.flight_analyzer_tab) self._create_out_processor_tab(self.out_processor_tab) self._create_rec_converter_tab(self.rec_converter_tab) - - self._create_log_console_frame(main_frame) - + self.status_bar = ttk.Label( self, textvariable=self.status_bar_var, @@ -155,9 +159,36 @@ class MainWindow(tk.Frame): ) self.status_bar.pack(side=tk.BOTTOM, fill=tk.X) + def _create_global_progress_frame(self, parent): + """Crea il pannello di stato e progresso globale.""" + frame = ttk.LabelFrame(parent, text="Global Process Status") + frame.columnconfigure(1, weight=1) + + self.global_progress_bar = ttk.Progressbar( + frame, variable=self.global_progress_bar_var, maximum=100 + ) + self.global_progress_bar.grid( + row=0, column=0, columnspan=3, sticky="ew", padx=5, pady=(5, 2) + ) + + ttk.Label(frame, text="Status:", anchor="e").grid( + row=1, column=0, padx=(10, 5), pady=2, sticky="w" + ) + ttk.Label(frame, textvariable=self.global_progress_text_var, anchor="w").grid( + row=1, column=1, padx=5, pady=2, sticky="ew" + ) + + batches_frame = ttk.Frame(frame) + batches_frame.grid(row=1, column=2, sticky='e', padx=10) + ttk.Label(batches_frame, text="Batches Found:", anchor="e").pack(side=tk.LEFT) + ttk.Label(batches_frame, textvariable=self.global_batches_found_var, anchor="w").pack(side=tk.LEFT, padx=(5,0)) + + return frame + def _create_flight_analyzer_tab(self, parent): parent.columnconfigure(0, weight=1) - parent.rowconfigure(5, weight=1) + # --- MODIFICA: Ora la row 4 è quella dei risultati, non più 5 --- + parent.rowconfigure(4, weight=1) # --- Frame 1: Flight Source --- setup_frame = ttk.LabelFrame(parent, text="Flight Source") @@ -172,11 +203,9 @@ class MainWindow(tk.Frame): workspace_frame = ttk.LabelFrame(parent, text="Flight Workspace (Analysis Output)") workspace_frame.grid(row=1, column=0, sticky="ew", padx=5, pady=5) workspace_frame.columnconfigure(1, weight=1) - ttk.Label(workspace_frame, text="Workspace Path:").grid(row=0, column=0, padx=5, pady=5, sticky="w") workspace_entry = ttk.Entry(workspace_frame, textvariable=self.analyzer_workspace_dir_var) workspace_entry.grid(row=0, column=1, sticky="ew", padx=5) - dir_buttons_frame = ttk.Frame(workspace_frame) dir_buttons_frame.grid(row=0, column=2, padx=5) ttk.Button( @@ -187,22 +216,18 @@ class MainWindow(tk.Frame): dir_buttons_frame, text="Open...", command=lambda: self.controller.open_folder_from_path(self.analyzer_workspace_dir_var.get()) ).pack(side=tk.LEFT, padx=(5, 0)) - ttk.Label(workspace_frame, text="Flight Name:").grid(row=1, column=0, padx=5, pady=5, sticky="w") flight_name_entry = ttk.Entry(workspace_frame, textvariable=self.analyzer_flight_name_var) flight_name_entry.grid(row=1, column=1, columnspan=2, sticky="ew", padx=5) - # --- Frame 3: Segment Definition --- aggregation_frame = ttk.LabelFrame(parent, text="Segment Definition Options") aggregation_frame.grid(row=2, column=0, sticky="ew", padx=5, pady=5) - ttk.Checkbutton( aggregation_frame, text="Create new segment on Scale change", variable=self.aggregate_by_scale_var ).pack(side=tk.LEFT, padx=10, pady=5) - ttk.Checkbutton( aggregation_frame, text="Create new segment on Waveform (WF) change", @@ -219,26 +244,19 @@ class MainWindow(tk.Frame): info_label = ttk.Label(action_frame, textvariable=self.analyzer_info_var) info_label.pack(side=tk.LEFT, padx=20) - # --- Frame 5: Progress --- - progress_frame = ttk.Frame(parent) - progress_frame.grid(row=4, column=0, sticky="ew", padx=5, pady=5) - progress_frame.columnconfigure(1, weight=1) - ttk.Label(progress_frame, text="Analysis Progress:").grid(row=0, column=0, sticky="w") - self.analyzer_progressbar = ttk.Progressbar(progress_frame, variable=self.analyzer_progress_var) - self.analyzer_progressbar.grid(row=0, column=1, sticky="ew", padx=5) - ttk.Label(progress_frame, textvariable=self.analyzer_progress_text_var).grid(row=0, column=2, sticky="w") + # --- RIMOZIONE: Frame di progresso locale rimosso --- - # --- Frame 6: Results --- + # --- Frame 5 (ex 6): Results --- results_frame = ttk.LabelFrame(parent, text="Flight Summary & Segments") - results_frame.grid(row=5, column=0, sticky="nsew", padx=5, pady=5) + results_frame.grid(row=4, column=0, sticky="nsew", padx=5, pady=5) # Row index aggiornato results_frame.columnconfigure(0, weight=1) results_frame.rowconfigure(0, weight=1) - self.flight_timeline_tree = ttk.Treeview( results_frame, columns=("status", "start_batch", "end_batch", "batch_count", "duration", "start_file", "end_file", "file_count"), show="headings", selectmode="extended" ) + # ... (configurazione treeview rimane invariata) ... self.flight_timeline_tree.heading("status", text="Segment (Mode | Scale | WF)") self.flight_timeline_tree.heading("start_batch", text="Start Batch") self.flight_timeline_tree.heading("end_batch", text="End Batch") @@ -259,7 +277,6 @@ class MainWindow(tk.Frame): tree_scrollbar = ttk.Scrollbar(results_frame, orient="vertical", command=self.flight_timeline_tree.yview) self.flight_timeline_tree.configure(yscrollcommand=tree_scrollbar.set) tree_scrollbar.grid(row=0, column=1, sticky="ns") - buttons_frame = ttk.Frame(results_frame) buttons_frame.grid(row=1, column=0, columnspan=2, sticky="ew", pady=5) ttk.Button(buttons_frame, text="Select All", command=self._select_all_segments).pack(side=tk.LEFT, padx=(0, 5)) @@ -281,6 +298,7 @@ class MainWindow(tk.Frame): def _create_out_processor_tab(self, parent): parent.columnconfigure(1, weight=1) + # ... (Input Frame, Output Frame, Formats & Options Frame rimangono invariati) ... # --- Input Frame --- input_frame = ttk.LabelFrame(parent, text="Input .out File") input_frame.grid(row=0, column=0, columnspan=3, sticky="ew", padx=5, pady=5) @@ -332,7 +350,6 @@ class MainWindow(tk.Frame): formats_frame = ttk.LabelFrame(parent, text="Output Formats & Options") formats_frame.grid(row=2, column=0, columnspan=3, sticky="ew", padx=5, pady=5) formats_frame.columnconfigure(1, weight=1) - analysis_check = ttk.Checkbutton( formats_frame, text="Generate Structure Analysis Report Only", @@ -340,10 +357,8 @@ class MainWindow(tk.Frame): command=self._on_analysis_only_toggle ) analysis_check.grid(row=0, column=0, columnspan=3, sticky="w", padx=5, pady=(5, 10)) - separator = ttk.Separator(formats_frame, orient='horizontal') separator.grid(row=1, column=0, columnspan=3, sticky='ew', padx=5, pady=5) - self.out_csv_check = ttk.Checkbutton( formats_frame, text="Generate .csv file", variable=self.out_output_csv_var ) @@ -355,7 +370,6 @@ class MainWindow(tk.Frame): width=25, ) self.out_csv_profile_combobox.grid(row=2, column=1, sticky="w", padx=5) - self.out_json_check = ttk.Checkbutton( formats_frame, text="Generate .json file", variable=self.out_output_json_var ) @@ -367,7 +381,6 @@ class MainWindow(tk.Frame): width=25, ) self.out_json_profile_combobox.grid(row=3, column=1, sticky="w", padx=5) - options_subframe = ttk.Frame(formats_frame) options_subframe.grid(row=2, column=2, rowspan=2, sticky="w", padx=(20, 5)) ttk.Checkbutton( @@ -380,7 +393,7 @@ class MainWindow(tk.Frame): text="Use Full Path for Headers", variable=self.out_use_full_path_var, ).pack(anchor="w") - + # --- Action & Live Data Frames --- action_frame = ttk.Frame(parent) action_frame.grid(row=3, column=0, columnspan=3, pady=(10, 0)) @@ -397,11 +410,11 @@ class MainWindow(tk.Frame): state=tk.DISABLED, ) self.out_stop_button.pack(side=tk.LEFT, padx=5) - self._create_live_data_frame(parent).grid( - row=4, column=0, columnspan=3, sticky="ew", padx=5, pady=(10, 0) - ) + + # --- RIMOZIONE: Frame di progresso locale rimosso --- def _create_rec_converter_tab(self, parent): + # ... (Questo tab non aveva una barra di progresso, quindi rimane invariato) ... parent.columnconfigure(1, weight=1) input_frame = ttk.LabelFrame(parent, text="Input REC Sequence") input_frame.grid(row=0, column=0, columnspan=3, sticky="ew", padx=5, pady=5) @@ -483,34 +496,8 @@ class MainWindow(tk.Frame): ) self.process_generated_out_button.pack(side=tk.LEFT, padx=5) - def _create_live_data_frame(self, parent): - status_frame = ttk.LabelFrame( - parent, text="Live Data & Progress (.out Processor)" - ) - status_frame.columnconfigure(1, weight=1) - self.progress_bar = ttk.Progressbar( - status_frame, variable=self.progress_bar_var, maximum=100 - ) - self.progress_bar.grid( - row=0, column=0, columnspan=2, sticky="ew", padx=5, pady=(5, 2) - ) - ttk.Label(status_frame, text="Progress:", anchor="e").grid( - row=1, column=0, padx=(10, 5), pady=2, sticky="e" - ) - ttk.Label(status_frame, textvariable=self.progress_text_var, anchor="w").grid( - row=1, column=1, padx=5, pady=2, sticky="w" - ) - ttk.Label(status_frame, text="Batches Found:", anchor="e").grid( - row=2, column=0, padx=(10, 5), pady=2, sticky="e" - ) - ttk.Label(status_frame, textvariable=self.batches_found_var, anchor="w").grid( - row=2, column=1, padx=5, pady=2, sticky="w" - ) - return status_frame - def _create_log_console_frame(self, parent): log_frame = ttk.LabelFrame(parent, text="Log Console") - log_frame.grid(row=1, column=0, sticky="nsew", pady=(5, 0)) log_frame.rowconfigure(0, weight=1) log_frame.columnconfigure(0, weight=1) self.log_widget = scrolledtext.ScrolledText( @@ -523,6 +510,7 @@ class MainWindow(tk.Frame): self.log_widget.tag_config("WARNING", foreground="orange") self.log_widget.tag_config("DEBUG", foreground="gray") self.log_widget.tag_config("CMD", foreground="blue") + return log_frame def _setup_gui_logging(self, logging_config): logger.add_tkinter_handler(self.log_widget, self.master, logging_config) @@ -548,15 +536,11 @@ class MainWindow(tk.Frame): ) def _reset_progress(self): - self.analyzer_progress_var.set(0) - self.analyzer_progress_text_var.set("N/A") - self.progress_bar_var.set(0) - self.progress_text_var.set("N/A") - self.batches_found_var.set("N/A") + # --- MODIFICA: Resetta solo le variabili globali --- + self.global_progress_bar_var.set(0) + self.global_progress_text_var.set("N/A") + self.global_batches_found_var.set("N/A") self.segments_done_count = 0 - if hasattr(self, "segment_processor_tab"): - self.segment_processor_tab.progress_var.set(0) - self.segment_processor_tab.progress_text_var.set("N/A") def start_processing_ui(self): self.update_ui_for_processing_state(True) @@ -623,6 +607,7 @@ class MainWindow(tk.Frame): msg_type = msg.get("type") if msg_type == "log": + # ... (gestione log C++) ... level_str = msg.get("level", "INFO").upper() level_map = { "ERROR": logging.ERROR, "WARNING": logging.WARNING, @@ -630,31 +615,28 @@ class MainWindow(tk.Frame): } log_level = level_map.get(level_str, logging.INFO) log.log(log_level, f"[C++ Runner] {msg.get('message')}") - + elif msg_type == "export_log": log.info(f"[C++ Export] {msg.get('message')}") elif msg_type == "start": self.total_blocks_for_progress = msg.get("total", 0) - self.progress_bar_var.set(0) - self.progress_text_var.set("Starting...") + self.global_progress_bar_var.set(0) + self.global_progress_text_var.set("Starting...") elif msg_type == "data_batch_fragment": blocks_done = msg.get("blocks_done", 0) if self.total_blocks_for_progress > 0: progress_percent = (blocks_done / self.total_blocks_for_progress) * 100 - self.progress_bar_var.set(progress_percent) - - self.progress_text_var.set(f"{blocks_done} / {self.total_blocks_for_progress} blocks") + self.global_progress_bar_var.set(progress_percent) + self.global_progress_text_var.set(f"Processing .out file... ({blocks_done} / {self.total_blocks_for_progress} blocks)") self.controller.handle_data_batch_fragment(msg.get("data")) + self.global_batches_found_var.set(f"{self.controller.total_batches_found_count}") - self.batches_found_var.set(f"{self.controller.total_batches_found_count}") - - # --- NUOVA CONDIZIONE PER GESTIRE IL REPORT DI ANALISI --- elif msg_type == "analysis_report": - self.progress_bar_var.set(100) - self.progress_text_var.set("Analysis complete. Saving report...") + self.global_progress_bar_var.set(100) + self.global_progress_text_var.set("Analysis complete. Saving report...") self.controller.handle_analysis_report(msg) elif msg_type == "file_progress": @@ -662,9 +644,9 @@ class MainWindow(tk.Frame): total_files = self.controller.total_files_for_analysis if total_files > 0: progress = (file_num / total_files) * 100 - self.analyzer_progress_var.set(progress) - self.analyzer_progress_text_var.set( - f"Analyzing file {file_num} / {total_files}" + self.global_progress_bar_var.set(progress) + self.global_progress_text_var.set( + f"Analyzing flight file {file_num} / {total_files}" ) elif msg_type == "segment_progress": @@ -672,36 +654,31 @@ class MainWindow(tk.Frame): total_segs = self.controller.total_segments_for_export if total_segs > 0: progress = (self.segments_done_count / total_segs) * 100 - self.analyzer_progress_var.set(progress) - self.analyzer_progress_text_var.set( - f"Exported {self.segments_done_count} / {total_segs}" + self.global_progress_bar_var.set(progress) + self.global_progress_text_var.set( + f"Exporting segment {self.segments_done_count} / {total_segs}" ) elif msg_type == "batch_progress": current, total = msg.get("current", 0), msg.get("total", 0) if total > 0: progress = (current / total) * 100 - self.segment_processor_tab.progress_var.set(progress) - self.segment_processor_tab.progress_text_var.set( - f"Processing segment {current} of {total}: {msg.get('segment_name', '')}" + self.global_progress_bar_var.set(progress) + self.global_progress_text_var.set( + f"Batch processing segment {current} of {total}: {msg.get('segment_name', '')}" ) elif msg_type == "cpp_complete": + self.global_progress_text_var.set("C++ analysis finished. Parsing results...") self.controller.handle_final_analysis_steps() elif msg_type == "analysis_summary_data": self.controller.handle_analysis_summary_data(msg) elif msg_type in ("success", "complete", "error"): - # Gestione generica di fine processo per i flussi standard - if msg.get("type") != "analysis_report": - self.progress_bar_var.set(100) - self.analyzer_progress_var.set(100) - self.analyzer_progress_text_var.set("Done") - if hasattr(self, "segment_processor_tab"): - self.segment_processor_tab.progress_var.set(100) - self.segment_processor_tab.progress_text_var.set("Finished.") - self.controller.handle_worker_completion(msg) + self.global_progress_bar_var.set(100) + self.global_progress_text_var.set("Finished.") + self.controller.handle_worker_completion(msg) except queue.Empty: pass @@ -713,13 +690,6 @@ class MainWindow(tk.Frame): ) if self.controller.is_processing: - # Per la modalità analisi, diamo un feedback visivo generico - if self.out_analysis_only_var.get(): - current_progress = self.progress_bar_var.get() - if current_progress < 95: # Evita di andare al 100% prima della fine - self.progress_bar_var.set(current_progress + 1) - self.progress_text_var.set("Analyzing structure...") - self.after(100, self.poll_result_queue) def populate_timeline_from_dataframe(self, summary_df: "pd.DataFrame"): diff --git a/radar_data_reader/gui/segment_processor_tab.py b/radar_data_reader/gui/segment_processor_tab.py index 236d958..535b183 100644 --- a/radar_data_reader/gui/segment_processor_tab.py +++ b/radar_data_reader/gui/segment_processor_tab.py @@ -31,9 +31,6 @@ class SegmentProcessorTab(ttk.Frame): self.create_separate_folders_var = tk.BooleanVar(value=True) self.csv_use_tab_var = tk.BooleanVar(value=False) self.use_full_path_var = tk.BooleanVar(value=False) - - self.progress_var = tk.DoubleVar(value=0) - self.progress_text_var = tk.StringVar(value="N/A") self.flight_analysis_dir_var = tk.StringVar() self._create_widgets() @@ -41,6 +38,7 @@ class SegmentProcessorTab(ttk.Frame): def _create_widgets(self): """Creates and lays out all widgets for the tab.""" self.columnconfigure(0, weight=1) + # --- MODIFICA: La row 3 è ora l'ultima, la 2 è il treeview --- self.rowconfigure(2, weight=1) source_frame = ttk.LabelFrame(self, text="Flight Analysis Source Directory") @@ -76,17 +74,12 @@ class SegmentProcessorTab(ttk.Frame): self.segments_tree = ttk.Treeview( segments_frame, columns=( - "status", - "name", - "start_batch", - "end_batch", - "duration", - "start_file", - "end_file", + "status", "name", "start_batch", "end_batch", "duration", + "start_file", "end_file", ), - show="headings", - selectmode="extended", + show="headings", selectmode="extended", ) + # ... (configurazione treeview rimane invariata) ... self.segments_tree.heading("status", text="Status") self.segments_tree.heading("name", text="Segment Name") self.segments_tree.heading("start_batch", text="Start Batch") @@ -102,34 +95,26 @@ class SegmentProcessorTab(ttk.Frame): self.segments_tree.column("duration", width=100, anchor="center") self.segments_tree.column("start_file", width=200, stretch=True) self.segments_tree.column("end_file", width=200, stretch=True) - self.segments_tree.grid(row=0, column=0, sticky="nsew") - scrollbar = ttk.Scrollbar( segments_frame, orient="vertical", command=self.segments_tree.yview ) self.segments_tree.configure(yscrollcommand=scrollbar.set) scrollbar.grid(row=0, column=1, sticky="ns") - self.segments_tree.tag_configure("ready", foreground="green") self.segments_tree.tag_configure("not_exported", foreground="gray") - selection_frame = ttk.Frame(segments_frame) selection_frame.grid(row=1, column=0, columnspan=2, sticky="ew", pady=(5, 0)) - ttk.Button( selection_frame, text="Select All Ready", command=self._select_all_ready ).pack(side=tk.LEFT) ttk.Button(selection_frame, text="Select None", command=self._select_none).pack( side=tk.LEFT, padx=5 ) - help_label = ttk.Label( segments_frame, text="Tip: Segments in gray are not exported and cannot be selected. Use the 'Flight Analyzer' tab to export them.", - wraplength=600, - justify=tk.LEFT, - style="Italic.TLabel", + wraplength=600, justify=tk.LEFT, style="Italic.TLabel", ) help_label.grid(row=2, column=0, columnspan=2, sticky="w", padx=5, pady=5) self.master.style = ttk.Style() @@ -141,36 +126,32 @@ class SegmentProcessorTab(ttk.Frame): output_config_frame.grid(row=3, column=0, sticky="ew", pady=10) output_config_frame.columnconfigure(1, weight=1) + # --- Riga per la directory di output --- ttk.Label(output_config_frame, text="Output Directory:").grid( row=0, column=0, padx=5, pady=5, sticky="w" ) dir_entry = ttk.Entry(output_config_frame, textvariable=self.output_dir_var) dir_entry.grid(row=0, column=1, sticky="ew", padx=5) - dir_buttons_frame = ttk.Frame(output_config_frame) dir_buttons_frame.grid(row=0, column=2, padx=5) ttk.Button( - dir_buttons_frame, - text="Browse...", + dir_buttons_frame, text="Browse...", command=lambda: self.controller.select_output_dir(self.output_dir_var), ).pack(side=tk.LEFT) ttk.Button( - dir_buttons_frame, - text="Open...", + dir_buttons_frame, text="Open...", command=lambda: self.controller.open_folder_from_path( self.output_dir_var.get() ), ).pack(side=tk.LEFT, padx=(5, 0)) + # --- Riga per i formati e i profili --- formats_frame = ttk.Frame(output_config_frame) formats_frame.grid(row=1, column=0, columnspan=3, sticky="ew", padx=10, pady=5) formats_frame.columnconfigure(2, weight=1) - self.csv_check = ttk.Checkbutton( - formats_frame, - text="Generate .csv file", - variable=self.generate_csv_var, - command=self._on_format_toggle, + formats_frame, text="Generate .csv file", + variable=self.generate_csv_var, command=self._on_format_toggle, ) self.csv_check.grid(row=0, column=0, sticky="w") ttk.Label(formats_frame, text="CSV Profile:").grid( @@ -180,26 +161,22 @@ class SegmentProcessorTab(ttk.Frame): formats_frame, textvariable=self.csv_profile_var, state="readonly", width=25 ) self.csv_profile_combobox.grid(row=0, column=2, sticky="ew") - self.json_check = ttk.Checkbutton( - formats_frame, - text="Generate .json file", - variable=self.generate_json_var, - command=self._on_format_toggle, + formats_frame, text="Generate .json file", + variable=self.generate_json_var, command=self._on_format_toggle, ) self.json_check.grid(row=1, column=0, sticky="w") ttk.Label(formats_frame, text="JSON Profile:").grid( row=1, column=1, sticky="e", padx=(10, 2) ) self.json_profile_combobox = ttk.Combobox( - formats_frame, - textvariable=self.json_profile_var, - state="readonly", - width=25, + formats_frame, textvariable=self.json_profile_var, + state="readonly", width=25, ) self.json_profile_combobox.grid(row=1, column=2, sticky="ew") self._on_format_toggle() + # --- Riga per le altre opzioni --- other_options_frame = ttk.Frame(output_config_frame) other_options_frame.grid( row=2, column=0, columnspan=3, sticky="w", padx=10, pady=5 @@ -219,28 +196,19 @@ class SegmentProcessorTab(ttk.Frame): text="Use Full Path for Headers", variable=self.use_full_path_var, ).pack(side=tk.LEFT, anchor="w", padx=(20, 0)) - - progress_frame = ttk.LabelFrame(self, text="Processing Progress") - progress_frame.grid(row=4, column=0, sticky="ew", pady=(10, 0)) - progress_frame.columnconfigure(1, weight=1) - - self.progress_bar = ttk.Progressbar(progress_frame, variable=self.progress_var) - self.progress_bar.grid( - row=0, column=0, columnspan=2, sticky="ew", padx=10, pady=5 - ) - - self.progress_label = ttk.Label( - progress_frame, textvariable=self.progress_text_var - ) - self.progress_label.grid(row=1, column=0, sticky="w", padx=10, pady=(0, 5)) - + + # --- Riga per il bottone di avvio --- + process_button_frame = ttk.Frame(output_config_frame) + process_button_frame.grid(row=3, column=0, columnspan=3, sticky='e', pady=10, padx=5) self.process_button = ttk.Button( - progress_frame, + process_button_frame, text="Process Selected Segments", command=self.controller.start_segment_batch_processing, state=tk.DISABLED, ) - self.process_button.grid(row=1, column=1, sticky="e", padx=10, pady=(0, 5)) + self.process_button.pack() + + # --- RIMOZIONE: Frame di progresso rimosso --- def _on_format_toggle(self): self.csv_profile_combobox.config( @@ -309,4 +277,4 @@ class SegmentProcessorTab(ttk.Frame): elif profile_names: var.set(profile_names[0]) else: - var.set("") + var.set("") \ No newline at end of file