develop #11

Merged
itdominator merged 36 commits from develop into master 2023-09-19 01:11:24 +00:00
40 changed files with 355 additions and 914 deletions
Showing only changes of commit 3c72ad2801 - Show all commits

View File

@ -64,6 +64,8 @@ class FileSearchMixin:
break break
def _stop_fsearch_query(self, widget=None, eve=None): def _stop_fsearch_query(self, widget=None, eve=None):
self._spinner.stop()
# NOTE: Freeze IPC consumption # NOTE: Freeze IPC consumption
self.pause_fifo_update = True self.pause_fifo_update = True
self.search_query = "" self.search_query = ""
@ -86,10 +88,10 @@ class FileSearchMixin:
self.search_query = query self.search_query = query
target_dir = shlex.quote( self._fm_state.tab.get_current_directory() ) target_dir = shlex.quote( self._fm_state.tab.get_current_directory() )
command = ["python", f"{self.path}/utils/search.py", "-t", "file_search", "-d", f"{target_dir}", "-q", f"{query}"] command = ["python", f"{self.path}/utils/search.py", "-t", "file_search", "-d", f"{target_dir}", "-q", f"{query}"]
self._spinner.start()
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() Gtk.main_iteration()

View File

@ -64,6 +64,8 @@ class GrepSearchMixin:
break break
def _stop_grep_query(self, widget=None, eve=None): def _stop_grep_query(self, widget=None, eve=None):
self._spinner.stop()
# NOTE: Freeze IPC consumption # NOTE: Freeze IPC consumption
self.pause_fifo_update = True self.pause_fifo_update = True
self.grep_query = "" self.grep_query = ""
@ -88,6 +90,7 @@ class GrepSearchMixin:
target_dir = shlex.quote( self._fm_state.tab.get_current_directory() ) target_dir = shlex.quote( self._fm_state.tab.get_current_directory() )
command = ["python", f"{self.path}/utils/search.py", "-t", "grep_search", "-d", f"{target_dir}", "-q", f"{query}"] command = ["python", f"{self.path}/utils/search.py", "-t", "grep_search", "-d", f"{target_dir}", "-q", f"{query}"]
self._spinner.start()
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):

View File

@ -28,6 +28,7 @@ class Plugin(IPCServer, FileSearchMixin, GrepSearchMixin, PluginBase):
self.update_list_ui_buffer = () self.update_list_ui_buffer = ()
self._search_dialog = None self._search_dialog = None
self._spinner = None
self._active_path = None self._active_path = None
self.file_list_parent = None self.file_list_parent = None
self.grep_list_parent = None self.grep_list_parent = None
@ -55,6 +56,7 @@ class Plugin(IPCServer, FileSearchMixin, GrepSearchMixin, PluginBase):
self._search_dialog = self._builder.get_object("search_dialog") self._search_dialog = self._builder.get_object("search_dialog")
self.fsearch = self._builder.get_object("fsearch") self.fsearch = self._builder.get_object("fsearch")
self._spinner = self._builder.get_object("spinner")
self.grep_list_parent = self._builder.get_object("grep_list_parent") self.grep_list_parent = self._builder.get_object("grep_list_parent")
self.file_list_parent = self._builder.get_object("file_list_parent") self.file_list_parent = self._builder.get_object("file_list_parent")
@ -72,6 +74,10 @@ class Plugin(IPCServer, FileSearchMixin, GrepSearchMixin, PluginBase):
item.set_always_show_image(True) item.set_always_show_image(True)
return item return item
def stop_spinner(self, ret_code):
print(f"Return Code: {ret_code}")
self._spinner.stop()
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")

View File

@ -25,6 +25,17 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="layout-style">end</property> <property name="layout-style">end</property>
<child>
<object class="GtkSpinner" id="spinner">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child> <child>
<object class="GtkButton" id="cancel_button"> <object class="GtkButton" id="cancel_button">
<property name="label">gtk-cancel</property> <property name="label">gtk-cancel</property>
@ -37,7 +48,7 @@
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">0</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -52,7 +63,7 @@
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</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>
</object> </object>
@ -260,6 +271,12 @@
<child type="tab"> <child type="tab">
<placeholder/> <placeholder/>
</child> </child>
<child>
<placeholder/>
</child>
<child type="tab">
<placeholder/>
</child>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>

View File

@ -59,23 +59,27 @@ class IPCServer:
while True: while True:
msg = conn.recv() msg = conn.recv()
try:
if "SEARCH_DONE|" in msg:
ts, ret_code = msg.split("SEARCH_DONE|")[1].strip().split("|", 1)
timestamp = float(ts)
if self.fsearch_time_stamp or self.grep_time_stamp:
if (timestamp > self.fsearch_time_stamp) or (timestamp > self.grep_time_stamp):
GLib.idle_add(self.stop_spinner, (ret_code,), priority=GLib.PRIORITY_HIGH_IDLE)
if "SEARCH|" in msg: if "SEARCH|" in msg:
ts, file = msg.split("SEARCH|")[1].strip().split("|", 1) ts, file = msg.split("SEARCH|")[1].strip().split("|", 1)
try:
timestamp = float(ts) timestamp = float(ts)
if timestamp > self.fsearch_time_stamp and file: if file and (timestamp > self.fsearch_time_stamp):
GLib.idle_add(self._load_file_ui, file, priority=GLib.PRIORITY_LOW) GLib.idle_add(self._load_file_ui, file, priority=GLib.PRIORITY_HIGH_IDLE)
except Exception as e:
...
if "GREP|" in msg: if "GREP|" in msg:
ts, data = msg.split("GREP|")[1].strip().split("|", 1) ts, data = msg.split("GREP|")[1].strip().split("|", 1)
try:
timestamp = float(ts) timestamp = float(ts)
if timestamp > self.grep_time_stamp and data: if data and (timestamp > self.grep_time_stamp):
GLib.idle_add(self._load_grep_ui, data, priority=GLib.PRIORITY_LOW) GLib.idle_add(self._load_grep_ui, data, priority=GLib.PRIORITY_HIGH_IDLE)
except Exception as e: except Exception as e:
... print( repr(e) )
conn.close() conn.close()

View File

@ -82,12 +82,11 @@ def grep_search(target=None, query=None):
collection[f"{b64_file}"] = {} collection[f"{b64_file}"] = {}
collection[f"{b64_file}"] = { f"{line_no}": b64_data} collection[f"{b64_file}"] = { f"{line_no}": b64_data}
data = f"GREP|{ts}|{json.dumps(collection, separators=(',', ':'), indent=4)}"
send_ipc_message(data)
except Exception as e: except Exception as e:
traceback.print_exc() traceback.print_exc()
data = f"GREP|{ts}|{json.dumps(collection, separators=(',', ':'), indent=4)}"
send_ipc_message(data)
collection = {} collection = {}
@ -112,5 +111,11 @@ if __name__ == "__main__":
# Read arguments (If any...) # Read arguments (If any...)
args = parser.parse_args() args = parser.parse_args()
search(args) search(args)
data = f"SEARCH_DONE|{ts}|0"
send_ipc_message(data)
except Exception as e: except Exception as e:
traceback.print_exc() traceback.print_exc()
data = f"SEARCH_DONE|{ts}|1"
send_ipc_message(data)

View File

@ -60,7 +60,7 @@ class Plugin(PluginBase):
self._queue_translate = False self._queue_translate = False
self._watcher_running = False self._watcher_running = False
self._vqd_attrib = None self._vqd_attrib = None
self.from_trans = "jp" self.from_trans = "ja"
self.to_trans = "en" self.to_trans = "en"
self.translate_tries = 0 self.translate_tries = 0
@ -138,14 +138,14 @@ class Plugin(PluginBase):
self.translate_tries += 1 self.translate_tries += 1
tlink = f"https://duckduckgo.com/translation.js?vqd={self._vqd_attrib}&query=translate&from={self.from_trans}&to={self.to_trans}" tlink = f"https://duckduckgo.com/translation.js?vqd={self._vqd_attrib}&query=translate&from={self.from_trans}&to={self.to_trans}"
response = requests.post(self.tlink, headers=self._headers, data=from_translate) response = requests.post(tlink, headers=self._headers, data=from_translate)
if response.status_code == 200: if response.status_code == 200:
data = response.json() data = response.json()
self._translate_to_buffer.set_text(data["translated"]) self._translate_to_buffer.set_text(data["translated"])
self.translate_tries = 0 self.translate_tries = 0
if "detected_language" in data.keys(): if data["detected_language"]:
self._detected_language_lbl.set_label(f"Detected Language: {data['detected_language']}") self._detected_language_lbl.set_label(f"Detected Language: {data['detected_language']}")
else: else:
self._detected_language_lbl.set_label(f"Selected Language: {self.from_trans}") self._detected_language_lbl.set_label(f"Selected Language: {self.from_trans}")
@ -157,7 +157,7 @@ class Plugin(PluginBase):
msg = f"Could not translate... Response Code: {response.status_code}" msg = f"Could not translate... Response Code: {response.status_code}"
self._translate_to_buffer.set_text(msg) self._translate_to_buffer.set_text(msg)
# NOTE: https://github.com/deedy5/duckduckgo_search/blob/72acb900a346be576f0917dd3d6c0fbd618a71bf/duckduckgo_search/utils.py
def get_vqd(self): def get_vqd(self):
response = requests.post(self.vqd_link, headers=self.vqd_headers, data=self.vqd_data, timeout=10) response = requests.post(self.vqd_link, headers=self.vqd_headers, data=self.vqd_data, timeout=10)
if response.status_code == 200: if response.status_code == 200:

