Moved widgets to core, externalized load_save

This commit is contained in:
itdominator 2022-12-04 19:43:32 -06:00
parent a237757e5e
commit 22b22958de
25 changed files with 239 additions and 219 deletions

View File

@ -1,6 +1,5 @@
# Python imports
import os
import gc
import time
# Lib imports
@ -13,25 +12,29 @@ from gi.repository import GLib
from .controller_data import Controller_Data
from .mixins.signals_mixins import SignalsMixins
from widgets.popups.message_popup_widget import MessagePopupWidget
from widgets.popups.path_menu_popup_widget import PathMenuPopupWidget
from widgets.popups.plugins_popup_widget import PluginsPopupWidget
from widgets.popups.io_popup_widget import IOPopupWidget
from .ui.dialogs.about_widget import AboutWidget
from .ui.dialogs.appchooser_widget import AppchooserWidget
from .ui.dialogs.file_exists_widget import FileExistsWidget
from .ui.dialogs.new_file_widget import NewFileWidget
from .ui.dialogs.message_widget import MessageWidget
from .ui.dialogs.rename_widget import RenameWidget
from .ui.dialogs.save_load_widget import SaveLoadWidget
from widgets.context_menu_widget import ContextMenuWidget
from widgets.new_file_widget import NewFileWidget
from widgets.rename_widget import RenameWidget
from widgets.file_exists_widget import FileExistsWidget
from widgets.about_widget import AboutWidget
from widgets.appchooser_widget import AppchooserWidget
from .ui.popups.message_popup_widget import MessagePopupWidget
from .ui.popups.path_menu_popup_widget import PathMenuPopupWidget
from .ui.popups.plugins_popup_widget import PluginsPopupWidget
from .ui.popups.io_popup_widget import IOPopupWidget
from .ui import UI
from .ui.context_menu_widget import ContextMenuWidget
from .ui_mixin import UIMixin
class Controller(UI, SignalsMixins, Controller_Data):
class Controller(UIMixin, SignalsMixins, Controller_Data):
""" Controller coordinates the mixins and is somewhat the root hub of it all. """
def __init__(self, args, unknownargs):
self._setup_styling()
self._setup_signals()
@ -49,33 +52,39 @@ class Controller(UI, SignalsMixins, Controller_Data):
message = f"FILE|{arg}"
event_system.emit("post_file_to_ipc", message)
def _setup_styling(self):
...
def _setup_signals(self):
...
# NOTE: Really we will move these to the UI/(New) Window 'base' controller
# after we're done cleaning and refactoring to use fewer mixins.
def _load_widgets(self):
MessagePopupWidget()
PathMenuPopupWidget()
PluginsPopupWidget()
IOPopupWidget()
ContextMenuWidget()
NewFileWidget()
RenameWidget()
FileExistsWidget()
AboutWidget()
AppchooserWidget()
def _subscribe_to_events(self):
event_system.subscribe("handle_file_from_ipc", self.handle_file_from_ipc)
event_system.subscribe("clear_notebooks", self.clear_notebooks)
event_system.subscribe("get_current_state", self.get_current_state)
event_system.subscribe("go_to_path", self.go_to_path)
event_system.subscribe("do_action_from_menu_controls", self.do_action_from_menu_controls)
# NOTE: Needs to be moved (probably just to file actions class) after reducing mixins usage
event_system.subscribe("open_with_files", self.open_with_files)
event_system.subscribe("generate_windows", self.generate_windows)
# NOTE: Really we will move these to the UI/(New) Window 'base' controller
# after we're done cleaning and refactoring to use fewer mixins.
def _load_widgets(self):
IOPopupWidget()
MessagePopupWidget()
PathMenuPopupWidget()
PluginsPopupWidget()
AboutWidget()
AppchooserWidget()
ContextMenuWidget()
NewFileWidget()
RenameWidget()
FileExistsWidget()
SaveLoadWidget()
self.message_dialog = MessageWidget()
def tear_down(self, widget=None, eve=None):
@ -87,54 +96,6 @@ class Controller(UI, SignalsMixins, Controller_Data):
Gtk.main_quit()
def save_load_session(self, action="save_session"):
wid, tid = self.fm_controller.get_active_wid_and_tid()
tab = self.get_fm_window(wid).get_tab_by_id(tid)
save_load_dialog = self.builder.get_object("save_load_dialog")
if action == "save_session":
if not settings.is_trace_debug():
self.fm_controller.save_state()
return
elif action == "save_session_as":
save_load_dialog.set_action(Gtk.FileChooserAction.SAVE)
elif action == "load_session":
save_load_dialog.set_action(Gtk.FileChooserAction.OPEN)
else:
raise Exception(f"Unknown action given: {action}")
save_load_dialog.set_current_folder(tab.get_current_directory())
save_load_dialog.set_current_name("session.json")
response = save_load_dialog.run()
if response == Gtk.ResponseType.OK:
if action == "save_session_as":
path = f"{save_load_dialog.get_current_folder()}/{save_load_dialog.get_current_name()}"
self.fm_controller.save_state(path)
elif action == "load_session":
path = f"{save_load_dialog.get_file().get_path()}"
session_json = self.fm_controller.get_state_from_file(path)
self.load_session(session_json)
if (response == Gtk.ResponseType.CANCEL) or (response == Gtk.ResponseType.DELETE_EVENT):
...
save_load_dialog.hide()
def load_session(self, session_json):
if settings.is_debug():
logger.debug(f"Session Data: {session_json}")
self.ctrl_down = False
self.shift_down = False
self.alt_down = False
for notebook in self.notebooks:
self.clear_children(notebook)
self.fm_controller.unload_tabs_and_windows()
self.generate_windows(session_json)
gc.collect()
def do_action_from_menu_controls(self, widget, eve = None):
if not isinstance(widget, str):
action = widget.get_name()
@ -166,7 +127,7 @@ class Controller(UI, SignalsMixins, Controller_Data):
if action == "create":
self.create_files()
if action in ["save_session", "save_session_as", "load_session"]:
self.save_load_session(action)
event_system.emit("save_load_session", (action))
if action == "about_page":
event_system.emit("show_about_page")

