diff --git a/CHANGELOG.md b/CHANGELOG.md index e51e053..197922c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,3 +44,9 @@ - Local documentation - Offline mods - Move debug mode to developers only + +## Devs +- Show deprecation warnings +- Options -> Dev page +- Raw debug command +- Moved debug log to this mode diff --git a/dzgui/controllers/mc.py b/dzgui/controllers/mc.py index d205a03..f9fdfe8 100644 --- a/dzgui/controllers/mc.py +++ b/dzgui/controllers/mc.py @@ -262,7 +262,7 @@ class Controller(GObject.GObject): c = self.mediator.statusbar.statusbar.get_context_id(context) self.mediator.statusbar.statusbar.pop(c) - # TODO: + # TODO: refactor any modules using this @deprecated("use set_by_context") def set_statusbar(self, text: str, context: str) -> int: msg_id = self.mediator.statusbar.set_text(text, context) @@ -297,7 +297,6 @@ class Controller(GObject.GObject): self.emitter.emit("distcalc_ended", dist, context) - # TODO: threading def delete_multiple_mods(self) -> None: sel = self.mediator.modtreeview.get_selection() model, pathlist = sel.get_selected_rows() @@ -392,11 +391,11 @@ class Controller(GObject.GObject): total = 10 with ThreadPoolExecutor() as executor: futures = [executor.submit(job, key, APPID_DAYZ, param) for param in params] - #wait(futures) + # wait(futures) for future in as_completed(futures): try: i += 1 - GLib.idle_add(lambda: self.wait_dialog.prog.set_fraction(i/total)) + GLib.idle_add(lambda: self.wait_dialog.prog.set_fraction(i / total)) res = future.result(timeout=3) if res.status != 200 or not res.parsed: # TODO: pop warning dialog, create enum around various failure states @@ -410,7 +409,6 @@ class Controller(GObject.GObject): print(e) self.cleanup_func = CleanupFunc(self.cleanup_on_failure) - """ TODO: e.g. class method like 'total' total of 10 params for this call @@ -429,7 +427,7 @@ class Controller(GObject.GObject): GLib.idle_add( lambda: self.wait_dialog.format_secondary_text("Unpacking servers") ) - GLib.idle_add(lambda: self.wait_dialog.prog.set_fraction(10/total)) + GLib.idle_add(lambda: self.wait_dialog.prog.set_fraction(10 / total)) # TODO: additional ping column pass, collated parsed = Servers.parse_json(serv) @@ -507,6 +505,7 @@ class Controller(GObject.GObject): def delete_single_mod_cleanup(self, _iter: Gtk.TreeIter) -> None: self.get_mod_store().remove(_iter) + remove_stale_signatures(self.prefs.paths.config, self.prefs.paths.version) # TODO: strings @call_on_thread("deleting mod") @@ -574,6 +573,7 @@ class Controller(GObject.GObject): # add to saved servers model verbatim and sort in place # update tab with ! # update config file with IP + # TODO: needs threading case ContextMenu.ADD_SERVER: pass @@ -593,10 +593,7 @@ class Controller(GObject.GObject): # Gtk.TreeModel, row-inserted/row-deleted # updates statusbar # FIXME: signal should instead be emitted off of treeview when rows added/inserted - #self.update_mod_statusbar() - remove_stale_signatures( - self.prefs.paths.config, self.prefs.paths.version - ) + # self.update_mod_statusbar() # call a2s on thread and update ephemeral model in situ case ContextMenu.REFRESH_PLAYERS: @@ -610,12 +607,15 @@ class Controller(GObject.GObject): # reverse of ADD_SERVER case ContextMenu.REMOVE_SERVER: pass + case ContextMenu.SET_FAV: self.set_fav() # NOTE: spawns dedicated dialogs + # TODO: needs threading case ContextMenu.SHOW_DETAILS: pass + # TODO: needs threading case ContextMenu.SHOW_MODS: pass @@ -634,8 +634,7 @@ class Controller(GObject.GObject): log = self.prefs.paths.debug store = self.model_man.get_log_store() store.clear() - # NOTE: this model is reloaded each time as log changes, rather than adding - # atomic events + # NOTE: this model is reloaded each time as log changes try: with open(log, "r") as f: lines = [ @@ -872,7 +871,7 @@ class Controller(GObject.GObject): dialog = ExceptionDialog(self, "API TIMEOUT") dialog.run() - #def push_data_failure(self) -> None: + # def push_data_failure(self) -> None: # #treeview = self.get_active_treeview() # #treeview.set_loaded(True) # # TODO: wipe control model on failure or keep old results? @@ -910,7 +909,6 @@ class Controller(GObject.GObject): model[path][4] = HEX_RED self.emitter.emit("mods_highlighted") - @call_on_thread(strings.dialog.working) def highlight_stale(self) -> None: stale = find_stale_mods(self.prefs.paths.config) @@ -947,7 +945,9 @@ class Controller(GObject.GObject): if res is True: self.update_config(key, text) else: - self.cleanup_func = CleanupFunc(lambda: self.emitter.emit("api_change_failed")) + self.cleanup_func = CleanupFunc( + lambda: self.emitter.emit("api_change_failed") + ) def set_resolution(self, window: "OuterWindow") -> None: if self.prefs.is_game_mode: @@ -1016,6 +1016,7 @@ class Controller(GObject.GObject): self.filter_threaded(mode, label) def populate_model(self) -> None: + # NOTE: prepare GTK objects outside of thread treeview = self.get_active_treeview() if treeview.is_loaded() is True: self.emitter.emit("servers_loaded", treeview.get_enum()) @@ -1045,8 +1046,6 @@ class Controller(GObject.GObject): def get_dist_cache(self) -> dict[str, "Haversine"]: return self.dist_cache - # TODO: use model manager, map and keyword caches - # TODO: model cache that hooks checkbox signal def get_help_store(self) -> Gtk.ListStore: return self.model_man.get_help_store() @@ -1091,6 +1090,7 @@ class Controller(GObject.GObject): mode = FilterMode.TOGGLE_OFF self.refilter_model(mode, label) + # TODO: map man should be consolidated into filter man def _on_map_selection_changed(self, emitter: Emitter, selection: str) -> None: map_man = self.get_map_man() map_man.set_selected_map(selection) diff --git a/dzgui/data/CHANGELOG.md b/dzgui/data/CHANGELOG.md index e51e053..197922c 100644 --- a/dzgui/data/CHANGELOG.md +++ b/dzgui/data/CHANGELOG.md @@ -44,3 +44,9 @@ - Local documentation - Offline mods - Move debug mode to developers only + +## Devs +- Show deprecation warnings +- Options -> Dev page +- Raw debug command +- Moved debug log to this mode diff --git a/dzgui/model/filtered_model.py b/dzgui/model/filtered_model.py index 84be7df..dffd952 100644 --- a/dzgui/model/filtered_model.py +++ b/dzgui/model/filtered_model.py @@ -52,7 +52,6 @@ class FilteredModelManager: self.ping_cache: dict[str, int] = {} self.ephemeral_model: ListStore = None - #= self.new_model_from_class(ServerColumns) self.control_model: list = None self.filtered: list = None @@ -125,7 +124,7 @@ class FilteredModelManager: rows = self.sort_rows(rows) for row in rows: clone.append(row) - #else: + # else: # print("nothing to filter, sending none") # clone = None @@ -222,7 +221,6 @@ class FilteredModelManager: rows = [row for row in rows if row[0].isascii()] case strings.filter_lowpop: rows = [row for row in rows if (row[4] / row[5] * 100) > 30] - # FIXME: can create logically opposed contexts like "official + modded" case strings.filter_modded: rows = [row for row in rows if not row[11]] return rows @@ -254,7 +252,6 @@ class FilteredModelManager: filters = self.controller.get_filters() refiltered = self.filter_toggle_on(filters) self.set_filtered(refiltered) - #self.set_success(True) def convert_model_to_list(self, model: ListStore) -> list: return [[el for el in row] for row in model] diff --git a/dzgui/views/dialogs/entry.py b/dzgui/views/dialogs/entry.py index 4a520d1..64d57a8 100644 --- a/dzgui/views/dialogs/entry.py +++ b/dzgui/views/dialogs/entry.py @@ -1,10 +1,12 @@ import gi + gi.require_version("Gtk", "3.0") from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa from dzgui.const.constants import NO_EXPAND, NO_FILL, NO_PADDING from dzgui.const.enum import Popup + class EntryDialog(GenericDialog): def __init__(self, text: str, mode: Popup, link: str, button_type=None): super().__init__(text, mode) diff --git a/dzgui/views/pages/devs.py b/dzgui/views/pages/devs.py index e1a086f..b453829 100644 --- a/dzgui/views/pages/devs.py +++ b/dzgui/views/pages/devs.py @@ -8,6 +8,7 @@ from dzgui.views.components.labels import BoldLabel from dzgui.views.trees.tree_base import TreeView import gi # noqa E402 + gi.require_version("Gtk", "3.0") from gi.repository import Gtk # noqa E402 @@ -16,20 +17,19 @@ if TYPE_CHECKING: from dzgui.config.userprefs import UserPrefs from dzgui.config.xdg import Xdg + class Developers(Gtk.ScrolledWindow): """ Shows TreeViews displaying contents of parsed XDG paths and user preferences """ + def __init__(self, controller: "Controller") -> None: - super().__init__( - ) + super().__init__() self.controller = controller self.box = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, - margin_start=10, - margin_end=10 + orientation=Gtk.Orientation.VERTICAL, margin_start=10, margin_end=10 ) heading = Gtk.Label(label=developers.header) @@ -42,8 +42,9 @@ class Developers(Gtk.ScrolledWindow): paths_label = BoldLabel(developers.paths_label) prefs_label = BoldLabel(developers.prefs_label) - paths_tree = self._make_tree(self.controller.prefs.paths) - prefs_tree = self._make_tree(self.controller.prefs) + prefs = self.controller.get_prefs() + paths_tree = self._make_tree(prefs.paths) + prefs_tree = self._make_tree(prefs) trees_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10) path = Gtk.TreePath.new_from_indices([0]) @@ -72,9 +73,12 @@ class Developers(Gtk.ScrolledWindow): store = Gtk.ListStore(str, str) for field in fields(prefs): if field.name == "paths": - break + continue k, v = field.name, getattr(prefs, field.name) store.append((k, str(v))) view.set_model(store) return view + + def grab_content_area(self) -> None: + return diff --git a/dzgui/views/trees/tree_servers.py b/dzgui/views/trees/tree_servers.py index 8423ef2..fdcaf6b 100644 --- a/dzgui/views/trees/tree_servers.py +++ b/dzgui/views/trees/tree_servers.py @@ -69,7 +69,14 @@ class ServerTreeView(ContextMixin, TreeView): logger.critical(e) valid_json = False + width_map = { + "Name": 800, + "Map": 300, + "IP": 240, + } + # TODO: abstract + # FIXME: resize col width func causes snapping behavior browser_cols = strings.browser_cols for i, column_title in enumerate(browser_cols): renderer = Gtk.CellRendererText() @@ -77,8 +84,6 @@ class ServerTreeView(ContextMixin, TreeView): column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_resizable(True) column.set_sort_column_id(i) - #if column_title == "Ping": - # column.set_cell_data_func(renderer, self._get_ping) if valid_json: try: @@ -88,18 +93,20 @@ class ServerTreeView(ContextMixin, TreeView): column.set_fixed_width(saved_size) column.set_expand(True) else: - if column_title == "Name": - column.set_fixed_width(800) - if column_title == "Map": - column.set_fixed_width(300) + w = width_map[column_title] + column.set_fixed_width(w) + #if column_title == "Name": + # column.set_fixed_width(800) + #if column_title == "Map": + # column.set_fixed_width(300) + # TODO: standardize widths based on column title and longest content - # TODO: resize col width func causes snapping behavior - if column_title == "Name": - column.set_fixed_width(500) - if column_title == "Map": - column.set_fixed_width(200) - if column_title == "IP": - column.set_fixed_width(240) + #if column_title == "Name": + # column.set_fixed_width(500) + #if column_title == "Map": + # column.set_fixed_width(200) + #if column_title == "IP": + # column.set_fixed_width(240) column.connect("notify::fixed-width", self._on_col_width_changed) self.append_column(column) @@ -129,38 +136,38 @@ class ServerTreeView(ContextMixin, TreeView): store = self.map_man.get_map_store() self.emitter.emit("load_maps", store) - def _get_ping( - self, - column: Gtk.TreeViewColumn, - cell: Gtk.CellRendererText, - model: Gtk.TreeModel, - it: Gtk.TreeIter, - data: Any, - ): - def ping(model, it, ip: str): - # TODO: use a2s to ping server - # a2s.info -> "ping" key - # Servers.ping() -> this accepts a whole row - # try, if failure just abort - self.res = ip.replace(":", "%") - num = 11111 - GLib.idle_add(lambda: model.set(it, 9, num)) + #def _get_ping( + # self, + # column: Gtk.TreeViewColumn, + # cell: Gtk.CellRendererText, + # model: Gtk.TreeModel, + # it: Gtk.TreeIter, + # data: Any, + #): + # def ping(model, it, ip: str): + # # TODO: use a2s to ping server + # # a2s.info -> "ping" key + # # Servers.ping() -> this accepts a whole row + # # try, if failure just abort + # self.res = ip.replace(":", "%") + # num = 11111 + # GLib.idle_add(lambda: model.set(it, 9, num)) - addr = model.get_value(it, 7).split(":")[0] - qport = model.get_value(it, 8) - ip = f"{addr}:{qport}" + # addr = model.get_value(it, 7).split(":")[0] + # qport = model.get_value(it, 8) + # ip = f"{addr}:{qport}" - thread = threading.Thread( - daemon=True, - target=ping, - args=( - model, - it, - ip, - ), - ) - thread.start() - pass + # thread = threading.Thread( + # daemon=True, + # target=ping, + # args=( + # model, + # it, + # ip, + # ), + # ) + # thread.start() + # pass def start_timeout(self) -> None: self.queue_id = GLib.timeout_add(QUEUE_CHECK_DELAY, self._check_result_queue) @@ -171,27 +178,27 @@ class ServerTreeView(ContextMixin, TreeView): def get_filter_man(self) -> FilteredModelManager: return self.filter_man - def shrink_to_fit(self) -> None: - cols = self.get_columns() - # TODO: run on only one treeview and propagate results - # TODO: does not shrink name, map, ip fields to fit - # TODO: col width changed signal is buggy on current treeview - for col in cols: - title = col.get_title() - if title == "Name": - continue - if title == "Map": - continue - if title == "IP": - continue - label = Gtk.Label(label=title) - pango = label.get_layout() - size = pango.get_pixel_size() - if size.width > 50: - width = size.width * 1.30 - else: - width = size.width * 1.65 - col.set_fixed_width(width) + #def shrink_to_fit(self) -> None: + # cols = self.get_columns() + # # TODO: run on only one treeview and propagate results + # # TODO: does not shrink name, map, ip fields to fit + # # TODO: col width changed signal is buggy on current treeview + # for col in cols: + # title = col.get_title() + # if title == "Name": + # continue + # if title == "Map": + # continue + # if title == "IP": + # continue + # label = Gtk.Label(label=title) + # pango = label.get_layout() + # size = pango.get_pixel_size() + # if size.width > 50: + # width = size.width * 1.30 + # else: + # width = size.width * 1.65 + # col.set_fixed_width(width) def get_enum(self) -> None: return self.enum @@ -277,7 +284,7 @@ class ServerTreeView(ContextMixin, TreeView): if event.state is Gdk.ModifierType.CONTROL_MASK: match event.keyval: case Gdk.KEY_r: - # TODO: unimplemented + # TODO: unimplemented, threading self.refresh_player_count() case Gdk.KEY_f: self.emitter.emit("request_keyword_focus")