View File

@ -13,7 +13,7 @@ function main() {
LINK=`xclip -selection clipboard -o` LINK=`xclip -selection clipboard -o`
python "${HOME}/.config/solarfm/plugins/youtube_download/yt_dlp/__main__.py" \ python "${HOME}/.config/solarfm/plugins/youtube_download/yt_dlp/__main__.py" \
--cookies-from-browser firefox --write-sub --embed-sub --sub-langs en \ --write-sub --embed-sub --sub-langs en \
-o "${1}/%(title)s.%(ext)s" "${LINK}" -o "${1}/%(title)s.%(ext)s" "${LINK}"
} }
main "$@"; main "$@";

View File

@ -27,6 +27,7 @@ from .widgets.popups.plugins_popup_widget import PluginsPopupWidget
from .widgets.popups.io_popup_widget import IOPopupWidget from .widgets.popups.io_popup_widget import IOPopupWidget
from .widgets.context_menu_widget import ContextMenuWidget from .widgets.context_menu_widget import ContextMenuWidget
from .widgets.bottom_status_info_widget import BottomStatusInfoWidget
from .ui_mixin import UIMixin from .ui_mixin import UIMixin
@ -56,7 +57,9 @@ class Controller(UIMixin, SignalsMixins, Controller_Data):
def _setup_styling(self): def _setup_styling(self):
... self.window.connect("focus-out-event", self.unset_keys_and_data)
self.window.connect("key-press-event", self.on_global_key_press_controller)
self.window.connect("key-release-event", self.on_global_key_release_controller)
def _setup_signals(self): def _setup_signals(self):
FileSystemActions() FileSystemActions()
@ -67,6 +70,7 @@ class Controller(UIMixin, SignalsMixins, Controller_Data):
event_system.subscribe("clear_notebooks", self.clear_notebooks) event_system.subscribe("clear_notebooks", self.clear_notebooks)
event_system.subscribe("get_current_state", self.get_current_state) event_system.subscribe("get_current_state", self.get_current_state)
event_system.subscribe("go_to_path", self.go_to_path) event_system.subscribe("go_to_path", self.go_to_path)
event_system.subscribe("format_to_uris", self.format_to_uris)
event_system.subscribe("do_action_from_menu_controls", self.do_action_from_menu_controls) event_system.subscribe("do_action_from_menu_controls", self.do_action_from_menu_controls)
event_system.subscribe("set_clipboard_data", self.set_clipboard_data) event_system.subscribe("set_clipboard_data", self.set_clipboard_data)
@ -78,7 +82,7 @@ class Controller(UIMixin, SignalsMixins, Controller_Data):
self.core_widget = self.builder.get_object("core_widget") self.core_widget = self.builder.get_object("core_widget")
settings.set_builder(self.builder) settings.set_builder(self.builder)
settings.register_signals_to_builder([self,]) settings.register_signals_to_builder([self,], self.builder)
def get_core_widget(self): def get_core_widget(self):
return self.core_widget return self.core_widget
@ -87,6 +91,7 @@ class Controller(UIMixin, SignalsMixins, Controller_Data):
# NOTE: Really we will move these to the UI/(New) Window 'base' controller # NOTE: Really we will move these to the UI/(New) Window 'base' controller
# after we're done cleaning and refactoring to use fewer mixins. # after we're done cleaning and refactoring to use fewer mixins.
def _load_widgets(self): def _load_widgets(self):
BottomStatusInfoWidget()
IOPopupWidget() IOPopupWidget()
MessagePopupWidget() MessagePopupWidget()
PathMenuPopupWidget() PathMenuPopupWidget()

View File

@ -13,8 +13,6 @@ from gi.repository import Gtk
from shellfm.windows.controller import WindowController from shellfm.windows.controller import WindowController
from plugins.plugins_controller import PluginsController from plugins.plugins_controller import PluginsController
# from factories.split_view_widget import SplitViewWidget
@ -49,21 +47,15 @@ class Controller_Data:
self.plugins = PluginsController() 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.pane_master = self.builder.get_object("pane_master")
# self.pane_master.pack1(SplitViewWidget(), True, True)
# self.pane_master.pack2(SplitViewWidget(), True, True)
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")
self.window4 = self.builder.get_object("window_4") self.window4 = self.builder.get_object("window_4")
self.path_entry = self.builder.get_object("path_entry") self.path_entry = self.builder.get_object("path_entry")
self.bottom_size_label = self.builder.get_object("bottom_size_label") # self.bottom_size_label = self.builder.get_object("bottom_size_label")
self.bottom_file_count_label = self.builder.get_object("bottom_file_count_label") # self.bottom_file_count_label = self.builder.get_object("bottom_file_count_label")
self.bottom_path_label = self.builder.get_object("bottom_path_label") # self.bottom_path_label = self.builder.get_object("bottom_path_label")
self.notebooks = [self.window1, self.window2, self.window3, self.window4] self.notebooks = [self.window1, self.window2, self.window3, self.window4]
self.selected_files = [] self.selected_files = []
@ -132,6 +124,24 @@ class Controller_Data:
event_system.emit("update_state_info_plugins", state) event_system.emit("update_state_info_plugins", state)
return state return state
def format_to_uris(self, store, wid, tid, treePaths, use_just_path=False):
tab = self.get_fm_window(wid).get_tab_by_id(tid)
dir = tab.get_current_directory()
uris = []
for path in treePaths:
itr = store.get_iter(path)
file = store.get(itr, 1)[0]
fpath = ""
if not use_just_path:
fpath = f"file://{dir}/{file}"
else:
fpath = f"{dir}/{file}"
uris.append(fpath)
return uris
def clear_console(self) -> None: def clear_console(self) -> None:
''' Clears the terminal screen. ''' ''' Clears the terminal screen. '''

View File