View File

@ -20,6 +20,8 @@ from plugins.plugins_controller import PluginsController
@dataclass(slots=True)
class State:
fm_controller: any = None
notebooks: any = None
wid: int = None
tid: int = None
tab: type = None
@ -28,7 +30,7 @@ class State:
selected_files: [] = None
to_copy_files: [] = None
to_cut_files: [] = None
warning_alert: type = None
message_dialog: type = None
class Controller_Data:
@ -108,11 +110,13 @@ class Controller_Data:
state (obj): State
'''
state = State()
state.fm_controller = self.fm_controller
state.notebooks = self.notebooks
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.icon_grid = self.builder.get_object(f"{state.wid}|{state.tid}|icon_grid")
state.store = state.icon_grid.get_model()
state.warning_alert = self.warning_alert
state.message_dialog = self.message_dialog
selected_files = state.icon_grid.get_selected_items()
if selected_files:
@ -153,6 +157,15 @@ class Controller_Data:
''' Checks if a given method exists. '''
return callable(getattr(obj, name, None))
def clear_notebooks(self) -> None:
self.ctrl_down = False
self.shift_down = False
self.alt_down = False
for notebook in self.notebooks:
self.clear_children(notebook)
def clear_children(self, widget: type) -> None:
''' Clear children of a gtk widget. '''
for child in widget.get_children():

View File

@ -13,7 +13,7 @@ from gi.repository import Gio
# Application imports
from widgets.io_widget import IOWidget
from ...ui.io_widget import IOWidget

View File

@ -13,9 +13,9 @@ from gi.repository import Gio
from gi.repository import GdkPixbuf
# Application imports
from widgets.tab_header_widget import TabHeaderWidget
from widgets.icon_grid_widget import IconGridWidget
from widgets.icon_tree_widget import IconTreeWidget
from ...ui.tab_header_widget import TabHeaderWidget
from ...ui.icon_grid_widget import IconGridWidget
from ...ui.icon_tree_widget import IconTreeWidget

View File

@ -0,0 +1,33 @@
# Python imports
# Lib imports
import inspect
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
class MessageWidget(Gtk.MessageDialog):
"""docstring for MessageWidget."""
def __init__(self):
super(MessageWidget, self).__init__()
self._setup_styling()
self._setup_signals()
self._load_widgets()
def _setup_styling(self):
...
def _setup_signals(self):
...
def _load_widgets(self):
...

View File

@ -0,0 +1,83 @@
# Python imports
import inspect
import gc
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
class SaveLoadWidget:
"""docstring for SaveLoadWidget."""
def __init__(self):
super(SaveLoadWidget, self).__init__()
_GLADE_FILE = f"{settings.get_ui_widgets_path()}/save_load_ui.glade"
builder = settings.get_builder()
self._builder = Gtk.Builder()
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_signals()
self._load_widgets()
def _setup_styling(self):
...
def _setup_signals(self):
event_system.subscribe("save_load_session", self.save_load_session)
def _load_widgets(self):
...
def save_load_session(self, action="save_session"):
state = event_system.emit_and_await("get_current_state")
if action == "save_session":
if not settings.is_trace_debug():
state.fm_controller.save_state()
return
elif action == "save_session_as":
self.save_load_dialog.set_action(Gtk.FileChooserAction.SAVE)
elif action == "load_session":
self.save_load_dialog.set_action(Gtk.FileChooserAction.OPEN)
else:
raise Exception(f"Unknown action given: {action}")
self.save_load_dialog.set_current_folder(state.tab.get_current_directory())
self.save_load_dialog.set_current_name("session.json")
response = self.save_load_dialog.run()
if response == Gtk.ResponseType.OK:
if action == "save_session_as":
path = f"{self.save_load_dialog.get_current_folder()}/{self.save_load_dialog.get_current_name()}"
state.fm_controller.save_state(path)
elif action == "load_session":
path = f"{self.save_load_dialog.get_file().get_path()}"
session_json = state.fm_controller.get_state_from_file(path)
self.load_session(session_json)
if (response == Gtk.ResponseType.CANCEL) or (response == Gtk.ResponseType.DELETE_EVENT):
...
self.save_load_dialog.hide()
def load_session(self, session_json):
if settings.is_debug():
logger.debug(f"Session Data: {session_json}")
state = event_system.emit_and_await("get_current_state")
event_system.emit("clear_notebooks")
state.fm_controller.unload_tabs_and_windows()
event_system.emit("generate_windows", (session_json,))
gc.collect()

View File

@ -22,7 +22,6 @@ class PathMenuPopupWidget(Gtk.Popover):
self._setup_styling()
self._setup_signals()
self._load_widgets()
self.show_all()
def _setup_styling(self):
@ -48,6 +47,7 @@ class PathMenuPopupWidget(Gtk.Popover):
self.builder.expose_object(f"path_menu_buttons", path_menu_buttons)
view_port.add(path_menu_buttons)
scroll_window.add(view_port)
scroll_window.show_all()
self.add(scroll_window)
def show_path_menu(self, widget=None, eve=None):

View File

@ -9,5 +9,5 @@ from .mixins.ui.window_mixin import WindowMixin
class UI(PaneMixin, WindowMixin):
class UIMixin(PaneMixin, WindowMixin):
...

View File

@ -32,66 +32,6 @@
<property name="can-focus">False</property>
<property name="stock">gtk-stop</property>
</object>
<object class="GtkFileChooserDialog" id="save_load_dialog">
<property name="can-focus">False</property>
<property name="type-hint">dialog</property>
<property name="do-overwrite-confirmation">True</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="button11">
<property name="label">gtk-cancel</property>
<property name="use-action-appearance">True</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="use-stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button12">
<property name="label">gtk-ok</property>
<property name="use-action-appearance">True</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="use-stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">button11</action-widget>
<action-widget response="-5">button12</action-widget>
</action-widgets>
</object>
<object class="GtkImage" id="tggl_notebook_1_img">
<property name="visible">True</property>
<property name="can-focus">False</property>
@ -901,79 +841,4 @@
</object>
</child>
</object>
<object class="GtkMessageDialog" id="warning_alert">
<property name="can-focus">False</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="window-position">center</property>
<property name="destroy-with-parent">True</property>
<property name="type-hint">dialog</property>
<property name="skip-taskbar-hint">True</property>
<property name="skip-pager-hint">True</property>
<property name="urgency-hint">True</property>
<property name="decorated">False</property>
<property name="deletable">False</property>
<property name="gravity">center</property>
<property name="message-type">warning</property>
<property name="text" translatable="yes">Warning!</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="margin-left">5</property>
<property name="margin-right">5</property>
<property name="margin-top">5</property>
<property name="margin-bottom">5</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="homogeneous">True</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="button4">
<property name="label">gtk-no</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="use-stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button3">
<property name="label">gtk-yes</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="has-focus">True</property>
<property name="receives-default">True</property>
<property name="use-stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-9">button4</action-widget>
<action-widget response="-8">button3</action-widget>
</action-widgets>
<style>
<class name="alert-border"/>
</style>
</object>
</interface>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<object class="GtkFileChooserDialog" id="save_load_dialog">
<property name="can-focus">False</property>
<property name="type-hint">dialog</property>
<property name="do-overwrite-confirmation">True</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="button11">
<property name="label">gtk-cancel</property>
<property name="use-action-appearance">True</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="use-stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button12">
<property name="label">gtk-ok</property>
<property name="use-action-appearance">True</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="use-stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">button11</action-widget>
<action-widget response="-5">button12</action-widget>
</action-widgets>
</object>
</interface>