add statusbar
This commit is contained in:
parent
96a916ca09
commit
2416ab0b2a
@ -173,6 +173,7 @@ class GitSvnSyncApp:
|
||||
f"Error setting up logger with GUI TextHandler: {log_e}", exc_info=True
|
||||
)
|
||||
|
||||
self.main_frame.update_status_bar("Ready.")
|
||||
self.logger.info("Git SVN Sync Tool initialization sequence complete.")
|
||||
|
||||
def _perform_initial_load(self):
|
||||
@ -187,6 +188,9 @@ class GitSvnSyncApp:
|
||||
self._clear_and_disable_fields()
|
||||
#self.logger.info("Application started and initial state set.")
|
||||
|
||||
if self.main_frame.status_bar_var.get() == "": # Imposta solo se vuota
|
||||
self.main_frame.update_status_bar("Ready.")
|
||||
|
||||
def _handle_gitignore_save(self):
|
||||
"""
|
||||
Callback function triggered after .gitignore is saved successfully.
|
||||
@ -704,6 +708,7 @@ class GitSvnSyncApp:
|
||||
def prepare_svn_for_git(self):
|
||||
"""Handles the 'Prepare SVN Repo' action (Synchronous)."""
|
||||
self.logger.info("--- Action Triggered: Prepare Repo ---")
|
||||
self.main_frame.update_status_bar("Processing: Preparing repository...")
|
||||
# Validazione input
|
||||
svn_path = self._get_and_validate_svn_path("Prepare Repository")
|
||||
if not svn_path:
|
||||
@ -713,6 +718,7 @@ class GitSvnSyncApp:
|
||||
# Chiamata diretta a ActionHandler
|
||||
self.action_handler.execute_prepare_repo(svn_path)
|
||||
self.main_frame.show_info("Success", "Repository prepared successfully.")
|
||||
self.main_frame.update_status_bar("Repository prepared.")
|
||||
except (ValueError, GitCommandError, IOError) as e:
|
||||
self.logger.error(f"Prepare Repo failed: {e}", exc_info=True)
|
||||
# Mostra errore specifico (ValueError è spesso per 'già preparato')
|
||||
@ -734,6 +740,9 @@ class GitSvnSyncApp:
|
||||
def create_git_bundle(self):
|
||||
"""Handles the 'Create Bundle' action (Synchronous)."""
|
||||
self.logger.info("--- Action Triggered: Create Bundle ---")
|
||||
self.main_frame.update_status_bar("Processing: Creating bundle...")
|
||||
|
||||
status_final = "Ready."
|
||||
# Validazione Input e Preparazione Argomenti
|
||||
profile = self.main_frame.profile_var.get()
|
||||
if not profile:
|
||||
@ -786,23 +795,37 @@ class GitSvnSyncApp:
|
||||
self.main_frame.show_info(
|
||||
"Bundle Created", f"Bundle created:\n{bundle_path_result}"
|
||||
)
|
||||
status_final = f"Bundle created: {os.path.basename(bundle_path_result)}"
|
||||
else:
|
||||
self.main_frame.show_info(
|
||||
"Bundle Info",
|
||||
"Bundle creation finished, but no file generated (repo empty?).",
|
||||
)
|
||||
status_final = "Bundle created (empty or no changes)."
|
||||
except (IOError, GitCommandError, ValueError) as e:
|
||||
self.logger.error(f"Create Bundle failed: {e}", exc_info=True)
|
||||
status_final = "Error: Unexpected failure creating bundle."
|
||||
self.main_frame.show_error("Create Bundle Error", f"Operation failed:\n{e}")
|
||||
|
||||
except Exception as e:
|
||||
self.logger.exception(f"Unexpected error during Create Bundle: {e}")
|
||||
status_final = f"Error creating bundle: {type(e).__name__}"
|
||||
self.main_frame.show_error(
|
||||
"Unexpected Error", f"An unexpected error occurred:\n{e}"
|
||||
)
|
||||
|
||||
finally:
|
||||
# --- MODIFICA: Status Bar (Fine Operazione) ---
|
||||
self.main_frame.update_status_bar(status_final)
|
||||
# --- FINE MODIFICA ---
|
||||
# Aggiorna stato UI (invariato)
|
||||
self.update_svn_status_indicator(svn_path)
|
||||
|
||||
def fetch_from_git_bundle(self):
|
||||
"""Handles the 'Fetch from Bundle' action (Synchronous)."""
|
||||
self.logger.info("--- Action Triggered: Fetch from Bundle ---")
|
||||
self.main_frame.update_status_bar("Processing: Fetching from bundle...")
|
||||
status_final = "Ready."
|
||||
# Validazione Input e Preparazione Argomenti
|
||||
profile = self.main_frame.profile_var.get()
|
||||
if not profile:
|
||||
@ -854,8 +877,10 @@ class GitSvnSyncApp:
|
||||
"Fetch Complete",
|
||||
"Fetch and merge completed.\nCheck log for details.",
|
||||
)
|
||||
status_final = "Fetch/Clone from bundle complete."
|
||||
# else non dovrebbe accadere se ActionHandler solleva eccezioni
|
||||
except FileNotFoundError as e: # Cattura se il file scompare tra check e uso
|
||||
status_final = f"Error: Bundle file not found."
|
||||
self.logger.error(f"Fetch failed: {e}", exc_info=False) # Log meno verboso
|
||||
self.main_frame.show_error("File Not Found", f"{e}")
|
||||
except GitCommandError as e: # Gestione specifica conflitti
|
||||
@ -877,10 +902,14 @@ class GitSvnSyncApp:
|
||||
self.main_frame.show_error(
|
||||
"Unexpected Error", f"An unexpected error occurred:\n{e}"
|
||||
)
|
||||
finally:
|
||||
self.main_frame.update_status_bar(status_final)
|
||||
|
||||
|
||||
def manual_backup(self):
|
||||
"""Handles the 'Backup Now' button click (Synchronous)."""
|
||||
self.logger.info("--- Action Triggered: Manual Backup ---")
|
||||
self.main_frame.update_status_bar("Processing: Manual Backup...")
|
||||
# Validazione Input
|
||||
profile = self.main_frame.profile_var.get()
|
||||
if not profile:
|
||||
@ -920,11 +949,13 @@ class GitSvnSyncApp:
|
||||
self.main_frame.show_info(
|
||||
"Backup Complete", f"Manual backup created:\n{backup_path_result}"
|
||||
)
|
||||
self.main_frame.update_status_bar(f"Manual backup created:\n{backup_path_result}")
|
||||
else:
|
||||
self.main_frame.show_warning(
|
||||
"Backup Info",
|
||||
"Backup finished, but no file generated (source empty?).",
|
||||
)
|
||||
self.main_frame.update_status_bar("Backup finished, but no file generated (source empty?).")
|
||||
except (IOError, ValueError, PermissionError) as e: # Cattura errori specifici
|
||||
self.logger.error(f"Manual backup failed: {e}", exc_info=True)
|
||||
self.main_frame.show_error("Backup Error", f"Manual backup failed:\n{e}")
|
||||
|
||||
60
ToDo.md
Normal file
60
ToDo.md
Normal file
@ -0,0 +1,60 @@
|
||||
Ottima domanda! È sempre utile fare un passo indietro e pensare a possibili miglioramenti o funzionalità aggiuntive. Discutiamone:
|
||||
|
||||
**Potenziali Miglioramenti e Funzionalità Mancanti:**
|
||||
|
||||
1. **Gestione Conflitti (GUI):**
|
||||
* **Situazione Attuale:** Quando "Fetch from Bundle" causa un conflitto, lo script lo rileva, logga l'errore e mostra un messaggio all'utente dicendo di risolvere manualmente.
|
||||
* **Possibile Miglioramento:** Potrebbe essere *molto* utile avere un'indicazione visiva più chiara nella GUI quando si verifica un conflitto (magari un'icona di stato diversa, un messaggio persistente in una status bar). Ancora più avanzato (e complesso) sarebbe integrare un semplice strumento di visualizzazione/risoluzione dei conflitti direttamente nell'applicazione, anche se questo aumenterebbe significativamente la complessità. Un primo passo potrebbe essere semplicemente elencare i file in conflitto nell'area log o in un popup dedicato.
|
||||
|
||||
2. **Bundle Incrementali:**
|
||||
* **Situazione Attuale:** `git bundle create --all` crea un bundle completo ogni volta. Questo è sicuro ma può essere inefficiente se le modifiche tra le sincronizzazioni sono piccole e il repository è grande.
|
||||
* **Possibile Miglioramento:** Esplorare l'uso dei bundle incrementali. `git bundle create mio_update.bundle <ultimo_tag_o_commit_noto_all_altra_parte>..HEAD`. Questo richiede di tenere traccia dell'ultimo stato sincronizzato (magari salvando l'hash dell'ultimo commit importato/esportato nel profilo?). Questo renderebbe i trasferimenti molto più veloci per grandi repository.
|
||||
* **Complessità:** Richiede una gestione dello stato più sofisticata.
|
||||
|
||||
3. **Gestione Errori di `git rm --cached` nell'Untrack Automatico:**
|
||||
* **Situazione Attuale:** Se un batch di `git rm --cached` fallisce, l'intero processo si interrompe.
|
||||
* **Possibile Miglioramento:** Si potrebbe decidere di rendere l'operazione più resiliente: se un batch fallisce, loggare l'errore, *continuare* con i batch successivi e alla fine riportare un successo parziale o un avviso, magari elencando i file che non è riuscito a untraccare. Il commit automatico verrebbe comunque creato per i file untracciati con successo. Questo eviterebbe che un singolo file problematico blocchi l'untracking di tutti gli altri.
|
||||
|
||||
4. **Visualizzazione Modifiche (Diff):**
|
||||
* **Situazione Attuale:** L'utente non ha modo di vedere quali file sono stati modificati direttamente dall'interno del tool prima di fare un commit (manuale o pre-tag).
|
||||
* **Possibile Miglioramento:** Aggiungere una sezione (magari una nuova scheda o un pannello nella scheda "Commit") che esegua `git status --short` o `git diff --name-status` e mostri l'elenco dei file modificati, aggiunti, cancellati. Ancora più avanzato sarebbe mostrare il diff effettivo per il file selezionato. Questo aiuterebbe l'utente a scrivere messaggi di commit più accurati.
|
||||
|
||||
5. **Gestione Branch Remoti (se Applicabile):**
|
||||
* **Situazione Attuale:** Il tool si concentra sui branch locali e sui bundle. Non gestisce direttamente interazioni con repository remoti (tipo GitHub/GitLab).
|
||||
* **Considerazione:** Sebbene lo scopo principale sia la sincronizzazione offline, potrebbe esserci uno scenario in cui la macchina "origine" interagisce anche con un remote. Aggiungere funzionalità `push`/`pull`/`fetch` standard potrebbe essere utile per alcuni, ma forse snaturerebbe l'obiettivo primario del tool focalizzato sui bundle.
|
||||
|
||||
6. **Opzioni di Pulizia:**
|
||||
* **Situazione Attuale:** Non ci sono comandi di pulizia integrati.
|
||||
* **Possibile Miglioramento:** Aggiungere pulsanti per eseguire comandi Git utili come `git clean -fdx` (per rimuovere file non tracciati e ignorati - **pericoloso, da usare con cautela!**) o `git gc --prune=now --aggressive` (per ottimizzare il repository). Questi dovrebbero avere conferme molto chiare sui rischi.
|
||||
|
||||
7. **Interfaccia Utente (Piccoli Ritocchi):**
|
||||
* **Progresso Operazioni Lunghe:** Per operazioni come la creazione di bundle grandi o il backup, una progress bar (anche indeterminata) darebbe un feedback migliore rispetto al solo log testuale. (Richiederebbe però di reintrodurre un po' di threading/async per non bloccare la GUI).
|
||||
* **Stato Pulsanti:** Rivedere attentamente quando i pulsanti dovrebbero essere abilitati/disabilitati per guidare l'utente nel flusso corretto (ad esempio, il pulsante "Commit" potrebbe essere disabilitato se `git status` non riporta modifiche).
|
||||
* **Status Bar:** Una piccola area in basso (sotto l'area log) per messaggi di stato rapidi ("Ready", "Operation in progress...", "Conflict detected", "Last backup: ...") potrebbe essere utile.
|
||||
|
||||
8. **Configurazione Avanzata Bundle:**
|
||||
* **Situazione Attuale:** Usa sempre `--all` per la creazione.
|
||||
* **Possibile Miglioramento:** Permettere all'utente di specificare riferimenti specifici (branch/tag) da includere nel bundle, invece di usare sempre `--all`, tramite un'interfaccia o opzioni nel profilo.
|
||||
|
||||
9. **Internazionalizzazione (i18n):**
|
||||
* **Situazione Attuale:** L'interfaccia è solo in inglese (testi nei widget). I messaggi di log e i commenti sono in inglese, ma le interazioni con te sono in italiano.
|
||||
* **Possibile Miglioramento:** Se dovesse essere usato da altri, separare le stringhe dell'interfaccia in file di traduzione per supportare più lingue.
|
||||
|
||||
**Discussione:**
|
||||
|
||||
* **Priorità Alta (Secondo Me):**
|
||||
* Migliore gestione/visualizzazione dei conflitti (almeno elencare i file).
|
||||
* Raffinamento dello stato dei pulsanti GUI.
|
||||
* Resilienza opzionale per `git rm --cached` in batch.
|
||||
* **Priorità Media:**
|
||||
* Visualizzazione delle modifiche (`git status`/`diff`).
|
||||
* Bundle incrementali (grande vantaggio per repo grandi, ma più complesso).
|
||||
* Status bar.
|
||||
* **Priorità Bassa/Opzionale:**
|
||||
* Opzioni di pulizia (`git clean`, `gc`).
|
||||
* Gestione remoti standard.
|
||||
* Configurazione avanzata bundle.
|
||||
* Internazionalizzazione.
|
||||
* Progress bar (richiede più lavoro strutturale).
|
||||
|
||||
Cosa ne pensi? Quali di questi punti ti sembrano più interessanti o utili per i tuoi casi d'uso?
|
||||
42
gui.py
42
gui.py
@ -463,7 +463,22 @@ class MainFrame(ttk.Frame):
|
||||
self.notebook.add(self.history_tab_frame, text=" History ")
|
||||
|
||||
# Log area (always visible below tabs)
|
||||
self._create_log_area()
|
||||
# Modifichiamo leggermente il pack del log frame per fare spazio sotto
|
||||
log_frame_container = ttk.Frame(self)
|
||||
log_frame_container.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True, padx=0, pady=(5, 0))
|
||||
self._create_log_area(log_frame_container) # Passa il container
|
||||
|
||||
self.status_bar_var = tk.StringVar()
|
||||
self.status_bar_var.set("Ready.") # Messaggio iniziale
|
||||
self.status_bar = ttk.Label(
|
||||
self, # Direttamente nel MainFrame
|
||||
textvariable=self.status_bar_var,
|
||||
relief=tk.SUNKEN,
|
||||
anchor=tk.W, # Allinea testo a sinistra
|
||||
padding=(5, 2) # Un po' di padding interno
|
||||
)
|
||||
# Pack sotto tutto il resto, occupa la larghezza
|
||||
self.status_bar.pack(side=tk.BOTTOM, fill=tk.X, pady=(2, 0), padx=0)
|
||||
|
||||
# --- Initial State Configuration ---
|
||||
# Set initial profile selection using the improved logic from previous discussion
|
||||
@ -1008,15 +1023,15 @@ class MainFrame(ttk.Frame):
|
||||
self.history_text.config(xscrollcommand=history_xscroll.set)
|
||||
return frame
|
||||
|
||||
def _create_log_area(self):
|
||||
"""Creates the application log area at the bottom."""
|
||||
# (No changes needed here for this modification)
|
||||
log_frame = ttk.LabelFrame(self, text="Application Log", padding=(10, 5))
|
||||
log_frame.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True, padx=0, pady=(5, 0))
|
||||
def _create_log_area(self, parent_frame):
|
||||
"""Creates the application log area within the specified parent."""
|
||||
log_frame = ttk.LabelFrame(parent_frame, text="Application Log", padding=(10, 5))
|
||||
log_frame.pack(fill=tk.BOTH, expand=True) # Si espande nel suo container
|
||||
log_frame.rowconfigure(0, weight=1)
|
||||
log_frame.columnconfigure(0, weight=1)
|
||||
self.log_text = scrolledtext.ScrolledText(
|
||||
log_frame,
|
||||
# ... (configurazione log_text invariata) ...
|
||||
height=8,
|
||||
width=100,
|
||||
font=("Consolas", 9),
|
||||
@ -1026,6 +1041,7 @@ class MainFrame(ttk.Frame):
|
||||
pady=5,
|
||||
)
|
||||
self.log_text.grid(row=0, column=0, sticky="nsew")
|
||||
# (configurazione tag invariata)
|
||||
self.log_text.tag_config("INFO", foreground="black")
|
||||
self.log_text.tag_config("DEBUG", foreground="grey")
|
||||
self.log_text.tag_config("WARNING", foreground="orange")
|
||||
@ -1162,6 +1178,20 @@ class MainFrame(ttk.Frame):
|
||||
except Exception as e:
|
||||
logging.error(f"Error tags: {e}", exc_info=True)
|
||||
self.tag_listbox.insert(tk.END, "(Error)")
|
||||
|
||||
def update_status_bar(self, message):
|
||||
"""Updates the text displayed in the status bar."""
|
||||
if hasattr(self, "status_bar_var"):
|
||||
try:
|
||||
# Usiamo after(0,..) per sicurezza, anche se probabilmente non strettamente necessario
|
||||
# nella maggior parte dei casi di questa app. Previene potenziali problemi se
|
||||
# una chiamata arrivasse da un thread diverso (improbabile qui ma buona pratica).
|
||||
self.master.after(0, self.status_bar_var.set, message)
|
||||
except Exception as e:
|
||||
# Logga se l'aggiornamento della status bar fallisce
|
||||
# Evita di usare self.logger qui per non creare dipendenze circolari potenziali
|
||||
# durante l'inizializzazione o la chiusura. Usa print o un logger di base.
|
||||
print(f"ERROR: Failed to update status bar: {e}")
|
||||
|
||||
def get_selected_tag(self):
|
||||
if hasattr(self, "tag_listbox"):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user