commit 39

This commit is contained in:
2025-08-02 20:01:29 +02:00
parent b350e562fa
commit 07751e5c9a
7 changed files with 853 additions and 504 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -1 +1,128 @@
#!/usr/bin/python3
"""App configuration for Wire-Py"""
import logging
from pathlib import Path
import os
from subprocess import CompletedProcess, run
from typing import Dict, Any
from shared_libs.common_tools import Translate
class AppConfig:
"""Central configuration and system setup manager for the Wire-Py application.
This class serves as a singleton-like container for all global configuration data,
including paths, UI settings, localization, versioning, and system-specific resources.
It ensures that required directories, files, and services are created and configured
before the application starts. Additionally, it provides tools for managing translations,
default settings, and autostart functionality to maintain a consistent user experience.
Key Responsibilities:
- Centralizes all configuration values (paths, UI preferences, localization).
- Ensures required directories and files exist on startup.
- Handles translation setup via `gettext` for multilingual support.
- Manages default settings file generation.
- Configures autostart services using systemd for user-specific launch behavior.
This class is used globally across the application to access configuration data
consistently and perform system-level setup tasks.
"""
# Helper to make icon paths robust, so the script can be run from anywhere
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
MAX_ITEMS_TO_DISPLAY = 1000
# Logging
LOG_DIR = Path.home() / ".local/share/lxlogs"
Path(LOG_DIR).mkdir(parents=True, exist_ok=True)
LOG_FILE_PATH = LOG_DIR / "cfiledialog.log"
# Base paths
BASE_DIR: Path = Path.home()
CONFIG_DIR: Path = BASE_DIR / ".config/cfiledialog"
# Configuration files
SETTINGS_FILE: Path = CONFIG_DIR / "settings"
DEFAULT_SETTINGS: Dict[str, str] = {
"# Configuration": "on",
"# Theme": "dark",
"# Tooltips": True,
"# Autostart": "off",
"# Logfile": LOG_FILE_PATH,
}
# Updates
# 1 = 1. Year, 09 = Month of the Year, 2924 = Day and Year of the Year
VERSION: str = "v. 1.07.2725"
UPDATE_URL: str = "https://git.ilunix.de/api/v1/repos/punix/example/releases"
DOWNLOAD_URL: str = "https://git.ilunix.de/punix/example/archive"
# UI configuration
UI_CONFIG: Dict[str, Any] = {
"window_title": "File Dialog",
"window_size": (1100, 850),
"font_family": "Ubuntu",
"font_size": 11,
"resizable_window": (True, True),
}
# System-dependent paths
SYSTEM_PATHS: Dict[str, Path] = {
"tcl_path": "/usr/share/TK-Themes",
}
@classmethod
def ensure_directories(cls) -> None:
"""Ensures that all required directories exist"""
if not cls.CONFIG_DIR.exists():
cls.CONFIG_DIR.mkdir(parents=True, exist_ok=True)
@classmethod
def create_default_settings(cls) -> None:
"""Creates default settings if they don't exist"""
if not cls.SETTINGS_FILE.exists():
content = "\n".join(
f"[{k.upper()}]\n{v}" for k, v in cls.DEFAULT_SETTINGS.items()
)
cls.SETTINGS_FILE.write_text(content)
@classmethod
def ensure_log(cls) -> None:
"""Ensures that the log file exists"""
if not cls.LOG_FILE_PATH.exists():
cls.LOG_FILE_PATH.touch()
# here is initializing the class for translation strings
_ = Translate.setup_translations("custom_file_fialog")
class Msg:
"""
A utility class that provides centralized access to translated message strings.
This class contains a dictionary of message strings used throughout the custom file dialog application.
All strings are prepared for translation using gettext. The short key names make the code
more concise while maintaining readability.
Attributes:
STR (dict): A dictionary mapping short keys to translated message strings.
Keys are abbreviated for brevity but remain descriptive.
Usage:
Import this class and access messages using the dictionary:
`Msg.STR["sel_tl"]` returns the translated "Select tunnel" message.
Note:
Ensure that gettext translation is properly initialized before
accessing these strings to ensure correct localization.
"""
STR: Dict[str, str] = {
# Strings for messages
}
TTIP: Dict[str, str] = {
# Strings for Tooltips
}

456
cfd_ui_setup.py Normal file
View File

