chore: rename to ProxyModelManager

This commit is contained in:
aclist 2026-02-23 21:53:20 +09:00
parent fd9a23c6d6
commit 0283baf3a9
7 changed files with 82 additions and 66 deletions

View File

@ -41,7 +41,7 @@ from dzgui.config.userprefs import UserPrefs
from dzgui.controllers.emitter import Emitter
from dzgui.managers.config import ConfigManager
from dzgui.managers.contextmenu import ContextMenuManager
from dzgui.model.filtered_model import FilteredModelManager
from dzgui.model.proxy_model import ProxyModelManager
from dzgui.model.servers import ServerModelManager
from dzgui.model.model_factory import ModelFactory
from dzgui.util import strings
@ -585,20 +585,20 @@ class Controller(GObject.GObject):
def get_player_count(self) -> str:
treeview = self.get_active_treeview()
model = treeview.get_model()
filter_man = treeview.get_filter_man()
control_model = filter_man.get_control()
proxy_man = treeview.get_proxy_man()
control_model = proxy_man.get_control()
count = format_player_count(model, control_model)
return count
def get_statusbar(self) -> None:
return self.mediator.statusbar
def get_filter_man(self) -> "FilteredModelManager":
return self.filter_man
def get_proxy_man(self) -> "ProxyModelManager":
return self.proxy_man
def set_filter_man(self, filter_man: "FilteredModelManager") -> None:
# TODO: used when staging filter man outside of thread
self.filter_man = filter_man
# def set_proxy_man(self, proxy_man: "ProxyModelManager") -> None:
# # TODO: used when staging filter man outside of thread
# self.proxy_man = proxy_man
def populate_model(self, tv: Gtk.TreeView) -> None:
# NOTE: skip on previously loaded tabs
@ -624,8 +624,8 @@ class Controller(GObject.GObject):
# TODO: filterman calls back to here, gets convoluted
def get_keyword(self) -> str:
tv = self.get_active_treeview()
filter_man = tv.get_filter_man()
return filter_man.get_keyword_filter()
proxy_man = tv.get_proxy_man()
return proxy_man.get_keyword_filter()
def get_map_store(self) -> Gtk.ListStore:
map_man = self.get_map_man()
@ -677,7 +677,7 @@ class Controller(GObject.GObject):
map_man = self.get_map_man()
map_man.set_selected_map(selection)
# FIXME: label should not be mandatory
ServerModelManager(self, self.get_active_treeview()).refilter(FilterMode.MAP)
ServerModelManager(self, self.get_active_treeview()).refilter(FilterMode.MAP, selection)
def get_notebook(self) -> "Notebook":
return self.mediator.notebook

View File

@ -1,6 +1,7 @@
import inspect
import logging
import threading
from typing import Any
from functools import wraps
from typing import Callable, Optional

View File

@ -1,18 +1,18 @@
import gi
from typing import TYPE_CHECKING
from dzgui.model.model_factory import ModelFactory
from dzgui.util import strings
from dzgui.util.strings import all_maps
gi.require_version("Gtk", "3.0")
from gi.repository.Gtk import ListStore # noqa E402
from gi.repository import Gtk # noqa E402
if TYPE_CHECKING:
from dzgui.model.model_factory import FastInsertListStore
# TODO: rename class to MetaManager
class MapManager:
def __init__(self) -> None:
self.map_store = ListStore(str)
self.map_store = ModelFactory().make_map_store()
self.prior_map: str
self.selected_map = all_maps
@ -54,11 +54,11 @@ class MapManager:
def set_filter(self, label: str, state: bool) -> None:
self.enabled_filters[label] = state
def get_map_store(self) -> ListStore:
def get_map_store(self) -> "FastInsertListStore":
return self.map_store
def reinit_map_store(self) -> None:
model = ListStore(str)
model = ModelFactory().make_map_store()
model.append([all_maps])
self.map_store = model
self.selected_map = all_maps
@ -88,3 +88,7 @@ class MapManager:
self.reinit_map_store()
for m in maps:
self.append_map([m])
# when switching views, just grab the map store, active keyword, active map, and selected checks
# for that view and apply them to filter panel outside of thread
# initialize proxyman with access to filterman

View File

