diff --git a/__pycache__/cfd_ui_setup.cpython-312.pyc b/__pycache__/cfd_ui_setup.cpython-312.pyc index 590a5c2..ddc02ff 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__/custom_file_dialog.cpython-312.pyc b/__pycache__/custom_file_dialog.cpython-312.pyc index a049d2d..c4cee9b 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_ui_setup.py b/cfd_ui_setup.py index afbd2a8..198fffd 100644 --- a/cfd_ui_setup.py +++ b/cfd_ui_setup.py @@ -2,60 +2,7 @@ import os import shutil import tkinter as tk from tkinter import ttk -import subprocess -import json -from shared_libs.common_tools import Tooltip, LxTools - - -class InputDialog(tk.Toplevel): - def __init__(self, parent, title, prompt): - super().__init__(parent) - self.title(title) - self.prompt = prompt - self.result = None - - self.transient(parent) - self.grab_set() - - self.setup_widgets() - LxTools.center_window_cross_platform(self, 300, 120) - self.entry.focus_set() - - self.bind("", self.on_ok) - self.bind("", self.on_cancel) - - self.protocol("WM_DELETE_WINDOW", self.on_cancel) - self.wait_window(self) - - def setup_widgets(self): - main_frame = ttk.Frame(self, padding=10) - main_frame.pack(fill="both", expand=True) - - ttk.Label(main_frame, text=self.prompt).pack(pady=5) - - self.entry = ttk.Entry(main_frame, width=40) - self.entry.pack(pady=5, padx=5) - - button_frame = ttk.Frame(main_frame) - button_frame.pack(pady=10) - - ok_button = ttk.Button(button_frame, text="OK", command=self.on_ok) - ok_button.pack(side="left", padx=5) - - cancel_button = ttk.Button( - button_frame, text="Abbrechen", command=self.on_cancel) - cancel_button.pack(side="left", padx=5) - - def on_ok(self, event=None): - self.result = self.entry.get() - self.destroy() - - def on_cancel(self, event=None): - self.result = None - self.destroy() - - def get_input(self): - return self.result +from shared_libs.common_tools import Tooltip def get_xdg_user_dir(dir_key, fallback_name): @@ -178,12 +125,12 @@ class WidgetManager: self.back_button = ttk.Button(nav_buttons_container, image=self.dialog.icon_manager.get_icon( 'back'), command=self.dialog.go_back, state=tk.DISABLED, style="Header.TButton.Borderless.Round") - self.back_button.pack(side="left", padx=10) + self.back_button.pack(side="left", padx=20) Tooltip(self.back_button, "Zurück") self.forward_button = ttk.Button(nav_buttons_container, image=self.dialog.icon_manager.get_icon( 'forward'), command=self.dialog.go_forward, state=tk.DISABLED, style="Header.TButton.Borderless.Round") - self.forward_button.pack(side="left") + self.forward_button.pack(side="left", padx=(0, 20)) Tooltip(self.forward_button, "Vorwärts") self.home_button = ttk.Button(nav_buttons_container, image=self.dialog.icon_manager.get_icon( @@ -201,16 +148,6 @@ class WidgetManager: right_top_bar_frame = ttk.Frame(top_bar, style='Accent.TFrame') right_top_bar_frame.grid(row=0, column=2, sticky="e") - self.new_folder_button = ttk.Button(right_top_bar_frame, image=self.dialog.icon_manager.get_icon( - 'new_folder_small'), command=self.dialog.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") - - self.new_file_button = ttk.Button(right_top_bar_frame, image=self.dialog.icon_manager.get_icon( - 'new_document_small'), command=self.dialog.create_new_file, style="Header.TButton.Borderless.Round") - self.new_file_button.pack(side="left", padx=(0, 10)) - Tooltip(self.new_file_button, "Neues Dokument erstellen") - # Search button and options container search_container = ttk.Frame( right_top_bar_frame, style='Accent.TFrame') @@ -232,13 +169,23 @@ class WidgetManager: self.recursive_button.pack(side="left", padx=2) Tooltip(self.recursive_button, "Rekursive Suche ein/ausschalten") + self.new_folder_button = ttk.Button(right_top_bar_frame, image=self.dialog.icon_manager.get_icon( + 'new_folder_small'), command=self.dialog.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") + + self.new_file_button = ttk.Button(right_top_bar_frame, image=self.dialog.icon_manager.get_icon( + 'new_document_small'), command=self.dialog.create_new_file, style="Header.TButton.Borderless.Round") + self.new_file_button.pack(side="left", padx=(0, 10)) + Tooltip(self.new_file_button, "Neues Dokument erstellen") + view_switch = ttk.Frame(right_top_bar_frame, padding=(5, 0), style='Accent.TFrame') view_switch.pack(side="left") self.icon_view_button = ttk.Button(view_switch, image=self.dialog.icon_manager.get_icon( 'icon_view'), command=self.dialog.set_icon_view, style="Header.TButton.Active.Round") - self.icon_view_button.pack(side="left", padx=(50, 10)) + self.icon_view_button.pack(side="left", padx=(5, 10)) Tooltip(self.icon_view_button, "Kachelansicht") self.list_view_button = ttk.Button(view_switch, image=self.dialog.icon_manager.get_icon( @@ -257,7 +204,8 @@ class WidgetManager: row=1, column=0, columnspan=2, sticky="ew") # PanedWindow for resizable sidebar and content - paned_window = ttk.PanedWindow(main_frame, orient=tk.HORIZONTAL) + paned_window = ttk.PanedWindow( + main_frame, orient=tk.HORIZONTAL, style="Sidebar.TFrame") paned_window.grid(row=2, column=0, columnspan=2, sticky="nsew") # Sidebar @@ -415,42 +363,35 @@ class WidgetManager: # Status bar (top-left in the bottom area) self.status_bar = ttk.Label( bottom_controls_frame, text="", anchor="w", style="AccentBottom.TLabel") - self.status_bar.grid(row=0, column=0, columnspan=2, + self.status_bar.grid(row=0, column=1, columnspan=2, sticky="w", padx=10, pady=5) - # New folder/file buttons (top-right in the bottom area) - right_top_buttons = ttk.Frame( - bottom_controls_frame, style="AccentBottom.TFrame") - right_top_buttons.grid(row=0, column=2, sticky="e") - - self.new_folder_button = ttk.Button(right_top_buttons, image=self.dialog.icon_manager.get_icon( - 'new_folder_small'), command=self.dialog.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") - - self.new_file_button = ttk.Button(right_top_buttons, image=self.dialog.icon_manager.get_icon( - 'new_document_small'), command=self.dialog.create_new_file, style="Header.TButton.Borderless.Round") - self.new_file_button.pack(side="left", padx=(0, 10)) - Tooltip(self.new_file_button, "Neues Dokument erstellen") - # Main action buttons (bottom-left) - left_bottom_buttons = ttk.Frame(bottom_controls_frame, style="AccentBottom.TFrame") - left_bottom_buttons.grid(row=1, column=0, sticky="w", pady=(5, 10)) + left_bottom_buttons = ttk.Frame( + bottom_controls_frame, style="AccentBottom.TFrame") + left_bottom_buttons.grid(row=0, column=0, sticky="w", pady=(5, 10)) if self.dialog.dialog_mode == "save": self.filename_entry = ttk.Entry(left_bottom_buttons, width=50) - self.filename_entry.grid(row=0, column=0, padx=(10,5), pady=5, sticky="ew") + self.filename_entry.grid( + row=0, column=1, padx=(5, 5), pady=5, sticky="ew") left_bottom_buttons.grid_columnconfigure(0, weight=1) - ttk.Button(left_bottom_buttons, text="Speichern", command=self.dialog.on_save).grid(row=0, column=1, padx=5) - ttk.Button(left_bottom_buttons, text="Abbrechen", command=self.dialog.on_cancel).grid(row=0, column=2, padx=5) + ttk.Button(left_bottom_buttons, text="Speichern", + command=self.dialog.on_save).grid(row=0, column=0, padx=(10, 5), pady=10) + ttk.Button(left_bottom_buttons, text="Abbrechen", + command=self.dialog.on_cancel).grid(row=1, column=0, padx=(10, 5)) else: - ttk.Button(left_bottom_buttons, text="Öffnen", command=self.dialog.on_open).grid(row=0, column=0, padx=(10, 5)) - ttk.Button(left_bottom_buttons, text="Abbrechen", command=self.dialog.on_cancel).grid(row=0, column=1, padx=5) - + ttk.Button(left_bottom_buttons, text="Öffnen", command=self.dialog.on_open).grid( + row=0, column=0, padx=(10, 5), pady=10) + ttk.Button(left_bottom_buttons, text="Abbrechen", + command=self.dialog.on_cancel).grid(row=1, column=0, padx=(10, 5)) # Filter combobox (bottom-right) - self.filter_combobox = ttk.Combobox(bottom_controls_frame, values=[ft[0] for ft in self.dialog.filetypes], state="readonly") - self.filter_combobox.grid(row=1, column=2, sticky="e", padx=(0, 10), pady=(5, 10)) - self.filter_combobox.bind("<>", self.dialog.on_filter_change) + self.filter_combobox = ttk.Combobox(left_bottom_buttons, values=[ + ft[0] for ft in self.dialog.filetypes], state="readonly") + self.filter_combobox.grid( + row=1, column=1, sticky="w", padx=(5, 10)) + self.filter_combobox.bind( + "<>", self.dialog.on_filter_change) self.filter_combobox.set(self.dialog.filetypes[0][0]) diff --git a/custom_file_dialog.py b/custom_file_dialog.py index 25e3d29..f185e31 100644 --- a/custom_file_dialog.py +++ b/custom_file_dialog.py @@ -8,7 +8,7 @@ import json from shared_libs.message import MessageDialog from shared_libs.common_tools import IconManager, Tooltip, ConfigManager, LxTools, ThemeManager from cfd_app_config import AppConfig -from cfd_ui_setup import StyleManager, WidgetManager, get_xdg_user_dir, InputDialog +from cfd_ui_setup import StyleManager, WidgetManager, get_xdg_user_dir # Helper to make icon paths robust, so the script can be run from anywhere @@ -60,7 +60,7 @@ class CustomFileDialog(tk.Toplevel): self.icon_manager = IconManager() self.style_manager = StyleManager(self) self.widget_manager = WidgetManager(self) - + self.navigate_to(self.current_dir) def get_file_icon(self, filename, size='large'): @@ -88,11 +88,13 @@ class CustomFileDialog(tk.Toplevel): if self.show_hidden_files.get(): self.widget_manager.hidden_files_button.config( image=self.icon_manager.get_icon('unhide')) - Tooltip(self.widget_manager.hidden_files_button, "Versteckte Dateien ausblenden") + Tooltip(self.widget_manager.hidden_files_button, + "Versteckte Dateien ausblenden") else: self.widget_manager.hidden_files_button.config( image=self.icon_manager.get_icon('hide')) - Tooltip(self.widget_manager.hidden_files_button, "Versteckte Dateien anzeigen") + Tooltip(self.widget_manager.hidden_files_button, + "Versteckte Dateien anzeigen") self.populate_files() def on_window_resize(self, event): @@ -123,7 +125,8 @@ class CustomFileDialog(tk.Toplevel): def _on_devices_enter(self, event): """Show scrollbar when mouse enters devices area""" - self.widget_manager.devices_scrollbar.grid(row=1, column=1, sticky="ns") + self.widget_manager.devices_scrollbar.grid( + row=1, column=1, sticky="ns") def _on_devices_leave(self, event): """Hide scrollbar when mouse leaves devices area""" @@ -148,11 +151,14 @@ class CustomFileDialog(tk.Toplevel): self.original_path_text = self.widget_manager.path_entry.get() self.widget_manager.path_entry.delete(0, tk.END) self.widget_manager.path_entry.insert(0, "Suchbegriff eingeben...") - self.widget_manager.path_entry.bind("", self.execute_search) - self.widget_manager.path_entry.bind("", self.clear_search_placeholder) + self.widget_manager.path_entry.bind( + "", self.execute_search) + self.widget_manager.path_entry.bind( + "", self.clear_search_placeholder) # Show search options - self.widget_manager.search_options_frame.pack(side="left", padx=(5, 0)) + self.widget_manager.search_options_frame.pack( + side="left", padx=(5, 0)) else: # Exit search mode self.search_mode = False @@ -170,7 +176,8 @@ class CustomFileDialog(tk.Toplevel): def toggle_recursive_search(self): """Toggle recursive search on/off and update button style""" - self.widget_manager.recursive_search.set(not self.widget_manager.recursive_search.get()) + self.widget_manager.recursive_search.set( + not self.widget_manager.recursive_search.get()) if self.widget_manager.recursive_search.get(): self.widget_manager.recursive_button.configure( style="Header.TButton.Active.Round") @@ -181,7 +188,8 @@ class CustomFileDialog(tk.Toplevel): def set_icon_view(self): """Set icon view and update button styles""" self.view_mode.set("icons") - self.widget_manager.icon_view_button.configure(style="Header.TButton.Active.Round") + self.widget_manager.icon_view_button.configure( + style="Header.TButton.Active.Round") self.widget_manager.list_view_button.configure( style="Header.TButton.Borderless.Round") self.populate_files() @@ -189,7 +197,8 @@ class CustomFileDialog(tk.Toplevel): def set_list_view(self): """Set list view and update button styles""" self.view_mode.set("list") - self.widget_manager.list_view_button.configure(style="Header.TButton.Active.Round") + self.widget_manager.list_view_button.configure( + style="Header.TButton.Active.Round") self.widget_manager.icon_view_button.configure( style="Header.TButton.Borderless.Round") self.populate_files() @@ -473,7 +482,8 @@ class CustomFileDialog(tk.Toplevel): else: icon = self.icon_manager.get_icon('folder_large') if is_dir else self.get_file_icon( name, 'large') - icon_label = ttk.Label(item_frame, image=icon, style="Icon.TLabel") + icon_label = ttk.Label( + item_frame, image=icon, style="Icon.TLabel") icon_label.pack(pady=(10, 5)) name_label = ttk.Label(item_frame, text=self.shorten_text( name, 14), anchor="center", style="Item.TLabel") @@ -488,7 +498,8 @@ class CustomFileDialog(tk.Toplevel): widget.bind("", _on_mouse_wheel) widget.bind("", _on_mouse_wheel) widget.bind("", _on_mouse_wheel) - widget.bind("", lambda e, p=path, f=item_frame: self.on_rename_request(e, p, f)) + widget.bind("", lambda e, p=path, + f=item_frame: self.on_rename_request(e, p, f)) col = (col + 1) % col_count if col == 0: @@ -598,9 +609,10 @@ class CustomFileDialog(tk.Toplevel): if not self.tree.selection(): return item_id = self.tree.selection()[0] - item_path = os.path.join(self.current_dir, self.tree.item(item_id, "text").strip()) + item_path = os.path.join( + self.current_dir, self.tree.item(item_id, "text").strip()) self.start_rename(item_id, item_path) - else: # icon view + else: # icon view if item_path and item_frame: self.start_rename(item_frame, item_path) @@ -693,7 +705,8 @@ class CustomFileDialog(tk.Toplevel): try: 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}") + self.widget_manager.storage_label.config( + text=f"Freier Speicher: {free_str}") self.widget_manager.storage_bar['value'] = (used / total) * 100 status_text = "" @@ -703,8 +716,10 @@ class CustomFileDialog(tk.Toplevel): status_text = f"'{os.path.basename(self.selected_file)}' Größe: {size_str}" self.widget_manager.status_bar.config(text=status_text) except FileNotFoundError: - self.widget_manager.status_bar.config(text="Verzeichnis nicht gefunden") - self.widget_manager.storage_label.config(text="Freier Speicher: Unbekannt") + self.widget_manager.status_bar.config( + text="Verzeichnis nicht gefunden") + self.widget_manager.storage_label.config( + text="Freier Speicher: Unbekannt") self.widget_manager.storage_bar['value'] = 0 def on_open(self): @@ -744,7 +759,8 @@ class CustomFileDialog(tk.Toplevel): open(new_path, 'a').close() self.populate_files(item_to_rename=new_name) except Exception as e: - self.widget_manager.status_bar.config(text=f"Fehler beim Erstellen: {e}") + self.widget_manager.status_bar.config( + text=f"Fehler beim Erstellen: {e}") def _get_unique_name(self, base_name): name, ext = os.path.splitext(base_name) @@ -758,8 +774,8 @@ class CustomFileDialog(tk.Toplevel): def start_rename(self, item_widget, item_path): if self.view_mode.get() == "icons": self._start_rename_icon_view(item_widget, item_path) - else: # list view - self._start_rename_list_view(item_widget) # item_widget is item_id + else: # list view + self._start_rename_list_view(item_widget) # item_widget is item_id def _start_rename_icon_view(self, item_frame, item_path): for child in item_frame.winfo_children(): @@ -776,13 +792,15 @@ class CustomFileDialog(tk.Toplevel): new_path = os.path.join(self.current_dir, new_name) if new_name and new_path != item_path: if os.path.exists(new_path): - self.widget_manager.status_bar.config(text=f"'{new_name}' existiert bereits.") + self.widget_manager.status_bar.config( + text=f"'{new_name}' existiert bereits.") self.populate_files() return try: os.rename(item_path, new_path) except Exception as e: - self.widget_manager.status_bar.config(text=f"Fehler beim Umbenennen: {e}") + self.widget_manager.status_bar.config( + text=f"Fehler beim Umbenennen: {e}") self.populate_files() def cancel_rename(event): @@ -809,12 +827,14 @@ class CustomFileDialog(tk.Toplevel): if new_name and new_path != old_path: if os.path.exists(new_path): - self.widget_manager.status_bar.config(text=f"'{new_name}' existiert bereits.") + self.widget_manager.status_bar.config( + text=f"'{new_name}' existiert bereits.") else: try: os.rename(old_path, new_path) except Exception as e: - self.widget_manager.status_bar.config(text=f"Fehler beim Umbenennen: {e}") + self.widget_manager.status_bar.config( + text=f"Fehler beim Umbenennen: {e}") entry.destroy() self.populate_files() @@ -842,8 +862,6 @@ class CustomFileDialog(tk.Toplevel): return True return False - - def _format_size(self, size_bytes): if size_bytes is None: return "" diff --git a/mainwindow.py b/mainwindow.py index c0bd05e..19db77e 100755 --- a/mainwindow.py +++ b/mainwindow.py @@ -55,7 +55,7 @@ if __name__ == "__main__": style = ttk.Style(root) root.tk.call('source', f"{theme_path}/water.tcl") try: - root.tk.call('set_theme', 'light') + root.tk.call('set_theme', 'dark') except tk.TclError: pass root.mainloop()