From 79728cb7063f016d4d2587c60918d41ecd8a29c6 Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Sun, 16 Apr 2023 02:47:26 -0500 Subject: [PATCH] WIP FileWidget copy vs link logic --- src/core/query_controller.py | 11 ++- src/core/widgets/dialogs/message_widget.py | 11 +++ src/core/widgets/io_widget.py | 83 +++++++++++++++++ .../widgets/widget_selector/widgets/file.py | 91 ++++++++++++++++--- 4 files changed, 176 insertions(+), 20 deletions(-) create mode 100644 src/core/widgets/io_widget.py diff --git a/src/core/query_controller.py b/src/core/query_controller.py index 5cd0c0e..1409afa 100644 --- a/src/core/query_controller.py +++ b/src/core/query_controller.py @@ -65,11 +65,12 @@ class QueryController(Gtk.Popover): self.clear_children(self._query_selector_list) for _widget, collector in self.queryable_widgets: - if query.lower() in collector().lower(): - path = self.get_path_names(_widget) - button = Gtk.Button(label=path) - button.connect("button-release-event", self._focus_widget, _widget) - self._query_selector_list.add(button) + if not query in (None, ""): + if query.lower() in collector().lower(): + path = self.get_path_names(_widget) + button = Gtk.Button(label=path) + button.connect("button-release-event", self._focus_widget, _widget) + self._query_selector_list.add(button) self._query_selector_list.show_all() self.show() diff --git a/src/core/widgets/dialogs/message_widget.py b/src/core/widgets/dialogs/message_widget.py index 1029da4..9dcf9ad 100644 --- a/src/core/widgets/dialogs/message_widget.py +++ b/src/core/widgets/dialogs/message_widget.py @@ -32,6 +32,7 @@ class MessageWidget(Gtk.MessageDialog): def _subscribe_to_events(self): event_system.subscribe("delete_files", self.delete_files) + event_system.subscribe("confirm_action", self.confirm_action) def _load_widgets(self): message_area = self.get_message_area() @@ -42,6 +43,16 @@ class MessageWidget(Gtk.MessageDialog): self.add_buttons(Gtk.STOCK_NO, Gtk.ResponseType.NO) self.add_buttons(Gtk.STOCK_YES, Gtk.ResponseType.YES) + def confirm_action(self, widget = None, eve = None, msg = f"Do you really want to do this action?"): + response = None + + self.format_secondary_text(msg) + if not response: + response = self.run() + self.hide() + + return response + def delete_files(self, widget = None, eve = None, uris = None, msg = f"Do you really want to delete the file(s)?"): response = None diff --git a/src/core/widgets/io_widget.py b/src/core/widgets/io_widget.py new file mode 100644 index 0000000..c0bcce1 --- /dev/null +++ b/src/core/widgets/io_widget.py @@ -0,0 +1,83 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk +from gi.repository import Gio + +# Application imports + + + + +class IOWidget(Gtk.Box): + """docstring for IOWidget""" + + def __init__(self, action, file): + super(IOWidget, self).__init__() + + self._action = action + self._file = file + self._basename = self._file.get_basename() + + self.cancle_eve = Gio.Cancellable.new() + self.progress = None + + self._setup_styling() + self._setup_signals() + self._load_widgets() + + self.show_all() + + + def _setup_styling(self): + self.set_orientation(1) + + def _setup_signals(self): + ... + + def _load_widgets(self): + stats = Gtk.Box() + label = Gtk.Label() + cncl_button = Gtk.Button(label="Cancel") + del_button = Gtk.Button(label="Clear") + self.progress = Gtk.ProgressBar() + + label.set_label(self._basename) + self.progress.set_show_text(True) + self.progress.set_text(f"{self._action.upper()}ING") + stats.set_orientation(0) + + stats.pack_end(del_button, False, False, 5) + del_button.connect("clicked", self.delete_self, ()) + + if not self._action in ("create", "rename"): + stats.pack_end(cncl_button, False, False, 5) + cncl_button.connect("clicked", self.do_cancel, *(self, self.cancle_eve)) + + stats.add(self.progress) + self.add(label) + self.add(stats) + + + def do_cancel(self, widget, container, eve): + logger.info(f"Canceling: [{self._action}] of {self._basename} ...") + eve.cancel() + + def update_progress(self, current, total, eve=None): + self.progress.set_fraction(current/total) + + def finish_callback(self, file, task=None, eve=None): + if self._action == "move" or self._action == "rename": + status = self._file.move_finish(task) + if self._action == "copy": + status = self._file.copy_finish(task) + + if status: + self.delete_self() + else: + logger.info(f"{self._action} of {self._basename} failed...") + + def delete_self(self, widget=None, eve=None): + self.get_parent().remove(self) diff --git a/src/core/widgets/widget_selector/widgets/file.py b/src/core/widgets/widget_selector/widgets/file.py index eb337d1..8409461 100644 --- a/src/core/widgets/widget_selector/widgets/file.py +++ b/src/core/widgets/widget_selector/widgets/file.py @@ -1,4 +1,5 @@ # Python imports +import os # Lib imports import gi @@ -8,6 +9,7 @@ from gi.repository import Gio # Application imports from utils.widget_save_load_controller import WidgetSaveLoadController +from ...io_widget import IOWidget @@ -57,7 +59,7 @@ class FileWidget(WidgetSaveLoadController, Gtk.Box): def __init__(self): super(FileWidget, self).__init__() - self._file_path = None + self._file = None self._file_name = "No File Selected..." self.label = None @@ -133,43 +135,102 @@ class FileWidget(WidgetSaveLoadController, Gtk.Box): self.load_saveable_data() def load_saveable_data(self): - self.set_file_path( self.save_collection["data"] ) + self.set_file_path( self.save_collection["data"], True) - def set_file_path(self, path = settings.get_home_path()): + def set_file_path(self, path = settings.get_home_path(), is_loading = False): try: - self._file_path = Gio.File.new_for_uri(path) - if not self._file_path.get_path(): + self._file = Gio.File.new_for_uri(path) + if not self._file.get_path(): raise FileWidgetException("Not URI based path...") except FileWidgetException as e: - self._file_path = Gio.File.new_for_path(path) + self._file = Gio.File.new_for_path(path) self._file_name = self.get_file_name() self.label.set_label(self._file_name) + self._process_path(is_loading) + + def _process_path(self, is_loading = False): + fpath = self.get_file_path() + + if not is_loading and not os.path.isdir(fpath): + size = self.get_file_size() + if size > 25000000: # NOTE: Aproximatly 25MB + response = event_system.emit_and_await("confirm_action", \ + (None, None, f"File is greator than 25MB. Keep as link or copy to notebook?\n\nFile:\n\t\t{self._file_name}\n\n(No) Use Link Only\t\t\t\t(Yes) Copy To Notebook")) + + if response in [Gtk.ResponseType.NO, Gtk.ResponseType.DELETE_EVENT]: + return + + self.copy_to_notebook() + + + def copy_to_notebook(self): + gio_copy_file = None + io_widget = IOWidget("copy", self._file) + working_page = settings.get_active_page().replace('MANIFEST', '') + files_dir = os.path.join(working_page, "files") + copy_tgt_pth = os.path.join(files_dir, self._file_name) + + if not os.path.exists(files_dir): + os.mkdir(files_dir) + + if os.path.exists(copy_tgt_pth): + return + + try: + gio_copy_file = Gio.File.new_for_uri(copy_tgt_pth) + if not gio_copy_file.get_path(): + raise FileWidgetException("Not URI based path...") + except FileWidgetException as e: + gio_copy_file = Gio.File.new_for_path(copy_tgt_pth) + + self._file.copy_async(destination = gio_copy_file, + flags = Gio.FileCopyFlags.BACKUP, + io_priority = 75, + cancellable = io_widget.cancle_eve, + progress_callback = io_widget.update_progress, + callback = io_widget.finish_callback) + + event_system.emit("append_to_io_list", (io_widget,)) + self._file = gio_copy_file def get_file(self): - return self._file_path + return self._file - def get_file_path(self): - path = self._file_path.get_path() + def get_file_path(self, file = None): + if not file: + file = self._file + + path = file.get_path() if not path: - path = self._file_path.get_uri() + path = file.get_uri() return path - def get_file_name(self): - info = self._file_path.query_info("standard::*", 0, cancellable = None) + def get_file_name(self, file = None): + if not file: + file = self._file + + info = file.query_info("standard::*", 0, cancellable = None) return info.get_display_name() + def get_file_size(self, file = None): + if not file: + file = self._file + + info = file.query_info("standard::*", 0, cancellable = None) + return info.get_size() + def set_current_file(self): dlg = FileChooser() response = dlg.run() + if response == 0: widget = dlg.get_file_chooser_widget() uris = widget.get_uris() - if len(uris) == 1: - uri = uris[0] - self.set_file_path(uri) + if len(uris) == 1: + self.set_file_path(uris[0]) dlg.destroy()