WIP implimentig new files widget attempt 2; keybindings fixed prior commits

This commit is contained in:
itdominator 2023-03-05 15:42:11 -06:00
parent 66cfe8caec
commit 4b69622cc6
11 changed files with 657 additions and 59 deletions

View File

@ -37,14 +37,14 @@ class Controller(UIMixin, SignalsMixins, 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): def __init__(self, args, unknownargs):
self.setup_controller_data() self._setup_controller_data()
self._setup_styling() self._setup_styling()
self._setup_signals() self._setup_signals()
self._subscribe_to_events() self._subscribe_to_events()
self._load_widgets() self._load_widgets()
self.generate_windows(self.fm_controller_data) self._generate_file_views(self.fm_controller_data)
if args.no_plugins == "false": if args.no_plugins == "false":
self.plugins.launch_plugins() self.plugins.launch_plugins()
@ -65,8 +65,10 @@ class Controller(UIMixin, SignalsMixins, Controller_Data):
def _subscribe_to_events(self): def _subscribe_to_events(self):
event_system.subscribe("handle_file_from_ipc", self.handle_file_from_ipc) event_system.subscribe("handle_file_from_ipc", self.handle_file_from_ipc)
event_system.subscribe("generate_windows", self.generate_windows) event_system.subscribe("generate_file_views", self._generate_file_views)
event_system.subscribe("clear_notebooks", self.clear_notebooks) event_system.subscribe("clear_notebooks", self.clear_notebooks)
event_system.subscribe("set_window_title", self._set_window_title)
event_system.subscribe("unset_selected_files_views", self._unset_selected_files_views)
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("format_to_uris", self.format_to_uris)
@ -105,7 +107,6 @@ class Controller(UIMixin, SignalsMixins, Controller_Data):
FileExistsWidget() FileExistsWidget()
SaveLoadWidget() SaveLoadWidget()
def reload_plugins(self, widget=None, eve=None): def reload_plugins(self, widget=None, eve=None):
self.plugins.reload_plugins() self.plugins.reload_plugins()

View File

@ -37,7 +37,7 @@ 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) -> None: def _setup_controller_data(self) -> None:
self.window = settings.get_main_window() self.window = settings.get_main_window()
self.builder = None self.builder = None
self.core_widget = None self.core_widget = None
@ -87,6 +87,7 @@ class Controller_Data:
state.wid, state.tid = self.fm_controller.get_active_wid_and_tid() state.wid, state.tid = self.fm_controller.get_active_wid_and_tid()
state.tab = self.get_fm_window(state.wid).get_tab_by_id(state.tid) state.tab = self.get_fm_window(state.wid).get_tab_by_id(state.tid)
state.icon_grid = self.builder.get_object(f"{state.wid}|{state.tid}|icon_grid") state.icon_grid = self.builder.get_object(f"{state.wid}|{state.tid}|icon_grid")
# state.icon_grid = event_system.emit_and_await("get_files_view_icon_grid", (state.wid, state.tid))
state.store = state.icon_grid.get_model() state.store = state.icon_grid.get_model()
state.message_dialog = MessageWidget() state.message_dialog = MessageWidget()
@ -103,7 +104,7 @@ class Controller_Data:
# if self.to_cut_files: # if self.to_cut_files:
# state.to_cut_files = self.format_to_uris(state.store, state.wid, state.tid, self.to_cut_files, True) # state.to_cut_files = self.format_to_uris(state.store, state.wid, state.tid, self.to_cut_files, True)
event_system.emit("update_state_info_plugins", state) event_system.emit("update_state_info_plugins", state) # NOTE: Need to remove after we convert plugins to use emit_and_await
return state return state
def format_to_uris(self, store, wid, tid, treePaths, use_just_path=False): def format_to_uris(self, store, wid, tid, treePaths, use_just_path=False):
@ -125,6 +126,20 @@ class Controller_Data:
return uris return uris
def get_fm_window(self, wid):
return self.fm_controller.get_window_by_nickname(f"window_{wid}")
def _unset_selected_files_views(self):
for _notebook in self.notebooks:
ctx = _notebook.get_style_context()
ctx.remove_class("notebook-selected-focus")
ctx.add_class("notebook-unselected-focus")
def _set_window_title(self, dir):
self.window.set_title(f"{app_name} ~ {dir}")
def clear_console(self) -> None: def clear_console(self) -> None:
''' Clears the terminal screen. ''' ''' Clears the terminal screen. '''
os.system('cls' if os.name == 'nt' else 'clear') os.system('cls' if os.name == 'nt' else 'clear')

