modify log system qith queue, add async command, change status bar function with color
This commit is contained in:
parent
788334d969
commit
daaf409be9
168
GitUtility.py
168
GitUtility.py
@ -1834,122 +1834,198 @@ class GitSvnSyncApp:
|
|||||||
def _check_completion_queue(self, results_queue, context):
|
def _check_completion_queue(self, results_queue, context):
|
||||||
"""Checks result queue, updates GUI (incl. status bar color)."""
|
"""Checks result queue, updates GUI (incl. status bar color)."""
|
||||||
task_context = context.get('context', 'unknown')
|
task_context = context.get('context', 'unknown')
|
||||||
# log_handler.log_debug(f"Checking completion queue for context: {task_context}", func_name="_check_completion_queue") # Mantenuto commentato per ora
|
# log_handler.log_debug(f"Checking completion queue for context: {task_context}", func_name="_check_completion_queue") # Mantenuto commentato
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# Tenta di ottenere un risultato dalla coda senza bloccare
|
||||||
result_data = results_queue.get_nowait()
|
result_data = results_queue.get_nowait()
|
||||||
log_handler.log_info(f"Result received for '{task_context}'. Status: {result_data.get('status')}", func_name="_check_completion_queue")
|
log_handler.log_info(f"Result received for '{task_context}'. Status: {result_data.get('status')}", func_name="_check_completion_queue")
|
||||||
|
|
||||||
# --- 1. Re-enable GUI Widgets ---
|
# --- 1. Re-enable GUI Widgets ---
|
||||||
|
# Riabilita i widget principali prima di processare il risultato
|
||||||
log_handler.log_debug("Re-enabling widgets.", func_name="_check_completion_queue")
|
log_handler.log_debug("Re-enabling widgets.", func_name="_check_completion_queue")
|
||||||
self.main_frame.set_action_widgets_state(tk.NORMAL)
|
if hasattr(self, "main_frame") and self.main_frame.winfo_exists():
|
||||||
|
self.main_frame.set_action_widgets_state(tk.NORMAL)
|
||||||
|
else:
|
||||||
|
log_handler.log_warning("Cannot re-enable widgets, MainFrame missing.", func_name="_check_completion_queue")
|
||||||
|
# Potrebbe essere necessario uscire qui se la GUI non c'è più
|
||||||
|
return
|
||||||
|
|
||||||
# --- 2. Extract Details ---
|
# --- 2. Extract Details ---
|
||||||
|
# Estrae i dati dal dizionario del risultato, con fallback sicuri
|
||||||
status = result_data.get('status')
|
status = result_data.get('status')
|
||||||
message = result_data.get('message')
|
message = result_data.get('message')
|
||||||
result = result_data.get('result')
|
result = result_data.get('result')
|
||||||
exception = result_data.get('exception')
|
exception = result_data.get('exception')
|
||||||
committed = result_data.get('committed', False)
|
committed = result_data.get('committed', False) # Flag per operazioni che potrebbero committare
|
||||||
is_conflict = result_data.get('conflict', False)
|
is_conflict = result_data.get('conflict', False) # Flag specifico per conflitti merge
|
||||||
repo_path_conflict = result_data.get('repo_path')
|
repo_path_conflict = result_data.get('repo_path') # Percorso repo in caso di conflitto
|
||||||
new_branch_context = context.get('new_branch_name')
|
new_branch_context = context.get('new_branch_name') # Info dal contesto originale se si crea un branch
|
||||||
|
|
||||||
# --- 3. Update Status Bar (con colore e reset temporizzato) ---
|
# --- 3. Update Status Bar (con colore e reset temporizzato) ---
|
||||||
# (Logica status bar invariata)
|
# Imposta colore e durata del messaggio nella status bar in base allo stato
|
||||||
status_color = None
|
status_color = None
|
||||||
reset_duration = 5000 # Resetta colore dopo 5 secondi
|
reset_duration = 5000 # Default reset 5 secondi
|
||||||
if status == 'success':
|
if status == 'success':
|
||||||
status_color = self.main_frame.STATUS_GREEN
|
status_color = self.main_frame.STATUS_GREEN
|
||||||
elif status == 'warning':
|
elif status == 'warning':
|
||||||
status_color = self.main_frame.STATUS_YELLOW
|
status_color = self.main_frame.STATUS_YELLOW
|
||||||
reset_duration = 7000
|
reset_duration = 7000 # Warning dura un po' di più
|
||||||
elif status == 'error':
|
elif status == 'error':
|
||||||
status_color = self.main_frame.STATUS_RED
|
status_color = self.main_frame.STATUS_RED
|
||||||
reset_duration = 10000
|
reset_duration = 10000 # Errore dura di più
|
||||||
|
|
||||||
|
# Aggiorna la status bar tramite la funzione helper in MainFrame
|
||||||
self.main_frame.update_status_bar(message, bg_color=status_color, duration_ms=reset_duration)
|
self.main_frame.update_status_bar(message, bg_color=status_color, duration_ms=reset_duration)
|
||||||
|
|
||||||
|
|
||||||
# --- 4. Process Result & Trigger Updates ---
|
# --- 4. Process Result & Trigger Updates ---
|
||||||
|
# Ottieni il percorso corrente del repo per eventuali refresh necessari
|
||||||
repo_path_for_updates = self._get_and_validate_svn_path("Post-Action Update")
|
repo_path_for_updates = self._get_and_validate_svn_path("Post-Action Update")
|
||||||
|
|
||||||
|
# Gestione basata sullo stato del risultato ('success', 'warning', 'error')
|
||||||
if status == 'success':
|
if status == 'success':
|
||||||
refresh_list = []
|
refresh_list = [] # Lista di funzioni di refresh da chiamare dopo
|
||||||
# (Logica per popolare refresh_list invariata)
|
|
||||||
|
# --- Logica per determinare quali refresh avviare ---
|
||||||
|
# Se l'operazione ha modificato lo stato del repo (commit, fetch, prepare, checkout, ecc.)
|
||||||
if task_context in ['prepare_repo', 'fetch_bundle', 'commit', 'create_tag', 'checkout_tag', 'create_branch', 'checkout_branch', '_handle_gitignore_save_async', 'add_file']:
|
if task_context in ['prepare_repo', 'fetch_bundle', 'commit', 'create_tag', 'checkout_tag', 'create_branch', 'checkout_branch', '_handle_gitignore_save_async', 'add_file']:
|
||||||
if committed or task_context in ['fetch_bundle','prepare_repo','create_tag','_handle_gitignore_save_async']: refresh_list.append(self.refresh_commit_history)
|
# Aggiorna la history se c'è stato un commit o se l'operazione lo richiede implicitamente
|
||||||
if task_context != 'refresh_changes': refresh_list.append(self.refresh_changed_files_list)
|
if committed or task_context in ['fetch_bundle','prepare_repo','create_tag','_handle_gitignore_save_async']:
|
||||||
if task_context not in ['refresh_tags','checkout_tag'] or committed: refresh_list.append(self.refresh_tag_list)
|
if self.refresh_commit_history not in refresh_list: refresh_list.append(self.refresh_commit_history)
|
||||||
if task_context != 'refresh_branches': refresh_list.append(self.refresh_branch_list)
|
# Aggiorna sempre la lista dei file modificati tranne se l'azione era proprio il refresh dei file
|
||||||
|
if task_context != 'refresh_changes':
|
||||||
|
if self.refresh_changed_files_list not in refresh_list: refresh_list.append(self.refresh_changed_files_list)
|
||||||
|
# Aggiorna i tag (tranne se si è fatto checkout di un tag o refresh dei tag stessi), o se c'è stato commit
|
||||||
|
if task_context not in ['refresh_tags','checkout_tag'] or committed:
|
||||||
|
if self.refresh_tag_list not in refresh_list: refresh_list.append(self.refresh_tag_list)
|
||||||
|
# Aggiorna i branch (tranne se si è fatto refresh dei branch)
|
||||||
|
if task_context != 'refresh_branches':
|
||||||
|
if self.refresh_branch_list not in refresh_list: refresh_list.append(self.refresh_branch_list)
|
||||||
|
|
||||||
|
|
||||||
# Gestione aggiornamenti diretti post-refresh
|
# --- Gestione aggiornamenti diretti post-operazioni di refresh ---
|
||||||
|
# Se l'azione era un refresh, aggiorna direttamente la GUI con i dati ricevuti
|
||||||
if task_context == 'refresh_tags':
|
if task_context == 'refresh_tags':
|
||||||
self.main_frame.update_tag_list(result if result else [])
|
self.main_frame.update_tag_list(result if isinstance(result, list) else []) # Assicura sia una lista
|
||||||
elif task_context == 'refresh_branches':
|
elif task_context == 'refresh_branches':
|
||||||
branches, current = result if result else ([], None)
|
# Estrai i dati con un fallback sicuro
|
||||||
|
branches, current = result if isinstance(result, tuple) and len(result) == 2 else ([], None)
|
||||||
|
# Log di debug aggiunto qui
|
||||||
|
log_handler.log_debug(
|
||||||
|
f"Preparing to call update_branch_list. Task Context: '{task_context}'. "
|
||||||
|
f"Branches type: {type(branches)}, Count: {len(branches) if isinstance(branches, list) else 'N/A'}. Current: {repr(current)}. "
|
||||||
|
f"Raw result: {repr(result)}",
|
||||||
|
func_name="_check_completion_queue"
|
||||||
|
)
|
||||||
self.main_frame.update_branch_list(branches, current)
|
self.main_frame.update_branch_list(branches, current)
|
||||||
self.main_frame.update_history_branch_filter(branches)
|
# Aggiorna anche il filtro nella tab history
|
||||||
|
self.main_frame.update_history_branch_filter(branches) # Usa solo la lista branches
|
||||||
elif task_context == 'refresh_history':
|
elif task_context == 'refresh_history':
|
||||||
self.main_frame.update_history_display(result if result else [])
|
# Assicura sia una lista
|
||||||
|
log_lines_result = result if isinstance(result, list) else []
|
||||||
|
# Log di debug aggiunto qui
|
||||||
|
log_handler.log_debug(
|
||||||
|
f"Preparing to call update_history_display. Task Context: '{task_context}'. "
|
||||||
|
f"Result type: {type(result)}. Lines count: {len(log_lines_result)}. "
|
||||||
|
f"Raw result sample: {repr(log_lines_result[:5])}", # Usa la variabile già controllata
|
||||||
|
func_name="_check_completion_queue"
|
||||||
|
)
|
||||||
|
self.main_frame.update_history_display(log_lines_result)
|
||||||
elif task_context == 'refresh_changes':
|
elif task_context == 'refresh_changes':
|
||||||
# ---<<< INIZIO MODIFICA DEBUG >>>---
|
# Log di debug aggiunto qui
|
||||||
# Logga esattamente cosa sta per essere passato a update_changed_files_list
|
|
||||||
log_handler.log_debug(
|
log_handler.log_debug(
|
||||||
f"Preparing to call update_changed_files_list. "
|
f"Preparing to call update_changed_files_list. "
|
||||||
f"Task Context: '{task_context}'. Result type: {type(result)}. Result value: {repr(result)}",
|
f"Task Context: '{task_context}'. Result type: {type(result)}. Result value: {repr(result)}",
|
||||||
func_name="_check_completion_queue"
|
func_name="_check_completion_queue"
|
||||||
)
|
)
|
||||||
# ---<<< FINE MODIFICA DEBUG >>>---
|
self.main_frame.update_changed_files_list(result if isinstance(result, list) else []) # Assicura sia lista
|
||||||
self.main_frame.update_changed_files_list(result if result else [])
|
|
||||||
|
|
||||||
# (Altre gestioni di successo invariate: commit, create_branch checkout, etc.)
|
|
||||||
if task_context == 'commit' and committed: self.main_frame.clear_commit_message()
|
# --- Gestione azioni post-successo specifiche ---
|
||||||
|
if task_context == 'commit' and committed:
|
||||||
|
# Pulisce il messaggio di commit solo se è stato fatto un commit effettivo
|
||||||
|
self.main_frame.clear_commit_message()
|
||||||
if task_context == 'create_branch' and new_branch_context:
|
if task_context == 'create_branch' and new_branch_context:
|
||||||
|
# Chiede se fare checkout del nuovo branch creato
|
||||||
if self.main_frame.ask_yes_no("Checkout?", f"Switch to new branch '{new_branch_context}'?"):
|
if self.main_frame.ask_yes_no("Checkout?", f"Switch to new branch '{new_branch_context}'?"):
|
||||||
|
# Avvia un'altra operazione asincrona per il checkout
|
||||||
self.checkout_branch(branch_to_checkout=new_branch_context)
|
self.checkout_branch(branch_to_checkout=new_branch_context)
|
||||||
else: # Refresh history if not checking out
|
else:
|
||||||
|
# Se non fa checkout, assicurati che la history venga aggiornata
|
||||||
if self.refresh_commit_history not in refresh_list: refresh_list.append(self.refresh_commit_history)
|
if self.refresh_commit_history not in refresh_list: refresh_list.append(self.refresh_commit_history)
|
||||||
|
|
||||||
|
|
||||||
# Trigger collected async refreshes
|
# --- Trigger finale dei refresh asincroni raccolti ---
|
||||||
if repo_path_for_updates and refresh_list:
|
if repo_path_for_updates and refresh_list:
|
||||||
log_handler.log_debug(f"Triggering {len(refresh_list)} async refreshes for '{task_context}'", func_name="_check_completion_queue")
|
log_handler.log_debug(f"Triggering {len(refresh_list)} async refreshes for '{task_context}'", func_name="_check_completion_queue")
|
||||||
|
# Avvia ogni funzione di refresh nella lista (sono anch'esse asincrone)
|
||||||
for refresh_func in refresh_list:
|
for refresh_func in refresh_list:
|
||||||
try: refresh_func()
|
try:
|
||||||
except Exception as ref_e: log_handler.log_error(f"Error triggering {refresh_func.__name__}: {ref_e}", func_name="_check_completion_queue")
|
refresh_func()
|
||||||
|
except Exception as ref_e:
|
||||||
|
log_handler.log_error(f"Error triggering {refresh_func.__name__}: {ref_e}", func_name="_check_completion_queue")
|
||||||
elif refresh_list:
|
elif refresh_list:
|
||||||
|
# Se la lista refresh non è vuota ma manca il path, logga un warning
|
||||||
log_handler.log_warning("Cannot trigger UI refreshes: Repo path unavailable.", func_name="_check_completion_queue")
|
log_handler.log_warning("Cannot trigger UI refreshes: Repo path unavailable.", func_name="_check_completion_queue")
|
||||||
|
|
||||||
|
|
||||||
elif status == 'warning':
|
elif status == 'warning':
|
||||||
# (gestione warning invariata)
|
# Gestione dei warning: mostra un popup informativo
|
||||||
self.main_frame.show_warning("Operation Info", message)
|
if hasattr(self, "main_frame"):
|
||||||
if "already prepared" in message: self.refresh_changed_files_list()
|
self.main_frame.show_warning("Operation Info", message)
|
||||||
|
# Caso specifico: repo già preparato
|
||||||
|
if "already prepared" in message:
|
||||||
|
if self.refresh_changed_files_list not in refresh_list: refresh_list.append(self.refresh_changed_files_list)
|
||||||
|
if self.refresh_branch_list not in refresh_list: refresh_list.append(self.refresh_branch_list)
|
||||||
|
# Avvia refresh post warning
|
||||||
|
if repo_path_for_updates and refresh_list:
|
||||||
|
for refresh_func in refresh_list:
|
||||||
|
try: refresh_func()
|
||||||
|
except Exception as ref_e: log_handler.log_error(f"Error triggering refresh after warning: {ref_e}", func_name="_check_completion_queue")
|
||||||
|
|
||||||
|
|
||||||
elif status == 'error':
|
elif status == 'error':
|
||||||
# (gestione errore invariata)
|
# Gestione degli errori: mostra un popup di errore
|
||||||
error_details = f"{message}\n({exception})" if exception else message
|
error_details = f"{message}\n({type(exception).__name__}: {exception})" if exception else message
|
||||||
if is_conflict and repo_path_conflict: self.main_frame.show_error("Merge Conflict", f"Conflict occurred.\nResolve in:\n{repo_path_conflict}\nThen commit.")
|
if hasattr(self, "main_frame"):
|
||||||
elif "Uncommitted changes" in message: self.main_frame.show_warning("Action Blocked", f"{exception}\nCommit or stash first.")
|
# Mostra popup specifici per errori comuni
|
||||||
else: self.main_frame.show_error("Error: Operation Failed", error_details)
|
if is_conflict and repo_path_conflict:
|
||||||
# Aggiornamento liste con errore (opzionale, dipende dal task)
|
self.main_frame.show_error("Merge Conflict", f"Conflict occurred.\nResolve in:\n{repo_path_conflict}\nThen commit.")
|
||||||
|
elif "Uncommitted changes" in str(exception): # Controlla messaggio eccezione
|
||||||
|
self.main_frame.show_warning("Action Blocked", f"{exception}\nCommit or stash first.")
|
||||||
|
else:
|
||||||
|
# Errore generico
|
||||||
|
self.main_frame.show_error("Error: Operation Failed", error_details)
|
||||||
|
|
||||||
|
# Aggiorna le liste della GUI per mostrare lo stato di errore (se applicabile)
|
||||||
if task_context == 'refresh_tags': self.main_frame.update_tag_list([("(Error)", "")])
|
if task_context == 'refresh_tags': self.main_frame.update_tag_list([("(Error)", "")])
|
||||||
elif task_context == 'refresh_branches': self.main_frame.update_branch_list([], None); self.main_frame.update_history_branch_filter([])
|
elif task_context == 'refresh_branches':
|
||||||
|
self.main_frame.update_branch_list([], None) # Pulisci lista branch
|
||||||
|
self.main_frame.update_history_branch_filter([]) # Pulisci anche il filtro history
|
||||||
elif task_context == 'refresh_history': self.main_frame.update_history_display(["(Error retrieving history)"])
|
elif task_context == 'refresh_history': self.main_frame.update_history_display(["(Error retrieving history)"])
|
||||||
elif task_context == 'refresh_changes': self.main_frame.update_changed_files_list(["(Error refreshing changes)"])
|
elif task_context == 'refresh_changes': self.main_frame.update_changed_files_list(["(Error refreshing changes)"])
|
||||||
|
|
||||||
|
|
||||||
|
# Log finale per il processamento di questo risultato
|
||||||
log_handler.log_debug(f"Finished processing result for context '{task_context}'.", func_name="_check_completion_queue")
|
log_handler.log_debug(f"Finished processing result for context '{task_context}'.", func_name="_check_completion_queue")
|
||||||
|
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
# Reschedule check
|
# La coda è vuota, significa che non c'erano risultati pronti.
|
||||||
self.master.after(self.ASYNC_QUEUE_CHECK_INTERVAL_MS, self._check_completion_queue, results_queue, context)
|
# Pianifica un altro controllo in futuro.
|
||||||
|
if hasattr(self, "master") and self.master.winfo_exists():
|
||||||
|
self.master.after(self.ASYNC_QUEUE_CHECK_INTERVAL_MS, self._check_completion_queue, results_queue, context)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
# Errore critico durante il processamento della coda stessa
|
||||||
log_handler.log_exception(f"Critical error processing completion queue for {task_context}: {e}", func_name="_check_completion_queue")
|
log_handler.log_exception(f"Critical error processing completion queue for {task_context}: {e}", func_name="_check_completion_queue")
|
||||||
try: self.main_frame.set_action_widgets_state(tk.NORMAL) # Attempt recovery
|
# Tenta di riabilitare i widget come misura di sicurezza
|
||||||
except: pass
|
try:
|
||||||
self.main_frame.update_status_bar("Error processing async result.", bg_color=self.main_frame.STATUS_RED, duration_ms=10000)
|
if hasattr(self, "main_frame") and self.main_frame.winfo_exists():
|
||||||
|
self.main_frame.set_action_widgets_state(tk.NORMAL)
|
||||||
|
except: pass # Ignora errori nel tentativo di recupero
|
||||||
|
# Mostra errore generico nella status bar
|
||||||
|
if hasattr(self, "main_frame") and self.main_frame.winfo_exists():
|
||||||
|
self.main_frame.update_status_bar("Error processing async result.", bg_color=self.main_frame.STATUS_RED, duration_ms=10000)
|
||||||
|
|
||||||
|
|
||||||
# --- Punto di Ingresso (invariato) ---
|
# --- Punto di Ingresso (invariato) ---
|
||||||
|
|||||||
154
gui.py
154
gui.py
@ -1181,44 +1181,68 @@ class MainFrame(ttk.Frame):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def update_branch_list(self, branches, current_branch):
|
def update_branch_list(self, branches, current_branch):
|
||||||
if (
|
"""Clears and populates the branch listbox."""
|
||||||
not hasattr(self, "branch_listbox")
|
func_name = "update_branch_list (GUI)" # Nome specifico per i log
|
||||||
or not self.branch_listbox.winfo_exists()
|
# ---<<< INIZIO MODIFICA DEBUG & ERRORE >>>---
|
||||||
):
|
log_handler.log_debug(
|
||||||
|
f"Received branches type={type(branches)}, count={len(branches) if isinstance(branches, list) else 'N/A'}, "
|
||||||
|
f"current={repr(current_branch)}",
|
||||||
|
func_name=func_name
|
||||||
|
)
|
||||||
|
listbox = getattr(self, "branch_listbox", None)
|
||||||
|
if not listbox or not listbox.winfo_exists():
|
||||||
|
log_handler.log_error("branch_listbox not available for update.", func_name=func_name)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.branch_listbox.config(state=tk.NORMAL)
|
listbox.config(state=tk.NORMAL)
|
||||||
self.branch_listbox.delete(0, tk.END)
|
listbox.delete(0, tk.END)
|
||||||
sel_idx = -1
|
sel_idx = -1
|
||||||
if branches:
|
|
||||||
|
# Assicurati che 'branches' sia una lista prima di iterare
|
||||||
|
if isinstance(branches, list) and branches:
|
||||||
|
# Resetta colore (se era grigio o rosso)
|
||||||
try:
|
try:
|
||||||
if self.branch_listbox.cget("fg") == "grey":
|
default_fg = self.style.lookup("TListbox", "foreground")
|
||||||
self.branch_listbox.config(
|
if listbox.cget("fg") != default_fg:
|
||||||
fg=self.style.lookup("TListbox", "foreground")
|
listbox.config(fg=default_fg)
|
||||||
)
|
except tk.TclError: pass # Ignora errori di stile
|
||||||
except tk.TclError:
|
|
||||||
pass
|
# Popola la lista
|
||||||
for i, branch in enumerate(branches):
|
for i, branch in enumerate(branches):
|
||||||
prefix = "* " if branch == current_branch else " "
|
prefix = "* " if branch == current_branch else " "
|
||||||
self.branch_listbox.insert(tk.END, f"{prefix}{branch}")
|
# Assicura che branch sia una stringa prima di inserire
|
||||||
if branch == current_branch:
|
listbox.insert(tk.END, f"{prefix}{str(branch)}")
|
||||||
sel_idx = i
|
if branch == current_branch:
|
||||||
else:
|
sel_idx = i
|
||||||
self.branch_listbox.insert(tk.END, "(No local branches)")
|
elif isinstance(branches, list) and not branches: # Lista vuota valida
|
||||||
self.branch_listbox.config(fg="grey")
|
listbox.insert(tk.END, "(No local branches)")
|
||||||
|
listbox.config(fg="grey")
|
||||||
|
else: # Caso in cui branches non è una lista (errore?)
|
||||||
|
log_handler.log_warning(f"Invalid data received for branches: {repr(branches)}", func_name=func_name)
|
||||||
|
listbox.insert(tk.END, "(Invalid data received)")
|
||||||
|
listbox.config(fg="orange")
|
||||||
|
|
||||||
|
# Imposta selezione e vista
|
||||||
if sel_idx >= 0:
|
if sel_idx >= 0:
|
||||||
self.branch_listbox.selection_set(sel_idx)
|
listbox.selection_set(sel_idx)
|
||||||
self.branch_listbox.see(sel_idx)
|
listbox.see(sel_idx)
|
||||||
self.branch_listbox.config(state=tk.NORMAL)
|
|
||||||
self.branch_listbox.yview_moveto(0.0)
|
listbox.config(state=tk.NORMAL) # Mantieni selezionabile
|
||||||
|
listbox.yview_moveto(0.0)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"ERROR updating branch list GUI: {e}", file=sys.stderr)
|
log_handler.log_exception(f"Error updating branch list GUI: {e}", func_name=func_name)
|
||||||
try:
|
# Fallback: Mostra errore nella listbox
|
||||||
self.branch_listbox.delete(0, tk.END)
|
try:
|
||||||
self.branch_listbox.insert(tk.END, "(Error)")
|
if listbox.winfo_exists():
|
||||||
self.branch_listbox.config(fg="red")
|
listbox.config(state=tk.NORMAL)
|
||||||
except:
|
listbox.delete(0, tk.END)
|
||||||
pass
|
listbox.insert(tk.END, "(Error)")
|
||||||
|
listbox.config(fg="red", state=tk.DISABLED) # Disabilita su errore
|
||||||
|
except Exception as fallback_e:
|
||||||
|
log_handler.log_error(f"Error displaying fallback error in branch listbox: {fallback_e}", func_name=func_name)
|
||||||
|
# ---<<< FINE MODIFICA DEBUG & ERRORE >>>---
|
||||||
|
|
||||||
def get_selected_tag(self):
|
def get_selected_tag(self):
|
||||||
if hasattr(self, "tag_listbox") and self.tag_listbox.winfo_exists():
|
if hasattr(self, "tag_listbox") and self.tag_listbox.winfo_exists():
|
||||||
@ -1264,26 +1288,62 @@ class MainFrame(ttk.Frame):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def update_history_display(self, log_lines):
|
def update_history_display(self, log_lines):
|
||||||
if not hasattr(self, "history_text") or not self.history_text.winfo_exists():
|
"""Clears and populates the history ScrolledText widget."""
|
||||||
|
func_name = "update_history_display (GUI)" # Nome specifico per i log
|
||||||
|
# ---<<< INIZIO MODIFICA DEBUG & ERRORE >>>---
|
||||||
|
log_handler.log_debug(
|
||||||
|
f"Received log_lines type={type(log_lines)}, count={len(log_lines) if isinstance(log_lines, list) else 'N/A'}. "
|
||||||
|
f"Sample: {repr(log_lines[:5]) if isinstance(log_lines, list) else repr(log_lines)}",
|
||||||
|
func_name=func_name
|
||||||
|
)
|
||||||
|
history_widget = getattr(self, "history_text", None)
|
||||||
|
if not history_widget or not history_widget.winfo_exists():
|
||||||
|
log_handler.log_error("history_text widget not available for update.", func_name=func_name)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.history_text.config(state=tk.NORMAL)
|
history_widget.config(state=tk.NORMAL)
|
||||||
self.history_text.delete("1.0", tk.END)
|
history_widget.delete("1.0", tk.END)
|
||||||
self.history_text.insert(
|
|
||||||
tk.END, "\n".join(log_lines) if log_lines else "(No history found)"
|
# Assicurati che log_lines sia una lista prima di fare join
|
||||||
)
|
if isinstance(log_lines, list):
|
||||||
self.history_text.config(state=tk.DISABLED)
|
if log_lines:
|
||||||
self.history_text.yview_moveto(0.0)
|
# Resetta colore (se era rosso o altro)
|
||||||
self.history_text.xview_moveto(0.0)
|
try:
|
||||||
|
# Potrebbe non esserci un colore foreground specifico per ScrolledText nello stile
|
||||||
|
# Potremmo impostare a nero o lasciare il default del widget
|
||||||
|
default_fg = 'black' # Assumiamo nero come default sicuro
|
||||||
|
if history_widget.cget("fg") != default_fg:
|
||||||
|
history_widget.config(fg=default_fg)
|
||||||
|
except tk.TclError: pass
|
||||||
|
|
||||||
|
# Unisci le linee (assicurati siano stringhe)
|
||||||
|
text_to_insert = "\n".join(map(str, log_lines))
|
||||||
|
history_widget.insert(tk.END, text_to_insert)
|
||||||
|
else: # Lista vuota valida
|
||||||
|
history_widget.insert(tk.END, "(No history found)")
|
||||||
|
history_widget.config(fg="grey") # Colore grigio per indicare vuoto
|
||||||
|
else: # log_lines non è una lista (errore?)
|
||||||
|
log_handler.log_warning(f"Invalid data received for history: {repr(log_lines)}", func_name=func_name)
|
||||||
|
history_widget.insert(tk.END, f"(Invalid data received: {repr(log_lines)})")
|
||||||
|
history_widget.config(fg="orange") # Arancione per dato inatteso
|
||||||
|
|
||||||
|
history_widget.config(state=tk.DISABLED) # Rendi read-only
|
||||||
|
history_widget.yview_moveto(0.0)
|
||||||
|
history_widget.xview_moveto(0.0)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"ERROR updating history GUI: {e}", file=sys.stderr)
|
log_handler.log_exception(f"Error updating history GUI: {e}", func_name=func_name)
|
||||||
try:
|
# Fallback: Mostra errore nel widget di testo
|
||||||
self.history_text.config(state=tk.NORMAL)
|
try:
|
||||||
self.history_text.delete("1.0", tk.END)
|
if history_widget.winfo_exists():
|
||||||
self.history_text.insert(tk.END, "(Error)")
|
history_widget.config(state=tk.NORMAL)
|
||||||
self.history_text.config(state=tk.DISABLED, fg="red")
|
history_widget.delete("1.0", tk.END)
|
||||||
except:
|
history_widget.insert(tk.END, "(Error displaying history)")
|
||||||
pass
|
history_widget.config(state=tk.DISABLED, fg="red") # Rosso e disabilitato
|
||||||
|
except Exception as fallback_e:
|
||||||
|
log_handler.log_error(f"Error displaying fallback error in history widget: {fallback_e}", func_name=func_name)
|
||||||
|
# ---<<< FINE MODIFICA DEBUG & ERRORE >>>---
|
||||||
|
|
||||||
def update_history_branch_filter(self, branches_tags, current_ref=None):
|
def update_history_branch_filter(self, branches_tags, current_ref=None):
|
||||||
if (
|
if (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user