@ -72,75 +72,8 @@ class WindowMixin(TabMixin):
def get_fm_window(self, wid): def get_fm_window(self, wid):
return self.fm_controller.get_window_by_nickname(f"window_{wid}") return self.fm_controller.get_window_by_nickname(f"window_{wid}")
def format_to_uris(self, store, wid, tid, treePaths, use_just_path=False):
tab = self.get_fm_window(wid).get_tab_by_id(tid)
dir = tab.get_current_directory()
uris = []
for path in treePaths:
itr = store.get_iter(path)
file = store.get(itr, 1)[0]
fpath = ""
if not use_just_path:
fpath = f"file://{dir}/{file}"
else:
fpath = f"{dir}/{file}"
uris.append(fpath)
return uris
def set_bottom_labels(self, tab): def set_bottom_labels(self, tab):
state = self.get_current_state() event_system.emit("set_bottom_labels", (tab,))
selected_files = state.icon_grid.get_selected_items()
current_directory = tab.get_current_directory()
path_file = Gio.File.new_for_path(current_directory)
mount_file = path_file.query_filesystem_info(attributes="filesystem::*", cancellable=None)
formatted_mount_free = sizeof_fmt( int(mount_file.get_attribute_as_string("filesystem::free")) )
formatted_mount_size = sizeof_fmt( int(mount_file.get_attribute_as_string("filesystem::size")) )
# NOTE: Hides empty trash and other desired buttons based on context.
if settings.get_trash_files_path() == current_directory:
event_system.emit("show_trash_buttons")
else:
event_system.emit("hide_trash_buttons")
# If something selected
self.bottom_size_label.set_label(f"{formatted_mount_free} free / {formatted_mount_size}")
self.bottom_path_label.set_label(tab.get_current_directory())
if selected_files:
uris = self.format_to_uris(state.store, state.wid, state.tid, selected_files, True)
combined_size = 0
for uri in uris:
try:
file_info = Gio.File.new_for_path(uri).query_info(attributes="standard::size",
flags=Gio.FileQueryInfoFlags.NONE,
cancellable=None)
file_size = file_info.get_size()
combined_size += file_size
except WindowException as e:
logger.debug(repr(e))
formatted_size = sizeof_fmt(combined_size)
if tab.is_hiding_hidden():
self.bottom_path_label.set_label(f" {len(uris)} / {tab.get_files_count()} ({formatted_size})")
else:
self.bottom_path_label.set_label(f" {len(uris)} / {tab.get_not_hidden_count()} ({formatted_size})")
return
# If nothing selected
if tab.is_hiding_hidden():
if tab.get_hidden_count() > 0:
self.bottom_file_count_label.set_label(f"{tab.get_not_hidden_count()} visible ({tab.get_hidden_count()} hidden)")
else:
self.bottom_file_count_label.set_label(f"{tab.get_files_count()} items")
else:
self.bottom_file_count_label.set_label(f"{tab.get_files_count()} items")
def set_window_title(self): def set_window_title(self):
wid, tid = self.fm_controller.get_active_wid_and_tid() wid, tid = self.fm_controller.get_active_wid_and_tid()

View File

@ -0,0 +1,101 @@
# 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 BottomStatusInfoWidget:
"""docstring for BottomStatusInfoWidget."""
def __init__(self):
super(BottomStatusInfoWidget, self).__init__()
_GLADE_FILE = f"{settings.get_ui_widgets_path()}/bottom_status_info_ui.glade"
self._builder = Gtk.Builder()
self._builder.add_from_file(_GLADE_FILE)
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
self._load_widgets()
def _setup_styling(self):
...
def _setup_signals(self):
...
def _subscribe_to_events(self):
event_system.subscribe("set_bottom_labels", self.set_bottom_labels)
def _load_widgets(self):
builder = settings.get_builder()
self.bottom_status_info = self._builder.get_object("bottom_status_info")
self.bottom_size_label = self._builder.get_object("bottom_size_label")
self.bottom_file_count_label = self._builder.get_object("bottom_file_count_label")
self.bottom_path_label = self._builder.get_object("bottom_path_label")
builder.expose_object(f"bottom_status_info", self.bottom_status_info)
builder.expose_object(f"bottom_size_label", self.bottom_size_label)
builder.expose_object(f"bottom_file_count_label", self.bottom_file_count_label)
builder.expose_object(f"bottom_path_label", self.bottom_path_label)
builder.get_object("core_widget").add(self.bottom_status_info)
def set_bottom_labels(self, tab):
state = event_system.emit_and_await("get_current_state")
selected_files = state.icon_grid.get_selected_items()
current_directory = tab.get_current_directory()
path_file = Gio.File.new_for_path(current_directory)
mount_file = path_file.query_filesystem_info(attributes="filesystem::*", cancellable=None)
formatted_mount_free = sizeof_fmt( int(mount_file.get_attribute_as_string("filesystem::free")) )
formatted_mount_size = sizeof_fmt( int(mount_file.get_attribute_as_string("filesystem::size")) )
# NOTE: Hides empty trash and other desired buttons based on context.
if settings.get_trash_files_path() == current_directory:
event_system.emit("show_trash_buttons")
else:
event_system.emit("hide_trash_buttons")
# If something selected
self.bottom_size_label.set_label(f"{formatted_mount_free} free / {formatted_mount_size}")
self.bottom_path_label.set_label(tab.get_current_directory())
if selected_files:
uris = event_system.emit_and_await("format_to_uris", (state.store, state.wid, state.tid, selected_files, True))
combined_size = 0
for uri in uris:
try:
file_info = Gio.File.new_for_path(uri).query_info(attributes="standard::size",
flags=Gio.FileQueryInfoFlags.NONE,
cancellable=None)
file_size = file_info.get_size()
combined_size += file_size
except WindowException as e:
logger.debug(repr(e))
formatted_size = sizeof_fmt(combined_size)
if tab.is_hiding_hidden():
self.bottom_path_label.set_label(f" {len(uris)} / {tab.get_files_count()} ({formatted_size})")
else:
self.bottom_path_label.set_label(f" {len(uris)} / {tab.get_not_hidden_count()} ({formatted_size})")
return
# If nothing selected
if tab.is_hiding_hidden():
if tab.get_hidden_count() > 0:
self.bottom_file_count_label.set_label(f"{tab.get_not_hidden_count()} visible ({tab.get_hidden_count()} hidden)")
else:
self.bottom_file_count_label.set_label(f"{tab.get_files_count()} items")
else:
self.bottom_file_count_label.set_label(f"{tab.get_files_count()} items")

View File

@ -1,5 +1,4 @@
# Python imports # Python imports
import inspect
# Lib imports # Lib imports
import gi import gi
@ -16,6 +15,7 @@ class ContextMenuWidget(Gtk.Menu):
def __init__(self): def __init__(self):
super(ContextMenuWidget, self).__init__() super(ContextMenuWidget, self).__init__()
self.builder = settings.get_builder() self.builder = settings.get_builder()
self._builder = Gtk.Builder() self._builder = Gtk.Builder()
self._context_menu_data = settings.get_context_menu_data() self._context_menu_data = settings.get_context_menu_data()
@ -32,22 +32,14 @@ class ContextMenuWidget(Gtk.Menu):
def _setup_signals(self): def _setup_signals(self):
event_system.subscribe("show_context_menu", self.show_context_menu) event_system.subscribe("show_context_menu", self.show_context_menu)
event_system.subscribe("hide_context_menu", self.hide_context_menu) event_system.subscribe("hide_context_menu", self.hide_context_menu)
settings.register_signals_to_builder([self,], self._builder)
classes = [self]
handlers = {}
for c in classes:
methods = None
try:
methods = inspect.getmembers(c, predicate=inspect.ismethod)
handlers.update(methods)
except Exception as e:
logger.debug(repr(e))
self._builder.connect_signals(handlers)
def _load_widgets(self): def _load_widgets(self):
self.build_context_menu() self.build_context_menu()
def _emit(self, menu_item, type):
event_system.emit("do_action_from_menu_controls", type)
def make_submenu(self, name, data, keys): def make_submenu(self, name, data, keys):
menu = Gtk.Menu() menu = Gtk.Menu()
@ -94,9 +86,6 @@ class ContextMenuWidget(Gtk.Menu):
if plugins_entry: if plugins_entry:
self.builder.expose_object("context_menu_plugins", plugins_entry.get_submenu()) self.builder.expose_object("context_menu_plugins", plugins_entry.get_submenu())
def _emit(self, menu_item, type):
event_system.emit("do_action_from_menu_controls", type)
def show_context_menu(self, widget=None, eve=None): def show_context_menu(self, widget=None, eve=None):
self.builder.get_object("context_menu").popup_at_pointer(None) self.builder.get_object("context_menu").popup_at_pointer(None)

View File

@ -1,5 +1,4 @@
# Python imports # Python imports
import inspect
# Lib imports # Lib imports
import gi import gi
@ -16,14 +15,10 @@ class AboutWidget:
def __init__(self): def __init__(self):
super(AboutWidget, self).__init__() super(AboutWidget, self).__init__()
_GLADE_FILE = f"{settings.get_ui_widgets_path()}/about_ui.glade" _GLADE_FILE = f"{settings.get_ui_widgets_path()}/about_ui.glade"
builder = settings.get_builder()
self._builder = Gtk.Builder() self._builder = Gtk.Builder()
self._builder.add_from_file(_GLADE_FILE) self._builder.add_from_file(_GLADE_FILE)
self.about_page = self._builder.get_object("about_page")
builder.expose_object(f"about_page", self.about_page)
self._setup_styling() self._setup_styling()
self._setup_signals() self._setup_signals()
@ -36,21 +31,14 @@ class AboutWidget:
def _setup_signals(self): def _setup_signals(self):
event_system.subscribe("show_about_page", self.show_about_page) event_system.subscribe("show_about_page", self.show_about_page)
event_system.subscribe("hide_about_page", self.hide_about_page) event_system.subscribe("hide_about_page", self.hide_about_page)
settings.register_signals_to_builder([self,], self._builder)
classes = [self]
handlers = {}
for c in classes:
methods = None
try:
methods = inspect.getmembers(c, predicate=inspect.ismethod)
handlers.update(methods)
except Exception as e:
logger.debug(repr(e))
self._builder.connect_signals(handlers)
def _load_widgets(self): def _load_widgets(self):
... builder = settings.get_builder()
self.about_page = self._builder.get_object("about_page")
builder.expose_object(f"about_page", self.about_page)
def show_about_page(self, widget=None, eve=None): def show_about_page(self, widget=None, eve=None):
response = self.about_page.run() response = self.about_page.run()

