add settings for animation select
This commit is contained in:
Binary file not shown.
@@ -195,6 +195,9 @@ class Msg:
|
||||
"backup_mode_info": _("Backup Mode: You can start a backup here."),
|
||||
"restore_mode_info": _("Restore Mode: You can start a restore here."),
|
||||
"advanced_settings_title": _("Advanced Settings"),
|
||||
"animation_settings_title": _("Animation Settings"),
|
||||
"backup_animation_label": _("Backup/Restore Animation:"),
|
||||
"calc_animation_label": _("Size Calculation Animation:"),
|
||||
"advanced_settings_warning": _("WARNING: Changing these settings is recommended for experienced users only. Incorrect configurations can lead to an unreliable backup.\n\nThe backup destination is always excluded for security reasons and cannot be changed here."),
|
||||
"exclude_system_folders": _("Exclude system folders"),
|
||||
"in_backup": _("In Backup"),
|
||||
|
||||
@@ -309,8 +309,11 @@ class MainApplication(tk.Tk):
|
||||
# Explicitly get the theme's background color for the canvas
|
||||
bg_color = self.style.lookup('TFrame', 'background')
|
||||
|
||||
# Get the animation type from settings, with a default
|
||||
animation_type = self.config_manager.get_setting("backup_animation_type", "counter_arc")
|
||||
|
||||
self.animated_icon = AnimatedIcon(
|
||||
self.action_frame, width=20, height=20, use_pillow=True, bg=bg_color)
|
||||
self.action_frame, width=20, height=20, use_pillow=True, bg=bg_color, animation_type=animation_type)
|
||||
self.animated_icon.pack(side=tk.LEFT, padx=5)
|
||||
self.animated_icon.stop("DISABLE")
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -78,10 +78,13 @@ class Actions:
|
||||
}
|
||||
self.app.drawing.redraw_left_canvas()
|
||||
|
||||
# Get the animation type from settings, with a default
|
||||
animation_type = self.app.config_manager.get_setting("calculation_animation_type", "double_arc")
|
||||
|
||||
if self.app.calculating_animation:
|
||||
self.app.calculating_animation.destroy()
|
||||
self.app.calculating_animation = AnimatedIcon(
|
||||
self.app.left_canvas, width=20, height=20, animation_type="counter_arc", use_pillow=True)
|
||||
self.app.left_canvas, width=20, height=20, animation_type=animation_type, use_pillow=True)
|
||||
self.app.calculating_animation.start()
|
||||
self.app.drawing.redraw_left_canvas()
|
||||
|
||||
|
||||
@@ -7,17 +7,16 @@ import fnmatch
|
||||
from app_config import AppConfig, Msg
|
||||
|
||||
class AdvancedSettingsFrame(tk.Toplevel):
|
||||
def __init__(self, master, **kwargs):
|
||||
def __init__(self, master, config_manager, app_instance, **kwargs):
|
||||
super().__init__(master, **kwargs)
|
||||
|
||||
self.title(Msg.STR["advanced_settings_title"])
|
||||
self.geometry("800x600")
|
||||
|
||||
self.app_config = AppConfig()
|
||||
self.config_manager = config_manager
|
||||
self.app_instance = app_instance
|
||||
|
||||
# --- Warning Label ---
|
||||
warning_label = ttk.Label(self, text=Msg.STR["advanced_settings_warning"], wraplength=780, justify="center")
|
||||
warning_label.pack(pady=10)
|
||||
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)
|
||||
@@ -33,6 +32,24 @@ class AdvancedSettingsFrame(tk.Toplevel):
|
||||
|
||||
self.tree.bind("<Button-1>", self._toggle_include_status)
|
||||
|
||||
# --- Animation Settings ---
|
||||
animation_frame = ttk.LabelFrame(self, text="Animationseinstellungen", 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)
|
||||
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.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)
|
||||
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.grid(row=1, column=1, sticky="ew", padx=5)
|
||||
|
||||
animation_frame.columnconfigure(1, weight=1)
|
||||
|
||||
# --- Action Buttons ---
|
||||
button_frame = ttk.Frame(self)
|
||||
button_frame.pack(pady=10)
|
||||
@@ -41,9 +58,15 @@ class AdvancedSettingsFrame(tk.Toplevel):
|
||||
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()
|
||||
|
||||
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")
|
||||
self.backup_anim_var.set(backup_anim)
|
||||
self.calc_anim_var.set(calc_anim)
|
||||
|
||||
def _load_system_folders(self):
|
||||
# Clear existing items
|
||||
for i in self.tree.get_children():
|
||||
self.tree.delete(i)
|
||||
|
||||
@@ -52,66 +75,50 @@ class AdvancedSettingsFrame(tk.Toplevel):
|
||||
"/tmp", "/dev", "/run", "/mnt", "/proc", "/media", "/cdrom", "/var",
|
||||
"/sbin.usr-is-merged", "/bin.usr-is-merged", "/lib.usr-is-merged", "/boot"
|
||||
]
|
||||
|
||||
# Add patterns from standard exclude content
|
||||
always_exclude.extend(AppConfig.STANDARD_EXCLUDE_CONTENT.splitlines())
|
||||
|
||||
# Load user exclude patterns
|
||||
_, user_patterns = self._load_exclude_patterns()
|
||||
items_to_display = {}
|
||||
|
||||
items_to_display = {} # Use a dictionary to avoid duplicates and easily manage items
|
||||
|
||||
# Add root directories
|
||||
root_dir = Path("/")
|
||||
for item in root_dir.iterdir():
|
||||
if item.is_dir():
|
||||
item_path_str = str(item.absolute())
|
||||
if item_path_str in always_exclude or f"{item_path_str}/*" in always_exclude:
|
||||
continue # Skip always excluded items
|
||||
|
||||
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)
|
||||
|
||||
# Explicitly add or update the backup destination's root
|
||||
app_instance = self.master.master.master # Assuming master is SettingsFrame, master.master is content_frame, master.master.master is MainApplication
|
||||
if app_instance.destination_path:
|
||||
backup_root_path = Path(f"/{app_instance.destination_path.strip('/').split('/')[0]}")
|
||||
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_str = str(backup_root_path.absolute())
|
||||
|
||||
# Set the backup destination to be always excluded
|
||||
items_to_display[backup_root_path_str] = (Msg.STR["no"], backup_root_path.name, backup_root_path_str)
|
||||
|
||||
# Insert items into the treeview
|
||||
for item_path_str in sorted(items_to_display.keys()):
|
||||
tags = ()
|
||||
if app_instance.destination_path and item_path_str == str(Path(f"/{app_instance.destination_path.strip('/').split('/')[0]}").absolute()):
|
||||
tags = ("backup_dest_exclude",) # Add tag for backup destination
|
||||
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)
|
||||
|
||||
def _toggle_include_status(self, event):
|
||||
item_id = self.tree.identify_row(event.y)
|
||||
if not item_id:
|
||||
return
|
||||
|
||||
# Check if the item is the backup destination exclude
|
||||
if "backup_dest_exclude" in self.tree.item(item_id, "tags"):
|
||||
return # Do nothing if it's the backup destination exclude
|
||||
|
||||
return
|
||||
current_values = self.tree.item(item_id, 'values')
|
||||
current_status = current_values[0]
|
||||
new_status = Msg.STR["yes"] if current_status == Msg.STR["no"] else Msg.STR["no"]
|
||||
|
||||
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]))
|
||||
|
||||
def _apply_changes(self):
|
||||
# Get all paths displayed in the tree
|
||||
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())
|
||||
|
||||
tree_paths = set()
|
||||
for item_id in self.tree.get_children():
|
||||
values = self.tree.item(item_id, 'values')
|
||||
tree_paths.add(values[2])
|
||||
|
||||
# Get the new excludes from the tree
|
||||
new_excludes = []
|
||||
for item_id in self.tree.get_children():
|
||||
values = self.tree.item(item_id, 'values')
|
||||
@@ -122,27 +129,21 @@ class AdvancedSettingsFrame(tk.Toplevel):
|
||||
else:
|
||||
new_excludes.append(path)
|
||||
|
||||
# Load existing patterns
|
||||
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('#')]
|
||||
|
||||
# Preserve patterns that are not managed by this view
|
||||
preserved_patterns = []
|
||||
for pattern in existing_patterns:
|
||||
# A bit tricky to match pattern to tree_paths, this is a simplification
|
||||
# This assumes patterns are in the form of /path/* or /path
|
||||
clean_pattern = pattern.replace('/*', '')
|
||||
if clean_pattern not in tree_paths:
|
||||
preserved_patterns.append(pattern)
|
||||
|
||||
# Combine preserved patterns with new excludes from this view
|
||||
final_excludes = list(set(preserved_patterns + new_excludes))
|
||||
|
||||
# Handle backup destination separately to ensure it's always excluded
|
||||
if self.master.master.master.destination_path:
|
||||
backup_root_to_exclude = f"/{self.master.master.master.destination_path.strip('/').split('/')[0]}/*"
|
||||
if self.app_instance and self.app_instance.destination_path:
|
||||
backup_root_to_exclude = f"/{self.app_instance.destination_path.strip('/').split('/')[0]}/*"
|
||||
if backup_root_to_exclude not in final_excludes:
|
||||
final_excludes.append(backup_root_to_exclude)
|
||||
|
||||
@@ -152,10 +153,10 @@ class AdvancedSettingsFrame(tk.Toplevel):
|
||||
|
||||
self.destroy()
|
||||
|
||||
# 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)
|
||||
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)
|
||||
|
||||
def _load_exclude_patterns(self):
|
||||
generated_patterns = []
|
||||
|
||||
@@ -205,7 +205,11 @@ class SettingsFrame(ttk.Frame):
|
||||
self.master.master.master.actions.on_sidebar_button_click(current_source)
|
||||
|
||||
def _open_advanced_settings(self):
|
||||
advanced_settings_window = AdvancedSettingsFrame(self.master)
|
||||
advanced_settings_window = AdvancedSettingsFrame(
|
||||
self.master,
|
||||
config_manager=self.master.master.master.config_manager,
|
||||
app_instance=self.master.master.master
|
||||
)
|
||||
advanced_settings_window.grab_set()
|
||||
|
||||
def _toggle_hidden_files_view(self):
|
||||
|
||||
Reference in New Issue
Block a user