@@ -0,0 +1,456 @@
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("<Return>", self.on_ok)
self.bind("<Escape>", 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
def get_xdg_user_dir(dir_key, fallback_name):
home = os.path.expanduser("~")
fallback_path = os.path.join(home, fallback_name)
config_path = os.path.join(home, ".config", "user-dirs.dirs")
if not os.path.exists(config_path):
return fallback_path
try:
with open(config_path, 'r') as f:
for line in f:
line = line.strip()
if line.startswith(f"{dir_key}="):
path = line.split('=', 1)[1].strip().strip('"')
path = path.replace('$HOME', home)
if not os.path.isabs(path):
path = os.path.join(home, path)
return path
except Exception:
pass
return fallback_path
class StyleManager:
def __init__(self, dialog):
self.dialog = dialog
self.setup_styles()
def setup_styles(self):
style = ttk.Style(self.dialog)
base_bg = self.dialog.cget('background')
self.is_dark = sum(self.dialog.winfo_rgb(base_bg)) / 3 < 32768
if self.is_dark:
self.selection_color = "#4a6984"
self.icon_bg_color = "#3c3c3c"
self.accent_color = "#2a2a2a"
self.header = "#2b2b2b"
self.hover_extrastyle = "#4a4a4a"
self.hover_extrastyle2 = "#494949"
self.sidebar_color = "#333333"
self.bottom_color = self.accent_color
self.color_foreground = "#ffffff"
self.freespace_background = self.sidebar_color
else:
self.selection_color = "#cce5ff"
self.icon_bg_color = base_bg
self.accent_color = "#e0e0e0"
self.header = "#d9d9d9"
self.hover_extrastyle = "#f5f5f5"
self.hover_extrastyle2 = "#494949"
self.sidebar_color = "#e7e7e7"
self.bottom_color = "#cecece"
self.freespace_background = self.sidebar_color
self.color_foreground = "#000000"
style.configure("Header.TButton.Borderless.Round",
background=self.header)
style.map("Header.TButton.Borderless.Round", background=[
('active', self.hover_extrastyle)])
style.configure("Header.TButton.Active.Round",
background=self.selection_color)
style.layout("Header.TButton.Active.Round",
style.layout("Header.TButton.Borderless.Round"))
style.map("Header.TButton.Active.Round", background=[
('active', self.selection_color)])
style.configure("Dark.TButton.Borderless", anchor="w", background=self.sidebar_color,
foreground=self.color_foreground, padding=(20, 5, 0, 5))
style.map("Dark.TButton.Borderless", background=[
('active', self.hover_extrastyle2)])
style.configure("Accent.TFrame", background=self.header)
style.configure("Accent.TLabel", background=self.header)
style.configure("AccentBottom.TFrame", background=self.bottom_color)
style.configure("AccentBottom.TLabel", background=self.bottom_color)
style.configure("Sidebar.TFrame", background=self.sidebar_color)
style.configure("Content.TFrame", background=self.icon_bg_color)
style.configure("Item.TFrame", background=self.icon_bg_color)
style.map('Item.TFrame', background=[
('selected', self.selection_color)])
style.configure("Item.TLabel", background=self.icon_bg_color)
style.map('Item.TLabel', background=[('selected', self.selection_color)], foreground=[
('selected', "black" if not self.is_dark else "white")])
style.configure("Icon.TLabel", background=self.icon_bg_color)
style.map('Icon.TLabel', background=[
('selected', self.selection_color)])
style.configure("Treeview.Heading", relief="flat",
borderwidth=0, font=('TkDefaultFont', 10, 'bold'))
style.configure("Treeview", rowheight=32, pady=2, background=self.icon_bg_color,
fieldbackground=self.icon_bg_color, borderwidth=0)
style.map("Treeview", background=[('selected', self.selection_color)], foreground=[
('selected', "black" if not self.is_dark else "white")])
style.configure("TButton.Borderless.Round", anchor="w")
style.configure("Small.Horizontal.TProgressbar", thickness=8)
class WidgetManager:
def __init__(self, dialog):
self.dialog = dialog
self.style_manager = dialog.style_manager
self.setup_widgets()
def setup_widgets(self):
# Main container
main_frame = ttk.Frame(self.dialog, style='Accent.TFrame')
main_frame.pack(fill="both", expand=True)
main_frame.grid_rowconfigure(2, weight=1)
main_frame.grid_columnconfigure(0, weight=1)
# Top bar for navigation and path
top_bar = ttk.Frame(
main_frame, style='Accent.TFrame', padding=(0, 5, 0, 5))
top_bar.grid(row=0, column=0, columnspan=2, sticky="ew")
top_bar.grid_columnconfigure(1, weight=1)
# Navigation buttons
nav_buttons_container = ttk.Frame(top_bar, style='Accent.TFrame')
nav_buttons_container.grid(row=0, column=0, sticky="w")
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)
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")
Tooltip(self.forward_button, "Vorwärts")
self.home_button = ttk.Button(nav_buttons_container, image=self.dialog.icon_manager.get_icon(
'home'), command=lambda: self.dialog.navigate_to(os.path.expanduser("~")), style="Header.TButton.Borderless.Round")
self.home_button.pack(side="left", padx=10)
Tooltip(self.home_button, "Home")
# Path entry
self.path_entry = ttk.Entry(top_bar)
self.path_entry.grid(row=0, column=1, sticky="ew")
self.path_entry.bind(
"<Return>", lambda e: self.dialog.navigate_to(self.path_entry.get()))
# Search, view switch and hidden files button
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')
search_container.pack(side="left", padx=(0, 10))
self.search_button = ttk.Button(search_container, image=self.dialog.icon_manager.get_icon(
'search_small'), command=self.dialog.toggle_search_mode, style="Header.TButton.Borderless.Round")
self.search_button.pack(side="left")
Tooltip(self.search_button, "Suchen")
# Search options frame (initially hidden, next to search button)
self.search_options_frame = ttk.Frame(
search_container, style='Accent.TFrame')
# Recursive search toggle button
self.recursive_search = tk.BooleanVar(value=True)
self.recursive_button = ttk.Button(self.search_options_frame, image=self.dialog.icon_manager.get_icon(
'recursive_small'), command=self.dialog.toggle_recursive_search, style="Header.TButton.Active.Round")
self.recursive_button.pack(side="left", padx=2)
Tooltip(self.recursive_button, "Rekursive Suche ein/ausschalten")
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))
Tooltip(self.icon_view_button, "Kachelansicht")
self.list_view_button = ttk.Button(view_switch, image=self.dialog.icon_manager.get_icon(
'list_view'), command=self.dialog.set_list_view, style="Header.TButton.Borderless.Round")
self.list_view_button.pack(side="left")
Tooltip(self.list_view_button, "Listenansicht")
self.hidden_files_button = ttk.Button(right_top_bar_frame, image=self.dialog.icon_manager.get_icon(
'hide'), command=self.dialog.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")
# Horizontal separator
separator_color = "#000000" if self.style_manager.is_dark else "#9c9c9c"
tk.Frame(main_frame, height=1, bg=separator_color).grid(
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.grid(row=2, column=0, columnspan=2, sticky="nsew")
# Sidebar
sidebar_frame = ttk.Frame(
paned_window, style="Sidebar.TFrame", padding=(0, 0, 0, 0), width=200)
sidebar_frame.grid_propagate(False)
sidebar_frame.bind("<Configure>", self.dialog.on_sidebar_resize)
paned_window.add(sidebar_frame, weight=0)
sidebar_frame.grid_rowconfigure(2, weight=1)
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")},
]
self.sidebar_buttons = []
for config in sidebar_buttons_config:
btn = ttk.Button(sidebar_buttons_frame, text=f" {config['name']}", image=config['icon'], compound="left",
command=lambda p=config['path']: self.dialog.navigate_to(p), style="Dark.TButton.Borderless")
btn.pack(fill="x", pady=1)
self.sidebar_buttons.append((btn, f" {config['name']}"))
separator_color = "#a9a9a9" if self.style_manager.is_dark else "#7c7c7c"
tk.Frame(sidebar_frame, height=1, bg=separator_color).grid(
row=1, column=0, sticky="ew", padx=20, pady=15)
mounted_devices_frame = ttk.Frame(
sidebar_frame, style="Sidebar.TFrame")
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,
foreground=self.style_manager.color_foreground).grid(row=0, column=0, sticky="ew", padx=10, pady=(5, 0))
self.devices_canvas = tk.Canvas(
mounted_devices_frame, highlightthickness=0, bg=self.style_manager.sidebar_color, height=150, width=180)
self.devices_scrollbar = ttk.Scrollbar(
mounted_devices_frame, orient="vertical", command=self.devices_canvas.yview)
self.devices_canvas.configure(
yscrollcommand=self.devices_scrollbar.set)
self.devices_canvas.grid(row=1, column=0, sticky="nsew")
self.devices_scrollable_frame = ttk.Frame(
self.devices_canvas, style="Sidebar.TFrame")
self.devices_canvas_window = self.devices_canvas.create_window(
(0, 0), window=self.devices_scrollable_frame, anchor="nw")
self.devices_canvas.bind("<Enter>", self.dialog._on_devices_enter)
self.devices_canvas.bind("<Leave>", self.dialog._on_devices_leave)
self.devices_scrollable_frame.bind(
"<Enter>", self.dialog._on_devices_enter)
self.devices_scrollable_frame.bind(
"<Leave>", self.dialog._on_devices_leave)
def _configure_devices_canvas(event):
self.devices_canvas.configure(
scrollregion=self.devices_canvas.bbox("all"))
canvas_width = event.width
self.devices_canvas.itemconfig(
self.devices_canvas_window, width=canvas_width)
self.devices_scrollable_frame.bind("<Configure>", lambda e: self.devices_canvas.configure(
scrollregion=self.devices_canvas.bbox("all")))
self.devices_canvas.bind("<Configure>", _configure_devices_canvas)
def _on_devices_mouse_wheel(event):
if event.num == 4:
delta = -1
elif event.num == 5:
delta = 1
else:
delta = -1 * int(event.delta / 120)
self.devices_canvas.yview_scroll(delta, "units")
for widget in [self.devices_canvas, self.devices_scrollable_frame]:
widget.bind("<MouseWheel>", _on_devices_mouse_wheel)
widget.bind("<Button-4>", _on_devices_mouse_wheel)
widget.bind("<Button-5>", _on_devices_mouse_wheel)
self.device_buttons = []
for device_name, mount_point, removable in self.dialog._get_mounted_devices():
icon = self.dialog.icon_manager.get_icon(
'usb_small') if removable else self.dialog.icon_manager.get_icon('device_small')
button_text = f" {device_name}"
if len(device_name) > 15:
button_text = f" {device_name[:15]}\n{device_name[15:]}"
btn = ttk.Button(self.devices_scrollable_frame, text=button_text, image=icon, compound="left",
command=lambda p=mount_point: self.dialog.navigate_to(p), style="Dark.TButton.Borderless")
btn.pack(fill="x", pady=1)
self.device_buttons.append((btn, button_text))
for w in [btn, self.devices_canvas, self.devices_scrollable_frame]:
w.bind("<MouseWheel>", _on_devices_mouse_wheel)
w.bind("<Button-4>", _on_devices_mouse_wheel)
w.bind("<Button-5>", _on_devices_mouse_wheel)
w.bind("<Enter>", self.dialog._on_devices_enter)
w.bind("<Leave>", self.dialog._on_devices_leave)
try:
total, used, _ = shutil.disk_usage(mount_point)
progress_bar = ttk.Progressbar(self.devices_scrollable_frame, orient="horizontal",
length=100, mode="determinate", style='Small.Horizontal.TProgressbar')
progress_bar.pack(fill="x", pady=(2, 8), padx=25)
progress_bar['value'] = (used / total) * 100
for w in [progress_bar]:
w.bind("<MouseWheel>", _on_devices_mouse_wheel)
w.bind("<Button-4>", _on_devices_mouse_wheel)
w.bind("<Button-5>", _on_devices_mouse_wheel)
w.bind("<Enter>", self.dialog._on_devices_enter)
w.bind("<Leave>", self.dialog._on_devices_leave)
except (FileNotFoundError, PermissionError):
pass
tk.Frame(sidebar_frame, height=1, bg=separator_color).grid(
row=3, column=0, sticky="ew", padx=20, pady=15)
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.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)
content_frame = ttk.Frame(paned_window, padding=(
0, 0, 0, 0), style="AccentBottom.TFrame")
paned_window.add(content_frame, weight=1)
content_frame.grid_rowconfigure(0, weight=1)
content_frame.grid_columnconfigure(0, weight=1)
self.file_list_frame = ttk.Frame(
content_frame, style="AccentBottom.TFrame")
self.file_list_frame.grid(row=0, column=0, sticky="nsew")
self.dialog.bind("<Configure>", self.dialog.on_window_resize)
bottom_controls_frame = ttk.Frame(
content_frame, style="AccentBottom.TFrame")
bottom_controls_frame.grid(row=1, column=0, sticky="ew", pady=(5, 0))
bottom_controls_frame.grid_columnconfigure(1, weight=1)
# 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,
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))
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")
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)
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)
# 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("<<ComboboxSelected>>", self.dialog.on_filter_change)
self.filter_combobox.set(self.dialog.filetypes[0][0])

File diff suppressed because it is too large Load Diff

View File

@@ -30,24 +30,23 @@ class GlotzMol(tk.Tk):
def open_custom_dialog(self):
dialog = CustomFileDialog(self,
initial_dir=os.path.expanduser("~"),
filetypes=[("Wireguard Files (.conf)", "*.conf"),
("All Files", "*.*")
])
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__":