This stops the devshell from being re-built constantly, when the source code changes. Based on a new feature in treefmt-nix: https://github.com/numtide/treefmt-nix/pull/208
135 lines
4.8 KiB
Python
135 lines
4.8 KiB
Python
# ruff: noqa: N801
|
|
import gi
|
|
|
|
gi.require_version("Gtk", "4.0")
|
|
|
|
import logging
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
from clan_cli.api import ErrorDataClass, SuccessDataClass
|
|
from clan_cli.api.directory import FileRequest
|
|
from gi.repository import Gio, GLib, Gtk
|
|
|
|
from clan_app.api import ImplFunc
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
def remove_none(_list: list) -> list:
|
|
return [i for i in _list if i is not None]
|
|
|
|
|
|
# This implements the abstract function open_file with one argument, file_request,
|
|
# which is a FileRequest object and returns a string or None.
|
|
class open_file(
|
|
ImplFunc[[FileRequest, str], SuccessDataClass[list[str] | None] | ErrorDataClass]
|
|
):
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
|
|
def async_run(self, file_request: FileRequest, op_key: str) -> bool:
|
|
def on_file_select(file_dialog: Gtk.FileDialog, task: Gio.Task) -> None:
|
|
try:
|
|
gfile = file_dialog.open_finish(task)
|
|
if gfile:
|
|
selected_path = remove_none([gfile.get_path()])
|
|
self.returns(
|
|
SuccessDataClass(
|
|
op_key=op_key, data=selected_path, status="success"
|
|
)
|
|
)
|
|
except Exception as e:
|
|
print(f"Error getting selected file or directory: {e}")
|
|
|
|
def on_file_select_multiple(
|
|
file_dialog: Gtk.FileDialog, task: Gio.Task
|
|
) -> None:
|
|
try:
|
|
gfiles: Any = file_dialog.open_multiple_finish(task)
|
|
if gfiles:
|
|
selected_paths = remove_none([gfile.get_path() for gfile in gfiles])
|
|
self.returns(
|
|
SuccessDataClass(
|
|
op_key=op_key, data=selected_paths, status="success"
|
|
)
|
|
)
|
|
except Exception as e:
|
|
print(f"Error getting selected files: {e}")
|
|
|
|
def on_folder_select(file_dialog: Gtk.FileDialog, task: Gio.Task) -> None:
|
|
try:
|
|
gfile = file_dialog.select_folder_finish(task)
|
|
if gfile:
|
|
selected_path = remove_none([gfile.get_path()])
|
|
self.returns(
|
|
SuccessDataClass(
|
|
op_key=op_key, data=selected_path, status="success"
|
|
)
|
|
)
|
|
except Exception as e:
|
|
print(f"Error getting selected directory: {e}")
|
|
|
|
def on_save_finish(file_dialog: Gtk.FileDialog, task: Gio.Task) -> None:
|
|
try:
|
|
gfile = file_dialog.save_finish(task)
|
|
if gfile:
|
|
selected_path = remove_none([gfile.get_path()])
|
|
self.returns(
|
|
SuccessDataClass(
|
|
op_key=op_key, data=selected_path, status="success"
|
|
)
|
|
)
|
|
except Exception as e:
|
|
print(f"Error getting selected file: {e}")
|
|
|
|
dialog = Gtk.FileDialog()
|
|
|
|
if file_request.title:
|
|
dialog.set_title(file_request.title)
|
|
|
|
if file_request.filters:
|
|
filters = Gio.ListStore.new(Gtk.FileFilter)
|
|
file_filters = Gtk.FileFilter()
|
|
|
|
if file_request.filters.title:
|
|
file_filters.set_name(file_request.filters.title)
|
|
|
|
if file_request.filters.mime_types:
|
|
for mime in file_request.filters.mime_types:
|
|
file_filters.add_mime_type(mime)
|
|
filters.append(file_filters)
|
|
|
|
if file_request.filters.patterns:
|
|
for pattern in file_request.filters.patterns:
|
|
file_filters.add_pattern(pattern)
|
|
|
|
if file_request.filters.suffixes:
|
|
for suffix in file_request.filters.suffixes:
|
|
file_filters.add_suffix(suffix)
|
|
|
|
filters.append(file_filters)
|
|
dialog.set_filters(filters)
|
|
|
|
if file_request.initial_file:
|
|
p = Path(file_request.initial_file).expanduser()
|
|
f = Gio.File.new_for_path(str(p))
|
|
dialog.set_initial_file(f)
|
|
|
|
if file_request.initial_folder:
|
|
p = Path(file_request.initial_folder).expanduser()
|
|
f = Gio.File.new_for_path(str(p))
|
|
dialog.set_initial_folder(f)
|
|
|
|
# if select_folder
|
|
if file_request.mode == "select_folder":
|
|
dialog.select_folder(callback=on_folder_select)
|
|
if file_request.mode == "open_multiple_files":
|
|
dialog.open_multiple(callback=on_file_select_multiple)
|
|
elif file_request.mode == "open_file":
|
|
dialog.open(callback=on_file_select)
|
|
elif file_request.mode == "save":
|
|
dialog.save(callback=on_save_finish)
|
|
|
|
return GLib.SOURCE_REMOVE
|