View File

@ -1,5 +1,4 @@
# Python imports # Python imports
import inspect
# Lib imports # Lib imports
import gi import gi
@ -16,16 +15,10 @@ class AppchooserWidget:
def __init__(self): def __init__(self):
super(AppchooserWidget, self).__init__() super(AppchooserWidget, self).__init__()
_GLADE_FILE = f"{settings.get_ui_widgets_path()}/appchooser_ui.glade" _GLADE_FILE = f"{settings.get_ui_widgets_path()}/appchooser_ui.glade"
builder = settings.get_builder()
self._builder = Gtk.Builder() self._builder = Gtk.Builder()
self._builder.add_from_file(_GLADE_FILE) self._builder.add_from_file(_GLADE_FILE)
self._appchooser_menu = self._builder.get_object("appchooser_menu")
self._appchooser_widget = self._builder.get_object("appchooser_widget")
builder.expose_object(f"appchooser_menu", self._appchooser_menu)
builder.expose_object(f"appchooser_widget", self._appchooser_widget)
self._setup_styling() self._setup_styling()
self._setup_signals() self._setup_signals()
@ -39,21 +32,17 @@ class AppchooserWidget:
event_system.subscribe("show_appchooser_menu", self.show_appchooser_menu) event_system.subscribe("show_appchooser_menu", self.show_appchooser_menu)
event_system.subscribe("hide_appchooser_menu", self.hide_appchooser_menu) event_system.subscribe("hide_appchooser_menu", self.hide_appchooser_menu)
event_system.subscribe("run_appchooser_launch", self.run_appchooser_launch) event_system.subscribe("run_appchooser_launch", self.run_appchooser_launch)
settings.register_signals_to_builder([self,], self._builder)
classes = [self]
handlers = {}
for c in classes:
methods = None
try:
methods = inspect.getmembers(c, predicate=inspect.ismethod)
handlers.update(methods)
except Exception as e:
print(repr(e))
self._builder.connect_signals(handlers)
def _load_widgets(self): def _load_widgets(self):
... builder = settings.get_builder()
self._appchooser_menu = self._builder.get_object("appchooser_menu")
self._appchooser_widget = self._builder.get_object("appchooser_widget")
builder.expose_object(f"appchooser_menu", self._appchooser_menu)
builder.expose_object(f"appchooser_widget", self._appchooser_widget)
def show_appchooser_menu(self, widget=None, eve=None): def show_appchooser_menu(self, widget=None, eve=None):
response = self._appchooser_menu.run() response = self._appchooser_menu.run()

View File

@ -1,5 +1,4 @@
# Python imports # Python imports
import inspect
# Lib imports # Lib imports
import gi import gi
@ -17,12 +16,27 @@ class FileExistsWidget:
def __init__(self): def __init__(self):
super(FileExistsWidget, self).__init__() super(FileExistsWidget, self).__init__()
_GLADE_FILE = f"{settings.get_ui_widgets_path()}/file_exists_ui.glade"
builder = settings.get_builder()
self._builder = Gtk.Builder()
_GLADE_FILE = f"{settings.get_ui_widgets_path()}/file_exists_ui.glade"
self._builder = Gtk.Builder()
self._builder.add_from_file(_GLADE_FILE) self._builder.add_from_file(_GLADE_FILE)
self._setup_styling()
self._setup_signals()
self._load_widgets()
def _setup_styling(self):
...
def _setup_signals(self):
event_system.subscribe("setup_exists_data", self.setup_exists_data)
event_system.subscribe("show_exists_page", self.show_exists_page)
settings.register_signals_to_builder([self,], self._builder)
def _load_widgets(self):
builder = settings.get_builder()
self.file_exists_dialog = self._builder.get_object("file_exists_dialog") self.file_exists_dialog = self._builder.get_object("file_exists_dialog")
self._exists_file_label = self._builder.get_object("exists_file_label") self._exists_file_label = self._builder.get_object("exists_file_label")
self._exists_file_diff_from = self._builder.get_object("exists_file_diff_from") self._exists_file_diff_from = self._builder.get_object("exists_file_diff_from")
@ -38,33 +52,6 @@ class FileExistsWidget:
builder.expose_object(f"exists_file_field", self._exists_file_field) builder.expose_object(f"exists_file_field", self._exists_file_field)
builder.expose_object(f"exists_file_rename_bttn", self._exists_file_rename_bttn) builder.expose_object(f"exists_file_rename_bttn", self._exists_file_rename_bttn)
self._setup_styling()
self._setup_signals()
self._load_widgets()
def _setup_styling(self):
...
def _setup_signals(self):
event_system.subscribe("setup_exists_data", self.setup_exists_data)
event_system.subscribe("show_exists_page", self.show_exists_page)
classes = [self]
handlers = {}
for c in classes:
methods = None
try:
methods = inspect.getmembers(c, predicate=inspect.ismethod)
handlers.update(methods)
except Exception as e:
logger.debug(repr(e))
self._builder.connect_signals(handlers)
def _load_widgets(self):
...
def show_exists_page(self, widget=None, eve=None): def show_exists_page(self, widget=None, eve=None):
response = self.file_exists_dialog.run() response = self.file_exists_dialog.run()

View File

@ -1,5 +1,4 @@
# Python imports # Python imports
import inspect
# Lib imports # Lib imports
import gi import gi
@ -17,20 +16,17 @@ class MessageWidget(Gtk.MessageDialog):
def __init__(self): def __init__(self):
super(MessageWidget, self).__init__() super(MessageWidget, self).__init__()
self._setup_styling() self._setup_styling()
self._setup_signals() self._setup_signals()
self._load_widgets() self._load_widgets()
def _setup_styling(self): def _setup_styling(self):
self.type = Gtk.MessageType.WARNING self.type = Gtk.MessageType.WARNING
def _setup_signals(self): def _setup_signals(self):
... ...
def _load_widgets(self): def _load_widgets(self):
message_area = self.get_message_area() message_area = self.get_message_area()
message_area.get_children()[0].set_label("Alert!") message_area.get_children()[0].set_label("Alert!")

View File

@ -1,5 +1,4 @@
# Python imports # Python imports
import inspect
# Lib imports # Lib imports
import gi import gi
@ -18,18 +17,10 @@ class NewFileWidget:
def __init__(self): def __init__(self):
super(NewFileWidget, self).__init__() super(NewFileWidget, self).__init__()
_GLADE_FILE = f"{settings.get_ui_widgets_path()}/new_file_ui.glade" _GLADE_FILE = f"{settings.get_ui_widgets_path()}/new_file_ui.glade"
builder = settings.get_builder()
self._builder = Gtk.Builder() self._builder = Gtk.Builder()
self._builder.add_from_file(_GLADE_FILE) self._builder.add_from_file(_GLADE_FILE)
self._new_file_menu = self._builder.get_object("new_file_menu")
self._new_fname_field = self._builder.get_object("new_fname_field")
self._new_file_toggle_type = self._builder.get_object("new_file_toggle_type")
builder.expose_object(f"new_file_menu", self._new_file_menu)
builder.expose_object(f"new_fname_field", self._new_fname_field)
builder.expose_object(f"new_file_toggle_type", self._new_file_toggle_type)
self._setup_styling() self._setup_styling()
self._setup_signals() self._setup_signals()
@ -42,21 +33,19 @@ class NewFileWidget:
def _setup_signals(self): def _setup_signals(self):
event_system.subscribe("show_new_file_menu", self.show_new_file_menu) event_system.subscribe("show_new_file_menu", self.show_new_file_menu)
event_system.subscribe("hide_new_file_menu", self.hide_new_file_menu) event_system.subscribe("hide_new_file_menu", self.hide_new_file_menu)
settings.register_signals_to_builder([self,], self._builder)
classes = [self]
handlers = {}
for c in classes:
methods = None
try:
methods = inspect.getmembers(c, predicate=inspect.ismethod)
handlers.update(methods)
except Exception as e:
print(repr(e))
self._builder.connect_signals(handlers)
def _load_widgets(self): def _load_widgets(self):
... builder = settings.get_builder()
self._new_file_menu = self._builder.get_object("new_file_menu")
self._new_fname_field = self._builder.get_object("new_fname_field")
self._new_file_toggle_type = self._builder.get_object("new_file_toggle_type")
builder.expose_object(f"new_file_menu", self._new_file_menu)
builder.expose_object(f"new_fname_field", self._new_fname_field)
builder.expose_object(f"new_file_toggle_type", self._new_file_toggle_type)
def show_new_file_menu(self, widget=None, eve=None): def show_new_file_menu(self, widget=None, eve=None):
if widget: if widget:

