The `CustomFileDialog` class had become too large and complex, making it difficult to maintain. This change refactors the monolithic class into several specialized manager classes, each responsible for a specific area of concern: - `SettingsDialog`: Moved to its own file, `cfd_settings_dialog.py`. - `FileOperationsManager`: Handles file/folder creation, deletion, and renaming. - `SearchManager`: Encapsulates all search-related logic. - `NavigationManager`: Manages directory navigation and history. - `ViewManager`: Controls the rendering of file and folder views. The main `CustomFileDialog` class has been streamlined and now acts as an orchestrator for these managers. This improves readability, separation of concerns, and the overall maintainability of the code.
174 lines
8.4 KiB
Python
174 lines
8.4 KiB
Python
import tkinter as tk
|
|
from tkinter import ttk
|
|
from cfd_app_config import CfdConfigManager
|
|
from cfd_animated_icon import PIL_AVAILABLE
|
|
|
|
try:
|
|
import send2trash
|
|
SEND2TRASH_AVAILABLE = True
|
|
except ImportError:
|
|
SEND2TRASH_AVAILABLE = False
|
|
|
|
|
|
class SettingsDialog(tk.Toplevel):
|
|
def __init__(self, parent, dialog_mode="save"):
|
|
super().__init__(parent)
|
|
self.transient(parent)
|
|
self.grab_set()
|
|
self.title("Einstellungen")
|
|
|
|
self.settings = CfdConfigManager.load()
|
|
self.dialog_mode = dialog_mode
|
|
|
|
# Variables
|
|
self.search_icon_pos = tk.StringVar(
|
|
value=self.settings.get("search_icon_pos", "right"))
|
|
self.button_box_pos = tk.StringVar(
|
|
value=self.settings.get("button_box_pos", "left"))
|
|
self.window_size_preset = tk.StringVar(
|
|
value=self.settings.get("window_size_preset", "1050x850"))
|
|
self.default_view_mode = tk.StringVar(
|
|
value=self.settings.get("default_view_mode", "icons"))
|
|
self.search_hidden_files = tk.BooleanVar(
|
|
value=self.settings.get("search_hidden_files", False))
|
|
self.recursive_search = tk.BooleanVar(
|
|
value=self.settings.get("recursive_search", True))
|
|
self.use_trash = tk.BooleanVar(
|
|
value=self.settings.get("use_trash", False))
|
|
self.confirm_delete = tk.BooleanVar(
|
|
value=self.settings.get("confirm_delete", False))
|
|
self.use_pillow_animation = tk.BooleanVar(
|
|
value=self.settings.get("use_pillow_animation", False))
|
|
self.animation_type = tk.StringVar(
|
|
value=self.settings.get("animation_type", "double_arc"))
|
|
|
|
# --- UI Elements ---
|
|
main_frame = ttk.Frame(self, padding=10)
|
|
main_frame.pack(fill="both", expand=True)
|
|
|
|
# Button Box Position
|
|
button_box_frame = ttk.LabelFrame(
|
|
main_frame, text="Position der Dialog-Buttons", padding=10)
|
|
button_box_frame.pack(fill="x", pady=5)
|
|
ttk.Radiobutton(button_box_frame, text="Links",
|
|
variable=self.button_box_pos, value="left").pack(side="left", padx=5)
|
|
ttk.Radiobutton(button_box_frame, text="Rechts",
|
|
variable=self.button_box_pos, value="right").pack(side="left", padx=5)
|
|
|
|
# Window Size
|
|
size_frame = ttk.LabelFrame(
|
|
main_frame, text="Fenstergröße", padding=10)
|
|
size_frame.pack(fill="x", pady=5)
|
|
sizes = ["1050x850", "850x650", "650x450"]
|
|
size_combo = ttk.Combobox(
|
|
size_frame, textvariable=self.window_size_preset, values=sizes, state="readonly")
|
|
size_combo.pack(fill="x")
|
|
|
|
# Default View Mode
|
|
view_mode_frame = ttk.LabelFrame(
|
|
main_frame, text="Standardansicht", padding=10)
|
|
view_mode_frame.pack(fill="x", pady=5)
|
|
ttk.Radiobutton(view_mode_frame, text="Kacheln",
|
|
variable=self.default_view_mode, value="icons").pack(side="left", padx=5)
|
|
ttk.Radiobutton(view_mode_frame, text="Liste",
|
|
variable=self.default_view_mode, value="list").pack(side="left", padx=5)
|
|
|
|
# Search Hidden Files
|
|
search_hidden_frame = ttk.LabelFrame(
|
|
main_frame, text="Sucheinstellungen", padding=10)
|
|
search_hidden_frame.pack(fill="x", pady=5)
|
|
ttk.Checkbutton(search_hidden_frame, text="Versteckte Dateien und Ordner durchsuchen",
|
|
variable=self.search_hidden_files).pack(anchor="w")
|
|
ttk.Checkbutton(search_hidden_frame, text="Rekursiv suchen",
|
|
variable=self.recursive_search).pack(anchor="w")
|
|
|
|
# Deletion Settings
|
|
delete_frame = ttk.LabelFrame(
|
|
main_frame, text="Löscheinstellungen", padding=10)
|
|
delete_frame.pack(fill="x", pady=5)
|
|
|
|
self.use_trash_checkbutton = ttk.Checkbutton(delete_frame, text="Dateien in den Papierkorb verschieben (empfohlen)",
|
|
variable=self.use_trash)
|
|
self.use_trash_checkbutton.pack(anchor="w")
|
|
|
|
if not SEND2TRASH_AVAILABLE:
|
|
self.use_trash_checkbutton.config(state=tk.DISABLED)
|
|
ttk.Label(delete_frame, text="(send2trash-Bibliothek nicht gefunden)",
|
|
font=("TkDefaultFont", 9, "italic")).pack(anchor="w", padx=(20, 0))
|
|
|
|
self.confirm_delete_checkbutton = ttk.Checkbutton(delete_frame, text="Löschen/Verschieben ohne Bestätigung",
|
|
variable=self.confirm_delete)
|
|
self.confirm_delete_checkbutton.pack(anchor="w")
|
|
|
|
# Pillow Animation
|
|
pillow_frame = ttk.LabelFrame(
|
|
main_frame, text="Animationseinstellungen", padding=10)
|
|
pillow_frame.pack(fill="x", pady=5)
|
|
self.use_pillow_animation_checkbutton = ttk.Checkbutton(pillow_frame, text="Hochauflösende Animation verwenden (Pillow)",
|
|
variable=self.use_pillow_animation)
|
|
self.use_pillow_animation_checkbutton.pack(anchor="w")
|
|
if not PIL_AVAILABLE:
|
|
self.use_pillow_animation_checkbutton.config(state=tk.DISABLED)
|
|
ttk.Label(pillow_frame, text="(Pillow-Bibliothek nicht gefunden)",
|
|
font=("TkDefaultFont", 9, "italic")).pack(anchor="w", padx=(20, 0))
|
|
|
|
# Animation Type
|
|
anim_type_frame = ttk.LabelFrame(
|
|
main_frame, text="Animationstyp", padding=10)
|
|
anim_type_frame.pack(fill="x", pady=5)
|
|
ttk.Radiobutton(anim_type_frame, text="Gegenläufige Bogen", variable=self.animation_type,
|
|
value="counter_arc").pack(side="left", padx=5)
|
|
ttk.Radiobutton(anim_type_frame, text="Doppelbogen", variable=self.animation_type,
|
|
value="double_arc").pack(side="left", padx=5)
|
|
ttk.Radiobutton(anim_type_frame, text="Linie", variable=self.animation_type,
|
|
value="line").pack(side="left", padx=5)
|
|
ttk.Radiobutton(anim_type_frame, text="Blinken", variable=self.animation_type,
|
|
value="blink").pack(side="left", padx=5)
|
|
|
|
# Disable deletion options in "open" mode
|
|
if not self.dialog_mode == "save":
|
|
self.use_trash_checkbutton.config(state=tk.DISABLED)
|
|
self.confirm_delete_checkbutton.config(state=tk.DISABLED)
|
|
info_label = ttk.Label(delete_frame, text="(Löschoptionen sind nur im Speichern-Modus verfügbar)",
|
|
font=("TkDefaultFont", 9, "italic"))
|
|
info_label.pack(anchor="w", padx=(20, 0))
|
|
|
|
# --- Action Buttons ---
|
|
button_frame = ttk.Frame(main_frame)
|
|
button_frame.pack(fill="x", pady=(10, 0))
|
|
|
|
ttk.Button(button_frame, text="Auf Standard zurücksetzen",
|
|
command=self.reset_to_defaults).pack(side="left", padx=5)
|
|
ttk.Button(button_frame, text="Speichern",
|
|
command=self.save_settings).pack(side="right", padx=5)
|
|
ttk.Button(button_frame, text="Abbrechen",
|
|
command=self.destroy).pack(side="right")
|
|
|
|
def save_settings(self):
|
|
new_settings = {
|
|
"button_box_pos": self.button_box_pos.get(),
|
|
"window_size_preset": self.window_size_preset.get(),
|
|
"default_view_mode": self.default_view_mode.get(),
|
|
"search_hidden_files": self.search_hidden_files.get(),
|
|
"recursive_search": self.recursive_search.get(),
|
|
"use_trash": self.use_trash.get(),
|
|
"confirm_delete": self.confirm_delete.get(),
|
|
"use_pillow_animation": self.use_pillow_animation.get(),
|
|
"animation_type": self.animation_type.get()
|
|
}
|
|
CfdConfigManager.save(new_settings)
|
|
self.master.reload_config_and_rebuild_ui()
|
|
self.destroy()
|
|
|
|
def reset_to_defaults(self):
|
|
defaults = CfdConfigManager._default_settings
|
|
self.button_box_pos.set(defaults["button_box_pos"])
|
|
self.window_size_preset.set(defaults["window_size_preset"])
|
|
self.default_view_mode.set(defaults["default_view_mode"])
|
|
self.search_hidden_files.set(defaults["search_hidden_files"])
|
|
self.recursive_search.set(defaults["recursive_search"])
|
|
self.use_trash.set(defaults["use_trash"])
|
|
self.confirm_delete.set(defaults["confirm_delete"])
|
|
self.use_pillow_animation.set(defaults.get("use_pillow_animation", True) and PIL_AVAILABLE)
|
|
self.animation_type.set(defaults.get("animation_type", "counter_arc"))
|