commit 43
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -60,7 +60,7 @@ class AppConfig:
|
||||
# UI configuration
|
||||
UI_CONFIG: Dict[str, Any] = {
|
||||
"window_title": "File Dialog",
|
||||
"window_size": (1100, 850),
|
||||
"window_size": (1050, 850),
|
||||
"font_family": "Ubuntu",
|
||||
"font_size": 11,
|
||||
"resizable_window": (True, True),
|
||||
|
@@ -369,32 +369,50 @@ class WidgetManager:
|
||||
left_bottom_buttons, text="", anchor="w", style="AccentBottom.TLabel")
|
||||
|
||||
if self.dialog.dialog_mode == "save":
|
||||
self.filename_entry = ttk.Entry(left_bottom_buttons, width=50)
|
||||
self.filename_entry.grid(
|
||||
row=0, column=1, padx=(5, 5), pady=5, sticky="ew")
|
||||
left_bottom_buttons.grid_columnconfigure(1, weight=1)
|
||||
|
||||
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))
|
||||
self.status_bar.grid(row=2, column=0, columnspan=2,
|
||||
sticky="ew", padx=10, pady=5)
|
||||
# Widgets for save mode
|
||||
self.filename_entry = ttk.Entry(left_bottom_buttons, width=60)
|
||||
self.filename_entry.grid(row=0, column=1, padx=(
|
||||
0, 5), pady=(10, 10), sticky="ew")
|
||||
|
||||
save_button = ttk.Button(
|
||||
left_bottom_buttons, text="Speichern", command=self.dialog.on_save)
|
||||
save_button.grid(row=0, column=0, padx=(10, 5), pady=10)
|
||||
|
||||
cancel_button = ttk.Button(
|
||||
left_bottom_buttons, text="Abbrechen", command=self.dialog.on_cancel)
|
||||
cancel_button.grid(row=1, column=0, padx=(10, 5), pady=(0, 10))
|
||||
|
||||
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=(0, 10), pady=(0, 10))
|
||||
self.filter_combobox.bind(
|
||||
"<<ComboboxSelected>>", self.dialog.on_filter_change)
|
||||
self.filter_combobox.set(self.dialog.filetypes[0][0])
|
||||
|
||||
self.status_bar.grid(
|
||||
row=0, column=1, sticky="w", padx=0, pady=(0, 5))
|
||||
|
||||
else:
|
||||
# Open mode layout
|
||||
left_bottom_buttons.grid_columnconfigure(1, weight=1)
|
||||
|
||||
# Status bar (top-left in the bottom area)
|
||||
self.status_bar.grid(row=0, column=1, columnspan=2,
|
||||
sticky="e", padx=10, pady=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))
|
||||
open_button = ttk.Button(
|
||||
left_bottom_buttons, text="Öffnen", command=self.dialog.on_open)
|
||||
open_button.grid(row=0, column=0, padx=(10, 5), pady=10)
|
||||
|
||||
# Filter combobox (bottom-right)
|
||||
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(
|
||||
"<<ComboboxSelected>>", self.dialog.on_filter_change)
|
||||
self.filter_combobox.set(self.dialog.filetypes[0][0])
|
||||
cancel_button = ttk.Button(
|
||||
left_bottom_buttons, text="Abbrechen", command=self.dialog.on_cancel)
|
||||
cancel_button.grid(row=1, column=0, padx=(10, 5), pady=(0, 10))
|
||||
|
||||
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=(0, 10), pady=(0, 10))
|
||||
self.filter_combobox.bind(
|
||||
"<<ComboboxSelected>>", self.dialog.on_filter_change)
|
||||
self.filter_combobox.set(self.dialog.filetypes[0][0])
|
||||
|
||||
self.status_bar.grid(row=0, column=1, sticky="w", padx=0, pady=5)
|
||||
|
@@ -151,6 +151,7 @@ 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.focus_set() # Set focus to path entry
|
||||
self.widget_manager.path_entry.bind(
|
||||
"<Return>", self.execute_search)
|
||||
self.widget_manager.path_entry.bind(
|
||||
@@ -371,6 +372,30 @@ class CustomFileDialog(tk.Toplevel):
|
||||
except (FileNotFoundError, PermissionError):
|
||||
continue
|
||||
|
||||
# Bind selection event
|
||||
def on_search_select(event):
|
||||
selection = search_tree.selection()
|
||||
if selection:
|
||||
item = search_tree.item(selection[0])
|
||||
filename = item['text'].strip()
|
||||
directory = item['values'][0]
|
||||
full_path = os.path.join(directory, filename)
|
||||
|
||||
# Update status bar
|
||||
try:
|
||||
stat = os.stat(full_path)
|
||||
size_str = self._format_size(stat.st_size)
|
||||
self.widget_manager.status_bar.config(text=f"'{filename}' Größe: {size_str}")
|
||||
except (FileNotFoundError, PermissionError):
|
||||
self.widget_manager.status_bar.config(text=f"'{filename}' nicht zugänglich")
|
||||
|
||||
# If in save mode, update filename entry
|
||||
if self.dialog_mode == "save":
|
||||
self.widget_manager.filename_entry.delete(0, tk.END)
|
||||
self.widget_manager.filename_entry.insert(0, filename)
|
||||
|
||||
search_tree.bind("<<TreeviewSelect>>", on_search_select)
|
||||
|
||||
# Bind double-click to select file
|
||||
def on_search_double_click(event):
|
||||
selection = search_tree.selection()
|
||||
@@ -392,7 +417,7 @@ class CustomFileDialog(tk.Toplevel):
|
||||
self.unbind_all("<Button-4>")
|
||||
self.unbind_all("<Button-5>")
|
||||
|
||||
def populate_files(self, item_to_rename=None):
|
||||
def populate_files(self, item_to_rename=None, item_to_select=None):
|
||||
# Unbind previous global mouse wheel events
|
||||
self._unbind_mouse_wheel_events()
|
||||
|
||||
@@ -403,9 +428,9 @@ class CustomFileDialog(tk.Toplevel):
|
||||
self.selected_file = None
|
||||
self.update_status_bar()
|
||||
if self.view_mode.get() == "list":
|
||||
self.populate_list_view(item_to_rename)
|
||||
self.populate_list_view(item_to_rename, item_to_select)
|
||||
else:
|
||||
self.populate_icon_view(item_to_rename)
|
||||
self.populate_icon_view(item_to_rename, item_to_select)
|
||||
|
||||
def _get_sorted_items(self):
|
||||
try:
|
||||
@@ -425,7 +450,22 @@ class CustomFileDialog(tk.Toplevel):
|
||||
except FileNotFoundError:
|
||||
return ([], "Verzeichnis nicht gefunden.", None)
|
||||
|
||||
def populate_icon_view(self, item_to_rename=None):
|
||||
def _get_folder_content_count(self, folder_path):
|
||||
try:
|
||||
if not os.path.isdir(folder_path) or not os.access(folder_path, os.R_OK):
|
||||
return None
|
||||
|
||||
items = os.listdir(folder_path)
|
||||
|
||||
# Filter based on hidden files setting
|
||||
if not self.show_hidden_files.get():
|
||||
items = [item for item in items if not item.startswith('.')]
|
||||
|
||||
return len(items)
|
||||
except (PermissionError, FileNotFoundError):
|
||||
return None
|
||||
|
||||
def populate_icon_view(self, item_to_rename=None, item_to_select=None):
|
||||
canvas = tk.Canvas(self.widget_manager.file_list_frame,
|
||||
highlightthickness=0, bg=self.style_manager.icon_bg_color)
|
||||
v_scrollbar = ttk.Scrollbar(
|
||||
@@ -488,7 +528,14 @@ class CustomFileDialog(tk.Toplevel):
|
||||
name_label = ttk.Label(item_frame, text=self.shorten_text(
|
||||
name, 14), anchor="center", style="Item.TLabel")
|
||||
name_label.pack(fill="x", expand=True)
|
||||
Tooltip(item_frame, name)
|
||||
|
||||
tooltip_text = name
|
||||
if is_dir:
|
||||
content_count = self._get_folder_content_count(path)
|
||||
if content_count is not None:
|
||||
tooltip_text += f"\n({content_count} Einträge)"
|
||||
Tooltip(item_frame, tooltip_text)
|
||||
|
||||
# Bind events to all individual widgets so scrolling works everywhere
|
||||
for widget in [item_frame, icon_label, name_label]:
|
||||
widget.bind("<Double-Button-1>", lambda e,
|
||||
@@ -501,11 +548,15 @@ class CustomFileDialog(tk.Toplevel):
|
||||
widget.bind("<F2>", lambda e, p=path,
|
||||
f=item_frame: self.on_rename_request(e, p, f))
|
||||
|
||||
if name == item_to_select:
|
||||
self.on_item_select(path, item_frame)
|
||||
canvas.yview_moveto(row / max(1, (len(items) // col_count)))
|
||||
|
||||
col = (col + 1) % col_count
|
||||
if col == 0:
|
||||
row += 1
|
||||
|
||||
def populate_list_view(self, item_to_rename=None):
|
||||
def populate_list_view(self, item_to_rename=None, item_to_select=None):
|
||||
tree_frame = ttk.Frame(self.widget_manager.file_list_frame)
|
||||
tree_frame.pack(fill='both', expand=True)
|
||||
tree_frame.grid_rowconfigure(0, weight=1)
|
||||
@@ -571,7 +622,12 @@ class CustomFileDialog(tk.Toplevel):
|
||||
if name == item_to_rename:
|
||||
self.tree.selection_set(item_id)
|
||||
self.tree.focus(item_id)
|
||||
self.tree.see(item_id) # Scroll to the item
|
||||
self.start_rename(item_id, path)
|
||||
elif name == item_to_select:
|
||||
self.tree.selection_set(item_id)
|
||||
self.tree.focus(item_id)
|
||||
self.tree.see(item_id) # Scroll to the item
|
||||
|
||||
except (FileNotFoundError, PermissionError):
|
||||
continue
|
||||
@@ -589,9 +645,10 @@ class CustomFileDialog(tk.Toplevel):
|
||||
self.selected_item_frame = item_frame
|
||||
self.selected_file = path
|
||||
self.update_status_bar()
|
||||
self.bind("<F2>", lambda e, p=path, f=item_frame: self.on_rename_request(e, p, f))
|
||||
if self.dialog_mode == "save" and not os.path.isdir(path):
|
||||
self.widget_manager.path_entry.delete(0, tk.END)
|
||||
self.widget_manager.path_entry.insert(0, path)
|
||||
self.widget_manager.filename_entry.delete(0, tk.END)
|
||||
self.widget_manager.filename_entry.insert(0, os.path.basename(path))
|
||||
|
||||
def on_list_select(self, event):
|
||||
if not self.tree.selection():
|
||||
@@ -601,8 +658,8 @@ class CustomFileDialog(tk.Toplevel):
|
||||
self.selected_file = os.path.join(self.current_dir, item_text)
|
||||
self.update_status_bar()
|
||||
if self.dialog_mode == "save" and not os.path.isdir(self.selected_file):
|
||||
self.widget_manager.path_entry.delete(0, tk.END)
|
||||
self.widget_manager.path_entry.insert(0, self.selected_file)
|
||||
self.widget_manager.filename_entry.delete(0, tk.END)
|
||||
self.widget_manager.filename_entry.insert(0, item_text)
|
||||
|
||||
def on_rename_request(self, event, item_path=None, item_frame=None):
|
||||
if self.view_mode.get() == "list":
|
||||
@@ -686,6 +743,7 @@ class CustomFileDialog(tk.Toplevel):
|
||||
self.populate_files()
|
||||
self.update_nav_buttons()
|
||||
self.update_status_bar()
|
||||
self.update_action_buttons_state()
|
||||
|
||||
def go_forward(self):
|
||||
if self.history_pos < len(self.history) - 1:
|
||||
@@ -694,6 +752,7 @@ class CustomFileDialog(tk.Toplevel):
|
||||
self.populate_files()
|
||||
self.update_nav_buttons()
|
||||
self.update_status_bar()
|
||||
self.update_action_buttons_state()
|
||||
|
||||
def update_nav_buttons(self):
|
||||
self.widget_manager.back_button.config(
|
||||
@@ -784,7 +843,7 @@ class CustomFileDialog(tk.Toplevel):
|
||||
entry = ttk.Entry(item_frame)
|
||||
entry.insert(0, os.path.basename(item_path))
|
||||
entry.select_range(0, tk.END)
|
||||
entry.pack(fill="both", expand=True, padx=5, pady=5)
|
||||
entry.pack(fill="x", expand=True, padx=5, pady=5)
|
||||
entry.focus_set()
|
||||
|
||||
def finish_rename(event):
|
||||
@@ -794,14 +853,17 @@ class CustomFileDialog(tk.Toplevel):
|
||||
if os.path.exists(new_path):
|
||||
self.widget_manager.status_bar.config(
|
||||
text=f"'{new_name}' existiert bereits.")
|
||||
self.populate_files()
|
||||
self.populate_files(item_to_select=os.path.basename(item_path))
|
||||
return
|
||||
try:
|
||||
os.rename(item_path, new_path)
|
||||
self.populate_files(item_to_select=new_name)
|
||||
except Exception as e:
|
||||
self.widget_manager.status_bar.config(
|
||||
text=f"Fehler beim Umbenennen: {e}")
|
||||
self.populate_files()
|
||||
self.populate_files()
|
||||
else:
|
||||
self.populate_files(item_to_select=os.path.basename(item_path))
|
||||
|
||||
def cancel_rename(event):
|
||||
self.populate_files()
|
||||
@@ -813,7 +875,9 @@ class CustomFileDialog(tk.Toplevel):
|
||||
def _start_rename_list_view(self, item_id):
|
||||
x, y, width, height = self.tree.bbox(item_id, column="#0")
|
||||
entry = ttk.Entry(self.tree)
|
||||
entry.place(x=x, y=y, width=width, height=height)
|
||||
# Set a fixed width for the entry widget to prevent it from expanding too much
|
||||
entry_width = self.tree.column("#0", "width")
|
||||
entry.place(x=x, y=y, width=entry_width, height=height)
|
||||
|
||||
item_text = self.tree.item(item_id, "text").strip()
|
||||
entry.insert(0, item_text)
|
||||
@@ -829,14 +893,18 @@ class CustomFileDialog(tk.Toplevel):
|
||||
if os.path.exists(new_path):
|
||||
self.widget_manager.status_bar.config(
|
||||
text=f"'{new_name}' existiert bereits.")
|
||||
self.populate_files(item_to_select=item_text)
|
||||
else:
|
||||
try:
|
||||
os.rename(old_path, new_path)
|
||||
self.populate_files(item_to_select=new_name)
|
||||
except Exception as e:
|
||||
self.widget_manager.status_bar.config(
|
||||
text=f"Fehler beim Umbenennen: {e}")
|
||||
self.populate_files()
|
||||
else:
|
||||
self.populate_files(item_to_select=item_text)
|
||||
entry.destroy()
|
||||
self.populate_files()
|
||||
|
||||
def cancel_rename(event):
|
||||
entry.destroy()
|
||||
|
@@ -30,23 +30,23 @@ class GlotzMol(tk.Tk):
|
||||
|
||||
def open_custom_dialog(self):
|
||||
|
||||
CustomFileDialog(self,
|
||||
initial_dir=os.path.expanduser("~"),
|
||||
filetypes=[("All Files", "*.*")
|
||||
], dialog_mode="save")
|
||||
dialog = CustomFileDialog(self,
|
||||
initial_dir=os.path.expanduser("~"),
|
||||
filetypes=[("All Files", "*.*")
|
||||
])
|
||||
|
||||
# This is the crucial part: wait for the dialog to be closed
|
||||
# self.wait_window(dialog)
|
||||
self.wait_window(dialog)
|
||||
|
||||
# Now, get the result
|
||||
# selected_path = dialog.get_selected_file()
|
||||
selected_path = dialog.get_selected_file()
|
||||
|
||||
# if selected_path:
|
||||
# self.iso_path_entry.delete(0, tk.END)
|
||||
# self.iso_path_entry.insert(0, selected_path)
|
||||
# print(f"Die ausgewählte Datei ist: {selected_path}")
|
||||
# else:
|
||||
# print("Keine Datei ausgewählt.")
|
||||
if selected_path:
|
||||
self.iso_path_entry.delete(0, tk.END)
|
||||
self.iso_path_entry.insert(0, selected_path)
|
||||
print(f"Die ausgewählte Datei ist: {selected_path}")
|
||||
else:
|
||||
print("Keine Datei ausgewählt.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
Reference in New Issue
Block a user