mirror of
https://github.com/aclist/dztui.git
synced 2026-08-26 17:57:06 +02:00
chore: change modelman to model factory
This commit is contained in:
parent
85c1d18622
commit
bdfebf9a69
@ -26,14 +26,6 @@ class Popup(Enum):
|
||||
QUIT = 8
|
||||
|
||||
|
||||
class Command(Enum):
|
||||
INTERACTIVE = 1
|
||||
ONESHOT = 2
|
||||
HELP = 3
|
||||
TOGGLE = 4
|
||||
THANKS = 5
|
||||
|
||||
|
||||
class VAdjustment(Enum):
|
||||
UP = 1
|
||||
DOWN = 2
|
||||
@ -111,14 +103,14 @@ class Preferences(EnumWithAttrs):
|
||||
|
||||
class NotebookPage(EnumWithAttrs):
|
||||
CHANGELOG = {"crumbs": strings.crumbs.changelog, "statusbar": True}
|
||||
DEVELOPERS = {"crumbs": strings.crumbs.developers, "statusbar": False}
|
||||
HELP = {"crumbs": strings.crumbs._help, "statusbar": True}
|
||||
KEYS = {"crumbs": strings.crumbs.keys, "statusbar": True}
|
||||
LOG = {"crumbs": strings.crumbs.log, "statusbar": True}
|
||||
HELP = {"crumbs": strings.crumbs._help, "statusbar": True}
|
||||
MODS = {"crumbs": strings.crumbs.mods, "statusbar": True}
|
||||
OPTIONS = {"crumbs": strings.crumbs.options, "statusbar": False}
|
||||
SERVERS = {"crumbs": strings.crumbs.servers, "statusbar": True}
|
||||
THANKS = {"crumbs": strings.crumbs.thanks, "statusbar": True}
|
||||
DEVELOPERS = {"crumbs": strings.crumbs.developers, "statusbar": False}
|
||||
|
||||
|
||||
class RowType(EnumWithAttrs):
|
||||
@ -128,7 +120,7 @@ class RowType(EnumWithAttrs):
|
||||
if string == member.dict["label"]:
|
||||
return member
|
||||
|
||||
# TODO: add to strings
|
||||
# TODO: add to notebook tab tooltips
|
||||
# SERVER_BROWSER = {
|
||||
# "label": "Server browser",
|
||||
# "tooltip": "Used to browse the global server list",
|
||||
@ -155,6 +147,7 @@ class RowType(EnumWithAttrs):
|
||||
# "quad_label": "Mods",
|
||||
# "type": "mods",
|
||||
# }
|
||||
# TODO: strings
|
||||
CHANGELOG = {
|
||||
"label": "View changelog",
|
||||
"tooltip": "Opens the DZGUI changelog",
|
||||
@ -162,7 +155,6 @@ class RowType(EnumWithAttrs):
|
||||
SHOW_LOG = {
|
||||
"label": "Show debug log",
|
||||
"tooltip": "Read the DZGUI log generated since startup",
|
||||
"quad_label": "Debug log",
|
||||
}
|
||||
SEPARATOR = {
|
||||
"label": "SEPARATOR",
|
||||
@ -171,43 +163,34 @@ class RowType(EnumWithAttrs):
|
||||
DUMP_LOG = {
|
||||
"label": "Output system info to log file",
|
||||
"tooltip": "Dump diagnostic data for troubleshooting",
|
||||
"wait_msg": "Generating log",
|
||||
"type": Command.ONESHOT,
|
||||
}
|
||||
# help pages
|
||||
DOCS = {
|
||||
"label": "Documentation/help files (GitHub) ⧉",
|
||||
"tooltip": "Open the DZGUI documentation in a browser",
|
||||
"type": Command.HELP,
|
||||
}
|
||||
DOCS_FALLBACK = {
|
||||
"label": "Documentation/help files (Codeberg mirror) ⧉",
|
||||
"tooltip": "Open the DZGUI documentation in a browser",
|
||||
"type": Command.HELP,
|
||||
}
|
||||
BUGS = {
|
||||
"label": "Report a bug (GitHub) ⧉",
|
||||
"tooltip": "Open the DZGUI issue tracker in a browser",
|
||||
"type": Command.HELP,
|
||||
}
|
||||
FORUM = {
|
||||
"label": "DZGUI Subreddit ⧉",
|
||||
"tooltip": "Open the DZGUI discussion forum in a browser",
|
||||
"type": Command.HELP,
|
||||
}
|
||||
SPONSOR = {
|
||||
"label": "Sponsor (GitHub) ⧉",
|
||||
"tooltip": "Sponsor development of the DZGUI project",
|
||||
"type": Command.HELP,
|
||||
}
|
||||
THANKS = {
|
||||
"label": "Special thanks",
|
||||
"tooltip": "A list of contributors, testers, and sponsors",
|
||||
"type": Command.THANKS,
|
||||
}
|
||||
|
||||
|
||||
# TODO: rename to ContextItem
|
||||
# TODO: rename to ContextMenuItem
|
||||
class ContextMenu(EnumWithAttrs):
|
||||
ADD_NOTE = {"label": strings.add_note}
|
||||
ADD_SERVER = {"label": strings.add}
|
||||
|
||||
@ -45,14 +45,13 @@ from dzgui.config.userprefs import UserPrefs
|
||||
from dzgui.controllers.emitter import Emitter
|
||||
from dzgui.model.contextmenu import ContextMenuManager
|
||||
from dzgui.model.filtered_model import FilteredModelManager
|
||||
from dzgui.model.misc_model import ModelManager
|
||||
from dzgui.model.model_factory import ModelFactory
|
||||
from dzgui.util import strings
|
||||
from dzgui.util._json import read_json, write_json
|
||||
from dzgui.util.diag import write_diagnostic
|
||||
from dzgui.util.format import format_mods, format_player_count
|
||||
from dzgui.util.localize import number
|
||||
from dzgui.util.open_links import open_workshop_page, open_user_workshop
|
||||
from dzgui.util.redact import redact_log
|
||||
from dzgui.views.dialogs.filepicker import FilePicker
|
||||
from dzgui.views.dialogs.generic import ExceptionDialog, WaitDialog
|
||||
|
||||
@ -112,7 +111,7 @@ class Controller(GObject.GObject):
|
||||
self.prefs: UserPrefs
|
||||
self.cleanup_func: StoredFunc = None
|
||||
|
||||
self.model_man = ModelManager()
|
||||
#self.model_man = ModelManager()
|
||||
self.emitter = Emitter()
|
||||
self.emitter.connect("map_selection_changed", self._on_map_selection_changed)
|
||||
self.emitter.connect("check_toggled", self._on_check_toggled)
|
||||
@ -163,12 +162,6 @@ class Controller(GObject.GObject):
|
||||
def is_auto_install(self) -> bool:
|
||||
return self.query_config(Preferences.INSTALL)
|
||||
|
||||
def reinit_map_store(self) -> None:
|
||||
self.model_man.set_all_maps()
|
||||
|
||||
def append_map(self, map_row: list) -> None:
|
||||
self.model_man.append_map(map_row)
|
||||
|
||||
def unblock_signals(self) -> None:
|
||||
self.block_signals(False)
|
||||
|
||||
@ -313,7 +306,7 @@ class Controller(GObject.GObject):
|
||||
|
||||
@call_on_thread(strings.dialog.modlist)
|
||||
def load_mods(self) -> None:
|
||||
model = self.model_man.new_mod_store()
|
||||
model = ModelFactory().make_mod_store() #self.model_man.new_mod_store()
|
||||
path = self.query_config(Preferences.DEFAULT)
|
||||
mods = get_delimited_mods(Path(path))
|
||||
|
||||
@ -543,11 +536,7 @@ class Controller(GObject.GObject):
|
||||
self.push_data_success(parsed, FilterMode.INITIAL)
|
||||
|
||||
def get_help_row(self) -> str:
|
||||
tv = self.mediator.menu
|
||||
model = self.get_help_store()
|
||||
tree_iter = tv.get_focused_row_iter()
|
||||
value = model.get_value(tree_iter, 1)
|
||||
return value.dict["tooltip"]
|
||||
return self.mediator.menu.get_row_enum()
|
||||
|
||||
def open_user_workshop(self, uid: str) -> None:
|
||||
# NOTE: uid may contain leading zeroes, not a real integer
|
||||
@ -634,22 +623,12 @@ class Controller(GObject.GObject):
|
||||
|
||||
def populate_log(self) -> None:
|
||||
log = self.prefs.paths.debug
|
||||
store = self.model_man.get_log_store()
|
||||
store.clear()
|
||||
# NOTE: this model is reloaded each time as log changes
|
||||
try:
|
||||
with open(log, "r") as f:
|
||||
lines = [
|
||||
line.split(strings.delimiter) for line in f.read().splitlines()
|
||||
]
|
||||
for record in lines:
|
||||
clean = redact_log(record)
|
||||
store.append(clean)
|
||||
self.mediator.logtreeview.populate_log(log)
|
||||
self.open_page(NotebookPage.LOG)
|
||||
except Exception as e:
|
||||
dialog = ExceptionDialog(self, str(e))
|
||||
dialog.run()
|
||||
return
|
||||
self.open_page(NotebookPage.LOG)
|
||||
|
||||
def select_colorized(self) -> None:
|
||||
model = self.get_mod_store()
|
||||
@ -930,15 +909,6 @@ class Controller(GObject.GObject):
|
||||
def get_dist_cache(self) -> dict[str, "Haversine"]:
|
||||
return self.dist_cache
|
||||
|
||||
def get_help_store(self) -> Gtk.ListStore:
|
||||
return self.model_man.get_help_store()
|
||||
|
||||
def get_modlist_store(self) -> Gtk.ListStore:
|
||||
return self.model_man.get_modlist_store()
|
||||
|
||||
def get_log_store(self) -> Gtk.ListStore:
|
||||
return self.model_man.get_log_store()
|
||||
|
||||
def get_filters(self) -> list:
|
||||
return self.mediator.filters.get_filters()
|
||||
|
||||
|
||||
@ -1,82 +0,0 @@
|
||||
from dataclasses import dataclass
|
||||
from dzgui.const.enum import HELP_MENU_ROWS
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository.Gtk import ListStore # noqa E402
|
||||
from gi.repository import GObject, Gtk # noqa E402
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class ModCols:
|
||||
name: str
|
||||
symlink: str
|
||||
directory: str
|
||||
size: float
|
||||
color: str
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class LogCols:
|
||||
timestamp: str
|
||||
flag: str
|
||||
traceback: str
|
||||
msg: str
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class ServerModCols:
|
||||
name: str
|
||||
uid: GObject.TYPE_INT64
|
||||
installed: str
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class MenuCols:
|
||||
name: str
|
||||
hidden: GObject.TYPE_PYOBJECT
|
||||
|
||||
|
||||
class ModelManager:
|
||||
"""
|
||||
Manager for miscellaneous ListStores
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
||||
self.map_store = ListStore(str)
|
||||
self.help_store = self.new_model_from_class(MenuCols)
|
||||
self.log_store = self.new_model_from_class(LogCols)
|
||||
# FIXME: needs to be generated on demand for servers
|
||||
self.modlist_store = self.new_model_from_class(ServerModCols)
|
||||
|
||||
for row in HELP_MENU_ROWS:
|
||||
label = row.dict["label"]
|
||||
self.help_store.append([label, row])
|
||||
|
||||
def new_model_from_class(self, cls: type) -> ListStore:
|
||||
store = ListStore(*[ftype for field, ftype in cls.__annotations__.items()])
|
||||
return store
|
||||
|
||||
def get_map_store(self) -> ListStore:
|
||||
return self.map_store
|
||||
|
||||
def get_help_store(self) -> ListStore:
|
||||
return self.help_store
|
||||
|
||||
def new_mod_store(self) -> ListStore:
|
||||
return self.new_model_from_class(ModCols)
|
||||
|
||||
def get_log_store(self) -> ListStore:
|
||||
return self.log_store
|
||||
|
||||
def get_modlist_store(self) -> ListStore:
|
||||
return self.modlist_store
|
||||
|
||||
def set_all_maps(self) -> None:
|
||||
self.map_store.clear()
|
||||
self.map_store.append(["All maps"])
|
||||
|
||||
def append_map(self, row: list) -> None:
|
||||
self.map_store.append(row)
|
||||
82
dzgui/model/model_factory.py
Normal file
82
dzgui/model/model_factory.py
Normal file
@ -0,0 +1,82 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
from dzgui.const.enum import HELP_MENU_ROWS
|
||||
from dzgui.util.redact import redact_log
|
||||
from dzgui.util.strings import delimiter
|
||||
from dzgui.views.dialogs.generic import ExceptionDialog
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository.Gtk import ListStore # noqa E402
|
||||
from gi.repository import GObject # noqa E402
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class ModCols:
|
||||
name: str
|
||||
symlink: str
|
||||
directory: str
|
||||
size: float
|
||||
color: str
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class LogCols:
|
||||
timestamp: str
|
||||
flag: str
|
||||
traceback: str
|
||||
msg: str
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class ServerModCols:
|
||||
name: str
|
||||
uid: GObject.TYPE_INT64
|
||||
installed: str
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class MenuCols:
|
||||
name: str
|
||||
hidden: GObject.TYPE_PYOBJECT
|
||||
|
||||
|
||||
class ModelFactory:
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
|
||||
def new_model_from_logfile(self, path: str) -> None:
|
||||
store = self.make_log_store()
|
||||
with open(path, "r") as f:
|
||||
lines = [
|
||||
line.split(delimiter) for line in f.read().splitlines()
|
||||
]
|
||||
for record in lines:
|
||||
# NOTE: strip PII and API keys
|
||||
clean = redact_log(record)
|
||||
store.append(clean)
|
||||
return store
|
||||
|
||||
def new_model_from_class(self, cls: type) -> ListStore:
|
||||
store = ListStore(*[ftype for field, ftype in cls.__annotations__.items()])
|
||||
return store
|
||||
|
||||
def make_map_store(self) -> ListStore:
|
||||
return ListStore(str)
|
||||
|
||||
def make_help_store(self) -> ListStore:
|
||||
store = self.new_model_from_class(MenuCols)
|
||||
for row in HELP_MENU_ROWS:
|
||||
label = row.dict["label"]
|
||||
store.append([label, row])
|
||||
return store
|
||||
|
||||
def make_mod_store(self) -> ListStore:
|
||||
return self.new_model_from_class(ModCols)
|
||||
|
||||
def make_log_store(self) -> ListStore:
|
||||
return self.new_model_from_class(LogCols)
|
||||
|
||||
def make_server_mod_store(self) -> ListStore:
|
||||
return self.new_model_from_class(ServerModCols)
|
||||
@ -3,6 +3,7 @@ import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from dzgui.const.enum import ContextMenuGroup
|
||||
from dzgui.model.model_factory import ModelFactory
|
||||
from dzgui.util import strings
|
||||
from dzgui.views.trees.tree_base import TreeView
|
||||
from dzgui.views.mixins.context_mixin import ContextMixin
|
||||
@ -25,13 +26,11 @@ class LogTreeView(ContextMixin, TreeView):
|
||||
self.controller = controller
|
||||
self.controller.register_widget("logtreeview", self)
|
||||
|
||||
# TODO: maybe put this in init
|
||||
self.set_headers_visible(True)
|
||||
self.set_fixed_height_mode(True)
|
||||
self.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
|
||||
|
||||
model = self.controller.get_log_store()
|
||||
self.set_model(model)
|
||||
self.set_model(None)
|
||||
|
||||
for i, column_title in enumerate(strings.log_cols):
|
||||
renderer = Gtk.CellRendererText()
|
||||
@ -44,7 +43,10 @@ class LogTreeView(ContextMixin, TreeView):
|
||||
self.connect("key-press-event", self._on_log_keypress)
|
||||
self.connect("button-press-event", self._on_log_keypress)
|
||||
|
||||
self.s = self.get_selection().get_selected_rows()
|
||||
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_keypress(self, widget: Gtk.Widget, event: Gdk.EventKey) -> None:
|
||||
self.present_menu(widget, event)
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import Any, TYPE_CHECKING
|
||||
|
||||
from dzgui.const.enum import RowType, NotebookPage
|
||||
from dzgui.model.model_factory import ModelFactory
|
||||
from dzgui.util.open_links import open_link_by_rowtype
|
||||
from dzgui.views.trees.tree_base import TreeView
|
||||
|
||||
@ -32,7 +33,7 @@ class MenuTreeView(TreeView):
|
||||
column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
|
||||
self.append_column(column)
|
||||
|
||||
help_store = self.controller.get_help_store()
|
||||
help_store = ModelFactory().make_help_store()
|
||||
self.set_model(help_store)
|
||||
|
||||
self.selected_row = self.get_selection()
|
||||
@ -45,6 +46,7 @@ class MenuTreeView(TreeView):
|
||||
def _parent_row_activated(
|
||||
self, tree: TreeView, path: Gtk.TreePath, column: Gtk.TreeViewColumn
|
||||
) -> None:
|
||||
# FIXME: may be expected to return str, not enum
|
||||
row_type = self.get_value_at_index(1)
|
||||
|
||||
match row_type:
|
||||
@ -66,5 +68,11 @@ class MenuTreeView(TreeView):
|
||||
RowType.SPONSOR,
|
||||
]
|
||||
if row_type in docs:
|
||||
# FIXME: prior method is returning a str, not enum
|
||||
open_link_by_rowtype(row_type)
|
||||
|
||||
def get_row_enum(self) -> Any:
|
||||
# NOTE: col 1 contains a RowType enum
|
||||
model = self.get_model()
|
||||
_iter = self.get_focused_row_iter()
|
||||
rowtype = model.get_value(_iter, 1)
|
||||
return rowtype.dict["tooltip"]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user