View File

@ -1,5 +1,4 @@
# Python imports # Python imports
import inspect
# Lib imports # Lib imports
import gi import gi
@ -18,18 +17,10 @@ class RenameWidget:
def __init__(self): def __init__(self):
super(RenameWidget, self).__init__() super(RenameWidget, self).__init__()
_GLADE_FILE = f"{settings.get_ui_widgets_path()}/rename_ui.glade" _GLADE_FILE = f"{settings.get_ui_widgets_path()}/rename_ui.glade"
builder = settings.get_builder()
self._builder = Gtk.Builder() self._builder = Gtk.Builder()
self._builder.add_from_file(_GLADE_FILE) self._builder.add_from_file(_GLADE_FILE)
self._rename_file_menu = self._builder.get_object("rename_file_menu")
self._rename_fname = self._builder.get_object("rename_fname")
self._file_to_rename_label = self._builder.get_object("file_to_rename_label")
builder.expose_object(f"rename_file_menu", self._rename_file_menu)
builder.expose_object(f"rename_fname", self._rename_fname)
builder.expose_object(f"file_to_rename_label", self._file_to_rename_label)
self._setup_styling() self._setup_styling()
self._setup_signals() self._setup_signals()
@ -42,21 +33,19 @@ class RenameWidget:
def _setup_signals(self): def _setup_signals(self):
event_system.subscribe("show_rename_file_menu", self.show_rename_file_menu) event_system.subscribe("show_rename_file_menu", self.show_rename_file_menu)
event_system.subscribe("hide_rename_file_menu", self.hide_rename_file_menu) event_system.subscribe("hide_rename_file_menu", self.hide_rename_file_menu)
settings.register_signals_to_builder([self,], self._builder)
classes = [self]
handlers = {}
for c in classes:
methods = None
try:
methods = inspect.getmembers(c, predicate=inspect.ismethod)
handlers.update(methods)
except Exception as e:
logger.debug(repr(e))
self._builder.connect_signals(handlers)
def _load_widgets(self): def _load_widgets(self):
... builder = settings.get_builder()
self._rename_file_menu = self._builder.get_object("rename_file_menu")
self._rename_fname = self._builder.get_object("rename_fname")
self._file_to_rename_label = self._builder.get_object("file_to_rename_label")
builder.expose_object(f"rename_file_menu", self._rename_file_menu)
builder.expose_object(f"rename_fname", self._rename_fname)
builder.expose_object(f"file_to_rename_label", self._file_to_rename_label)
def show_rename_file_menu(self, widget=None, eve=None): def show_rename_file_menu(self, widget=None, eve=None):
if widget: if widget:

View File

@ -1,5 +1,4 @@
# Python imports # Python imports
import inspect
import gc import gc
# Lib imports # Lib imports
@ -17,14 +16,10 @@ class SaveLoadWidget:
def __init__(self): def __init__(self):
super(SaveLoadWidget, self).__init__() super(SaveLoadWidget, self).__init__()
_GLADE_FILE = f"{settings.get_ui_widgets_path()}/save_load_ui.glade" _GLADE_FILE = f"{settings.get_ui_widgets_path()}/save_load_ui.glade"
builder = settings.get_builder()
self._builder = Gtk.Builder() self._builder = Gtk.Builder()
self._builder.add_from_file(_GLADE_FILE) self._builder.add_from_file(_GLADE_FILE)
self.save_load_dialog = self._builder.get_object("save_load_dialog")
builder.expose_object(f"save_load_dialog", self.save_load_dialog)
self._setup_styling() self._setup_styling()
self._setup_signals() self._setup_signals()
@ -38,7 +33,10 @@ class SaveLoadWidget:
event_system.subscribe("save_load_session", self.save_load_session) event_system.subscribe("save_load_session", self.save_load_session)
def _load_widgets(self): def _load_widgets(self):
... builder = settings.get_builder()
self.save_load_dialog = self._builder.get_object("save_load_dialog")
builder.expose_object(f"save_load_dialog", self.save_load_dialog)
def save_load_session(self, action="save_session"): def save_load_session(self, action="save_session"):

View File

@ -1,3 +0,0 @@
"""
FileView module
"""

View File

@ -1,71 +0,0 @@
# Python imports
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
from shellfm.windows.tabs.tab import Tab
from .icon_view import IconView
class FileView(Gtk.ScrolledWindow):
"""docstring for FileView."""
def __init__(self):
super(FileView, self).__init__()
self.tab_state = Tab()
self.icon_view = IconView(self.tab_state)
self.tab_widget = self.create_tab_widget()
self._setup_styling()
self._setup_signals()
self.add(self.icon_view)
self.show_all()
def _setup_styling(self):
self.set_hexpand(True)
self.set_vexpand(True)
def _setup_signals(self):
# self.connect("update-tab-title", self._update_tab_title)
...
def _update_tab_title(self, widget=None, eve=None):
label = self.tab_widget.get_children()[0]
label.set_label(f"{self.tab_state.get_end_of_path()}")
label.set_width_chars( len(self.tab_state.get_end_of_path()) )
def set_path(self, path):
if path:
self.tab_state.set_path(path)
self.icon_view.load_store()
self._update_tab_title()
def create_tab_widget(self):
button_box = Gtk.ButtonBox()
label = Gtk.Label()
close = Gtk.Button()
icon = Gtk.Image(stock=Gtk.STOCK_CLOSE)
label.set_label(f"{self.tab_state.get_end_of_path()}")
label.set_width_chars(len(self.tab_state.get_end_of_path()))
label.set_xalign(0.0)
close.add(icon)
button_box.add(label)
button_box.add(close)
close.connect("released", self.close_tab)
button_box.show_all()
return button_box
def close_tab(self, widget, eve=None):
self.get_parent().emit('close-view', (self,))

View File

