diff --git a/__pycache__/animated_icon.cpython-312.pyc b/__pycache__/animated_icon.cpython-312.pyc new file mode 100644 index 0000000..7eec2b6 Binary files /dev/null and b/__pycache__/animated_icon.cpython-312.pyc differ diff --git a/__pycache__/cfd_animated_icon.cpython-312.pyc b/__pycache__/cfd_animated_icon.cpython-312.pyc index b02c3a7..8e1af96 100644 Binary files a/__pycache__/cfd_animated_icon.cpython-312.pyc and b/__pycache__/cfd_animated_icon.cpython-312.pyc differ diff --git a/__pycache__/cfd_app_config.cpython-312.pyc b/__pycache__/cfd_app_config.cpython-312.pyc index 3bf1bd0..461b793 100644 Binary files a/__pycache__/cfd_app_config.cpython-312.pyc and b/__pycache__/cfd_app_config.cpython-312.pyc differ diff --git a/__pycache__/cfd_file_operations.cpython-312.pyc b/__pycache__/cfd_file_operations.cpython-312.pyc new file mode 100644 index 0000000..6b5dd50 Binary files /dev/null and b/__pycache__/cfd_file_operations.cpython-312.pyc differ diff --git a/__pycache__/cfd_navigation_manager.cpython-312.pyc b/__pycache__/cfd_navigation_manager.cpython-312.pyc new file mode 100644 index 0000000..d7fef1a Binary files /dev/null and b/__pycache__/cfd_navigation_manager.cpython-312.pyc differ diff --git a/__pycache__/cfd_search_manager.cpython-312.pyc b/__pycache__/cfd_search_manager.cpython-312.pyc new file mode 100644 index 0000000..81e4b12 Binary files /dev/null and b/__pycache__/cfd_search_manager.cpython-312.pyc differ diff --git a/__pycache__/cfd_settings_dialog.cpython-312.pyc b/__pycache__/cfd_settings_dialog.cpython-312.pyc new file mode 100644 index 0000000..8178e35 Binary files /dev/null and b/__pycache__/cfd_settings_dialog.cpython-312.pyc differ diff --git a/__pycache__/cfd_ui_setup.cpython-312.pyc b/__pycache__/cfd_ui_setup.cpython-312.pyc index f93a798..9b2aa40 100644 Binary files a/__pycache__/cfd_ui_setup.cpython-312.pyc and b/__pycache__/cfd_ui_setup.cpython-312.pyc differ diff --git a/__pycache__/cfd_view_manager.cpython-312.pyc b/__pycache__/cfd_view_manager.cpython-312.pyc new file mode 100644 index 0000000..ff75bf8 Binary files /dev/null and b/__pycache__/cfd_view_manager.cpython-312.pyc differ diff --git a/__pycache__/custom_file_dialog.cpython-312.pyc b/__pycache__/custom_file_dialog.cpython-312.pyc index 9db50d8..4efc26f 100644 Binary files a/__pycache__/custom_file_dialog.cpython-312.pyc and b/__pycache__/custom_file_dialog.cpython-312.pyc differ diff --git a/cfd_animated_icon.py b/animated_icon.py similarity index 100% rename from cfd_animated_icon.py rename to animated_icon.py diff --git a/cfd_app_config.py b/cfd_app_config.py index 0c34775..f4031ce 100755 --- a/cfd_app_config.py +++ b/cfd_app_config.py @@ -46,7 +46,7 @@ class AppConfig: # here is initializing the class for translation strings -_ = Translate.setup_translations("custom_file_fialog") +_ = Translate.setup_translations("custom_file_dialog") class CfdConfigManager: @@ -104,13 +104,152 @@ class CfdConfigManager: print(f"Error saving settings: {e}") -class Msg: - - STR: Dict[str, str] = { - # Strings for messages - +class LocaleStrings: + # Strings from custom_file_dialog.py + CFD = { + "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."), } - TTIP: Dict[str, str] = { - # Strings for Tooltips + # Strings from cfd_view_manager.py + VIEW = { + "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 = { + "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"), + } + + # Strings from cfd_settings_dialog.py + SET = { + "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"), + } + + # Strings from cfd_file_operations.py + FILE = { + "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 = { + "home": _("Home"), + "trash": _("Trash"), + "desktop": _("Desktop"), + "documents": _("Documents"), + "downloads": _("Downloads"), + "music": _("Music"), + "pictures": _("Pictures"), + "videos": _("Videos"), + "computer": _("Computer"), + } + + diff --git a/cfd_file_operations.py b/cfd_file_operations.py index 465b405..f8e2d43 100644 --- a/cfd_file_operations.py +++ b/cfd_file_operations.py @@ -10,6 +10,7 @@ except ImportError: SEND2TRASH_AVAILABLE = False from shared_libs.message import MessageDialog +from cfd_app_config import LocaleStrings, _ class FileOperationsManager: @@ -25,14 +26,14 @@ class FileOperationsManager: "use_trash", False) and SEND2TRASH_AVAILABLE confirm = self.dialog.settings.get("confirm_delete", False) - action_text = "in den Papierkorb verschieben" if use_trash else "endgültig löschen" + action_text = LocaleStrings.FILE["move_to_trash"] if use_trash else LocaleStrings.FILE["delete_permanently"] item_name = os.path.basename(self.dialog.selected_file) if not confirm: dialog = MessageDialog( master=self.dialog, - title="Bestätigung erforderlich", - text=f"Möchten Sie '{item_name}' wirklich {action_text}?", + title=LocaleStrings.FILE["confirm_delete_title"], + text=f"{LocaleStrings.FILE['are_you_sure']} '{item_name}' {action_text}?", message_type="question" ) if not dialog.show(): @@ -49,13 +50,13 @@ class FileOperationsManager: self.dialog.view_manager.populate_files() self.dialog.widget_manager.search_status_label.config( - text=f"'{item_name}' wurde erfolgreich entfernt.") + text=f"'{item_name}' {LocaleStrings.FILE['was_successfully_removed']}") except Exception as e: MessageDialog( master=self.dialog, - title="Fehler", - text=f"Fehler beim Entfernen von '{item_name}':\n{e}", + title=LocaleStrings.FILE["error_title"], + text=f"{LocaleStrings.FILE['error_removing']} '{item_name}':\n{e}", message_type="error" ).show() @@ -66,7 +67,7 @@ class FileOperationsManager: self._create_new_item(is_folder=False) def _create_new_item(self, is_folder): - base_name = "Neuer Ordner" if is_folder else "Neues Dokument.txt" + base_name = LocaleStrings.FILE["new_folder_title"] if is_folder else LocaleStrings.FILE["new_document_txt"] new_name = self._get_unique_name(base_name) new_path = os.path.join(self.dialog.current_dir, new_name) @@ -78,7 +79,7 @@ class FileOperationsManager: self.dialog.view_manager.populate_files(item_to_rename=new_name) except Exception as e: self.dialog.widget_manager.search_status_label.config( - text=f"Fehler beim Erstellen: {e}") + text=f"{LocaleStrings.FILE['error_creating']}: {e}") def _get_unique_name(self, base_name): name, ext = os.path.splitext(base_name) @@ -93,7 +94,7 @@ class FileOperationsManager: self.dialog.clipboard_clear() self.dialog.clipboard_append(data) self.dialog.widget_manager.search_status_label.config( - text=f"'{self.dialog.shorten_text(data, 50)}' in Zwischenablage kopiert.") + text=f"'{self.dialog.shorten_text(data, 50)}' {LocaleStrings.FILE['copied_to_clipboard']}") def _show_context_menu(self, event, item_path): if not item_path: @@ -105,14 +106,14 @@ class FileOperationsManager: self.dialog.context_menu = tk.Menu(self.dialog, tearoff=0, background=self.dialog.style_manager.header, foreground=self.dialog.style_manager.color_foreground, activebackground=self.dialog.style_manager.selection_color, activeforeground=self.dialog.style_manager.color_foreground, relief='flat', borderwidth=0) - self.dialog.context_menu.add_command(label="Dateiname in Zwischenablage", + self.dialog.context_menu.add_command(label=LocaleStrings.UI["copy_filename_to_clipboard"], command=lambda: self._copy_to_clipboard(os.path.basename(item_path))) self.dialog.context_menu.add_command( - label="Pfad in Zwischenablage", command=lambda: self._copy_to_clipboard(item_path)) + label=LocaleStrings.UI["copy_path_to_clipboard"], command=lambda: self._copy_to_clipboard(item_path)) self.dialog.context_menu.add_separator() self.dialog.context_menu.add_command( - label="Speicherort öffnen", command=lambda: self._open_file_location_from_context(item_path)) + label=LocaleStrings.UI["open_file_location"], command=lambda: self._open_file_location_from_context(item_path)) self.dialog.context_menu.tk_popup(event.x_root, event.y_root) return "break" @@ -152,7 +153,6 @@ class FileOperationsManager: entry = ttk.Entry(item_frame) entry.insert(0, os.path.basename(item_path)) entry.select_range(0, tk.END) - entry.pack(fill="x", expand=True, padx=5, pady=5) entry.focus_set() def finish_rename(event): @@ -161,7 +161,7 @@ class FileOperationsManager: if new_name and new_path != item_path: if os.path.exists(new_path): self.dialog.widget_manager.search_status_label.config( - text=f"'{new_name}' existiert bereits.") + text=f"'{new_name}' {LocaleStrings.FILE['folder_exists_error']}") self.dialog.view_manager.populate_files( item_to_select=os.path.basename(item_path)) return @@ -170,7 +170,7 @@ class FileOperationsManager: self.dialog.view_manager.populate_files(item_to_select=new_name) except Exception as e: self.dialog.widget_manager.search_status_label.config( - text=f"Fehler beim Umbenennen: {e}") + text=f"{LocaleStrings.FILE['error_renaming']}: {e}") self.dialog.view_manager.populate_files() else: self.dialog.populate_files(item_to_select=os.path.basename(item_path)) @@ -209,7 +209,7 @@ class FileOperationsManager: if new_name and new_path != old_path: if os.path.exists(new_path): self.dialog.widget_manager.search_status_label.config( - text=f"'{new_name}' existiert bereits.") + text=f"'{new_name}' {LocaleStrings.FILE['folder_exists_error']}") self.dialog.view_manager.populate_files(item_to_select=item_text) else: try: @@ -217,7 +217,7 @@ class FileOperationsManager: self.dialog.view_manager.populate_files(item_to_select=new_name) except Exception as e: self.dialog.widget_manager.search_status_label.config( - text=f"Fehler beim Umbenennen: {e}") + text=f"{LocaleStrings.FILE['error_renaming']}: {e}") self.dialog.view_manager.populate_files() else: self.dialog.populate_files(item_to_select=item_text) @@ -229,3 +229,4 @@ class FileOperationsManager: entry.bind("", finish_rename) entry.bind("", finish_rename) entry.bind("", cancel_rename) + diff --git a/cfd_navigation_manager.py b/cfd_navigation_manager.py index 640505a..fe2b659 100644 --- a/cfd_navigation_manager.py +++ b/cfd_navigation_manager.py @@ -1,5 +1,6 @@ import os import tkinter as tk +from cfd_app_config import LocaleStrings, _ class NavigationManager: def __init__(self, dialog): @@ -17,7 +18,7 @@ class NavigationManager: self.navigate_to(directory, file_to_select=filename) else: self.dialog.widget_manager.search_status_label.config( - text=f"Pfad nicht gefunden: {self.dialog.shorten_text(path_text, 50)}") + text=f"{LocaleStrings.CFD['path_not_found']}: {self.dialog.shorten_text(path_text, 50)}") def navigate_to(self, path, file_to_select=None): try: @@ -25,11 +26,11 @@ class NavigationManager: os.path.abspath(os.path.expanduser(path))) if not os.path.isdir(real_path): self.dialog.widget_manager.search_status_label.config( - text=f"Fehler: Verzeichnis '{os.path.basename(path)}' nicht gefunden.") + text=f"{LocaleStrings.CFD['error_title']}: {LocaleStrings.CFD['directory']} '{os.path.basename(path)}' {LocaleStrings.CFD['not_found']}") return if not os.access(real_path, os.R_OK): self.dialog.widget_manager.search_status_label.config( - text=f"Zugriff auf '{os.path.basename(path)}' verweigert.") + text=f"{LocaleStrings.CFD['access_to']} '{os.path.basename(path)}' {LocaleStrings.CFD['denied']}") return self.dialog.current_dir = real_path if self.dialog.history_pos < len(self.dialog.history) - 1: @@ -45,7 +46,7 @@ class NavigationManager: self.dialog.update_status_bar() self.dialog.update_action_buttons_state() except Exception as e: - self.dialog.widget_manager.search_status_label.config(text=f"Fehler: {e}") + self.dialog.widget_manager.search_status_label.config(text=f"{LocaleStrings.CFD['error_title']}: {e}") def go_back(self): if self.dialog.history_pos > 0: diff --git a/cfd_search_manager.py b/cfd_search_manager.py index 0e61f01..838fc7c 100644 --- a/cfd_search_manager.py +++ b/cfd_search_manager.py @@ -6,6 +6,7 @@ import tkinter as tk from tkinter import ttk from shared_libs.message import MessageDialog from cfd_ui_setup import get_xdg_user_dir +from cfd_app_config import LocaleStrings, _ class SearchManager: def __init__(self, dialog): @@ -22,7 +23,7 @@ class SearchManager: if self.dialog.search_thread and self.dialog.search_thread.is_alive(): self.dialog.search_thread.cancelled = True self.dialog.widget_manager.search_animation.stop() - self.dialog.widget_manager.search_status_label.config(text="Suche abgebrochen.") + self.dialog.widget_manager.search_status_label.config(text=LocaleStrings.UI["cancel_search"]) else: self.execute_search() @@ -50,7 +51,7 @@ class SearchManager: if not search_term: self.hide_search_bar() return - self.dialog.widget_manager.search_status_label.config(text=f"Suche nach '{search_term}'...") + self.dialog.widget_manager.search_status_label.config(text=f"{LocaleStrings.UI['searching_for']} '{search_term}'...") self.dialog.widget_manager.search_animation.start(pulse=False) self.dialog.update_idletasks() self.dialog.search_thread = threading.Thread(target=self._perform_search_in_thread, args=(search_term,)) @@ -82,7 +83,7 @@ class SearchManager: if is_recursive: for root, dirs, files in os.walk(search_dir, followlinks=follow_links): if not (self.dialog.search_thread and self.dialog.search_thread.is_alive()): - raise InterruptedError("Search cancelled by user") + raise InterruptedError(LocaleStrings.UI["search_cancelled_by_user"]) if not search_hidden: dirs[:] = [d for d in dirs if not d.startswith('.')] @@ -97,7 +98,7 @@ class SearchManager: else: for name in os.listdir(search_dir): if not (self.dialog.search_thread and self.dialog.search_thread.is_alive()): - raise InterruptedError("Search cancelled by user") + raise InterruptedError(LocaleStrings.UI["search_cancelled_by_user"]) if not search_hidden and name.startswith('.'): continue @@ -115,7 +116,7 @@ class SearchManager: break if not (self.dialog.search_thread and self.dialog.search_thread.is_alive()): - raise InterruptedError("Search cancelled by user") + raise InterruptedError(LocaleStrings.UI["search_cancelled_by_user"]) seen = set() self.dialog.search_results = [x for x in all_files if not (x in seen or seen.add(x))] @@ -126,18 +127,18 @@ class SearchManager: folder_count = sum(1 for p in self.dialog.search_results if os.path.isdir(p)) file_count = len(self.dialog.search_results) - folder_count self.dialog.widget_manager.search_status_label.config( - text=f"{folder_count} Ordner und {file_count} Dateien gefunden.") + text=f"{folder_count} {LocaleStrings.UI['folders_and']} {file_count} {LocaleStrings.UI['files_found']}") else: self.dialog.widget_manager.search_status_label.config( - text=f"Keine Ergebnisse für '{search_term}'.") + text=f"{LocaleStrings.UI['no_results_for']} '{search_term}'.") self.dialog.after(0, update_ui) except (Exception, InterruptedError) as e: if isinstance(e, (InterruptedError, subprocess.SubprocessError)): - self.dialog.after(0, lambda: self.dialog.widget_manager.search_status_label.config(text="Suche abgebrochen.")) + self.dialog.after(0, lambda: self.dialog.widget_manager.search_status_label.config(text=LocaleStrings.UI["cancel_search"])) else: self.dialog.after(0, lambda: MessageDialog( - message_type="error", text=f"Fehler bei der Suche: {e}", title="Suchfehler", master=self.dialog).show()) + message_type="error", text=f"{LocaleStrings.UI['error_during_search']}: {e}", title=LocaleStrings.UI["search_error"], master=self.dialog).show()) finally: self.dialog.after(0, self.dialog.widget_manager.search_animation.stop) self.dialog.search_process = None @@ -155,13 +156,13 @@ class SearchManager: search_tree = ttk.Treeview( tree_frame, columns=columns, show="tree headings") - search_tree.heading("#0", text="Dateiname", anchor="w") + search_tree.heading("#0", text=LocaleStrings.VIEW["filename"], anchor="w") search_tree.column("#0", anchor="w", width=200, stretch=True) - search_tree.heading("path", text="Pfad", anchor="w") + search_tree.heading("path", text=LocaleStrings.VIEW["path"], anchor="w") search_tree.column("path", anchor="w", width=300, stretch=True) - search_tree.heading("size", text="Größe", anchor="e") + search_tree.heading("size", text=LocaleStrings.VIEW["size"], anchor="e") search_tree.column("size", anchor="e", width=100, stretch=False) - search_tree.heading("modified", text="Geändert am", anchor="w") + search_tree.heading("modified", text=LocaleStrings.VIEW["date_modified"], anchor="w") search_tree.column("modified", anchor="w", width=160, stretch=False) v_scrollbar = ttk.Scrollbar( @@ -206,10 +207,10 @@ class SearchManager: stat = os.stat(full_path) size_str = self.dialog._format_size(stat.st_size) self.dialog.widget_manager.search_status_label.config( - text=f"'{filename}' Größe: {size_str}") + text=f"'{filename}' {LocaleStrings.VIEW['size']}: {size_str}") except (FileNotFoundError, PermissionError): self.dialog.widget_manager.search_status_label.config( - text=f"'{filename}' nicht zugänglich") + text=f"'{filename}' {LocaleStrings.FILE['not_accessible']}") self.dialog.widget_manager.filename_entry.delete(0, tk.END) self.dialog.widget_manager.filename_entry.insert(0, filename) diff --git a/cfd_settings_dialog.py b/cfd_settings_dialog.py index d9b118f..faa50e8 100644 --- a/cfd_settings_dialog.py +++ b/cfd_settings_dialog.py @@ -1,7 +1,7 @@ import tkinter as tk from tkinter import ttk -from cfd_app_config import CfdConfigManager -from cfd_animated_icon import PIL_AVAILABLE +from cfd_app_config import CfdConfigManager, LocaleStrings, _ +from animated_icon import PIL_AVAILABLE try: import send2trash @@ -15,7 +15,7 @@ class SettingsDialog(tk.Toplevel): super().__init__(parent) self.transient(parent) self.grab_set() - self.title("Einstellungen") + self.title(LocaleStrings.SET["title"]) self.settings = CfdConfigManager.load() self.dialog_mode = dialog_mode @@ -48,16 +48,16 @@ class SettingsDialog(tk.Toplevel): # Button Box Position button_box_frame = ttk.LabelFrame( - main_frame, text="Position der Dialog-Buttons", padding=10) + 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="Links", + 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="Rechts", + 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="Fenstergröße", padding=10) + 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( @@ -66,70 +66,70 @@ class SettingsDialog(tk.Toplevel): # Default View Mode view_mode_frame = ttk.LabelFrame( - main_frame, text="Standardansicht", padding=10) + 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="Kacheln", + 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="Liste", + 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="Sucheinstellungen", padding=10) + main_frame, text=LocaleStrings.SET["search_settings"], padding=10) search_hidden_frame.pack(fill="x", pady=5) - ttk.Checkbutton(search_hidden_frame, text="Versteckte Dateien und Ordner durchsuchen", + 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="Rekursiv suchen", + 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="Löscheinstellungen", padding=10) + 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="Dateien in den Papierkorb verschieben (empfohlen)", + 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="(send2trash-Bibliothek nicht gefunden)", + 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="Löschen/Verschieben ohne Bestätigung", + 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="Animationseinstellungen", padding=10) + 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="Hochauflösende Animation verwenden (Pillow)", + 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="(Pillow-Bibliothek nicht gefunden)", + 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="Animationstyp", padding=10) + main_frame, text=LocaleStrings.SET["animation_type"], padding=10) anim_type_frame.pack(fill="x", pady=5) - ttk.Radiobutton(anim_type_frame, text="Gegenläufige Bogen", variable=self.animation_type, + 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="Doppelbogen", variable=self.animation_type, + 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="Linie", variable=self.animation_type, + 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="Blinken", variable=self.animation_type, + ttk.Radiobutton(anim_type_frame, text=LocaleStrings.SET["blink"], 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)", + 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)) @@ -137,11 +137,11 @@ class SettingsDialog(tk.Toplevel): button_frame = ttk.Frame(main_frame) button_frame.pack(fill="x", pady=(10, 0)) - ttk.Button(button_frame, text="Auf Standard zurücksetzen", + 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="Speichern", + ttk.Button(button_frame, text=LocaleStrings.SET["save_button"], command=self.save_settings).pack(side="right", padx=5) - ttk.Button(button_frame, text="Abbrechen", + ttk.Button(button_frame, text=LocaleStrings.SET["cancel_button"], command=self.destroy).pack(side="right") def save_settings(self): diff --git a/cfd_ui_setup.py b/cfd_ui_setup.py index 541140d..17a822c 100644 --- a/cfd_ui_setup.py +++ b/cfd_ui_setup.py @@ -3,7 +3,8 @@ import shutil import tkinter as tk from tkinter import ttk from shared_libs.common_tools import Tooltip -from cfd_animated_icon import AnimatedIcon +from animated_icon import AnimatedIcon +from cfd_app_config import LocaleStrings, _ def get_xdg_user_dir(dir_key, fallback_name): @@ -129,22 +130,22 @@ class WidgetManager: self.back_button = ttk.Button(left_nav_container, image=self.dialog.icon_manager.get_icon( 'back'), command=self.dialog.navigation_manager.go_back, state=tk.DISABLED, style="Header.TButton.Borderless.Round") self.back_button.pack(side="left", padx=(10, 5)) - Tooltip(self.back_button, "Zurück") + Tooltip(self.back_button, LocaleStrings.UI["back"]) self.forward_button = ttk.Button(left_nav_container, image=self.dialog.icon_manager.get_icon( 'forward'), command=self.dialog.navigation_manager.go_forward, state=tk.DISABLED, style="Header.TButton.Borderless.Round") self.forward_button.pack(side="left", padx=5) - Tooltip(self.forward_button, "Vorwärts") + Tooltip(self.forward_button, LocaleStrings.UI["forward"]) self.up_button = ttk.Button(left_nav_container, image=self.dialog.icon_manager.get_icon( 'up'), command=self.dialog.navigation_manager.go_up_level, style="Header.TButton.Borderless.Round") self.up_button.pack(side="left", padx=5) - Tooltip(self.up_button, "Eine Ebene höher") + Tooltip(self.up_button, LocaleStrings.UI["up"]) self.home_button = ttk.Button(left_nav_container, image=self.dialog.icon_manager.get_icon( 'home'), command=lambda: self.dialog.navigation_manager.navigate_to(os.path.expanduser("~")), style="Header.TButton.Borderless.Round") self.home_button.pack(side="left", padx=(5, 10)) - Tooltip(self.home_button, "Home") + Tooltip(self.home_button, LocaleStrings.UI["home"]) # Path and search path_search_container = ttk.Frame(top_bar, style='Accent.TFrame') @@ -169,12 +170,12 @@ class WidgetManager: self.new_folder_button = ttk.Button(self.responsive_buttons_container, image=self.dialog.icon_manager.get_icon( 'new_folder_small'), command=self.dialog.file_op_manager.create_new_folder, style="Header.TButton.Borderless.Round") self.new_folder_button.pack(side="left", padx=5) - Tooltip(self.new_folder_button, "Neuen Ordner erstellen") + Tooltip(self.new_folder_button, LocaleStrings.UI["new_folder"]) self.new_file_button = ttk.Button(self.responsive_buttons_container, image=self.dialog.icon_manager.get_icon( 'new_document_small'), command=self.dialog.file_op_manager.create_new_file, style="Header.TButton.Borderless.Round") self.new_file_button.pack(side="left", padx=5) - Tooltip(self.new_file_button, "Neues Dokument erstellen") + Tooltip(self.new_file_button, LocaleStrings.UI["new_document"]) if self.dialog.dialog_mode == "open": self.new_folder_button.config(state=tk.DISABLED) @@ -185,17 +186,17 @@ class WidgetManager: self.icon_view_button = ttk.Button(self.view_switch, image=self.dialog.icon_manager.get_icon( 'icon_view'), command=self.dialog.view_manager.set_icon_view, style="Header.TButton.Active.Round") self.icon_view_button.pack(side="left", padx=5) - Tooltip(self.icon_view_button, "Kachelansicht") + Tooltip(self.icon_view_button, LocaleStrings.VIEW["icon_view"]) self.list_view_button = ttk.Button(self.view_switch, image=self.dialog.icon_manager.get_icon( 'list_view'), command=self.dialog.view_manager.set_list_view, style="Header.TButton.Borderless.Round") self.list_view_button.pack(side="left") - Tooltip(self.list_view_button, "Listenansicht") + Tooltip(self.list_view_button, LocaleStrings.VIEW["list_view"]) self.hidden_files_button = ttk.Button(self.responsive_buttons_container, image=self.dialog.icon_manager.get_icon( 'hide'), command=self.dialog.view_manager.toggle_hidden_files, style="Header.TButton.Borderless.Round") self.hidden_files_button.pack(side="left", padx=10) - Tooltip(self.hidden_files_button, "Versteckte Dateien anzeigen") + Tooltip(self.hidden_files_button, LocaleStrings.UI["show_hidden_files"]) self.more_button = ttk.Button(right_controls_container, text="...", command=self.dialog.show_more_menu, style="Header.TButton.Borderless.Round", width=3) @@ -222,12 +223,12 @@ class WidgetManager: sidebar_buttons_frame = ttk.Frame(sidebar_frame, style="Sidebar.TFrame", padding=(0, 15, 0, 0)) sidebar_buttons_frame.grid(row=0, column=0, sticky="nsew") sidebar_buttons_config = [ - {'name': 'Computer', 'icon': self.dialog.icon_manager.get_icon('computer_small'), 'path': '/'}, - {'name': 'Downloads', 'icon': self.dialog.icon_manager.get_icon('downloads_small'), 'path': get_xdg_user_dir("XDG_DOWNLOAD_DIR", "Downloads")}, - {'name': 'Dokumente', 'icon': self.dialog.icon_manager.get_icon('documents_small'), 'path': get_xdg_user_dir("XDG_DOCUMENTS_DIR", "Documents")}, - {'name': 'Bilder', 'icon': self.dialog.icon_manager.get_icon('pictures_small'), 'path': get_xdg_user_dir("XDG_PICTURES_DIR", "Pictures")}, - {'name': 'Musik', 'icon': self.dialog.icon_manager.get_icon('music_small'), 'path': get_xdg_user_dir("XDG_MUSIC_DIR", "Music")}, - {'name': 'Videos', 'icon': self.dialog.icon_manager.get_icon('video_small'), 'path': get_xdg_user_dir("XDG_VIDEO_DIR", "Videos")}, + {'name': LocaleStrings.NAV["computer"], 'icon': self.dialog.icon_manager.get_icon('computer_small'), 'path': '/'}, + {'name': LocaleStrings.NAV["downloads"], 'icon': self.dialog.icon_manager.get_icon('downloads_small'), 'path': get_xdg_user_dir("XDG_DOWNLOAD_DIR", "Downloads")}, + {'name': LocaleStrings.NAV["documents"], 'icon': self.dialog.icon_manager.get_icon('documents_small'), 'path': get_xdg_user_dir("XDG_DOCUMENTS_DIR", "Documents")}, + {'name': LocaleStrings.NAV["pictures"], 'icon': self.dialog.icon_manager.get_icon('pictures_small'), 'path': get_xdg_user_dir("XDG_PICTURES_DIR", "Pictures")}, + {'name': LocaleStrings.NAV["music"], 'icon': self.dialog.icon_manager.get_icon('music_small'), 'path': get_xdg_user_dir("XDG_MUSIC_DIR", "Music")}, + {'name': LocaleStrings.NAV["videos"], 'icon': self.dialog.icon_manager.get_icon('video_small'), 'path': get_xdg_user_dir("XDG_VIDEO_DIR", "Videos")}, ] self.sidebar_buttons = [] for config in sidebar_buttons_config: @@ -241,7 +242,7 @@ class WidgetManager: mounted_devices_frame.grid(row=2, column=0, sticky="nsew", padx=10) mounted_devices_frame.grid_columnconfigure(0, weight=1) - ttk.Label(mounted_devices_frame, text="Geräte:", background=self.style_manager.sidebar_color, + ttk.Label(mounted_devices_frame, text=LocaleStrings.UI["devices"], background=self.style_manager.sidebar_color, foreground=self.style_manager.color_foreground).grid(row=0, column=0, sticky="ew", padx=10, pady=(5, 0)) self.devices_canvas = tk.Canvas( @@ -327,7 +328,7 @@ class WidgetManager: def _setup_sidebar_storage(self, sidebar_frame): storage_frame = ttk.Frame(sidebar_frame, style="Sidebar.TFrame") storage_frame.grid(row=5, column=0, sticky="sew", padx=10, pady=10) - self.storage_label = ttk.Label(storage_frame, text="Freier Speicher:", background=self.style_manager.freespace_background) + self.storage_label = ttk.Label(storage_frame, text=f"{LocaleStrings.CFD["free_space"]}:", background=self.style_manager.freespace_background) self.storage_label.pack(fill="x", padx=10) self.storage_bar = ttk.Progressbar(storage_frame, orient="horizontal", length=100, mode="determinate") self.storage_bar.pack(fill="x", pady=(2, 5), padx=15) @@ -371,9 +372,9 @@ class WidgetManager: if self.dialog.dialog_mode == "save": self.trash_button = ttk.Button(self.action_status_frame, image=self.dialog.icon_manager.get_icon('trash_small2'), command=self.dialog.file_op_manager.delete_selected_item, style="Bottom.TButton.Borderless.Round") - Tooltip(self.trash_button, "Ausgewähltes Element löschen/verschieben") - self.save_button = ttk.Button(self.action_status_frame, text="Speichern", command=self.dialog.on_save) - self.cancel_button = ttk.Button(self.action_status_frame, text="Abbrechen", command=self.dialog.on_cancel) + Tooltip(self.trash_button, LocaleStrings.UI["delete_move"]) + self.save_button = ttk.Button(self.action_status_frame, text=LocaleStrings.SET["save_button"], command=self.dialog.on_save) + self.cancel_button = ttk.Button(self.action_status_frame, text=LocaleStrings.SET["cancel_button"], command=self.dialog.on_cancel) self.filter_combobox = ttk.Combobox(self.center_container, values=[ft[0] for ft in self.dialog.filetypes], state="readonly") self.filter_combobox.bind("<>", self.dialog.view_manager.on_filter_change) self.filter_combobox.set(self.dialog.filetypes[0][0]) @@ -383,8 +384,8 @@ class WidgetManager: self._layout_bottom_buttons(button_box_pos) else: # Open mode - self.open_button = ttk.Button(self.action_status_frame, text="Öffnen", command=self.dialog.on_open) - self.cancel_button = ttk.Button(self.action_status_frame, text="Abbrechen", command=self.dialog.on_cancel) + self.open_button = ttk.Button(self.action_status_frame, text=LocaleStrings.CFD["open"], command=self.dialog.on_open) + self.cancel_button = ttk.Button(self.action_status_frame, text=LocaleStrings.CFD["cancel"], command=self.dialog.on_cancel) self.filter_combobox = ttk.Combobox(self.center_container, values=[ft[0] for ft in self.dialog.filetypes], state="readonly") self.filter_combobox.bind("<>", self.dialog.view_manager.on_filter_change) self.filter_combobox.set(self.dialog.filetypes[0][0]) @@ -426,9 +427,6 @@ class WidgetManager: self.center_container.grid_columnconfigure(1, weight=1) self.filter_combobox.grid(in_=self.center_container, row=1, column=1, sticky="e", pady=(5, 0)) - #self.search_status_label.grid(row=0, column=0, sticky="w", pady=(5, 0), padx=(5, 0)) - - def setup_widgets(self): # Main container diff --git a/cfd_view_manager.py b/cfd_view_manager.py index 15e2516..b316393 100644 --- a/cfd_view_manager.py +++ b/cfd_view_manager.py @@ -3,7 +3,7 @@ import tkinter as tk from tkinter import ttk from datetime import datetime from shared_libs.common_tools import Tooltip -from cfd_app_config import AppConfig +from cfd_app_config import AppConfig, LocaleStrings, _ class ViewManager: def __init__(self, dialog): @@ -29,7 +29,7 @@ class ViewManager: num_items = len(items) warning_message = None if num_items > AppConfig.MAX_ITEMS_TO_DISPLAY: - warning_message = f"Zeige {AppConfig.MAX_ITEMS_TO_DISPLAY} von {num_items} Einträgen." + warning_message = f"{LocaleStrings.CFD['showing']} {AppConfig.MAX_ITEMS_TO_DISPLAY} {LocaleStrings.CFD['of']} {num_items} {LocaleStrings.CFD['entries']}." items = items[:AppConfig.MAX_ITEMS_TO_DISPLAY] dirs = sorted([d for d in items if os.path.isdir( os.path.join(self.dialog.current_dir, d))], key=str.lower) @@ -37,9 +37,9 @@ class ViewManager: os.path.join(self.dialog.current_dir, f))], key=str.lower) return (dirs + files, None, warning_message) except PermissionError: - return ([], "Zugriff verweigert.", None) + return ([], LocaleStrings.CFD["access_denied"], None) except FileNotFoundError: - return ([], "Verzeichnis nicht gefunden.", None) + return ([], LocaleStrings.CFD["directory_not_found"], None) def _get_folder_content_count(self, folder_path): try: @@ -232,13 +232,13 @@ class ViewManager: self.dialog.tree = ttk.Treeview( tree_frame, columns=columns, show="tree headings") - self.dialog.tree.heading("#0", text="Name", anchor="w") + self.dialog.tree.heading("#0", text=LocaleStrings.VIEW["name"], anchor="w") self.dialog.tree.column("#0", anchor="w", width=250, stretch=True) - self.dialog.tree.heading("size", text="Größe", anchor="e") + self.dialog.tree.heading("size", text=LocaleStrings.VIEW["size"], anchor="e") self.dialog.tree.column("size", anchor="e", width=120, stretch=False) - self.dialog.tree.heading("type", text="Typ", anchor="w") + self.dialog.tree.heading("type", text=LocaleStrings.VIEW["type"], anchor="w") self.dialog.tree.column("type", anchor="w", width=120, stretch=False) - self.dialog.tree.heading("modified", text="Geändert am", anchor="w") + self.dialog.tree.heading("modified", text=LocaleStrings.VIEW["date_modified"], anchor="w") self.dialog.tree.column("modified", anchor="w", width=160, stretch=False) v_scrollbar = ttk.Scrollbar( @@ -294,10 +294,10 @@ class ViewManager: stat.st_mtime).strftime('%d.%m.%Y %H:%M') if is_dir: icon, file_type, size = self.dialog.icon_manager.get_icon( - 'folder_small'), "Ordner", "" + 'folder_small'), LocaleStrings.FILE["folder"], "" else: icon, file_type, size = self.dialog.get_file_icon( - name, 'small'), "Datei", self.dialog._format_size(stat.st_size) + name, 'small'), LocaleStrings.FILE["file"], self.dialog._format_size(stat.st_size) item_id = self.dialog.tree.insert("", "end", text=f" {name}", image=icon, values=( size, file_type, modified_time)) if name == item_to_rename: @@ -446,12 +446,12 @@ class ViewManager: self.dialog.widget_manager.hidden_files_button.config( image=self.dialog.icon_manager.get_icon('unhide')) Tooltip(self.dialog.widget_manager.hidden_files_button, - "Versteckte Dateien ausblenden") + LocaleStrings.UI["hide_hidden_files"]) else: self.dialog.widget_manager.hidden_files_button.config( image=self.dialog.icon_manager.get_icon('hide')) Tooltip(self.dialog.widget_manager.hidden_files_button, - "Versteckte Dateien anzeigen") + LocaleStrings.UI["show_hidden_files"]) self.populate_files() def on_filter_change(self, event): diff --git a/custom_file_dialog.py b/custom_file_dialog.py index a0f12dd..b733a8b 100644 --- a/custom_file_dialog.py +++ b/custom_file_dialog.py @@ -8,9 +8,9 @@ import json import threading from shared_libs.message import MessageDialog from shared_libs.common_tools import IconManager, Tooltip, ConfigManager, LxTools -from cfd_app_config import AppConfig, CfdConfigManager +from cfd_app_config import AppConfig, CfdConfigManager, LocaleStrings, _ from cfd_ui_setup import StyleManager, WidgetManager, get_xdg_user_dir -from cfd_animated_icon import AnimatedIcon, PIL_AVAILABLE +from animated_icon import AnimatedIcon, PIL_AVAILABLE from cfd_settings_dialog import SettingsDialog from cfd_file_operations import FileOperationsManager from cfd_search_manager import SearchManager @@ -18,7 +18,7 @@ from cfd_navigation_manager import NavigationManager from cfd_view_manager import ViewManager class CustomFileDialog(tk.Toplevel): - def __init__(self, parent, initial_dir=None, filetypes=None, dialog_mode="open", title="File Dialog"): + def __init__(self, parent, initial_dir=None, filetypes=None, dialog_mode="open", title=LocaleStrings.CFD["title"]): super().__init__(parent) self.my_tool_tip = None @@ -43,7 +43,7 @@ class CustomFileDialog(tk.Toplevel): self.selected_file = None self.current_dir = os.path.abspath( initial_dir) if initial_dir else os.path.expanduser("~") - self.filetypes = filetypes if filetypes else [("Alle Dateien", "*.* ")] + self.filetypes = filetypes if filetypes else [(LocaleStrings.CFD["all_files"], "*.* ")] self.current_filter_pattern = self.filetypes[0][1] self.history = [] self.history_pos = -1 @@ -228,18 +228,18 @@ class CustomFileDialog(tk.Toplevel): is_writable = os.access(self.current_dir, os.W_OK) creation_state = tk.NORMAL if is_writable and self.dialog_mode != "open" else tk.DISABLED - more_menu.add_command(label="Neuer Ordner", command=self.file_op_manager.create_new_folder, + more_menu.add_command(label=LocaleStrings.UI["new_folder"], command=self.file_op_manager.create_new_folder, image=self.icon_manager.get_icon('new_folder_small'), compound='left', state=creation_state) - more_menu.add_command(label="Neues Dokument", command=self.file_op_manager.create_new_file, + more_menu.add_command(label=LocaleStrings.UI["new_document"], command=self.file_op_manager.create_new_file, image=self.icon_manager.get_icon('new_document_small'), compound='left', state=creation_state) more_menu.add_separator() - more_menu.add_command(label="Kachelansicht", command=self.view_manager.set_icon_view, + more_menu.add_command(label=LocaleStrings.VIEW["icon_view"], command=self.view_manager.set_icon_view, image=self.icon_manager.get_icon('icon_view'), compound='left') - more_menu.add_command(label="Listenansicht", command=self.view_manager.set_list_view, + more_menu.add_command(label=LocaleStrings.VIEW["list_view"], command=self.view_manager.set_list_view, image=self.icon_manager.get_icon('list_view'), compound='left') more_menu.add_separator() - hidden_files_label = "Versteckte Dateien ausblenden" if self.show_hidden_files.get() else "Versteckte Dateien anzeigen" + hidden_files_label = LocaleStrings.UI["hide_hidden_files"] if self.show_hidden_files.get() else LocaleStrings.UI["show_hidden_files"] hidden_files_icon = self.icon_manager.get_icon( 'unhide') if self.show_hidden_files.get() else self.icon_manager.get_icon('hide') more_menu.add_command(label=hidden_files_label, command=self.view_manager.toggle_hidden_files, @@ -296,7 +296,7 @@ class CustomFileDialog(tk.Toplevel): total, used, free = shutil.disk_usage(self.current_dir) free_str = self._format_size(free) self.widget_manager.storage_label.config( - text=f"Freier Speicher: {free_str}") + text=f"{LocaleStrings.CFD["free_space"]}: {free_str}") self.widget_manager.storage_bar['value'] = (used / total) * 100 status_text = "" @@ -305,19 +305,19 @@ class CustomFileDialog(tk.Toplevel): content_count = self.view_manager._get_folder_content_count( selected_path) if content_count is not None: - status_text = f"'{os.path.basename(selected_path)}' ({content_count} Einträge)" + status_text = f"'{os.path.basename(selected_path)}' ({content_count} {LocaleStrings.CFD["entries"]})" else: status_text = f"'{os.path.basename(selected_path)}'" else: size = os.path.getsize(selected_path) size_str = self._format_size(size) - status_text = f"'{os.path.basename(selected_path)}' Größe: {size_str}" + status_text = f"'{os.path.basename(selected_path)}' {LocaleStrings.VIEW["size"]}: {size_str}" self.widget_manager.search_status_label.config(text=status_text) except FileNotFoundError: self.widget_manager.search_status_label.config( - text="Verzeichnis nicht gefunden") + text=LocaleStrings.CFD["directory_not_found"]) self.widget_manager.storage_label.config( - text="Freier Speicher: Unbekannt") + text=f"{LocaleStrings.CFD["free_space"]}: {LocaleStrings.CFD["unknown"]}") self.widget_manager.storage_bar['value'] = 0 def on_open(self): @@ -435,7 +435,7 @@ class CustomFileDialog(tk.Toplevel): if hasattr(self, 'tooltip_window') and self.tooltip_window.winfo_exists(): return - tooltip_text = "Suche starten" if not self.widget_manager.search_animation.running else "Suche abbrechen" + tooltip_text = LocaleStrings.UI["start_search"] if not self.widget_manager.search_animation.running else LocaleStrings.UI["cancel_search"] x = self.widget_manager.search_animation.winfo_rootx() + 25 y = self.widget_manager.search_animation.winfo_rooty() + 25 diff --git a/mainwindow.py b/mainwindow.py index 54b0a35..e764fb1 100755 --- a/mainwindow.py +++ b/mainwindow.py @@ -34,7 +34,7 @@ class GlotzMol(tk.Tk): initial_dir=os.path.expanduser("~"), filetypes=[("All Files", "*.*"), ("Wireguard config Files", "*.conf") - ]) + ], dialog_mode="save") # This is the crucial part: wait for the dialog to be closed self.wait_window(dialog)