commit 11

This commit is contained in:
2025-07-27 21:02:22 +02:00
parent 872513f348
commit 11f8d0e2fd
3 changed files with 131 additions and 50 deletions

View File

@@ -128,13 +128,20 @@ class CustomFileDialog(tk.Toplevel):
'file_small': '/usr/share/icons/lx-icons/32/document-32.png', 'python_small': '/usr/share/icons/lx-icons/32/file-python-32.png',
'pdf_small': '/usr/share/icons/lx-icons/32/pdf-32.png', 'archive_small': '/usr/share/icons/lx-icons/32/tar-32.png',
'audio_small': '/usr/share/icons/lx-icons/32/audio-32.png', 'video_small_file': '/usr/share/icons/lx-icons/32/video-32.png',
'picture_small': '/usr/share/icons/lx-icons/32/picture-32.png', 'iso_small': '/usr/share/icons/lx-icons/32/media-optical-32.png'
'picture_small': '/usr/share/icons/lx-icons/32/picture-32.png', 'iso_small': '/usr/share/icons/lx-icons/32/media-optical-32.png',
'list_view': '/usr/share/icons/lx-icons/32/list-32.png',
'icon_view': '/usr/share/icons/lx-icons/32/carrel-32.png',
'hide': '/usr/share/icons/lx-icons/32/hide-32.png',
'unhide': '/usr/share/icons/lx-icons/32/unhide-32.png',
'back': '/usr/share/icons/lx-icons/32/arrow-left-32.png',
'forward': '/usr/share/icons/lx-icons/32/arrow-right-32.png',
'home': '/usr/share/icons/lx-icons/32/home-32.png'
}
for key, filename in icon_files.items():
try:
self.icons[key] = tk.PhotoImage(file=get_icon_path(filename))
except tk.TclError:
size = 32 if 'small' in key else 64
size = 32 if 'small' in key or 'view' in key or 'hide' in key or 'unhide' in key or 'back' in key or 'forward' in key or 'home' in key else 64
self.icons[key] = tk.PhotoImage(width=size, height=size)
def get_file_icon(self, filename, size='large'):
@@ -178,6 +185,8 @@ class CustomFileDialog(tk.Toplevel):
style.map("Sidebar.TButton", background=[
('active', self.selection_color)])
style.configure("Sidebar.TLabel", background=self.sidebar_color,
foreground="black" if not is_dark else "white")
style.configure("Content.TFrame", background=self.icon_bg_color)
style.configure("Item.TFrame", background=self.icon_bg_color)
style.map('Item.TFrame', background=[
@@ -189,34 +198,56 @@ class CustomFileDialog(tk.Toplevel):
style.map('Icon.TLabel', background=[
('selected', self.selection_color)])
style.configure("Treeview.Heading", relief="raised",
borderwidth=1, font=('TkDefaultFont', 10, 'bold'))
style.configure("Treeview.Heading", relief="flat",
borderwidth=0, font=('TkDefaultFont', 10, 'bold'))
style.configure("Treeview", rowheight=28,
background=self.icon_bg_color, fieldbackground=self.icon_bg_color)
style.map("Treeview", background=[('selected', self.selection_color)], foreground=[
('selected', "black" if not is_dark else "white")])
style.configure("Toolbutton.TCheckbutton", padding=5,
relief="flat", background=self.icon_bg_color)
style.map("Toolbutton.TCheckbutton",
background=[('active', self.selection_color)],
)
style.configure("Toolbutton.TRadiobutton", padding=5,
relief="flat", background=self.icon_bg_color)
style.map("Toolbutton.TRadiobutton",
background=[('active', self.selection_color)],
)
style.configure("Toolbutton.TButton", padding=0,
relief="flat", background=self.sidebar_color)
style.map("Toolbutton.TButton",
background=[('active', self.selection_color)],
)
def create_widgets(self):
main_frame = ttk.Frame(self, padding=(0, 0, 10, 0))
main_frame.pack(fill="both", expand=True)
paned_window = ttk.PanedWindow(main_frame, orient=tk.HORIZONTAL)
paned_window.pack(fill="both", expand=True)
sidebar_frame = ttk.Frame(paned_window, padding=(
15, 5, 15, 0), style="Sidebar.TFrame")
15, 10, 15, 15), style="Sidebar.TFrame")
paned_window.add(sidebar_frame, weight=0)
paned_window.pane(0, weight=0)
sidebar_frame.grid_rowconfigure(1, weight=1)
sidebar_nav_frame = ttk.Frame(sidebar_frame, style="Sidebar.TFrame")
sidebar_nav_frame.grid(row=0, column=0, sticky="ew", pady=(0, 10))
self.back_button = ttk.Button(
sidebar_nav_frame, text="", command=self.go_back, state=tk.DISABLED, width=3)
sidebar_nav_frame, image=self.icons['back'], command=self.go_back, state=tk.DISABLED, style="Toolbutton.TButton")
self.back_button.pack(side="left", fill="x", expand=True)
self.home_button = ttk.Button(sidebar_nav_frame, text="🏠", command=lambda: self.navigate_to(
os.path.expanduser("~")), width=3)
Tooltip(self.back_button, "Zurück")
self.home_button = ttk.Button(sidebar_nav_frame, image=self.icons['home'], command=lambda: self.navigate_to(
os.path.expanduser("~")), style="Toolbutton.TButton")
self.home_button.pack(side="left", fill="x", expand=True, padx=2)
Tooltip(self.home_button, "Home")
self.forward_button = ttk.Button(
sidebar_nav_frame, text="", command=self.go_forward, state=tk.DISABLED, width=3)
sidebar_nav_frame, image=self.icons['forward'], command=self.go_forward, state=tk.DISABLED, style="Toolbutton.TButton")
self.forward_button.pack(side="left", fill="x", expand=True)
sidebar_buttons_frame = ttk.Frame(
@@ -241,33 +272,43 @@ class CustomFileDialog(tk.Toplevel):
compound="top", command=lambda p=config['path']: self.navigate_to(p), style="Sidebar.TButton")
btn.pack(fill="x", pady=1)
storage_frame = ttk.Frame(sidebar_frame, style="Sidebar.TFrame")
storage_frame.grid(row=2, column=0, sticky="ew", pady=(10, 0), padx=10)
self.storage_label = ttk.Label(
storage_frame, text="Freier Speicher:", style="Sidebar.TLabel")
self.storage_label.pack(fill="x")
self.storage_bar = ttk.Progressbar(
storage_frame, orient="horizontal", length=100, mode="determinate")
self.storage_bar.pack(fill="x", pady=(2, 10))
content_frame = ttk.Frame(paned_window, padding=(5, 0, 0, 0))
paned_window.add(content_frame, weight=1)
content_frame.grid_rowconfigure(2, weight=1)
content_frame.grid_columnconfigure(0, weight=1)
top_bar = ttk.Frame(content_frame)
top_bar.grid(row=0, column=0, sticky="ew", pady=(5, 0))
top_bar.grid(row=0, column=0, sticky="ew", pady=(10, 0))
top_bar.grid_columnconfigure(0, weight=1)
self.path_entry = ttk.Entry(top_bar)
self.path_entry.grid(row=0, column=0, sticky="ew")
self.path_entry.bind(
"<Return>", lambda e: self.navigate_to(self.path_entry.get()))
self.hidden_files_button = ttk.Checkbutton(
top_bar, text="Versteckte Dateien", variable=self.show_hidden_files, command=self.populate_files)
self.hidden_files_button.grid(row=0, column=1, padx=5)
view_switch = ttk.Frame(top_bar, padding=(5, 0))
view_switch.grid(row=0, column=2)
ttk.Radiobutton(view_switch, text="Kacheln", variable=self.view_mode,
value="icons", command=self.populate_files).pack(side="left")
ttk.Radiobutton(view_switch, text="Liste", variable=self.view_mode,
value="list", command=self.populate_files).pack(side="left")
self.filter_combobox = ttk.Combobox(
top_bar, values=[ft[0] for ft in self.filetypes], state="readonly", width=20)
self.filter_combobox.grid(row=0, column=3, padx=5)
self.filter_combobox.bind(
"<<ComboboxSelected>>", self.on_filter_change)
self.filter_combobox.set(self.filetypes[0][0])
view_switch.grid(row=0, column=1)
self.icon_view_button = ttk.Button(view_switch, image=self.icons['icon_view'], command=lambda: (
self.view_mode.set("icons"), self.populate_files()), style="Toolbutton.TButton")
self.icon_view_button.pack(side="left")
Tooltip(self.icon_view_button, "Kachelansicht")
self.list_view_button = ttk.Button(view_switch, image=self.icons['list_view'], command=lambda: (
self.view_mode.set("list"), self.populate_files()), style="Toolbutton.TButton")
self.list_view_button.pack(side="left")
Tooltip(self.list_view_button, "Listenansicht")
self.hidden_files_button = ttk.Button(
top_bar, image=self.icons['hide'], command=self.toggle_hidden_files, style="Toolbutton.TButton")
self.hidden_files_button.grid(row=0, column=2, padx=5)
Tooltip(self.hidden_files_button, "Versteckte Dateien anzeigen")
ttk.Separator(content_frame, orient='horizontal').grid(
row=1, column=0, sticky="ew", pady=5)
@@ -276,17 +317,40 @@ class CustomFileDialog(tk.Toplevel):
self.file_list_frame.grid(row=2, column=0, sticky="nsew")
self.bind("<Configure>", self.on_window_resize)
bottom_frame = ttk.Frame(content_frame)
bottom_frame.grid(row=3, column=0, sticky="ew", pady=(5, 0))
bottom_frame.grid_columnconfigure(0, weight=1)
self.status_bar = ttk.Label(bottom_frame, text="", anchor="w")
bottom_controls_frame = ttk.Frame(content_frame)
bottom_controls_frame.grid(row=3, column=0, sticky="ew", pady=(5, 0))
bottom_controls_frame.grid_columnconfigure(0, weight=1)
self.status_bar = ttk.Label(bottom_controls_frame, text="", anchor="w")
self.status_bar.grid(row=0, column=0, sticky="ew")
action_buttons_frame = ttk.Frame(bottom_frame)
action_buttons_frame.grid(row=0, column=1)
right_side_buttons_frame = ttk.Frame(bottom_controls_frame)
right_side_buttons_frame.grid(row=0, column=1, sticky="e")
self.filter_combobox = ttk.Combobox(
right_side_buttons_frame, values=[ft[0] for ft in self.filetypes], state="readonly", width=20)
self.filter_combobox.pack(anchor="e", pady=(0, 5))
self.filter_combobox.bind(
"<<ComboboxSelected>>", self.on_filter_change)
self.filter_combobox.set(self.filetypes[0][0])
action_buttons_frame = ttk.Frame(right_side_buttons_frame)
action_buttons_frame.pack(anchor="e", pady=(0, 10))
ttk.Button(action_buttons_frame, text="Öffnen",
command=self.on_open).pack(side="right")
ttk.Button(action_buttons_frame, text="Abbrechen",
command=self.on_cancel).pack(side="right", padx=5, pady=15)
command=self.on_cancel).pack(side="right", padx=5)
def toggle_hidden_files(self):
self.show_hidden_files.set(not self.show_hidden_files.get())
if self.show_hidden_files.get():
self.hidden_files_button.config(image=self.icons['unhide'])
Tooltip(self.hidden_files_button, "Versteckte Dateien ausblenden")
else:
self.hidden_files_button.config(image=self.icons['hide'])
Tooltip(self.hidden_files_button, "Versteckte Dateien anzeigen")
self.populate_files()
def on_window_resize(self, event):
new_width = self.file_list_frame.winfo_width()
@@ -311,9 +375,7 @@ class CustomFileDialog(tk.Toplevel):
self.path_entry.delete(0, tk.END)
self.path_entry.insert(0, self.current_dir)
self.selected_file = None
current_status = self.status_bar.cget("text")
if not current_status.startswith("Zeige"):
self.update_status_bar()
self.update_status_bar()
if self.view_mode.get() == "list":
self.populate_list_view()
else:
@@ -400,25 +462,36 @@ class CustomFileDialog(tk.Toplevel):
def populate_list_view(self):
tree_frame = ttk.Frame(self.file_list_frame)
tree_frame.pack(fill='both', expand=True)
columns = ("name", "size", "type", "modified")
self.tree = ttk.Treeview(tree_frame, columns=columns, show="headings")
self.tree.heading("name", text="Name", anchor="w")
self.tree.column("name", anchor="w", width=300, stretch=True)
tree_frame.grid_rowconfigure(0, weight=1)
tree_frame.grid_columnconfigure(0, weight=1)
columns = ("size", "type", "modified")
self.tree = ttk.Treeview(
tree_frame, columns=columns, show="tree headings")
# Tree Column (#0)
self.tree.heading("#0", text="Name", anchor="w")
self.tree.column("#0", anchor="w", width=250, stretch=True)
# Other Columns
self.tree.heading("size", text="Größe", anchor="e")
self.tree.column("size", anchor="e", width=120, stretch=False)
self.tree.heading("type", text="Typ", anchor="w")
self.tree.column("type", anchor="w", width=120, stretch=False)
self.tree.heading("modified", text="Geändert am", anchor="w")
self.tree.column("modified", anchor="w", width=160, stretch=False)
v_scrollbar = ttk.Scrollbar(
tree_frame, orient="vertical", command=self.tree.yview)
h_scrollbar = ttk.Scrollbar(
tree_frame, orient="horizontal", command=self.tree.xview)
self.tree.configure(yscrollcommand=v_scrollbar.set,
xscrollcommand=h_scrollbar.set)
self.tree.pack(side="left", fill="both", expand=True)
v_scrollbar.pack(side="right", fill="y")
h_scrollbar.pack(side="bottom", fill="x")
self.tree.grid(row=0, column=0, sticky='nsew')
v_scrollbar.grid(row=0, column=1, sticky='ns')
h_scrollbar.grid(row=1, column=0, sticky='ew')
self.tree.bind("<Double-1>", self.on_list_double_click)
self.tree.bind("<<TreeviewSelect>>", self.on_list_select)
@@ -426,7 +499,7 @@ class CustomFileDialog(tk.Toplevel):
if warning:
self.status_bar.config(text=warning)
if error:
self.tree.insert("", "end", values=(error,))
self.tree.insert("", "end", text=error, values=())
return
for name in items:
@@ -446,7 +519,7 @@ class CustomFileDialog(tk.Toplevel):
icon, file_type, size = self.get_file_icon(
name, 'small'), "Datei", self._format_size(stat.st_size)
self.tree.insert("", "end", text=name, image=icon, values=(
name, size, file_type, modified_time))
size, file_type, modified_time))
except (FileNotFoundError, PermissionError):
continue
@@ -468,7 +541,7 @@ class CustomFileDialog(tk.Toplevel):
if not self.tree.selection():
return
item_id = self.tree.selection()[0]
item_text = self.tree.item(item_id, 'values')[0]
item_text = self.tree.item(item_id, 'text')
self.selected_file = os.path.join(self.current_dir, item_text)
self.update_status_bar()
@@ -492,7 +565,7 @@ class CustomFileDialog(tk.Toplevel):
if not self.tree.selection():
return
item_id = self.tree.selection()[0]
item_text = self.tree.item(item_id, 'values')[0]
item_text = self.tree.item(item_id, 'text')
path = os.path.join(self.current_dir, item_text)
if self._handle_unsupported_file(path):
return
@@ -530,6 +603,7 @@ class CustomFileDialog(tk.Toplevel):
self.history_pos = len(self.history) - 1
self.populate_files()
self.update_nav_buttons()
self.update_status_bar()
except Exception as e:
self.status_bar.config(text=f"Fehler: {e}")
@@ -539,6 +613,7 @@ class CustomFileDialog(tk.Toplevel):
self.current_dir = self.history[self.history_pos]
self.populate_files()
self.update_nav_buttons()
self.update_status_bar()
def go_forward(self):
if self.history_pos < len(self.history) - 1:
@@ -546,6 +621,7 @@ class CustomFileDialog(tk.Toplevel):
self.current_dir = self.history[self.history_pos]
self.populate_files()
self.update_nav_buttons()
self.update_status_bar()
def update_nav_buttons(self):
self.back_button.config(
@@ -555,16 +631,21 @@ class CustomFileDialog(tk.Toplevel):
def update_status_bar(self):
try:
_, _, free = shutil.disk_usage(self.current_dir)
total, used, free = shutil.disk_usage(self.current_dir)
free_str = self._format_size(free)
status_text = f"Freier Speicher: {free_str}"
self.storage_label.config(text=f"Freier Speicher: {free_str}")
self.storage_bar['value'] = (used / total) * 100
status_text = ""
if self.selected_file and os.path.exists(self.selected_file) and not os.path.isdir(self.selected_file):
size = os.path.getsize(self.selected_file)
size_str = self._format_size(size)
status_text += f" | '{os.path.basename(self.selected_file)}' Größe: {size_str}"
status_text = f"'{os.path.basename(self.selected_file)}' Größe: {size_str}"
self.status_bar.config(text=status_text)
except FileNotFoundError:
self.status_bar.config(text="Verzeichnis nicht gefunden")
self.storage_label.config(text="Freier Speicher: Unbekannt")
self.storage_bar['value'] = 0
def on_open(self):
if self.selected_file and os.path.isfile(self.selected_file):

View File

@@ -13,7 +13,7 @@ class GlotzMol(tk.Tk):
self.title("Custom File Dialog Test")
container = ttk.Frame(self, padding=10)
container.pack(fill="both", expand=True)
container.pack(fill="x", anchor="n")
ttk.Label(container, text="Ausgewählte Datei:").grid(
row=0, column=0, sticky="w")
@@ -58,7 +58,7 @@ if __name__ == "__main__":
style = ttk.Style(root)
root.tk.call('source', f"{theme_path}/water.tcl")
try:
root.tk.call('set_theme', 'dark')
root.tk.call('set_theme', 'light')
except tk.TclError:
pass
root.mainloop()