233 lines
12 KiB
Python
233 lines
12 KiB
Python
import tkinter as tk
|
|
from tkinter import ttk
|
|
from typing import TYPE_CHECKING
|
|
|
|
from .cfd_app_config import CfdConfigManager, LocaleStrings
|
|
from shared_libs.animated_icon import PIL_AVAILABLE
|
|
from .cfd_sftp_manager import PARAMIKO_AVAILABLE
|
|
|
|
if TYPE_CHECKING:
|
|
from custom_file_dialog import CustomFileDialog
|
|
|
|
try:
|
|
import send2trash
|
|
SEND2TRASH_AVAILABLE = True
|
|
except ImportError:
|
|
SEND2TRASH_AVAILABLE = False
|
|
|
|
|
|
class SettingsDialog(tk.Toplevel):
|
|
"""A dialog window for configuring the application settings."""
|
|
|
|
def __init__(self, parent: 'CustomFileDialog', dialog_mode: str = "save") -> None:
|
|
"""
|
|
Initializes the SettingsDialog.
|
|
|
|
Args:
|
|
parent: The parent widget.
|
|
dialog_mode (str, optional): The mode of the main dialog ("open" or "save"),
|
|
which affects available settings. Defaults to "save".
|
|
"""
|
|
super().__init__(parent)
|
|
self.transient(parent)
|
|
self.grab_set()
|
|
self.title(LocaleStrings.SET["title"])
|
|
|
|
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"))
|
|
self.keep_bookmarks_on_reset = tk.BooleanVar(
|
|
value=self.settings.get("keep_bookmarks_on_reset", True))
|
|
|
|
# --- 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=LocaleStrings.SET["button_box_pos_label"], padding=10)
|
|
button_box_frame.pack(fill="x", pady=5)
|
|
ttk.Radiobutton(button_box_frame, text=LocaleStrings.SET["left_radio"],
|
|
variable=self.button_box_pos, value="left").pack(side="left", padx=5)
|
|
ttk.Radiobutton(button_box_frame, text=LocaleStrings.SET["right_radio"],
|
|
variable=self.button_box_pos, value="right").pack(side="left", padx=5)
|
|
|
|
# Window Size
|
|
size_frame = ttk.LabelFrame(
|
|
main_frame, text=LocaleStrings.SET["window_size_label"], 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=LocaleStrings.SET["default_view_mode_label"], padding=10)
|
|
view_mode_frame.pack(fill="x", pady=5)
|
|
ttk.Radiobutton(view_mode_frame, text=LocaleStrings.SET["icons_radio"],
|
|
variable=self.default_view_mode, value="icons").pack(side="left", padx=5)
|
|
ttk.Radiobutton(view_mode_frame, text=LocaleStrings.SET["list_radio"],
|
|
variable=self.default_view_mode, value="list").pack(side="left", padx=5)
|
|
|
|
# Search Hidden Files
|
|
search_hidden_frame = ttk.LabelFrame(
|
|
main_frame, text=LocaleStrings.SET["search_settings"], padding=10)
|
|
search_hidden_frame.pack(fill="x", pady=5)
|
|
ttk.Checkbutton(search_hidden_frame, text=LocaleStrings.SET["search_hidden_check"],
|
|
variable=self.search_hidden_files).pack(anchor="w")
|
|
ttk.Checkbutton(search_hidden_frame, text=LocaleStrings.SET["recursive_search_check"],
|
|
variable=self.recursive_search).pack(anchor="w")
|
|
|
|
# Deletion Settings
|
|
delete_frame = ttk.LabelFrame(
|
|
main_frame, text=LocaleStrings.SET["deletion_settings"], padding=10)
|
|
delete_frame.pack(fill="x", pady=5)
|
|
|
|
self.use_trash_checkbutton = ttk.Checkbutton(delete_frame, text=f"{LocaleStrings.SET['use_trash_check']} ({LocaleStrings.SET['recommended']})",
|
|
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=f"({LocaleStrings.SET['send2trash_not_found']})",
|
|
font=("TkDefaultFont", 9, "italic")).pack(anchor="w", padx=(20, 0))
|
|
|
|
self.confirm_delete_checkbutton = ttk.Checkbutton(delete_frame, text=LocaleStrings.SET["confirm_delete_check"],
|
|
variable=self.confirm_delete)
|
|
self.confirm_delete_checkbutton.pack(anchor="w")
|
|
|
|
# Pillow Animation
|
|
pillow_frame = ttk.LabelFrame(
|
|
main_frame, text=LocaleStrings.SET["animation_settings"], padding=10)
|
|
pillow_frame.pack(fill="x", pady=5)
|
|
self.use_pillow_animation_checkbutton = ttk.Checkbutton(pillow_frame, text=f"{LocaleStrings.SET['use_pillow_check']} ({LocaleStrings.SET['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=f"({LocaleStrings.SET['pillow_not_found']})",
|
|
font=("TkDefaultFont", 9, "italic")).pack(anchor="w", padx=(20, 0))
|
|
|
|
# Animation Type
|
|
anim_type_frame = ttk.LabelFrame(
|
|
main_frame, text=LocaleStrings.SET["animation_type"], padding=10)
|
|
anim_type_frame.pack(fill="x", pady=5)
|
|
ttk.Radiobutton(anim_type_frame, text=LocaleStrings.SET["counter_arc"], variable=self.animation_type,
|
|
value="counter_arc").pack(side="left", padx=5)
|
|
ttk.Radiobutton(anim_type_frame, text=LocaleStrings.SET["double_arc"], variable=self.animation_type,
|
|
value="double_arc").pack(side="left", padx=5)
|
|
ttk.Radiobutton(anim_type_frame, text=LocaleStrings.SET["line"], variable=self.animation_type,
|
|
value="line").pack(side="left", padx=5)
|
|
ttk.Radiobutton(anim_type_frame, text=LocaleStrings.SET["blink"], variable=self.animation_type,
|
|
value="blink").pack(side="left", padx=5)
|
|
|
|
# SFTP Settings
|
|
sftp_frame = ttk.LabelFrame(
|
|
main_frame, text=LocaleStrings.SET["sftp_settings"], padding=10)
|
|
sftp_frame.pack(fill="x", pady=5)
|
|
|
|
if not PARAMIKO_AVAILABLE:
|
|
ttk.Label(sftp_frame, text=LocaleStrings.SET["paramiko_not_found"],
|
|
font=("TkDefaultFont", 9, "italic")).pack(anchor="w")
|
|
ttk.Label(sftp_frame, text=LocaleStrings.SET["sftp_disabled"],
|
|
font=("TkDefaultFont", 9, "italic")).pack(anchor="w")
|
|
else:
|
|
ttk.Label(sftp_frame, text=LocaleStrings.SET["paramiko_found"],
|
|
font=("TkDefaultFont", 9)).pack(anchor="w")
|
|
|
|
# Keyring status
|
|
try:
|
|
import keyring
|
|
keyring_available = True
|
|
except ImportError:
|
|
keyring_available = False
|
|
|
|
if keyring_available:
|
|
ttk.Label(sftp_frame, text="Keyring library found. Passwords will be stored securely.",
|
|
font=("TkDefaultFont", 9)).pack(anchor="w", pady=(5,0))
|
|
else:
|
|
ttk.Label(sftp_frame, text="Keyring library not found. Passwords cannot be saved.",
|
|
font=("TkDefaultFont", 9, "italic")).pack(anchor="w", pady=(5,0))
|
|
|
|
|
|
self.keep_bookmarks_checkbutton = ttk.Checkbutton(sftp_frame, text=LocaleStrings.SET["keep_sftp_bookmarks"],
|
|
variable=self.keep_bookmarks_on_reset)
|
|
self.keep_bookmarks_checkbutton.pack(anchor="w", pady=(5,0))
|
|
|
|
# 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=f"({LocaleStrings.SET['deletion_options_info']})",
|
|
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=LocaleStrings.SET["reset_to_default"],
|
|
command=self.reset_to_defaults).pack(side="left", padx=5)
|
|
ttk.Button(button_frame, text=LocaleStrings.SET["save_button"],
|
|
command=self.save_settings).pack(side="right", padx=5)
|
|
ttk.Button(button_frame, text=LocaleStrings.SET["cancel_button"],
|
|
command=self.destroy).pack(side="right")
|
|
|
|
def save_settings(self) -> None:
|
|
"""
|
|
Saves the current settings to the configuration file and closes the dialog.
|
|
|
|
Triggers a UI rebuild in the parent dialog to apply the changes.
|
|
"""
|
|
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(),
|
|
"keep_bookmarks_on_reset": self.keep_bookmarks_on_reset.get()
|
|
}
|
|
CfdConfigManager.save(new_settings)
|
|
self.master.reload_config_and_rebuild_ui()
|
|
self.destroy()
|
|
|
|
def reset_to_defaults(self) -> None:
|
|
"""Resets all settings in the dialog to their default values."""
|
|
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"))
|
|
self.keep_bookmarks_on_reset.set(defaults.get("keep_bookmarks_on_reset", True)) |