@ -17,13 +17,13 @@ if TYPE_CHECKING:
from dzgui.controllers.emitter import Emitter
class FilteredModelManager:
class ProxyModelManager:
"""
Manages access to cached ListStore resources and
performs filtering on behalf of atomic TreeViews,
which share the same column structure.
A FilteredModelManager is attached to each ServerTreeView.
A ProxyModelManager is attached to each ServerTreeView.
Raw data is cached before being packed into a ListStore, see get_control()
Filtration creates a proxy of the TreeView's model, see get_proxy_model()
@ -282,3 +282,9 @@ class FilteredModelManager:
self.ping_cache = {}
# if full:
# self.control_model = None
def set_active_map(self, _map: str) -> None:
self.active_map = _map
def get_active_map(self) -> str:
return self.active_map

View File

@ -24,7 +24,7 @@ API_TIMEOUT = 3
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
from dzgui.model.filtered_model import FilteredModelManager
from dzgui.model.proxy_model import ProxyModelManager
logger = logging.getLogger(__name__)
@ -46,7 +46,7 @@ class ServerModelManager:
self.jobs = 1
# NOTE: store filter man for access inside thread
self.filter_man = tv.get_filter_man()
self.proxy_man = tv.get_proxy_man()
# FIXME: change WaitDialog to use parent window only
self.thread_man = ThreadingManager(parent=controller)
@ -195,8 +195,8 @@ class ServerModelManager:
record = Servers.parse_json([res])
filter_man = self._get_filter_man()
raw_model = filter_man.get_control()
proxy_man = self._get_proxy_man()
raw_model = proxy_man.get_control()
fqip = Servers.response_to_fq_ip(res)
config_man = self.controller.get_config_man()
@ -209,7 +209,7 @@ class ServerModelManager:
raw_model.append(record[0])
# TODO: if all filters are already applied, strange behavior may occur
# -> need to insert and update per current filters
filter_man.filter(FilterMode.INITIAL)
proxy_man.filter(FilterMode.INITIAL)
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_single_ip))
@ -249,7 +249,7 @@ class ServerModelManager:
self._dump_ips(ips)
def _cleanup_single_ip(self) -> None:
proxy = self._get_filter_man().get_proxy_model()
proxy = self._get_proxy_man().get_proxy_model()
self.tv.set_model(proxy)
# TODO: if current tab != self.saved, add label
@ -307,7 +307,7 @@ class ServerModelManager:
# FIXME: filterman calls GTK methods in thread
# if mode == FilterMode.INITIAL:
manager = self._get_filter_man()
manager = self._get_proxy_man()
manager.wipe_cache()
manager.set_control(data)
manager.filter(FilterMode.INITIAL)
@ -324,13 +324,13 @@ class ServerModelManager:
def _get_new_maps(self) -> list[str]:
return self.new_maps
def _get_filter_man(self) -> "FilteredModelManager":
return self.filter_man
def _get_proxy_man(self) -> "ProxyModelManager":
return self.proxy_man
@call_on_thread(dialog.filtering)
def refilter(self, mode: FilterMode, label: str) -> None:
self.first_iteration = False
filter_man = self._get_filter_man()
filter_man.filter(mode, label)
self.to_insert = filter_man.get_proxy_model()
proxy_man = self._get_proxy_man()
proxy_man.filter(mode, label)
self.to_insert = proxy_man.get_proxy_model()
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_success))

View File

@ -4,7 +4,6 @@ from typing import Literal, TYPE_CHECKING
from dzgui.const.enum import FilterMode
from dzgui.const.constants import EXPAND, NO_EXPAND, NO_FILL, NO_PADDING, SEARCH_ICON
from dzgui.model.servers import ServerModelManager
from dzgui.util.margins import set_surrounding_margins
from dzgui.views.components.labels import BoldLabel
import gi
@ -128,12 +127,24 @@ class KeywordEntry(Gtk.Entry):
class FilterPanel(Gtk.Box):
def __init__(self, controller: "Controller") -> None:
super().__init__(spacing=6, vexpand=False, orientation=Gtk.Orientation.VERTICAL)
super().__init__(
spacing=6,
vexpand=False,
orientation=Gtk.Orientation.VERTICAL,
margin_top=1,
margin_bottom=10,
margin_left=10,
margin_right=10,
)
self.controller = controller
self.controller.register_widget("filters", self)
self.emitter = self.controller.get_emitter()
# TODO: strings
self.sel_map = "All maps"
# TODO: each treeview for that tab context has its own filter manager, independent of this
# self.selected_map: str = strings.all_maps
# self.prior_map: str = strings.all_maps
# self.set_orientation(Gtk.Orientation.VERTICAL)
@ -147,11 +158,6 @@ class FilterPanel(Gtk.Box):
self.keyword_entry = KeywordEntry(self.controller)
self.button_grid = ButtonGrid(self.controller, defaults)
# TODO: unintended legacy behavior?
self.connect("button-release-event", lambda *args: True)
set_surrounding_margins(self, 10)
self.set_margin_top(1)
# TODO: strings
self.filters_label = BoldLabel("Filters")
@ -201,11 +207,13 @@ class FilterPanel(Gtk.Box):
model = self.maps_combo.get_model()
if text is None:
return
if text == self.sel_map:
return
for i, row in enumerate(model):
if text == row[0]:
self.maps_combo.set_active(i)
self._on_map_changed(self.maps_combo)
self.controller.set_active_map(i)
# self.controller.set_active_map(i)
# print("HERE3")
def _on_maps_loaded(self, emitter: "Emitter", store: Gtk.ListStore) -> None:
self.maps_combo.set_model(store)
@ -272,8 +280,8 @@ class FilterPanel(Gtk.Box):
store = self.controller.get_map_store()
if len(text) >= completion.get_minimum_key_length():
completion.set_model(store)
ind = self.get_active_combo()
self.controller.set_active_map(ind)
# ind = self.get_active_combo()
# self.controller.set_active_map(ind)
def restore_focus_to_treeview(self) -> Literal[False]:
view = self.controller.get_active_treeview()
@ -282,17 +290,17 @@ class FilterPanel(Gtk.Box):
def _on_combo_keypress(self, combo: Gtk.ComboBox, event: Gdk.EventKey) -> bool:
match event.keyval:
case Gdk.KEY_Down:
case Gdk.KEY_Down | Gdk.KEY_Up:
self.maps_combo.popup()
return True
case _:
return False
def get_active_combo(self) -> int:
return self.maps_combo.get_active()
def set_active_combo(self, row: int) -> None:
self.maps_combo.set_active(row)
# def get_active_combo(self) -> int:
# return self.maps_combo.get_active()
#
# def set_active_combo(self, row: int) -> None:
# self.maps_combo.set_active(row)
def toggle_check_by_key(self, emitter: "Emitter", keyval: int) -> bool:
mappings = {
@ -322,16 +330,13 @@ class FilterPanel(Gtk.Box):
check.set_active(not state)
def _on_map_changed(self, combo: Gtk.ComboBox) -> None:
old_sel = self.controller.get_selected_map()
model = combo.get_model()
tree_iter = combo.get_active_iter()
if tree_iter is None:
ind = combo.get_active()
if ind < 0:
return
selection = model[tree_iter][0]
if selection == old_sel:
return
if not selection:
return
self.maps_entry.set_text(selection)
logger.info(f"User selected map '{selection}'")
selection = self.maps_entry.get_text()
self.sel_map = selection
self.emitter.emit("map_selection_changed", selection)
tv = self.controller.get_active_treeview()
proxy_man = tv.get_proxy_man()
proxy_man.set_active_map(selection)

View File

@ -9,7 +9,7 @@ from dzgui.views.mixins.context_mixin import ContextMixin
from dzgui.const.enum import ContextMenu, ContextMenuGroup, ServerTab
from dzgui.api.servers import Record
from dzgui.model.map_model import MapManager
from dzgui.model.filtered_model import FilteredModelManager
from dzgui.model.proxy_model import ProxyModelManager
from dzgui.util.dist import CalcDist
from dzgui.util import strings
from typing import Literal, TYPE_CHECKING
@ -45,8 +45,8 @@ class ServerTreeView(ContextMixin, TreeView):
self.loaded = False
self.filter_man = FilteredModelManager(controller)
model = self.filter_man.get_proxy_model()
self.proxy_man = ProxyModelManager(controller)
model = self.proxy_man.get_proxy_model()
self.set_model(model)
# NOTE: each tab context has its own unique maps
@ -132,8 +132,8 @@ class ServerTreeView(ContextMixin, TreeView):
def get_map_man(self) -> MapManager:
return self.map_man
def get_filter_man(self) -> FilteredModelManager:
return self.filter_man
def get_proxy_man(self) -> ProxyModelManager:
return self.proxy_man
# def shrink_to_fit(self) -> None:
# cols = self.get_columns()
@ -372,6 +372,6 @@ class ServerTreeView(ContextMixin, TreeView):
return
if row_index >= start[0] <= end[0]:
# NOTE: fetch raw data rows
real_model = self.filter_man.get_control()
real_model = self.proxy_man.get_control()
value = real_model[row_index][col_index]
cell.set_property("text", str(value))