SXXXXXXX_GitUtility/gitutility/gui/tabs/backup_tab.py
2025-07-29 08:41:44 +02:00

144 lines
6.1 KiB
Python

# --- FILE: gitsync_tool/gui/tabs/backup_tab.py ---
import tkinter as tk
from tkinter import ttk
from typing import Callable, Optional
from gitutility.gui.tooltip import Tooltip
class BackupTab(ttk.Frame):
"""
The 'Backup Settings' tab in the main application notebook.
This tab provides widgets for configuring automatic and manual backups.
"""
def __init__(self, master: tk.Misc, **kwargs):
"""
Initializes the Backup Settings tab.
Args:
master: The parent widget (the ttk.Notebook).
**kwargs: Dictionary of callbacks from the main controller.
"""
super().__init__(master, padding=(10, 10))
# Store callbacks
self.manual_backup_callback = kwargs.get('manual_backup_cb')
self.browse_folder_callback = kwargs.get('browse_folder_cb')
# --- Tkinter Variables specific to this tab ---
self.autobackup_var = tk.BooleanVar()
self.backup_dir_var = tk.StringVar()
self.backup_exclude_extensions_var = tk.StringVar()
self.backup_exclude_dirs_var = tk.StringVar()
# Configure layout
self.columnconfigure(1, weight=1)
# Create widgets
self._create_widgets()
def _create_widgets(self) -> None:
"""Creates and arranges all widgets for this tab."""
# --- Backup Configuration Frame ---
config_frame = ttk.LabelFrame(self, text="Backup Configuration", padding=(10, 5))
config_frame.pack(pady=5, fill="x", expand=False)
config_frame.columnconfigure(1, weight=1)
# Autobackup Checkbox
self.autobackup_checkbox = ttk.Checkbutton(
config_frame,
text="Enable Auto Backup before Actions (Create/Fetch Bundle)",
variable=self.autobackup_var,
command=self.toggle_backup_dir_widgets,
)
self.autobackup_checkbox.grid(row=0, column=0, columnspan=3, sticky=tk.W, padx=5, pady=(5, 5))
Tooltip(
self.autobackup_checkbox,
"Automatically create a ZIP backup of the working directory before creating or fetching from a bundle."
)
# Backup Directory
backup_dir_label = ttk.Label(config_frame, text="Backup Directory:")
backup_dir_label.grid(row=1, column=0, sticky=tk.W, padx=5, pady=3)
self.backup_dir_entry = ttk.Entry(
config_frame, textvariable=self.backup_dir_var, width=60, state=tk.DISABLED
)
self.backup_dir_entry.grid(row=1, column=1, sticky=tk.EW, padx=5, pady=3)
Tooltip(self.backup_dir_entry, "Directory where automatic and manual backup ZIP files will be stored.")
self.backup_dir_button = ttk.Button(
config_frame, text="Browse...", width=9, command=self._browse_backup_dir, state=tk.DISABLED
)
self.backup_dir_button.grid(row=1, column=2, sticky=tk.W, padx=(0, 5), pady=3)
# Exclusions
exclude_ext_label = ttk.Label(config_frame, text="Exclude File Exts:")
exclude_ext_label.grid(row=2, column=0, sticky=tk.W, padx=5, pady=3)
self.backup_exclude_entry = ttk.Entry(
config_frame, textvariable=self.backup_exclude_extensions_var, width=60
)
self.backup_exclude_entry.grid(row=2, column=1, columnspan=2, sticky=tk.EW, padx=5, pady=3)
Tooltip(
self.backup_exclude_entry,
"Comma-separated list of file extensions to exclude from backups (e.g., .log, .tmp, .bak)."
)
exclude_dir_label = ttk.Label(config_frame, text="Exclude Dirs (Name):")
exclude_dir_label.grid(row=3, column=0, sticky=tk.W, padx=5, pady=3)
self.backup_exclude_dirs_entry = ttk.Entry(
config_frame, textvariable=self.backup_exclude_dirs_var, width=60
)
self.backup_exclude_dirs_entry.grid(row=3, column=1, columnspan=2, sticky=tk.EW, padx=5, pady=3)
Tooltip(
self.backup_exclude_dirs_entry,
"Comma-separated list of directory base names to exclude (e.g., __pycache__, build, node_modules). .git and .svn are always excluded."
)
# --- Manual Backup Action Frame ---
action_frame = ttk.LabelFrame(self, text="Manual Backup", padding=(10, 5))
action_frame.pack(pady=10, fill="x", expand=False)
self.manual_backup_button = ttk.Button(
action_frame, text="Backup Now (ZIP)", command=self.manual_backup_callback, state=tk.DISABLED
)
self.manual_backup_button.pack(side=tk.LEFT, padx=5, pady=5)
Tooltip(
self.manual_backup_button,
"Create a manual ZIP backup of the working directory now using the configured exclusions."
)
def _browse_backup_dir(self):
"""Internal handler to call the browse callback for the backup directory entry."""
if hasattr(self, "backup_dir_entry") and callable(self.browse_folder_callback):
self.browse_folder_callback(self.backup_dir_entry)
def toggle_backup_dir_widgets(self) -> None:
"""Enables or disables the backup directory widgets based on the autobackup checkbox."""
state = tk.NORMAL if self.autobackup_var.get() else tk.DISABLED
if hasattr(self, "backup_dir_entry") and self.backup_dir_entry.winfo_exists():
self.backup_dir_entry.config(state=state)
if hasattr(self, "backup_dir_button") and self.backup_dir_button.winfo_exists():
self.backup_dir_button.config(state=state)
def set_action_widgets_state(self, state: str) -> None:
"""Sets the state of all action widgets in this tab."""
widgets_to_toggle = [
self.autobackup_checkbox,
self.manual_backup_button,
]
for widget in widgets_to_toggle:
if widget and widget.winfo_exists():
widget.config(state=state)
if state == tk.DISABLED:
if hasattr(self, "backup_dir_entry"): self.backup_dir_entry.config(state=tk.DISABLED)
if hasattr(self, "backup_dir_button"): self.backup_dir_button.config(state=tk.DISABLED)
else:
self.toggle_backup_dir_widgets()