Added open with feature; fixed delete non empty dir

This commit is contained in:
itdominator 2021-11-27 00:51:31 -06:00
parent 7119e49ab7
commit 49e2bc5983
6 changed files with 189 additions and 35 deletions

View File

@ -33,6 +33,7 @@ if __name__ == "__main__":
Main(args, unknownargs) Main(args, unknownargs)
Gtk.main() Gtk.main()
except Exception as e: except Exception as e:
print(repr(e))
event_system.keep_ipc_alive = False event_system.keep_ipc_alive = False
if debug: if debug:
traceback.print_exc() traceback.print_exc()

View File

@ -383,6 +383,75 @@ PyFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspecti
</object> </object>
</child> </child>
</object> </object>
<object class="GtkDialog" id="appchooser_menu">
<property name="can-focus">False</property>
<property name="window-position">mouse</property>
<property name="type-hint">splashscreen</property>
<property name="gravity">south</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="button1">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="use-stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="appchooser_select_btn">
<property name="label" translatable="yes">Select</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkAppChooserWidget" id="appchooser_widget">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="show-recommended">False</property>
<property name="show-all">True</property>
<signal name="application-activated" handler="run_appchooser_launch" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">button1</action-widget>
<action-widget response="-5">appchooser_select_btn</action-widget>
</action-widgets>
</object>
<object class="GtkImage" id="createImage"> <object class="GtkImage" id="createImage">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
@ -534,6 +603,11 @@ PyFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspecti
</object> </object>
</child> </child>
</object> </object>
<object class="GtkImage" id="open_with_img">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="stock">gtk-open</property>
</object>
<object class="GtkImage" id="rename_img"> <object class="GtkImage" id="rename_img">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
@ -555,6 +629,7 @@ PyFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspecti
<property name="modal">True</property> <property name="modal">True</property>
<property name="window-position">center</property> <property name="window-position">center</property>
<property name="type-hint">splashscreen</property> <property name="type-hint">splashscreen</property>
<property name="skip-pager-hint">True</property>
<property name="gravity">center</property> <property name="gravity">center</property>
<signal name="focus-out-event" handler="hide_edit_file_menu" swapped="no"/> <signal name="focus-out-event" handler="hide_edit_file_menu" swapped="no"/>
<child internal-child="vbox"> <child internal-child="vbox">
@ -1256,6 +1331,9 @@ PyFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspecti
<property name="position">2</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
<child>
<placeholder/>
</child>
</object> </object>
</child> </child>
</object> </object>
@ -1269,6 +1347,7 @@ PyFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspecti
<property name="resizable">False</property> <property name="resizable">False</property>
<property name="window-position">mouse</property> <property name="window-position">mouse</property>
<property name="type-hint">splashscreen</property> <property name="type-hint">splashscreen</property>
<property name="skip-pager-hint">True</property>
<property name="decorated">False</property> <property name="decorated">False</property>
<property name="deletable">False</property> <property name="deletable">False</property>
<property name="gravity">static</property> <property name="gravity">static</property>
@ -1321,7 +1400,7 @@ PyFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspecti
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">3</property> <property name="position">4</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -1341,6 +1420,22 @@ PyFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspecti
<property name="position">0</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Open With</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="image">open_with_img</property>
<property name="always-show-image">True</property>
<signal name="button-release-event" handler="show_appchooser_menu" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child> <child>
<object class="GtkButton"> <object class="GtkButton">
<property name="label" translatable="yes">Rename</property> <property name="label" translatable="yes">Rename</property>
@ -1356,7 +1451,7 @@ PyFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspecti
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">1</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -1375,7 +1470,7 @@ PyFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspecti
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="pack-type">end</property> <property name="pack-type">end</property>
<property name="position">2</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -1393,7 +1488,7 @@ PyFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspecti
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">3</property> <property name="position">4</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -1411,7 +1506,7 @@ PyFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspecti
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">4</property> <property name="position">5</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -1429,7 +1524,7 @@ PyFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspecti
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">5</property> <property name="position">6</property>
</packing> </packing>
</child> </child>
</object> </object>

View File

