add colors on settings treeview, fix update view after default settings on hide files

This commit is contained in:
2025-08-27 11:31:30 +02:00
parent bd947bd80e
commit 1b4fcc8a1c
8 changed files with 171 additions and 89 deletions

View File

@@ -20,7 +20,7 @@ class Actions:
def _check_for_first_backup(self):
# This logic only applies if no override from advanced settings is active
if self.app.full_backup_cb.cget('state') != 'normal':
self.app.is_first_backup = False # Ensure this is reset if controls are disabled
self.app.is_first_backup = False # Ensure this is reset if controls are disabled
return
# A "first backup" situation exists if the destination is selected but empty.
@@ -48,7 +48,8 @@ class Actions:
def on_sidebar_button_click(self, button_text):
self.app.drawing.reset_projection_canvases()
if not self.app.canvas_frame.winfo_viewable():
self.app.navigation.toggle_mode(self.app.mode, trigger_calculation=False)
self.app.navigation.toggle_mode(
self.app.mode, trigger_calculation=False)
self.app.log_window.clear_log()
folder_path = AppConfig.FOLDER_PATHS.get(button_text)
@@ -73,16 +74,17 @@ class Actions:
if button_text == "Computer":
if self.app.mode == 'backup':
extra_info = Msg.STR["system_backup_info"]
else: # restore
else: # restore
extra_info = Msg.STR["system_restore_info"]
else: # User folder
else: # User folder
if self.app.mode == 'backup':
extra_info = Msg.STR["user_backup_info"]
else: # restore
else: # restore
extra_info = Msg.STR["user_restore_info"]
# Unified logic for starting a calculation on the left canvas
self._start_left_canvas_calculation(button_text, str(folder_path), icon_name, extra_info)
self._start_left_canvas_calculation(
button_text, str(folder_path), icon_name, extra_info)
def _start_left_canvas_calculation(self, button_text, folder_path, icon_name, extra_info):
self.app.start_pause_button.config(state="disabled")
@@ -126,8 +128,9 @@ class Actions:
if self.app.mode == 'backup':
self._check_for_first_backup()
else: # restore mode
self.app.config_manager.set_setting("restore_destination_path", folder_path)
else: # restore mode
self.app.config_manager.set_setting(
"restore_destination_path", folder_path)
def on_right_canvas_click(self, event):
self.app.drawing.reset_projection_canvases()
@@ -171,11 +174,12 @@ class Actions:
size_str = f"{used / (1024**3):.2f} GB / {total / (1024**3):.2f} GB"
self.app.right_canvas_data.update({
'folder': os.path.basename(path.rstrip('/')),
'folder': os.path.basename(path.rstrip('/')),
'path_display': path,
'size': size_str
})
self.app.config_manager.set_setting("backup_destination_path", path)
self.app.config_manager.set_setting(
"backup_destination_path", path)
self.app.drawing.redraw_right_canvas()
self.app.drawing.update_target_projection()
self.app.start_pause_button.config(state="normal")
@@ -187,11 +191,12 @@ class Actions:
elif self.app.mode == "restore":
self.app.right_canvas_data.update({
'folder': os.path.basename(path.rstrip('/')),
'folder': os.path.basename(path.rstrip('/')),
'path_display': path,
'size': ''
})
self.app.config_manager.set_setting("restore_source_path", path)
self.app.config_manager.set_setting(
"restore_source_path", path)
self.app.drawing.calculate_restore_folder_size()
self.app.start_pause_button.config(state="normal")
@@ -221,22 +226,19 @@ class Actions:
# Update the main UI to reflect the cleared settings
self.app.update_backup_options_from_config()
self.app.backup_left_canvas_data.clear()
self.app.backup_right_canvas_data.clear()
self.app.restore_left_canvas_data.clear()
self.app.restore_right_canvas_data.clear()
AppConfig.generate_and_write_final_exclude_list()
app_logger.log("Settings have been reset to default values.")
settings_frame = self.app.settings_frame
if settings_frame:
settings_frame.load_and_display_excludes()
settings_frame._load_hidden_files()
self.app.destination_path = None
self.app.navigation.initialize_ui_for_mode(self.app.mode)
self.app.start_pause_button.config(state="disabled")
# Clear the canvases and reset the UI to its initial state for the current mode
self.app.drawing.reset_all_canvases()
with message_box_animation(self.app.animated_icon):
MessageDialog(master=self.app, message_type="info",
title=Msg.STR["settings_reset_title"], text=Msg.STR["settings_reset_text"])
@@ -249,10 +251,12 @@ class Actions:
self.app.start_pause_button["text"] = "Pause"
self.app.animated_icon.destroy()
backup_animation_type = self.app.config_manager.get_setting("backup_animation_type", "counter_arc")
backup_animation_type = self.app.config_manager.get_setting(
"backup_animation_type", "counter_arc")
self.app.animated_icon = AnimatedIcon(
self.app.action_frame, width=20, height=20, use_pillow=True, bg=bg_color, animation_type=backup_animation_type)
self.app.animated_icon.pack(side=tk.LEFT, padx=5, before=self.app.task_progress)
self.app.animated_icon.pack(
side=tk.LEFT, padx=5, before=self.app.task_progress)
self.app.animated_icon.start()
if self.app.mode == "backup":
@@ -268,7 +272,8 @@ class Actions:
self.app.animated_icon.destroy()
self.app.animated_icon = AnimatedIcon(
self.app.action_frame, width=20, height=20, use_pillow=True, bg=bg_color, animation_type="blink")
self.app.animated_icon.pack(side=tk.LEFT, padx=5, before=self.app.task_progress)
self.app.animated_icon.pack(
side=tk.LEFT, padx=5, before=self.app.task_progress)
self.app.animated_icon.start()
self.app.backup_manager.pause_backup()
@@ -277,11 +282,13 @@ class Actions:
self.app.start_pause_button["text"] = "Pause"
self.app.animated_icon.destroy()
backup_animation_type = self.app.config_manager.get_setting("backup_animation_type", "counter_arc")
backup_animation_type = self.app.config_manager.get_setting(
"backup_animation_type", "counter_arc")
self.app.animated_icon = AnimatedIcon(
self.app.action_frame, width=20, height=20, use_pillow=True, bg=bg_color, animation_type=backup_animation_type)
self.app.animated_icon.pack(side=tk.LEFT, padx=5, before=self.app.task_progress)
self.app.animated_icon.pack(
side=tk.LEFT, padx=5, before=self.app.task_progress)
self.app.animated_icon.start()
self.app.backup_manager.resume_backup()
@@ -306,7 +313,7 @@ class Actions:
MessageDialog(master=self.app, message_type="error",
title=Msg.STR["error"], text=Msg.STR["system_backup_in_home_error"])
return
exclude_file_paths = []
if AppConfig.GENERATED_EXCLUDE_LIST_PATH.exists():
exclude_file_paths.append(AppConfig.GENERATED_EXCLUDE_LIST_PATH)
@@ -330,4 +337,4 @@ class Actions:
source, dest, False, is_dry_run=is_dry_run, exclude_files=None, on_progress=self.update_task_progress, on_completion=self.on_backup_completion, on_error=self.on_backup_error)
def update_task_progress(self, percentage):
self.app.task_progress["value"] = percentage
self.app.task_progress["value"] = percentage

