Bringing to latest changes #3

Merged
itdominator merged 41 commits from develop into master 2022-07-16 19:14:30 +00:00
9 changed files with 99 additions and 17 deletions
Showing only changes of commit bcc04dda3c - Show all commits

View File

@ -3,7 +3,7 @@ Copy the example and rename it to your desired name. Plugins define a ui target
Plugins must have a run method defined; though, you do not need to necessarily do anything within it. The run method implies that the passed in event system or other data is ready for the plugin to use. Plugins must have a run method defined; though, you do not need to necessarily do anything within it. The run method implies that the passed in event system or other data is ready for the plugin to use.
### Manifest ### Manifest Example (All are required.)
``` ```
class Manifest: class Manifest:
path: str = os.path.dirname(os.path.realpath(__file__)) path: str = os.path.dirname(os.path.realpath(__file__))
@ -24,7 +24,10 @@ class Manifest:
permissions: {} = { permissions: {} = {
'ui_target': "plugin_control_list", 'ui_target': "plugin_control_list",
'ui_target_id': "<some other Gtk Glade ID>" # Only needed if using "other" in "ui_target". See below for predefined "ui_target" options... 'ui_target_id': "<some other Gtk Glade ID>" # Only needed if using "other" in "ui_target". See below for predefined "ui_target" options...
'pass_fm_events': "true" # If empty or undefined will be ignored. 'pass_fm_events': "true" # If empty or not present will be ignored.
'bind_keys': [f"{name}||send_message:<Control>f"],
f"{name}||do_save:<Control>s"] # Bind keys with method and key pare using list. Must pass "name" like shown with delimiter to its right.
} }
``` ```

View File

@ -32,8 +32,8 @@ class Manifest:
support: str = "" support: str = ""
permissions: {} = { permissions: {} = {
'ui_target': "plugin_control_list", 'ui_target': "plugin_control_list",
'pass_fm_events': "true" 'pass_fm_events': "true",
'bind_keys': [f"{name}||send_message:<Control>f"]
} }
@ -58,6 +58,7 @@ class Plugin(Manifest):
def send_message(self, widget=None, eve=None): def send_message(self, widget=None, eve=None):
message = "Hello, World!" message = "Hello, World!"
print("here")
self._event_system.push_gui_event([self.name, "display_message", ("warning", message, None)]) self._event_system.push_gui_event([self.name, "display_message", ("warning", message, None)])
@ -68,13 +69,17 @@ class Plugin(Manifest):
event = self._event_system.read_module_event() event = self._event_system.read_module_event()
if event: if event:
try: try:
if event[0] is self.name: if event[0] == self.name:
target_id, method_target, data = self._event_system.consume_module_event() target_id, method_target, data = self._event_system.consume_module_event()
if not method_target: if not method_target:
self._event_message = data self._event_message = data
else: else:
method = getattr(self.__class__, f"{method_target}") method = getattr(self.__class__, f"{method_target}")
data = method(*(self, *parameters)) if data:
data = method(*(self, *data))
else:
method(*(self,))
except Exception as e: except Exception as e:
print("ewww here")
print(repr(e)) print(repr(e))

View File

@ -63,14 +63,17 @@ class Plugin(Manifest):
event = self._fm_event_system.read_module_event() event = self._fm_event_system.read_module_event()
if event: if event:
try: try:
if event[0] is self.name: if event[0] == self.name:
target_id, method_target, data = self._fm_event_system.consume_module_event() target_id, method_target, data = self._fm_event_system.consume_module_event()
if not method_target: if not method_target:
self._fm_event_message = data self._fm_event_message = data
else: else:
method = getattr(self.__class__, f"{method_target}") method = getattr(self.__class__, f"{method_target}")
data = method(*(self, *parameters)) if data:
data = method(*(self, *data))
else:
method(*(self,))
except Exception as e: except Exception as e:
print(repr(e)) print(repr(e))

View File