@ -13,7 +13,7 @@ class FileHandler:
return True return True
except Exception as e: except Exception as e:
print("An error occured renaming the file:") print("An error occured renaming the file:")
print(e) print(repr(e))
return False return False
def delete_file(self, toDeleteFile): def delete_file(self, toDeleteFile):
@ -32,7 +32,7 @@ class FileHandler:
return False return False
except Exception as e: except Exception as e:
print("An error occured deleting the file:") print("An error occured deleting the file:")
print(e) print(repr(e))
return False return False
return True return True
@ -50,16 +50,22 @@ class FileHandler:
return False return False
except Exception as e: except Exception as e:
print("An error occured moving the file:") print("An error occured moving the file:")
print(e) print(repr(e))
return False return False
return True return True
def copy_file(self): def copy_file(self,fFile, tFile, symlinks=False, ignore=None):
pass try:
if os.path.isdir(fFile):
shutil.copytree(fFile, tFile, symlinks, ignore)
else:
shutil.copy2(fFile, tFile)
except Exception as e:
print("An error occured copying the file:")
print(repr(e))
return False
def cut_file(self):
pass
def paste_file(self): def paste_file(self):
pass pass

View File

@ -222,24 +222,42 @@ class Signals(WidgetFileActionMixin, PaneMixin, WindowMixin):
def hide_about_page(self, widget=None, eve=None): def hide_about_page(self, widget=None, eve=None):
about_page = self.builder.get_object("about_page").hide() about_page = self.builder.get_object("about_page").hide()
def show_appchooser_menu(self, widget=None, eve=None):
appchooser_menu = self.builder.get_object("appchooser_menu")
appchooser_widget = self.builder.get_object("appchooser_widget")
resp = appchooser_menu.run()
if resp == Gtk.ResponseType.CANCEL:
self.hide_appchooser_menu()
if resp == Gtk.ResponseType.OK:
self.open_with_files(appchooser_widget)
self.hide_appchooser_menu()
def hide_appchooser_menu(self, widget=None, eve=None):
self.builder.get_object("appchooser_menu").hide()
def run_appchooser_launch(self, widget=None, eve=None):
self.builder.get_object("appchooser_select_btn").pressed()
def show_context_menu(self, widget=None, eve=None): def show_context_menu(self, widget=None, eve=None):
self.builder.get_object("context_menu").run() self.builder.get_object("context_menu").run()
def hide_context_menu(self, widget=None, eve=None): def hide_context_menu(self, widget=None, eve=None):
self.builder.get_object("context_menu").hide() self.builder.get_object("context_menu").hide()
def show_edit_file_menu(self, widget=None, eve=None):
self.builder.get_object("edit_file_menu").run()
def hide_edit_file_menu(self, widget=None, eve=None):
self.builder.get_object("edit_file_menu").hide()
def show_new_file_menu(self, widget=None, eve=None): def show_new_file_menu(self, widget=None, eve=None):
self.builder.get_object("new_file_menu").run() self.builder.get_object("new_file_menu").run()
def hide_new_file_menu(self, widget=None, eve=None): def hide_new_file_menu(self, widget=None, eve=None):
self.builder.get_object("new_file_menu").hide() self.builder.get_object("new_file_menu").hide()
def show_edit_file_menu(self, widget=None, eve=None):
self.builder.get_object("edit_file_menu").run()
def hide_edit_file_menu(self, widget=None, eve=None):
self.builder.get_object("edit_file_menu").hide()
def hide_edit_file_menu_skip(self, widget=None, eve=None): def hide_edit_file_menu_skip(self, widget=None, eve=None):
self.skip_edit = True self.skip_edit = True
self.builder.get_object("edit_file_menu").hide() self.builder.get_object("edit_file_menu").hide()

View File

@ -62,8 +62,8 @@ class TabMixin(WidgetMixin):
page = notebook.page_num(scroll) page = notebook.page_num(scroll)
view = self.get_fm_window(wid).get_view_by_id(tid) view = self.get_fm_window(wid).get_view_by_id(tid)
watcher = view.get_dir_watcher() watcher = view.get_dir_watcher()
watcher.cancel()
watcher.cancel()
self.get_fm_window(wid).delete_view_by_id(tid) self.get_fm_window(wid).delete_view_by_id(tid)
notebook.remove_page(page) notebook.remove_page(page)
self.window_controller.save_state() self.window_controller.save_state()
@ -76,8 +76,8 @@ class TabMixin(WidgetMixin):
for i, view in enumerate(window.views): for i, view in enumerate(window.views):
if view.id == tid: if view.id == tid:
_view = window.get_view_by_id(tid) _view = window.get_view_by_id(tid)
watcher = _view.get_dir_watcher() watcher = _view.get_dir_watcher()
watcher.cancel() watcher.cancel()
window.views.insert(new_index, window.views.pop(i)) window.views.insert(new_index, window.views.pop(i))

View File

