SXXXXXXX_PyUCC/pyucc/gui/progress_handlers.py

140 lines
4.6 KiB
Python

"""
Progress handlers for PyUCC GUI.
Handles progress callbacks with batch processing to avoid GUI blocking.
"""
from pathlib import Path
class ProgressHandlers:
"""Handles progress callbacks for all analysis types with batch processing."""
BATCH_SIZE = 50 # Insert items in batches of 50 to reduce GUI blocking
UPDATE_FREQUENCY = 10 # Update progress UI every N files
def __init__(self, gui_app):
"""
Args:
gui_app: Reference to the main GUI application instance
"""
self.app = gui_app
self._count_batch_buffer = []
self._metrics_batch_buffer = []
def on_count_progress(self, res):
"""Handle progress for countings analysis.
Args:
res: Dictionary with file counting results
"""
try:
if not isinstance(res, dict):
return
file = res.get("file")
name = Path(file).name if file else ""
code = res.get("code_lines") or res.get("code") or 0
comment = res.get("comment_lines") or 0
blank = res.get("blank_lines") or 0
total = res.get("physical_lines") or 0
lang = res.get("language") or ""
# Add to batch buffer
self._count_batch_buffer.append(
(name, file, int(code), int(comment), int(blank), int(total), lang)
)
# Insert batch when buffer is full
if len(self._count_batch_buffer) >= self.BATCH_SIZE:
self._flush_count_batch()
# Update progress less frequently
self._update_progress_counter()
except Exception:
pass
def on_count_done(self, results):
"""Handle completion of countings analysis."""
# Flush remaining batch buffer
self._flush_count_batch()
self.app._current_task_id = None
try:
self.app._set_phase("Idle")
except Exception:
pass
self.app._enable_action_buttons()
def on_metrics_progress(self, res):
"""Handle progress for metrics analysis.
Args:
res: Dictionary with file metrics results
"""
try:
if not isinstance(res, dict):
return
file = res.get("file")
name = Path(file).name if file else ""
avg = res.get("avg_cc") or res.get("avg") or 0
maxcc = res.get("max_cc") or 0
func = res.get("func_count") or 0
mi = res.get("mi") or 0
lang = res.get("language") or ""
# Add to batch buffer
self._metrics_batch_buffer.append((name, file, avg, maxcc, func, mi, lang))
# Insert batch when buffer is full
if len(self._metrics_batch_buffer) >= self.BATCH_SIZE:
self._flush_metrics_batch()
# Update progress
self._update_progress_counter()
except Exception:
pass
def on_metrics_done(self, results):
"""Handle completion of metrics analysis."""
# Flush remaining batch buffer
self._flush_metrics_batch()
self.app._current_task_id = None
try:
self.app._set_phase("Idle")
except Exception:
pass
self.app._enable_action_buttons()
def _flush_count_batch(self):
"""Flush countings batch buffer to results tree."""
if self._count_batch_buffer:
for row_values in self._count_batch_buffer:
self.app.results_tree.insert("", "end", values=row_values)
self._count_batch_buffer.clear()
def _flush_metrics_batch(self):
"""Flush metrics batch buffer to results tree."""
if self._metrics_batch_buffer:
for row_values in self._metrics_batch_buffer:
self.app.results_tree.insert("", "end", values=row_values)
self._metrics_batch_buffer.clear()
def _update_progress_counter(self):
"""Update progress counter and UI (with reduced frequency)."""
try:
self.app._processed_files = getattr(self.app, "_processed_files", 0) + 1
# Update UI only every N files or at completion
if (
self.app._processed_files % self.UPDATE_FREQUENCY == 0
or self.app._processed_files == self.app._total_files
):
self.app._lbl_files.config(
text=f"Files: {self.app._processed_files}/{self.app._total_files}"
)
self.app.progress["value"] = self.app._processed_files
except Exception:
pass