View File

@ -22,53 +22,6 @@ class WindowException(Exception):
class WindowMixin(TabMixin): class WindowMixin(TabMixin):
"""docstring for WindowMixin""" """docstring for WindowMixin"""
def generate_windows(self, session_json = None):
# for session in session_json:
# nickname = session["window"]["Nickname"]
# tabs = session["window"]["tabs"]
# isHidden = True if session["window"]["isHidden"] == "True" else False
# event_system.emit("load-window-state", (nickname, tabs))
if session_json:
for j, value in enumerate(session_json):
i = j + 1
notebook_tggl_button = self.builder.get_object(f"tggl_notebook_{i}")
is_hidden = True if value["window"]["isHidden"] == "True" else False
tabs = value["window"]["tabs"]
self.fm_controller.create_window()
notebook_tggl_button.set_active(True)
if tabs:
for tab in tabs:
self.create_new_tab_notebook(None, i, tab)
else:
self.create_new_tab_notebook(None, i, None)
if is_hidden:
self.toggle_notebook_pane(notebook_tggl_button)
try:
if not self.is_pane4_hidden:
icon_grid = self.window4.get_children()[-1].get_children()[0]
elif not self.is_pane3_hidden:
icon_grid = self.window3.get_children()[-1].get_children()[0]
elif not self.is_pane2_hidden:
icon_grid = self.window2.get_children()[-1].get_children()[0]
elif not self.is_pane1_hidden:
icon_grid = self.window1.get_children()[-1].get_children()[0]
icon_grid.event(Gdk.Event().new(type=Gdk.EventType.BUTTON_RELEASE))
icon_grid.event(Gdk.Event().new(type=Gdk.EventType.BUTTON_RELEASE))
except WindowException as e:
logger.info("\n: The saved session might be missing window data! :\nLocation: ~/.config/solarfm/session.json\nFix: Back it up and delete it to reset.\n")
logger.debug(repr(e))
else:
for j in range(0, 4):
i = j + 1
self.fm_controller.create_window()
self.create_new_tab_notebook(None, i, None)
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}")

View File

@ -1,13 +1,78 @@
# Python imports # Python imports
# Gtk 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
# Application imports # Application imports
from .mixins.ui.pane_mixin import PaneMixin from .mixins.ui.pane_mixin import PaneMixin
from .mixins.ui.window_mixin import WindowMixin from .mixins.ui.window_mixin import WindowMixin
from .widgets.files_view.files_widget import FilesWidget
class UIMixinException(Exception):
...
class UIMixin(PaneMixin, WindowMixin): class UIMixin(PaneMixin, WindowMixin):
... # class UIMixin(PaneMixin):
def _generate_file_views(self, session_json = None):
# self._wip_hybrid_approach_loading_process(session_json)
self._current_loading_process(session_json)
def _wip_hybrid_approach_loading_process(self, session_json = None):
for session in session_json:
self.fm_controller.create_window()
FilesWidget().set_fm_controller(self.fm_controller)
for session in session_json:
nickname = session["window"]["Nickname"]
tabs = session["window"]["tabs"]
isHidden = True if session["window"]["isHidden"] == "True" else False
event_system.emit("load_files_view_state", (nickname, tabs))
def _current_loading_process(self, session_json = None):
if session_json:
for j, value in enumerate(session_json):
i = j + 1
notebook_tggl_button = self.builder.get_object(f"tggl_notebook_{i}")
is_hidden = True if value["window"]["isHidden"] == "True" else False
tabs = value["window"]["tabs"]
self.fm_controller.create_window()
notebook_tggl_button.set_active(True)
if tabs:
for tab in tabs:
self.create_new_tab_notebook(None, i, tab)
else:
self.create_new_tab_notebook(None, i, None)
if is_hidden:
self.toggle_notebook_pane(notebook_tggl_button)
try:
if not self.is_pane4_hidden:
icon_grid = self.window4.get_children()[-1].get_children()[0]
elif not self.is_pane3_hidden:
icon_grid = self.window3.get_children()[-1].get_children()[0]
elif not self.is_pane2_hidden:
icon_grid = self.window2.get_children()[-1].get_children()[0]
elif not self.is_pane1_hidden:
icon_grid = self.window1.get_children()[-1].get_children()[0]
icon_grid.event(Gdk.Event().new(type=Gdk.EventType.BUTTON_RELEASE))
icon_grid.event(Gdk.Event().new(type=Gdk.EventType.BUTTON_RELEASE))
except UIMixinException as e:
logger.info("\n: The saved session might be missing window data! :\nLocation: ~/.config/solarfm/session.json\nFix: Back it up and delete it to reset.\n")
logger.debug(repr(e))
else:
for j in range(0, 4):
i = j + 1
self.fm_controller.create_window()
self.create_new_tab_notebook(None, i, None)

