Merge Stable Changesto Master #9
|
@ -40,25 +40,3 @@ UI Targets:
|
||||||
<li>context_menu</li>
|
<li>context_menu</li>
|
||||||
<li>other</li>
|
<li>other</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
### Methods
|
|
||||||
```
|
|
||||||
# Must define and return a widget if "ui_target" is defined.
|
|
||||||
def get_ui_element(self):
|
|
||||||
button = Gtk.Button(label=self.name)
|
|
||||||
button.connect("button-release-event", self._do_download)
|
|
||||||
return button
|
|
||||||
|
|
||||||
# Must define in plugin if "pass_fm_events" is set to "true" string.
|
|
||||||
def set_fm_event_system(self, fm_event_system):
|
|
||||||
self._fm_event_system = fm_event_system
|
|
||||||
|
|
||||||
# Must define regardless if needed. Can just pass if plugin does stuff in its __init__
|
|
||||||
def run(self):
|
|
||||||
self._module_event_observer()
|
|
||||||
|
|
||||||
# Must define in plugin if "pass_ui_objects" is set and an array of valid glade UI IDs.
|
|
||||||
def set_ui_object_collection(self, ui_objects):
|
|
||||||
self._ui_objects = ui_objects
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
|
@ -41,11 +41,6 @@ class Plugin(PluginBase):
|
||||||
self._selected = None
|
self._selected = None
|
||||||
|
|
||||||
|
|
||||||
def get_ui_element(self):
|
|
||||||
button = Gtk.Button(label=self.name)
|
|
||||||
button.connect("button-release-event", self._show_favorites_menu)
|
|
||||||
return button
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self._builder = Gtk.Builder()
|
self._builder = Gtk.Builder()
|
||||||
self._builder.add_from_file(self._GLADE_FILE)
|
self._builder.add_from_file(self._GLADE_FILE)
|
||||||
|
@ -76,9 +71,14 @@ class Plugin(PluginBase):
|
||||||
f.write('[]')
|
f.write('[]')
|
||||||
|
|
||||||
|
|
||||||
|
def generate_reference_ui_element(self):
|
||||||
|
button = Gtk.Button(label=self.name)
|
||||||
|
button.connect("button-release-event", self._show_favorites_menu)
|
||||||
|
return button
|
||||||
|
|
||||||
@threaded
|
@threaded
|
||||||
def _get_state(self, widget=None, eve=None):
|
def _get_state(self, widget=None, eve=None):
|
||||||
self._event_system.emit("get_current_state
|
self._event_system.emit("get_current_state")
|
||||||
|
|
||||||
|
|
||||||
@threaded
|
@threaded
|
||||||
|
|
|
@ -83,11 +83,6 @@ class Plugin(PluginBase):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_ui_element(self):
|
|
||||||
button = Gtk.Button(label=self.name)
|
|
||||||
button.connect("button-release-event", self._show_properties_page)
|
|
||||||
return button
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self._builder = Gtk.Builder()
|
self._builder = Gtk.Builder()
|
||||||
self._builder.add_from_file(self._GLADE_FILE)
|
self._builder.add_from_file(self._GLADE_FILE)
|
||||||
|
@ -103,11 +98,15 @@ class Plugin(PluginBase):
|
||||||
self._file_owner = self._builder.get_object("file_owner")
|
self._file_owner = self._builder.get_object("file_owner")
|
||||||
self._file_group = self._builder.get_object("file_group")
|
self._file_group = self._builder.get_object("file_group")
|
||||||
|
|
||||||
|
def generate_reference_ui_element(self):
|
||||||
|
button = Gtk.Button(label=self.name)
|
||||||
|
button.connect("button-release-event", self._show_properties_page)
|
||||||
|
return button
|
||||||
|
|
||||||
|
|
||||||
@threaded
|
@threaded
|
||||||
def _show_properties_page(self, widget=None, eve=None):
|
def _show_properties_page(self, widget=None, eve=None):
|
||||||
event_system.emit("get_current_state
|
event_system.emit("get_current_state")
|
||||||
|
|
||||||
state = self._fm_state
|
state = self._fm_state
|
||||||
self._event_message = None
|
self._event_message = None
|
||||||
|
|
|
@ -45,12 +45,6 @@ class Plugin(PluginBase):
|
||||||
self._trailer_link = None
|
self._trailer_link = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_ui_element(self):
|
|
||||||
button = Gtk.Button(label=self.name)
|
|
||||||
button.connect("button-release-event", self._show_info_page)
|
|
||||||
return button
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self._builder = Gtk.Builder()
|
self._builder = Gtk.Builder()
|
||||||
self._builder.add_from_file(self._GLADE_FILE)
|
self._builder.add_from_file(self._GLADE_FILE)
|
||||||
|
@ -75,6 +69,11 @@ class Plugin(PluginBase):
|
||||||
self._file_hash = self._builder.get_object("file_hash")
|
self._file_hash = self._builder.get_object("file_hash")
|
||||||
self._trailer_link = self._builder.get_object("trailer_link")
|
self._trailer_link = self._builder.get_object("trailer_link")
|
||||||
|
|
||||||
|
def generate_reference_ui_element(self):
|
||||||
|
button = Gtk.Button(label=self.name)
|
||||||
|
button.connect("button-release-event", self._show_info_page)
|
||||||
|
return button
|
||||||
|
|
||||||
@threaded
|
@threaded
|
||||||
def _show_info_page(self, widget=None, eve=None):
|
def _show_info_page(self, widget=None, eve=None):
|
||||||
self._event_system.emit("get_current_state")
|
self._event_system.emit("get_current_state")
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
"""
|
||||||
|
Pligin Module
|
||||||
|
"""
|
|
@ -1,8 +1,10 @@
|
||||||
# Python imports
|
# Python imports
|
||||||
import threading, subprocess, signal, time, json, shlex
|
import threading, subprocess, signal, json, shlex
|
||||||
|
|
||||||
# Lib imports
|
# Lib imports
|
||||||
from gi.repository import GLib
|
import gi
|
||||||
|
gi.require_version('Gtk', '3.0')
|
||||||
|
from gi.repository import Gtk, GLib
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from ..widgets.file_preview_widget import FilePreviewWidget
|
from ..widgets.file_preview_widget import FilePreviewWidget
|
||||||
|
@ -61,6 +63,8 @@ class FileSearchMixin:
|
||||||
self._list_proc = subprocess.Popen(command, cwd=self.path, stdin=None, stdout=None, stderr=None)
|
self._list_proc = subprocess.Popen(command, cwd=self.path, stdin=None, stdout=None, stderr=None)
|
||||||
|
|
||||||
def _load_file_ui(self, data):
|
def _load_file_ui(self, data):
|
||||||
|
Gtk.main_iteration()
|
||||||
|
|
||||||
if not data in ("", None):
|
if not data in ("", None):
|
||||||
jdata = json.loads( data )
|
jdata = json.loads( data )
|
||||||
target = jdata[0]
|
target = jdata[0]
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
# Python imports
|
# Python imports
|
||||||
import threading, subprocess, signal, time, json, shlex
|
import threading, subprocess, signal, json, shlex
|
||||||
|
|
||||||
# Lib imports
|
# Lib imports
|
||||||
from gi.repository import GLib
|
import gi
|
||||||
|
gi.require_version('Gtk', '3.0')
|
||||||
|
from gi.repository import Gtk, GLib
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from ..widgets.grep_preview_widget import GrepPreviewWidget
|
from ..widgets.grep_preview_widget import GrepPreviewWidget
|
||||||
|
@ -53,7 +55,7 @@ class GrepSearchMixin:
|
||||||
|
|
||||||
def _exec_grep_query(self, widget=None, eve=None):
|
def _exec_grep_query(self, widget=None, eve=None):
|
||||||
query = widget.get_text()
|
query = widget.get_text()
|
||||||
if not query in ("", None):
|
if not query.strip() in ("", None):
|
||||||
self.grep_query = query
|
self.grep_query = query
|
||||||
|
|
||||||
target_dir = shlex.quote( self._fm_state.tab.get_current_directory() )
|
target_dir = shlex.quote( self._fm_state.tab.get_current_directory() )
|
||||||
|
@ -61,6 +63,8 @@ class GrepSearchMixin:
|
||||||
self._grep_proc = subprocess.Popen(command, cwd=self.path, stdin=None, stdout=None, stderr=None)
|
self._grep_proc = subprocess.Popen(command, cwd=self.path, stdin=None, stdout=None, stderr=None)
|
||||||
|
|
||||||
def _load_grep_ui(self, data):
|
def _load_grep_ui(self, data):
|
||||||
|
Gtk.main_iteration()
|
||||||
|
|
||||||
if not data in ("", None):
|
if not data in ("", None):
|
||||||
jdata = json.loads( data )
|
jdata = json.loads( data )
|
||||||
jkeys = jdata.keys()
|
jkeys = jdata.keys()
|
||||||
|
|
|
@ -52,11 +52,6 @@ class Plugin(IPCServer, FileSearchMixin, GrepSearchMixin, PluginBase):
|
||||||
self.search_query = ""
|
self.search_query = ""
|
||||||
|
|
||||||
|
|
||||||
def get_ui_element(self):
|
|
||||||
button = Gtk.Button(label=self.name)
|
|
||||||
button.connect("button-release-event", self._show_page)
|
|
||||||
return button
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self._builder = Gtk.Builder()
|
self._builder = Gtk.Builder()
|
||||||
self._builder.add_from_file(self._GLADE_FILE)
|
self._builder.add_from_file(self._GLADE_FILE)
|
||||||
|
@ -84,6 +79,11 @@ class Plugin(IPCServer, FileSearchMixin, GrepSearchMixin, PluginBase):
|
||||||
|
|
||||||
self.create_ipc_listener()
|
self.create_ipc_listener()
|
||||||
|
|
||||||
|
def generate_reference_ui_element(self):
|
||||||
|
button = Gtk.Button(label=self.name)
|
||||||
|
button.connect("button-release-event", self._show_page)
|
||||||
|
return button
|
||||||
|
|
||||||
|
|
||||||
def _show_page(self, widget=None, eve=None):
|
def _show_page(self, widget=None, eve=None):
|
||||||
self._event_system.emit("get_current_state")
|
self._event_system.emit("get_current_state")
|
||||||
|
@ -109,6 +109,8 @@ class Plugin(IPCServer, FileSearchMixin, GrepSearchMixin, PluginBase):
|
||||||
self.grep_list_parent.add(self._grep_list)
|
self.grep_list_parent.add(self._grep_list)
|
||||||
self.grep_list_parent.show_all()
|
self.grep_list_parent.show_all()
|
||||||
|
|
||||||
|
Gtk.main_iteration()
|
||||||
|
|
||||||
def reset_file_list_box(self) -> None:
|
def reset_file_list_box(self) -> None:
|
||||||
try:
|
try:
|
||||||
child = self.file_list_parent.get_children()[0]
|
child = self.file_list_parent.get_children()[0]
|
||||||
|
@ -121,3 +123,5 @@ class Plugin(IPCServer, FileSearchMixin, GrepSearchMixin, PluginBase):
|
||||||
self._file_list.set_orientation(Gtk.Orientation.VERTICAL)
|
self._file_list.set_orientation(Gtk.Orientation.VERTICAL)
|
||||||
self.file_list_parent.add(self._file_list)
|
self.file_list_parent.add(self._file_list)
|
||||||
self.file_list_parent.show_all()
|
self.file_list_parent.show_all()
|
||||||
|
|
||||||
|
Gtk.main_iteration()
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
# Python imports
|
# Python imports
|
||||||
import os, threading, time, pickle
|
import os, threading, pickle
|
||||||
from multiprocessing.connection import Listener, Client
|
from multiprocessing.connection import Listener, Client
|
||||||
|
|
||||||
# Lib imports
|
# Lib imports
|
||||||
import gi
|
from gi.repository import GLib
|
||||||
gi.require_version('Gtk', '3.0')
|
|
||||||
from gi.repository import Gtk, GLib
|
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
|
|
||||||
|
@ -64,12 +62,12 @@ class IPCServer:
|
||||||
if "SEARCH|" in msg:
|
if "SEARCH|" in msg:
|
||||||
file = msg.split("SEARCH|")[1].strip()
|
file = msg.split("SEARCH|")[1].strip()
|
||||||
if file:
|
if file:
|
||||||
GLib.idle_add(self._load_file_ui, file)
|
GLib.idle_add(self._load_file_ui, file, priority=GLib.PRIORITY_LOW)
|
||||||
|
|
||||||
if "GREP|" in msg:
|
if "GREP|" in msg:
|
||||||
data = msg.split("GREP|")[1].strip()
|
data = msg.split("GREP|")[1].strip()
|
||||||
if data:
|
if data:
|
||||||
GLib.idle_add(self._load_grep_ui, data)
|
GLib.idle_add(self._load_grep_ui, data, priority=GLib.PRIORITY_LOW)
|
||||||
|
|
||||||
|
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
|
@ -16,8 +16,9 @@ from multiprocessing.connection import Client
|
||||||
_ipc_address = f'/tmp/solarfm-search_grep-ipc.sock'
|
_ipc_address = f'/tmp/solarfm-search_grep-ipc.sock'
|
||||||
_ipc_authkey = b'' + bytes(f'solarfm-search_grep-ipc', 'utf-8')
|
_ipc_authkey = b'' + bytes(f'solarfm-search_grep-ipc', 'utf-8')
|
||||||
|
|
||||||
filter = (".cpp", ".css", ".c", ".go", ".html", ".htm", ".java", ".js", ".json", ".lua", ".md", ".py", ".rs", ".toml", ".xml", ".pom") + \
|
filter = (".mkv", ".mp4", ".webm", ".avi", ".mov", ".m4v", ".mpg", ".mpeg", ".wmv", ".flv") + \
|
||||||
(".txt", ".text", ".sh", ".cfg", ".conf", ".log")
|
(".png", ".jpg", ".jpeg", ".gif", ".ico", ".tga", ".webp") + \
|
||||||
|
(".psf", ".mp3", ".ogg", ".flac", ".m4a")
|
||||||
|
|
||||||
# NOTE: Threads WILL NOT die with parent's destruction.
|
# NOTE: Threads WILL NOT die with parent's destruction.
|
||||||
def threaded(fn):
|
def threaded(fn):
|
||||||
|
@ -33,12 +34,12 @@ def daemon_threaded(fn):
|
||||||
|
|
||||||
|
|
||||||
def send_ipc_message(message) -> None:
|
def send_ipc_message(message) -> None:
|
||||||
with Client(address=_ipc_address, family="AF_UNIX", authkey=_ipc_authkey) as conn:
|
conn = Client(address=_ipc_address, family="AF_UNIX", authkey=_ipc_authkey)
|
||||||
conn.send(message)
|
conn.send(message)
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
# NOTE: Kinda important as this prevents overloading the UI thread
|
# NOTE: Kinda important as this prevents overloading the UI thread
|
||||||
time.sleep(0.04)
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
|
||||||
def file_search(path, query):
|
def file_search(path, query):
|
||||||
|
@ -57,10 +58,12 @@ def _search_for_string(file, query):
|
||||||
b64_file = base64.urlsafe_b64encode(file.encode('utf-8')).decode('utf-8')
|
b64_file = base64.urlsafe_b64encode(file.encode('utf-8')).decode('utf-8')
|
||||||
grep_result_set = {}
|
grep_result_set = {}
|
||||||
padding = 15
|
padding = 15
|
||||||
|
|
||||||
with open(file, 'r') as fp:
|
with open(file, 'r') as fp:
|
||||||
# NOTE: I know there's an issue if there's a very large file with content
|
# NOTE: I know there's an issue if there's a very large file with content
|
||||||
# all on one line will lower and dupe it. And, yes, it will only
|
# all on one line will lower and dupe it. And, yes, it will only
|
||||||
# return one instance from the file.
|
# return one instance from the file.
|
||||||
|
try:
|
||||||
for i, raw in enumerate(fp):
|
for i, raw in enumerate(fp):
|
||||||
line = None
|
line = None
|
||||||
llower = raw.lower()
|
llower = raw.lower()
|
||||||
|
@ -84,8 +87,15 @@ def _search_for_string(file, query):
|
||||||
grep_result_set[f"{b64_file}"] = {}
|
grep_result_set[f"{b64_file}"] = {}
|
||||||
grep_result_set[f"{b64_file}"] = {f"{i+1}": b64_line}
|
grep_result_set[f"{b64_file}"] = {f"{i+1}": b64_line}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
...
|
||||||
|
|
||||||
|
try:
|
||||||
data = f"GREP|{json.dumps(grep_result_set)}"
|
data = f"GREP|{json.dumps(grep_result_set)}"
|
||||||
send_ipc_message(data)
|
send_ipc_message(data)
|
||||||
|
except Exception as e:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@daemon_threaded
|
@daemon_threaded
|
||||||
|
@ -99,7 +109,7 @@ def grep_search(path, query):
|
||||||
if os.path.isdir(target):
|
if os.path.isdir(target):
|
||||||
grep_search(target, query)
|
grep_search(target, query)
|
||||||
else:
|
else:
|
||||||
if target.lower().endswith(filter):
|
if not target.lower().endswith(filter):
|
||||||
size = os.path.getsize(target)
|
size = os.path.getsize(target)
|
||||||
if not size > 5000:
|
if not size > 5000:
|
||||||
_search_for_string(target, query)
|
_search_for_string(target, query)
|
||||||
|
|
|
@ -33,7 +33,7 @@ class Plugin(PluginBase):
|
||||||
# where self.name should not be needed for message comms
|
# where self.name should not be needed for message comms
|
||||||
|
|
||||||
|
|
||||||
def get_ui_element(self):
|
def generate_reference_ui_element(self):
|
||||||
button = Gtk.Button(label=self.name)
|
button = Gtk.Button(label=self.name)
|
||||||
button.connect("button-release-event", self.send_message)
|
button.connect("button-release-event", self.send_message)
|
||||||
return button
|
return button
|
||||||
|
|
|
@ -39,7 +39,14 @@ class Plugin(PluginBase):
|
||||||
|
|
||||||
self.trashman.regenerate()
|
self.trashman.regenerate()
|
||||||
|
|
||||||
def get_ui_element(self):
|
|
||||||
|
def run(self):
|
||||||
|
self._event_system.subscribe("show_trash_buttons", self._show_trash_buttons)
|
||||||
|
self._event_system.subscribe("hide_trash_buttons", self._hide_trash_buttons)
|
||||||
|
self._event_system.subscribe("delete_files", self.delete_files)
|
||||||
|
self._event_system.subscribe("trash_files", self.trash_files)
|
||||||
|
|
||||||
|
def generate_reference_ui_element(self):
|
||||||
self._builder = Gtk.Builder()
|
self._builder = Gtk.Builder()
|
||||||
self._builder.add_from_file(self._GLADE_FILE)
|
self._builder.add_from_file(self._GLADE_FILE)
|
||||||
|
|
||||||
|
@ -61,10 +68,6 @@ class Plugin(PluginBase):
|
||||||
return trasher
|
return trasher
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self._event_system.subscribe("show_trash_buttons", self._show_trash_buttons)
|
|
||||||
self._event_system.subscribe("hide_trash_buttons", self._hide_trash_buttons)
|
|
||||||
|
|
||||||
def _show_trash_buttons(self):
|
def _show_trash_buttons(self):
|
||||||
self._builder.get_object("restore_from_trash").show()
|
self._builder.get_object("restore_from_trash").show()
|
||||||
self._builder.get_object("empty_trash").show()
|
self._builder.get_object("empty_trash").show()
|
||||||
|
@ -74,6 +77,7 @@ class Plugin(PluginBase):
|
||||||
self._builder.get_object("empty_trash").hide()
|
self._builder.get_object("empty_trash").hide()
|
||||||
|
|
||||||
def delete_files(self, widget = None, eve = None):
|
def delete_files(self, widget = None, eve = None):
|
||||||
|
self._event_system.emit("do_hide_context_menu")
|
||||||
self._event_system.emit("get_current_state")
|
self._event_system.emit("get_current_state")
|
||||||
state = self._fm_state
|
state = self._fm_state
|
||||||
uris = state.selected_files
|
uris = state.selected_files
|
||||||
|
@ -97,19 +101,23 @@ class Plugin(PluginBase):
|
||||||
break
|
break
|
||||||
|
|
||||||
def trash_files(self, widget = None, eve = None, verbocity = False):
|
def trash_files(self, widget = None, eve = None, verbocity = False):
|
||||||
|
self._event_system.emit("do_hide_context_menu")
|
||||||
self._event_system.emit("get_current_state")
|
self._event_system.emit("get_current_state")
|
||||||
state = self._fm_state
|
state = self._fm_state
|
||||||
for uri in state.selected_files:
|
for uri in state.selected_files:
|
||||||
self.trashman.trash(uri, verbocity)
|
self.trashman.trash(uri, verbocity)
|
||||||
|
|
||||||
def restore_trash_files(self, widget = None, eve = None, verbocity = False):
|
def restore_trash_files(self, widget = None, eve = None, verbocity = False):
|
||||||
|
self._event_system.emit("do_hide_context_menu")
|
||||||
self._event_system.emit("get_current_state")
|
self._event_system.emit("get_current_state")
|
||||||
state = self._fm_state
|
state = self._fm_state
|
||||||
for uri in state.selected_files:
|
for uri in state.selected_files:
|
||||||
self.trashman.restore(filename=uri.split("/")[-1], verbose = verbocity)
|
self.trashman.restore(filename=uri.split("/")[-1], verbose = verbocity)
|
||||||
|
|
||||||
def empty_trash(self, widget = None, eve = None, verbocity = False):
|
def empty_trash(self, widget = None, eve = None, verbocity = False):
|
||||||
|
self._event_system.emit("do_hide_context_menu")
|
||||||
self.trashman.empty(verbose = verbocity)
|
self.trashman.empty(verbose = verbocity)
|
||||||
|
|
||||||
def go_to_trash(self, widget = None, eve = None, verbocity = False):
|
def go_to_trash(self, widget = None, eve = None, verbocity = False):
|
||||||
|
self._event_system.emit("do_hide_context_menu")
|
||||||
self._event_system.emit("go_to_path", self.trash_files_path)
|
self._event_system.emit("go_to_path", self.trash_files_path)
|
||||||
|
|
|
@ -44,11 +44,6 @@ class Plugin(PluginBase):
|
||||||
self._file_hash = None
|
self._file_hash = None
|
||||||
|
|
||||||
|
|
||||||
def get_ui_element(self):
|
|
||||||
button = Gtk.Button(label=self.name)
|
|
||||||
button.connect("button-release-event", self._show_thumbnailer_page)
|
|
||||||
return button
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self._builder = Gtk.Builder()
|
self._builder = Gtk.Builder()
|
||||||
self._builder.add_from_file(self._GLADE_FILE)
|
self._builder.add_from_file(self._GLADE_FILE)
|
||||||
|
@ -72,10 +67,15 @@ class Plugin(PluginBase):
|
||||||
self._thumbnail_preview_img = self._builder.get_object("thumbnail_preview_img")
|
self._thumbnail_preview_img = self._builder.get_object("thumbnail_preview_img")
|
||||||
self._file_hash = self._builder.get_object("file_hash")
|
self._file_hash = self._builder.get_object("file_hash")
|
||||||
|
|
||||||
|
def generate_reference_ui_element(self):
|
||||||
|
button = Gtk.Button(label=self.name)
|
||||||
|
button.connect("button-release-event", self._show_thumbnailer_page)
|
||||||
|
return button
|
||||||
|
|
||||||
|
|
||||||
@threaded
|
@threaded
|
||||||
def _show_thumbnailer_page(self, widget=None, eve=None):
|
def _show_thumbnailer_page(self, widget=None, eve=None):
|
||||||
self._event_system.emit("get_current_state
|
self._event_system.emit("get_current_state")
|
||||||
|
|
||||||
state = self._fm_state
|
state = self._fm_state
|
||||||
self._event_message = None
|
self._event_message = None
|
||||||
|
|
|
@ -33,8 +33,7 @@ class Plugin(PluginBase):
|
||||||
self.name = "Youtube Download" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus
|
self.name = "Youtube Download" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus
|
||||||
# where self.name should not be needed for message comms
|
# where self.name should not be needed for message comms
|
||||||
|
|
||||||
|
def generate_reference_ui_element(self):
|
||||||
def get_ui_element(self):
|
|
||||||
button = Gtk.Button(label=self.name)
|
button = Gtk.Button(label=self.name)
|
||||||
button.connect("button-release-event", self._do_download)
|
button.connect("button-release-event", self._do_download)
|
||||||
return button
|
return button
|
||||||
|
@ -44,7 +43,7 @@ class Plugin(PluginBase):
|
||||||
|
|
||||||
|
|
||||||
def _do_download(self, widget=None, eve=None):
|
def _do_download(self, widget=None, eve=None):
|
||||||
self._event_system.emit("get_current_state
|
self._event_system.emit("get_current_state")
|
||||||
|
|
||||||
dir = self._fm_state.tab.get_current_directory()
|
dir = self._fm_state.tab.get_current_directory()
|
||||||
self._download(dir)
|
self._download(dir)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import builtins, threading
|
||||||
# Application imports
|
# Application imports
|
||||||
from utils.event_system import EventSystem
|
from utils.event_system import EventSystem
|
||||||
from utils.endpoint_registry import EndpointRegistry
|
from utils.endpoint_registry import EndpointRegistry
|
||||||
|
from utils.settings import Settings
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,11 +28,11 @@ def daemon_threaded_wrapper(fn):
|
||||||
# NOTE: Just reminding myself we can add to builtins two different ways...
|
# NOTE: Just reminding myself we can add to builtins two different ways...
|
||||||
# __builtins__.update({"event_system": Builtins()})
|
# __builtins__.update({"event_system": Builtins()})
|
||||||
builtins.app_name = "SolarFM"
|
builtins.app_name = "SolarFM"
|
||||||
|
builtins.settings = Settings()
|
||||||
|
builtins.logger = settings.get_logger()
|
||||||
builtins.event_system = EventSystem()
|
builtins.event_system = EventSystem()
|
||||||
builtins.endpoint_registry = EndpointRegistry()
|
builtins.endpoint_registry = EndpointRegistry()
|
||||||
|
|
||||||
builtins.threaded = threaded_wrapper
|
builtins.threaded = threaded_wrapper
|
||||||
builtins.daemon_threaded = daemon_threaded_wrapper
|
builtins.daemon_threaded = daemon_threaded_wrapper
|
||||||
builtins.event_sleep_time = 0.05
|
builtins.event_sleep_time = 0.05
|
||||||
builtins.trace_debug = False
|
|
||||||
builtins.debug = False
|
|
||||||
builtins.app_settings = None
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ gi.require_version('Gtk', '3.0')
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
|
from __builtins__ import *
|
||||||
from app import Application
|
from app import Application
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +28,9 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
# Add long and short arguments
|
# Add long and short arguments
|
||||||
|
parser.add_argument("--debug", "-d", default="false", help="Do extra console messaging.")
|
||||||
|
parser.add_argument("--trace-debug", "-td", default="false", help="Disable saves, ignore IPC lock, do extra console messaging.")
|
||||||
|
|
||||||
parser.add_argument("--new-tab", "-t", default="", help="Open a file into new tab.")
|
parser.add_argument("--new-tab", "-t", default="", help="Open a file into new tab.")
|
||||||
parser.add_argument("--new-window", "-w", default="", help="Open a file into a new window.")
|
parser.add_argument("--new-window", "-w", default="", help="Open a file into a new window.")
|
||||||
# Read arguments (If any...)
|
# Read arguments (If any...)
|
||||||
|
|
|
@ -4,7 +4,7 @@ import os, inspect, time
|
||||||
# Lib imports
|
# Lib imports
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from __builtins__ import *
|
|
||||||
from utils.ipc_server import IPCServer
|
from utils.ipc_server import IPCServer
|
||||||
from utils.settings import Settings
|
from utils.settings import Settings
|
||||||
from core.controller import Controller
|
from core.controller import Controller
|
||||||
|
@ -22,8 +22,14 @@ class Application(IPCServer):
|
||||||
|
|
||||||
def __init__(self, args, unknownargs):
|
def __init__(self, args, unknownargs):
|
||||||
super(Application, self).__init__()
|
super(Application, self).__init__()
|
||||||
|
if args.debug == "true":
|
||||||
|
settings.set_debug(True)
|
||||||
|
|
||||||
if not trace_debug:
|
if args.trace_debug == "true":
|
||||||
|
settings.set_trace_debug(True)
|
||||||
|
|
||||||
|
# NOTE: Instance found, sending files to it...
|
||||||
|
if not settings.is_trace_debug():
|
||||||
self.create_ipc_listener()
|
self.create_ipc_listener()
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
@ -41,10 +47,9 @@ class Application(IPCServer):
|
||||||
raise AppLaunchException(f"IPC Server Exists: Will send path(s) to it and close...\nNote: If no fm exists, remove /tmp/{app_name}-ipc.sock")
|
raise AppLaunchException(f"IPC Server Exists: Will send path(s) to it and close...\nNote: If no fm exists, remove /tmp/{app_name}-ipc.sock")
|
||||||
|
|
||||||
|
|
||||||
settings = Settings()
|
|
||||||
settings.create_window()
|
settings.create_window()
|
||||||
|
|
||||||
controller = Controller(args, unknownargs, settings)
|
controller = Controller(args, unknownargs)
|
||||||
if not controller:
|
if not controller:
|
||||||
raise ControllerStartExceptio("Controller exited and doesn't exist...")
|
raise ControllerStartExceptio("Controller exited and doesn't exist...")
|
||||||
|
|
||||||
|
|
|
@ -18,18 +18,18 @@ from .controller_data import Controller_Data
|
||||||
|
|
||||||
class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMixin, Controller_Data):
|
class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMixin, Controller_Data):
|
||||||
""" Controller coordinates the mixins and is somewhat the root hub of it all. """
|
""" Controller coordinates the mixins and is somewhat the root hub of it all. """
|
||||||
def __init__(self, args, unknownargs, _settings):
|
def __init__(self, args, unknownargs):
|
||||||
self.setup_controller_data(_settings)
|
self.setup_controller_data()
|
||||||
self.window.show()
|
self.window.show()
|
||||||
|
|
||||||
self.generate_windows(self.fm_controller_data)
|
self.generate_windows(self.fm_controller_data)
|
||||||
self.plugins.launch_plugins()
|
self.plugins.launch_plugins()
|
||||||
|
|
||||||
if debug:
|
if settings.is_debug():
|
||||||
self.window.set_interactive_debugging(True)
|
self.window.set_interactive_debugging(True)
|
||||||
|
|
||||||
|
# NOTE: Open files if passed in from cli and not trace debugging...
|
||||||
if not trace_debug:
|
if not settings.is_trace_debug():
|
||||||
self._subscribe_to_events()
|
self._subscribe_to_events()
|
||||||
|
|
||||||
if unknownargs:
|
if unknownargs:
|
||||||
|
@ -51,7 +51,9 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMi
|
||||||
event_system.subscribe("do_hide_context_menu", self.do_hide_context_menu)
|
event_system.subscribe("do_hide_context_menu", self.do_hide_context_menu)
|
||||||
|
|
||||||
def tear_down(self, widget=None, eve=None):
|
def tear_down(self, widget=None, eve=None):
|
||||||
|
if not settings.is_trace_debug():
|
||||||
self.fm_controller.save_state()
|
self.fm_controller.save_state()
|
||||||
|
|
||||||
time.sleep(event_sleep_time)
|
time.sleep(event_sleep_time)
|
||||||
Gtk.main_quit()
|
Gtk.main_quit()
|
||||||
|
|
||||||
|
@ -62,7 +64,9 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMi
|
||||||
save_load_dialog = self.builder.get_object("save_load_dialog")
|
save_load_dialog = self.builder.get_object("save_load_dialog")
|
||||||
|
|
||||||
if action == "save_session":
|
if action == "save_session":
|
||||||
|
if not settings.is_trace_debug():
|
||||||
self.fm_controller.save_state()
|
self.fm_controller.save_state()
|
||||||
|
|
||||||
return
|
return
|
||||||
elif action == "save_session_as":
|
elif action == "save_session_as":
|
||||||
save_load_dialog.set_action(Gtk.FileChooserAction.SAVE)
|
save_load_dialog.set_action(Gtk.FileChooserAction.SAVE)
|
||||||
|
@ -88,8 +92,8 @@ class Controller(UIMixin, KeyboardSignalsMixin, IPCSignalsMixin, ExceptionHookMi
|
||||||
save_load_dialog.hide()
|
save_load_dialog.hide()
|
||||||
|
|
||||||
def load_session(self, session_json):
|
def load_session(self, session_json):
|
||||||
if debug:
|
if settings.is_debug():
|
||||||
self.logger.debug(f"Session Data: {session_json}")
|
logger.debug(f"Session Data: {session_json}")
|
||||||
|
|
||||||
self.ctrl_down = False
|
self.ctrl_down = False
|
||||||
self.shift_down = False
|
self.shift_down = False
|
||||||
|
|
|
@ -28,17 +28,15 @@ class Controller_Data:
|
||||||
""" Controller_Data contains most of the state of the app at ay given time. It also has some support methods. """
|
""" Controller_Data contains most of the state of the app at ay given time. It also has some support methods. """
|
||||||
__slots__ = "settings", "builder", "logger", "keybindings", "trashman", "fm_controller", "window", "window1", "window2", "window3", "window4"
|
__slots__ = "settings", "builder", "logger", "keybindings", "trashman", "fm_controller", "window", "window1", "window2", "window3", "window4"
|
||||||
|
|
||||||
def setup_controller_data(self, _settings: type) -> None:
|
def setup_controller_data(self) -> None:
|
||||||
self.settings = _settings
|
self.builder = settings.get_builder()
|
||||||
self.builder = self.settings.get_builder()
|
self.keybindings = settings.get_keybindings()
|
||||||
self.logger = self.settings.get_logger()
|
|
||||||
self.keybindings = self.settings.get_keybindings()
|
|
||||||
|
|
||||||
self.fm_controller = WindowController()
|
self.fm_controller = WindowController()
|
||||||
self.plugins = PluginsController(_settings)
|
self.plugins = PluginsController()
|
||||||
self.fm_controller_data = self.fm_controller.get_state_from_file()
|
self.fm_controller_data = self.fm_controller.get_state_from_file()
|
||||||
|
|
||||||
self.window = self.settings.get_main_window()
|
self.window = settings.get_main_window()
|
||||||
self.window1 = self.builder.get_object("window_1")
|
self.window1 = self.builder.get_object("window_1")
|
||||||
self.window2 = self.builder.get_object("window_2")
|
self.window2 = self.builder.get_object("window_2")
|
||||||
self.window3 = self.builder.get_object("window_3")
|
self.window3 = self.builder.get_object("window_3")
|
||||||
|
@ -64,7 +62,7 @@ class Controller_Data:
|
||||||
|
|
||||||
self.trash_files_path = f"{GLib.get_user_data_dir()}/Trash/files"
|
self.trash_files_path = f"{GLib.get_user_data_dir()}/Trash/files"
|
||||||
self.trash_info_path = f"{GLib.get_user_data_dir()}/Trash/info"
|
self.trash_info_path = f"{GLib.get_user_data_dir()}/Trash/info"
|
||||||
self.icon_theme = self.settings.get_icon_theme()
|
self.icon_theme = settings.get_icon_theme()
|
||||||
|
|
||||||
# In compress commands:
|
# In compress commands:
|
||||||
# %n: First selected filename/dir to archive
|
# %n: First selected filename/dir to archive
|
||||||
|
@ -116,9 +114,9 @@ class Controller_Data:
|
||||||
self.shift_down = False
|
self.shift_down = False
|
||||||
self.alt_down = False
|
self.alt_down = False
|
||||||
|
|
||||||
self.success_color = self.settings.get_success_color()
|
self.success_color = settings.get_success_color()
|
||||||
self.warning_color = self.settings.get_warning_color()
|
self.warning_color = settings.get_warning_color()
|
||||||
self.error_color = self.settings.get_error_color()
|
self.error_color = settings.get_error_color()
|
||||||
|
|
||||||
# sys.excepthook = self.custom_except_hook
|
# sys.excepthook = self.custom_except_hook
|
||||||
self.window.connect("delete-event", self.tear_down)
|
self.window.connect("delete-event", self.tear_down)
|
||||||
|
|
|
@ -61,7 +61,7 @@ class GridMixin:
|
||||||
self.create_icon(i, tab, store, dir, file[0])
|
self.create_icon(i, tab, store, dir, file[0])
|
||||||
|
|
||||||
# NOTE: Not likely called often from here but it could be useful
|
# NOTE: Not likely called often from here but it could be useful
|
||||||
if save_state:
|
if save_state and not trace_debug:
|
||||||
self.fm_controller.save_state()
|
self.fm_controller.save_state()
|
||||||
|
|
||||||
@threaded
|
@threaded
|
||||||
|
|
|
@ -56,4 +56,5 @@ class PaneMixin:
|
||||||
def _save_state(self, state, pane_index):
|
def _save_state(self, state, pane_index):
|
||||||
window = self.fm_controller.get_window_by_index(pane_index - 1)
|
window = self.fm_controller.get_window_by_index(pane_index - 1)
|
||||||
window.set_is_hidden(state)
|
window.set_is_hidden(state)
|
||||||
|
if not settings.is_trace_debug():
|
||||||
self.fm_controller.save_state()
|
self.fm_controller.save_state()
|
||||||
|
|
|
@ -22,7 +22,7 @@ class TabMixin(GridMixin):
|
||||||
notebook = self.builder.get_object(f"window_{wid}")
|
notebook = self.builder.get_object(f"window_{wid}")
|
||||||
path_entry = self.builder.get_object(f"path_entry")
|
path_entry = self.builder.get_object(f"path_entry")
|
||||||
tab = self.fm_controller.add_tab_for_window_by_nickname(f"window_{wid}")
|
tab = self.fm_controller.add_tab_for_window_by_nickname(f"window_{wid}")
|
||||||
tab.logger = self.logger
|
tab.logger = logger
|
||||||
|
|
||||||
tab.set_wid(wid)
|
tab.set_wid(wid)
|
||||||
if not path:
|
if not path:
|
||||||
|
@ -63,6 +63,7 @@ class TabMixin(GridMixin):
|
||||||
watcher.cancel()
|
watcher.cancel()
|
||||||
self.get_fm_window(wid).delete_tab_by_id(tid)
|
self.get_fm_window(wid).delete_tab_by_id(tid)
|
||||||
notebook.remove_page(page)
|
notebook.remove_page(page)
|
||||||
|
if not settings.is_trace_debug():
|
||||||
self.fm_controller.save_state()
|
self.fm_controller.save_state()
|
||||||
self.set_window_title()
|
self.set_window_title()
|
||||||
|
|
||||||
|
@ -80,6 +81,7 @@ class TabMixin(GridMixin):
|
||||||
|
|
||||||
tab = window.get_tab_by_id(tid)
|
tab = window.get_tab_by_id(tid)
|
||||||
self.set_file_watcher(tab)
|
self.set_file_watcher(tab)
|
||||||
|
if not settings.is_trace_debug():
|
||||||
self.fm_controller.save_state()
|
self.fm_controller.save_state()
|
||||||
|
|
||||||
def on_tab_switch_update(self, notebook, content=None, index=None):
|
def on_tab_switch_update(self, notebook, content=None, index=None):
|
||||||
|
@ -115,6 +117,7 @@ class TabMixin(GridMixin):
|
||||||
tab_label.set_label(tab.get_end_of_path())
|
tab_label.set_label(tab.get_end_of_path())
|
||||||
self.set_window_title()
|
self.set_window_title()
|
||||||
self.set_file_watcher(tab)
|
self.set_file_watcher(tab)
|
||||||
|
if not settings.is_trace_debug():
|
||||||
self.fm_controller.save_state()
|
self.fm_controller.save_state()
|
||||||
|
|
||||||
def do_action_from_bar_controls(self, widget, eve=None):
|
def do_action_from_bar_controls(self, widget, eve=None):
|
||||||
|
@ -127,7 +130,9 @@ class TabMixin(GridMixin):
|
||||||
if action == "create_tab":
|
if action == "create_tab":
|
||||||
dir = tab.get_current_directory()
|
dir = tab.get_current_directory()
|
||||||
self.create_tab(wid, None, dir)
|
self.create_tab(wid, None, dir)
|
||||||
|
if not settings.is_trace_debug():
|
||||||
self.fm_controller.save_state()
|
self.fm_controller.save_state()
|
||||||
|
|
||||||
return
|
return
|
||||||
if action == "go_up":
|
if action == "go_up":
|
||||||
tab.pop_from_path()
|
tab.pop_from_path()
|
||||||
|
|
|
@ -40,8 +40,8 @@ class WidgetFileActionMixin:
|
||||||
if tab.get_dir_watcher():
|
if tab.get_dir_watcher():
|
||||||
watcher = tab.get_dir_watcher()
|
watcher = tab.get_dir_watcher()
|
||||||
watcher.cancel()
|
watcher.cancel()
|
||||||
if debug:
|
if settings.is_debug():
|
||||||
self.logger.debug(f"Watcher Is Cancelled: {watcher.is_cancelled()}")
|
logger.debug(f"Watcher Is Cancelled: {watcher.is_cancelled()}")
|
||||||
|
|
||||||
cur_dir = tab.get_current_directory()
|
cur_dir = tab.get_current_directory()
|
||||||
|
|
||||||
|
@ -59,8 +59,8 @@ class WidgetFileActionMixin:
|
||||||
if eve_type in [Gio.FileMonitorEvent.CREATED, Gio.FileMonitorEvent.DELETED,
|
if eve_type in [Gio.FileMonitorEvent.CREATED, Gio.FileMonitorEvent.DELETED,
|
||||||
Gio.FileMonitorEvent.RENAMED, Gio.FileMonitorEvent.MOVED_IN,
|
Gio.FileMonitorEvent.RENAMED, Gio.FileMonitorEvent.MOVED_IN,
|
||||||
Gio.FileMonitorEvent.MOVED_OUT]:
|
Gio.FileMonitorEvent.MOVED_OUT]:
|
||||||
if debug:
|
if settings.is_debug():
|
||||||
self.logger.debug(eve_type)
|
logger.debug(eve_type)
|
||||||
|
|
||||||
if eve_type in [Gio.FileMonitorEvent.MOVED_IN, Gio.FileMonitorEvent.MOVED_OUT]:
|
if eve_type in [Gio.FileMonitorEvent.MOVED_IN, Gio.FileMonitorEvent.MOVED_OUT]:
|
||||||
self.update_on_soft_lock_end(data[0])
|
self.update_on_soft_lock_end(data[0])
|
||||||
|
@ -389,11 +389,11 @@ class WidgetFileActionMixin:
|
||||||
target = Gio.File.new_for_path(full_path)
|
target = Gio.File.new_for_path(full_path)
|
||||||
start = "-copy"
|
start = "-copy"
|
||||||
|
|
||||||
if debug:
|
if settings.is_debug():
|
||||||
self.logger.debug(f"Path: {full_path}")
|
logger.debug(f"Path: {full_path}")
|
||||||
self.logger.debug(f"Base Path: {base_path}")
|
logger.debug(f"Base Path: {base_path}")
|
||||||
self.logger.debug(f'Name: {file_name}')
|
logger.debug(f'Name: {file_name}')
|
||||||
self.logger.debug(f"Extension: {extension}")
|
logger.debug(f"Extension: {extension}")
|
||||||
|
|
||||||
i = 2
|
i = 2
|
||||||
while target.query_exists():
|
while target.query_exists():
|
||||||
|
|
|
@ -24,8 +24,8 @@ class WindowMixin(TabMixin):
|
||||||
for j, value in enumerate(session_json):
|
for j, value in enumerate(session_json):
|
||||||
i = j + 1
|
i = j + 1
|
||||||
notebook_tggl_button = self.builder.get_object(f"tggl_notebook_{i}")
|
notebook_tggl_button = self.builder.get_object(f"tggl_notebook_{i}")
|
||||||
is_hidden = True if value[0]["window"]["isHidden"] == "True" else False
|
is_hidden = True if value["window"]["isHidden"] == "True" else False
|
||||||
tabs = value[0]["window"]["tabs"]
|
tabs = value["window"]["tabs"]
|
||||||
self.fm_controller.create_window()
|
self.fm_controller.create_window()
|
||||||
notebook_tggl_button.set_active(True)
|
notebook_tggl_button.set_active(True)
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ class WindowMixin(TabMixin):
|
||||||
file_size = file_info.get_size()
|
file_size = file_info.get_size()
|
||||||
combined_size += file_size
|
combined_size += file_size
|
||||||
except WindowException as e:
|
except WindowException as e:
|
||||||
if debug:
|
if settings.is_debug():
|
||||||
print(repr(e))
|
print(repr(e))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ class KeyboardSignalsMixin:
|
||||||
sender, eve_type = mapping.split("||")
|
sender, eve_type = mapping.split("||")
|
||||||
self.handle_plugin_key_event(sender, eve_type)
|
self.handle_plugin_key_event(sender, eve_type)
|
||||||
else:
|
else:
|
||||||
if debug:
|
if settings.is_debug():
|
||||||
print(f"on_global_key_release_controller > key > {keyname}")
|
print(f"on_global_key_release_controller > key > {keyname}")
|
||||||
|
|
||||||
if self.ctrl_down:
|
if self.ctrl_down:
|
||||||
|
@ -91,5 +91,6 @@ class KeyboardSignalsMixin:
|
||||||
|
|
||||||
self.get_fm_window(wid).delete_tab_by_id(tid)
|
self.get_fm_window(wid).delete_tab_by_id(tid)
|
||||||
notebook.remove_page(page)
|
notebook.remove_page(page)
|
||||||
|
if not trace_debug:
|
||||||
self.fm_controller.save_state()
|
self.fm_controller.save_state()
|
||||||
self.set_window_title()
|
self.set_window_title()
|
||||||
|
|
|
@ -6,6 +6,10 @@ import os, time
|
||||||
# Application imports
|
# Application imports
|
||||||
|
|
||||||
|
|
||||||
|
class PluginBaseException(Exception):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
class PluginBase:
|
class PluginBase:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.name = "Example Plugin" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus
|
self.name = "Example Plugin" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus
|
||||||
|
@ -18,14 +22,23 @@ class PluginBase:
|
||||||
|
|
||||||
|
|
||||||
def set_fm_event_system(self, fm_event_system):
|
def set_fm_event_system(self, fm_event_system):
|
||||||
|
"""
|
||||||
|
Requests Key: 'pass_fm_events': "true"
|
||||||
|
Must define in plugin if "pass_fm_events" is set to "true" string.
|
||||||
|
"""
|
||||||
self._event_system = fm_event_system
|
self._event_system = fm_event_system
|
||||||
|
|
||||||
def set_ui_object_collection(self, ui_objects):
|
def set_ui_object_collection(self, ui_objects):
|
||||||
|
"""
|
||||||
|
Requests Key: "pass_ui_objects": [""]
|
||||||
|
Request reference to a UI component. Will be passed back as array to plugin.
|
||||||
|
Must define in plugin if set and an array of valid glade UI IDs is given.
|
||||||
|
"""
|
||||||
self._ui_objects = ui_objects
|
self._ui_objects = ui_objects
|
||||||
|
|
||||||
|
|
||||||
def clear_children(self, widget: type) -> None:
|
def clear_children(self, widget: type) -> None:
|
||||||
''' Clear children of a gtk widget. '''
|
""" Clear children of a gtk widget. """
|
||||||
for child in widget.get_children():
|
for child in widget.get_children():
|
||||||
widget.remove(child)
|
widget.remove(child)
|
||||||
|
|
||||||
|
@ -34,3 +47,18 @@ class PluginBase:
|
||||||
|
|
||||||
def _update_fm_state_info(self, state):
|
def _update_fm_state_info(self, state):
|
||||||
self._fm_state = state
|
self._fm_state = state
|
||||||
|
|
||||||
|
def generate_reference_ui_element(self):
|
||||||
|
"""
|
||||||
|
Requests Key: 'ui_target': "plugin_control_list",
|
||||||
|
Must define regardless if needed and can 'pass' if plugin doesn't use it.
|
||||||
|
Must return a widget if "ui_target" is set.
|
||||||
|
"""
|
||||||
|
raise PluginBaseException("Method hasn't been overriden...")
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
"""
|
||||||
|
Must define regardless if needed and can 'pass' if plugin doesn't need it.
|
||||||
|
Is intended to be used to setup internal signals or custom Gtk Builders/UI logic.
|
||||||
|
"""
|
||||||
|
raise PluginBaseException("Method hasn't been overriden...")
|
||||||
|
|
|
@ -20,14 +20,13 @@ class InvalidPluginException(Exception):
|
||||||
class PluginsController:
|
class PluginsController:
|
||||||
"""PluginsController controller"""
|
"""PluginsController controller"""
|
||||||
|
|
||||||
def __init__(self, settings: type):
|
def __init__(self):
|
||||||
path = os.path.dirname(os.path.realpath(__file__))
|
path = os.path.dirname(os.path.realpath(__file__))
|
||||||
sys.path.insert(0, path) # NOTE: I think I'm not using this correctly...
|
sys.path.insert(0, path) # NOTE: I think I'm not using this correctly...
|
||||||
|
|
||||||
self._settings = settings
|
self._builder = settings.get_builder()
|
||||||
self._builder = self._settings.get_builder()
|
self._plugins_path = settings.get_plugins_path()
|
||||||
self._plugins_path = self._settings.get_plugins_path()
|
self._keybindings = settings.get_keybindings()
|
||||||
self._keybindings = self._settings.get_keybindings()
|
|
||||||
|
|
||||||
self._plugins_dir_watcher = None
|
self._plugins_dir_watcher = None
|
||||||
self._plugin_collection = []
|
self._plugin_collection = []
|
||||||
|
@ -95,7 +94,7 @@ class PluginsController:
|
||||||
keys = loading_data.keys()
|
keys = loading_data.keys()
|
||||||
|
|
||||||
if "ui_target" in keys:
|
if "ui_target" in keys:
|
||||||
loading_data["ui_target"].add( plugin.reference.get_ui_element() )
|
loading_data["ui_target"].add( plugin.reference.generate_reference_ui_element() )
|
||||||
loading_data["ui_target"].show_all()
|
loading_data["ui_target"].show_all()
|
||||||
|
|
||||||
if "pass_ui_objects" in keys:
|
if "pass_ui_objects" in keys:
|
||||||
|
|
|
@ -158,7 +158,6 @@ class WindowController:
|
||||||
tabs.append(tab.get_current_directory())
|
tabs.append(tab.get_current_directory())
|
||||||
|
|
||||||
windows.append(
|
windows.append(
|
||||||
[
|
|
||||||
{
|
{
|
||||||
'window':{
|
'window':{
|
||||||
"ID": window.get_id(),
|
"ID": window.get_id(),
|
||||||
|
@ -168,7 +167,6 @@ class WindowController:
|
||||||
'tabs': tabs
|
'tabs': tabs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
with open(session_file, 'w') as outfile:
|
with open(session_file, 'w') as outfile:
|
||||||
|
|
|
@ -322,10 +322,8 @@ def getIconPath(iconname, size = None, theme = None, extensions = ["png", "svg",
|
||||||
icon_cache[tmp] = [time.time(), icon]
|
icon_cache[tmp] = [time.time(), icon]
|
||||||
return icon
|
return icon
|
||||||
except UnicodeDecodeError as e:
|
except UnicodeDecodeError as e:
|
||||||
if debug:
|
...
|
||||||
raise e
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# we haven't found anything? "hicolor" is our fallback
|
# we haven't found anything? "hicolor" is our fallback
|
||||||
if theme != "hicolor":
|
if theme != "hicolor":
|
||||||
|
|
|
@ -59,7 +59,7 @@ class IPCServer:
|
||||||
def handle_message(self, conn, start_time) -> None:
|
def handle_message(self, conn, start_time) -> None:
|
||||||
while True:
|
while True:
|
||||||
msg = conn.recv()
|
msg = conn.recv()
|
||||||
if debug:
|
if settings.is_debug():
|
||||||
print(msg)
|
print(msg)
|
||||||
|
|
||||||
if "FILE|" in msg:
|
if "FILE|" in msg:
|
||||||
|
|
|
@ -63,6 +63,9 @@ class Settings:
|
||||||
self._builder = Gtk.Builder()
|
self._builder = Gtk.Builder()
|
||||||
self._builder.add_from_file(self._GLADE_FILE)
|
self._builder.add_from_file(self._GLADE_FILE)
|
||||||
|
|
||||||
|
self._trace_debug = False
|
||||||
|
self._debug = False
|
||||||
|
|
||||||
|
|
||||||
def create_window(self) -> None:
|
def create_window(self) -> None:
|
||||||
# Get window and connect signals
|
# Get window and connect signals
|
||||||
|
@ -111,3 +114,13 @@ class Settings:
|
||||||
def get_success_color(self) -> str: return self._success_color
|
def get_success_color(self) -> str: return self._success_color
|
||||||
def get_warning_color(self) -> str: return self._warning_color
|
def get_warning_color(self) -> str: return self._warning_color
|
||||||
def get_error_color(self) -> str: return self._error_color
|
def get_error_color(self) -> str: return self._error_color
|
||||||
|
|
||||||
|
def is_trace_debug(self) -> str: return self._trace_debug
|
||||||
|
def is_debug(self) -> str: return self._debug
|
||||||
|
|
||||||
|
|
||||||
|
def set_trace_debug(self, trace_debug):
|
||||||
|
self._trace_debug = trace_debug
|
||||||
|
|
||||||
|
def set_debug(self, debug):
|
||||||
|
self._debug = debug
|
||||||
|
|
Loading…
Reference in New Issue