@ -84,6 +84,10 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMi
data = method(*(self, *parameters)) data = method(*(self, *parameters))
event_system.push_module_event([sender, None, data]) event_system.push_module_event([sender, None, data])
def handle_plugin_key_event(self, sender, method_target, parameters=()):
event_system.push_module_event([sender, method_target, parameters])
def save_load_session(self, action="save_session"): def save_load_session(self, action="save_session"):
wid, tid = self.fm_controller.get_active_wid_and_tid() wid, tid = self.fm_controller.get_active_wid_and_tid()
tab = self.get_fm_window(wid).get_tab_by_id(tid) tab = self.get_fm_window(wid).get_tab_by_id(tid)

View File

@ -19,6 +19,39 @@ def threaded(fn):
# NOTE: Consider trying to use Gtk.TreeView with css that turns it into a grid...
# Can possibly use this to dynamicly load icons instead...
class Icon(Gtk.HBox):
def __init__(self, tab, dir, file):
super(Icon, self).__init__()
self.load_icon(tab, dir, file)
@threaded
def load_icon(self, tab, dir, file):
icon = tab.create_icon(dir, file)
if not icon:
path = f"{dir}/{file}"
icon = self.get_system_thumbnail(path, tab.sys_icon_wh[0])
if not icon:
icon = GdkPixbuf.Pixbuf.new_from_file(tab.DEFAULT_ICON)
self.add(Gtk.Image.new_from_pixbuf(icon))
self.show_all()
def get_system_thumbnail(self, file, size):
try:
gio_file = Gio.File.new_for_path(file)
info = gio_file.query_info('standard::icon' , 0, None)
icon = info.get_icon().get_names()[0]
icon_path = self.icon_theme.lookup_icon(icon , size , 0).get_filename()
return GdkPixbuf.Pixbuf.new_from_file(icon_path)
except Exception as e:
return None
class GridMixin: class GridMixin:
"""docstring for WidgetMixin""" """docstring for WidgetMixin"""
@ -86,6 +119,15 @@ class GridMixin:
tid.hide() tid.hide()
return tab_widget return tab_widget
def create_scroll_and_store(self, tab, wid, use_tree_view=False):
if not use_tree_view:
scroll, store = self.create_icon_grid_widget(tab, wid)
else:
# TODO: Fix global logic to make the below work too
scroll, store = self.create_icon_tree_widget(tab, wid)
return scroll, store
def create_icon_grid_widget(self, tab, wid): def create_icon_grid_widget(self, tab, wid):
scroll = Gtk.ScrolledWindow() scroll = Gtk.ScrolledWindow()
grid = Gtk.IconView() grid = Gtk.IconView()
@ -112,7 +154,6 @@ class GridMixin:
grid.connect("drag-data-received", self.grid_on_drag_data_received) grid.connect("drag-data-received", self.grid_on_drag_data_received)
grid.connect("drag-motion", self.grid_on_drag_motion) grid.connect("drag-motion", self.grid_on_drag_motion)
URI_TARGET_TYPE = 80 URI_TARGET_TYPE = 80
uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE) uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE)
targets = [ uri_target ] targets = [ uri_target ]
@ -167,12 +208,14 @@ class GridMixin:
grid.enable_model_drag_dest(targets, action) grid.enable_model_drag_dest(targets, action)
grid.enable_model_drag_source(0, targets, action) grid.enable_model_drag_source(0, targets, action)
grid.show_all() grid.show_all()
scroll.add(grid) scroll.add(grid)
grid.set_name(f"{wid}|{tab.get_id()}") grid.set_name(f"{wid}|{tab.get_id()}")
scroll.set_name(f"{wid}|{tab.get_id()}") scroll.set_name(f"{wid}|{tab.get_id()}")
self.builder.expose_object(f"{wid}|{tab.get_id()}|icon_grid", grid)
self.builder.expose_object(f"{wid}|{tab.get_id()}", scroll)
grid.columns_autosize() grid.columns_autosize()
self.builder.expose_object(f"{wid}|{tab.get_id()}", scroll) self.builder.expose_object(f"{wid}|{tab.get_id()}", scroll)
return scroll, store return scroll, store