@ -1,149 +0,0 @@
# Python imports
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
from .file_view import FileView
class FilesWidget(Gtk.Notebook):
"""docstring for FilesWidget."""
ccount = 0
def __new__(cls, *args, **kwargs):
obj = super(FilesWidget, cls).__new__(cls)
cls.ccount += 1
return obj
def __init__(self):
super(FilesWidget, self).__init__()
self.set_group_name("file_window")
self.NAME = f"window_{self.ccount}"
builder = settings.get_builder()
builder.expose_object(self.NAME, self)
self._add_action_widgets()
self._setup_styling()
self._setup_signals()
self.show_all()
def _setup_styling(self):
self.set_scrollable(True)
self.set_show_tabs(True)
self.set_show_border(False)
self.set_hexpand(True)
self.set_margin_top(5)
self.set_margin_bottom(5)
self.set_margin_start(5)
self.set_margin_end(5)
def _setup_signals(self):
# self.connect("close-view", self.close_view)
event_system.subscribe("load-window-state", self.load_window_state)
def _add_action_widgets(self):
start_box = Gtk.Box()
end_box = Gtk.Box()
search = Gtk.SearchEntry()
search.set_placeholder_text("Search...")
search.connect("changed", self._do_query)
home_btn = Gtk.Button()
home_btn.set_image( Gtk.Image.new_from_icon_name("gtk-home", 4) )
home_btn.set_always_show_image(True)
home_btn.connect("released", self.do_action, ("go_home_dir"))
up_btn = Gtk.Button()
up_btn.set_image( Gtk.Image.new_from_icon_name("up", 4) )
up_btn.set_always_show_image(True)
up_btn.connect("released", self.do_action, ("go_up_dir"))
refresh_btn = Gtk.Button()
refresh_btn.set_image( Gtk.Image.new_from_icon_name("gtk-refresh", 4) )
refresh_btn.set_always_show_image(True)
refresh_btn.connect("released", self.do_action, ("refresh_dir"))
add_btn = Gtk.Button()
add_btn.set_image( Gtk.Image.new_from_icon_name("add", 4) )
add_btn.set_always_show_image(True)
add_btn.connect("released", self.create_view)
start_box.add(home_btn)
start_box.add(add_btn)
end_box.add(search)
end_box.add(up_btn)
end_box.add(refresh_btn)
start_box.show_all()
end_box.show_all()
# PACKTYPE: 0 Start, 1 = End
self.set_action_widget(start_box, 0)
self.set_action_widget(end_box, 1)
def _do_query(self, widget):
text = widget.get_text()
page = self.get_nth_page( self.get_current_page() )
page.icon_view.search_filter(text)
def load_window_state(self, win_name=None, tabs=None):
if win_name == self.NAME:
if len(tabs) > 0:
for tab in tabs:
self.create_view()
self.load_tab(tab)
else:
self.create_view()
def create_view(self, widget = None):
file_view = FileView()
index = self.append_page(file_view, file_view.tab_widget)
self.set_current_page(index)
return file_view
def load_tab(self, path = None):
if path:
file_view = self.get_nth_page( self.get_current_page() )
file_view.set_path(path)
def do_action(self, widget = None, action = None):
file_view = self.get_nth_page( self.get_current_page() )
if action == "refresh_dir":
file_view.icon_view.refresh_dir()
if action == "go_up_dir":
file_view.icon_view.go_up_dir()
if action == "go_home_dir":
file_view.icon_view.go_home_dir()
def close_view(self, parent, data = None):
widget = data[0]
page = self.page_num(widget)
# watcher = widget.tab_state.get_dir_watcher()
# watcher.cancel()
if self.get_n_pages() > 1:
self.remove_page(page)
# NOTE: Will prob try and call a window custom signal...
# self.fm_controller.save_state()
# self.set_window_title()

View File

@ -1,146 +0,0 @@
# Python imports
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GdkPixbuf
from gi.repository import Gio
# Application imports
from .signals.icon_view_signals_mixin import IconViewSignalsMixin
class IconView(IconViewSignalsMixin, Gtk.FlowBox):
"""docstring for IconView."""
def __init__(self, _tab_state):
super(IconView, self).__init__()
self.tab_state = _tab_state
self.selected_files = []
self.icon_theme = settings.get_icon_theme()
self._setup_styling()
self._setup_signals()
# self._setup_dnd()
self.load_store()
self.show_all()
def _emmit_signal_to_file_view(self, signal_type):
self.get_parent().get_parent().emit(signal_type, None)
def _setup_styling(self):
self.set_selection_mode(Gtk.SelectionMode.MULTIPLE)
self.set_valign(Gtk.Align.START)
self.set_column_spacing(15)
self.set_row_spacing(15)
self.set_homogeneous(True)
def _setup_signals(self):
self.set_activate_on_single_click(False)
self.connect("child-activated", self.icon_double_click)
# self.connect("drag-data-get", self.on_drag_set)
# self.connect("drag-data-received", self.on_drag_data_received)
# self.connect("drag-motion", self.on_drag_motion)
# NOTE: This gets called by a txt box which then shows/hides the flowbox child
# https://stackoverflow.com/questions/55828169/how-to-filter-gtk-flowbox-children-with-gtk-entrysearch
def search_filter(self, text):
def filter_func(fb_child, text):
if text.lower() in fb_child.get_name().lower():
return True
else:
return False
self.set_filter_func(filter_func, text)
def _setup_dnd(self):
URI_TARGET_TYPE = 80
uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE)
targets = [ uri_target ]
action = Gdk.DragAction.COPY
self.enable_model_drag_dest(targets, action)
self.enable_model_drag_source(0, targets, action)
def _clear_children(self, widget: type) -> None:
''' Clear children of a gtk widget. '''
for child in widget.get_children():
widget.remove(child)
# class IconView(IconViewSignalsMixin, Gtk.IconView):
# """docstring for IconView."""
#
# def __init__(self, _tab_state):
# super(IconView, self).__init__()
# self.store = None
# self.tab_state = _tab_state
# self.selected_files = []
# self.icon_theme = Gtk.IconTheme.get_default()
#
# self._setup_store()
# self._setup_styling()
# self._setup_signals()
# self._setup_dnd()
# self.load_store()
#
# self.show_all()
#
#
# def _setup_store(self):
# self.store = Gtk.ListStore(GdkPixbuf.Pixbuf or GdkPixbuf.PixbufAnimation or None, str or None)
# self.set_model(self.store)
# self.set_pixbuf_column(0)
# self.set_text_column(1)
#
# def _setup_styling(self):
# self.set_item_orientation(1)
# self.set_selection_mode(3)
# self.set_item_width(96)
# self.set_item_padding(8)
# self.set_margin(12)
# self.set_row_spacing(18)
# self.set_columns(-1)
# self.set_spacing(12)
# self.set_column_spacing(18)
#
# def _setup_signals(self):
# # self.connect("button_release_event", self.icon_single_click)
# self.connect("item-activated", self.icon_double_click)
# self.connect("selection-changed", self.set_selected_items)
# # self.connect("drag-data-get", self.on_drag_set)
# # self.connect("drag-data-received", self.on_drag_data_received)
# # self.connect("drag-motion", self.on_drag_motion)
# pass
#
# def _setup_dnd(self):
# URI_TARGET_TYPE = 80
# uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE)
# targets = [ uri_target ]
# action = Gdk.DragAction.COPY
# self.enable_model_drag_dest(targets, action)
# self.enable_model_drag_source(0, targets, action)
#
# def set_selected_items(self, icons_grid):
# self.selected_files = self.get_selected_items()

View File

@ -1,3 +0,0 @@
"""
Signals module
"""

View File

@ -1,183 +0,0 @@
# Python imports
import os
import traceback
import threading
import subprocess
import time
from os.path import isdir
# Lib imports
import gi
gi.require_version("Gtk", "3.0")
gi.require_version('Gdk', '3.0')
from gi.repository import Gtk
from gi.repository import GLib
from gi.repository import Gdk
from gi.repository import GdkPixbuf
from gi.repository import Gio
# Application imports
class FileView(Gtk.Box):
"""docstring for FileView."""
def __init__(self, _icon = None, _label = None):
super(FileView, self).__init__()
self.icon = None
self.label = _label
self.label.set_line_wrap(True)
self.label.set_selectable(True)
self.label.set_max_width_chars(20)
self.label.set_justify(2)
self.label.set_line_wrap_mode(2)
self.add(self.label)
self.set_orientation(1)
self.show_all()
def set_img(self, img):
self.icon = img
self.add(img)
self.reorder_child(self.icon, 0)
class IconViewSignalsMixin:
"""docstring for WidgetMixin"""
def load_store(self):
self._clear_children(self)
self.search_filter("")
dir = self.tab_state.get_current_directory()
files = self.tab_state.get_files()
for i, file in enumerate(files):
label = Gtk.Label(label=file[0])
child = Gtk.FlowBoxChild()
child.set_name(file[0])
file_view = FileView(_label=label)
child.add( file_view )
self.add(child)
self.create_icon(file_view, dir, file[0])
@threaded
def create_icon(self, file_view, dir, file):
icon = self.tab_state.create_icon(dir, file)
GLib.idle_add(self.update_store, *(file_view, icon, dir, file,))
def update_store(self, file_view, icon, dir, file):
if not icon:
path = f"{dir}/{file}"
icon = self.get_system_thumbnail(path, self.tab_state.sys_icon_wh[0])
if not icon:
icon = GdkPixbuf.Pixbuf.new_from_file(self.tab_state.DEFAULT_ICON)
img = Gtk.Image.new_from_pixbuf(icon)
img.show()
file_view.set_img(img)
self.show_all()
def get_system_thumbnail(self, filename, size):
try:
gio_file = Gio.File.new_for_path(filename)
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:
...
return None
def icon_double_click(self, icons_grid, item, data=None):
try:
file_view = item.get_children()[0]
file_name = file_view.label.get_label()
dir = self.tab_state.get_current_directory()
file = f"{dir}/{file_name}"
if isdir(file):
self.tab_state.set_path(file)
self.load_store()
self._emmit_signal_to_file_view('update-tab-title')
else:
event_system.emit("open_files", (self, file))
except Exception as e:
traceback.print_exc()
def go_up_dir(self):
self.tab_state.pop_from_path()
self.load_store()
self._emmit_signal_to_file_view('update-tab-title')
def go_home_dir(self):
self.tab_state.set_to_home()
self.load_store()
self._emmit_signal_to_file_view('update-tab-title')
def go_to_path(self, path):
self.tab_state.set_path(path)
self.load_store()
self._emmit_signal_to_file_view('update-tab-title')
def refresh_dir(self):
self.tab_state.load_directory()
self.load_store()
# def on_drag_set(self, icons_grid, drag_context, data, info, time):
# action = icons_grid.get_name()
# wid, tid = action.split("|")
# store = icons_grid.get_model()
# treePaths = icons_grid.get_selected_items()
# # NOTE: Need URIs as URI format for DnD to work. Will strip 'file://'
# # further down call chain when doing internal fm stuff.
# uris = self.format_to_uris(store, wid, tid, treePaths)
# uris_text = '\n'.join(uris)
#
# data.set_uris(uris)
# data.set_text(uris_text, -1)
#
# def on_drag_motion(self, icons_grid, drag_context, x, y, data):
# current = '|'.join(self.fm_controller.get_active_wid_and_tid())
# target = icons_grid.get_name()
# wid, tid = target.split("|")
# store = icons_grid.get_model()
# treePath = icons_grid.get_drag_dest_item().path
#
# if treePath:
# uri = self.format_to_uris(store, wid, tid, treePath)[0].replace("file://", "")
# self.override_drop_dest = uri if isdir(uri) else None
#
# if target not in current:
# self.fm_controller.set_wid_and_tid(wid, tid)
#
#
# def on_drag_data_received(self, widget, drag_context, x, y, data, info, time):
# if info == 80:
# wid, tid = self.fm_controller.get_active_wid_and_tid()
# notebook = self.builder.get_object(f"window_{wid}")
# store, tab_label = self.get_store_and_label_from_notebook(notebook, f"{wid}|{tid}")
# tab = self.get_fm_window(wid).get_tab_by_id(tid)
#
# uris = data.get_uris()
# dest = f"{tab.get_current_directory()}" if not self.override_drop_dest else self.override_drop_dest
# if len(uris) == 0:
# uris = data.get_text().split("\n")
#
# from_uri = '/'.join(uris[0].replace("file://", "").split("/")[:-1])
# if from_uri != dest:
# self.move_files(uris, dest)