View File

@@ -8,6 +8,7 @@ from app_config import AppConfig, Msg
from shared_libs.animated_icon import AnimatedIcon
from pyimage_ui.shared_logic import enforce_backup_type_exclusivity
class AdvancedSettingsFrame(tk.Toplevel):
def __init__(self, master, config_manager, app_instance, **kwargs):
super().__init__(master, **kwargs)
@@ -17,46 +18,60 @@ class AdvancedSettingsFrame(tk.Toplevel):
self.app_instance = app_instance
# --- Warning Label ---
warning_label = ttk.Label(self, text=Msg.STR["advanced_settings_warning"], wraplength=780, justify="center")
warning_label = ttk.Label(
self, text=Msg.STR["advanced_settings_warning"], wraplength=780, justify="center")
warning_label.pack(pady=10, fill=tk.X, padx=10)
# --- Treeview for system folder exclusion ---
self.tree_frame = ttk.LabelFrame(self, text=Msg.STR["exclude_system_folders"], padding=10)
self.tree_frame = ttk.LabelFrame(
self, text=Msg.STR["exclude_system_folders"], padding=10)
self.tree_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
columns = ("included", "name", "path")
self.tree = ttk.Treeview(self.tree_frame, columns=columns, show="headings")
self.tree = ttk.Treeview(
self.tree_frame, columns=columns, show="headings")
self.tree.heading("included", text=Msg.STR["in_backup"])
self.tree.heading("name", text=Msg.STR["name"])
self.tree.heading("path", text=Msg.STR["path"])
self.tree.column("path", anchor="center")
self.tree.column("name", anchor="center")
self.tree.column("included", width=100, anchor="center")
self.tree.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
self.tree.tag_configure("backup_dest_exclude", foreground="gray")
self.tree.bind("<Button-1>", self._toggle_include_status)
# --- Animation Settings ---
animation_frame = ttk.LabelFrame(self, text=Msg.STR["animation_settings_title"], padding=10)
animation_frame = ttk.LabelFrame(
self, text=Msg.STR["animation_settings_title"], padding=10)
animation_frame.pack(fill=tk.X, padx=10, pady=5)
animation_types = ["counter_arc", "double_arc", "line", "blink"]
ttk.Label(animation_frame, text=Msg.STR["backup_animation_label"]).grid(row=0, column=0, sticky="w", pady=2)
ttk.Label(animation_frame, text=Msg.STR["backup_animation_label"]).grid(
row=0, column=0, sticky="w", pady=2)
self.backup_anim_var = tk.StringVar()
self.backup_anim_combo = ttk.Combobox(animation_frame, textvariable=self.backup_anim_var, values=animation_types, state="readonly")
self.backup_anim_combo = ttk.Combobox(
animation_frame, textvariable=self.backup_anim_var, values=animation_types, state="readonly")
self.backup_anim_combo.grid(row=0, column=1, sticky="ew", padx=5)
ttk.Label(animation_frame, text=Msg.STR["calc_animation_label"]).grid(row=1, column=0, sticky="w", pady=2)
ttk.Label(animation_frame, text=Msg.STR["calc_animation_label"]).grid(
row=1, column=0, sticky="w", pady=2)
self.calc_anim_var = tk.StringVar()
self.calc_anim_combo = ttk.Combobox(animation_frame, textvariable=self.calc_anim_var, values=animation_types, state="readonly")
self.calc_anim_combo = ttk.Combobox(
animation_frame, textvariable=self.calc_anim_var, values=animation_types, state="readonly")
self.calc_anim_combo.grid(row=1, column=1, sticky="ew", padx=5)
reset_button = ttk.Button(animation_frame, text=Msg.STR["default_settings"], command=self._reset_animation_settings)
reset_button = ttk.Button(
animation_frame, text=Msg.STR["default_settings"], command=self._reset_animation_settings)
reset_button.grid(row=0, column=2, rowspan=2, padx=10)
animation_frame.columnconfigure(1, weight=1)
# --- Backup Default Settings ---
defaults_frame = ttk.LabelFrame(self, text="Backup Defaults", padding=10)
defaults_frame = ttk.LabelFrame(
self, text="Backup Defaults", padding=10)
defaults_frame.pack(fill=tk.X, padx=10, pady=5)
self.force_full_var = tk.BooleanVar()
@@ -64,22 +79,30 @@ class AdvancedSettingsFrame(tk.Toplevel):
self.force_compression_var = tk.BooleanVar()
self.force_encryption_var = tk.BooleanVar()
ttk.Checkbutton(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())).pack(anchor=tk.W)
ttk.Checkbutton(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())).pack(anchor=tk.W)
ttk.Checkbutton(defaults_frame, text=Msg.STR["force_compression"], variable=self.force_compression_var).pack(anchor=tk.W)
ttk.Checkbutton(defaults_frame, text=Msg.STR["force_encryption"], variable=self.force_encryption_var).pack(anchor=tk.W)
ttk.Separator(defaults_frame, orient=tk.HORIZONTAL).pack(fill=tk.X, pady=5)
encryption_note = ttk.Label(defaults_frame, text=Msg.STR["encryption_note_system_backup"], wraplength=750, justify="left")
ttk.Checkbutton(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())).pack(anchor=tk.W)
ttk.Checkbutton(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())).pack(anchor=tk.W)
ttk.Checkbutton(defaults_frame, text=Msg.STR["force_compression"],
variable=self.force_compression_var).pack(anchor=tk.W)
ttk.Checkbutton(defaults_frame, text=Msg.STR["force_encryption"],
variable=self.force_encryption_var).pack(anchor=tk.W)
ttk.Separator(defaults_frame, orient=tk.HORIZONTAL).pack(
fill=tk.X, pady=5)
encryption_note = ttk.Label(
defaults_frame, text=Msg.STR["encryption_note_system_backup"], wraplength=750, justify="left")
encryption_note.pack(anchor=tk.W, pady=5)
# --- Action Buttons ---
button_frame = ttk.Frame(self)
button_frame.pack(pady=10)
ttk.Button(button_frame, text=Msg.STR["apply"], command=self._apply_changes).pack(side=tk.LEFT, padx=5)
ttk.Button(button_frame, text=Msg.STR["cancel"], command=self.destroy).pack(side=tk.LEFT, padx=5)
ttk.Button(button_frame, text=Msg.STR["apply"], command=self._apply_changes).pack(
side=tk.LEFT, padx=5)
ttk.Button(button_frame, text=Msg.STR["cancel"], command=self.destroy).pack(
side=tk.LEFT, padx=5)
self._load_system_folders()
self._load_animation_settings()
@@ -100,14 +123,20 @@ class AdvancedSettingsFrame(tk.Toplevel):
self.app_instance.update_backup_options_from_config()
def _load_backup_defaults(self):
self.force_full_var.set(self.config_manager.get_setting("force_full_backup", False))
self.force_incremental_var.set(self.config_manager.get_setting("force_incremental_backup", False))
self.force_compression_var.set(self.config_manager.get_setting("force_compression", False))
self.force_encryption_var.set(self.config_manager.get_setting("force_encryption", False))
self.force_full_var.set(
self.config_manager.get_setting("force_full_backup", False))
self.force_incremental_var.set(
self.config_manager.get_setting("force_incremental_backup", False))
self.force_compression_var.set(
self.config_manager.get_setting("force_compression", False))
self.force_encryption_var.set(
self.config_manager.get_setting("force_encryption", False))
def _load_animation_settings(self):
backup_anim = self.config_manager.get_setting("backup_animation_type", "counter_arc")
calc_anim = self.config_manager.get_setting("calculation_animation_type", "double_arc")
backup_anim = self.config_manager.get_setting(
"backup_animation_type", "counter_arc")
calc_anim = self.config_manager.get_setting(
"calculation_animation_type", "double_arc")
self.backup_anim_var.set(backup_anim)
self.calc_anim_var.set(calc_anim)
@@ -132,18 +161,26 @@ class AdvancedSettingsFrame(tk.Toplevel):
continue
is_user_excluded = f"{item_path_str}/*" in user_patterns
included_text = Msg.STR["no"] if is_user_excluded else Msg.STR["yes"]
items_to_display[item_path_str] = (included_text, item.name, item_path_str)
items_to_display[item_path_str] = (
included_text, item.name, item_path_str)
if self.app_instance and self.app_instance.destination_path:
backup_root_path = Path(f"/{self.app_instance.destination_path.strip('/').split('/')[0]}")
backup_root_path = Path(
f"/{self.app_instance.destination_path.strip('/').split('/')[0]}")
backup_root_path_str = str(backup_root_path.absolute())
items_to_display[backup_root_path_str] = (Msg.STR["no"], backup_root_path.name, backup_root_path_str)
items_to_display[backup_root_path_str] = (
Msg.STR["no"], backup_root_path.name, backup_root_path_str)
for item_path_str in sorted(items_to_display.keys()):
tags = ()
item_values = items_to_display[item_path_str]
tag = "yes" if item_values[0] == Msg.STR["yes"] else "no"
# Special tag for the backup destination, which is always excluded and read-only
if self.app_instance and self.app_instance.destination_path and item_path_str == str(Path(f"/{self.app_instance.destination_path.strip('/').split('/')[0]}").absolute()):
tags = ("backup_dest_exclude",)
self.tree.insert("", "end", values=items_to_display[item_path_str], tags=tags)
tags = ("backup_dest_exclude", tag)
else:
tags = (tag,)
self.tree.insert("", "end", values=item_values, tags=tags)
def _toggle_include_status(self, event):
item_id = self.tree.identify_row(event.y)
@@ -153,15 +190,25 @@ class AdvancedSettingsFrame(tk.Toplevel):
return
current_values = self.tree.item(item_id, 'values')
new_status = Msg.STR["yes"] if current_values[0] == Msg.STR["no"] else Msg.STR["no"]
self.tree.item(item_id, values=(new_status, current_values[1], current_values[2]))
new_tag = "yes" if new_status == Msg.STR["yes"] else "no"
self.tree.item(item_id, values=(
new_status, current_values[1], current_values[2]), tags=(new_tag,))
def _apply_changes(self):
self.config_manager.set_setting("backup_animation_type", self.backup_anim_var.get())
self.config_manager.set_setting("calculation_animation_type", self.calc_anim_var.get())
self.config_manager.set_setting("force_full_backup", self.force_full_var.get())
self.config_manager.set_setting("force_incremental_backup", self.force_incremental_var.get())
self.config_manager.set_setting("force_compression", self.force_compression_var.get())
self.config_manager.set_setting("force_encryption", self.force_encryption_var.get())
self.config_manager.set_setting(
"backup_animation_type", self.backup_anim_var.get())
self.config_manager.set_setting(
"calculation_animation_type", self.calc_anim_var.get())
self.config_manager.set_setting(
"force_full_backup", self.force_full_var.get())
self.config_manager.set_setting(
"force_incremental_backup", self.force_incremental_var.get())
self.config_manager.set_setting(
"force_compression", self.force_compression_var.get())
self.config_manager.set_setting(
"force_encryption", self.force_encryption_var.get())
if self.app_instance:
self.app_instance.update_backup_options_from_config()
@@ -171,17 +218,18 @@ class AdvancedSettingsFrame(tk.Toplevel):
# Create a new one
bg_color = self.app_instance.style.lookup('TFrame', 'background')
backup_animation_type = self.backup_anim_var.get()
initial_animation_type = "blink"
if backup_animation_type == "line":
initial_animation_type = "line"
self.app_instance.animated_icon = AnimatedIcon(
self.app_instance.action_frame, width=20, height=20, use_pillow=True, bg=bg_color, animation_type=initial_animation_type)
# Pack it in the correct order
self.app_instance.animated_icon.pack(side=tk.LEFT, padx=5, before=self.app_instance.task_progress)
self.app_instance.animated_icon.pack(
side=tk.LEFT, padx=5, before=self.app_instance.task_progress)
# Set the correct state
self.app_instance.animated_icon.stop("DISABLE")
self.app_instance.animated_icon.animation_type = backup_animation_type
@@ -204,7 +252,8 @@ class AdvancedSettingsFrame(tk.Toplevel):
existing_patterns = []
if AppConfig.USER_EXCLUDE_LIST_PATH.exists():
with open(AppConfig.USER_EXCLUDE_LIST_PATH, 'r') as f:
existing_patterns = [line.strip() for line in f if line.strip() and not line.startswith('#')]
existing_patterns = [
line.strip() for line in f if line.strip() and not line.startswith('#')]
preserved_patterns = []
for pattern in existing_patterns:
@@ -222,23 +271,26 @@ class AdvancedSettingsFrame(tk.Toplevel):
with open(AppConfig.USER_EXCLUDE_LIST_PATH, 'w') as f:
for path in final_excludes:
f.write(f"{path}\n")
self.destroy()
if self.app_instance:
current_source = self.app_instance.left_canvas_data.get('folder')
if current_source:
self.app_instance.actions.on_sidebar_button_click(current_source)
self.app_instance.actions.on_sidebar_button_click(
current_source)
def _load_exclude_patterns(self):
generated_patterns = []
if AppConfig.GENERATED_EXCLUDE_LIST_PATH.exists():
with open(AppConfig.GENERATED_EXCLUDE_LIST_PATH, 'r') as f:
generated_patterns = [line.strip() for line in f if line.strip() and not line.startswith('#')]
generated_patterns = [
line.strip() for line in f if line.strip() and not line.startswith('#')]
user_patterns = []
if AppConfig.USER_EXCLUDE_LIST_PATH.exists():
with open(AppConfig.USER_EXCLUDE_LIST_PATH, 'r') as f:
user_patterns = [line.strip() for line in f if line.strip() and not line.startswith('#')]
user_patterns = [
line.strip() for line in f if line.strip() and not line.startswith('#')]
return generated_patterns, user_patterns