@ -74,6 +74,17 @@ class WidgetFileActionMixin:
for file in uris: for file in uris:
view.open_file_locally(file) view.open_file_locally(file)
def open_with_files(self, appchooser_widget):
wid, tid = self.window_controller.get_active_data()
view = self.get_fm_window(wid).get_view_by_id(tid)
iconview = self.builder.get_object(f"{wid}|{tid}|iconview")
store = iconview.get_model()
uris = self.format_to_uris(store, wid, tid, self.selected_files)
f = Gio.File.new_for_uri(uris[0])
app_info = appchooser_widget.get_app_info()
app_info.launch([f], None)
def edit_files(self): def edit_files(self):
pass pass
@ -84,9 +95,9 @@ class WidgetFileActionMixin:
view = self.get_fm_window(wid).get_view_by_id(tid) view = self.get_fm_window(wid).get_view_by_id(tid)
iconview = self.builder.get_object(f"{wid}|{tid}|iconview") iconview = self.builder.get_object(f"{wid}|{tid}|iconview")
store = iconview.get_model() store = iconview.get_model()
uris = self.format_to_uris(store, wid, tid, self.to_rename_files, True) uris = self.format_to_uris(store, wid, tid, self.to_rename_files)
# The rename button hides the rename dialog box which lets this loop continue. # The rename button hides the rename dialog box which lets the loop continue.
# Weirdly, the show at the end is needed to flow through all the list properly # Weirdly, the show at the end is needed to flow through all the list properly
# than auto chosing the first rename entry you do. # than auto chosing the first rename entry you do.
for uri in uris: for uri in uris:
@ -97,6 +108,7 @@ class WidgetFileActionMixin:
self.skip_edit = False self.skip_edit = False
self.show_edit_file_menu() self.show_edit_file_menu()
# Yes...this step is required even with the above... =/
self.show_edit_file_menu() self.show_edit_file_menu()
if self.skip_edit: if self.skip_edit:
@ -106,7 +118,7 @@ class WidgetFileActionMixin:
rname_to = rename_input.get_text().strip() rname_to = rename_input.get_text().strip()
target = f"file://{view.get_current_directory()}/{rname_to}" target = f"file://{view.get_current_directory()}/{rname_to}"
self.handle_file([f"file://{uri}"], "edit", target) self.handle_file([uri], "edit", target)
self.show_edit_file_menu() self.show_edit_file_menu()
@ -190,8 +202,8 @@ class WidgetFileActionMixin:
if _target_path: if _target_path:
if os.path.isdir(_target_path): if os.path.isdir(_target_path):
info = f.query_info("standard::display-name", 0, cancellable=None) info = f.query_info("standard::display-name", 0, cancellable=None)
_target = f"file://{base_dir}/{info.get_display_name()}" _target = f"file://{_target_path}/{info.get_display_name()}"
target = Gio.File.new_for_uri(_target_path) target = Gio.File.new_for_uri(_target)
else: else:
target = Gio.File.new_for_uri(_target_path) target = Gio.File.new_for_uri(_target_path)
@ -200,14 +212,36 @@ class WidgetFileActionMixin:
(f.get_parent().get_path() == target.get_parent().get_path()): (f.get_parent().get_path() == target.get_parent().get_path()):
break break
if action == "delete": type = f.query_file_type(flags=Gio.FileQueryInfoFlags.NONE, cancellable=None)
f.delete(cancellable=None) if not type == Gio.FileType.DIRECTORY:
if action == "trash": if action == "delete":
f.trash(cancellable=None) f.delete(cancellable=None)
if action == "copy": if action == "trash":
f.copy(target, flags=Gio.FileCopyFlags.BACKUP, cancellable=None) f.trash(cancellable=None)
if action == "move" or action == "edit": if action == "copy":
f.move(target, flags=Gio.FileCopyFlags.BACKUP, cancellable=None) f.copy(target, flags=Gio.FileCopyFlags.BACKUP, cancellable=None)
if action == "move" or action == "edit":
f.move(target, flags=Gio.FileCopyFlags.BACKUP, cancellable=None)
else:
wid, tid = self.window_controller.get_active_data()
view = self.get_fm_window(wid).get_view_by_id(tid)
fPath = f.get_path()
tPath = None
if target:
tPath = target.get_path()
if action == "delete":
view.delete_file(fPath)
if action == "trash":
f.trash(cancellable=None)
if action == "copy":
view.copy_file(fPath, tPath)
# f.copy(target, flags=Gio.FileCopyFlags.BACKUP, cancellable=None)
if action == "move" or action == "edit":
view.move_file(fPath, tPath)
# f.move(target, flags=Gio.FileCopyFlags.BACKUP, cancellable=None)
except GObject.GError as e: except GObject.GError as e:
raise OSError(e.message) raise OSError(e.message)