sistemati alcuni messaggi
This commit is contained in:
parent
5fa6477dca
commit
99253d02a1
@ -30,11 +30,13 @@ class ActionHandlers:
|
|||||||
self.app._set_phase("Scanning...")
|
self.app._set_phase("Scanning...")
|
||||||
self.app._current_mode = 'scan'
|
self.app._current_mode = 'scan'
|
||||||
|
|
||||||
|
# Disable action buttons during operation
|
||||||
|
self.app._disable_action_buttons()
|
||||||
|
|
||||||
# Reset UI
|
# Reset UI
|
||||||
self._reset_progress_ui()
|
self._reset_progress_ui()
|
||||||
self.app._set_results_columns(("name", "path"))
|
self.app._set_results_columns(("name", "path"))
|
||||||
self._clear_results()
|
self._clear_results()
|
||||||
self.app.export_btn.config(state='disabled')
|
|
||||||
self.app.update_idletasks()
|
self.app.update_idletasks()
|
||||||
|
|
||||||
# Get paths and filters
|
# Get paths and filters
|
||||||
@ -74,11 +76,13 @@ class ActionHandlers:
|
|||||||
self.app._set_phase("Counting...")
|
self.app._set_phase("Counting...")
|
||||||
self.app._current_mode = 'countings'
|
self.app._current_mode = 'countings'
|
||||||
|
|
||||||
|
# Disable action buttons during operation
|
||||||
|
self.app._disable_action_buttons()
|
||||||
|
|
||||||
# Reset UI
|
# Reset UI
|
||||||
self._reset_progress_ui()
|
self._reset_progress_ui()
|
||||||
self.app._set_results_columns(("name", "path", "code", "comment", "blank", "total", "language"))
|
self.app._set_results_columns(("name", "path", "code", "comment", "blank", "total", "language"))
|
||||||
self._clear_results()
|
self._clear_results()
|
||||||
self.app.export_btn.config(state='disabled')
|
|
||||||
self.app.update_idletasks()
|
self.app.update_idletasks()
|
||||||
|
|
||||||
paths, allowed_exts, ignore_patterns, pr = self.app._resolve_profile_and_filters()
|
paths, allowed_exts, ignore_patterns, pr = self.app._resolve_profile_and_filters()
|
||||||
@ -94,8 +98,8 @@ class ActionHandlers:
|
|||||||
files = results or []
|
files = results or []
|
||||||
if not files:
|
if not files:
|
||||||
messagebox.showinfo("Countings", "No files found to analyze.")
|
messagebox.showinfo("Countings", "No files found to analyze.")
|
||||||
self.app.cancel_btn.config(state='disabled')
|
|
||||||
self.app._set_phase('Idle')
|
self.app._set_phase('Idle')
|
||||||
|
self.app._enable_action_buttons()
|
||||||
return
|
return
|
||||||
|
|
||||||
from ..core.countings_impl import analyze_file_counts
|
from ..core.countings_impl import analyze_file_counts
|
||||||
@ -131,11 +135,13 @@ class ActionHandlers:
|
|||||||
self.app._set_phase("Computing metrics...")
|
self.app._set_phase("Computing metrics...")
|
||||||
self.app._current_mode = 'metrics'
|
self.app._current_mode = 'metrics'
|
||||||
|
|
||||||
|
# Disable action buttons during operation
|
||||||
|
self.app._disable_action_buttons()
|
||||||
|
|
||||||
# Reset UI
|
# Reset UI
|
||||||
self._reset_progress_ui()
|
self._reset_progress_ui()
|
||||||
self.app._set_results_columns(("name", "path", "avg_cc", "max_cc", "func_count", "mi", "language"))
|
self.app._set_results_columns(("name", "path", "avg_cc", "max_cc", "func_count", "mi", "language"))
|
||||||
self._clear_results()
|
self._clear_results()
|
||||||
self.app.export_btn.config(state='disabled')
|
|
||||||
self.app.update_idletasks()
|
self.app.update_idletasks()
|
||||||
|
|
||||||
paths, allowed_exts, ignore_patterns, pr = self.app._resolve_profile_and_filters()
|
paths, allowed_exts, ignore_patterns, pr = self.app._resolve_profile_and_filters()
|
||||||
@ -151,8 +157,8 @@ class ActionHandlers:
|
|||||||
files = results or []
|
files = results or []
|
||||||
if not files:
|
if not files:
|
||||||
messagebox.showinfo("Metrics", "No files found to analyze.")
|
messagebox.showinfo("Metrics", "No files found to analyze.")
|
||||||
self.app.cancel_btn.config(state='disabled')
|
|
||||||
self.app._set_phase('Idle')
|
self.app._set_phase('Idle')
|
||||||
|
self.app._enable_action_buttons()
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -160,6 +166,7 @@ class ActionHandlers:
|
|||||||
except Exception:
|
except Exception:
|
||||||
messagebox.showerror("Metrics", "Metrics analyzer not available")
|
messagebox.showerror("Metrics", "Metrics analyzer not available")
|
||||||
self.app._set_phase('Idle')
|
self.app._set_phase('Idle')
|
||||||
|
self.app._enable_action_buttons()
|
||||||
return
|
return
|
||||||
|
|
||||||
self.app._total_files = len(files)
|
self.app._total_files = len(files)
|
||||||
@ -194,7 +201,9 @@ class ActionHandlers:
|
|||||||
self.app._set_results_columns(("fileA", "fileB", "added", "deleted", "modified", "unmodified", "Δ code_lines", "Δ comment_lines", "Δ blank_lines", "Δ func_count", "Δ avg_cc", "Δ mi"))
|
self.app._set_results_columns(("fileA", "fileB", "added", "deleted", "modified", "unmodified", "Δ code_lines", "Δ comment_lines", "Δ blank_lines", "Δ func_count", "Δ avg_cc", "Δ mi"))
|
||||||
self._clear_results()
|
self._clear_results()
|
||||||
self.app._current_mode = 'differ'
|
self.app._current_mode = 'differ'
|
||||||
self.app.export_btn.config(state='disabled')
|
|
||||||
|
# Disable action buttons during operation
|
||||||
|
self.app._disable_action_buttons()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.app._lbl_files.config(text="Files: 0/0")
|
self.app._lbl_files.config(text="Files: 0/0")
|
||||||
@ -215,22 +224,35 @@ class ActionHandlers:
|
|||||||
self.app.update_idletasks()
|
self.app.update_idletasks()
|
||||||
|
|
||||||
bm = BaselineManager(project)
|
bm = BaselineManager(project)
|
||||||
baselines = bm.list_baselines()
|
all_baselines = bm.list_baselines()
|
||||||
|
|
||||||
profile_name = pr.get('name') if pr else None
|
profile_name = pr.get('name') if pr else None
|
||||||
max_keep = app_settings.get_max_keep()
|
max_keep = app_settings.get_max_keep()
|
||||||
|
|
||||||
|
# Filter baselines by current profile
|
||||||
|
baselines = []
|
||||||
|
for baseline_id in all_baselines:
|
||||||
|
try:
|
||||||
|
meta = bm.load_metadata(baseline_id)
|
||||||
|
baseline_profile = meta.profile if hasattr(meta, 'profile') else None
|
||||||
|
# Match baselines with same profile (or both None)
|
||||||
|
if baseline_profile == profile_name:
|
||||||
|
baselines.append(baseline_id)
|
||||||
|
except Exception:
|
||||||
|
# Skip baselines that can't be loaded
|
||||||
|
pass
|
||||||
|
|
||||||
# Callback handlers
|
# Callback handlers
|
||||||
def _on_create_done(baseline_id):
|
def _on_create_done(baseline_id):
|
||||||
try:
|
try:
|
||||||
self.app._set_phase('Idle')
|
self.app._set_phase('Idle')
|
||||||
self.app._current_task_id = None
|
self.app._current_task_id = None
|
||||||
self.app.cancel_btn.config(state='disabled')
|
self.app._enable_action_buttons()
|
||||||
messagebox.showinfo("Differing", f"Baseline created: {baseline_id}")
|
messagebox.showinfo("Differing", f"Baseline created: {baseline_id}")
|
||||||
except Exception:
|
except Exception:
|
||||||
self.app._set_phase('Idle')
|
self.app._set_phase('Idle')
|
||||||
self.app._current_task_id = None
|
self.app._current_task_id = None
|
||||||
self.app.cancel_btn.config(state='disabled')
|
self.app._enable_action_buttons()
|
||||||
|
|
||||||
def _on_diff_done(result):
|
def _on_diff_done(result):
|
||||||
try:
|
try:
|
||||||
@ -250,16 +272,18 @@ class ActionHandlers:
|
|||||||
self.app.cancel_btn.config(state='normal')
|
self.app.cancel_btn.config(state='normal')
|
||||||
except Exception:
|
except Exception:
|
||||||
self.app._set_phase('Idle')
|
self.app._set_phase('Idle')
|
||||||
self.app.cancel_btn.config(state='disabled')
|
|
||||||
self.app._current_task_id = None
|
self.app._current_task_id = None
|
||||||
|
self.app._enable_action_buttons()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
messagebox.showerror('Differ Error', str(e))
|
messagebox.showerror('Differ Error', str(e))
|
||||||
|
self.app._enable_action_buttons()
|
||||||
|
|
||||||
# No baseline exists - create one
|
# No baseline exists - create one
|
||||||
if not baselines:
|
if not baselines:
|
||||||
create = messagebox.askyesno("Differing", "No baseline found for this project. Create baseline now?")
|
create = messagebox.askyesno("Differing", "No baseline found for this project. Create baseline now?")
|
||||||
if not create:
|
if not create:
|
||||||
self.app._set_phase('Idle')
|
self.app._set_phase('Idle')
|
||||||
|
self.app._enable_action_buttons()
|
||||||
return
|
return
|
||||||
|
|
||||||
self.app._set_phase("Creating baseline...")
|
self.app._set_phase("Creating baseline...")
|
||||||
@ -277,6 +301,7 @@ class ActionHandlers:
|
|||||||
chosen = self._select_baseline_dialog(baselines)
|
chosen = self._select_baseline_dialog(baselines)
|
||||||
if not chosen:
|
if not chosen:
|
||||||
self.app._set_phase('Idle')
|
self.app._set_phase('Idle')
|
||||||
|
self.app._enable_action_buttons()
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -285,6 +310,7 @@ class ActionHandlers:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
messagebox.showerror("Differing", f"Failed to load baseline metadata: {e}")
|
messagebox.showerror("Differing", f"Failed to load baseline metadata: {e}")
|
||||||
self.app._set_phase('Idle')
|
self.app._set_phase('Idle')
|
||||||
|
self.app._enable_action_buttons()
|
||||||
return
|
return
|
||||||
|
|
||||||
# Setup baseline and current roots for diff viewer
|
# Setup baseline and current roots for diff viewer
|
||||||
@ -301,6 +327,7 @@ class ActionHandlers:
|
|||||||
except Exception:
|
except Exception:
|
||||||
messagebox.showerror('Differing', 'Failed to scan current project files')
|
messagebox.showerror('Differing', 'Failed to scan current project files')
|
||||||
self.app._set_phase('Idle')
|
self.app._set_phase('Idle')
|
||||||
|
self.app._enable_action_buttons()
|
||||||
return
|
return
|
||||||
|
|
||||||
self.app._set_phase("Building pairs...")
|
self.app._set_phase("Building pairs...")
|
||||||
@ -311,11 +338,13 @@ class ActionHandlers:
|
|||||||
except Exception:
|
except Exception:
|
||||||
messagebox.showerror('Differing', 'Failed to build file pairs')
|
messagebox.showerror('Differing', 'Failed to build file pairs')
|
||||||
self.app._set_phase('Idle')
|
self.app._set_phase('Idle')
|
||||||
|
self.app._enable_action_buttons()
|
||||||
return
|
return
|
||||||
|
|
||||||
if not pairs:
|
if not pairs:
|
||||||
messagebox.showinfo("Differing", "No files to compare")
|
messagebox.showinfo("Differing", "No files to compare")
|
||||||
self.app._set_phase('Idle')
|
self.app._set_phase('Idle')
|
||||||
|
self.app._enable_action_buttons()
|
||||||
return
|
return
|
||||||
|
|
||||||
# Process pairs in parallel
|
# Process pairs in parallel
|
||||||
|
|||||||
@ -166,6 +166,9 @@ class App(tk.Tk):
|
|||||||
# Worker manager (background task runner)
|
# Worker manager (background task runner)
|
||||||
self.worker = WorkerManager()
|
self.worker = WorkerManager()
|
||||||
|
|
||||||
|
# Track task names for logging
|
||||||
|
self._task_names = {}
|
||||||
|
|
||||||
# Initialize handlers (refactored to separate modules)
|
# Initialize handlers (refactored to separate modules)
|
||||||
self.action_handlers = ActionHandlers(self)
|
self.action_handlers = ActionHandlers(self)
|
||||||
self.progress_handlers = ProgressHandlers(self)
|
self.progress_handlers = ProgressHandlers(self)
|
||||||
@ -182,6 +185,34 @@ class App(tk.Tk):
|
|||||||
# poll the worker UI queue and dispatch callbacks in the main thread (50ms for better responsiveness)
|
# poll the worker UI queue and dispatch callbacks in the main thread (50ms for better responsiveness)
|
||||||
self.after(50, self._poll_worker_ui_queue)
|
self.after(50, self._poll_worker_ui_queue)
|
||||||
|
|
||||||
|
def _disable_action_buttons(self):
|
||||||
|
"""Disable all action buttons except Cancel when an operation is running."""
|
||||||
|
try:
|
||||||
|
self.scan_btn.config(state='disabled')
|
||||||
|
self.count_btn.config(state='disabled')
|
||||||
|
self.metrics_btn.config(state='disabled')
|
||||||
|
self.differ_btn.config(state='disabled')
|
||||||
|
self.export_btn.config(state='disabled')
|
||||||
|
self.cancel_btn.config(state='normal')
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _enable_action_buttons(self):
|
||||||
|
"""Re-enable all action buttons when operation is complete."""
|
||||||
|
try:
|
||||||
|
self.scan_btn.config(state='normal')
|
||||||
|
self.count_btn.config(state='normal')
|
||||||
|
self.metrics_btn.config(state='normal')
|
||||||
|
self.differ_btn.config(state='normal')
|
||||||
|
# Export button state depends on whether we have results
|
||||||
|
if self.results_tree.get_children():
|
||||||
|
self.export_btn.config(state='normal')
|
||||||
|
else:
|
||||||
|
self.export_btn.config(state='disabled')
|
||||||
|
self.cancel_btn.config(state='disabled')
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
def _set_results_columns(self, cols):
|
def _set_results_columns(self, cols):
|
||||||
"""Reconfigure the shared results tree to use given columns.
|
"""Reconfigure the shared results tree to use given columns.
|
||||||
Cols is an iterable of (col_id, ...) where col_id are string keys.
|
Cols is an iterable of (col_id, ...) where col_id are string keys.
|
||||||
@ -290,12 +321,8 @@ class App(tk.Tk):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
self._current_task_id = None
|
self._current_task_id = None
|
||||||
# reset phase to idle when finished
|
self._set_phase("Idle")
|
||||||
try:
|
self._enable_action_buttons()
|
||||||
self._set_phase("Idle")
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
self.cancel_btn.config(state='disabled')
|
|
||||||
|
|
||||||
def _on_action_export(self):
|
def _on_action_export(self):
|
||||||
"""Delegate export action to ExportHandler."""
|
"""Delegate export action to ExportHandler."""
|
||||||
@ -352,14 +379,13 @@ class App(tk.Tk):
|
|||||||
self.results_tree.insert('', 'end', values=(f.name, str(f)))
|
self.results_tree.insert('', 'end', values=(f.name, str(f)))
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
self.export_btn.config(state='normal' if files else 'disabled')
|
|
||||||
self.cancel_btn.config(state='disabled')
|
|
||||||
self._current_task_id = None
|
self._current_task_id = None
|
||||||
self._set_phase("Idle")
|
self._set_phase("Idle")
|
||||||
|
self._enable_action_buttons()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
messagebox.showerror('Scan Error', str(e))
|
messagebox.showerror('Scan Error', str(e))
|
||||||
self.cancel_btn.config(state='disabled')
|
|
||||||
self._set_phase("Idle")
|
self._set_phase("Idle")
|
||||||
|
self._enable_action_buttons()
|
||||||
|
|
||||||
def _on_count_progress(self, res):
|
def _on_count_progress(self, res):
|
||||||
"""Delegate count progress to ProgressHandlers."""
|
"""Delegate count progress to ProgressHandlers."""
|
||||||
@ -400,6 +426,8 @@ class App(tk.Tk):
|
|||||||
typ, task_id, payload = msg
|
typ, task_id, payload = msg
|
||||||
if typ == "started":
|
if typ == "started":
|
||||||
name = payload.get("func") if isinstance(payload, dict) else str(payload)
|
name = payload.get("func") if isinstance(payload, dict) else str(payload)
|
||||||
|
# Store task name for later use
|
||||||
|
self._task_names[task_id] = name
|
||||||
self.log(f"Task {task_id[:8]} started: {name}", level="INFO")
|
self.log(f"Task {task_id[:8]} started: {name}", level="INFO")
|
||||||
elif typ == "progress":
|
elif typ == "progress":
|
||||||
# payload is expected to be a partial result or status dictionary
|
# payload is expected to be a partial result or status dictionary
|
||||||
@ -407,13 +435,22 @@ class App(tk.Tk):
|
|||||||
# so we skip logging them to avoid clutter
|
# so we skip logging them to avoid clutter
|
||||||
pass # Skip progress logging
|
pass # Skip progress logging
|
||||||
elif typ == "done":
|
elif typ == "done":
|
||||||
# payload may contain final results
|
# Retrieve task name from stored mapping
|
||||||
self.log(f"Task {task_id[:8]} done. Result: {payload}", level="INFO")
|
name = self._task_names.get(task_id, "unknown")
|
||||||
|
self.log(f"Task {task_id[:8]} {name} done.", level="INFO")
|
||||||
|
# Clean up task name from memory
|
||||||
|
self._task_names.pop(task_id, None)
|
||||||
elif typ == "error":
|
elif typ == "error":
|
||||||
# payload is typically a traceback string or exception info
|
# payload is typically a traceback string or exception info
|
||||||
self.log(f"Task {task_id[:8]} error: {payload}", level="ERROR")
|
name = self._task_names.get(task_id, "unknown")
|
||||||
|
self.log(f"Task {task_id[:8]} {name} error: {payload}", level="ERROR")
|
||||||
|
# Clean up task name from memory
|
||||||
|
self._task_names.pop(task_id, None)
|
||||||
elif typ == "cancelled":
|
elif typ == "cancelled":
|
||||||
self.log(f"Task {task_id[:8]} cancelled", level="WARNING")
|
name = self._task_names.get(task_id, "unknown")
|
||||||
|
self.log(f"Task {task_id[:8]} {name} cancelled", level="WARNING")
|
||||||
|
# Clean up task name from memory
|
||||||
|
self._task_names.pop(task_id, None)
|
||||||
|
|
||||||
def on_closing(self):
|
def on_closing(self):
|
||||||
"""Cleanup when closing the application."""
|
"""Cleanup when closing the application."""
|
||||||
|
|||||||
@ -55,13 +55,12 @@ class ProgressHandlers:
|
|||||||
# Flush remaining batch buffer
|
# Flush remaining batch buffer
|
||||||
self._flush_count_batch()
|
self._flush_count_batch()
|
||||||
|
|
||||||
self.app.export_btn.config(state='normal')
|
|
||||||
self.app.cancel_btn.config(state='disabled')
|
|
||||||
self.app._current_task_id = None
|
self.app._current_task_id = None
|
||||||
try:
|
try:
|
||||||
self.app._set_phase("Idle")
|
self.app._set_phase("Idle")
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
self.app._enable_action_buttons()
|
||||||
|
|
||||||
def on_metrics_progress(self, res):
|
def on_metrics_progress(self, res):
|
||||||
"""Handle progress for metrics analysis.
|
"""Handle progress for metrics analysis.
|
||||||
@ -98,13 +97,12 @@ class ProgressHandlers:
|
|||||||
# Flush remaining batch buffer
|
# Flush remaining batch buffer
|
||||||
self._flush_metrics_batch()
|
self._flush_metrics_batch()
|
||||||
|
|
||||||
self.app.export_btn.config(state='normal')
|
|
||||||
self.app.cancel_btn.config(state='disabled')
|
|
||||||
self.app._current_task_id = None
|
self.app._current_task_id = None
|
||||||
try:
|
try:
|
||||||
self.app._set_phase("Idle")
|
self.app._set_phase("Idle")
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
self.app._enable_action_buttons()
|
||||||
|
|
||||||
def _flush_count_batch(self):
|
def _flush_count_batch(self):
|
||||||
"""Flush countings batch buffer to results tree."""
|
"""Flush countings batch buffer to results tree."""
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user