From 2f6a78fc65d25bc2ac0daa374b587847004f836f Mon Sep 17 00:00:00 2001 From: aclist <92275929+aclist@users.noreply.github.com> Date: Thu, 23 Apr 2026 00:41:26 +0900 Subject: [PATCH] feat: wrap TreeModelFilter in TreeModelSort --- dzgui/api/servers.py | 2 +- dzgui/controllers/emitter.py | 4 ++++ dzgui/controllers/mc.py | 3 +++ dzgui/main.py | 1 + dzgui/views/base.py | 3 +++ dzgui/views/components/connect_panel.py | 2 +- dzgui/views/components/statusbar.py | 13 +++++++------ dzgui/views/mixins/help_menu_mixin.py | 3 ++- dzgui/views/pages/log.py | 2 ++ dzgui/views/trees/tree_log.py | 14 ++++++++------ 10 files changed, 32 insertions(+), 15 deletions(-) diff --git a/dzgui/api/servers.py b/dzgui/api/servers.py index 9c728da..5255e9f 100644 --- a/dzgui/api/servers.py +++ b/dzgui/api/servers.py @@ -216,7 +216,7 @@ def query_direct(ip: str, qport: int, TIMEOUT: float = 3.0) -> dict | None: res["ping"] = ping return res except Exception as e: - logger.critical(e) + logger.critical(f"{type(e).__name__}: {e}") return None diff --git a/dzgui/controllers/emitter.py b/dzgui/controllers/emitter.py index b344a92..58684e9 100644 --- a/dzgui/controllers/emitter.py +++ b/dzgui/controllers/emitter.py @@ -140,4 +140,8 @@ class Emitter(GObject.GObject): def keyword_set(self, keyword: str) -> None: pass + @GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=()) + def log_page_loaded(self) -> None: + pass + # TODO: if servers fail to load, may leave dangling widgets waiting for a signal diff --git a/dzgui/controllers/mc.py b/dzgui/controllers/mc.py index 23075fb..a413c22 100644 --- a/dzgui/controllers/mc.py +++ b/dzgui/controllers/mc.py @@ -554,6 +554,9 @@ class Controller(GObject.GObject): def get_notebook(self) -> "Notebook": return self.mediator.notebook + def get_prior_page(self) -> NotebookPage: + return self.mediator.notebook.get_prior_page() + def get_servers(self) -> "Notebook": return self.mediator.servers diff --git a/dzgui/main.py b/dzgui/main.py index 6d991dc..eb4000c 100644 --- a/dzgui/main.py +++ b/dzgui/main.py @@ -143,4 +143,5 @@ def main() -> None: use_miles, ) print("All OK. Loading UI...") + logger.critical("e") App(prefs) diff --git a/dzgui/views/base.py b/dzgui/views/base.py index e54c3e6..d165541 100644 --- a/dzgui/views/base.py +++ b/dzgui/views/base.py @@ -180,6 +180,9 @@ class Notebook(ScrollableMixin, Gtk.Notebook): # type: ignore return self.set_page_by_enum(self.prior_page) + def get_prior_page(self) -> NotebookPage: + return self.prior_page + def get_page_by_enum(self) -> NotebookPage | None: for k, v in self.indexes.items(): if v == self.get_current_page(): diff --git a/dzgui/views/components/connect_panel.py b/dzgui/views/components/connect_panel.py index a29f580..71e7fff 100644 --- a/dzgui/views/components/connect_panel.py +++ b/dzgui/views/components/connect_panel.py @@ -78,7 +78,7 @@ class LanPanel(Gtk.Frame): self.entry.set_sensitive(False) - def _on_lan_keypress(self, widget: Gtk.Entry, event: Gdk.EventKey) -> None: + def _on_lan_keypress(self, widget: Gtk.Entry, event: Gdk.EventKey) -> bool: if event.state & Gdk.ModifierType.CONTROL_MASK: if event.keyval == Gdk.KEY_d: self.default_radio.set_active(True) diff --git a/dzgui/views/components/statusbar.py b/dzgui/views/components/statusbar.py index 7b5682a..ceb1c14 100644 --- a/dzgui/views/components/statusbar.py +++ b/dzgui/views/components/statusbar.py @@ -36,11 +36,11 @@ class Statusbar(Gtk.Grid): warnings, errors = self.controller.get_alerts() if warnings + errors > 0: - alert_button = LoggerAlertsButton(warnings, errors) + self.alert_button = LoggerAlertsButton(warnings, errors) self.attach_next_to( - alert_button, self.spinner, Gtk.PositionType.RIGHT, 3, 1 + self.alert_button, self.spinner, Gtk.PositionType.RIGHT, 3, 1 ) - alert_button.connect("clicked", self._on_alerts_clicked) + self.alert_button.connect("clicked", self._on_alerts_clicked) # TODO: pack version event box in right panel into hbox with update button # TODO: spawns a modal or just jumps right to install page @@ -61,13 +61,14 @@ class Statusbar(Gtk.Grid): self.emitter.connect("distcalc_ended", self._on_distcalc_ended) self.emitter.connect("servers_loaded", self._on_servers_loaded) self.emitter.connect("mod_page_loaded", self._on_mod_page_loaded) + self.emitter.connect("log_page_loaded", self._on_log_page_loaded) def _on_alerts_clicked(self, button: LoggerAlertsButton) -> None: - button.hide() - # FIXME: hitting ESC from here goes to help list instead of main menu - # need some kind of flag self.controller.populate_log() + def _on_log_page_loaded(self, emitter: "Emitter") -> None: + self.alert_button.hide() + def _on_mod_page_loaded(self, emitter: "Emitter") -> None: msg = self.controller.format_mod_statusbar() self.set_by_context(NotebookPage.MODS, msg) diff --git a/dzgui/views/mixins/help_menu_mixin.py b/dzgui/views/mixins/help_menu_mixin.py index 9fa3225..3b2870e 100644 --- a/dzgui/views/mixins/help_menu_mixin.py +++ b/dzgui/views/mixins/help_menu_mixin.py @@ -13,5 +13,6 @@ class HelpMenuMixin: self, widget: Gtk.Widget, event: Gdk.EventKey ) -> Literal[True]: if event.keyval == Gdk.KEY_Escape: - self.controller.open_page(NotebookPage.HELP) # type: ignore + prior = self.controller.get_prior_page() + self.controller.open_page(prior) # type: ignore return True diff --git a/dzgui/views/pages/log.py b/dzgui/views/pages/log.py index f1c48e1..2400b2f 100644 --- a/dzgui/views/pages/log.py +++ b/dzgui/views/pages/log.py @@ -39,8 +39,10 @@ class Log(CursorMixin, HelpMenuMixin, Gtk.Box): # type: ignore self.controller = controller self.controller.register_widget("logtreeview", self.treeview) + self.emitter = controller.get_emitter() self.connect("key-press-event", self._on_esc_keypress) + self.connect("map", lambda _: self.emitter.emit("log_page_loaded")) def _on_checkbox_clicked(self, checkbox: Gtk.CheckButton) -> None: label = checkbox.get_label() diff --git a/dzgui/views/trees/tree_log.py b/dzgui/views/trees/tree_log.py index 34e64a6..123e925 100644 --- a/dzgui/views/trees/tree_log.py +++ b/dzgui/views/trees/tree_log.py @@ -32,7 +32,7 @@ class LogTreeView(ContextMixin, TreeView): self.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) self.set_model(None) - self.filter: Gtk.TreeModelFilter + # self.filter: Gtk.TreeModelFilter # TODO: strings # NOTE: default filters that should be shown on startup @@ -52,10 +52,11 @@ class LogTreeView(ContextMixin, TreeView): def populate_log(self, filepath: str) -> None: model = ModelFactory().new_model_from_logfile(filepath) - self.filter = model.filter_new() - self.filter.set_visible_func(self._filter_rows) - self.set_model(self.filter) - self.filter.refilter() + _filter = model.filter_new() + _filter.set_visible_func(self._filter_rows) + sortable = Gtk.TreeModelSort(_filter) + self.set_model(sortable) + _filter.refilter() self.set_cursor(0) def toggle_filter(self, _filter: str) -> None: @@ -63,7 +64,8 @@ class LogTreeView(ContextMixin, TreeView): self.filters.remove(_filter) else: self.filters.append(_filter) - self.filter.refilter() + # NOTE: unwrap TreeModelSort and TreeModelFilter + self.get_model().get_model().refilter() def _filter_rows( self, model: Gtk.ListStore, _iter: Gtk.TreeIter, data: Any