View File

@ -80,5 +80,5 @@ class SaveLoadWidget:
state = event_system.emit_and_await("get_current_state") state = event_system.emit_and_await("get_current_state")
event_system.emit("clear_notebooks") event_system.emit("clear_notebooks")
state.fm_controller.unload_tabs_and_windows() state.fm_controller.unload_tabs_and_windows()
event_system.emit("generate_windows", (session_json,)) event_system.emit("generate_file_views", (session_json,))
gc.collect() gc.collect()

View File

@ -0,0 +1,3 @@
"""
Files View module
"""

View File

@ -0,0 +1,71 @@
# Python imports
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
from ...mixins.signals.file_action_signals_mixin import FileActionSignalsMixin
from .window_mixin import WindowMixin
class FilesWidget(FileActionSignalsMixin, WindowMixin):
"""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.INDEX = self.ccount
self.NAME = f"window_{self.INDEX}"
self.builder = Gtk.Builder()
self.files_view = None
self.fm_controller = None
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
self._load_widgets()
def _setup_styling(self):
...
def _setup_signals(self):
settings.register_signals_to_builder([self,], self.builder)
def _subscribe_to_events(self):
event_system.subscribe("load_files_view_state", self._load_files_view_state)
event_system.subscribe("get_files_view_icon_grid", self._get_files_view_icon_grid)
def _load_widgets(self):
_builder = settings.get_builder()
self.files_view = _builder.get_object(f"{self.NAME}")
self.files_view.set_group_name("files_widget")
self.builder.expose_object(f"{self.NAME}", self.files_view)
def _load_files_view_state(self, win_name=None, tabs=None):
if win_name == self.NAME:
if tabs:
for tab in tabs:
self.create_new_tab_notebook(None, self.INDEX, tab)
else:
self.create_new_tab_notebook(None, self.INDEX, None)
def _get_files_view_icon_grid(self, win_index=None, tid=None):
if win_index == str(self.INDEX):
return self.builder.get_object(f"{self.INDEX}|{tid}|icon_grid")
def set_fm_controller(self, _fm_controller):
self.fm_controller = _fm_controller

View File

@ -0,0 +1,105 @@
# Python imports
# Lib imports
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from gi.repository import GLib
# Application imports
from ...widgets.tab_header_widget import TabHeaderWidget
from ...widgets.icon_grid_widget import IconGridWidget
from ...widgets.icon_tree_widget import IconTreeWidget
class GridMixin:
"""docstring for GridMixin"""
def load_store(self, tab, store, save_state=False):
store.clear()
dir = tab.get_current_directory()
files = tab.get_files()
for file in files:
store.append([None, file[0]])
Gtk.main_iteration()
for i, file in enumerate(files):
self.create_icon(i, tab, store, dir, file[0])
# NOTE: Not likely called often from here but it could be useful
if save_state and not trace_debug:
self.fm_controller.save_state()
@daemon_threaded
def create_icon(self, i, tab, store, dir, file):
icon = tab.create_icon(dir, file)
GLib.idle_add(self.update_store, *(i, store, icon,))
def update_store(self, i, store, icon):
itr = store.get_iter(i)
store.set_value(itr, 0, icon)
def create_tab_widget(self, tab):
return TabHeaderWidget(tab, self.close_tab)
def create_scroll_and_store(self, tab, wid, use_tree_view=False):
scroll = Gtk.ScrolledWindow()
if not use_tree_view:
grid = self.create_icon_grid_widget()
else:
# TODO: Fix global logic to make the below work too
grid = self.create_icon_tree_widget()
scroll.add(grid)
scroll.set_name(f"{wid}|{tab.get_id()}")
grid.set_name(f"{wid}|{tab.get_id()}")
self.builder.expose_object(f"{wid}|{tab.get_id()}|icon_grid", grid)
self.builder.expose_object(f"{wid}|{tab.get_id()}", scroll)
return scroll, grid.get_store()
def create_icon_grid_widget(self):
grid = IconGridWidget()
grid._setup_additional_signals(
self.grid_icon_single_click,
self.grid_icon_double_click,
self.grid_set_selected_items,
self.grid_on_drag_set,
self.grid_on_drag_data_received,
self.grid_on_drag_motion
)
return grid
def create_icon_tree_widget(self):
grid = IconTreeWidget()
grid._setup_additional_signals(
self.grid_icon_single_click,
self.grid_icon_double_click,
self.grid_on_drag_set,
self.grid_on_drag_data_received,
self.grid_on_drag_motion
)
grid.columns_autosize()
return grid
def get_store_and_label_from_notebook(self, notebook, _name):
icon_grid = None
tab_label = None
store = None
for obj in notebook.get_children():
icon_grid = obj.get_children()[0]
name = icon_grid.get_name()
if name == _name:
store = icon_grid.get_model()
tab_label = notebook.get_tab_label(obj).get_children()[0]
return store, tab_label

View File

@ -0,0 +1,206 @@
# Python imports
import os
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
from .grid_mixin import GridMixin
class TabMixin(GridMixin):
"""docstring for TabMixin"""
def create_tab(self, wid=None, tid=None, path=None):
if not wid:
wid, tid = self.fm_controller.get_active_wid_and_tid()
notebook = self.builder.get_object(f"window_{wid}")
# path_entry = self.builder.get_object(f"path_entry")
tab = self.fm_controller.add_tab_for_window_by_nickname(f"window_{wid}")
# tab.logger = logger
tab.set_wid(wid)
if not path:
if wid and tid:
_tab = self.get_fm_window(wid).get_tab_by_id(tid)
tab.set_path(_tab.get_current_directory())
else:
tab.set_path(path)
tab_widget = self.create_tab_widget(tab)
scroll, store = self.create_scroll_and_store(tab, wid)
index = notebook.append_page(scroll, tab_widget)
notebook.set_tab_detachable(scroll, True)
self.fm_controller.set_wid_and_tid(wid, tab.get_id())
event_system.emit("go_to_path", (tab.get_current_directory(),)) # NOTE: Not efficent if I understand how
# path_entry.set_text(tab.get_current_directory())
notebook.show_all()
notebook.set_current_page(index)
ctx = notebook.get_style_context()
ctx.add_class("notebook-unselected-focus")
notebook.set_tab_reorderable(scroll, True)
self.load_store(tab, store)
# self.set_window_title()
event_system.emit("set_window_title", (tab.get_current_directory(),))
self.set_file_watcher(tab)
def close_tab(self, button, eve=None):
notebook = button.get_parent().get_parent()
wid = int(notebook.get_name()[-1])
tid = self.get_id_from_tab_box(button.get_parent())
scroll = self.builder.get_object(f"{wid}|{tid}")
page = notebook.page_num(scroll)
tab = self.get_fm_window(wid).get_tab_by_id(tid)
watcher = tab.get_dir_watcher()
watcher.cancel()
self.get_fm_window(wid).delete_tab_by_id(tid)
notebook.remove_page(page)
if not settings.is_trace_debug():
self.fm_controller.save_state()
self.set_window_title()
# NOTE: Not actually getting called even tho set in the glade file...
def on_tab_dnded(self, notebook, page, x, y):
...
def on_tab_reorder(self, child, page_num, new_index):
wid, tid = page_num.get_name().split("|")
window = self.get_fm_window(wid)
tab = None
for i, tab in enumerate(window.get_all_tabs()):
if tab.get_id() == tid:
_tab = window.get_tab_by_id(tid)
watcher = _tab.get_dir_watcher()
watcher.cancel()
window.get_all_tabs().insert(new_index, window.get_all_tabs().pop(i))
tab = window.get_tab_by_id(tid)
self.set_file_watcher(tab)
if not settings.is_trace_debug():
self.fm_controller.save_state()
def on_tab_switch_update(self, notebook, content=None, index=None):
self.selected_files.clear()
wid, tid = content.get_children()[0].get_name().split("|")
self.fm_controller.set_wid_and_tid(wid, tid)
self.set_path_text(wid, tid)
self.set_window_title()
def get_id_from_tab_box(self, tab_box):
return tab_box.get_children()[2].get_text()
def get_tab_label(self, notebook, icon_grid):
return notebook.get_tab_label(icon_grid.get_parent()).get_children()[0]
def get_tab_close(self, notebook, icon_grid):
return notebook.get_tab_label(icon_grid.get_parent()).get_children()[1]
def get_tab_icon_grid_from_notebook(self, notebook):
return notebook.get_children()[1].get_children()[0]
def refresh_tab(data=None):
state = self.get_current_state()
state.tab.load_directory()
self.load_store(state.tab, state.store)
def update_tab(self, tab_label, tab, store, wid, tid):
self.load_store(tab, store)
self.set_path_text(wid, tid)
char_width = len(tab.get_end_of_path())
tab_label.set_width_chars(char_width)
tab_label.set_label(tab.get_end_of_path())
self.set_window_title()
self.set_file_watcher(tab)
if not settings.is_trace_debug():
self.fm_controller.save_state()
def do_action_from_bar_controls(self, widget, eve=None):
action = widget.get_name()
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)
if action == "create_tab":
dir = tab.get_current_directory()
self.create_tab(wid, None, dir)
if not settings.is_trace_debug():
self.fm_controller.save_state()
return
if action == "go_up":
tab.pop_from_path()
if action == "go_home":
tab.set_to_home()
if action == "refresh_tab":
tab.load_directory()
if action == "path_entry":
focused_obj = self.window.get_focus()
dir = f"{tab.get_current_directory()}/"
path = widget.get_text()
if isinstance(focused_obj, Gtk.Entry):
path_menu_buttons = self.builder.get_object("path_menu_buttons")
query = widget.get_text().replace(dir, "")
files = tab.get_files() + tab.get_hidden()
self.clear_children(path_menu_buttons)
show_path_menu = False
for file, hash, size in files:
if os.path.isdir(f"{dir}{file}"):
if query.lower() in file.lower():
button = Gtk.Button(label=file)
button.show()
button.connect("clicked", self.set_path_entry)
path_menu_buttons.add(button)
show_path_menu = True
if not show_path_menu:
event_system.emit("hide_path_menu")
else:
event_system.emit("show_path_menu")
widget.grab_focus_without_selecting()
widget.set_position(-1)
if path.endswith(".") or path == dir:
return
if not tab.set_path(path):
return
self.update_tab(tab_label, tab, store, wid, tid)
try:
widget.grab_focus_without_selecting()
widget.set_position(-1)
except Exception as e:
pass
def set_path_entry(self, button=None, eve=None):
state = self.get_current_state()
path = f"{state.tab.get_current_directory()}/{button.get_label()}"
path_entry = self.builder.get_object("path_entry")
path_entry.set_text(path)
path_entry.grab_focus_without_selecting()
path_entry.set_position(-1)
event_system.emit("hide_path_menu")
def show_hide_hidden_files(self):
wid, tid = self.fm_controller.get_active_wid_and_tid()
tab = self.get_fm_window(wid).get_tab_by_id(tid)
tab.set_hiding_hidden(not tab.is_hiding_hidden())
tab.load_directory()
self.builder.get_object("refresh_tab").released()

View File

@ -0,0 +1,173 @@
# Python imports
import copy
import traceback
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 Gdk
from gi.repository import Gio
# Application imports
from .tab_mixin import TabMixin
class WindowException(Exception):
...
class WindowMixin(TabMixin):
"""docstring for WindowMixin"""
def get_fm_window(self, wid):
return self.fm_controller.get_window_by_nickname(f"window_{wid}")
def set_bottom_labels(self, tab):
event_system.emit("set_bottom_labels", (tab,))
def set_window_title(self):
wid, tid = self.fm_controller.get_active_wid_and_tid()
notebook = self.builder.get_object(f"window_{wid}")
tab = self.get_fm_window(wid).get_tab_by_id(tid)
dir = tab.get_current_directory()
event_system.emit("unset_selected_files_views")
ctx = self.files_view.get_style_context()
ctx.remove_class("notebook-unselected-focus")
ctx.add_class("notebook-selected-focus")
event_system.emit("set_window_title", (dir,))
self.set_bottom_labels(tab)
def set_path_text(self, wid, tid):
tab = self.get_fm_window(wid).get_tab_by_id(tid)
event_system.emit("go_to_path", (tab.get_current_directory(),))
def grid_set_selected_items(self, icons_grid):
new_items = icons_grid.get_selected_items()
items_size = len(new_items)
selected_items = event_system.emit_and_await("get_selected_files")
if items_size == 1:
# NOTE: If already in selection, likely dnd else not so wont readd
if new_items[0] in selected_items:
self.dnd_left_primed += 1
# NOTE: If in selection but trying to just select an already selected item.
if self.dnd_left_primed > 1:
self.dnd_left_primed = 0
selected_items.clear()
# NOTE: Likely trying dnd, just readd to selection the former set.
# Prevents losing highlighting of grid selected.
for path in selected_items:
icons_grid.select_path(path)
if items_size > 0:
event_system.emit("set_selected_files", (new_items,))
else:
self.dnd_left_primed = 0
selected_items.clear()
def grid_icon_single_click(self, icons_grid, eve):
try:
event_system.emit("hide_path_menu")
wid, tid = icons_grid.get_name().split("|")
self.fm_controller.set_wid_and_tid(wid, tid)
self.set_path_text(wid, tid)
self.set_window_title()
if eve.type == Gdk.EventType.BUTTON_RELEASE and eve.button == 1: # l-click
if self.ctrl_down:
self.dnd_left_primed = 0
if self.single_click_open: # FIXME: need to find a way to pass the model index
self.grid_icon_double_click(icons_grid)
elif eve.type == Gdk.EventType.BUTTON_RELEASE and eve.button == 3: # r-click
event_system.emit("show_context_menu")
except WindowException as e:
logger.info(repr(e))
self.display_message(settings.get_error_color(), f"{repr(e)}")
def grid_icon_double_click(self, icons_grid, item, data=None):
try:
if self.ctrl_down and self.shift_down:
self.unset_keys_and_data()
self.execute_files(in_terminal=True)
return
elif self.ctrl_down:
self.unset_keys_and_data()
self.execute_files()
return
state = self.get_current_state()
notebook = self.builder.get_object(f"window_{state.wid}")
tab_label = self.get_tab_label(notebook, icons_grid)
fileName = state.store[item][1]
dir = state.tab.get_current_directory()
file = f"{dir}/{fileName}"
if isdir(file):
state.tab.set_path(file)
self.update_tab(tab_label, state.tab, state.store, state.wid, state.tid)
else:
event_system.emit("open_files")
except WindowException as e:
traceback.print_exc()
self.display_message(settings.get_error_color(), f"{repr(e)}")
def grid_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 grid_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()
path_at_loc = None
try:
path_at_loc = icons_grid.get_item_at_pos(x, y)[0]
highlighted_item_path = icons_grid.get_drag_dest_item().path
if path_at_loc and path_at_loc == highlighted_item_path:
uri = self.format_to_uris(store, wid, tid, highlighted_item_path)[0].replace("file://", "")
self.override_drop_dest = uri if isdir(uri) else None
except Exception as e:
...
if target not in current:
self.fm_controller.set_wid_and_tid(wid, tid)
def grid_on_drag_data_received(self, widget, drag_context, x, y, data, info, time):
if info == 80:
uris = data.get_uris()
state = event_system.emit_and_await("get_current_state")
dest = f"{state.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:
event_system.emit("move_files", (uris, dest))
def create_new_tab_notebook(self, widget=None, wid=None, path=None):
self.create_tab(wid, None, path)

View File

@ -38,11 +38,17 @@ class EventSystem:
def emit_and_await(self, event_type, data = None): def emit_and_await(self, event_type, data = None):
""" NOTE: Should be used when signal has only one listener and vis-a-vis """ """ NOTE: Should be used when signal has only one listener and vis-a-vis """
if event_type in self.subscribers: if event_type in self.subscribers:
response = None
for fn in self.subscribers[event_type]: for fn in self.subscribers[event_type]:
if data: if data:
if hasattr(data, '__iter__') and not type(data) is str: if hasattr(data, '__iter__') and not type(data) is str:
return fn(*data) response = fn(*data)
else: else:
return fn(data) response = fn(data)
else: else:
return fn() response = fn()
if not response in (None, ''):
break
return response