diff --git a/dzgui/controllers/mc.py b/dzgui/controllers/mc.py index 785c790..a9dd8d1 100644 --- a/dzgui/controllers/mc.py +++ b/dzgui/controllers/mc.py @@ -27,7 +27,6 @@ from dzgui.util.format import format_player_count from dzgui.util.open_links import open_user_workshop, open_workshop_page from dzgui.views.dialogs.filepicker import FilePicker from dzgui.views.dialogs.generic import ExceptionDialog -from dzgui.views.dialogs.servers import ServerModDialog import gi @@ -68,6 +67,7 @@ class AppNavigation: lan: "ServerTreeView" logtreeview: "LogTreeView" filters: "FilterPanel" + preconnect: "PreConnectionAssistant" class Controller(GObject.GObject): @@ -460,6 +460,7 @@ class Controller(GObject.GObject): def open_connection_assistant(self, res: dict[Any], mods: list["DayzMod"]) -> None: self.open_page(NotebookPage.CONNECTION) + self.mediator.preconnect.populate(res, mods) # TODO: populate assistant # TODO: embed dialogs # dialog = ServerModDialog(self, mods) diff --git a/dzgui/managers/connection.py b/dzgui/managers/connection.py index f00a845..29a55a7 100644 --- a/dzgui/managers/connection.py +++ b/dzgui/managers/connection.py @@ -63,7 +63,8 @@ class ConnectionManager: self.thread_man.set_cleanup_func( StoredFunc(self._server_timeout), destroy_first=True ) - self.controller.open_connection_assistant(res, mods) + func = StoredFunc(self.controller.open_connection_assistant, res, mods) + self.thread_man.set_cleanup_func(func, destroy_first=True) @call_on_thread(dialog.querying) def query_details(self, record: Servers.Record) -> None: diff --git a/dzgui/views/dialogs/servers.py b/dzgui/views/dialogs/servers.py index 3ed4178..903cebb 100644 --- a/dzgui/views/dialogs/servers.py +++ b/dzgui/views/dialogs/servers.py @@ -19,7 +19,7 @@ if TYPE_CHECKING: class ServerDialog(GenericDialog): - def __init__(self, controller: "Controller", title: str, secondary: str): + def __init__(self, controller: "Controller", title: str, secondary: str) -> None: super().__init__( controller=controller, text=title, diff --git a/dzgui/views/pages/preconnect.py b/dzgui/views/pages/preconnect.py index cf17439..75665b6 100644 --- a/dzgui/views/pages/preconnect.py +++ b/dzgui/views/pages/preconnect.py @@ -9,6 +9,7 @@ from dzgui.const.constants import ( ) from dayzquery import DayzMod from dzgui.views.components.frame import HeadingFrame +from dzgui.views.trees.tree_server_mods import ServerModTree import gi @@ -20,9 +21,10 @@ if TYPE_CHECKING: from dzgui.controllers.mc import Controller +# TODO: pack entire box in scrolled window class PreConnectionAssistant(Gtk.Box): def __init__(self, controller: "Controller") -> None: - super().__init__() + super().__init__(orientation=Gtk.Orientation.VERTICAL) self.controller = controller @@ -31,13 +33,15 @@ class PreConnectionAssistant(Gtk.Box): halign=Gtk.Align.END, valign=Gtk.Align.END, hexpand=True, + vexpand=True, spacing=10, ) self.rules: dict[Any] self.mods: list["DayzMod"] - # TODO: pack in scrolled window + self.controller.register_widget("preconnect", self) + # TODO: strings self.back = Gtk.Button(label="Back") @@ -53,8 +57,15 @@ class PreConnectionAssistant(Gtk.Box): # TODO: populate with strings and icons # set visibility if warnings > 1 frame = HeadingFrame(Gtk.Label(label="ITEM ONE"), "Warnings") - self.add(frame) + self.tree = ServerModTree(self.controller) + + self.scrolled = Gtk.ScrolledWindow() + self.scrolled.add(self.tree) + self.scrolled.set_size_request(600, 400) + + self.add(self.scrolled) + self.add(frame) self.add(self.button_box) def _on_ok_clicked(self, button: Gtk.Button) -> None: @@ -67,6 +78,8 @@ class PreConnectionAssistant(Gtk.Box): self.controller.open_page(page) def populate(self, res: dict[Any], mods: list["DayzMod"]) -> None: + # TODO: embed tree from dialog, but not dialog itself + self.tree.populate(mods) # steam_path = self.controller.get_config_man().lookup(Preferences.DEFAULT) # dayz_version = PeFile.get_pretty_version(steam_path, APPID_DAYZ) # dayz_exp_version = PeFile.get_pretty_version(steam_path, APPID_DAYZ_EXP) @@ -78,3 +91,6 @@ class PreConnectionAssistant(Gtk.Box): def connect(self) -> None: # TODO: add to history file and list store pass + + # TODO: icon for mod signature issue + # or "Update mods and connect" diff --git a/dzgui/views/trees/tree_server_mods.py b/dzgui/views/trees/tree_server_mods.py index df44134..d239d1a 100644 --- a/dzgui/views/trees/tree_server_mods.py +++ b/dzgui/views/trees/tree_server_mods.py @@ -1,47 +1,43 @@ -import logging +from dzgui.model.model_factory import ModelFactory +from dzgui.views.mixins.cursor_mixin import CursorMixin +from dzgui.views.trees.tree_base import TreeView +from dzgui.util import strings + +from typing import TYPE_CHECKING import gi + gi.require_version("Gtk", "3.0") -from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa +from gi.repository import Gtk, GLib, Gdk, Pango # noqa -from dzgui.const.enum import ( - ContextMenuGroup, - Popup, - RowType, - WindowContext, - ) -from dzgui.util.open_links import open_workshop_page -from dzgui.util import strings, localize -from typing import Any +if TYPE_CHECKING: + from dzgui.controllers.mc import Controller -from dzgui.views.trees.tree_base import TreeView -class ModDialog(GenericDialog): - def __init__(self, record: str): - # TODO: center secondary text - msg = strings.workshop - super().__init__(textwrap.dedent(msg), Popup.MODLIST) +class ServerModTree(TreeView): # type: ignore + def __init__(self, controller: "Controller") -> None: + super().__init__(controller) - dialogBox = self.get_content_area() - self.set_default_response(Gtk.ResponseType.OK) - self.set_size_request(800, 500) + # self.view = TreeView(controller) + self.mod_store = ModelFactory().make_server_mod_store() - self.scrollable = Gtk.ScrolledWindow() - self.view = Gtk.TreeView( - enable_search=False, search_column=-1, fixed_height_mode=True - ) - self.scrollable.add(self.view) - set_surrounding_margins(self.scrollable, 20) + self.set_fixed_height_mode(True) + self.set_headers_visible(True) + self.set_model(self.mod_store) - self.connect("generic_row_activated", self._on_mod_row_activated) - self.connect("generic_treesel_changed", self._parent_selection_changed) + # self.scrollable_tree = Gtk.ScrolledWindow() + # self.scrollable_tree.add(self.view) + # self.scrollable_tree.set_size_request(700, 400) + + # self.view.connect("row-activated", self._on_row_activated) for i, column_title in enumerate(strings.server_mod_cols): renderer = Gtk.CellRendererText(ellipsize=Pango.EllipsizeMode.END) column = Gtk.TreeViewColumn(column_title, renderer, text=i) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) - self.view.append_column(column) + self.append_column(column) column.set_sort_column_id(i) + # FIXME: do not recycle generic string vars match column_title: case strings.mod: column.set_fixed_width(350) @@ -50,55 +46,9 @@ class ModDialog(GenericDialog): case _: pass - dialogBox.pack_end(self.scrollable, EXPAND, FILL, 0) + # mod_count = len(mods) + # self._set_footer(mod_count) - wait_dialog = GenericDialog(strings.modlist, Popup.WAIT) - wait_dialog.show_all() - thread = threading.Thread( - target=self._background, args=(wait_dialog, record) - ) - thread.start() - - def _on_mod_row_activated(self, - treeview: Gtk.TreeView, - path: Gtk.TreePath, - column: Gtk.TreeViewColumn - ) -> None: - uid = self.get_value_at_index(1) - self.controller.open_mod_page(uid) - - def _parent_selection_changed(self, base_class: TreeView, sel: Gtk.TreeSelection): - pass - - # TODO: threading shouldn't take place inside this dialog, should be external to controller - #def _background(self, dialog: "GenericDialog", record: str) -> None: - # def _load(): - # dialog.destroy() - # # TODO: natively implemented - # #if data.returncode == 1: - # # spawn_dialog(strings.server_error, Popup.NOTIFY) - # # return - # self.show_all() - # self.set_markup(f"Modlist ({mod_count} mods)") - # self.run() - # self.destroy() - - # record = treeview.get_record() - # if not record: - # return - - # # TODO: thread - # try: - # modlist = get_server_modlist(record) - # mod_count = self._parse_modlist_rows(modlist) - # except Exception: - # # TODO: needs to pop error dialog - # mod_count = 0 - # modlist_store.clear() - # self.view.set_model(modlist_store) - # GLib.idle_add(_load) - - #def _parse_modlist_rows(self, rows: list) -> bool | int: - # for row in rows: - # modlist_store.append(row) - # return len(rows) + def populate(self, mods: list[list[str]]) -> None: + for mod in mods: + self.mod_store.append(mod)