From 575e591c1020f54809bf963f32e34fa5640f4d7a Mon Sep 17 00:00:00 2001 From: aclist <92275929+aclist@users.noreply.github.com> Date: Mon, 23 Feb 2026 02:24:14 +0900 Subject: [PATCH] feat: restore partial context menu functionality --- dzgui/api/bm.py | 7 +++-- dzgui/api/servers.py | 8 +++--- dzgui/controllers/mc.py | 4 +-- dzgui/managers/connection.py | 6 ++--- dzgui/managers/contextmenu.py | 11 ++++++++ dzgui/model/servers.py | 2 +- dzgui/views/components/connect_panel.py | 2 +- dzgui/views/mixins/context_mixin.py | 11 ++++++-- dzgui/views/trees/tree_log.py | 14 +++++++++- dzgui/views/trees/tree_servers.py | 36 ++++++++++++++----------- 10 files changed, 68 insertions(+), 33 deletions(-) diff --git a/dzgui/api/bm.py b/dzgui/api/bm.py index c8c85db..196583b 100644 --- a/dzgui/api/bm.py +++ b/dzgui/api/bm.py @@ -13,10 +13,9 @@ if TYPE_CHECKING: from dzgui.api.servers import Record -def get_attributes(config: Path, uid: int) -> str: +def get_attributes(key: str, uid: int) -> str: # TODO: handle if key is not set # TODO: tests for malformed IDs/values - key = lookup(config, Preferences.BM) hdr = {"Authorization": "Bearer " + key} payload: dict[str, str] = { @@ -30,11 +29,11 @@ def get_attributes(config: Path, uid: int) -> str: return j -def map_id_to_record(config: Path, uid: int) -> Optional["Record"]: +def map_id_to_record(key: str, uid: int) -> Optional["Record"]: from dzgui.api.servers import Record try: - record = get_attributes(config, uid) + record = get_attributes(key, uid) ip = record["ip"] port = record["port"] qport = record["portQuery"] diff --git a/dzgui/api/servers.py b/dzgui/api/servers.py index c77c5f0..50b2dd6 100644 --- a/dzgui/api/servers.py +++ b/dzgui/api/servers.py @@ -461,18 +461,18 @@ def response_to_fq_ip(res: dict) -> str: return f"{ip}:{gameport}:{qport}" -def query_id_or_ip(addr: str) -> None: +def query_id_or_ip(addr: str, key: str) -> None: # NOTE: Battlemetrics if addr.isdigit(): try: - config = self.controller.get_prefs().paths.config - resolved = map_id_to_record(config, addr) + resolved = map_id_to_record(key, addr) res = query_direct(resolved.ip, resolved.qport) except Exception as e: logger.critical(e) return None else: record = addr.split(":") - ip, qport = record[0], record[1] + # TODO: create a Record object + ip, qport = record[0], record[2] res = query_direct(ip, int(qport)) return res diff --git a/dzgui/controllers/mc.py b/dzgui/controllers/mc.py index a13cc4d..9eb54c8 100644 --- a/dzgui/controllers/mc.py +++ b/dzgui/controllers/mc.py @@ -605,8 +605,8 @@ class Controller(GObject.GObject): record = treeview.get_record_string() try: - self.update_config(Preferences.FAV_LBL, name) - self.update_config(Preferences.FAV_SRV, record) + self.config_man.write_config(Preferences.FAV_LBL, name) + self.config_man.write_config(Preferences.FAV_SRV, record) except Exception as e: logger.critical(e) # TODO: add a failure dialog here diff --git a/dzgui/managers/connection.py b/dzgui/managers/connection.py index f4d9772..5787375 100644 --- a/dzgui/managers/connection.py +++ b/dzgui/managers/connection.py @@ -22,12 +22,12 @@ class ConnectionManager: self.thread_man = ThreadingManager(parent=controller) @call_on_thread(dialog.querying) - def _connect_by_id_or_ip(self, addr: str) -> None: - res = Servers.query_id_or_ip(addr) + def connect_by_id_or_ip(self, addr: str, key: str) -> None: + res = Servers.query_id_or_ip(addr, key) + print(res) if res is None: self.thread_man.set_cleanup_func(StoredFunc(self._connection_failure)) # TODO: add to history if successful - print(res) def _connection_failure(self) -> None: # TODO: more explicit warning message, not necessarily API failure? diff --git a/dzgui/managers/contextmenu.py b/dzgui/managers/contextmenu.py index be279c1..7b074fe 100644 --- a/dzgui/managers/contextmenu.py +++ b/dzgui/managers/contextmenu.py @@ -3,7 +3,9 @@ import logging from typing import TYPE_CHECKING from dzgui.const.enum import ContextMenu, Preferences +from dzgui.managers.connection import ConnectionManager from dzgui.managers.thread_man import ThreadingManager +from dzgui.model.servers import ServerModelManager from dzgui.util import strings from dzgui.util.clip import copy_clipboard from dzgui.util.open_links import open_workshop_page @@ -50,7 +52,16 @@ class ContextMenuManager: self.controller.set_fav() # THREADED + case ContextMenu.CONNECT: + record = self.treeview.get_record_string() + # FIXME: context menu connections do not require BM key + key = self.controller.get_config_man().lookup(Preferences.BM) + ConnectionManager(self.controller).connect_by_id_or_ip(record, key) case ContextMenu.ADD_SERVER: + record = self.treeview.get_record_string() + ServerModelManager(self.controller, self.treeview).add_by_id_or_ip( + record + ) # add to saved servers model verbatim and sort in place # update tab with ! # update config file with IP diff --git a/dzgui/model/servers.py b/dzgui/model/servers.py index 87a8bdf..8640dc6 100644 --- a/dzgui/model/servers.py +++ b/dzgui/model/servers.py @@ -182,7 +182,7 @@ class ServerModelManager: self._push_data(parsed, FilterMode.INITIAL) @call_on_thread(dialog.querying) - def _add_by_id_or_ip(self, addr: str) -> None: + def add_by_id_or_ip(self, addr: str) -> None: res = Servers.query_id_or_ip(addr) if res is None: self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_failure)) diff --git a/dzgui/views/components/connect_panel.py b/dzgui/views/components/connect_panel.py index 117c442..18f31c7 100644 --- a/dzgui/views/components/connect_panel.py +++ b/dzgui/views/components/connect_panel.py @@ -203,7 +203,7 @@ class AddPanel(Gtk.Frame): def _on_connect_clicked(self, button: Gtk.Button) -> None: text = self.entry.get_text() - ConnectionManager(self.controller)._connect_by_id_or_ip(text) + ConnectionManager(self.controller).connect_by_id_or_ip(text) def _submit_query(self) -> None: text = self.entry.get_text() diff --git a/dzgui/views/mixins/context_mixin.py b/dzgui/views/mixins/context_mixin.py index 85fae0a..e673049 100644 --- a/dzgui/views/mixins/context_mixin.py +++ b/dzgui/views/mixins/context_mixin.py @@ -19,7 +19,6 @@ class ContextMixin(TreeView): event: Gdk.EventButton | Gdk.EventKey, ) -> None: - # FIXME: start debug log focused if self.is_selection_empty(): return False @@ -80,7 +79,15 @@ class ContextMixin(TreeView): (path, col, cellx, celly) = pathinfo if path is None: return True - self.set_cursor(path, col, False) + # return True + selection = self.get_selection() + model, selected_paths = selection.get_selected_rows() + if path not in selected_paths: + for p in selected_paths: + selection.unselect_path(p) + self.set_cursor(path, col, False) + return True + # FIXME: if selection is not multiple, change cursor except AttributeError: pass diff --git a/dzgui/views/trees/tree_log.py b/dzgui/views/trees/tree_log.py index 1824558..026db11 100644 --- a/dzgui/views/trees/tree_log.py +++ b/dzgui/views/trees/tree_log.py @@ -40,13 +40,25 @@ class LogTreeView(ContextMixin, TreeView): column.set_sort_column_id(i) self.append_column(column) + self.connect("button-press-event", self._on_log_buttonpress) self.connect("key-press-event", self._on_log_keypress) - self.connect("button-press-event", self._on_log_keypress) def populate_log(self, filepath: str) -> None: model = ModelFactory().new_model_from_logfile(filepath) self.set_model(model) self.set_cursor(0) + def _on_log_buttonpress(self, widget: Gtk.Widget, event: Gdk.EventButton) -> None: + if event.button == Gdk.BUTTON_SECONDARY: + path, col, x, y = self.get_path_at_pos(int(event.x), int(event.y)) + if path: + selection = self.get_selection() + model, selected_paths = selection.get_selected_rows() + if path not in selected_paths: + selection.select_path(path) + self.present_menu(widget, event) + return True + return False + def _on_log_keypress(self, widget: Gtk.Widget, event: Gdk.EventKey) -> None: self.present_menu(widget, event) diff --git a/dzgui/views/trees/tree_servers.py b/dzgui/views/trees/tree_servers.py index 228acff..cf363c3 100644 --- a/dzgui/views/trees/tree_servers.py +++ b/dzgui/views/trees/tree_servers.py @@ -256,22 +256,28 @@ class ServerTreeView(ContextMixin, TreeView): self.emitter.emit("check_button_pressed", event.keyval) # TODO: unimplemented - # def is_modded(self) -> bool: - # select = self.get_selection() - # sels = select.get_selected_rows() - # (model, pathlist) = sels - # path = pathlist[0] - # tree_iter = model.get_iter(path) - # mods = model.get_value(tree_iter, 11) - # return mods + def is_modded(self) -> bool: + select = self.get_selection() + sels = select.get_selected_rows() + (model, pathlist) = sels + path = pathlist[0] + tree_iter = model.get_iter(path) + has_mods = model.get_value(tree_iter, 11) + return has_mods - # TODO: unimplemented - # def is_in_favs(self) -> bool: - # record = self.get_record_string() - # proc = call_out("is_in_favs", record) - # if proc.returncode == 0: - # return True - # return False + def get_selected_row(self) -> Gtk.TreeModelRow: + sel = self.get_selection() + sels = sel.get_selected_rows() + return sels[0] + + def is_in_favs(self) -> bool: + from dzgui.const.enum import Preferences + + record = self.get_record_string() + ips = self.controller.get_config_man().lookup(Preferences.IP_LIST) + if record in ips: + return True + return False def _parent_row_activated( self, tree: TreeView, path: Gtk.TreePath, column: Gtk.TreeViewColumn