View File

@ -29,8 +29,6 @@ class IconGridWidget(Gtk.IconView):
self.show_all() self.show_all()
def get_store(self):
return self._store
def _setup_styling(self): def _setup_styling(self):
self.set_pixbuf_column(0) self.set_pixbuf_column(0)
@ -74,3 +72,7 @@ class IconGridWidget(Gtk.IconView):
action = Gdk.DragAction.COPY action = Gdk.DragAction.COPY
self.enable_model_drag_dest(targets, action) self.enable_model_drag_dest(targets, action)
self.enable_model_drag_source(0, targets, action) self.enable_model_drag_source(0, targets, action)
def get_store(self):
return self._store

View File

@ -16,6 +16,7 @@ class IOWidget(Gtk.Box):
def __init__(self, action, file): def __init__(self, action, file):
super(IOWidget, self).__init__() super(IOWidget, self).__init__()
self._action = action self._action = action
self._file = file self._file = file
self._basename = self._file.get_basename() self._basename = self._file.get_basename()
@ -59,6 +60,7 @@ class IOWidget(Gtk.Box):
self.add(label) self.add(label)
self.add(stats) self.add(stats)
def do_cancel(self, widget, container, eve): def do_cancel(self, widget, container, eve):
logger.info(f"Canceling: [{self._action}] of {self._basename} ...") logger.info(f"Canceling: [{self._action}] of {self._basename} ...")
eve.cancel() eve.cancel()

View File

@ -1,5 +1,4 @@
# Python imports # Python imports
import inspect
# Lib imports # Lib imports
import gi import gi
@ -16,8 +15,8 @@ class IOPopupWidget(Gtk.Popover):
def __init__(self): def __init__(self):
super(IOPopupWidget, self).__init__() super(IOPopupWidget, self).__init__()
self._builder = settings.get_builder()
self._builder = settings.get_builder()
self._builder.expose_object(f"io_popup", self) self._builder.expose_object(f"io_popup", self)
self._setup_styling() self._setup_styling()
@ -42,5 +41,6 @@ class IOPopupWidget(Gtk.Popover):
self._builder.expose_object(f"io_list", vbox) self._builder.expose_object(f"io_list", vbox)
self.add(vbox) self.add(vbox)
def show_io_popup(self, widget=None, eve=None): def show_io_popup(self, widget=None, eve=None):
self.popup() self.popup()

View File

@ -20,9 +20,10 @@ class MessagePopupWidget(Gtk.Popover):
def __init__(self): def __init__(self):
super(MessagePopupWidget, self).__init__() super(MessagePopupWidget, self).__init__()
self.builder = settings.get_builder()
self.builder = settings.get_builder()
self.builder.expose_object(f"message_popup_widget", self) self.builder.expose_object(f"message_popup_widget", self)
self._message_buffer = None self._message_buffer = None
self._setup_styling() self._setup_styling()
@ -40,7 +41,6 @@ class MessagePopupWidget(Gtk.Popover):
event_system.subscribe("show_messages_popup", self.show_messages_popup) event_system.subscribe("show_messages_popup", self.show_messages_popup)
event_system.subscribe("hide_messages_popup", self.hide_messages_popup) event_system.subscribe("hide_messages_popup", self.hide_messages_popup)
def _load_widgets(self): def _load_widgets(self):
self._message_buffer = Gtk.TextBuffer() self._message_buffer = Gtk.TextBuffer()
vbox = Gtk.Box() vbox = Gtk.Box()
@ -66,6 +66,7 @@ class MessagePopupWidget(Gtk.Popover):
vbox.add(scroll_window) vbox.add(scroll_window)
self.add(vbox) self.add(vbox)
def show_messages_popup(self): def show_messages_popup(self):
self.popup() self.popup()

View File

@ -15,8 +15,8 @@ class PathMenuPopupWidget(Gtk.Popover):
def __init__(self): def __init__(self):
super(PathMenuPopupWidget, self).__init__() super(PathMenuPopupWidget, self).__init__()
self.builder = settings.get_builder()
self.builder = settings.get_builder()
self.builder.expose_object(f"path_menu", self) self.builder.expose_object(f"path_menu", self)
self._setup_styling() self._setup_styling()
@ -50,6 +50,7 @@ class PathMenuPopupWidget(Gtk.Popover):
scroll_window.show_all() scroll_window.show_all()
self.add(scroll_window) self.add(scroll_window)
def show_path_menu(self, widget=None, eve=None): def show_path_menu(self, widget=None, eve=None):
self.popup() self.popup()

View File

@ -1,5 +1,4 @@
# Python imports # Python imports
import inspect
# Lib imports # Lib imports
import gi import gi
@ -16,8 +15,8 @@ class PluginsPopupWidget(Gtk.Popover):
def __init__(self): def __init__(self):
super(PluginsPopupWidget, self).__init__() super(PluginsPopupWidget, self).__init__()
self.builder = settings.get_builder()
self.builder = settings.get_builder()
self.builder.expose_object(f"plugin_controls", self) self.builder.expose_object(f"plugin_controls", self)
self._setup_styling() self._setup_styling()
@ -43,6 +42,7 @@ class PluginsPopupWidget(Gtk.Popover):
self.builder.expose_object(f"plugin_control_list", vbox) self.builder.expose_object(f"plugin_control_list", vbox)
self.add(vbox) self.add(vbox)
def show_plugins_popup(self, widget=None, eve=None): def show_plugins_popup(self, widget=None, eve=None):
self.popup() self.popup()

View File

@ -15,6 +15,7 @@ class TabHeaderWidget(Gtk.ButtonBox):
def __init__(self, tab, close_tab): def __init__(self, tab, close_tab):
super(TabHeaderWidget, self).__init__() super(TabHeaderWidget, self).__init__()
self._tab = tab self._tab = tab
self._close_tab = close_tab # NOTE: Close method in tab_mixin self._close_tab = close_tab # NOTE: Close method in tab_mixin
@ -22,6 +23,7 @@ class TabHeaderWidget(Gtk.ButtonBox):
self._setup_signals() self._setup_signals()
self._load_widgets() self._load_widgets()
def _setup_styling(self): def _setup_styling(self):
self.set_orientation(0) self.set_orientation(0)