View File

@@ -392,3 +392,12 @@ class Drawing:
# Also reset the main info label
self.app.info_label.config(text="")
def reset_all_canvases(self):
self.reset_projection_canvases()
self.app.left_canvas.delete("all")
self.app.right_canvas.delete("all")
self.app.left_canvas_data.clear()
self.app.right_canvas_data.clear()
self.redraw_left_canvas()
self.redraw_right_canvas()

View File

@@ -33,6 +33,10 @@ class SettingsFrame(ttk.Frame):
self.tree.heading("included", text=Msg.STR["in_backup"])
self.tree.heading("name", text=Msg.STR["name"])
self.tree.heading("path", text=Msg.STR["path"])
self.tree.tag_configure("yes", background="#89b4fe")
self.tree.tag_configure("no", background="#4c92ed")
self.tree.column("included", width=100, anchor="center")
self.tree.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
@@ -46,8 +50,13 @@ class SettingsFrame(ttk.Frame):
self.hidden_tree.heading("included", text=Msg.STR["in_backup"])
self.hidden_tree.heading("name", text=Msg.STR["name"])
self.hidden_tree.heading("path", text=Msg.STR["path"])
self.hidden_tree.column("included", width=100, anchor="center")
self.hidden_tree.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
self.hidden_tree.tag_configure("yes", background="#89b4fe")
self.hidden_tree.tag_configure("no", background="#4c92ed")
self.hidden_tree.bind("<Button-1>", self._toggle_include_status_hidden)
self.hidden_tree_frame.pack_forget() # Initially hidden
@@ -126,7 +135,8 @@ class SettingsFrame(ttk.Frame):
items_to_display.sort(key=lambda x: x[0], reverse=True)
for item in items_to_display:
self.tree.insert("", "end", values=item)
tag = "yes" if item[0] == Msg.STR["yes"] else "no"
self.tree.insert("", "end", values=item, tags=(tag,))
def _toggle_include_status(self, event):
item_id = self.tree.identify_row(event.y)
@@ -137,8 +147,10 @@ class SettingsFrame(ttk.Frame):
current_status = current_values[0]
new_status = Msg.STR["yes"] if current_status == Msg.STR["no"] else Msg.STR["no"]
new_tag = "yes" if new_status == Msg.STR["yes"] else "no"
self.tree.item(item_id, values=(
new_status, current_values[1], current_values[2]))
new_status, current_values[1], current_values[2]), tags=(new_tag,))
def _apply_changes(self):
# Get all paths displayed in the treeviews
@@ -175,7 +187,8 @@ class SettingsFrame(ttk.Frame):
existing_patterns = []
if AppConfig.USER_EXCLUDE_LIST_PATH.exists():
with open(AppConfig.USER_EXCLUDE_LIST_PATH, 'r') as f:
existing_patterns = [line.strip() for line in f if line.strip() and not line.startswith('#')]
existing_patterns = [
line.strip() for line in f if line.strip() and not line.startswith('#')]
# Preserve patterns that are not managed by this view
preserved_patterns = []
@@ -196,18 +209,16 @@ class SettingsFrame(ttk.Frame):
with open(AppConfig.USER_EXCLUDE_LIST_PATH, 'w') as f:
for path in final_excludes:
f.write(f"{path}\n")
self.hide()
# Trigger recalculation
current_source = self.master.master.master.left_canvas_data.get('folder')
if current_source:
self.master.master.master.actions.on_sidebar_button_click(current_source)
# Reload the excludes to show the changes
self.load_and_display_excludes()
if self.hidden_files_visible:
self._load_hidden_files()
def _open_advanced_settings(self):
advanced_settings_window = AdvancedSettingsFrame(
self.master,
config_manager=self.master.master.master.config_manager,
self.master,
config_manager=self.master.master.master.config_manager,
app_instance=self.master.master.master
)
advanced_settings_window.grab_set()
@@ -246,7 +257,8 @@ class SettingsFrame(ttk.Frame):
items_to_display.sort(key=lambda x: x[1])
for item in items_to_display:
self.hidden_tree.insert("", "end", values=item)
tag = "yes" if item[0] == Msg.STR["yes"] else "no"
self.hidden_tree.insert("", "end", values=item, tags=(tag,))
def _toggle_include_status_hidden(self, event):
item_id = self.hidden_tree.identify_row(event.y)
@@ -257,5 +269,7 @@ class SettingsFrame(ttk.Frame):
current_status = current_values[0]
new_status = Msg.STR["yes"] if current_status == Msg.STR["no"] else Msg.STR["no"]
new_tag = "yes" if new_status == Msg.STR["yes"] else "no"
self.hidden_tree.item(item_id, values=(
new_status, current_values[1], current_values[2]))
new_status, current_values[1], current_values[2]), tags=(new_tag,))