Compare commits

..
Author SHA1 Message Date
aclist 3dc37561be chore: update pyproject.toml 2026-11-10 03:02:35 +09:00
aclist 13786591b3 chore: restore exclusion for GLibUnix 2026-11-10 03:02:06 +09:00
aclist 9eb1342877 drop: unused imports script 2026-11-10 03:00:35 +09:00
aclist 3f29484895 chore: drop unused Gtk imports 2026-11-10 02:59:22 +09:00
69 changed files with 217 additions and 240 deletions

No files matched your search

-2
View File
@@ -37,8 +37,6 @@ Users wishing to review the licenses to these components can inspect the `LICENS
Steam and the Steam logo are trademarks and/or registered trademarks of Valve Corporation in the U.S. and/or other countries.
DayZ is a trademark and brand of Bohemia Interactive a.s.
## Disclaimer
DZGUI is beta-quality software and is provided as-is.
+1 -2
View File
@@ -111,8 +111,7 @@ class WorkshopACF(ACF):
def __init__(self, file: Path) -> None:
super().__init__(file)
def unpack(self, d: dict[str, Any], lines: list[Any] = []) -> str:
self.indent: int
def unpack(self, d: dict, lines: list[Any] = []) -> str:
t1 = "AppWorkshop"
t2 = ("WorkshopItemsInstalled", "WorkshopItemDetails")
for k, v in d.items():
+5 -1
View File
@@ -114,6 +114,10 @@ def get_delimited_mods(steam_path: Path) -> list[Any]:
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:
md5 = hashlib.md5()
md5.update(uid.encode("ascii"))
@@ -148,7 +152,7 @@ def remove_stale_signatures(
def find_stale_mods(config: Path) -> list[int]:
def push_record(rec: str) -> list[int]:
def push_record(rec: str) -> list:
record = fqip_to_record(rec)
if record is None:
return []
+4 -6
View File
@@ -111,7 +111,7 @@ def get_netmask() -> str:
# TODO: rename
def test_ip(suffix: int, port: int, event: threading.Event) -> dict[str, Any] | None:
def test_ip(suffix: int, port: int, event: threading.Event) -> dict | None:
if event.is_set():
return None
netmask = get_netmask()
@@ -139,9 +139,7 @@ def sanitize(name: str) -> str:
return name
def parse_json(
json: list[dict[str, Any]],
) -> list[tuple[str, str, str, str, int, int, int, str, int, int, str, bool]]:
def parse_json(json: list) -> list:
"""
Server metadata is underspecified and server operators
tend to insert random garbage in the headers. In case
@@ -509,14 +507,14 @@ def record_to_fqip(record: Record) -> str:
return f"{record.ip}:{record.gameport}:{record.qport}"
def response_to_fqip(res: dict[str, Any]) -> str:
def response_to_fqip(res: dict) -> str:
ip = res["addr"].split(":")[0]
gameport = res["gameport"]
qport = res["addr"].split(":")[1]
return f"{ip}:{gameport}:{qport}"
def response_to_record(res: dict[str, Any]) -> Record:
def response_to_record(res: dict) -> Record:
ip = res["addr"].split(":")[0]
gameport = res["gameport"]
qport = res["addr"].split(":")[1]
+2 -2
View File
@@ -51,7 +51,7 @@ def is_writeable(path_str: str) -> bool:
return True
def get_xdg_paths() -> dict[str, Path]:
def get_xdg_paths() -> dict:
home = Path.home()
xdg_paths = {
"XDG_CONFIG_HOME": home / ".config",
@@ -73,7 +73,7 @@ def get_xdg_paths() -> dict[str, Path]:
return resolved_paths
def parse_filepaths(xdg: dict[str, Path]) -> Xdg:
def parse_filepaths(xdg: dict) -> Xdg:
config = xdg["XDG_CONFIG_HOME"]
state = xdg["XDG_STATE_HOME"]
share = xdg["XDG_DATA_HOME"]
+2 -2
View File
@@ -3,8 +3,8 @@ from typing import TYPE_CHECKING
import gi
gi.require_version("Gtk", "3.0")
from gi.repository.Gtk import ListStore # noqa E402
from gi.repository import Gdk, GObject # noqa E402
from gi.repository.Gtk import ListStore
from gi.repository import GObject
if TYPE_CHECKING:
from dzgui.const.enum import NotebookPage, ServerTab
+7 -7
View File
@@ -32,7 +32,7 @@ from dzgui.views.dialogs.generic import ExceptionDialog
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, GLib, GObject # noqa E402
from gi.repository import Gtk, Gdk, GLib, GObject
logger = logging.getLogger(APP_NAME)
@@ -77,7 +77,7 @@ class AppNavigation:
class Controller(GObject.GObject):
def __init__(self) -> None:
self.dist_cache: dict[str, "Haversine" | None] = {}
self.dist_cache: dict[str, "Haversine"] = {}
self.mediator = AppNavigation()
self.prefs: UserPrefs
@@ -274,7 +274,7 @@ class Controller(GObject.GObject):
except Exception as e:
dialog = ExceptionDialog(self, str(e))
dialog.show_all()
dialog.run() # type: ignore[no-untyped-call]
dialog.run()
def select_colorized(self) -> None:
mod_man = self.mediator.modtreeview.get_mod_man()
@@ -308,7 +308,7 @@ class Controller(GObject.GObject):
except Exception as e:
dialog = ExceptionDialog(self, str(e))
dialog.show_all()
dialog.run() # type: ignore[no-untyped-call]
dialog.run()
def update_steam_api_key(self, text: str) -> None:
self.config_man.update_steam_api_key(text)
@@ -355,17 +355,17 @@ class Controller(GObject.GObject):
filter_man.set_filter(filt, state)
self.mediator.filters.set_filters(filters)
def get_dist_cache(self) -> dict[str, Union["Haversine", None]]:
def get_dist_cache(self) -> dict[str, "Haversine"]:
return self.dist_cache
def set_dist_cache(self, addr: str, haversine: Union["Haversine", None]) -> None:
def set_dist_cache(self, addr: str, haversine: "Haversine") -> None:
self.dist_cache[addr] = haversine
def get_map_store(self) -> Gtk.ListStore:
filter_man = self.get_filter_man()
return filter_man.get_map_store()
def get_enabled_filters(self) -> dict[str, bool]:
def get_enabled_filters(self) -> dict:
filter_man = self.get_filter_man()
return filter_man.get_filters()
+1 -1
View File
@@ -162,7 +162,7 @@ class ConfigManager:
trace = traceback.format_exc()
dialog = ExceptionDialog(self.controller, trace)
dialog.show_all()
dialog.run() # type: ignore[no-untyped-call]
dialog.run()
def save_res_and_quit(self, tv: "ServerTreeView", window: "OuterWindow") -> None:
columns = tv.get_columns()
+4 -9
View File
@@ -55,11 +55,6 @@ from dzgui.util.symlink import rebuild_symlinks
from dzgui.views.dialogs.generic import ExceptionDialog
from dzgui.views.dialogs.servers import ServerDetailsDialog, ServerModDialog
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib # noqa E402
if TYPE_CHECKING:
from dzgui.api.servers import A2SInfo, Record
from dzgui.controllers.mc import Controller
@@ -298,22 +293,22 @@ class ConnectionManager:
def _present_modlist_dialog(self, mods: list[list[str]]) -> None:
dialog = ServerModDialog(self.controller, mods)
dialog.run() # type: ignore[no-untyped-call]
dialog.run()
def _present_details_dialog(self, details: Servers.Details) -> None:
dialog = ServerDetailsDialog(self.controller, details)
dialog.run() # type: ignore[no-untyped-call]
dialog.run()
def _workshop_timeout(self, msg: str) -> None:
dialog = ExceptionDialog(self.controller, msg)
dialog.show_all()
dialog.run() # type: ignore[no-untyped-call]
dialog.run()
def _server_timeout(self) -> None:
dialog = ExceptionDialog(self.controller, server_timeout)
dialog.set_details_buffer(kb.DZG_006)
dialog.show_all()
dialog.run() # type: ignore[no-untyped-call]
dialog.run()
def get_debug_args(self) -> str:
addr = f"{self.record.ip}:{self.record.gameport}"
+1 -1
View File
@@ -44,7 +44,7 @@ class ContextMenuManager:
# UNTHREADED
case ContextMenu.ADD_NOTE:
dialog = NoteDialog(self.controller)
dialog.run() # type: ignore[no-untyped-call]
dialog.run()
case ContextMenu.COPY_SERVER_IP:
self.copy_server_ip()
case ContextMenu.COPY_SERVER_NAME:
+4 -3
View File
@@ -51,6 +51,7 @@ class FilterManager:
self.active_map = (0, all_maps)
self.prior_map = all_maps
self.filters: list
self.enabled_filters = dict(self.default_filters)
def get_tooltips(self) -> dict[str, str]:
@@ -74,11 +75,11 @@ class FilterManager:
def set_active_keyword(self, word: str) -> None:
self.active_keyword = word
def get_default_filters(self) -> dict[str, bool]:
def get_default_filters(self) -> dict:
"""Deep copy of defaults"""
return dict(self.default_filters)
def get_filters(self) -> dict[str, bool]:
def get_filters(self) -> dict:
return self.enabled_filters
def set_filter(self, label: str, state: bool) -> None:
@@ -115,7 +116,7 @@ class FilterManager:
def get_unique_maps(self) -> list[str]:
return [row[0] for row in self.map_store if row[0] != "All maps"]
def get_all_filters(self) -> tuple[str, ...]:
def get_all_filters(self) -> tuple:
map_name = self.get_active_map_name()
enabled = self.get_filters()
kw = self.get_active_keyword()
+2 -2
View File
@@ -30,7 +30,7 @@ import dzgui.api.pefile as PeFile
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
@@ -221,7 +221,7 @@ class ModManager:
total_size += mod[3]
return total_mods, total_size
def _on_stale_mods_found(self, stale_mods: list[int]) -> None:
def _on_stale_mods_found(self, stale_mods: list) -> None:
"""Manipulates attached ListStore in the main event loop"""
model = self.treeview.get_model()
if model is None:
+1 -1
View File
@@ -52,7 +52,7 @@ class OfflineManager:
is_valid = is_mission(folder)
self.emitter.emit("custom_mission_loaded", str(folder), is_valid)
def find_custom_mods(self, callback: Callable[[], None]) -> None:
def find_custom_mods(self, callback: Callable) -> None:
folder = self.open_folderpicker(dialogs.custom_mod_dialog)
window = self.controller.get_window()
window.set_sensitive(False)
+4 -4
View File
@@ -15,15 +15,15 @@ if TYPE_CHECKING:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib # noqa E402
from gi.repository import GLib
logger = logging.getLogger(APP_NAME)
def call_on_thread(
dialog_str: str, show_dialog: bool = True, show_cancel: bool = False
) -> Callable[..., Any]:
def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
) -> Callable:
def decorator(func: Callable) -> Callable:
@wraps(func)
def wrapper(*args: Any, **kwargs: Any) -> None:
self = args[0]
@@ -42,7 +42,7 @@ def call_on_thread(
class StoredFunc:
def __init__(self, func: Callable[..., Any], *args: Any, **kwargs: Any) -> None:
def __init__(self, func: Callable, *args: Any, **kwargs: Any) -> None:
sig = inspect.signature(func)
self.func = func
self.bindings = sig.bind(*args, **kwargs)
+2 -7
View File
@@ -15,11 +15,6 @@ from dzgui.strings import dialogs
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
from dzgui.views.dialogs.generic import ExceptionDialog, QuitDialog
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib # noqa E402
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
@@ -60,9 +55,9 @@ class UpdateManager:
def _on_update_success(self) -> None:
msg = dialogs.update_success
dialog = QuitDialog(self.controller, msg)
dialog.run() # type: ignore[no-untyped-call]
dialog.run()
def _on_update_failure(self, msg: str) -> None:
dialog = ExceptionDialog(self.controller, msg)
dialog.show_all()
dialog.run() # type: ignore[no-untyped-call]
dialog.run()
+3 -3
View File
@@ -7,11 +7,11 @@ from dzgui.util.strings import delimiter
import gi
gi.require_version("Gtk", "3.0")
from gi.repository.Gtk import ListStore, TreeIter # noqa E402
from gi.repository import GObject # noqa E402
from gi.repository.Gtk import ListStore, TreeIter
from gi.repository import GObject
GTYPE_TO_PYTHON = {
GObject.type_from_name(GObject.type_name(ptype)): ptype # type: ignore[no-untyped-call]
GObject.type_from_name(GObject.type_name(ptype)): ptype
for ptype in (int, float, str, bool, object)
}
+7 -20
View File
@@ -1,6 +1,5 @@
import re
from dataclasses import dataclass
from typing import Any, TYPE_CHECKING, Union
from dzgui.const.enum import FilterMode
@@ -17,22 +16,6 @@ DAY_REG = r"([0][6-9]|[1][0-7])"
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:
"""
Manages access to cached FastInsertListStore resources and
@@ -47,7 +30,7 @@ class ProxyModelManager:
def __init__(self, filter_man: "FilterManager") -> None:
self.filter_cache: dict[
tuple[str, ...],
tuple[str],
list[tuple[str, str, str, str, int, int, int, str, int, int, str, bool]],
] = {}
@@ -68,6 +51,9 @@ class ProxyModelManager:
return False
return True
def append_row(self, row: list) -> None:
self.proxy_model.append(row)
def append_row_to_control(
self, row: tuple[str, str, str, str, int, int, int, str, int, int, str, bool]
) -> None:
@@ -81,6 +67,7 @@ class ProxyModelManager:
self.proxy_model[treeiter][4] = playercount.players
self.proxy_model[treeiter][6] = playercount.queue
# TODO: use dataclass for record rows
def append_row_to_history(
self,
history: tuple[str, str, str, str, int, int, int, str, int, int, str, bool],
@@ -260,7 +247,7 @@ class ProxyModelManager:
rows = [row for row in rows if row[11]]
return rows
def filter_toggle_on(self, filters: tuple[str, ...]) -> list:
def filter_toggle_on(self, filters: tuple[str]) -> list:
"""Effectively applies all filters"""
self.set_filtered(self.control_model)
self.set_filtered(self.filter_map(filters))
@@ -271,7 +258,7 @@ class ProxyModelManager:
self.set_filtered(self.filter_toggle_off(filters, f))
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
def set_filtered(self, rows: list | None) -> None:
+4 -4
View File
@@ -21,7 +21,7 @@ from dzgui.views.dialogs.generic import ExceptionDialog
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib # noqa E402
from gi.repository import Gtk, GLib
if TYPE_CHECKING:
from dzgui.api.servers import A2SInfo, Record
@@ -432,7 +432,7 @@ class ServerModelManager:
if show_dialog:
dialog = ExceptionDialog(self.controller, dialogs.load_error_lan)
dialog.show_all()
dialog.run() # type: ignore[no-untyped-call]
dialog.run()
def _cleanup_on_failure(self, show_dialog: bool = True) -> 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.set_details_buffer(kb.DZG_006)
dialog.show_all()
dialog.run() # type: ignore[no-untyped-call]
dialog.run()
def _push_data(self, data: list[Any]) -> None:
self._get_proxy_man().push(data)
self._sort_unique_maps(data)
self.thread_man.set_cleanup_func(StoredFunc(self._cleanup_on_success))
def _sort_unique_maps(self, data: list[Any]) -> None:
def _sort_unique_maps(self, data: list) -> None:
u_maps = set([row[1] for row in data])
self._set_new_maps(sorted(u_maps))
+1 -2
View File
@@ -1,8 +1,7 @@
import gi
gi.require_version("Gtk", "3.0")
gi.require_version("Gdk", "3.0")
from gi.repository import Gtk, Gdk # noqa E402
from gi.repository import Gtk, Gdk
def copy_clipboard(text: str) -> None:
+1 -1
View File
@@ -5,7 +5,7 @@ from dzgui.const.constants import APP_NAME_LOWER, CSS_PATH
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk # noqa E402
from gi.repository import Gtk, Gdk
def add_class(widget: Gtk.Widget, label: str) -> None:
+2 -7
View File
@@ -7,11 +7,6 @@ from dzgui.const.constants import APP_NAME
from dzgui.util.ip import get_coords
from dzgui.util.localize import number
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
if TYPE_CHECKING:
from queue import Queue
from dzgui.const.enum import ServerTab
@@ -59,7 +54,7 @@ class CalcDist:
self,
addr: str,
enum: "ServerTab",
result_queue: "Queue[tuple[str, Haversine | None, ServerTab]]",
result_queue: "Queue",
controller: "Controller",
cache: dict[str, Haversine],
) -> None:
@@ -72,7 +67,7 @@ class CalcDist:
self.ip = self.addr
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:
prefs = self.controller.get_prefs()
+2 -6
View File
@@ -1,16 +1,12 @@
import logging
import subprocess
from typing import TYPE_CHECKING
from dzgui.const.constants import APP_NAME, FLATPAK_APPID, GTK_APP_ID, TMP_PATH
logger = logging.getLogger(APP_NAME)
if TYPE_CHECKING:
from pathlib import Path
def apply_overrides(xdg: dict[str, "Path"]) -> None:
def apply_overrides(xdg: dict[str, str]) -> None:
try:
# NOTE: D-Bus registration required for sandbox
args = [
@@ -23,7 +19,7 @@ def apply_overrides(xdg: dict[str, "Path"]) -> None:
subprocess.run([*args], capture_output=True)
paths: list[str] = []
paths.extend([str(path) for path in xdg.values()])
paths.extend([*xdg.values()])
paths.append(TMP_PATH)
for path in paths:
+2 -3
View File
@@ -1,5 +1,4 @@
import re
from typing import Any
from dzgui.util.localize import number
from dzgui.strings.generic import selectable_tree
@@ -8,7 +7,7 @@ from dzgui.util.strings import no_mods, no_servers, workshop
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
def format_pango(text: str) -> str:
@@ -61,7 +60,7 @@ def format_server_mods(mods: int) -> str:
return f"Found {mods:n} {plural}. {workshop}"
def format_player_count(model: Gtk.TreeModel | None, control: list[Any]) -> str:
def format_player_count(model: Gtk.TreeModel | None, control: list) -> str:
players = 0
hits: int
status: str
+1 -1
View File
@@ -31,7 +31,7 @@ class ReservedIPError(Exception):
pass
def ip2list(ip: str) -> list[int]:
def ip2list(ip: str) -> list:
return [int(digit) for digit in ip.split(".")]
+4 -1
View File
@@ -1,6 +1,8 @@
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gdk # noqa E402
from gi.repository import Gdk
def is_navkey(key: int) -> bool:
nav_keys = [
@@ -18,6 +20,7 @@ def is_navkey(key: int) -> bool:
return True
return False
def is_ctrl_mask(event: Gdk.EventKey) -> bool:
if event.state is Gdk.ModifierType.CONTROL_MASK:
return True
+3 -1
View File
@@ -1,6 +1,8 @@
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
def set_surrounding_margins(widget: Gtk.Widget, margin: int) -> None:
"""
+1 -1
View File
@@ -4,7 +4,7 @@ from typing import cast, TYPE_CHECKING
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, GLib # noqa E402
from gi.repository import Gdk, GLib
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
+1 -1
View File
@@ -38,7 +38,7 @@ import gi
gi.require_version("Gtk", "3.0")
gi.require_version("GLibUnix", "2.0")
from gi.repository import Gtk, GLib, GLibUnix, Gdk # type: ignore # noqa E402
from gi.repository import Gtk, GLib, GLibUnix, Gdk # type: ignore
if TYPE_CHECKING:
from dzgui.config.userprefs import UserPrefs
+1 -1
View File
@@ -7,7 +7,7 @@ from dzgui.const.enum import ButtonType
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk # noqa E402
from gi.repository import Gtk, Gdk
logger = logging.getLogger(APP_NAME)
+34 -6
View File
@@ -1,8 +1,10 @@
from typing import Callable, Literal, Self, TYPE_CHECKING, Union
from dzgui.util.clip import copy_clipboard
from dzgui.util.format import pluralize
from dzgui.strings import buttons
from dzgui.util.strings import (
alert_button_tooltip,
atomic_buttons,
)
from dzgui.const.constants import (
@@ -12,6 +14,7 @@ from dzgui.const.constants import (
LIST_ADD,
REFRESH_ICON,
STEAM_ICON,
WARNING,
WEB_BROWSER,
)
from dzgui.strings import connect_panel
@@ -19,7 +22,7 @@ from dzgui.strings import connect_panel
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, GLib # noqa E402
from gi.repository import Gtk, GLib
if TYPE_CHECKING:
from gi.repository import GLib
@@ -61,7 +64,7 @@ class IconButton(Gtk.Button):
self.icon = Icon(icon, margin_start=margin_start, margin_end=margin_end)
self.set_image(self.icon)
self.set_image_position(position)
self.set_focus_on_click(False) # type: ignore[no-untyped-call]
self.set_focus_on_click(False)
self.set_always_show_image(True)
def swap_icon(self, icon: str) -> None:
@@ -98,14 +101,15 @@ class LargeIconTextButton(IconButton):
class ClipboardButton(IconTextButton):
def __init__(self, func: Callable[[], str]) -> None:
def __init__(self, controller: Union["Controller", None], func: Callable) -> None:
super().__init__(CLIPBOARD, atomic_buttons.copy)
self.controller = controller
self.connect("clicked", self._on_button_clicked, func)
# TODO: strings
self.set_tooltip_text("Copy to clipboard")
def _on_button_clicked(self, button: Self, func: Callable[[], str]) -> None:
def _on_button_clicked(self, button: Self, func: Callable) -> None:
def revert() -> Literal[False]:
self.revert_icon()
return False
@@ -116,9 +120,10 @@ class ClipboardButton(IconTextButton):
GLib.timeout_add(600, revert)
# TODO: determine when controller would be passed to this button or drop
class CopyIpButton(ClipboardButton):
def __init__(self, func: Callable[[], str]) -> None:
super().__init__(func)
def __init__(self, controller: Union["Controller", None], func: Callable) -> None:
super().__init__(controller, func)
# TODO: strings
self.set_tooltip_text("Copy IP to clipboard")
@@ -247,6 +252,29 @@ class AddButton(IconTextButton):
self.set_tooltip_text(connect_panel.add_tooltip)
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=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):
def __init__(self, label: str) -> None:
super().__init__()
+2 -2
View File
@@ -18,7 +18,7 @@ from dzgui.views.components.labels import BoldLabel
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk # noqa E402
from gi.repository import Gtk, Gdk
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
@@ -187,7 +187,7 @@ class FavPanel(Gtk.Frame):
self.fav_button = SteamConnectButton()
self.fav_button.connect("clicked", self._on_connect_clicked)
self.copy_button = CopyIpButton(self.get_fav_ip)
self.copy_button = CopyIpButton(self.controller, self.get_fav_ip)
# TODO: strings
self.unset_button = CloseButton("Unset")
+1 -1
View File
@@ -7,7 +7,7 @@ from dzgui.util.format import embolden
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa E402
from gi.repository import Gtk
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
+6 -5
View File
@@ -9,7 +9,7 @@ from dzgui.strings.errors import api_popover
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, GObject # noqa E402
from gi.repository import Gtk, Gdk, GObject
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
@@ -38,7 +38,7 @@ class ValidatedEntry(Gtk.Entry):
def __init__(
self,
controller: "Controller",
func: Callable[[str], bool],
func: Callable,
placeholder_text: str = "",
tooltip_text: str = "",
) -> None:
@@ -46,6 +46,7 @@ class ValidatedEntry(Gtk.Entry):
hexpand=True, placeholder_text=placeholder_text, tooltip_text=tooltip_text
)
self.func: Callable
self.set_validation_func(func)
self.controller = controller
@@ -71,7 +72,7 @@ class ValidatedEntry(Gtk.Entry):
self.emit("string_validated", False)
remove_class(self, self.classname)
def set_validation_func(self, func: Callable[[str], bool]) -> None:
def set_validation_func(self, func: Callable) -> None:
self.func = func
def insert_icon(self) -> None:
@@ -140,7 +141,7 @@ class APIEntry(Gtk.Box):
def __init__(self) -> None:
super().__init__(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
self.func: Callable[[str], None] | None = None
self.func: Callable | None = None
# TODO: strings
self.entry = Gtk.Entry(
@@ -221,7 +222,7 @@ class APIEntry(Gtk.Box):
res = self.func(text)
return res
def set_validation_func(self, func: Callable[[str], None] | None) -> None:
def set_validation_func(self, func: Callable | None) -> None:
self.func = func
def disable_button(self) -> None:
+1 -1
View File
@@ -6,7 +6,7 @@ from dzgui.const.constants import HELP_BUBBLE
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk # noqa E402
from gi.repository import Gtk, Gdk
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
+3 -4
View File
@@ -17,7 +17,7 @@ from dzgui.views.components.labels import BoldLabel
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, Pango, GLib # noqa E402
from gi.repository import Gtk, Gdk, Pango, GLib
logger = logging.getLogger(APP_NAME)
@@ -30,7 +30,7 @@ class ButtonGrid(Gtk.Grid):
def __init__(
self,
controller: "Controller",
defaults: dict[str, bool],
defaults: dict[str, str],
tooltips: dict[str, str],
) -> None:
super().__init__(
@@ -96,7 +96,7 @@ class ButtonGrid(Gtk.Grid):
logger.info(f"User toggled button '{label}' to {state}")
self.emitter.emit("check_toggled", label, state)
def get_checkboxes(self) -> list[Gtk.CheckButton]:
def get_checkboxes(self) -> list:
return self.checks
@@ -308,7 +308,6 @@ class FilterPanel(Gtk.Box):
Gdk.KEY_0: 9,
Gdk.KEY_minus: 10,
Gdk.KEY_backslash: 11,
Gdk.KEY_apostrophe: 12,
}
if keyval not in mappings:
return False
+1 -1
View File
@@ -1,7 +1,7 @@
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
class Icon(Gtk.Image):
+1 -1
View File
@@ -3,7 +3,7 @@ from dzgui.util.format import embolden
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
class BoldLabel(Gtk.Label):
+1 -1
View File
@@ -1,7 +1,7 @@
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib # noqa E402
from gi.repository import Gtk
class MapsCombo(Gtk.EntryCompletion):
+1 -1
View File
@@ -8,7 +8,7 @@ from dzgui.views.components.labels import BoldLabel
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
+1 -1
View File
@@ -23,7 +23,7 @@ from dzgui.views.components.buttons import IconTextButton, RefreshButton, KeysBu
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, GLib # noqa E402
from gi.repository import Gtk, Gdk, GLib
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
+5 -1
View File
@@ -2,11 +2,12 @@ from typing import Self, Union, TYPE_CHECKING
from dzgui.const.enum import NotebookPage, ServerTab
from dzgui.util.strings import esc_to_return, question_to_return
from dzgui.views.components.buttons import LoggerAlertsButton
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
if TYPE_CHECKING:
from dzgui.const.enum import ServerTab
@@ -46,6 +47,9 @@ class Statusbar(Gtk.Grid):
self.emitter.connect("servers_loaded", self._on_servers_loaded)
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:
self.set_by_context(NotebookPage.MODS, msg)
+2 -1
View File
@@ -2,8 +2,9 @@ from typing import Literal
from dzgui.util import css
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib # noqa E402
from gi.repository import Gtk, GLib
class Toast(Gtk.EventBox):
+1 -1
View File
@@ -105,7 +105,7 @@ class BootDialog(ColorAwareApp, Gtk.Dialog): # type: ignore
self.error_label = Gtk.Label(margin_start=15, margin_end=15)
# TODO: abstract class
self.copy_button = ClipboardButton(self.error_label.get_text)
self.copy_button = ClipboardButton(None, lambda: self.error_label.get_text())
self.button_hbox = Gtk.Box(
orientation=Gtk.Orientation.HORIZONTAL, halign=Gtk.Align.CENTER, spacing=10
)
+1 -1
View File
@@ -10,7 +10,7 @@ from dzgui.views.components.labels import BoldLabel
from dzgui.views.components.box import VBox, HBox
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, GObject # noqa E402
from gi.repository import Gtk, GLib, GObject
DAY_START_TIME = time(hour=6, minute=0, second=0)
DAY_END_TIME = time(hour=18, minute=0, second=0)
+2 -2
View File
@@ -8,7 +8,7 @@ from dzgui.views.mixins.colorscheme import ColorAwareApp
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
class AbortDialog(ColorAwareApp, Gtk.MessageDialog): # type: ignore
@@ -46,7 +46,7 @@ class AbortDialog(ColorAwareApp, Gtk.MessageDialog): # type: ignore
self.connect("response", self._on_response)
self.run() # type: ignore[no-untyped-call]
self.run()
self.destroy()
def _on_response(self, dialog: Self, response: Gtk.ResponseType) -> None:
+8 -8
View File
@@ -2,10 +2,10 @@ from pathlib import Path
from dzgui.util.strings import picker
import gi # noqa E402
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
class FilePicker(Gtk.FileChooserDialog):
@@ -16,14 +16,14 @@ class FilePicker(Gtk.FileChooserDialog):
transient_for=parent,
resizable=True,
)
self.add_buttons("_Cancel", Gtk.ResponseType.CANCEL) # type: ignore[no-untyped-call]
self.add_buttons("_Save", Gtk.ResponseType.OK) # type: ignore[no-untyped-call]
self.add_buttons("_Cancel", Gtk.ResponseType.CANCEL)
self.add_buttons("_Save", Gtk.ResponseType.OK)
self.set_default_response(Gtk.ResponseType.OK)
self.set_current_name(picker.placeholder)
def pick_file(self) -> Path | None:
res = self.run() # type: ignore[no-untyped-call]
res = self.run()
if res in (Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT):
self.destroy()
return None
@@ -43,12 +43,12 @@ class FolderPicker(Gtk.FileChooserDialog):
parent=parent,
resizable=True,
)
self.add_buttons("_Cancel", Gtk.ResponseType.CANCEL) # type: ignore[no-untyped-call]
self.add_buttons("_OK", Gtk.ResponseType.OK) # type: ignore[no-untyped-call]
self.add_buttons("_Cancel", Gtk.ResponseType.CANCEL)
self.add_buttons("_OK", Gtk.ResponseType.OK)
self.set_default_response(Gtk.ResponseType.OK)
def pick_folder(self) -> Path | None:
res = self.run() # type: ignore[no-untyped-call]
res = self.run()
if res in (Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT):
self.destroy()
return None
+2 -2
View File
@@ -8,7 +8,7 @@ from dzgui.views.components.buttons import ClipboardButton
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa E402
from gi.repository import Gtk, GLib
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
@@ -187,7 +187,7 @@ class TextBufferDialog(GenericDialog):
secondary=secondary,
)
self.text = text
copy_button = ClipboardButton(self.get_text)
copy_button = ClipboardButton(controller, self.get_text)
self.add_action_widget(copy_button, Gtk.ResponseType.NONE)
self.add_button("OK", Gtk.ResponseType.OK)
self.connect("response", self._on_response)
+1 -1
View File
@@ -9,7 +9,7 @@ from dzgui.views.components.buttons import SteamTextButton
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa E402
from gi.repository import Gtk
if TYPE_CHECKING:
+2 -2
View File
@@ -3,10 +3,10 @@ from typing import Self, TYPE_CHECKING
from dzgui.views.components.entry import ValidatedEntry
from dzgui.views.dialogs.generic import GenericDialog
import gi # noqa E402
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gdk, Gtk # noqa E402
from gi.repository import Gtk
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
+5 -5
View File
@@ -18,11 +18,11 @@ from dzgui.views.mixins.colorscheme import ColorAwareApp
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Pango # noqa E402
from gi.repository import Gtk, GLib, Pango
class Assistant(Gtk.Assistant):
def __init__(self, is_deck: bool, paths: dict[str, Path]):
def __init__(self, is_deck: bool, paths: dict[str, str]):
super().__init__()
if is_deck:
# NOTE: deemed to be "safe" dimensions that exclude taskbar size
@@ -63,7 +63,7 @@ class Assistant(Gtk.Assistant):
class Window(Gtk.Window):
def __init__(self, is_deck: bool, paths: dict[str, Path]) -> None:
def __init__(self, is_deck: bool, paths: dict[str, str]) -> None:
super().__init__(title=APP_NAME, icon_name=APP_NAME)
self.assistant = Assistant(is_deck, paths)
@@ -121,7 +121,7 @@ class CheckboxWithPath(CheckboxWithLabel):
class UninstallPage(ScrolledWizardPage):
def __init__(self, paths: dict[str, Path], pyapp: str | None):
def __init__(self, paths: dict[str, str], pyapp: str | None):
super().__init__(heading=uninstall.pg1_heading, description=uninstall.pg1_blurb)
self.pyapp = pyapp
@@ -219,7 +219,7 @@ class UninstallPage(ScrolledWizardPage):
class UninstallWizard(ColorAwareApp, Gtk.Application): # type: ignore
def __init__(self, is_deck: bool, paths: dict[str, Path]) -> None:
def __init__(self, is_deck: bool, paths: dict[str, str]) -> None:
super().__init__()
config = Path(paths["XDG_CONFIG_HOME"])
if not config.is_dir() or not config.joinpath("config.json").is_file():
+6 -11
View File
@@ -35,7 +35,7 @@ from dzgui.views.trees.tree_simple import SimpleTree
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gdk, Gtk, GLib, GObject, GdkPixbuf # noqa E402
from gi.repository import Gtk, GLib, GObject, GdkPixbuf
if TYPE_CHECKING:
from dzgui.config.xdg import Xdg
@@ -168,12 +168,7 @@ class NotificationFrame(Gtk.Frame):
class APIValidationPage(EnumeratedWizardPage):
def __init__(
self,
enum: PageNum,
heading: str,
description: str,
link: str,
func: Callable[[str], None],
self, enum: PageNum, heading: str, description: str, link: str, func: Callable
) -> None:
super().__init__(
enum=enum,
@@ -426,7 +421,7 @@ class PreferencesPage(EnumeratedWizardPage):
class FlatpakOverridePage(EnumeratedWizardPage):
def __init__(self, xdg_paths: dict[str, Path]) -> None:
def __init__(self, xdg_paths: dict[str, str]) -> None:
super().__init__(
enum=PageNum.FLATPAK,
heading=wizard.heading_flatpak,
@@ -476,7 +471,7 @@ class CompletionPage(EnumeratedWizardPage):
class Assistant(Gtk.Assistant):
def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, Path]):
def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, str]):
super().__init__()
if is_deck:
# NOTE: deemed to be "safe" dimensions that exclude taskbar size
@@ -781,7 +776,7 @@ class SteamPathPage(EnumeratedWizardPage):
class SetupWizard(ColorAwareApp, Gtk.Application): # type: ignore
def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, Path]) -> None:
def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, str]) -> None:
super().__init__()
GLib.set_prgname(APP_NAME)
self.win = Window(is_deck, XDG, xdg_paths)
@@ -792,7 +787,7 @@ class SetupWizard(ColorAwareApp, Gtk.Application): # type: ignore
class Window(Gtk.Window):
def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, Path]) -> None:
def __init__(self, is_deck: bool, XDG: "Xdg", xdg_paths: dict[str, str]) -> None:
super().__init__(title=APP_NAME, icon_name=APP_NAME)
self.assistant = Assistant(is_deck, XDG, xdg_paths)
+5 -3
View File
@@ -9,13 +9,15 @@ from dzgui.views.trees.tree_base import TreeView
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa E402
from gi.repository import Gtk, Gdk
logger = logging.getLogger(APP_NAME)
class ContextMixin(TreeView):
def present_menu(self, widget: Gtk.Widget, event: Gdk.Event) -> bool:
def present_menu(
self, widget: Gtk.Widget, event: Gdk.Event
) -> bool:
if self.menu is None:
return False
@@ -24,7 +26,7 @@ class ContextMixin(TreeView):
match event.type:
case Gdk.EventType.BUTTON_PRESS:
if event.button != Gdk.BUTTON_SECONDARY: # type: ignore[comparison-overlap]
if event.button != 3:
return False
self._process_button_event(event) # type: ignore
case Gdk.EventType.KEY_PRESS:
+1 -1
View File
@@ -5,7 +5,7 @@ from dzgui.util.keys import is_ctrl_mask
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa E402
from gi.repository import Gtk, Gdk
class CursorMixin:
+1 -1
View File
@@ -3,7 +3,7 @@ from dzgui.views.trees.tree_base import TreeView
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa E402
from gi.repository import Gtk
class ModsMixin:
+1 -1
View File
@@ -15,7 +15,7 @@ from dzgui.views.mixins.scrollable_mixin import ScrollableMixin
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
logger = logging.getLogger(APP_NAME)
+2 -2
View File
@@ -7,10 +7,10 @@ from dzgui.util.strings import developers
from dzgui.views.components.labels import BoldLabel
from dzgui.views.trees.tree_base import TreeView
import gi # noqa E402
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
+1 -1
View File
@@ -4,7 +4,7 @@ from dzgui.views.trees.tree_menu import MenuTreeView
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
+4 -5
View File
@@ -7,13 +7,12 @@ from dzgui.util.css import add_class
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
# TODO: refactor into autopopulated ListStores
class Keybindings(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
"""
Notebook page holding a prearranged grid
@@ -36,7 +35,7 @@ class Keybindings(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
self.connect("key-press-event", self._on_keypress)
def build_keys(self, items: list[dict[str, str]]) -> Gtk.Grid:
def build_keys(self, items: list) -> Gtk.Grid:
grid = Gtk.Grid(row_spacing=10, column_homogeneous=True)
grid.set_halign(Gtk.Align.START)
row, col = 1, 0
@@ -73,7 +72,7 @@ class Keybindings(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
row += 1
return grid
def build_sidebar(self, categories: list[str]) -> Gtk.Grid:
def build_sidebar(self, categories: list) -> Gtk.Grid:
row, col = 0, 0
w, h = 1, 1
sidebar = Gtk.Grid(row_homogeneous=True, orientation=Gtk.Orientation.VERTICAL)
@@ -84,7 +83,7 @@ class Keybindings(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
sidebar.attach(label, col, row, w, h)
return sidebar
def build_grid(self, items: list[dict[str, str]]) -> Gtk.Grid:
def build_grid(self, items: list) -> Gtk.Grid:
grid = Gtk.Grid(
row_spacing=20,
halign=Gtk.Align.CENTER,
+1 -1
View File
@@ -9,7 +9,7 @@ from dzgui.views.trees.tree_log import LogTreeView
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
+6 -7
View File
@@ -1,5 +1,5 @@
from pathlib import Path
from typing import Any, Callable, TYPE_CHECKING
from typing import Callable, TYPE_CHECKING
from dzgui.api import pefile as PeFile
from dzgui.api.steam import get_last_updated
@@ -55,7 +55,7 @@ class SubmitField(Gtk.Box):
) -> None:
super().__init__(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
self.callback: Callable[[], None]
self.callback: Callable
self.controller = controller
self.context = context
@@ -143,7 +143,7 @@ class SubmitField(Gtk.Box):
return
self.save_option()
def set_callback(self, callback: Callable[[], None]) -> None:
def set_callback(self, callback: Callable) -> None:
self.callback = callback
def save_option(self) -> None:
@@ -210,7 +210,7 @@ class NameSubmitField(SubmitField):
Preferences.NAME,
private=False,
)
self.entry.set_width_chars(30)
self.entry.set_width_chars(30) # type: ignore
self.set_callback(self.save_player_name)
def save_player_name(self) -> None:
@@ -406,8 +406,7 @@ class Options(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
def _on_link_button_clicked(self, button: Gtk.Button, url: str) -> None:
open_links.open_link_by_url(url)
# TODO: use FlowBox
def _make_grid(self, rows: list[list[Any]]) -> Gtk.Grid:
def _make_grid(self, rows: list) -> Gtk.Grid:
grid = Gtk.Grid(
orientation=Gtk.Orientation.VERTICAL,
column_spacing=10,
@@ -440,7 +439,7 @@ class Options(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
if prefs.paths.config.is_file() is False:
dialog = ExceptionDialog(self.controller, strings.config_not_found)
dialog.show_all()
dialog.run() # type: ignore[no-untyped-call]
dialog.run()
raise OSError(f"Config file '{prefs.paths.config}' not found")
config = query.get_config(prefs.paths.config)
+2 -2
View File
@@ -18,7 +18,7 @@ from dzgui.views.trees.tree_server_mods import ServerModTreeView
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gdk, Gtk # noqa E402
from gi.repository import Gdk, Gtk
if TYPE_CHECKING:
@@ -231,7 +231,7 @@ class PreConnectionAssistant(Gtk.Box):
args = self.controller.get_debug_args()
d = DebugDialog(self.controller, args)
d.show_all()
d.run() # type: ignore[no-untyped-call]
d.run()
def _on_ok_clicked(self, button: Gtk.Button) -> None:
self.controller.update_and_connect()
+1 -1
View File
@@ -10,7 +10,7 @@ from dzgui.util.strings import server_labels
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, GLib # noqa E402
from gi.repository import Gtk, Gdk
logger = logging.getLogger(APP_NAME)
+1 -1
View File
@@ -8,7 +8,7 @@ from dzgui.views.mixins.scrollable_mixin import ScrollableMixin
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
# TODO: wrap and center long values
if TYPE_CHECKING:
+25 -9
View File
@@ -79,6 +79,11 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
index = path.get_indices()[0]
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:
from dzgui.views.trees.tree_servers import ServerTreeView
@@ -140,11 +145,9 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
self.set_cursor(path)
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:
return ""
if model is None:
return ""
path = pathlist[0]
tree_iter = model.get_iter(path)
value = model.get_value(tree_iter, index)
@@ -158,16 +161,20 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
sel = self.get_selection()
self._on_tree_selection_changed(sel)
def get_model_and_pathlist(
self,
) -> tuple[Gtk.TreeModel | None, list[Gtk.TreePath]]:
def get_model_and_pathlist(self) -> tuple:
select = self.get_selection()
sels = select.get_selected_rows()
model: Gtk.TreeModel | None
pathlist: list[Gtk.TreePath]
model, pathlist = sels
(model, pathlist) = sels
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(
self,
treeview: Gtk.TreeView,
@@ -182,6 +189,15 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
return True
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:
model = self.get_model()
if model is None:
+1 -1
View File
@@ -12,7 +12,7 @@ from dzgui.views.mixins.context_mixin import ContextMixin
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa E402
from gi.repository import Gtk, Gdk
if TYPE_CHECKING:
from pathlib import Path
+2 -3
View File
@@ -32,7 +32,6 @@ if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
from dzgui.controllers.emitter import Emitter
from dzgui.model.model_factory import FastInsertListStore
from dzgui.util.dist import Haversine
QUEUE_CHECK_DELAY = 200
@@ -65,7 +64,7 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
self.queue_id: int
self.handler_id: int
self.queue: Queue[tuple[str, "Haversine" | None, ServerTab]] = Queue()
self.queue: Queue = Queue()
self.seen_cache: list[Record] = []
@@ -407,7 +406,7 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
path = model.get_path(it)
row_index = path.get_indices()[0]
try:
start, end = self.get_visible_range() # type: ignore[no-untyped-call]
start, end = self.get_visible_range()
except Exception:
return
if row_index >= start[0] <= end[0]:
+2 -1
View File
@@ -78,6 +78,7 @@ line-length = 88
indent-width = 4
extend-exclude = ["*lib/a2s"]
lint.unfixable = ["F401", "I001"]
lint.ignore = ["E402"]
[tool.ruff.format]
quote-style = "double"
@@ -104,7 +105,7 @@ python-a2s = { path = "./dzgui/lib/a2s", editable = true }
dayzquery = { path = "./dzgui/lib/dayzquery", editable = true }
[tool.uv]
config-settings-package = { pygobject-stubs = { config = "Gtk3,Gdk3" } }
config-settings-package = { pygobject-stubs = { config = "Gtk3,Gdk3,Soup2" } }
[tool.pytest.ini_options]
markers = [
-38
View File
@@ -1,38 +0,0 @@
from pathlib import Path
def iterate(search_str: str) -> None:
# TODO: exclude files from .gitignore
print()
print(f"Searching for '{search_str}'")
print()
files = Path(".").rglob("*")
ignore = [
"scripts/",
".git",
"egg",
"CHANGELOG",
".mypy",
"build/",
"test.py",
"bugs",
"pyproject.toml",
]
for file in files:
if file.is_dir():
continue
if any(s in str(file) for s in ignore):
continue
try:
text = file.read_text()
if search_str in text:
c = text.count(search_str)
if 0 < c < 2:
print(file, c)
except Exception:
continue
imports = ["Pango", "GObject", "GLib", "Gdk", "Gtk"]
for i in imports:
iterate(i)
+1 -1
View File
@@ -6,7 +6,7 @@ from dzgui.views.dialogs.servers import ServerDetailsDialog
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from gi.repository import Gtk
class MockController: