feat(ui): Ersetze Checkboxen und Radio-Buttons durch Switches
Dieses Commit ersetzt die meisten ttk.Checkbutton- und ttk.Radiobutton-Widgets in der gesamten Anwendung durch einen benutzerdefinierten "Switch"-Stil, um ein moderneres Erscheinungsbild zu erzielen. Die Änderungen umfassen: - **Hauptfenster**: - Umwandlung der Backup-Optionen (Voll, Inkrementell, Komprimiert, Verschlüsselt) in Switches. - Ersetzung der "Genaue Grössenberechnung"-Checkbox durch einen normalen Button. - Verschiebung der "Testlauf"- und "Sicherheit umgehen"-Switches in die Seitenleiste unter "Einstellungen". - **Scheduler**: - Ersetzung aller Radio-Buttons und Checkboxen durch Switches, mit implementierter Logik zur Gewährleistung der exklusiven Auswahl für Backup-Typ und Frequenz. - **Erweiterte Einstellungen**: - Umwandlung aller Checkboxen im Abschnitt "Backup-Standards" in Switches. - **Styling**: - Hinzufügen eines neuen Stils `Switch2.TCheckbutton` für die Switches in der Seitenleiste, um sie an das dunkle Thema der Seitenleiste anzupassen. Die Konfiguration erfolgt direkt in `main_app.py`. - **Fehlerbehebungen**: - Behebung eines `AttributeError`-Absturzes, der durch die Verschiebung der Switches vor der Deklaration ihrer `tk.BooleanVar`-Variablen verursacht wurde. - Anpassung der zugehörigen Logik in `pyimage_ui/actions.py` an den neuen Button.
This commit is contained in:
@@ -286,8 +286,10 @@ class BackupManager:
|
||||
self.logger.log(
|
||||
f"Executing rsync dry-run command: {' '.join(command)}")
|
||||
|
||||
env = os.environ.copy()
|
||||
env['LC_ALL'] = 'C'
|
||||
result = subprocess.run(
|
||||
command, capture_output=True, text=True, check=False)
|
||||
command, capture_output=True, text=True, check=False, env=env)
|
||||
|
||||
# rsync exit code 24 means some files vanished during transfer, which is okay for a dry-run estimate.
|
||||
if result.returncode != 0 and result.returncode != 24:
|
||||
|
||||
51
main_app.py
51
main_app.py
@@ -52,6 +52,11 @@ class MainApplication(tk.Tk):
|
||||
|
||||
self.style.configure("Green.Sidebar.TButton", foreground="green")
|
||||
|
||||
self.style.configure("Switch2.TCheckbutton", background="#2b3e4f", foreground="white")
|
||||
self.style.map("Switch2.TCheckbutton",
|
||||
background=[("active", "#2b3e4f"), ("selected", "#2b3e4f"), ("disabled", "#2b3e4f")],
|
||||
foreground=[("active", "white"), ("selected", "white"), ("disabled", "#737373")])
|
||||
|
||||
main_frame = ttk.Frame(self)
|
||||
main_frame.grid(row=0, column=0, sticky="nsew")
|
||||
self.grid_rowconfigure(0, weight=1)
|
||||
@@ -88,6 +93,14 @@ class MainApplication(tk.Tk):
|
||||
self.navigation = Navigation(self)
|
||||
self.actions = Actions(self)
|
||||
|
||||
self.vollbackup_var = tk.BooleanVar()
|
||||
self.inkrementell_var = tk.BooleanVar()
|
||||
self.genaue_berechnung_var = tk.BooleanVar()
|
||||
self.testlauf_var = tk.BooleanVar()
|
||||
self.compressed_var = tk.BooleanVar()
|
||||
self.encrypted_var = tk.BooleanVar()
|
||||
self.bypass_security_var = tk.BooleanVar()
|
||||
|
||||
self.mode = "backup" # Default mode
|
||||
self.backup_is_running = False
|
||||
self.start_time = None
|
||||
@@ -154,6 +167,13 @@ class MainApplication(tk.Tk):
|
||||
self.sidebar_buttons_frame, text=Msg.STR["settings"], command=lambda: self.navigation.toggle_settings_frame(4), style="Sidebar.TButton")
|
||||
self.settings_button.pack(fill=tk.X, pady=10)
|
||||
|
||||
self.test_run_cb = ttk.Checkbutton(self.sidebar_buttons_frame, text=Msg.STR["test_run"],
|
||||
variable=self.testlauf_var, style="Switch2.TCheckbutton")
|
||||
self.test_run_cb.pack(fill=tk.X, pady=10)
|
||||
self.bypass_security_cb = ttk.Checkbutton(self.sidebar_buttons_frame, text=Msg.STR["bypass_security"],
|
||||
variable=self.bypass_security_var, style="Switch2.TCheckbutton")
|
||||
self.bypass_security_cb.pack(fill=tk.X, pady=10)
|
||||
|
||||
self.header_frame = HeaderFrame(
|
||||
self.content_frame, self.image_manager, self.backup_manager.encryption_manager, self)
|
||||
self.header_frame.grid(row=0, column=0, sticky="nsew")
|
||||
@@ -305,7 +325,6 @@ class MainApplication(tk.Tk):
|
||||
self.restore_size_frame_after.grid_remove()
|
||||
|
||||
self._load_state_and_initialize()
|
||||
self.update_backup_options_from_config()
|
||||
self.protocol("WM_DELETE_WINDOW", self.on_closing)
|
||||
|
||||
def _load_state_and_initialize(self):
|
||||
@@ -421,14 +440,6 @@ class MainApplication(tk.Tk):
|
||||
self.backup_content_frame.grid_remove()
|
||||
|
||||
def _setup_task_bar(self):
|
||||
self.vollbackup_var = tk.BooleanVar()
|
||||
self.inkrementell_var = tk.BooleanVar()
|
||||
self.genaue_berechnung_var = tk.BooleanVar()
|
||||
self.testlauf_var = tk.BooleanVar()
|
||||
self.compressed_var = tk.BooleanVar()
|
||||
self.encrypted_var = tk.BooleanVar()
|
||||
self.bypass_security_var = tk.BooleanVar()
|
||||
|
||||
self.info_checkbox_frame = ttk.Frame(self.content_frame, padding=10)
|
||||
self.info_checkbox_frame.grid(row=3, column=0, sticky="ew")
|
||||
|
||||
@@ -458,9 +469,9 @@ class MainApplication(tk.Tk):
|
||||
accurate_size_frame = ttk.Frame(self.time_info_frame)
|
||||
accurate_size_frame.pack(side=tk.LEFT, padx=20)
|
||||
|
||||
self.accurate_size_cb = ttk.Checkbutton(accurate_size_frame, text=Msg.STR["accurate_size_cb_label"],
|
||||
variable=self.genaue_berechnung_var, command=self.actions.on_toggle_accurate_size_calc)
|
||||
self.accurate_size_cb.pack(side=tk.LEFT, padx=5)
|
||||
self.accurate_size_btn = ttk.Button(accurate_size_frame, text=Msg.STR["accurate_size_cb_label"],
|
||||
command=self.actions.on_accurate_size_calc)
|
||||
self.accurate_size_btn.pack(side=tk.LEFT, padx=5)
|
||||
|
||||
accurate_size_info_label = ttk.Label(
|
||||
accurate_size_frame, text=Msg.STR["accurate_size_info_label"], foreground="gray")
|
||||
@@ -470,24 +481,18 @@ class MainApplication(tk.Tk):
|
||||
checkbox_frame.pack(fill=tk.X, pady=5)
|
||||
|
||||
self.full_backup_cb = ttk.Checkbutton(checkbox_frame, text=Msg.STR["full_backup"],
|
||||
variable=self.vollbackup_var, command=lambda: self.actions.handle_backup_type_change('voll'))
|
||||
variable=self.vollbackup_var, command=lambda: self.actions.handle_backup_type_change('voll'), style="Switch.TCheckbutton")
|
||||
self.full_backup_cb.pack(side=tk.LEFT, padx=5)
|
||||
self.incremental_cb = ttk.Checkbutton(checkbox_frame, text=Msg.STR["incremental"],
|
||||
variable=self.inkrementell_var, command=lambda: self.actions.handle_backup_type_change('inkrementell'))
|
||||
variable=self.inkrementell_var, command=lambda: self.actions.handle_backup_type_change('inkrementell'), style="Switch.TCheckbutton")
|
||||
self.incremental_cb.pack(side=tk.LEFT, padx=5)
|
||||
|
||||
self.compressed_cb = ttk.Checkbutton(checkbox_frame, text=Msg.STR["compressed"],
|
||||
variable=self.compressed_var, command=self.actions.handle_compression_change)
|
||||
variable=self.compressed_var, command=self.actions.handle_compression_change, style="Switch.TCheckbutton")
|
||||
self.compressed_cb.pack(side=tk.LEFT, padx=5)
|
||||
self.encrypted_cb = ttk.Checkbutton(checkbox_frame, text=Msg.STR["encrypted"],
|
||||
variable=self.encrypted_var, command=self.actions.handle_encryption_change)
|
||||
variable=self.encrypted_var, command=self.actions.handle_encryption_change, style="Switch.TCheckbutton")
|
||||
self.encrypted_cb.pack(side=tk.LEFT, padx=5)
|
||||
self.test_run_cb = ttk.Checkbutton(checkbox_frame, text=Msg.STR["test_run"],
|
||||
variable=self.testlauf_var)
|
||||
self.test_run_cb.pack(side=tk.LEFT, padx=5)
|
||||
self.bypass_security_cb = ttk.Checkbutton(checkbox_frame, text=Msg.STR["bypass_security"],
|
||||
variable=self.bypass_security_var)
|
||||
self.bypass_security_cb.pack(side=tk.LEFT, padx=5)
|
||||
|
||||
self.action_frame = ttk.Frame(self.content_frame, padding=10)
|
||||
self.action_frame.grid(row=6, column=0, sticky="ew")
|
||||
@@ -585,7 +590,6 @@ class MainApplication(tk.Tk):
|
||||
if mode_when_started != self.mode:
|
||||
if calc_type == 'accurate_incremental':
|
||||
self.actions._set_ui_state(True)
|
||||
self.genaue_berechnung_var.set(False)
|
||||
self.accurate_calculation_running = False
|
||||
self.animated_icon.stop("DISABLE")
|
||||
else:
|
||||
@@ -634,7 +638,6 @@ class MainApplication(tk.Tk):
|
||||
self.task_progress.config(
|
||||
mode="determinate", value=0)
|
||||
self.actions._set_ui_state(True)
|
||||
self.genaue_berechnung_var.set(False)
|
||||
self.accurate_calculation_running = False
|
||||
self.start_pause_button.config(
|
||||
text=Msg.STR["start"])
|
||||
|
||||
@@ -73,7 +73,7 @@ class Actions:
|
||||
self.app.incremental_cb.config(state="normal")
|
||||
self.app.compressed_cb.config(state="normal")
|
||||
self.app.encrypted_cb.config(state="normal")
|
||||
self.app.accurate_size_cb.config(state="normal")
|
||||
self.app.accurate_size_btn.config(state="normal")
|
||||
|
||||
# Apply specific logic based on current states
|
||||
if self.app.compressed_var.get():
|
||||
@@ -82,8 +82,7 @@ class Actions:
|
||||
self.app.incremental_cb.config(state="disabled")
|
||||
self.app.encrypted_var.set(False) # If compressed, cannot be encrypted
|
||||
self.app.encrypted_cb.config(state="disabled")
|
||||
self.app.accurate_size_cb.config(state="disabled") # Accurate size not applicable for compressed
|
||||
self.app.genaue_berechnung_var.set(False)
|
||||
self.app.accurate_size_btn.config(state="disabled") # Accurate size not applicable for compressed
|
||||
elif self.app.encrypted_var.get():
|
||||
self.app.compressed_var.set(False) # If encrypted, cannot be compressed
|
||||
self.app.compressed_cb.config(state="disabled")
|
||||
@@ -108,9 +107,7 @@ class Actions:
|
||||
def handle_encryption_change(self):
|
||||
self._refresh_backup_options_ui()
|
||||
|
||||
def on_toggle_accurate_size_calc(self):
|
||||
if not self.app.genaue_berechnung_var.get():
|
||||
return
|
||||
def on_accurate_size_calc(self):
|
||||
|
||||
if self.app.calculation_thread and self.app.calculation_thread.is_alive():
|
||||
self.app.calculation_stop_event.set()
|
||||
@@ -141,7 +138,6 @@ class Actions:
|
||||
app_logger.log(
|
||||
"Cannot start accurate calculation, source folder info missing.")
|
||||
self._set_ui_state(True)
|
||||
self.app.genaue_berechnung_var.set(False)
|
||||
self.app.accurate_calculation_running = False
|
||||
self.app.animated_icon.stop("DISABLE")
|
||||
return
|
||||
@@ -235,12 +231,6 @@ class Actions:
|
||||
else:
|
||||
extra_info = Msg.STR["user_restore_info"]
|
||||
|
||||
if self.app.mode == 'backup':
|
||||
self._update_backup_type_controls()
|
||||
else:
|
||||
self.app.config_manager.set_setting(
|
||||
"restore_destination_path", folder_path)
|
||||
|
||||
self._start_left_canvas_calculation(
|
||||
button_text, str(folder_path), icon_name, extra_info)
|
||||
self.app._update_sync_mode_display()
|
||||
@@ -375,7 +365,6 @@ class Actions:
|
||||
current_source = self.app.left_canvas_data.get('folder')
|
||||
if current_source:
|
||||
self.on_sidebar_button_click(current_source)
|
||||
self._update_backup_type_controls()
|
||||
|
||||
elif self.app.mode == "restore":
|
||||
self.app.right_canvas_data.update({
|
||||
@@ -491,17 +480,16 @@ class Actions:
|
||||
|
||||
if enable:
|
||||
self.app.update_backup_options_from_config()
|
||||
self.app.actions._update_backup_type_controls()
|
||||
else:
|
||||
checkboxes = [
|
||||
self.app.full_backup_cb,
|
||||
self.app.incremental_cb,
|
||||
self.app.accurate_size_cb,
|
||||
self.app.compressed_cb,
|
||||
self.app.encrypted_cb,
|
||||
self.app.test_run_cb,
|
||||
self.app.bypass_security_cb
|
||||
]
|
||||
self.app.accurate_size_btn.config(state="disabled")
|
||||
for cb in checkboxes:
|
||||
cb.config(state="disabled")
|
||||
|
||||
@@ -512,7 +500,6 @@ class Actions:
|
||||
if self.app.accurate_calculation_running:
|
||||
app_logger.log("Accurate size calculation cancelled by user.")
|
||||
self.app.accurate_calculation_running = False
|
||||
self.app.genaue_berechnung_var.set(False)
|
||||
|
||||
self.app.animated_icon.stop("DISABLE")
|
||||
if self.app.left_canvas_animation:
|
||||
|
||||
@@ -126,17 +126,17 @@ class AdvancedSettingsFrame(ttk.Frame):
|
||||
self.no_trash_bin_var = tk.BooleanVar()
|
||||
|
||||
self.full_backup_checkbutton = ttk.Checkbutton(self.backup_defaults_frame, text=Msg.STR["force_full_backup"], variable=self.force_full_var, command=lambda: enforce_backup_type_exclusivity(
|
||||
self.force_full_var, self.force_incremental_var, self.force_full_var.get()))
|
||||
self.force_full_var, self.force_incremental_var, self.force_full_var.get()), style="Switch.TCheckbutton")
|
||||
self.full_backup_checkbutton.pack(anchor=tk.W)
|
||||
|
||||
self.incremental_checkbutton = ttk.Checkbutton(self.backup_defaults_frame, text=Msg.STR["force_incremental_backup"], variable=self.force_incremental_var, command=lambda: enforce_backup_type_exclusivity(
|
||||
self.force_incremental_var, self.force_full_var, self.force_incremental_var.get()))
|
||||
self.force_incremental_var, self.force_full_var, self.force_incremental_var.get()), style="Switch.TCheckbutton")
|
||||
self.incremental_checkbutton.pack(anchor=tk.W)
|
||||
|
||||
self.compression_checkbutton = ttk.Checkbutton(self.backup_defaults_frame, text=Msg.STR["force_compression"], variable=self.force_compression_var, command=self._on_compression_toggle)
|
||||
self.compression_checkbutton = ttk.Checkbutton(self.backup_defaults_frame, text=Msg.STR["force_compression"], variable=self.force_compression_var, command=self._on_compression_toggle, style="Switch.TCheckbutton")
|
||||
self.compression_checkbutton.pack(anchor=tk.W)
|
||||
|
||||
self.encryption_checkbutton = ttk.Checkbutton(self.backup_defaults_frame, text=Msg.STR["force_encryption"], variable=self.force_encryption_var)
|
||||
self.encryption_checkbutton = ttk.Checkbutton(self.backup_defaults_frame, text=Msg.STR["force_encryption"], variable=self.force_encryption_var, style="Switch.TCheckbutton")
|
||||
self.encryption_checkbutton.pack(anchor=tk.W)
|
||||
|
||||
ttk.Separator(self.backup_defaults_frame, orient=tk.HORIZONTAL).pack(fill=tk.X, pady=10)
|
||||
@@ -145,9 +145,9 @@ class AdvancedSettingsFrame(ttk.Frame):
|
||||
trash_info_label.pack(anchor=tk.W, pady=5)
|
||||
|
||||
ttk.Checkbutton(self.backup_defaults_frame, text=Msg.STR["use_trash_bin"], variable=self.use_trash_bin_var, command=lambda: self._handle_trash_checkbox_click(
|
||||
self.use_trash_bin_var, self.no_trash_bin_var)).pack(anchor=tk.W)
|
||||
self.use_trash_bin_var, self.no_trash_bin_var), style="Switch.TCheckbutton").pack(anchor=tk.W)
|
||||
ttk.Checkbutton(self.backup_defaults_frame, text=Msg.STR["no_trash_bin"], variable=self.no_trash_bin_var, command=lambda: self._handle_trash_checkbox_click(
|
||||
self.no_trash_bin_var, self.use_trash_bin_var)).pack(anchor=tk.W)
|
||||
self.no_trash_bin_var, self.use_trash_bin_var), style="Switch.TCheckbutton").pack(anchor=tk.W)
|
||||
|
||||
ttk.Separator(self.backup_defaults_frame, orient=tk.HORIZONTAL).pack(fill=tk.X, pady=10)
|
||||
|
||||
@@ -546,4 +546,4 @@ class AdvancedSettingsFrame(ttk.Frame):
|
||||
user_patterns.extend(
|
||||
[line.strip() for line in f if line.strip() and not line.startswith('#')])
|
||||
|
||||
return generated_patterns, user_patterns
|
||||
return generated_patterns, user_patterns
|
||||
|
||||
@@ -112,8 +112,6 @@ class Navigation:
|
||||
self.app.encrypted_cb.config(state="normal")
|
||||
self.app.bypass_security_cb.config(
|
||||
state='disabled') # This one is mode-dependent
|
||||
# Let the central config function handle the state of these checkboxes
|
||||
self.app.update_backup_options_from_config()
|
||||
else: # restore
|
||||
self.app.source_size_frame.grid_remove()
|
||||
self.app.target_size_frame.grid_remove()
|
||||
|
||||
@@ -53,13 +53,20 @@ class SchedulerFrame(ttk.Frame):
|
||||
}
|
||||
self.frequency = tk.StringVar(value="daily")
|
||||
|
||||
self.backup_type_system_var = tk.BooleanVar(value=True)
|
||||
self.backup_type_user_var = tk.BooleanVar(value=False)
|
||||
|
||||
self.freq_daily_var = tk.BooleanVar(value=True)
|
||||
self.freq_weekly_var = tk.BooleanVar(value=False)
|
||||
self.freq_monthly_var = tk.BooleanVar(value=False)
|
||||
|
||||
type_frame = ttk.LabelFrame(
|
||||
self.add_job_frame, text=Msg.STR["backup_type"], padding=10)
|
||||
type_frame.pack(fill=tk.X, padx=5, pady=5)
|
||||
ttk.Radiobutton(type_frame, text=Msg.STR["system_backup_menu"], variable=self.backup_type,
|
||||
value="system", command=self._toggle_user_sources).pack(anchor=tk.W)
|
||||
ttk.Radiobutton(type_frame, text=Msg.STR["user_backup_menu"], variable=self.backup_type,
|
||||
value="user", command=self._toggle_user_sources).pack(anchor=tk.W)
|
||||
ttk.Checkbutton(type_frame, text=Msg.STR["system_backup_menu"], variable=self.backup_type_system_var,
|
||||
style="Switch.TCheckbutton", command=lambda: self._handle_backup_type_switch("system")).pack(anchor=tk.W)
|
||||
ttk.Checkbutton(type_frame, text=Msg.STR["user_backup_menu"], variable=self.backup_type_user_var,
|
||||
style="Switch.TCheckbutton", command=lambda: self._handle_backup_type_switch("user")).pack(anchor=tk.W)
|
||||
|
||||
# Container for source folders and backup options
|
||||
source_options_container = ttk.Frame(self.add_job_frame)
|
||||
@@ -72,7 +79,7 @@ class SchedulerFrame(ttk.Frame):
|
||||
self.user_sources_frame.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)
|
||||
for name, var in self.user_sources.items():
|
||||
ttk.Checkbutton(self.user_sources_frame, text=name,
|
||||
variable=var).pack(anchor=tk.W)
|
||||
variable=var, style="Switch.TCheckbutton").pack(anchor=tk.W)
|
||||
|
||||
options_frame = ttk.LabelFrame(
|
||||
source_options_container, text=Msg.STR["backup_options"], padding=10)
|
||||
@@ -83,13 +90,13 @@ class SchedulerFrame(ttk.Frame):
|
||||
self.compress_var = tk.BooleanVar(value=False)
|
||||
self.encrypt_var = tk.BooleanVar(value=False)
|
||||
|
||||
self.full_checkbutton = ttk.Checkbutton(options_frame, text=Msg.STR["full_backup"], variable=self.full_var, command=lambda: enforce_backup_type_exclusivity(self.full_var, self.incremental_var, self.full_var.get()))
|
||||
self.full_checkbutton = ttk.Checkbutton(options_frame, text=Msg.STR["full_backup"], variable=self.full_var, command=lambda: enforce_backup_type_exclusivity(self.full_var, self.incremental_var, self.full_var.get()), style="Switch.TCheckbutton")
|
||||
self.full_checkbutton.pack(anchor=tk.W)
|
||||
self.incremental_checkbutton = ttk.Checkbutton(options_frame, text=Msg.STR["incremental_backup"], variable=self.incremental_var, command=lambda: enforce_backup_type_exclusivity(self.incremental_var, self.full_var, self.incremental_var.get()))
|
||||
self.incremental_checkbutton = ttk.Checkbutton(options_frame, text=Msg.STR["incremental_backup"], variable=self.incremental_var, command=lambda: enforce_backup_type_exclusivity(self.incremental_var, self.full_var, self.incremental_var.get()), style="Switch.TCheckbutton")
|
||||
self.incremental_checkbutton.pack(anchor=tk.W)
|
||||
self.compress_checkbutton = ttk.Checkbutton(options_frame, text=Msg.STR["compression"], variable=self.compress_var, command=self._on_compression_toggle_scheduler)
|
||||
self.compress_checkbutton = ttk.Checkbutton(options_frame, text=Msg.STR["compression"], variable=self.compress_var, command=self._on_compression_toggle_scheduler, style="Switch.TCheckbutton")
|
||||
self.compress_checkbutton.pack(anchor=tk.W)
|
||||
self.encrypt_checkbutton = ttk.Checkbutton(options_frame, text=Msg.STR["encryption"], variable=self.encrypt_var)
|
||||
self.encrypt_checkbutton = ttk.Checkbutton(options_frame, text=Msg.STR["encryption"], variable=self.encrypt_var, style="Switch.TCheckbutton")
|
||||
self.encrypt_checkbutton.pack(anchor=tk.W)
|
||||
|
||||
dest_frame = ttk.LabelFrame(
|
||||
@@ -103,12 +110,12 @@ class SchedulerFrame(ttk.Frame):
|
||||
freq_frame = ttk.LabelFrame(
|
||||
self.add_job_frame, text=Msg.STR["frequency"], padding=10)
|
||||
freq_frame.pack(fill=tk.X, padx=5, pady=5)
|
||||
ttk.Radiobutton(freq_frame, text=Msg.STR["freq_daily"],
|
||||
variable=self.frequency, value="daily").pack(anchor=tk.W)
|
||||
ttk.Radiobutton(freq_frame, text=Msg.STR["freq_weekly"],
|
||||
variable=self.frequency, value="weekly").pack(anchor=tk.W)
|
||||
ttk.Radiobutton(freq_frame, text=Msg.STR["freq_monthly"],
|
||||
variable=self.frequency, value="monthly").pack(anchor=tk.W)
|
||||
ttk.Checkbutton(freq_frame, text=Msg.STR["freq_daily"], variable=self.freq_daily_var,
|
||||
style="Switch.TCheckbutton", command=lambda: self._handle_freq_switch("daily")).pack(anchor=tk.W)
|
||||
ttk.Checkbutton(freq_frame, text=Msg.STR["freq_weekly"], variable=self.freq_weekly_var,
|
||||
style="Switch.TCheckbutton", command=lambda: self._handle_freq_switch("weekly")).pack(anchor=tk.W)
|
||||
ttk.Checkbutton(freq_frame, text=Msg.STR["freq_monthly"], variable=self.freq_monthly_var,
|
||||
style="Switch.TCheckbutton", command=lambda: self._handle_freq_switch("monthly")).pack(anchor=tk.W)
|
||||
|
||||
add_button_frame = ttk.Frame(self.add_job_frame)
|
||||
add_button_frame.pack(pady=10)
|
||||
@@ -123,6 +130,33 @@ class SchedulerFrame(ttk.Frame):
|
||||
# Initially, hide the add_job_frame
|
||||
self.add_job_frame.pack_forget()
|
||||
|
||||
def _handle_backup_type_switch(self, changed_var):
|
||||
if changed_var == "system":
|
||||
if self.backup_type_system_var.get():
|
||||
self.backup_type_user_var.set(False)
|
||||
self.backup_type.set("system")
|
||||
else:
|
||||
# Prevent unsetting both
|
||||
self.backup_type_system_var.set(True)
|
||||
elif changed_var == "user":
|
||||
if self.backup_type_user_var.get():
|
||||
self.backup_type_system_var.set(False)
|
||||
self.backup_type.set("user")
|
||||
else:
|
||||
self.backup_type_user_var.set(True)
|
||||
self._toggle_user_sources()
|
||||
|
||||
def _handle_freq_switch(self, changed_var):
|
||||
vars = {"daily": self.freq_daily_var, "weekly": self.freq_weekly_var, "monthly": self.freq_monthly_var}
|
||||
if vars[changed_var].get():
|
||||
self.frequency.set(changed_var)
|
||||
for var_name, var_obj in vars.items():
|
||||
if var_name != changed_var:
|
||||
var_obj.set(False)
|
||||
else:
|
||||
# Prevent unsetting all
|
||||
vars[changed_var].set(True)
|
||||
|
||||
def show(self):
|
||||
self.grid(row=2, column=0, sticky="nsew")
|
||||
self._load_scheduled_jobs()
|
||||
@@ -255,4 +289,4 @@ class SchedulerFrame(ttk.Frame):
|
||||
|
||||
job_id = self.jobs_tree.item(selected_item)["values"][0]
|
||||
self.backup_manager.remove_scheduled_job(job_id)
|
||||
self._load_scheduled_jobs()
|
||||
self._load_scheduled_jobs()
|
||||
Reference in New Issue
Block a user