View File

@ -33,9 +33,7 @@ class TabMixin(GridMixin):
tab.set_path(path) tab.set_path(path)
tab_widget = self.create_tab_widget(tab) tab_widget = self.create_tab_widget(tab)
scroll, store = self.create_icon_grid_widget(tab, wid) scroll, store = self.create_scroll_and_store(tab, wid)
# TODO: Fix global logic to make the below work too
# scroll, store = self.create_icon_tree_widget(tab, wid)
index = notebook.append_page(scroll, tab_widget) index = notebook.append_page(scroll, tab_widget)
self.fm_controller.set_wid_and_tid(wid, tab.get_id()) self.fm_controller.set_wid_and_tid(wid, tab.get_id())

View File

@ -46,8 +46,14 @@ class KeyboardSignalsMixin:
mapping = self.keybindings.lookup(event) mapping = self.keybindings.lookup(event)
if mapping: if mapping:
try:
# See if in filemanager scope
getattr(self, mapping)() getattr(self, mapping)()
return True return True
except Exception:
# Must be plugins scope or we forgot to add method to file manager scope
sender, method_target = mapping.split("||")
self.handle_plugin_key_event(sender, method_target)
else: else:
if debug: if debug:
print(f"on_global_key_release_controller > key > {keyname}") print(f"on_global_key_release_controller > key > {keyname}")

View File

@ -15,7 +15,7 @@ class Plugin:
name: str = None name: str = None
author: str = None author: str = None
version: str = None version: str = None
suppoert: str = None support: str = None
permissions:{} = None permissions:{} = None
reference: type = None reference: type = None
@ -28,6 +28,8 @@ class Plugins:
self._settings = settings self._settings = settings
self._builder = self._settings.get_builder() self._builder = self._settings.get_builder()
self._plugins_path = self._settings.get_plugins_path() self._plugins_path = self._settings.get_plugins_path()
self._keybindings = self._settings.get_keybindings()
self._plugins_dir_watcher = None self._plugins_dir_watcher = None
self._plugin_collection = [] self._plugin_collection = []
@ -114,6 +116,10 @@ class Plugins:
if permissions["pass_fm_events"] in ["true"]: if permissions["pass_fm_events"] in ["true"]:
loading_data["pass_fm_events"] = True loading_data["pass_fm_events"] = True
if "bind_keys" in keys:
if isinstance(permissions["bind_keys"], list):
loading_data["bind_keys"] = permissions["bind_keys"]
return loading_data return loading_data
def execute_plugin(self, module: type, plugin: Plugin, loading_data: []): def execute_plugin(self, module: type, plugin: Plugin, loading_data: []):
@ -127,6 +133,9 @@ class Plugins:
if "pass_fm_events" in keys: if "pass_fm_events" in keys:
plugin.reference.set_fm_event_system(event_system) plugin.reference.set_fm_event_system(event_system)
if "bind_keys" in keys:
self._keybindings.append_bindings(loading_data["bind_keys"])
plugin.reference.run() plugin.reference.run()
self._plugin_collection.append(plugin) self._plugin_collection.append(plugin)

View File

@ -42,6 +42,17 @@ class Keybindings:
self.keymap = Gdk.Keymap.get_default() self.keymap = Gdk.Keymap.get_default()
self.configure({}) self.configure({})
def print_keys(self):
print(self.keys)
def append_bindings(self, combos):
"""Accept new binding(s) and reload"""
for item in combos:
method, keys = item.split(":")
self.keys[method] = keys
self.reload()
def configure(self, bindings): def configure(self, bindings):
"""Accept new bindings and reconfigure with them""" """Accept new bindings and reconfigure with them"""
self.keys = bindings self.keys = bindings