From f51a860de5868d95063c5e8a7c8370a28c6e3f7a Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Fri, 25 Nov 2022 23:12:43 -0600 Subject: [PATCH] Added IO ui to stop move or copy, enhanced favorites plugin --- plugins/disk_usage/plugin.py | 15 +--- plugins/favorites/favorites.glade | 6 +- plugins/favorites/plugin.py | 42 +++++------ .../solarfm/core/mixins/show_hide_mixin.py | 3 + .../mixins/ui/widget_file_action_mixin.py | 70 ++++++++++++++++++- .../usr/share/solarfm/Main_Window.glade | 54 +++++++++++--- 6 files changed, 139 insertions(+), 51 deletions(-) diff --git a/plugins/disk_usage/plugin.py b/plugins/disk_usage/plugin.py index 790caa2..285c288 100644 --- a/plugins/disk_usage/plugin.py +++ b/plugins/disk_usage/plugin.py @@ -1,5 +1,5 @@ # Python imports -import os, threading, subprocess, time, inspect +import os, subprocess, time, inspect # Lib imports import gi @@ -10,19 +10,6 @@ from gi.repository import Gtk from plugins.plugin_base import PluginBase -# NOTE: Threads WILL NOT die with parent's destruction. -def threaded(fn): - def wrapper(*args, **kwargs): - threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=False).start() - return wrapper - -# NOTE: Threads WILL die with parent's destruction. -def daemon_threaded(fn): - def wrapper(*args, **kwargs): - threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start() - return wrapper - - class Plugin(PluginBase): diff --git a/plugins/favorites/favorites.glade b/plugins/favorites/favorites.glade index 6c213db..ae1449d 100644 --- a/plugins/favorites/favorites.glade +++ b/plugins/favorites/favorites.glade @@ -1,15 +1,17 @@ - + + + - 320 + 420 450 False True diff --git a/plugins/favorites/plugin.py b/plugins/favorites/plugin.py index 9dc40ed..ce068de 100644 --- a/plugins/favorites/plugin.py +++ b/plugins/favorites/plugin.py @@ -1,5 +1,5 @@ # Python imports -import os, threading, subprocess, time, inspect, json +import os, inspect, json # Lib imports import gi @@ -10,19 +10,6 @@ from gi.repository import Gtk from plugins.plugin_base import PluginBase -# NOTE: Threads WILL NOT die with parent's destruction. -def threaded(fn): - def wrapper(*args, **kwargs): - threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=False).start() - return wrapper - -# NOTE: Threads WILL die with parent's destruction. -def daemon_threaded(fn): - def wrapper(*args, **kwargs): - threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start() - return wrapper - - class Plugin(PluginBase): @@ -65,7 +52,8 @@ class Plugin(PluginBase): with open(self._FAVORITES_FILE) as f: self._favorites = json.load(f) for favorite in self._favorites: - self._favorites_store.append([favorite]) + display, path = favorite + self._favorites_store.append([display, path]) else: with open(self._FAVORITES_FILE, 'a') as f: f.write('[]') @@ -78,25 +66,29 @@ class Plugin(PluginBase): button.connect("button-release-event", self._show_favorites_menu) return button - @threaded def _get_state(self, widget=None, eve=None): self._event_system.emit("get_current_state") - - @threaded def _set_current_dir_lbl(self, widget=None, eve=None): self._current_dir_lbl.set_label(f"Current Directory:\n{self._fm_state.tab.get_current_directory()}") def _add_to_favorite(self, state): - current_directory = self._fm_state.tab.get_current_directory() - self._favorites_store.append([current_directory]) - self._favorites.append(current_directory) + path = self._fm_state.tab.get_current_directory() + parts = path.split("/") + display = '/'.join(parts[-3:]) if len(parts) > 3 else path + + self._favorites_store.append([display, path]) + self._favorites.append([display, path]) self._save_favorites() def _remove_from_favorite(self, state): - path = self._favorites_store.get_value(self._selected, 0) + path = self._favorites_store.get_value(self._selected, 1) self._favorites_store.remove(self._selected) - self._favorites.remove(path) + + for i, f in enumerate(self._favorites): + if f[1] == path: + self._favorites.remove( self._favorites[i] ) + self._save_favorites() def _save_favorites(self): @@ -104,7 +96,7 @@ class Plugin(PluginBase): json.dump(self._favorites, outfile, separators=(',', ':'), indent=4) def _set_selected_path(self, widget=None, eve=None): - path = self._favorites_store.get_value(self._selected, 0) + path = self._favorites_store.get_value(self._selected, 1) self._ui_objects[0].set_text(path) self._set_current_dir_lbl() @@ -119,5 +111,5 @@ class Plugin(PluginBase): def _set_selected(self, user_data): selected = user_data.get_selected()[1] - if selected: + if selected and not self._selected == selected: self._selected = selected diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/show_hide_mixin.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/show_hide_mixin.py index 239b155..f968121 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/show_hide_mixin.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/show_hide_mixin.py @@ -115,6 +115,9 @@ class ShowHideMixin: if response == Gtk.ResponseType.CANCEL: self.cancel_edit = True + def show_io_popup(self, widget=None, eve=None): + self.builder.get_object("io_popup").popup() + def hide_edit_file_menu(self, widget=None, eve=None): self.builder.get_object("edit_file_menu").hide() diff --git a/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/ui/widget_file_action_mixin.py b/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/ui/widget_file_action_mixin.py index 007008a..572ec19 100644 --- a/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/ui/widget_file_action_mixin.py +++ b/src/versions/solarfm-0.0.1/SolarFM/solarfm/core/mixins/ui/widget_file_action_mixin.py @@ -320,16 +320,82 @@ class WidgetFileActionMixin: if action == "move" or action == "rename": tab.move_file(fPath, tPath) else: + # if action == "copy": + # file.copy(target, flags=Gio.FileCopyFlags.BACKUP, cancellable=None) + # if action == "move" or action == "rename": + # file.move(target, flags=Gio.FileCopyFlags.BACKUP, cancellable=None) + if action == "copy": - file.copy(target, flags=Gio.FileCopyFlags.BACKUP, cancellable=None) + container, cancle_eve, update_progress, finish_callback = self.create_io_widget(action, file) + file.copy_async(destination=target, flags=Gio.FileCopyFlags.BACKUP, + io_priority=98, cancellable=cancle_eve, + progress_callback=update_progress, callback=finish_callback) + self.builder.get_object("io_list").add(container) if action == "move" or action == "rename": - file.move(target, flags=Gio.FileCopyFlags.BACKUP, cancellable=None) + container, cancle_eve, update_progress, finish_callback = self.create_io_widget(action, file) + file.move(destination=target, flags=Gio.FileCopyFlags.BACKUP, + cancellable=cancle_eve, progress_callback=update_progress) + self.builder.get_object("io_list").add(container) + except GObject.GError as e: raise OSError(e) self.exists_file_rename_bttn.set_sensitive(False) + # NOTE: There is something not right about the way we are doing this. + # Calling cancel results in an error getting thrown to finish_callback + # and checking for task.had_error() is True and task.get_completed() is False + def create_io_widget(self, action, file): + cancle_eve = Gio.Cancellable.new() + container = Gtk.Box() + stats = Gtk.Box() + label = Gtk.Label() + progress = Gtk.ProgressBar() + cncl_button = Gtk.Button(label="Cancel") + del_button = Gtk.Button(label="Delete") + io_list = self.builder.get_object("io_list") + label.set_label(file.get_basename()) + + progress.set_show_text(True) + progress.set_text(f"{action.upper()}ING") + + + def do_cancel(widget, container, eve): + print(f"Canceling: [{action}] of {file.get_basename()} ...") + eve.cancel() + + def update_progress(current, total, eve=None): + progress.set_fraction(current/total) + + def finish_callback(file, task=None, eve=None): + io_list.remove(container) + # if not task.had_error(): + # self.builder.get_object("io_list").remove(container) + # else: + # print(f"{action} of {file.get_basename()} failed...") + + def delete_container(widget, eve): + io_list.remove(container) + + + if not action == "move": + stats.pack_end(cncl_button, False, False, 5) + cncl_button.connect("clicked", do_cancel, *(container, cancle_eve)) + else: + stats.pack_end(del_button, False, False, 5) + del_button.connect("clicked", delete_container, ()) + + container.set_orientation(1) + stats.set_orientation(0) + stats.add(progress) + + container.add(label) + container.add(stats) + container.show_all() + + return container, cancle_eve, update_progress, finish_callback + def setup_exists_data(self, from_file, to_file): from_info = from_file.query_info("standard::*,time::modified", 0, cancellable=None) diff --git a/user_config/usr/share/solarfm/Main_Window.glade b/user_config/usr/share/solarfm/Main_Window.glade index de3b02a..3910294 100644 --- a/user_config/usr/share/solarfm/Main_Window.glade +++ b/user_config/usr/share/solarfm/Main_Window.glade @@ -1,5 +1,5 @@ - + @@ -482,6 +482,11 @@ SolarFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspe False gtk-execute + + True + False + gtk-stop + True @@ -824,7 +829,23 @@ SolarFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspe 5 start - + + I/O + True + True + True + io_img + True + + + + True + True + 0 + + + + Plugins True True @@ -834,7 +855,7 @@ SolarFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspe True True - 0 + 1 @@ -850,7 +871,7 @@ SolarFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspe True True - 1 + 2 @@ -866,7 +887,7 @@ SolarFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspe True True - 2 + 3 @@ -882,7 +903,7 @@ SolarFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspe True True - 3 + 4 @@ -898,7 +919,7 @@ SolarFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspe True True - 4 + 5 @@ -1832,6 +1853,23 @@ SolarFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspe + + False + io_button + bottom + + + 320 + 320 + True + False + vertical + + + + + + 320 False @@ -2099,7 +2137,7 @@ SolarFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspe False - plugins_buttoin + plugins_button