#!/usr/bin/python3 """App configuration for Custom File Dialog""" import json from pathlib import Path from typing import Dict, Any, Optional, Type from shared_libs.common_tools import Translate # here is initializing the class for translation strings _ = Translate.setup_translations("custom_file_dialog") class CfdConfigManager: """ Manages CFD-specific settings using a JSON file for flexibility. """ # 1 = 1. Year, 09 = Month of the Year, 2924 = Day and Year of the Year UPDATE_URL: str = "https://git.ilunix.de/api/v1/repos/punix/shared_libs/releases" VERSION: str = "v. 1.07.0125" MAX_ITEMS_TO_DISPLAY = 1000 # Base paths BASE_DIR: Path = Path.home() CONFIG_DIR: Path = BASE_DIR / ".config/cfiledialog" # UI configuration UI_CONFIG: Dict[str, Any] = { "window_size": (1050, 850), "window_min_size": (650, 550), "font_family": "Ubuntu", "font_size": 11, "resizable_window": (True, True), } _config: Optional[Dict[str, Any]] = None _config_file: Path = CONFIG_DIR / "cfd_settings.json" _bookmarks_file: Path = CONFIG_DIR / "cfd_bookmarks.json" _default_settings: Dict[str, Any] = { "search_icon_pos": "left", # 'left' or 'right' "button_box_pos": "left", # 'left' or 'right' "window_size_preset": "1050x850", # e.g., "1050x850" "default_view_mode": "icons", # 'icons' or 'list' "search_hidden_files": False, # True or False "use_trash": False, # True or False "confirm_delete": False, # True or False "recursive_search": True, "use_pillow_animation": True, "keep_bookmarks_on_reset": True # Keep bookmarks when resetting settings } @classmethod def _ensure_config_file(cls: Type['CfdConfigManager']) -> None: """Ensures the configuration file exists, creating it with default settings if necessary.""" if not cls._config_file.exists(): try: cls._config_file.parent.mkdir(parents=True, exist_ok=True) with open(cls._config_file, 'w', encoding='utf-8') as f: json.dump(cls._default_settings, f, indent=4) except IOError as e: print(f"Error creating default settings file: {e}") @classmethod def load(cls: Type['CfdConfigManager']) -> Dict[str, Any]: """Loads settings from the JSON file. If the file doesn't exist or is invalid, it loads default settings.""" cls._ensure_config_file() if cls._config is None: try: with open(cls._config_file, 'r', encoding='utf-8') as f: loaded_config = json.load(f) # Merge with defaults to ensure all keys are present cls._config = cls._default_settings.copy() cls._config.update(loaded_config) except (IOError, json.JSONDecodeError): cls._config = cls._default_settings.copy() return cls._config @classmethod def save(cls: Type['CfdConfigManager'], settings: Dict[str, Any]) -> None: """Saves the given settings dictionary to the JSON file.""" try: with open(cls._config_file, 'w', encoding='utf-8') as f: json.dump(settings, f, indent=4) cls._config = settings # Update cached config except IOError as e: print(f"Error saving settings: {e}") @classmethod def _ensure_bookmarks_file(cls: Type['CfdConfigManager']) -> None: """Ensures the bookmarks file exists.""" if not cls._bookmarks_file.exists(): try: cls._bookmarks_file.parent.mkdir(parents=True, exist_ok=True) with open(cls._bookmarks_file, 'w', encoding='utf-8') as f: json.dump({}, f, indent=4) except IOError as e: print(f"Error creating bookmarks file: {e}") @classmethod def load_bookmarks(cls: Type['CfdConfigManager']) -> Dict[str, Any]: """Loads bookmarks from the JSON file.""" cls._ensure_bookmarks_file() try: with open(cls._bookmarks_file, 'r', encoding='utf-8') as f: return json.load(f) except (IOError, json.JSONDecodeError): return {} @classmethod def save_bookmarks(cls: Type['CfdConfigManager'], bookmarks: Dict[str, Any]) -> None: """Saves the given bookmarks dictionary to the JSON file.""" try: with open(cls._bookmarks_file, 'w', encoding='utf-8') as f: json.dump(bookmarks, f, indent=4) except IOError as e: print(f"Error saving bookmarks: {e}") @classmethod def add_bookmark(cls: Type['CfdConfigManager'], name: str, data: Dict[str, Any]) -> None: """Adds or updates a bookmark.""" bookmarks = cls.load_bookmarks() bookmarks[name] = data cls.save_bookmarks(bookmarks) @classmethod def remove_bookmark(cls: Type['CfdConfigManager'], name: str) -> None: """Removes a bookmark by name.""" bookmarks = cls.load_bookmarks() if name in bookmarks: del bookmarks[name] cls.save_bookmarks(bookmarks) class LocaleStrings: """ Contains all translatable strings for the application, organized by module. This class centralizes all user-facing strings to make translation and management easier. The strings are grouped into nested dictionaries corresponding to the part of the application where they are used (e.g., CFD for the main dialog, VIEW for view-related strings). """ # Strings from custom_file_dialog.py CFD: Dict[str, str] = { "title": _("Custom File Dialog"), "select_file": _("Select a file"), "open": _("Open"), "cancel": _("Cancel"), "file_label": _("File:"), "no_file_selected": _("No file selected"), "error_title": _("Error"), "select_file_error": _("Please select a file."), "all_files": _("All Files"), "free_space": _("Free Space"), "entries": _("entries"), "directory_not_found": _("Directory not found"), "unknown": _("Unknown"), "showing": _("Showing"), "of": _("of"), "access_denied": _("Access denied."), "path_not_found": _("Path not found"), "directory": _("Directory"), "not_found": _("not found."), "access_to": _("Access to"), "denied": _("denied."), "items_selected": _("items selected"), "select_or_enter_title": _("Select or Enter?"), "select_or_enter_prompt": _("The folder '{folder_name}' contains no subdirectories. Do you want to select this folder or enter it?"), "select_button": _("Select"), "enter_button": _("Enter"), "cancel_button": _("Cancel"), } # Strings from cfd_view_manager.py VIEW: Dict[str, str] = { "name": _("Name"), "date_modified": _("Date Modified"), "type": _("Type"), "size": _("Size"), "view_mode": _("View Mode"), "icon_view": _("Icon View"), "list_view": _("List View"), "filename": _("Filename"), "path": _("Path"), } # Strings from cfd_ui_setup.py UI: Dict[str, str] = { "search": _("Search"), "go": _("Go"), "up": _("Up"), "back": _("Back"), "forward": _("Forward"), "home": _("Home"), "new_folder": _("New Folder"), "delete": _("Delete"), "settings": _("Settings"), "show_hidden_files": _("Show Hidden Files"), "places": _("Places"), "devices": _("Devices"), "bookmarks": _("Bookmarks"), "new_document": _("New Document"), "hide_hidden_files": _("Hide Hidden Files"), "start_search": _("Start Search"), "cancel_search": _("Cancel Search"), "delete_move": _("Delete/Move selected item"), "copy_filename_to_clipboard": _("Copy Filename to Clipboard"), "copy_path_to_clipboard": _("Copy Path to Clipboard"), "open_file_location": _("Open File Location"), "searching_for": _("Searching for"), "search_cancelled_by_user": _("Search cancelled by user"), "folders_and": _("folders and"), "files_found": _("files found."), "no_results_for": _("No results for"), "error_during_search": _("Error during search"), "search_error": _("Search Error"), "install_new_version": _("Install new version {version}"), "sftp_connection": _("SFTP Connection"), "sftp_bookmarks": _("SFTP Bookmarks"), "remove_bookmark": _("Remove Bookmark"), } # Strings from cfd_settings_dialog.py SET: Dict[str, str] = { "title": _("Settings"), "search_icon_pos_label": _("Search Icon Position"), "left_radio": _("Left"), "right_radio": _("Right"), "button_box_pos_label": _("Button Box Position"), "window_size_label": _("Window Size"), "default_view_mode_label": _("Default View Mode"), "icons_radio": _("Icons"), "list_radio": _("List"), "search_hidden_check": _("Search hidden files"), "use_trash_check": _("Use trash for deletion"), "confirm_delete_check": _("Confirm file deletion"), "recursive_search_check": _("Recursive search"), "use_pillow_check": _("Use Pillow animation"), "save_button": _("Save"), "cancel_button": _("Cancel"), "search_settings": _("Search Settings"), "deletion_settings": _("Deletion Settings"), "recommended": _("recommended"), "send2trash_not_found": _("send2trash library not found"), "animation_settings": _("Animation Settings"), "pillow": _("Pillow"), "pillow_not_found": _("Pillow library not found"), "animation_type": _("Animation Type"), "counter_arc": _("Counter Arc"), "double_arc": _("Double Arc"), "line": _("Line"), "blink": _("Blink"), "deletion_options_info": _("Deletion options are only available in save mode"), "reset_to_default": _("Reset to Default"), "sftp_settings": _("SFTP Settings"), "paramiko_not_found": _("Paramiko library not found."), "sftp_disabled": _("SFTP functionality is disabled. Please install 'paramiko'."), "paramiko_found": _("Paramiko library found. SFTP is enabled."), "keep_sftp_bookmarks": _("Keep SFTP bookmarks on reset"), } # Strings from cfd_file_operations.py FILE: Dict[str, str] = { "new_folder_title": _("New Folder"), "enter_folder_name_label": _("Enter folder name:"), "untitled_folder": _("Untitled Folder"), "error_title": _("Error"), "folder_exists_error": _("Folder already exists."), "create_folder_error": _("Could not create folder."), "confirm_delete_title": _("Confirm Deletion"), "confirm_delete_file_message": _("Are you sure you want to permanently delete this file?"), "confirm_delete_files_message": _("Are you sure you want to permanently delete these files?"), "delete_button": _("Delete"), "cancel_button": _("Cancel"), "file_not_found_error": _("File not found."), "trash_error": _("Could not move file to trash."), "delete_error": _("Could not delete file."), "folder": _("Folder"), "file": _("File"), "move_to_trash": _("move to trash"), "delete_permanently": _("delete permanently"), "are_you_sure": _("Are you sure you want to"), "was_successfully_removed": _("was successfully removed."), "error_removing": _("Error removing"), "new_document_txt": _("New Document.txt"), "error_creating": _("Error creating"), "copied_to_clipboard": _("copied to clipboard."), "error_renaming": _("Error renaming"), "not_accessible": _("not accessible"), } # Strings from cfd_navigation_manager.py NAV: Dict[str, str] = { "home": _("Home"), "trash": _("Trash"), "desktop": _("Desktop"), "documents": _("Documents"), "downloads": _("Downloads"), "music": _("Music"), "pictures": _("Pictures"), "videos": _("Videos"), "computer": _("Computer"), }