mirror of
https://github.com/aclist/dztui.git
synced 2026-11-11 20:40:38 +01:00
Compare commits
16
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c267b1bbc7 | ||
|
|
d0b3a723c6 | ||
|
|
535bc505f7 | ||
|
|
f2375feeec | ||
|
|
1b9448735d | ||
|
|
d5693b07fb | ||
|
|
7a6f4a2bb9 | ||
|
|
ba92d15085 | ||
|
|
65e04c2fc4 | ||
|
|
0907f5a474 | ||
|
|
bfa83c3f94 | ||
|
|
aef48e515b | ||
|
|
e6ebeaeb5e | ||
|
|
88c740105a | ||
|
|
b98a6f95a6 | ||
|
|
87d76e83ba |
No files matched your search
+3
-7
@@ -57,6 +57,7 @@
|
||||
- List timestamp of last DayZ client update
|
||||
- Validate mods via Mod page to pull in updates
|
||||
- Support for Nasdara (Badlands) DLC
|
||||
- Load offline mods
|
||||
|
||||
### Changed
|
||||
- Conform to PEP 440 versioning for beta versions
|
||||
@@ -99,16 +100,11 @@
|
||||
- Current keyword filter not being applied when refreshing table
|
||||
- Steam Flatpak cannot run DZGUI as a non-Steam game
|
||||
- Collisions between native Steam and Steam Flatpak clients
|
||||
|
||||
### Unreleased
|
||||
- Load offline mods
|
||||
- Local documentation
|
||||
- Raw debug command in context menu
|
||||
- Sticky toggle signal on radio buttons when reloading Options
|
||||
|
||||
### Developer-facing
|
||||
- Add pyproject.toml file
|
||||
- Show deprecation warnings
|
||||
- Options -> Dev page
|
||||
- Raw debug command in preconnect menu
|
||||
|
||||
## [6.0.5] 2026-05-17
|
||||
### Changed
|
||||
|
||||
+6
-5
@@ -5,7 +5,7 @@
|
||||
### Fetch submodules
|
||||
git submodule update --recursive --init
|
||||
|
||||
### Install with dev dependencies
|
||||
### Install into editable venv with dev dependencies
|
||||
uv pip install -e '.[dev]'
|
||||
|
||||
This includes all dependencies for building, linting, testing, and checking in code.
|
||||
@@ -16,7 +16,7 @@ docs: documentation tools
|
||||
lint: code linting, fixing, and type checking
|
||||
test: unit and integration tests
|
||||
|
||||
## Miscellaneous
|
||||
## Build process
|
||||
|
||||
### Setting up precommit hooks
|
||||
pre-commit install
|
||||
@@ -25,6 +25,7 @@ pre-commit install
|
||||
sphinx-build -M html source build -a
|
||||
|
||||
### Building standalone release binaries
|
||||
1. Set up the build target: `rustup target add x86_64-unknown-linux-musl`
|
||||
2. Run `python3 scripts/release.py`
|
||||
3. Generate a release and tag against the resulting tarfile generated in `dist`
|
||||
1. Install the applicable system package containing the 'musl-gcc' wrapper
|
||||
2. Set up the build target: `rustup target add x86_64-unknown-linux-musl`
|
||||
3. Run `python3 scripts/release.py`
|
||||
4. Generate a release and tag against the resulting tarfile generated in `dist`
|
||||
@@ -3,7 +3,6 @@ import logging
|
||||
import re
|
||||
|
||||
from concurrent.futures import ThreadPoolExecutor, wait
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
+1
-2
@@ -6,7 +6,6 @@ from importlib import resources
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
|
||||
from dzgui.const.constants import (
|
||||
APP_NAME,
|
||||
APP_NAME_LOWER,
|
||||
@@ -107,7 +106,7 @@ def load_steam_icon() -> None:
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk # noqa
|
||||
from gi.repository import Gtk
|
||||
|
||||
try:
|
||||
traversable = resources.files(APP_NAME_LOWER).joinpath(ICONS_PATH)
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ from dzgui.const.constants import (
|
||||
from dzgui.init.proc import is_sandboxed
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class Xdg:
|
||||
config: Path
|
||||
columns: Path
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import gi
|
||||
import logging
|
||||
import threading
|
||||
|
||||
from typing import Any, TYPE_CHECKING, Union
|
||||
|
||||
import dzgui.util._json as JSON # noqa
|
||||
|
||||
|
||||
from dzgui.config.userprefs import UserPrefs
|
||||
from dzgui.const.constants import APP_NAME
|
||||
from dzgui.const.enum import (
|
||||
ButtonType,
|
||||
ContextMenuItem,
|
||||
@@ -14,9 +14,6 @@ from dzgui.const.enum import (
|
||||
Preferences,
|
||||
ServerTab,
|
||||
)
|
||||
|
||||
from dzgui.config.userprefs import UserPrefs
|
||||
from dzgui.const.constants import APP_NAME
|
||||
from dzgui.controllers.emitter import Emitter
|
||||
from dzgui.managers.config import ConfigManager
|
||||
from dzgui.managers.connection import ConnectionManager
|
||||
@@ -29,8 +26,6 @@ from dzgui.util.open_links import open_user_workshop, open_workshop_page
|
||||
from dzgui.views.dialogs.filepicker import FilePicker
|
||||
from dzgui.views.dialogs.generic import ExceptionDialog
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GLib, GObject
|
||||
|
||||
@@ -371,7 +366,6 @@ class Controller(GObject.GObject):
|
||||
filter_man = self.get_filter_man()
|
||||
return filter_man.get_filters()
|
||||
|
||||
# FIXME: wipe maps store when changing tabs if model is none
|
||||
def has_server_model(self) -> bool:
|
||||
treeview = self.get_active_treeview()
|
||||
proxy_man = treeview.get_proxy_man()
|
||||
|
||||
+10
-7
@@ -53,6 +53,11 @@
|
||||
- Expand/collapse changelog versions
|
||||
- Support local light/dark mode changes on system theme
|
||||
- Server time calculator
|
||||
- Add "Unmodded" filter to servers
|
||||
- List timestamp of last DayZ client update
|
||||
- Validate mods via Mod page to pull in updates
|
||||
- Support for Nasdara (Badlands) DLC
|
||||
- Load offline mods
|
||||
|
||||
### Changed
|
||||
- Conform to PEP 440 versioning for beta versions
|
||||
@@ -74,6 +79,7 @@
|
||||
- Enable LAN page Empty/Full filters on first run of app
|
||||
- Propagate subscribed mods to Steam client
|
||||
- Make j/k keys in context menus follow same wraparound logic as down arrow/up arrow
|
||||
- Use SQLite DB for geolocation records
|
||||
|
||||
### Dropped
|
||||
- Battlemetrics API support
|
||||
@@ -92,16 +98,13 @@
|
||||
- Moved dialogs out of threads
|
||||
- History table not being in lock-step with state file
|
||||
- Current keyword filter not being applied when refreshing table
|
||||
|
||||
### Unreleased
|
||||
- Load offline mods
|
||||
- Local documentation
|
||||
- Raw debug command in context menu
|
||||
- Steam Flatpak cannot run DZGUI as a non-Steam game
|
||||
- Collisions between native Steam and Steam Flatpak clients
|
||||
- Sticky toggle signal on radio buttons when reloading Options
|
||||
|
||||
### Developer-facing
|
||||
- Add pyproject.toml file
|
||||
- Show deprecation warnings
|
||||
- Options -> Dev page
|
||||
- Raw debug command in preconnect menu
|
||||
|
||||
## [6.0.5] 2026-05-17
|
||||
### Changed
|
||||
|
||||
@@ -330,7 +330,6 @@ class ConnectionManager:
|
||||
|
||||
self.thread_man.update_dialog(waiting_for_launch)
|
||||
while True:
|
||||
# FIXME: cancel should not be visible here per setting above
|
||||
if self.controller.is_cancel_pending():
|
||||
# TODO: some facility to also close spawned steam process
|
||||
return
|
||||
|
||||
@@ -58,6 +58,11 @@ class ServerRow:
|
||||
getter = cls._to_tuple
|
||||
return [getter(row) for row in rows]
|
||||
|
||||
@classmethod
|
||||
def get_index(cls, field: str) -> int:
|
||||
_fields = [f.name for f in fields(cls)]
|
||||
return _fields.index(field)
|
||||
|
||||
|
||||
class FiltrationManager:
|
||||
def __init__(self) -> None:
|
||||
|
||||
@@ -34,7 +34,7 @@ LAN_TIMEOUT = 0.5
|
||||
API_TIMEOUT = 3
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class NewPlayerCount:
|
||||
treeiter: Gtk.TreeIter
|
||||
players: int
|
||||
@@ -341,8 +341,8 @@ class ServerModelManager:
|
||||
return
|
||||
config_man.add_saved_server(fqip)
|
||||
|
||||
# FIXME: this is valid if saved servers tab is already open,
|
||||
# but not if app was just booted; causes single row to appear prematurely
|
||||
# TODO: this is valid if saved servers tab is already open,
|
||||
# but not if tab is unloaded; causes single row to appear prematurely
|
||||
if proxy_man.has_control_model() is False:
|
||||
proxy_man.push(records)
|
||||
else:
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Callable
|
||||
|
||||
def immutable_dataclass(cls: type | None = None, **kwargs: bool) -> type | Callable[[type], type]:
|
||||
kwargs["slots"] = True
|
||||
kwargs["frozen"] = True
|
||||
if cls is None:
|
||||
return lambda c: dataclass(c, **kwargs)
|
||||
return dataclass(cls, **kwargs)
|
||||
+2
-3
@@ -1,10 +1,10 @@
|
||||
import a2s
|
||||
from ipaddress import ip_address
|
||||
import requests
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
from dataclasses import dataclass
|
||||
from ipaddress import ip_address
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from dzgui.api.servers import Record
|
||||
@@ -12,12 +12,11 @@ from dzgui.config.ipdb import read_from_table
|
||||
from dzgui.const.constants import REQUEST_TIMEOUT
|
||||
from dzgui.const.endpoints import IP_ECHO
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class Coords:
|
||||
lat: float
|
||||
lon: float
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from typing import Sequence
|
||||
|
||||
import gi
|
||||
|
||||
from typing import Sequence
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk # noqa
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
class GenericBox(Gtk.Box):
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
from typing import Self
|
||||
from dzgui.util import css
|
||||
|
||||
import gi
|
||||
|
||||
from typing import Self
|
||||
|
||||
from dzgui.util import css
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk # noqa
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
# TODO: subclass Gtk.Frame directly
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import gi
|
||||
from typing import Self
|
||||
from warnings import deprecated
|
||||
|
||||
@@ -8,10 +9,8 @@ from dzgui.strings import options
|
||||
from dzgui.views.components.box import HBox
|
||||
from dzgui.views.components.buttons import Icon
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk # noqa
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
@deprecated("Client choice is determined at setup time")
|
||||
|
||||
@@ -106,14 +106,15 @@ class RightPanel(Gtk.Box):
|
||||
if page.loaded is True:
|
||||
return
|
||||
self.filters_vbox.set_sensitive(False)
|
||||
# TODO: unless it is lan page
|
||||
# self.refresh_button.set_sensitive(False)
|
||||
self.refresh_button.set_sensitive(False)
|
||||
|
||||
def _on_lan_page_init(self, emitter: "Emitter") -> None:
|
||||
self.filters_vbox.set_sensitive(False)
|
||||
|
||||
def _on_servers_loaded(self, emitter: "Emitter", context: "ServerTab") -> None:
|
||||
# TODO: similar logic on notebook page change
|
||||
# TODO: wipe maps store when changing tabs if model is None
|
||||
|
||||
state = self.controller.has_server_model()
|
||||
self.filters_vbox.set_sensitive(state)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk # noqa
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
class NoOverlayScrolledWindow(Gtk.ScrolledWindow):
|
||||
|
||||
@@ -101,7 +101,7 @@ class Statusbar(Gtk.Grid):
|
||||
if type(context) is NotebookPage:
|
||||
self.prior_enum = context
|
||||
self.prior_status = ""
|
||||
# FIXME: CalcDist is being called when table is not loaded
|
||||
|
||||
if dist is None:
|
||||
self.set_by_context(context, "")
|
||||
return
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
import gi
|
||||
import sys
|
||||
|
||||
from enum import Enum
|
||||
from typing import Any, Literal, Self, TYPE_CHECKING
|
||||
|
||||
# import time
|
||||
from enum import Enum
|
||||
|
||||
|
||||
from dzgui.views.mixins.colorscheme import ColorAwareApp
|
||||
|
||||
# TODO: import dialog titles
|
||||
from dzgui.api.mods import remove_stale_signatures as remove_stale
|
||||
from dzgui.config.ipdb import get_ipdb
|
||||
from dzgui.const.constants import HEX_GREEN, HEX_RED
|
||||
@@ -20,12 +16,10 @@ from dzgui.util.format import format_exception
|
||||
from dzgui.util.strings import dialog_header
|
||||
from dzgui.util.symlink import rebuild_symlinks
|
||||
from dzgui.views.components.buttons import ClipboardButton
|
||||
|
||||
|
||||
import gi
|
||||
from dzgui.views.mixins.colorscheme import ColorAwareApp
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GLib, Gdk # noqa
|
||||
from gi.repository import Gtk, GLib, Gdk
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.config.xdg import Xdg
|
||||
|
||||
@@ -54,6 +54,7 @@ class FolderPicker(Gtk.FileChooserDialog):
|
||||
return None
|
||||
if res == Gtk.ResponseType.OK:
|
||||
folder = self.get_current_folder()
|
||||
# TODO: this should never be possible
|
||||
if folder is None:
|
||||
try:
|
||||
uri = self.get_uri()
|
||||
|
||||
@@ -15,7 +15,7 @@ from dzgui.views.dialogs.generic import GenericDialog
|
||||
from dzgui.views.trees.tree_base import TreeView
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, Pango # noqa
|
||||
from gi.repository import Gtk, Gdk, Pango
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.api.servers import Details
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import gi
|
||||
|
||||
from typing import Any
|
||||
|
||||
from dzgui.const.constants import (
|
||||
@@ -7,10 +9,8 @@ from dzgui.const.constants import (
|
||||
GIO_SETTINGS_VAL,
|
||||
)
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gio # noqa
|
||||
from gi.repository import Gtk, Gio
|
||||
|
||||
|
||||
class ColorAwareApp:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk # noqa
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
|
||||
class HelpMenuMixin:
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import gi
|
||||
|
||||
from dzgui.const.enum import VAdjustment
|
||||
from dzgui.const.constants import SCROLL_INCREMENT
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk # noqa
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
|
||||
class ScrollableMixin:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import gi
|
||||
from pathlib import Path
|
||||
|
||||
from typing import Self, TYPE_CHECKING
|
||||
@@ -8,10 +9,8 @@ from dzgui.views.components.buttons import SteamWorkshopButton
|
||||
from dzgui.views.components.scrollable import NoOverlayScrolledWindow
|
||||
from dzgui.views.trees.tree_mods import ModTreeView
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk # noqa
|
||||
from gi.repository import Gtk
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import gi
|
||||
|
||||
from enum import Enum
|
||||
from typing import Self, TYPE_CHECKING, Union
|
||||
|
||||
from dzgui.util import css
|
||||
from dzgui.const.icons import ICON_EDIT_DELETE, ICON_FOLDER, ICON_WARNING
|
||||
from dzgui.const.constants import (
|
||||
APPID_DAYZ,
|
||||
APPID_DAYZ_EXP,
|
||||
@@ -11,8 +12,10 @@ from dzgui.const.constants import (
|
||||
APPNAME_DAYZ_EXP_HUMAN,
|
||||
)
|
||||
from dzgui.const.enum import ContextMenuGroup, NotebookPage
|
||||
from dzgui.const.icons import ICON_EDIT_DELETE, ICON_FOLDER, ICON_WARNING
|
||||
from dzgui.managers.offline import OfflineManager
|
||||
from dzgui.strings import generic, offline
|
||||
from dzgui.util import css
|
||||
from dzgui.views.components.box import HBox, VBox
|
||||
from dzgui.views.components.buttons import Icon, IconTextButton
|
||||
from dzgui.views.components.eventbox import InfoEventBox
|
||||
@@ -21,11 +24,8 @@ from dzgui.views.components.scrollable import NoOverlayScrolledWindow
|
||||
from dzgui.views.components.misc import ErrorPopover
|
||||
from dzgui.views.trees.tree_mods import OfflineModTreeView
|
||||
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GObject # noqa
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
@@ -136,7 +136,6 @@ class FolderHBox(HBox):
|
||||
self.folder = ""
|
||||
self.label.set_label("")
|
||||
self.unset_button.hide()
|
||||
# FIXME: rename signal
|
||||
self.emitter.emit("custom_mods_unloaded", self)
|
||||
|
||||
def get_button(self) -> Gtk.Button:
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import gi
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable, TYPE_CHECKING
|
||||
|
||||
from dzgui.api import pefile as PeFile
|
||||
from dzgui.api.steam import get_last_updated
|
||||
|
||||
from dzgui.config import query
|
||||
from dzgui.const.constants import (
|
||||
APPID_DAYZ,
|
||||
@@ -14,12 +15,11 @@ from dzgui.const.constants import (
|
||||
FLATPAK_SANDBOX,
|
||||
FLATPAK_STEAM_PATH,
|
||||
)
|
||||
from dzgui.const.icons import ICON_VIEW_CONCEAL, ICON_VIEW_REVEAL
|
||||
from dzgui.const.endpoints import STEAM_API_SETUP
|
||||
from dzgui.const.enum import Preferences, ServerTab
|
||||
from dzgui.const.icons import ICON_VIEW_CONCEAL, ICON_VIEW_REVEAL
|
||||
from dzgui.strings import options
|
||||
from dzgui.util import strings, css, open_links
|
||||
|
||||
from dzgui.views.components.box import ShortHBox, VBox
|
||||
from dzgui.views.components.eventbox import InfoEventBox
|
||||
from dzgui.views.components.labels import LeftLabel
|
||||
@@ -29,11 +29,8 @@ from dzgui.views.components.misc import ErrorPopover
|
||||
from dzgui.views.dialogs.generic import ExceptionDialog
|
||||
from dzgui.views.mixins.scrollable_mixin import ScrollableMixin
|
||||
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk # noqa
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
@@ -233,10 +230,19 @@ class ToggleField(Gtk.Box):
|
||||
self.pack_start(self.radio1, expand=False, fill=False, padding=0)
|
||||
self.pack_start(self.radio2, expand=False, fill=False, padding=0)
|
||||
|
||||
self.signal_id: int | None = None
|
||||
|
||||
def disconnect_signal(self) -> None:
|
||||
if self.signal_id is not None:
|
||||
self.radio1.disconnect(self.signal_id)
|
||||
|
||||
def set_suboption_active(self, state: bool) -> None:
|
||||
# NOTE: defer connection of signal until after state is set
|
||||
self.radio2.set_active(state)
|
||||
self.radio1.connect("toggled", self._on_radio_toggled, self.context)
|
||||
self.disconnect_signal()
|
||||
self.signal_id = self.radio1.connect(
|
||||
"toggled", self._on_radio_toggled, self.context
|
||||
)
|
||||
|
||||
def _on_radio_toggled(self, button: Gtk.RadioButton, context: Preferences) -> None:
|
||||
self.controller.toggle_config(context)
|
||||
@@ -486,14 +492,5 @@ class Options(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
|
||||
start_tab = self.controller.query_config(Preferences.START_TAB)
|
||||
self.start_tab_combo.set_active(start_tab)
|
||||
|
||||
def _suppress_toggles(self, state: bool) -> None:
|
||||
for toggle in [
|
||||
self.fullscreen_toggle,
|
||||
self.distance_toggle,
|
||||
]:
|
||||
self.controller.suppress_signal(
|
||||
self, toggle.get_children()[0], "_on_radio_toggled", state
|
||||
)
|
||||
|
||||
def grab_content_area(self) -> None:
|
||||
self.grab_focus()
|
||||
@@ -1,11 +1,12 @@
|
||||
from dataclasses import dataclass
|
||||
import gi
|
||||
|
||||
from typing import Self, Sequence, TYPE_CHECKING
|
||||
|
||||
from dzgui.const.enum import NotebookPage
|
||||
from dzgui.const.icons import (
|
||||
ICON_ERROR,
|
||||
ICON_WARNING,
|
||||
)
|
||||
from dzgui.const.enum import NotebookPage
|
||||
from dzgui.util.css import add_class
|
||||
from dzgui.util.keys import is_ctrl_mask
|
||||
from dzgui.util.localize import number
|
||||
@@ -15,33 +16,15 @@ from dzgui.views.dialogs.generic import DebugDialog
|
||||
from dzgui.views.components.frame import HeadingFrame
|
||||
from dzgui.views.trees.tree_server_mods import ServerModTreeView
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gdk, Gtk
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.managers.connection import Prerequisites
|
||||
from dzgui.controllers.mc import Controller
|
||||
from dzgui.controllers.emitter import Emitter
|
||||
|
||||
|
||||
@dataclass
|
||||
class Warnings:
|
||||
passworded: bool
|
||||
dayz_running: bool
|
||||
no_steam: bool
|
||||
wrong_version: bool
|
||||
|
||||
|
||||
@dataclass
|
||||
class Errors:
|
||||
no_space: bool
|
||||
no_dayz_exp: bool
|
||||
no_dayz: bool
|
||||
|
||||
|
||||
class Placeholder(Gtk.Label):
|
||||
def __init__(self, text: str) -> None:
|
||||
super().__init__(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import gi
|
||||
import logging
|
||||
|
||||
from typing import Any, Optional, TYPE_CHECKING
|
||||
@@ -6,10 +7,8 @@ from dzgui.const.constants import APP_NAME, SEPARATOR
|
||||
from dzgui.util.keys import is_ctrl_mask, is_navkey
|
||||
from dzgui.views.mixins.cursor_mixin import CursorMixin
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa
|
||||
from gi.repository import Gtk, Gdk, GObject
|
||||
|
||||
logger = logging.getLogger(APP_NAME)
|
||||
|
||||
|
||||
@@ -10,7 +10,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
|
||||
from gi.repository import Gtk
|
||||
|
||||
logger = logging.getLogger(APP_NAME)
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import gi
|
||||
import logging
|
||||
|
||||
from typing import Any, TYPE_CHECKING
|
||||
|
||||
from dzgui.const.constants import APP_NAME, HEX_RED
|
||||
@@ -9,10 +11,8 @@ from dzgui.views.mixins.context_mixin import ContextMixin
|
||||
from dzgui.views.mixins.mods_mixin import ModsMixin
|
||||
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
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import gi
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from dzgui.const.enum import ContextMenuGroup
|
||||
from dzgui.model.model_factory import ModelFactory
|
||||
from dzgui.strings import server_mods
|
||||
from dzgui.views.mixins.context_mixin import ContextMixin
|
||||
from dzgui.views.trees.tree_base import TreeView
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GLib, Gdk, Pango # noqa
|
||||
from gi.repository import Gtk, Pango
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
|
||||
@@ -1,30 +1,25 @@
|
||||
import gi
|
||||
import logging
|
||||
import threading
|
||||
|
||||
from queue import Queue
|
||||
from typing import Any, Self, Union
|
||||
from typing import Any, Literal, Self, TYPE_CHECKING, Union
|
||||
from warnings import deprecated
|
||||
|
||||
from dzgui.api.servers import ping, Record
|
||||
from dzgui.const.constants import APP_NAME
|
||||
from dzgui.const.enum import ContextMenuItem, ContextMenuGroup, ServerTab
|
||||
from dzgui.managers.filter import FilterManager
|
||||
from dzgui.model.proxy_model import ProxyModelManager
|
||||
from dzgui.model.proxy_model import ProxyModelManager, ServerRow
|
||||
from dzgui.util import strings
|
||||
from dzgui.util.dist import CalcDist
|
||||
from dzgui.util.keys import is_ctrl_mask
|
||||
from dzgui.views.mixins.context_mixin import ContextMixin
|
||||
from typing import Literal, TYPE_CHECKING
|
||||
|
||||
|
||||
from dzgui.views.trees.tree_base import TreeView
|
||||
import dzgui.util._json as JSON # noqa
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa
|
||||
|
||||
from gi.repository import Gtk, GLib, Gdk, GObject
|
||||
|
||||
logger = logging.getLogger(APP_NAME)
|
||||
|
||||
@@ -34,8 +29,14 @@ if TYPE_CHECKING:
|
||||
from dzgui.model.model_factory import FastInsertListStore
|
||||
from dzgui.util.dist import Haversine
|
||||
|
||||
# TODO: consts
|
||||
QUEUE_CHECK_DELAY = 200
|
||||
|
||||
IND_NAME = ServerRow.get_index("name")
|
||||
IND_ADDR = ServerRow.get_index("ip")
|
||||
IND_QPORT = ServerRow.get_index("qport")
|
||||
IND_PING = ServerRow.get_index("ping")
|
||||
IND_MODDED = ServerRow.get_index("modded")
|
||||
|
||||
class ServerTreeView(ContextMixin, TreeView): # type: ignore
|
||||
def __init__(
|
||||
@@ -145,8 +146,8 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
|
||||
if model is None:
|
||||
return False
|
||||
tree_iter = model.get_iter(path[0])
|
||||
ip = model.get_value(tree_iter, 7)
|
||||
qport = model.get_value(tree_iter, 8)
|
||||
ip = model.get_value(tree_iter, IND_ADDR)
|
||||
qport = model.get_value(tree_iter, IND_QPORT)
|
||||
addr = ip + ":" + str(qport)
|
||||
note = self.controller.get_note_by_record(addr)
|
||||
|
||||
@@ -169,14 +170,12 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
|
||||
return self.enum
|
||||
|
||||
def _on_map(self, widget: Self) -> None:
|
||||
# TODO: disable filter panel if current model is None
|
||||
state = self.get_enum() is ServerTab.LAN
|
||||
self.emitter.emit("lan_tab_toggled", state)
|
||||
|
||||
store = self.filter_man.get_map_store()
|
||||
|
||||
# FIXME: if model is none, wipe maps
|
||||
# distinguish this signal from changing map combo in-situ
|
||||
# TODO: distinguish this signal from changing map combo in-situ
|
||||
self.emitter.emit("load_maps", store)
|
||||
self.handler_id = self.emitter.connect("statusbar_loaded", self.start_distcalc)
|
||||
self.start_queue_checker()
|
||||
@@ -221,7 +220,7 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
|
||||
|
||||
def _check_result_queue(self) -> Literal[True]:
|
||||
latest_result = None
|
||||
# FIXME: empty results cause statusbar to be emptied
|
||||
# TODO: Nonetype results cause statusbar to be blank
|
||||
while not self.queue.empty():
|
||||
latest_result = self.queue.get()
|
||||
|
||||
@@ -267,15 +266,9 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
|
||||
(model, pathlist) = sels
|
||||
path = pathlist[0]
|
||||
tree_iter = model.get_iter(path)
|
||||
has_mods = model.get_value(tree_iter, 11)
|
||||
has_mods = model.get_value(tree_iter, IND_MODDED)
|
||||
return bool(has_mods)
|
||||
|
||||
# def get_selected_row(self) -> Gtk.TreeModelRow:
|
||||
# sel = self.get_selection()
|
||||
# sels = sel.get_selected_rows()
|
||||
# print(type(sels[0]))
|
||||
# return sels[0]
|
||||
|
||||
def is_in_favs(self) -> bool:
|
||||
record = self.get_record_string()
|
||||
if self.controller.get_config_man().is_in_favs(record):
|
||||
@@ -304,17 +297,17 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
|
||||
self.start_distcalc()
|
||||
|
||||
def get_name(self) -> str:
|
||||
return str(self.get_value_at_index(0))
|
||||
return str(self.get_value_at_index(IND_NAME))
|
||||
|
||||
def get_simplified_ip(self) -> str:
|
||||
addr = self.get_value_at_index(7)
|
||||
qport = self.get_value_at_index(8)
|
||||
addr = self.get_value_at_index(IND_ADDR)
|
||||
qport = self.get_value_at_index(IND_QPORT)
|
||||
ip = addr.split(":")[0]
|
||||
return f"{ip}:{qport}"
|
||||
|
||||
def get_record_string(self) -> str:
|
||||
addr = self.get_value_at_index(7)
|
||||
qport = self.get_value_at_index(8)
|
||||
addr = self.get_value_at_index(IND_ADDR)
|
||||
qport = self.get_value_at_index(IND_QPORT)
|
||||
return f"{addr}:{qport}"
|
||||
|
||||
def get_record(self) -> Record | None:
|
||||
@@ -353,8 +346,7 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
|
||||
def _redraw(
|
||||
self, model: "FastInsertListStore", _iter: Gtk.TreeIter, _ping: int
|
||||
) -> None:
|
||||
ping_column = 9
|
||||
model.set(_iter, ping_column, _ping)
|
||||
model.set(_iter, IND_PING, _ping)
|
||||
self.queue_draw()
|
||||
|
||||
def wipe_cache(self) -> None:
|
||||
@@ -369,13 +361,10 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
|
||||
data: Any,
|
||||
) -> None:
|
||||
|
||||
addr_column = 7
|
||||
qport_column = 8
|
||||
|
||||
addr = model.get_value(_iter, addr_column).split(":")
|
||||
addr = model.get_value(_iter, IND_ADDR).split(":")
|
||||
ip = addr[0]
|
||||
gameport = int(addr[1])
|
||||
qport = model.get_value(_iter, qport_column)
|
||||
qport = model.get_value(_iter, IND_QPORT)
|
||||
record = Record(ip, gameport, qport)
|
||||
|
||||
if record in self.seen_cache:
|
||||
@@ -415,6 +404,7 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
|
||||
real_model = self.proxy_man.get_control()
|
||||
from dataclasses import fields
|
||||
from dzgui.model.proxy_model import ServerRow
|
||||
|
||||
key = fields(ServerRow)[col_index].name
|
||||
|
||||
value = getattr(real_model[row_index], key)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import gi
|
||||
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.model.model_factory import FastInsertListStore
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk # noqa
|
||||
|
||||
|
||||
class SimpleTree(Gtk.ScrolledWindow):
|
||||
"""Simple scrollable 1-column tree"""
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import gi
|
||||
import pytest
|
||||
import subprocess
|
||||
|
||||
from dzgui.const.constants import GIO_SETTINGS_KEY
|
||||
from dzgui.views.mixins.colorscheme import ColorAwareApp
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gio, GLib # noqa
|
||||
from gi.repository import Gtk, GLib
|
||||
|
||||
|
||||
class DummyWidget(ColorAwareApp, Gtk.Button):
|
||||
|
||||
@@ -48,5 +48,5 @@ def test_signatures_with_no_ids(monkeypatch, tmp: str, versions: str) -> None:
|
||||
monkeypatch.setattr("dzgui.api.mods.lookup", mock_lookup)
|
||||
dzgui.api.mods.remove_stale_signatures(path, path)
|
||||
with open(tmp, "r") as f:
|
||||
lines = f.readlines()
|
||||
assert lines == ["3410710885,1752864732\n", "3739934289,1780855136\n"]
|
||||
lines = [line.rstrip() for line in f.readlines()]
|
||||
assert lines == ["3410710885,1752864732", "3739934289,1780855136"]
|
||||
@@ -7,7 +7,7 @@ from dzgui.api.steam import (
|
||||
VDFLoadError,
|
||||
AppNotInstalledError,
|
||||
AppMovedError,
|
||||
get_app_path
|
||||
get_app_path,
|
||||
)
|
||||
|
||||
from dzgui.config.query import get_config
|
||||
@@ -26,9 +26,8 @@ def default_steam_path():
|
||||
conf = get_config(xdg.config)
|
||||
return conf["default_steam_path"]
|
||||
|
||||
# TODO: additional parsing tests
|
||||
|
||||
# TODO: split into separate test file
|
||||
# FIXME: use fixtures
|
||||
def test_pefile_length(default_steam_path):
|
||||
try:
|
||||
pe_file_path = PeFile.get_pefile_path(Path(default_steam_path), APPID_DAYZ)
|
||||
@@ -47,6 +46,7 @@ def test_invalid_pefile_path():
|
||||
raise e
|
||||
|
||||
|
||||
# TODO: split into separate test file
|
||||
@pytest.mark.parametrize(
|
||||
"fixture, exception",
|
||||
[
|
||||
@@ -57,6 +57,7 @@ def test_invalid_pefile_path():
|
||||
)
|
||||
def test_not_in_library(monkeypatch, fixture, exception):
|
||||
import dzgui.api.steam as steam
|
||||
|
||||
monkeypatch.setattr(steam, "LIBRARYFOLDERS_PATH", fixture)
|
||||
|
||||
folder_path = Path(fixture_path("api"))
|
||||
@@ -74,6 +75,7 @@ def second_drive():
|
||||
|
||||
def test_on_second_drive(monkeypatch, second_drive):
|
||||
import dzgui.api.steam as steam
|
||||
|
||||
monkeypatch.setattr(steam, "LIBRARYFOLDERS_PATH", second_drive)
|
||||
folder_path = Path(fixture_path("api"))
|
||||
path = get_app_path(folder_path, APPID_DAYZ)
|
||||
|
||||
Reference in new issue
Block a user