View File

@ -37,7 +37,8 @@ class Window(Gtk.ApplicationWindow):
def _setup_styling(self): def _setup_styling(self):
self.set_default_size(1670, 830) self.set_default_size(settings.get_main_window_width(),
settings.get_main_window_height())
self.set_title(f"{app_name}") self.set_title(f"{app_name}")
self.set_icon_from_file( settings.get_window_icon() ) self.set_icon_from_file( settings.get_window_icon() )
self.set_gravity(5) # 5 = CENTER self.set_gravity(5) # 5 = CENTER
@ -45,11 +46,6 @@ class Window(Gtk.ApplicationWindow):
def _setup_signals(self): def _setup_signals(self):
self.connect("delete-event", self._tear_down) self.connect("delete-event", self._tear_down)
# self.connect("focus-out-event", self._controller.unset_keys_and_data)
# self.connect("key-press-event", self._controller.on_global_key_press_controller)
# self.connect("key-release-event", self._controller.on_global_key_release_controller)
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self._tear_down) GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self._tear_down)
def _subscribe_to_events(self): def _subscribe_to_events(self):

View File

@ -1,3 +0,0 @@
"""
Factories Module
"""

View File

@ -1,33 +0,0 @@
# Python imports
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
from core.widgets.fm_widget.files_widget import FilesWidget
class SplitViewWidget(Gtk.Paned):
def __init__(self):
super(SplitViewWidget, self).__init__()
self._setup_styling()
self._setup_signals()
self._load_widgets()
self.show_all()
def _setup_styling(self):
self.set_wide_handle(True)
def _setup_signals(self):
...
def _load_widgets(self):
self.pack1(FilesWidget(), resize=False, shrink=False)
self.pack2(FilesWidget(), resize=True, shrink=False)

View File

@ -35,11 +35,11 @@ class Icon(DesktopIconMixin, VideoIconMixin, MeshsIconMixin):
def get_icon_image(self, dir, file, full_path): def get_icon_image(self, dir, file, full_path):
try: try:
thumbnl = self._get_system_thumbnail_gtk_thread(full_path, self.sys_icon_wh[0]) thumbnl = None
if file.lower().endswith(self.fmeshs): # 3D Mesh icon if file.lower().endswith(self.fmeshs): # 3D Mesh icon
... ...
if file.lower().endswith(self.fvideos): # Video icon elif file.lower().endswith(self.fvideos): # Video icon
thumbnl = self.create_video_thumbnail(full_path) thumbnl = self.create_video_thumbnail(full_path)
elif file.lower().endswith(self.fimages): # Image Icon elif file.lower().endswith(self.fimages): # Image Icon
thumbnl = self.create_scaled_image(full_path) thumbnl = self.create_scaled_image(full_path)
@ -48,9 +48,12 @@ class Icon(DesktopIconMixin, VideoIconMixin, MeshsIconMixin):
elif full_path.lower().endswith( ('.desktop',) ): # .desktop file parsing elif full_path.lower().endswith( ('.desktop',) ): # .desktop file parsing
thumbnl = self.find_thumbnail_from_desktop_file(full_path) thumbnl = self.find_thumbnail_from_desktop_file(full_path)
if not thumbnl:
thumbnl = self._get_system_thumbnail_gtk_thread(full_path, self.sys_icon_wh[0])
if not thumbnl: if not thumbnl:
raise IconException("No known icons found.") raise IconException("No known icons found.")
return thumbnl return thumbnl
except IconException: except IconException:
... ...

View File

@ -46,14 +46,24 @@ class Settings(StartCheckMixin):
if not os.path.exists(self._DEFAULT_ICONS): if not os.path.exists(self._DEFAULT_ICONS):
self._DEFAULT_ICONS = f"{self._USR_PATH}/icons" self._DEFAULT_ICONS = f"{self._USR_PATH}/icons"
if not os.path.exists(self._DEFAULT_ICONS):
raise MissingConfigError("Unable to find the application icons directory.")
if not os.path.exists(self._GLADE_FILE): if not os.path.exists(self._GLADE_FILE):
self._GLADE_FILE = f"{self._USR_PATH}/Main_Window.glade" self._GLADE_FILE = f"{self._USR_PATH}/Main_Window.glade"
if not os.path.exists(self._GLADE_FILE):
raise MissingConfigError("Unable to find the application Glade file.")
if not os.path.exists(self._KEY_BINDINGS_FILE): if not os.path.exists(self._KEY_BINDINGS_FILE):
self._KEY_BINDINGS_FILE = f"{self._USR_PATH}/key-bindings.json" self._KEY_BINDINGS_FILE = f"{self._USR_PATH}/key-bindings.json"
if not os.path.exists(self._KEY_BINDINGS_FILE):
raise MissingConfigError("Unable to find the application Keybindings file.")
if not os.path.exists(self._CSS_FILE): if not os.path.exists(self._CSS_FILE):
self._CSS_FILE = f"{self._USR_PATH}/stylesheet.css" self._CSS_FILE = f"{self._USR_PATH}/stylesheet.css"
if not os.path.exists(self._CSS_FILE):
raise MissingConfigError("Unable to find the application Stylesheet file.")
if not os.path.exists(self._WINDOW_ICON): if not os.path.exists(self._WINDOW_ICON):
self._WINDOW_ICON = f"{self._USR_PATH}/icons/{app_name.lower()}.png" self._WINDOW_ICON = f"{self._USR_PATH}/icons/{app_name.lower()}.png"
if not os.path.exists(self._WINDOW_ICON):
raise MissingConfigError("Unable to find the application icon.")
self._UI_WIDEGTS_PATH = f"{self._USR_PATH}/ui_widgets" self._UI_WIDEGTS_PATH = f"{self._USR_PATH}/ui_widgets"
@ -73,6 +83,8 @@ class Settings(StartCheckMixin):
self._context_menu_data = json.load(file) self._context_menu_data = json.load(file)
self._main_window = None self._main_window = None
self._main_window_w = 1670
self._main_window_h = 830
self._builder = None self._builder = None
self._trace_debug = False self._trace_debug = False
@ -82,7 +94,7 @@ class Settings(StartCheckMixin):
self.load_settings() self.load_settings()
def register_signals_to_builder(self, classes=None): def register_signals_to_builder(self, classes=None, builder=None):
handlers = {} handlers = {}
for c in classes: for c in classes:
@ -93,8 +105,7 @@ class Settings(StartCheckMixin):
except Exception as e: except Exception as e:
print(repr(e)) print(repr(e))
self._builder.connect_signals(handlers) builder.connect_signals(handlers)
def get_monitor_data(self) -> list: def get_monitor_data(self) -> list:
screen = self._main_window.get_screen() screen = self._main_window.get_screen()
@ -109,6 +120,8 @@ class Settings(StartCheckMixin):
def set_main_window(self, window): self._main_window = window def set_main_window(self, window): self._main_window = window
def get_main_window(self) -> Gtk.ApplicationWindow: return self._main_window def get_main_window(self) -> Gtk.ApplicationWindow: return self._main_window
def get_main_window_width(self) -> Gtk.ApplicationWindow: return self._main_window_w
def get_main_window_height(self) -> Gtk.ApplicationWindow: return self._main_window_h
def get_builder(self) -> Gtk.Builder: return self._builder def get_builder(self) -> Gtk.Builder: return self._builder
def get_glade_file(self) -> str: return self._GLADE_FILE def get_glade_file(self) -> str: return self._GLADE_FILE
def get_icon_theme(self) -> str: return self._ICON_THEME def get_icon_theme(self) -> str: return self._ICON_THEME

View File

@ -790,56 +790,7 @@
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkStatusbar" id="bottom_status_info"> <placeholder/>
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-left">10</property>
<property name="margin-right">10</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="spacing">15</property>
<property name="baseline-position">top</property>
<child>
<object class="GtkLabel" id="bottom_size_label">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="bottom_file_count_label">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="bottom_path_label">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child> </child>
</object> </object>
</interface> </interface>

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<object class="GtkStatusbar" id="bottom_status_info">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-left">10</property>
<property name="margin-right">10</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="spacing">15</property>
<property name="baseline-position">top</property>
<child>
<object class="GtkLabel" id="bottom_size_label">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="bottom_file_count_label">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="bottom_path_label">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</interface>