pax 5812f54877 dialogs: cache _use_gtk result instead of creating Database per call
_use_gtk() created a fresh Database instance on every file dialog
open just to read one setting. Now caches the result at module level
after first check. reset_gtk_cache() clears it when the setting
changes.
2026-04-11 22:19:36 -05:00

112 lines
2.9 KiB
Python

"""Native file dialog wrappers. Uses zenity on Linux when GTK dialogs are preferred."""
from __future__ import annotations
import subprocess
from PySide6.QtWidgets import QFileDialog, QWidget
from ..core.config import IS_WINDOWS
_gtk_cached: bool | None = None
def _use_gtk() -> bool:
global _gtk_cached
if IS_WINDOWS:
return False
if _gtk_cached is not None:
return _gtk_cached
try:
from ..core.db import Database
db = Database()
val = db.get_setting("file_dialog_platform")
db.close()
_gtk_cached = val == "gtk"
except Exception:
_gtk_cached = False
return _gtk_cached
def reset_gtk_cache() -> None:
"""Called after settings change so the next dialog picks up the new value."""
global _gtk_cached
_gtk_cached = None
def save_file(
parent: QWidget | None,
title: str,
default_name: str,
filter_str: str,
) -> str | None:
"""Show a save file dialog. Returns path or None."""
if _use_gtk():
try:
result = subprocess.run(
[
"zenity", "--file-selection", "--save",
"--title", title,
"--filename", default_name,
"--confirm-overwrite",
],
capture_output=True, text=True,
)
if result.returncode == 0:
return result.stdout.strip()
return None
except FileNotFoundError:
pass # zenity not installed, fall through to Qt
path, _ = QFileDialog.getSaveFileName(parent, title, default_name, filter_str)
return path or None
def open_file(
parent: QWidget | None,
title: str,
filter_str: str,
) -> str | None:
"""Show an open file dialog. Returns path or None."""
if _use_gtk():
try:
result = subprocess.run(
[
"zenity", "--file-selection",
"--title", title,
],
capture_output=True, text=True,
)
if result.returncode == 0:
return result.stdout.strip()
return None
except FileNotFoundError:
pass
path, _ = QFileDialog.getOpenFileName(parent, title, "", filter_str)
return path or None
def select_directory(
parent: QWidget | None,
title: str,
) -> str | None:
"""Show a directory picker. Returns path or None."""
if _use_gtk():
try:
result = subprocess.run(
[
"zenity", "--file-selection", "--directory",
"--title", title,
],
capture_output=True, text=True,
)
if result.returncode == 0:
return result.stdout.strip()
return None
except FileNotFoundError:
pass
path = QFileDialog.getExistingDirectory(parent, title)
return path or None