mirror of
https://github.com/aclist/dztui.git
synced 2026-08-26 17:57:06 +02:00
fix: set cell renderer properties
This commit is contained in:
parent
a22d1a6324
commit
e56b89fd64
@ -33,8 +33,13 @@ class Emitter(GObject.GObject):
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def request_lan_entry_focus(self) -> None:
|
||||
"""User invoked Ctrl-p keybinding from ServerTreeView"""
|
||||
def request_custom_port_focus(self) -> None:
|
||||
"""User invoked Ctrl-n keybinding from ServerTreeView"""
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def request_default_port_focus(self) -> None:
|
||||
"""user invoked ctrl-d keybinding from servertreeview"""
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
|
||||
@ -4,18 +4,14 @@ import shutil
|
||||
import threading
|
||||
import traceback
|
||||
|
||||
from concurrent.futures import wait, as_completed
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from functools import wraps
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable, Optional, TYPE_CHECKING
|
||||
from warnings import deprecated
|
||||
|
||||
import dzgui.api.pefile as PeFile
|
||||
import dzgui.api.servers as Servers
|
||||
import dzgui.util._json as JSON # noqa
|
||||
|
||||
from dzgui.api.bm import map_id_to_record
|
||||
from dzgui.api.mods import (
|
||||
get_delimited_mods,
|
||||
get_local_mod_path,
|
||||
@ -112,7 +108,7 @@ class Controller(GObject.GObject):
|
||||
self.prefs: UserPrefs
|
||||
self.cleanup_func: StoredFunc = None
|
||||
|
||||
#self.config_man = ConfigManager()
|
||||
# self.config_man = ConfigManager()
|
||||
|
||||
self.emitter = Emitter()
|
||||
self.emitter.connect("map_selection_changed", self._on_map_selection_changed)
|
||||
@ -223,7 +219,7 @@ class Controller(GObject.GObject):
|
||||
treeview = self.get_active_treeview()
|
||||
columns = treeview.get_columns()
|
||||
|
||||
#columns_file = self.config_man.get_columns()
|
||||
# columns_file = self.config_man.get_columns()
|
||||
columns_file = self.prefs.paths.columns
|
||||
try:
|
||||
data = JSON.read_json(columns_file)
|
||||
@ -249,7 +245,7 @@ class Controller(GObject.GObject):
|
||||
w, h = self.mediator.window.get_size()
|
||||
data = {"res": {"width": w, "height": h}}
|
||||
|
||||
#res_path = self.config_man.get_resolution()
|
||||
# res_path = self.config_man.get_resolution()
|
||||
res_path = self.prefs.paths.resolution
|
||||
try:
|
||||
write_json(data, res_path)
|
||||
@ -316,13 +312,13 @@ class Controller(GObject.GObject):
|
||||
# TODO: delegate to threadmanager
|
||||
@call_on_thread(strings.dialog.modlist)
|
||||
def load_mods(self) -> None:
|
||||
model = ModelFactory().make_mod_store() #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))
|
||||
|
||||
for mod in mods:
|
||||
# NOTE: holds color column
|
||||
mod.append(None)
|
||||
# NOTE: show highlight color bool
|
||||
mod.append(False)
|
||||
model.append(mod)
|
||||
|
||||
self.cleanup_func = StoredFunc(self.load_mods_cleanup, model)
|
||||
@ -749,7 +745,7 @@ class Controller(GObject.GObject):
|
||||
it = mod.iter
|
||||
path = model.get_path(it)
|
||||
if int(mod[2]) in stale_mods:
|
||||
model[path][4] = HEX_RED
|
||||
model[path][4] = True
|
||||
self.emitter.emit("mods_highlighted")
|
||||
|
||||
@call_on_thread(strings.dialog.working)
|
||||
@ -946,10 +942,6 @@ class Controller(GObject.GObject):
|
||||
map_man.set_selected_map(selection)
|
||||
self.refilter_model(FilterMode.MAP)
|
||||
|
||||
def hide_widgets_on_init(self) -> None:
|
||||
self.mediator.grid.conpan.set_lan_visible(False)
|
||||
self.mediator.grid.right_panel.sel_panel.hide()
|
||||
|
||||
def get_notebook(self) -> "Notebook":
|
||||
return self.mediator.notebook
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ def call_on_thread(dialog_str: str) -> Callable:
|
||||
def wrapper(*args, **kwargs):
|
||||
self = args[0]
|
||||
stored = StoredFunc(func, *args, **kwargs)
|
||||
print("SELF", self)
|
||||
if not hasattr(self, "thread_man"):
|
||||
raise AttributeError
|
||||
if type(self.thread_man) is not ThreadingManager:
|
||||
|
||||
@ -18,7 +18,7 @@ class ModCols:
|
||||
symlink: str
|
||||
directory: str
|
||||
size: float
|
||||
color: str
|
||||
color: bool
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
@ -42,6 +42,17 @@ class MenuCols:
|
||||
hidden: GObject.TYPE_PYOBJECT
|
||||
|
||||
|
||||
class FastInsertListStore(ListStore):
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def append(self, row) -> None:
|
||||
total = len(row)
|
||||
i = len(self)
|
||||
tree_iter = self.insert_with_values(i, tuple(range(0, total)), row)
|
||||
return tree_iter
|
||||
|
||||
|
||||
class ModelFactory:
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
@ -49,17 +60,17 @@ class ModelFactory:
|
||||
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()
|
||||
]
|
||||
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()])
|
||||
def new_model_from_class(self, cls: type) -> FastInsertListStore:
|
||||
store = FastInsertListStore(
|
||||
*[ftype for field, ftype in cls.__annotations__.items()]
|
||||
)
|
||||
return store
|
||||
|
||||
def make_map_store(self) -> ListStore:
|
||||
|
||||
@ -12,7 +12,7 @@ from dzgui.const.constants import (
|
||||
)
|
||||
from dzgui.const.enum import FilterMode, Preferences, ServerTab
|
||||
from dzgui.managers.thread_man import call_on_thread, StoredFunc, ThreadingManager
|
||||
from dzgui.util.strings import dialog
|
||||
from dzgui.util.strings import api_warn_msg, dialog
|
||||
from dzgui.views.dialogs.generic import ExceptionDialog
|
||||
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
@ -36,8 +36,11 @@ logger = logging.getLogger(__name__)
|
||||
# TODO: failure: spawns error dialog
|
||||
# TODO: non failure with empty model: updates statusbar
|
||||
|
||||
|
||||
class ServerModelManager:
|
||||
def __init__(self, controller: "Controller", tv: Gtk.TreeView, first_iteration=False) -> None:
|
||||
def __init__(
|
||||
self, controller: "Controller", tv: Gtk.TreeView, first_iteration=False
|
||||
) -> None:
|
||||
|
||||
enum = tv.get_enum()
|
||||
self.controller = controller
|
||||
@ -58,6 +61,8 @@ class ServerModelManager:
|
||||
# filter: iteration N+1
|
||||
self.first_iteration = first_iteration
|
||||
|
||||
# TODO: pass servers.saved treeview when using conpan regardless of current context
|
||||
|
||||
match enum:
|
||||
case ServerTab.BROWSER:
|
||||
# NOTE: extra DAYZ_EXP param
|
||||
@ -69,8 +74,11 @@ class ServerModelManager:
|
||||
# TODO: get row count
|
||||
self._dump_history()
|
||||
case ServerTab.LAN:
|
||||
return
|
||||
#self._dump_lan()
|
||||
# NOTE: LAN tab is only loaded on demand
|
||||
pass
|
||||
case _:
|
||||
pass
|
||||
# self._dump_lan()
|
||||
|
||||
@call_on_thread(dialog.fetching)
|
||||
def _dump_api(self) -> None:
|
||||
@ -85,14 +93,18 @@ class ServerModelManager:
|
||||
self.thread_man.increment_dialog()
|
||||
res = future.result(timeout=API_TIMEOUT)
|
||||
if res.status != 200 or not res.parsed:
|
||||
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_failure))
|
||||
self.thread_man.set_cleanup_func(
|
||||
StoredFunc(self._cleanup_on_failure)
|
||||
)
|
||||
return
|
||||
j = res.json
|
||||
servers += j["response"]["servers"]
|
||||
except Exception as e:
|
||||
# TODO: could store exception in cleanup func
|
||||
logger.critical(e)
|
||||
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_failure))
|
||||
self.thread_man.set_cleanup_func(
|
||||
StoredFunc(self._cleanup_on_failure)
|
||||
)
|
||||
return
|
||||
|
||||
# NOTE: This step is allowed to fail, since this metadata is incidental
|
||||
@ -112,9 +124,7 @@ class ServerModelManager:
|
||||
|
||||
event = threading.Event()
|
||||
with ThreadPoolExecutor() as executor:
|
||||
futures = [
|
||||
executor.submit(Servers.test_ip, i, port, event) for i in ports
|
||||
]
|
||||
futures = [executor.submit(Servers.test_ip, i, port, event) for i in ports]
|
||||
for future in as_completed(futures):
|
||||
try:
|
||||
res = future.result(timeout=LAN_TIMEOUT)
|
||||
@ -122,14 +132,18 @@ class ServerModelManager:
|
||||
# NOTE: first non-empty hit, flag pending threads to close
|
||||
event.set()
|
||||
servers.append(res)
|
||||
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_success))
|
||||
self.thread_man.set_cleanup_func(
|
||||
StoredFunc(self._cleanup_on_success)
|
||||
)
|
||||
return
|
||||
if res is None:
|
||||
continue
|
||||
servers.append(res)
|
||||
except Exception as e:
|
||||
logger.critical(e)
|
||||
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_failure))
|
||||
self.thread_man.set_cleanup_func(
|
||||
StoredFunc(self._cleanup_on_failure)
|
||||
)
|
||||
if len(servers) == 0:
|
||||
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_failure))
|
||||
return
|
||||
@ -161,7 +175,9 @@ class ServerModelManager:
|
||||
continue
|
||||
servers.append(res)
|
||||
if len(servers) == 0:
|
||||
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_failure))
|
||||
self.thread_man.set_cleanup_func(
|
||||
StoredFunc(self._cleanup_on_failure)
|
||||
)
|
||||
return
|
||||
|
||||
parsed = Servers.parse_json(servers)
|
||||
@ -200,8 +216,8 @@ class ServerModelManager:
|
||||
# NOTE: this can be called from other tabs--if current focus is not ServerTab.SAVED, update label only
|
||||
# TODO: saved servers might not be loaded yet, in which case should just update local file only
|
||||
# TODO: perform simple equality comparison of self.tv.get_enum() == ServerTab.SAVED
|
||||
# FIXME: filter man is saved on a per tab basis, so this will mismatch
|
||||
# check if servers.get_active_treeview() is same as self.tv
|
||||
# FIXME: filter man is saved on a per tab basis, so this will mismatch
|
||||
# check if servers.get_active_treeview() is same as self.tv
|
||||
self.set_cleanup_func(StoredFunc(self._cleanup_on_insert))
|
||||
|
||||
def _dump_history(self) -> None:
|
||||
@ -211,10 +227,14 @@ class ServerModelManager:
|
||||
with open(history, "r") as f:
|
||||
rows = [row.rstrip("\n") for row in f]
|
||||
except OSError:
|
||||
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_failure, False))
|
||||
self.thread_man.set_cleanup_func(
|
||||
StoredFunc(self._cleanup_on_failure, False)
|
||||
)
|
||||
return
|
||||
if len(rows) == 0:
|
||||
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_failure, False))
|
||||
self.thread_man.set_cleanup_func(
|
||||
StoredFunc(self._cleanup_on_failure, False)
|
||||
)
|
||||
return
|
||||
self.thread_man.set_job_count(len(rows))
|
||||
self._dump_ips(rows)
|
||||
@ -226,7 +246,9 @@ class ServerModelManager:
|
||||
if len(ips) == 0:
|
||||
# FIXME: this is not a failure, just a quiet exit with custom statusbar
|
||||
# TODO: add custom statusbar parameters
|
||||
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_failure, False))
|
||||
self.thread_man.set_cleanup_func(
|
||||
StoredFunc(self._cleanup_on_failure, False)
|
||||
)
|
||||
return
|
||||
self._dump_ips(ips)
|
||||
|
||||
@ -273,10 +295,10 @@ class ServerModelManager:
|
||||
self.new_maps = None
|
||||
|
||||
def _cleanup_on_failure(self, show_dialog=True) -> None:
|
||||
map_man = self.treeview.get_map_man()
|
||||
map_man = self.tv.get_map_man()
|
||||
|
||||
# TODO: disable map, keyword, and filter widgets if model is None
|
||||
# -> signal driven (servers_empty, servers_failed_to_load)
|
||||
# -> signal driven (servers_empty, servers_failed_to_load)
|
||||
# TODO: what if refresh action occurred and failed, and the old model is still valid?
|
||||
# skip the step below if refresh action failed
|
||||
# do not wipe control model in this case
|
||||
@ -284,15 +306,15 @@ class ServerModelManager:
|
||||
# revert old model
|
||||
# wipe refresh state to False
|
||||
|
||||
self.treeview.set_model(None)
|
||||
self.tv.set_model(None)
|
||||
map_man.set_unique_maps(None)
|
||||
context = self.treeview.get_enum()
|
||||
context = self.tv.get_enum()
|
||||
|
||||
# TODO: distinguish signals, e.g. "servers_failed_to_load", "servers_loaded_empty"
|
||||
# customize statusbar accordingly
|
||||
# customize statusbar and dialog accordingly
|
||||
self.emitter.emit("servers_loaded", context)
|
||||
if show_dialog:
|
||||
dialog = ExceptionDialog(self, strings.api_warn_msg)
|
||||
dialog = ExceptionDialog(self.controller, api_warn_msg)
|
||||
dialog.run()
|
||||
|
||||
# TODO: break into initial dump and refilter modes, can drop filtermode kwarg
|
||||
@ -330,9 +352,9 @@ class ServerModelManager:
|
||||
# self.cleanup_func = StoredFunc(self.cleanup_on_success)
|
||||
|
||||
# TODO: call filter_man methods directly
|
||||
#def refilter_model(self, mode: FilterMode, label: Optional[str] = None) -> None:
|
||||
# tv = self.get_active_treeview()
|
||||
# filter_man = tv.get_filter_man()
|
||||
# if filter_man.get_control() is None:
|
||||
# return
|
||||
# self.filter_threaded(filter_man, mode, label)
|
||||
def refilter_model(self, mode: FilterMode, label: Optional[str] = None) -> None:
|
||||
tv = self.get_active_treeview()
|
||||
self.filter_man = tv.get_filter_man()
|
||||
if self.filter_man.get_control() is None:
|
||||
return
|
||||
self.filter_threaded(self.filter_man, mode, label)
|
||||
|
||||
@ -132,7 +132,8 @@ servers = {
|
||||
"Ctrl-p": "refresh ping",
|
||||
"Ctrl-f": "jump to keyword search field",
|
||||
"Ctrl-m": "jump to maps field",
|
||||
"Ctrl-d": "toggle dry run (debug) mode",
|
||||
"Ctrl-d": "select default LAN port",
|
||||
"Ctrl-n": "select custom LAN port",
|
||||
"Ctrl-i": "jump to IP insert field",
|
||||
"ESC": "return to table",
|
||||
"1-9": "toggle filter 1-9 on/off",
|
||||
|
||||
@ -32,9 +32,11 @@ class LanPanel(Gtk.Frame):
|
||||
label = BoldLabel(lan_panel.heading)
|
||||
self.set_label_widget(label)
|
||||
|
||||
self.radio1 = Gtk.RadioButton.new_with_label(None, lan_panel.default_button)
|
||||
radio2 = Gtk.RadioButton.new_with_label_from_widget(
|
||||
self.radio1, lan_panel.custom_button
|
||||
self.default_radio = Gtk.RadioButton.new_with_label(
|
||||
None, lan_panel.default_button
|
||||
)
|
||||
self.custom_radio = Gtk.RadioButton.new_with_label_from_widget(
|
||||
self.default_radio, lan_panel.custom_button
|
||||
)
|
||||
|
||||
self.entry = PortEntry(controller)
|
||||
@ -47,18 +49,22 @@ class LanPanel(Gtk.Frame):
|
||||
"Unless you have multiple DayZ servers on your LAN,\nleave this checked to get results faster"
|
||||
)
|
||||
|
||||
self.entry.connect("activate", self._on_entry_activated)
|
||||
self.entry.connect("string_validated", self._on_port_validated)
|
||||
self.emitter.connect("request_custom_port_focus", self._on_custom_port_binding)
|
||||
self.emitter.connect(
|
||||
"request_lan_entry_focus", lambda _: self.entry.grab_focus()
|
||||
"request_default_port_focus", lambda _: self.default_radio.set_active(True)
|
||||
)
|
||||
self.radio1.connect("toggled", self._on_radio_toggled)
|
||||
self.default_radio.connect("toggled", self._on_radio_toggled)
|
||||
|
||||
self.grid = Gtk.Grid(margin=10, vexpand=False, column_spacing=15, row_spacing=5)
|
||||
self.grid.attach(self.radio1, 0, 0, COLS, ROWS)
|
||||
self.grid.attach(self.default_radio, 0, 0, COLS, ROWS)
|
||||
self.grid.attach_next_to(
|
||||
radio2, self.radio1, Gtk.PositionType.RIGHT, COLS, ROWS
|
||||
self.custom_radio, self.default_radio, Gtk.PositionType.RIGHT, COLS, ROWS
|
||||
)
|
||||
self.grid.attach_next_to(
|
||||
self.entry, self.custom_radio, Gtk.PositionType.RIGHT, COLS, ROWS
|
||||
)
|
||||
self.grid.attach_next_to(self.entry, radio2, Gtk.PositionType.RIGHT, COLS, ROWS)
|
||||
self.grid.attach_next_to(
|
||||
self.scan, self.entry, Gtk.PositionType.RIGHT, COLS, ROWS
|
||||
)
|
||||
@ -70,23 +76,36 @@ class LanPanel(Gtk.Frame):
|
||||
|
||||
self.entry.set_sensitive(False)
|
||||
|
||||
def _on_custom_port_binding(self, emitter: "Emitter") -> None:
|
||||
self.custom_radio.set_active(True)
|
||||
self.entry.grab_focus()
|
||||
|
||||
def _on_entry_activated(self, entry: Gtk.Entry) -> None:
|
||||
if self.entry.get_text() == "":
|
||||
return
|
||||
self.scan_ports()
|
||||
|
||||
def _on_scan_clicked(self, button: Gtk.Button) -> None:
|
||||
if self.radio1.get_active():
|
||||
self.scan_ports()
|
||||
|
||||
def scan_ports(self) -> None:
|
||||
if self.default_radio.get_active():
|
||||
port = 27016
|
||||
else:
|
||||
port = self.entry.get_text()
|
||||
abort = self.early_abort.get_active()
|
||||
smm = ServerModelManager(self.controller, self.controller.get_active_treeview())
|
||||
smm.dump_lan(int(port), abort)
|
||||
#self.controller.dump_lan(int(port), abort)
|
||||
|
||||
def _on_radio_toggled(self, button: Gtk.RadioButton) -> None:
|
||||
state = button.get_active()
|
||||
self.entry.set_sensitive(not state)
|
||||
if state:
|
||||
self.scan.set_sensitive(True)
|
||||
elif len(self.entry.get_text()) < 1:
|
||||
self.scan.set_sensitive(False)
|
||||
else:
|
||||
self.entry.grab_focus()
|
||||
if len(self.entry.get_text()) < 1:
|
||||
self.scan.set_sensitive(False)
|
||||
|
||||
def _on_port_validated(self, entry: Gtk.Entry, state: bool) -> None:
|
||||
self.scan.set_sensitive(state)
|
||||
@ -182,9 +201,13 @@ class AddPanel(Gtk.Frame):
|
||||
|
||||
def _submit_query(self) -> None:
|
||||
text = self.entry.get_text()
|
||||
self.controller.add_by_id_or_ip(text)
|
||||
# TODO: call servermodelmanager
|
||||
ServerModelManager().add_by_id_or_ip(text)
|
||||
# self.controller.add_by_id_or_ip(text)
|
||||
|
||||
def _on_activate(self, entry: Gtk.Entry) -> None:
|
||||
if not self.add_server.is_sensitive():
|
||||
return
|
||||
self._submit_query()
|
||||
|
||||
def _on_add_clicked(self, button: Gtk.Button) -> None:
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import logging
|
||||
|
||||
from typing import Self, TYPE_CHECKING
|
||||
from typing import Optional, Self, TYPE_CHECKING
|
||||
|
||||
from dzgui.controllers.mc import StoredFunc
|
||||
from dzgui.const.enum import ContextMenuGroup, ServerTab
|
||||
@ -76,13 +76,13 @@ class ServerNotebook(Gtk.ScrolledWindow):
|
||||
def _on_unmap(self, widget: Self) -> None:
|
||||
self.emitter.emit("server_page_toggled", False)
|
||||
|
||||
def _on_keypress(self, widget: Self, event: Gdk.EventKey) -> None:
|
||||
def _on_keypress(self, widget: Self, event: Gdk.EventKey) -> Optional[False]:
|
||||
if event.state is Gdk.ModifierType.CONTROL_MASK:
|
||||
return False
|
||||
match event.keyval:
|
||||
case Gdk.KEY_n:
|
||||
self.notebook.next_page()
|
||||
case Gdk.KEY_p:
|
||||
if event.state is Gdk.ModifierType.CONTROL_MASK:
|
||||
return
|
||||
self.notebook.prev_page()
|
||||
case _:
|
||||
return
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import logging
|
||||
from typing import Any, TYPE_CHECKING
|
||||
|
||||
from dzgui.const.constants import HEX_RED
|
||||
from dzgui.const.enum import ContextMenuGroup
|
||||
from dzgui.util import strings, localize
|
||||
from dzgui.views.trees.tree_base import TreeView
|
||||
from dzgui.views.mixins.context_mixin import ContextMixin
|
||||
from dzgui.views.mixins.mods_mixin import ModsMixin
|
||||
from dzgui.const.enum import ContextMenuGroup
|
||||
from dzgui.views.trees.tree_base import TreeView
|
||||
|
||||
import gi
|
||||
|
||||
@ -35,14 +36,15 @@ class ModTreeView(ModsMixin, ContextMixin, TreeView):
|
||||
|
||||
for i, column_title in enumerate(strings.mod_cols):
|
||||
renderer = Gtk.CellRendererText()
|
||||
column = Gtk.TreeViewColumn(column_title, renderer, text=i, foreground=4)
|
||||
if i == 3:
|
||||
column = Gtk.TreeViewColumn(column_title, renderer, text=i)
|
||||
column.set_cell_data_func(renderer, self._format_color, func_data=None)
|
||||
if i == 4:
|
||||
column.set_cell_data_func(renderer, self._format_float, func_data=None)
|
||||
|
||||
if column_title == "Mod":
|
||||
column.set_fixed_width(500)
|
||||
else:
|
||||
column.set_fixed_width(150)
|
||||
# NOTE: hidden color property column
|
||||
column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
|
||||
column.set_sort_column_id(i)
|
||||
if i != 4:
|
||||
@ -88,6 +90,21 @@ class ModTreeView(ModsMixin, ContextMixin, TreeView):
|
||||
def _parent_selection_changed(self, base_class: TreeView, sel: Gtk.TreeSelection):
|
||||
pass
|
||||
|
||||
def _format_color(
|
||||
self,
|
||||
column: Gtk.TreeViewColumn,
|
||||
cell: Gtk.CellRendererText,
|
||||
model: Gtk.TreeModel,
|
||||
it: Gtk.TreeIter,
|
||||
data: Any,
|
||||
) -> Any:
|
||||
state = model[it][4]
|
||||
if state is True:
|
||||
cell.set_property("foreground", HEX_RED)
|
||||
else:
|
||||
cell.set_property("foreground", None)
|
||||
return
|
||||
|
||||
def _format_float(
|
||||
self,
|
||||
column: Gtk.TreeViewColumn,
|
||||
|
||||
@ -8,12 +8,11 @@ from warnings import deprecated
|
||||
from dzgui.views.mixins.context_mixin import ContextMixin
|
||||
from dzgui.const.enum import ContextMenu, ContextMenuGroup, ServerTab
|
||||
from dzgui.api.servers import Record
|
||||
from dzgui.api.servers import ping as Ping
|
||||
from dzgui.model.map_model import MapManager
|
||||
from dzgui.model.filtered_model import FilteredModelManager
|
||||
from dzgui.util.dist import CalcDist
|
||||
from dzgui.util import strings
|
||||
from typing import Callable, Literal, TYPE_CHECKING
|
||||
from typing import Literal, TYPE_CHECKING
|
||||
|
||||
|
||||
from dzgui.views.trees.tree_base import TreeView
|
||||
@ -28,7 +27,7 @@ from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller, StoredFunc
|
||||
from dzgui.controllers.mc import Controller
|
||||
from dzgui.controllers.emitter import Emitter
|
||||
|
||||
QUEUE_CHECK_DELAY = 200
|
||||
@ -216,7 +215,7 @@ class ServerTreeView(ContextMixin, TreeView):
|
||||
while not self.queue.empty():
|
||||
latest_result = self.queue.get()
|
||||
|
||||
# FIXME: cache is being checked at two intervals
|
||||
# FIXME: cache is being checked in two passes
|
||||
cache = self.controller.get_dist_cache()
|
||||
|
||||
if latest_result:
|
||||
@ -239,9 +238,11 @@ class ServerTreeView(ContextMixin, TreeView):
|
||||
self.emitter.emit("request_maps_focus")
|
||||
case Gdk.KEY_i:
|
||||
self.emitter.emit("request_ip_entry_focus")
|
||||
case Gdk.KEY_p:
|
||||
case Gdk.KEY_d:
|
||||
self.emitter.emit("request_default_port_focus")
|
||||
case Gdk.KEY_n:
|
||||
if self.enum is ServerTab.LAN:
|
||||
self.emitter.emit("request_lan_entry_focus")
|
||||
self.emitter.emit("request_custom_port_focus")
|
||||
case Gdk.KEY_c:
|
||||
self.controller.menu_action(ContextMenu.COPY_SERVER_IP, self)
|
||||
case Gdk.KEY_r:
|
||||
@ -294,23 +295,12 @@ class ServerTreeView(ContextMixin, TreeView):
|
||||
return f"{addr}:{qport}"
|
||||
|
||||
def get_record(self) -> Record | None:
|
||||
# TODO: clean up, use tree_base.get_selected_row()
|
||||
select = self.get_selection()
|
||||
sels = select.get_selected_rows()
|
||||
(model, pathlist) = sels
|
||||
if len(pathlist) < 1:
|
||||
r = self.get_record_string()
|
||||
try:
|
||||
ip, gameport, qport = r.split(":")
|
||||
return Record(ip, int(gameport), int(qport))
|
||||
except ValueError:
|
||||
return None
|
||||
path = pathlist[0]
|
||||
model = self.get_model()
|
||||
if not model:
|
||||
return None
|
||||
addr = model[path][7]
|
||||
if addr is None:
|
||||
return
|
||||
qport = model[path][8]
|
||||
ip = addr.split(":")[0]
|
||||
gameport = int(addr.split(":")[1])
|
||||
return Record(ip, gameport, qport)
|
||||
|
||||
def is_loaded(self) -> bool:
|
||||
return self.loaded
|
||||
@ -348,7 +338,7 @@ class ServerTreeView(ContextMixin, TreeView):
|
||||
# thread = threading.Thread(
|
||||
# daemon=True,
|
||||
# target=ping_server,
|
||||
# args=(model, it, ip, qport, ping),
|
||||
# args=(model, it, addr, qport, ping),
|
||||
# )
|
||||
# thread.start()
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user