Merge pull request #534 from aclist/chore/strict-typehinting

chore: clear strict typehinting errors
This commit is contained in:
aclist authored and GitHub committed 2026-11-11 03:19:29 +09:00
commit f2d21be347
39 files changed
+131 -155

No files matched your search

+2 -1
View File
@@ -111,7 +111,8 @@ class WorkshopACF(ACF):
def __init__(self, file: Path) -> None: def __init__(self, file: Path) -> None:
super().__init__(file) super().__init__(file)
def unpack(self, d: dict, lines: list[Any] = []) -> str: def unpack(self, d: dict[str, Any], lines: list[Any] = []) -> str:
self.indent: int
t1 = "AppWorkshop" t1 = "AppWorkshop"
t2 = ("WorkshopItemsInstalled", "WorkshopItemDetails") t2 = ("WorkshopItemsInstalled", "WorkshopItemDetails")
for k, v in d.items(): for k, v in d.items():
+1 -5
View File
@@ -106,10 +106,6 @@ def get_delimited_mods(steam_path: Path) -> list[Any]:
return parse_mods(mods) return parse_mods(mods)
def get_missing_mods(local: list, remote: list) -> list:
return [mod for mod in remote if mod not in local]
def _hash(uid: str, use_custom: bool = False) -> str: def _hash(uid: str, use_custom: bool = False) -> str:
md5 = hashlib.md5() md5 = hashlib.md5()
md5.update(uid.encode("ascii")) md5.update(uid.encode("ascii"))
@@ -144,7 +140,7 @@ def remove_stale_signatures(
def find_stale_mods(config: Path) -> list[int]: def find_stale_mods(config: Path) -> list[int]:
def push_record(rec: str) -> list: def push_record(rec: str) -> list[int]:
record = fqip_to_record(rec) record = fqip_to_record(rec)
if record is None: if record is None:
return [] return []
+6 -4
View File
@@ -111,7 +111,7 @@ def get_netmask() -> str:
# TODO: rename # TODO: rename
def test_ip(suffix: int, port: int, event: threading.Event) -> dict | None: def test_ip(suffix: int, port: int, event: threading.Event) -> dict[str, Any] | None:
if event.is_set(): if event.is_set():
return None return None
netmask = get_netmask() netmask = get_netmask()
@@ -139,7 +139,9 @@ def sanitize(name: str) -> str:
return name return name
def parse_json(json: list) -> list: def parse_json(
json: list[dict[str, Any]],
) -> list[tuple[str, str, str, str, int, int, int, str, int, int, str, bool]]:
""" """
Server metadata is underspecified and server operators Server metadata is underspecified and server operators
tend to insert random garbage in the headers. In case tend to insert random garbage in the headers. In case
@@ -507,14 +509,14 @@ def record_to_fqip(record: Record) -> str:
return f"{record.ip}:{record.gameport}:{record.qport}" return f"{record.ip}:{record.gameport}:{record.qport}"
def response_to_fqip(res: dict) -> str: def response_to_fqip(res: dict[str, Any]) -> str:
ip = res["addr"].split(":")[0] ip = res["addr"].split(":")[0]
gameport = res["gameport"] gameport = res["gameport"]
qport = res["addr"].split(":")[1] qport = res["addr"].split(":")[1]
return f"{ip}:{gameport}:{qport}" return f"{ip}:{gameport}:{qport}"
def response_to_record(res: dict) -> Record: def response_to_record(res: dict[str, Any]) -> Record:
ip = res["addr"].split(":")[0] ip = res["addr"].split(":")[0]
gameport = res["gameport"] gameport = res["gameport"]
qport = res["addr"].split(":")[1] qport = res["addr"].split(":")[1]
+2 -2
View File
@@ -51,7 +51,7 @@ def is_writeable(path_str: str) -> bool:
return True return True
def get_xdg_paths() -> dict: def get_xdg_paths() -> dict[str, Path]:
home = Path.home() home = Path.home()
xdg_paths = { xdg_paths = {
"XDG_CONFIG_HOME": home / ".config", "XDG_CONFIG_HOME": home / ".config",
@@ -73,7 +73,7 @@ def get_xdg_paths() -> dict:
return resolved_paths return resolved_paths
def parse_filepaths(xdg: dict) -> Xdg: def parse_filepaths(xdg: dict[str, Path]) -> Xdg:
config = xdg["XDG_CONFIG_HOME"] config = xdg["XDG_CONFIG_HOME"]
state = xdg["XDG_STATE_HOME"] state = xdg["XDG_STATE_HOME"]
share = xdg["XDG_DATA_HOME"] share = xdg["XDG_DATA_HOME"]
+6 -6
View File
@@ -77,7 +77,7 @@ class AppNavigation:
class Controller(GObject.GObject): class Controller(GObject.GObject):
def __init__(self) -> None: def __init__(self) -> None:
self.dist_cache: dict[str, "Haversine"] = {} self.dist_cache: dict[str, "Haversine" | None] = {}
self.mediator = AppNavigation() self.mediator = AppNavigation()
self.prefs: UserPrefs self.prefs: UserPrefs
@@ -274,7 +274,7 @@ class Controller(GObject.GObject):
except Exception as e: except Exception as e:
dialog = ExceptionDialog(self, str(e)) dialog = ExceptionDialog(self, str(e))
dialog.show_all() dialog.show_all()
dialog.run() dialog.run() # type: ignore[no-untyped-call]
def select_colorized(self) -> None: def select_colorized(self) -> None:
mod_man = self.mediator.modtreeview.get_mod_man() mod_man = self.mediator.modtreeview.get_mod_man()
@@ -308,7 +308,7 @@ class Controller(GObject.GObject):
except Exception as e: except Exception as e:
dialog = ExceptionDialog(self, str(e)) dialog = ExceptionDialog(self, str(e))
dialog.show_all() dialog.show_all()
dialog.run() dialog.run() # type: ignore[no-untyped-call]
def update_steam_api_key(self, text: str) -> None: def update_steam_api_key(self, text: str) -> None:
self.config_man.update_steam_api_key(text) self.config_man.update_steam_api_key(text)
@@ -355,17 +355,17 @@ class Controller(GObject.GObject):
filter_man.set_filter(filt, state) filter_man.set_filter(filt, state)
self.mediator.filters.set_filters(filters) self.mediator.filters.set_filters(filters)
def get_dist_cache(self) -> dict[str, "Haversine"]: def get_dist_cache(self) -> dict[str, Union["Haversine", None]]:
return self.dist_cache return self.dist_cache
def set_dist_cache(self, addr: str, haversine: "Haversine") -> None: def set_dist_cache(self, addr: str, haversine: Union["Haversine", None]) -> None:
self.dist_cache[addr] = haversine self.dist_cache[addr] = haversine
def get_map_store(self) -> Gtk.ListStore: def get_map_store(self) -> Gtk.ListStore:
filter_man = self.get_filter_man() filter_man = self.get_filter_man()
return filter_man.get_map_store() return filter_man.get_map_store()
def get_enabled_filters(self) -> dict: def get_enabled_filters(self) -> dict[str, bool]:
filter_man = self.get_filter_man() filter_man = self.get_filter_man()
return filter_man.get_filters() return filter_man.get_filters()
+1 -1
View File
@@ -162,7 +162,7 @@ class ConfigManager:
trace = traceback.format_exc() trace = traceback.format_exc()
dialog = ExceptionDialog(self.controller, trace) dialog = ExceptionDialog(self.controller, trace)
dialog.show_all() dialog.show_all()
dialog.run() dialog.run() # type: ignore[no-untyped-call]
def save_res_and_quit(self, tv: "ServerTreeView", window: "OuterWindow") -> None: def save_res_and_quit(self, tv: "ServerTreeView", window: "OuterWindow") -> None:
columns = tv.get_columns() columns = tv.get_columns()
+4 -4
View File
@@ -291,22 +291,22 @@ class ConnectionManager:
def _present_modlist_dialog(self, mods: list[list[str]]) -> None: def _present_modlist_dialog(self, mods: list[list[str]]) -> None:
dialog = ServerModDialog(self.controller, mods) dialog = ServerModDialog(self.controller, mods)
dialog.run() dialog.run() # type: ignore[no-untyped-call]
def _present_details_dialog(self, details: Servers.Details) -> None: def _present_details_dialog(self, details: Servers.Details) -> None:
dialog = ServerDetailsDialog(self.controller, details) dialog = ServerDetailsDialog(self.controller, details)
dialog.run() dialog.run() # type: ignore[no-untyped-call]
def _workshop_timeout(self, msg: str) -> None: def _workshop_timeout(self, msg: str) -> None:
dialog = ExceptionDialog(self.controller, msg) dialog = ExceptionDialog(self.controller, msg)
dialog.show_all() dialog.show_all()
dialog.run() dialog.run() # type: ignore[no-untyped-call]
def _server_timeout(self) -> None: def _server_timeout(self) -> None:
dialog = ExceptionDialog(self.controller, server_timeout) dialog = ExceptionDialog(self.controller, server_timeout)
dialog.set_details_buffer(kb.DZG_006) dialog.set_details_buffer(kb.DZG_006)
dialog.show_all() dialog.show_all()
dialog.run() dialog.run() # type: ignore[no-untyped-call]
def get_debug_args(self) -> str: def get_debug_args(self) -> str:
addr = f"{self.record.ip}:{self.record.gameport}" addr = f"{self.record.ip}:{self.record.gameport}"
+1 -1
View File
@@ -44,7 +44,7 @@ class ContextMenuManager:
# UNTHREADED # UNTHREADED
case ContextMenu.ADD_NOTE: case ContextMenu.ADD_NOTE:
dialog = NoteDialog(self.controller) dialog = NoteDialog(self.controller)
dialog.run() dialog.run() # type: ignore[no-untyped-call]
case ContextMenu.COPY_SERVER_IP: case ContextMenu.COPY_SERVER_IP:
self.copy_server_ip() self.copy_server_ip()
case ContextMenu.COPY_SERVER_NAME: case ContextMenu.COPY_SERVER_NAME:
+2 -3
View File
@@ -51,7 +51,6 @@ class FilterManager:
self.active_map = (0, all_maps) self.active_map = (0, all_maps)
self.prior_map = all_maps self.prior_map = all_maps
self.filters: list
self.enabled_filters = dict(self.default_filters) self.enabled_filters = dict(self.default_filters)
def get_tooltips(self) -> dict[str, str]: def get_tooltips(self) -> dict[str, str]:
@@ -75,11 +74,11 @@ class FilterManager:
def set_active_keyword(self, word: str) -> None: def set_active_keyword(self, word: str) -> None:
self.active_keyword = word self.active_keyword = word
def get_default_filters(self) -> dict: def get_default_filters(self) -> dict[str, bool]:
"""Deep copy of defaults""" """Deep copy of defaults"""
return dict(self.default_filters) return dict(self.default_filters)
def get_filters(self) -> dict: def get_filters(self) -> dict[str, bool]:
return self.enabled_filters return self.enabled_filters
def set_filter(self, label: str, state: bool) -> None: def set_filter(self, label: str, state: bool) -> None:
+1 -1
View File
@@ -221,7 +221,7 @@ class ModManager:
total_size += mod[3] total_size += mod[3]
return total_mods, total_size return total_mods, total_size
def _on_stale_mods_found(self, stale_mods: list) -> None: def _on_stale_mods_found(self, stale_mods: list[int]) -> None:
"""Manipulates attached ListStore in the main event loop""" """Manipulates attached ListStore in the main event loop"""
model = self.treeview.get_model() model = self.treeview.get_model()
if model is None: if model is None:
+1 -1
View File
@@ -52,7 +52,7 @@ class OfflineManager:
is_valid = is_mission(folder) is_valid = is_mission(folder)
self.emitter.emit("custom_mission_loaded", str(folder), is_valid) self.emitter.emit("custom_mission_loaded", str(folder), is_valid)
def find_custom_mods(self, callback: Callable) -> None: def find_custom_mods(self, callback: Callable[[], None]) -> None:
folder = self.open_folderpicker(dialogs.custom_mod_dialog) folder = self.open_folderpicker(dialogs.custom_mod_dialog)
window = self.controller.get_window() window = self.controller.get_window()
window.set_sensitive(False) window.set_sensitive(False)
+3 -3
View File
@@ -22,8 +22,8 @@ logger = logging.getLogger(APP_NAME)
def call_on_thread( def call_on_thread(
dialog_str: str, show_dialog: bool = True, show_cancel: bool = False dialog_str: str, show_dialog: bool = True, show_cancel: bool = False
) -> Callable: ) -> Callable[..., Any]:
def decorator(func: Callable) -> Callable: def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
@wraps(func) @wraps(func)
def wrapper(*args: Any, **kwargs: Any) -> None: def wrapper(*args: Any, **kwargs: Any) -> None:
self = args[0] self = args[0]
@@ -42,7 +42,7 @@ def call_on_thread(
class StoredFunc: class StoredFunc:
def __init__(self, func: Callable, *args: Any, **kwargs: Any) -> None: def __init__(self, func: Callable[..., Any], *args: Any, **kwargs: Any) -> None:
sig = inspect.signature(func) sig = inspect.signature(func)
self.func = func self.func = func
self.bindings = sig.bind(*args, **kwargs) self.bindings = sig.bind(*args, **kwargs)
+2 -2
View File
@@ -55,9 +55,9 @@ class UpdateManager:
def _on_update_success(self) -> None: def _on_update_success(self) -> None:
msg = dialogs.update_success msg = dialogs.update_success
dialog = QuitDialog(self.controller, msg) dialog = QuitDialog(self.controller, msg)
dialog.run() dialog.run() # type: ignore[no-untyped-call]
def _on_update_failure(self, msg: str) -> None: def _on_update_failure(self, msg: str) -> None:
dialog = ExceptionDialog(self.controller, msg) dialog = ExceptionDialog(self.controller, msg)
dialog.show_all() dialog.show_all()
dialog.run() dialog.run() # type: ignore[no-untyped-call]
+1 -1
View File
@@ -11,7 +11,7 @@ from gi.repository.Gtk import ListStore, TreeIter
from gi.repository import GObject from gi.repository import GObject
GTYPE_TO_PYTHON = { GTYPE_TO_PYTHON = {
GObject.type_from_name(GObject.type_name(ptype)): ptype GObject.type_from_name(GObject.type_name(ptype)): ptype # type: ignore[no-untyped-call]
for ptype in (int, float, str, bool, object) for ptype in (int, float, str, bool, object)
} }
+20 -7
View File
@@ -1,5 +1,6 @@
import re import re
from dataclasses import dataclass
from typing import Any, TYPE_CHECKING, Union from typing import Any, TYPE_CHECKING, Union
from dzgui.const.enum import FilterMode from dzgui.const.enum import FilterMode
@@ -17,6 +18,22 @@ DAY_REG = r"([0][6-9]|[1][0-7])"
NIGHT_REG = r"([0][0-5]|[1][8-9]|[2][0-3])" NIGHT_REG = r"([0][0-5]|[1][8-9]|[2][0-3])"
@dataclass(slots=True, frozen=True)
class ServerRow:
name: str
mapname: str
view: str
time: str
players: int
max_players: int
queue: int
ip: str
qport: int
ping: str
provider: str
modded: bool
class ProxyModelManager: class ProxyModelManager:
""" """
Manages access to cached FastInsertListStore resources and Manages access to cached FastInsertListStore resources and
@@ -31,7 +48,7 @@ class ProxyModelManager:
def __init__(self, filter_man: "FilterManager") -> None: def __init__(self, filter_man: "FilterManager") -> None:
self.filter_cache: dict[ self.filter_cache: dict[
tuple[str], tuple[str, ...],
list[tuple[str, str, str, str, int, int, int, str, int, int, str, bool]], list[tuple[str, str, str, str, int, int, int, str, int, int, str, bool]],
] = {} ] = {}
@@ -52,9 +69,6 @@ class ProxyModelManager:
return False return False
return True return True
def append_row(self, row: list) -> None:
self.proxy_model.append(row)
def append_row_to_control( def append_row_to_control(
self, row: tuple[str, str, str, str, int, int, int, str, int, int, str, bool] self, row: tuple[str, str, str, str, int, int, int, str, int, int, str, bool]
) -> None: ) -> None:
@@ -68,7 +82,6 @@ class ProxyModelManager:
self.proxy_model[treeiter][4] = playercount.players self.proxy_model[treeiter][4] = playercount.players
self.proxy_model[treeiter][6] = playercount.queue self.proxy_model[treeiter][6] = playercount.queue
# TODO: use dataclass for record rows
def append_row_to_history( def append_row_to_history(
self, self,
history: tuple[str, str, str, str, int, int, int, str, int, int, str, bool], history: tuple[str, str, str, str, int, int, int, str, int, int, str, bool],
@@ -248,7 +261,7 @@ class ProxyModelManager:
rows = [row for row in rows if row[11]] rows = [row for row in rows if row[11]]
return rows return rows
def filter_toggle_on(self, filters: tuple[str]) -> list: def filter_toggle_on(self, filters: tuple[str, ...]) -> list:
"""Effectively applies all filters""" """Effectively applies all filters"""
self.set_filtered(self.control_model) self.set_filtered(self.control_model)
self.set_filtered(self.filter_map(filters)) self.set_filtered(self.filter_map(filters))
@@ -259,7 +272,7 @@ class ProxyModelManager:
self.set_filtered(self.filter_toggle_off(filters, f)) self.set_filtered(self.filter_toggle_off(filters, f))
return self.filtered return self.filtered
def set_cache(self, filters: tuple[str], filtered_rows: list[tuple]) -> None: def set_cache(self, filters: tuple[str, ...], filtered_rows: list[tuple]) -> None:
self.filter_cache[filters] = filtered_rows self.filter_cache[filters] = filtered_rows
def set_filtered(self, rows: list | None) -> None: def set_filtered(self, rows: list | None) -> None:
+3 -3
View File
@@ -432,7 +432,7 @@ class ServerModelManager:
if show_dialog: if show_dialog:
dialog = ExceptionDialog(self.controller, dialogs.load_error_lan) dialog = ExceptionDialog(self.controller, dialogs.load_error_lan)
dialog.show_all() dialog.show_all()
dialog.run() dialog.run() # type: ignore[no-untyped-call]
def _cleanup_on_failure(self, show_dialog: bool = True) -> None: def _cleanup_on_failure(self, show_dialog: bool = True) -> None:
# TODO: disable map, keyword, and filter widgets if model is None # TODO: disable map, keyword, and filter widgets if model is None
@@ -451,14 +451,14 @@ class ServerModelManager:
dialog = ExceptionDialog(self.controller, server_timeout) dialog = ExceptionDialog(self.controller, server_timeout)
dialog.set_details_buffer(kb.DZG_006) dialog.set_details_buffer(kb.DZG_006)
dialog.show_all() dialog.show_all()
dialog.run() dialog.run() # type: ignore[no-untyped-call]
def _push_data(self, data: list[Any]) -> None: def _push_data(self, data: list[Any]) -> None:
self._get_proxy_man().push(data) self._get_proxy_man().push(data)
self._sort_unique_maps(data) self._sort_unique_maps(data)
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_success)) self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_success))
def _sort_unique_maps(self, data: list) -> None: def _sort_unique_maps(self, data: list[Any]) -> None:
u_maps = set([row[1] for row in data]) u_maps = set([row[1] for row in data])
self._set_new_maps(sorted(u_maps)) self._set_new_maps(sorted(u_maps))
+2 -2
View File
@@ -54,7 +54,7 @@ class CalcDist:
self, self,
addr: str, addr: str,
enum: "ServerTab", enum: "ServerTab",
result_queue: "Queue", result_queue: "Queue[tuple[str, Haversine | None, ServerTab]]",
controller: "Controller", controller: "Controller",
cache: dict[str, Haversine], cache: dict[str, Haversine],
) -> None: ) -> None:
@@ -67,7 +67,7 @@ class CalcDist:
self.ip = self.addr self.ip = self.addr
dist = self.compare(self.ip) dist = self.compare(self.ip)
self.result_queue.put([self.addr, dist, self.enum]) self.result_queue.put((self.addr, dist, self.enum))
def compare(self, remote_ip: str) -> Haversine | None: def compare(self, remote_ip: str) -> Haversine | None:
prefs = self.controller.get_prefs() prefs = self.controller.get_prefs()
+6 -2
View File
@@ -1,12 +1,16 @@
import logging import logging
import subprocess import subprocess
from typing import TYPE_CHECKING
from dzgui.const.constants import APP_NAME, FLATPAK_APPID, GTK_APP_ID, TMP_PATH from dzgui.const.constants import APP_NAME, FLATPAK_APPID, GTK_APP_ID, TMP_PATH
logger = logging.getLogger(APP_NAME) logger = logging.getLogger(APP_NAME)
if TYPE_CHECKING:
from pathlib import Path
def apply_overrides(xdg: dict[str, str]) -> None:
def apply_overrides(xdg: dict[str, "Path"]) -> None:
try: try:
# NOTE: D-Bus registration required for sandbox # NOTE: D-Bus registration required for sandbox
args = [ args = [
@@ -19,7 +23,7 @@ def apply_overrides(xdg: dict[str, str]) -> None:
subprocess.run([*args], capture_output=True) subprocess.run([*args], capture_output=True)
paths: list[str] = [] paths: list[str] = []
paths.extend([*xdg.values()]) paths.extend([str(path) for path in xdg.values()])
paths.append(TMP_PATH) paths.append(TMP_PATH)
for path in paths: for path in paths:
+2 -1
View File
@@ -1,4 +1,5 @@
import re import re
from typing import Any
from dzgui.util.localize import number from dzgui.util.localize import number
from dzgui.strings.generic import selectable_tree from dzgui.strings.generic import selectable_tree
@@ -60,7 +61,7 @@ def format_server_mods(mods: int) -> str:
return f"Found {mods:n} {plural}. {workshop}" return f"Found {mods:n} {plural}. {workshop}"
def format_player_count(model: Gtk.TreeModel | None, control: list) -> str: def format_player_count(model: Gtk.TreeModel | None, control: list[Any]) -> str:
players = 0 players = 0
hits: int hits: int
status: str status: str
+1 -1
View File
@@ -31,7 +31,7 @@ class ReservedIPError(Exception):
pass pass
def ip2list(ip: str) -> list: def ip2list(ip: str) -> list[int]:
return [int(digit) for digit in ip.split(".")] return [int(digit) for digit in ip.split(".")]
+1
View File
@@ -118,6 +118,7 @@ servers = {
"0": "toggle filter 10", "0": "toggle filter 10",
"Minus": "toggle filter 11", "Minus": "toggle filter 11",
"Backslash": "toggle filter 12", "Backslash": "toggle filter 12",
"Apostrophe": "toggle filter 13",
} }
vim = { vim = {
"j": "Move down a row/scroll up", "j": "Move down a row/scroll up",
+5 -32
View File
@@ -1,10 +1,8 @@
from typing import Callable, Literal, Self, TYPE_CHECKING, Union from typing import Callable, Literal, Self, TYPE_CHECKING
from dzgui.util.clip import copy_clipboard from dzgui.util.clip import copy_clipboard
from dzgui.util.format import pluralize
from dzgui.strings import buttons from dzgui.strings import buttons
from dzgui.util.strings import ( from dzgui.util.strings import (
alert_button_tooltip,
atomic_buttons, atomic_buttons,
) )
from dzgui.const.icons import ( from dzgui.const.icons import (
@@ -64,7 +62,7 @@ class IconButton(Gtk.Button):
self.icon = Icon(icon, margin_start=margin_start, margin_end=margin_end) self.icon = Icon(icon, margin_start=margin_start, margin_end=margin_end)
self.set_image(self.icon) self.set_image(self.icon)
self.set_image_position(position) self.set_image_position(position)
self.set_focus_on_click(False) self.set_focus_on_click(False) # type: ignore[no-untyped-call]
self.set_always_show_image(True) self.set_always_show_image(True)
def swap_icon(self, icon: str) -> None: def swap_icon(self, icon: str) -> None:
@@ -108,7 +106,7 @@ class ClipboardButton(IconTextButton):
self.set_tooltip_text(buttons.clipboard_button) self.set_tooltip_text(buttons.clipboard_button)
def _on_button_clicked(self, button: Self, func: Callable) -> None: def _on_button_clicked(self, button: Self, func: Callable[[], str]) -> None:
def revert() -> Literal[False]: def revert() -> Literal[False]:
self.revert_icon() self.revert_icon()
return False return False
@@ -119,10 +117,9 @@ class ClipboardButton(IconTextButton):
GLib.timeout_add(600, revert) GLib.timeout_add(600, revert)
# TODO: determine when controller would be passed to this button or drop
class CopyIpButton(ClipboardButton): class CopyIpButton(ClipboardButton):
def __init__(self, controller: Union["Controller", None], func: Callable) -> None: def __init__(self, func: Callable[[], str]) -> None:
super().__init__(controller, func) super().__init__(func)
self.set_tooltip_text(buttons.clipboard_ip_button) self.set_tooltip_text(buttons.clipboard_ip_button)
@@ -249,30 +246,6 @@ class AddButton(IconTextButton):
self.set_tooltip_text(connect_panel.add_tooltip) self.set_tooltip_text(connect_panel.add_tooltip)
# TODO: drop
class LoggerAlertsButton(IconTextButton):
def __init__(self, warnings: int, errors: int) -> None:
warnings_text = ""
errors_text = ""
separator = ""
if warnings > 0:
warnings_plural = pluralize("warnings", warnings)
warnings_text = f"{warnings} {warnings_plural}"
if errors > 0:
errors_plural = pluralize("errors", errors)
errors_text = f" {errors} {errors_plural}"
if warnings + errors > 1:
separator = ","
concat = warnings_text + separator + errors_text
super().__init__(
icon=ICON_WARNING,
label=f"Loaded with{concat}",
)
self.set_halign(Gtk.Align.END)
self.set_hexpand(True)
self.set_tooltip_text(alert_button_tooltip)
class SpinnerButton(Gtk.Button): class SpinnerButton(Gtk.Button):
def __init__(self, label: str) -> None: def __init__(self, label: str) -> None:
super().__init__() super().__init__()
+1 -1
View File
@@ -189,7 +189,7 @@ class FavPanel(Gtk.Frame):
self.fav_button = SteamConnectButton() self.fav_button = SteamConnectButton()
self.fav_button.connect("clicked", self._on_connect_clicked) self.fav_button.connect("clicked", self._on_connect_clicked)
self.copy_button = CopyIpButton(self.controller, self.get_fav_ip) self.copy_button = CopyIpButton(self.get_fav_ip)
self.unset_button = CloseButton(unset_button_label) self.unset_button = CloseButton(unset_button_label)
self.unset_button.connect("clicked", self._on_unset_clicked) self.unset_button.connect("clicked", self._on_unset_clicked)
+4 -5
View File
@@ -39,7 +39,7 @@ class ValidatedEntry(Gtk.Entry):
def __init__( def __init__(
self, self,
controller: "Controller", controller: "Controller",
func: Callable, func: Callable[[str], bool],
placeholder_text: str = "", placeholder_text: str = "",
tooltip_text: str = "", tooltip_text: str = "",
) -> None: ) -> None:
@@ -47,7 +47,6 @@ class ValidatedEntry(Gtk.Entry):
hexpand=True, placeholder_text=placeholder_text, tooltip_text=tooltip_text hexpand=True, placeholder_text=placeholder_text, tooltip_text=tooltip_text
) )
self.func: Callable
self.set_validation_func(func) self.set_validation_func(func)
self.controller = controller self.controller = controller
@@ -73,7 +72,7 @@ class ValidatedEntry(Gtk.Entry):
self.emit("string_validated", False) self.emit("string_validated", False)
remove_class(self, self.classname) remove_class(self, self.classname)
def set_validation_func(self, func: Callable) -> None: def set_validation_func(self, func: Callable[[str], bool]) -> None:
self.func = func self.func = func
def insert_icon(self) -> None: def insert_icon(self) -> None:
@@ -142,7 +141,7 @@ class APIEntry(Gtk.Box):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) super().__init__(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
self.func: Callable | None = None self.func: Callable[[str], None] | None = None
self.entry = Gtk.Entry( self.entry = Gtk.Entry(
width_chars=60, hexpand=True, placeholder_text=api_placeholder width_chars=60, hexpand=True, placeholder_text=api_placeholder
@@ -221,7 +220,7 @@ class APIEntry(Gtk.Box):
res = self.func(text) res = self.func(text)
return res return res
def set_validation_func(self, func: Callable | None) -> None: def set_validation_func(self, func: Callable[[str], None] | None) -> None:
self.func = func self.func = func
def disable_button(self) -> None: def disable_button(self) -> None:
+3 -2
View File
@@ -31,7 +31,7 @@ class ButtonGrid(Gtk.Grid):
def __init__( def __init__(
self, self,
controller: "Controller", controller: "Controller",
defaults: dict[str, str], defaults: dict[str, bool],
tooltips: dict[str, str], tooltips: dict[str, str],
) -> None: ) -> None:
super().__init__( super().__init__(
@@ -97,7 +97,7 @@ class ButtonGrid(Gtk.Grid):
logger.info(f"User toggled button '{label}' to {state}") logger.info(f"User toggled button '{label}' to {state}")
self.emitter.emit("check_toggled", label, state) self.emitter.emit("check_toggled", label, state)
def get_checkboxes(self) -> list: def get_checkboxes(self) -> list[Gtk.CheckButton]:
return self.checks return self.checks
@@ -306,6 +306,7 @@ class FilterPanel(Gtk.Box):
Gdk.KEY_0: 9, Gdk.KEY_0: 9,
Gdk.KEY_minus: 10, Gdk.KEY_minus: 10,
Gdk.KEY_backslash: 11, Gdk.KEY_backslash: 11,
Gdk.KEY_apostrophe: 12,
} }
if keyval not in mappings: if keyval not in mappings:
return False return False
-4
View File
@@ -2,7 +2,6 @@ from typing import Self, Union, TYPE_CHECKING
from dzgui.const.enum import NotebookPage, ServerTab from dzgui.const.enum import NotebookPage, ServerTab
from dzgui.util.strings import esc_to_return, question_to_return from dzgui.util.strings import esc_to_return, question_to_return
from dzgui.views.components.buttons import LoggerAlertsButton
import gi import gi
@@ -47,9 +46,6 @@ class Statusbar(Gtk.Grid):
self.emitter.connect("servers_loaded", self._on_servers_loaded) self.emitter.connect("servers_loaded", self._on_servers_loaded)
self.emitter.connect("mods_updated", self._on_mods_updated) self.emitter.connect("mods_updated", self._on_mods_updated)
def _on_alerts_clicked(self, button: LoggerAlertsButton) -> None:
self.controller.populate_log()
def _on_mods_updated(self, emitter: "Emitter", msg: str, mods: int) -> None: def _on_mods_updated(self, emitter: "Emitter", msg: str, mods: int) -> None:
self.set_by_context(NotebookPage.MODS, msg) self.set_by_context(NotebookPage.MODS, msg)
+1 -1
View File
@@ -104,7 +104,7 @@ class BootDialog(ColorAwareApp, Gtk.Dialog): # type: ignore
self.error_label = Gtk.Label(margin_start=15, margin_end=15) self.error_label = Gtk.Label(margin_start=15, margin_end=15)
# TODO: abstract class # TODO: abstract class
self.copy_button = ClipboardButton(None, lambda: self.error_label.get_text()) self.copy_button = ClipboardButton(self.error_label.get_text)
self.button_hbox = Gtk.Box( self.button_hbox = Gtk.Box(
orientation=Gtk.Orientation.HORIZONTAL, halign=Gtk.Align.CENTER, spacing=10 orientation=Gtk.Orientation.HORIZONTAL, halign=Gtk.Align.CENTER, spacing=10
) )
+1 -1
View File
@@ -46,7 +46,7 @@ class AbortDialog(ColorAwareApp, Gtk.MessageDialog): # type: ignore
self.connect("response", self._on_response) self.connect("response", self._on_response)
self.run() self.run() # type: ignore[no-untyped-call]
self.destroy() self.destroy()
def _on_response(self, dialog: Self, response: Gtk.ResponseType) -> None: def _on_response(self, dialog: Self, response: Gtk.ResponseType) -> None:
+6 -6
View File
@@ -16,14 +16,14 @@ class FilePicker(Gtk.FileChooserDialog):
transient_for=parent, transient_for=parent,
resizable=True, resizable=True,
) )
self.add_buttons("_Cancel", Gtk.ResponseType.CANCEL) self.add_buttons("_Cancel", Gtk.ResponseType.CANCEL) # type: ignore[no-untyped-call]
self.add_buttons("_Save", Gtk.ResponseType.OK) self.add_buttons("_Save", Gtk.ResponseType.OK) # type: ignore[no-untyped-call]
self.set_default_response(Gtk.ResponseType.OK) self.set_default_response(Gtk.ResponseType.OK)
self.set_current_name(picker.placeholder) self.set_current_name(picker.placeholder)
def pick_file(self) -> Path | None: def pick_file(self) -> Path | None:
res = self.run() res = self.run() # type: ignore[no-untyped-call]
if res in (Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT): if res in (Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT):
self.destroy() self.destroy()
return None return None
@@ -43,12 +43,12 @@ class FolderPicker(Gtk.FileChooserDialog):
parent=parent, parent=parent,
resizable=True, resizable=True,
) )
self.add_buttons("_Cancel", Gtk.ResponseType.CANCEL) self.add_buttons("_Cancel", Gtk.ResponseType.CANCEL) # type: ignore[no-untyped-call]
self.add_buttons("_OK", Gtk.ResponseType.OK) self.add_buttons("_OK", Gtk.ResponseType.OK) # type: ignore[no-untyped-call]
self.set_default_response(Gtk.ResponseType.OK) self.set_default_response(Gtk.ResponseType.OK)
def pick_folder(self) -> Path | None: def pick_folder(self) -> Path | None:
res = self.run() res = self.run() # type: ignore[no-untyped-call]
if res in (Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT): if res in (Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT):
self.destroy() self.destroy()
return None return None
+1 -1
View File
@@ -185,7 +185,7 @@ class TextBufferDialog(GenericDialog):
secondary=secondary, secondary=secondary,
) )
self.text = text self.text = text
copy_button = ClipboardButton(controller, self.get_text) copy_button = ClipboardButton(self.get_text)
self.add_action_widget(copy_button, Gtk.ResponseType.NONE) self.add_action_widget(copy_button, Gtk.ResponseType.NONE)
self.add_button("OK", Gtk.ResponseType.OK) self.add_button("OK", Gtk.ResponseType.OK)
self.connect("response", self._on_response) self.connect("response", self._on_response)
+4 -4
View File
@@ -22,7 +22,7 @@ from gi.repository import Gtk, GLib, Pango
class Assistant(Gtk.Assistant): class Assistant(Gtk.Assistant):
def __init__(self, is_deck: bool, paths: dict[str, str]): def __init__(self, is_deck: bool, paths: dict[str, Path]):
super().__init__() super().__init__()
if is_deck: if is_deck:
# NOTE: deemed to be "safe" dimensions that exclude taskbar size # NOTE: deemed to be "safe" dimensions that exclude taskbar size
@@ -63,7 +63,7 @@ class Assistant(Gtk.Assistant):
class Window(Gtk.Window): class Window(Gtk.Window):
def __init__(self, is_deck: bool, paths: dict[str, str]) -> None: def __init__(self, is_deck: bool, paths: dict[str, Path]) -> None:
super().__init__(title=APP_NAME, icon_name=APP_NAME) super().__init__(title=APP_NAME, icon_name=APP_NAME)
self.assistant = Assistant(is_deck, paths) self.assistant = Assistant(is_deck, paths)
@@ -121,7 +121,7 @@ class CheckboxWithPath(CheckboxWithLabel):
class UninstallPage(ScrolledWizardPage): class UninstallPage(ScrolledWizardPage):
def __init__(self, paths: dict[str, str], pyapp: str | None): def __init__(self, paths: dict[str, Path], pyapp: str | None):
super().__init__(heading=uninstall.pg1_heading, description=uninstall.pg1_blurb) super().__init__(heading=uninstall.pg1_heading, description=uninstall.pg1_blurb)
self.pyapp = pyapp self.pyapp = pyapp
@@ -219,7 +219,7 @@ class UninstallPage(ScrolledWizardPage):
class UninstallWizard(ColorAwareApp, Gtk.Application): # type: ignore class UninstallWizard(ColorAwareApp, Gtk.Application): # type: ignore
def __init__(self, is_deck: bool, paths: dict[str, str]) -> None: def __init__(self, is_deck: bool, paths: dict[str, Path]) -> None:
super().__init__() super().__init__()
config = Path(paths["XDG_CONFIG_HOME"]) config = Path(paths["XDG_CONFIG_HOME"])
if not config.is_dir() or not config.joinpath("config.json").is_file(): if not config.is_dir() or not config.joinpath("config.json").is_file():
+10 -5
View File
@@ -168,7 +168,12 @@ class NotificationFrame(Gtk.Frame):
class APIValidationPage(EnumeratedWizardPage): class APIValidationPage(EnumeratedWizardPage):
def __init__( def __init__(
self, enum: PageNum, heading: str, description: str, link: str, func: Callable self,
enum: PageNum,
heading: str,
description: str,
link: str,
func: Callable[[str], None],
) -> None: ) -> None:
super().__init__( super().__init__(
enum=enum, enum=enum,
@@ -421,7 +426,7 @@ class PreferencesPage(EnumeratedWizardPage):
class FlatpakOverridePage(EnumeratedWizardPage): class FlatpakOverridePage(EnumeratedWizardPage):
def __init__(self, xdg_paths: dict[str, str]) -> None: def __init__(self, xdg_paths: dict[str, Path]) -> None:
super().__init__( super().__init__(
enum=PageNum.FLATPAK, enum=PageNum.FLATPAK,
heading=wizard.heading_flatpak, heading=wizard.heading_flatpak,
@@ -471,7 +476,7 @@ class CompletionPage(EnumeratedWizardPage):
class Assistant(Gtk.Assistant): class Assistant(Gtk.Assistant):
def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, str]): def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, Path]):
super().__init__() super().__init__()
if is_deck: if is_deck:
# NOTE: deemed to be "safe" dimensions that exclude taskbar size # NOTE: deemed to be "safe" dimensions that exclude taskbar size
@@ -776,7 +781,7 @@ class SteamPathPage(EnumeratedWizardPage):
class SetupWizard(ColorAwareApp, Gtk.Application): # type: ignore class SetupWizard(ColorAwareApp, Gtk.Application): # type: ignore
def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, str]) -> None: def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, Path]) -> None:
super().__init__() super().__init__()
GLib.set_prgname(APP_NAME) GLib.set_prgname(APP_NAME)
self.win = Window(is_deck, XDG, xdg_paths) self.win = Window(is_deck, XDG, xdg_paths)
@@ -787,7 +792,7 @@ class SetupWizard(ColorAwareApp, Gtk.Application): # type: ignore
class Window(Gtk.Window): class Window(Gtk.Window):
def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, str]) -> None: def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, Path]) -> None:
super().__init__(title=APP_NAME, icon_name=APP_NAME) super().__init__(title=APP_NAME, icon_name=APP_NAME)
self.assistant = Assistant(is_deck, XDG, xdg_paths) self.assistant = Assistant(is_deck, XDG, xdg_paths)
+2 -4
View File
@@ -15,9 +15,7 @@ logger = logging.getLogger(APP_NAME)
class ContextMixin(TreeView): class ContextMixin(TreeView):
def present_menu( def present_menu(self, widget: Gtk.Widget, event: Gdk.Event) -> bool:
self, widget: Gtk.Widget, event: Gdk.Event
) -> bool:
if self.menu is None: if self.menu is None:
return False return False
@@ -26,7 +24,7 @@ class ContextMixin(TreeView):
match event.type: match event.type:
case Gdk.EventType.BUTTON_PRESS: case Gdk.EventType.BUTTON_PRESS:
if event.button != 3: if event.button != Gdk.BUTTON_SECONDARY: # type: ignore[comparison-overlap]
return False return False
self._process_button_event(event) # type: ignore self._process_button_event(event) # type: ignore
case Gdk.EventType.KEY_PRESS: case Gdk.EventType.KEY_PRESS:
+4 -3
View File
@@ -13,6 +13,7 @@ if TYPE_CHECKING:
from dzgui.controllers.mc import Controller from dzgui.controllers.mc import Controller
# TODO: refactor into autopopulated ListStores
class Keybindings(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore class Keybindings(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
""" """
Notebook page holding a prearranged grid Notebook page holding a prearranged grid
@@ -35,7 +36,7 @@ class Keybindings(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
self.connect("key-press-event", self._on_keypress) self.connect("key-press-event", self._on_keypress)
def build_keys(self, items: list) -> Gtk.Grid: def build_keys(self, items: list[dict[str, str]]) -> Gtk.Grid:
grid = Gtk.Grid(row_spacing=10, column_homogeneous=True) grid = Gtk.Grid(row_spacing=10, column_homogeneous=True)
grid.set_halign(Gtk.Align.START) grid.set_halign(Gtk.Align.START)
row, col = 1, 0 row, col = 1, 0
@@ -72,7 +73,7 @@ class Keybindings(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
row += 1 row += 1
return grid return grid
def build_sidebar(self, categories: list) -> Gtk.Grid: def build_sidebar(self, categories: list[str]) -> Gtk.Grid:
row, col = 0, 0 row, col = 0, 0
w, h = 1, 1 w, h = 1, 1
sidebar = Gtk.Grid(row_homogeneous=True, orientation=Gtk.Orientation.VERTICAL) sidebar = Gtk.Grid(row_homogeneous=True, orientation=Gtk.Orientation.VERTICAL)
@@ -83,7 +84,7 @@ class Keybindings(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
sidebar.attach(label, col, row, w, h) sidebar.attach(label, col, row, w, h)
return sidebar return sidebar
def build_grid(self, items: list) -> Gtk.Grid: def build_grid(self, items: list[dict[str, str]]) -> Gtk.Grid:
grid = Gtk.Grid( grid = Gtk.Grid(
row_spacing=20, row_spacing=20,
halign=Gtk.Align.CENTER, halign=Gtk.Align.CENTER,
+7 -6
View File
@@ -1,5 +1,5 @@
from pathlib import Path from pathlib import Path
from typing import Callable, TYPE_CHECKING from typing import Any, Callable, TYPE_CHECKING
from dzgui.api import pefile as PeFile from dzgui.api import pefile as PeFile
from dzgui.api.steam import get_last_updated from dzgui.api.steam import get_last_updated
@@ -51,7 +51,7 @@ class SubmitField(Gtk.Box):
) -> None: ) -> None:
super().__init__(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) super().__init__(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
self.callback: Callable self.callback: Callable[[], None]
self.controller = controller self.controller = controller
self.context = context self.context = context
@@ -139,7 +139,7 @@ class SubmitField(Gtk.Box):
return return
self.save_option() self.save_option()
def set_callback(self, callback: Callable) -> None: def set_callback(self, callback: Callable[[], None]) -> None:
self.callback = callback self.callback = callback
def save_option(self) -> None: def save_option(self) -> None:
@@ -206,7 +206,7 @@ class NameSubmitField(SubmitField):
Preferences.NAME, Preferences.NAME,
private=False, private=False,
) )
self.entry.set_width_chars(30) # type: ignore self.entry.set_width_chars(30)
self.set_callback(self.save_player_name) self.set_callback(self.save_player_name)
def save_player_name(self) -> None: def save_player_name(self) -> None:
@@ -402,7 +402,8 @@ class Options(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
def _on_link_button_clicked(self, button: Gtk.Button, url: str) -> None: def _on_link_button_clicked(self, button: Gtk.Button, url: str) -> None:
open_links.open_link_by_url(url) open_links.open_link_by_url(url)
def _make_grid(self, rows: list) -> Gtk.Grid: # TODO: use FlowBox
def _make_grid(self, rows: list[list[Any]]) -> Gtk.Grid:
grid = Gtk.Grid( grid = Gtk.Grid(
orientation=Gtk.Orientation.VERTICAL, orientation=Gtk.Orientation.VERTICAL,
column_spacing=10, column_spacing=10,
@@ -435,7 +436,7 @@ class Options(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
if prefs.paths.config.is_file() is False: if prefs.paths.config.is_file() is False:
dialog = ExceptionDialog(self.controller, strings.config_not_found) dialog = ExceptionDialog(self.controller, strings.config_not_found)
dialog.show_all() dialog.show_all()
dialog.run() dialog.run() # type: ignore[no-untyped-call]
raise OSError(f"Config file '{prefs.paths.config}' not found") raise OSError(f"Config file '{prefs.paths.config}' not found")
config = query.get_config(prefs.paths.config) config = query.get_config(prefs.paths.config)
+1 -1
View File
@@ -231,7 +231,7 @@ class PreConnectionAssistant(Gtk.Box):
args = self.controller.get_debug_args() args = self.controller.get_debug_args()
d = DebugDialog(self.controller, args) d = DebugDialog(self.controller, args)
d.show_all() d.show_all()
d.run() d.run() # type: ignore[no-untyped-call]
def _on_ok_clicked(self, button: Gtk.Button) -> None: def _on_ok_clicked(self, button: Gtk.Button) -> None:
self.controller.update_and_connect() self.controller.update_and_connect()
+9 -25
View File
@@ -79,11 +79,6 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
index = path.get_indices()[0] index = path.get_indices()[0]
return index return index
def get_selected_records(self) -> list:
sel = self.get_selection()
model, rows = sel.get_selected_rows()
return [model[row] for row in rows]
def _on_keypress(self, treeview: Gtk.TreeView, event: Gdk.EventKey) -> bool: def _on_keypress(self, treeview: Gtk.TreeView, event: Gdk.EventKey) -> bool:
from dzgui.views.trees.tree_servers import ServerTreeView from dzgui.views.trees.tree_servers import ServerTreeView
@@ -145,9 +140,11 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
self.set_cursor(path) self.set_cursor(path)
def get_value_at_index(self, index: int) -> Any: def get_value_at_index(self, index: int) -> Any:
(model, pathlist) = self.get_model_and_pathlist() model, pathlist = self.get_model_and_pathlist()
if len(pathlist) < 1: if len(pathlist) < 1:
return "" return ""
if model is None:
return ""
path = pathlist[0] path = pathlist[0]
tree_iter = model.get_iter(path) tree_iter = model.get_iter(path)
value = model.get_value(tree_iter, index) value = model.get_value(tree_iter, index)
@@ -161,20 +158,16 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
sel = self.get_selection() sel = self.get_selection()
self._on_tree_selection_changed(sel) self._on_tree_selection_changed(sel)
def get_model_and_pathlist(self) -> tuple: def get_model_and_pathlist(
self,
) -> tuple[Gtk.TreeModel | None, list[Gtk.TreePath]]:
select = self.get_selection() select = self.get_selection()
sels = select.get_selected_rows() sels = select.get_selected_rows()
(model, pathlist) = sels model: Gtk.TreeModel | None
pathlist: list[Gtk.TreePath]
model, pathlist = sels
return (model, pathlist) return (model, pathlist)
# @deprecated("Currently unused")
# def get_mpath(self) -> Optional[Gtk.TreePath]:
# (model, pathlist) = self.get_model_and_pathlist()
# if len(pathlist) < 1:
# return None
# path = pathlist[0]
# return path
def _on_row_activated( def _on_row_activated(
self, self,
treeview: Gtk.TreeView, treeview: Gtk.TreeView,
@@ -189,15 +182,6 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
return True return True
return False return False
# @deprecated("unused")
# def get_selected_row(self) -> Optional[Gtk.TreeModelRow]:
# ind = self.get_selected_row_index()
# model = self.get_model()
# if model is None:
# return None
# row = model[ind]
# return row
def get_col_value_by_path_index(self, path: Gtk.TreePath, index: int) -> Any: def get_col_value_by_path_index(self, path: Gtk.TreePath, index: int) -> Any:
model = self.get_model() model = self.get_model()
if model is None: if model is None:
+3 -2
View File
@@ -32,6 +32,7 @@ if TYPE_CHECKING:
from dzgui.controllers.mc import Controller from dzgui.controllers.mc import Controller
from dzgui.controllers.emitter import Emitter from dzgui.controllers.emitter import Emitter
from dzgui.model.model_factory import FastInsertListStore from dzgui.model.model_factory import FastInsertListStore
from dzgui.util.dist import Haversine
QUEUE_CHECK_DELAY = 200 QUEUE_CHECK_DELAY = 200
@@ -64,7 +65,7 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
self.queue_id: int self.queue_id: int
self.handler_id: int self.handler_id: int
self.queue: Queue = Queue() self.queue: Queue[tuple[str, "Haversine" | None, ServerTab]] = Queue()
self.seen_cache: list[Record] = [] self.seen_cache: list[Record] = []
@@ -406,7 +407,7 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
path = model.get_path(it) path = model.get_path(it)
row_index = path.get_indices()[0] row_index = path.get_indices()[0]
try: try:
start, end = self.get_visible_range() start, end = self.get_visible_range() # type: ignore[no-untyped-call]
except Exception: except Exception:
return return
if row_index >= start[0] <= end[0]: if row_index >= start[0] <= end[0]:
+1 -1
View File
@@ -105,7 +105,7 @@ python-a2s = { path = "./dzgui/lib/a2s", editable = true }
dayzquery = { path = "./dzgui/lib/dayzquery", editable = true } dayzquery = { path = "./dzgui/lib/dayzquery", editable = true }
[tool.uv] [tool.uv]
config-settings-package = { pygobject-stubs = { config = "Gtk3,Gdk3,Soup2" } } config-settings-package = { pygobject-stubs = { config = "Gtk3,Gdk3" } }
[tool.pytest.ini_options] [tool.pytest.ini_options]
markers = [ markers = [