From da8722ec2aa135859a345d6895f654d01604b464 Mon Sep 17 00:00:00 2001 From: aclist <92275929+aclist@users.noreply.github.com> Date: Sun, 25 Jan 2026 10:14:51 +0900 Subject: [PATCH] feat: filtered model WIP --- dzgui/controllers/mc.py | 21 ++++++++------- dzgui/model/filtered_model.py | 36 ++++++++++++-------------- dzgui/views/components/filter_panel.py | 28 ++++++++------------ dzgui/views/pages/servers.py | 2 +- 4 files changed, 41 insertions(+), 46 deletions(-) diff --git a/dzgui/controllers/mc.py b/dzgui/controllers/mc.py index 9191cdb..90064ac 100644 --- a/dzgui/controllers/mc.py +++ b/dzgui/controllers/mc.py @@ -22,7 +22,7 @@ from dzgui.api.mods import ( _hash, remove_stale_signatures, ) -from dzgui.const.enum import Preferences, NotebookPage, ButtonType, ContextMenu +from dzgui.const.enum import FilterMode, Preferences, NotebookPage, ButtonType, ContextMenu from dzgui.const.constants import ( APPID_DAYZ, @@ -615,9 +615,12 @@ class Controller(GObject.GObject): insert = None else: manager = treeview.get_filter_man() - for row in data: - manager.append_row(row) + manager.set_control(data) + manager.filter(FilterMode.INITIAL) + #for row in data: + # manager.append_row(row) insert = manager.get_model() + print(insert) treeview.set_model(insert) treeview.set_loaded(True) GLib.idle_add(cleanup) @@ -740,12 +743,12 @@ class Controller(GObject.GObject): if func is None: self.mediator.statusbar.emit("server_page_changed", treeview.get_enum()) return + # TODO: on legacy version, model clearing happens in thread treeview.set_model(None) manager = treeview.get_filter_man() - manager.clear_model() + # manager.clear_model() self.set_callback(None, None) self.thread_data_func(func) - #self.call_on_thread(func) def focus_button_box(self) -> None: self.mediator.right_panel.focus_button_box() @@ -787,13 +790,13 @@ class Controller(GObject.GObject): # TODO: use model manager, map and keyword caches def get_filters(self) -> list: - self.mediator.filters.get_filters() + return self.mediator.filters.get_filters() def get_keyword(self) -> str: - self.mediator.filters.get_keyword_filter() + return self.mediator.filters.get_keyword_filter() def get_map(self) -> str: - self.mediator.filters.get_selected_map() + return self.mediator.filters.get_selected_map() def get_prior_map(self) -> str: - self.mediator.filters.get_prior_map() + return self.mediator.filters.get_prior_map() diff --git a/dzgui/model/filtered_model.py b/dzgui/model/filtered_model.py index 10c4e88..8825aa0 100644 --- a/dzgui/model/filtered_model.py +++ b/dzgui/model/filtered_model.py @@ -42,29 +42,25 @@ class FilteredModelManager: """ def __init__(self, controller: "Controller") -> None: - self.filter_cache: tuple + self.controller = controller + + self.filter_cache = {} self.ping_cache: dict[str, int] = {} - self.model = self.new_model_from_class(ServerColumns) - self.real_model = self.new_model_from_class(ServerColumns) + self.ephemeral_model = self.new_model_from_class(ServerColumns) self.control_model = None self.filtered = None self.success = True def append_row(self, row: list) -> None: - # self.real_model.append(row) - # NOTE: append null rows to thin client - self.model.append(row) + self.ephemeral_model.append(row) def clear_model(self) -> None: - self.model.clear() - - def get_real_model(self) -> ListStore: - return self.real_model + self.ephemeral_model.clear() def get_model(self) -> ListStore: - return self.model + return self.ephemeral_model def new_model_from_class(self, cls: type) -> ListStore: store = ListStore(*[ftype for field, ftype in cls.__annotations__.items()]) @@ -79,7 +75,7 @@ class FilteredModelManager: if filters in self.filter_cache: cache = self.filter_cache[filters] - self.set_store(cache[0]) + self.set_model(cache[0]) self.set_filtered(cache[1]) GLib.idle_add( self.controller.mediator.get_active_treeview()._filter_cleanup @@ -123,8 +119,7 @@ class FilteredModelManager: clone = None self.set_cache(filters, clone, rows) - self.set_store(clone) - GLib.idle_add(self.controller.mediator.get_active_treeview()._filter_cleanup) + self.set_model(clone) def sort_rows(self, rows: list) -> list: rows.sort(key=lambda x: re.sub(r"[^A-Za-z0-9]+", "", x[0].lower())) @@ -261,13 +256,16 @@ class FilteredModelManager: def get_filtered(self) -> list: return self.filtered - def set_store(self, model: ListStore | None) -> None: - self.store = model - - def get_store(self) -> ListStore | None: - return self.store + def set_model(self, model: ListStore | None) -> None: + """ + ListStore representation of the model + """ + self.ephemeral_model = model def set_control(self, rows: list) -> None: + """ + Raw representation of the model, no transformations + """ self.control_model = rows def set_success(self, result: bool) -> None: diff --git a/dzgui/views/components/filter_panel.py b/dzgui/views/components/filter_panel.py index 60b381a..e5d87df 100644 --- a/dzgui/views/components/filter_panel.py +++ b/dzgui/views/components/filter_panel.py @@ -1,18 +1,20 @@ import logging from typing import Literal -import gi # noqa E402 -gi.require_version("Gtk", "3.0") -from gi.repository import Gtk, Gdk, Pango, GLib - from dzgui.const.enum import FilterMode from dzgui.const.constants import NO_EXPAND, NO_FILL, NO_PADDING from dzgui.util import strings from dzgui.util.margins import set_surrounding_margins from dzgui.views.components.labels import BoldLabel +import gi + +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk, Gdk, Pango, GLib # noqa E402 + logger = logging.getLogger(__name__) + class FilterPanel(Gtk.Box): def __init__(self, controller): super().__init__(spacing=6, vexpand=False) @@ -41,7 +43,7 @@ class FilterPanel(Gtk.Box): self.maps_hr = [] self.enabled_filters = dict(self.default_filters) - self.keyword_filter: str + self.keyword_filter = "" self.selected_map: str = strings.all_maps self.prior_map: str = strings.all_maps @@ -79,9 +81,7 @@ class FilterPanel(Gtk.Box): self.keyword_entry = Gtk.Entry() self.keyword_entry.set_placeholder_text("Filter by keyword") self.keyword_entry.connect("activate", self._on_keyword_enter) - self.keyword_entry.connect( - "key-press-event", self._on_keyword_keypress - ) + self.keyword_entry.connect("key-press-event", self._on_keyword_keypress) completion = Gtk.EntryCompletion(inline_completion=True) completion.set_text_column(0) @@ -142,9 +142,7 @@ class FilterPanel(Gtk.Box): state = self.default_filters[label] check.set_active(state) - def _on_map_entry_keypress( - self, entry: Gtk.Entry, event: Gdk.EventKey - ) -> None: + def _on_map_entry_keypress(self, entry: Gtk.Entry, event: Gdk.EventKey) -> None: match event.keyval: case Gdk.KEY_Return: text = entry.get_text() @@ -189,9 +187,7 @@ class FilterPanel(Gtk.Box): view.grab_focus() return False - def _on_keyword_keypress( - self, entry: Gtk.Entry, event: Gdk.EventKey - ) -> bool: + def _on_keyword_keypress(self, entry: Gtk.Entry, event: Gdk.EventKey) -> bool: match event.keyval: case Gdk.KEY_Up: return True @@ -202,9 +198,7 @@ class FilterPanel(Gtk.Box): return True return False - def _on_combo_keypress( - self, combo: Gtk.ComboBox, event: Gdk.EventKey - ) -> bool: + def _on_combo_keypress(self, combo: Gtk.ComboBox, event: Gdk.EventKey) -> bool: match event.keyval: case Gdk.KEY_Down: self.maps_combo.popup() diff --git a/dzgui/views/pages/servers.py b/dzgui/views/pages/servers.py index b55b2c5..55589e9 100644 --- a/dzgui/views/pages/servers.py +++ b/dzgui/views/pages/servers.py @@ -35,7 +35,7 @@ class ServerNotebook(Gtk.ScrolledWindow): self.lan = ServerTreeView(controller, ServerTab.LAN, ContextMenuGroup.SCAN_LAN) self.lan.set_query_func(self.controller.dump_test_2) - self.browser.set_query_func(self.controller.dump_test_2) + self.browser.set_query_func(self.controller.dump_api) tabs = [ (self.browser, server_labels.browser),