mirror of
https://github.com/aclist/dztui.git
synced 2026-11-10 03:50:38 +01:00
Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cab10efc96 | ||
|
|
0a4efba905 | ||
|
|
1e4e09e52c | ||
|
|
910c068109 | ||
|
|
1dd773a9bf | ||
|
|
f4d065d766 | ||
|
|
1fe66076c6 | ||
|
|
668ec1d7a0 | ||
|
|
412f0d3193 | ||
|
|
894a9b106d | ||
|
|
1b0a9c9a69 | ||
|
|
c4818d2097 | ||
|
|
69135150c7 | ||
|
|
4d8949427b |
No files matched your search
@@ -57,6 +57,7 @@
|
|||||||
- Disable overlay scrollbars on server tables
|
- Disable overlay scrollbars on server tables
|
||||||
- Reduce size of geolocation DB on disk (~100MB)
|
- Reduce size of geolocation DB on disk (~100MB)
|
||||||
- Enable LAN page Empty/Full filters on first run of app
|
- Enable LAN page Empty/Full filters on first run of app
|
||||||
|
- Propagate subscribed mods to Steam client
|
||||||
|
|
||||||
## Dropped
|
## Dropped
|
||||||
- Debug mode
|
- Debug mode
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
import re
|
||||||
|
from collections.abc import Iterator
|
||||||
|
from typing import Any
|
||||||
|
from warnings import deprecated
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated("Use dzgui.api.steam.unsubscribe()")
|
||||||
|
class WorkshopACF:
|
||||||
|
def __init__(self, file: str) -> None:
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.dict: dict[str, Any]
|
||||||
|
self.load(file)
|
||||||
|
|
||||||
|
def as_dict(self) -> dict[str, Any]:
|
||||||
|
return self.dict
|
||||||
|
|
||||||
|
def load(self, file: str) -> None:
|
||||||
|
delimiter = r"\t\t"
|
||||||
|
lines = []
|
||||||
|
with open(file, "r", encoding="utf-8") as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
els = re.split(delimiter, line, maxsplit=1)
|
||||||
|
lines.append(els)
|
||||||
|
self.dict = self.parse(iter(lines))
|
||||||
|
|
||||||
|
def parse(self, lines: Iterator[list[str]]) -> dict[str, str]:
|
||||||
|
acf: dict[str, Any] = {}
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
line = next(lines)
|
||||||
|
if len(line) == 1:
|
||||||
|
key = line[0]
|
||||||
|
if key == "{":
|
||||||
|
continue
|
||||||
|
return acf
|
||||||
|
elif key == "}":
|
||||||
|
return acf
|
||||||
|
else:
|
||||||
|
key = self.dequote(key)
|
||||||
|
acf[key] = self.parse(lines)
|
||||||
|
elif len(line) == 2:
|
||||||
|
k, v = line
|
||||||
|
k = self.dequote(k)
|
||||||
|
v = self.dequote(v)
|
||||||
|
try:
|
||||||
|
n = list(acf.keys())[-1]
|
||||||
|
acf[n][k] = v
|
||||||
|
except Exception:
|
||||||
|
acf[k] = v
|
||||||
|
except StopIteration:
|
||||||
|
return acf
|
||||||
|
|
||||||
|
def unpack(self, d: dict, lines: list[Any] = []) -> str:
|
||||||
|
t1 = "AppWorkshop"
|
||||||
|
t2 = ("WorkshopItemsInstalled", "WorkshopItemDetails")
|
||||||
|
for k, v in d.items():
|
||||||
|
if type(v) is dict:
|
||||||
|
if k in t1:
|
||||||
|
self.indent = 0
|
||||||
|
elif k in t2:
|
||||||
|
self.indent = 1
|
||||||
|
else:
|
||||||
|
self.indent = 2
|
||||||
|
pref = "\t" * self.indent
|
||||||
|
lines.append(pref + self.enquote(k))
|
||||||
|
lines.append(pref + "{")
|
||||||
|
self.unpack(v, lines)
|
||||||
|
lines.append(pref + "}")
|
||||||
|
else:
|
||||||
|
pref = "\t" * (self.indent + 1)
|
||||||
|
lines.append(pref + self.enquote(k) + "\t\t" + self.enquote(v))
|
||||||
|
s = ""
|
||||||
|
for line in lines:
|
||||||
|
s += line + "\n"
|
||||||
|
return s
|
||||||
|
|
||||||
|
def to_file(self, file: str) -> None:
|
||||||
|
s = self.unpack(self.dict)
|
||||||
|
with open(file, "w") as f:
|
||||||
|
f.write(s)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enquote(cls, s: str) -> str:
|
||||||
|
return f'"{s}"'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def dequote(cls, s: str) -> str:
|
||||||
|
return s.rstrip('"').lstrip('"')
|
||||||
|
|
||||||
|
def delete(self, modid: int) -> None:
|
||||||
|
del self.dict["AppWorkshop"]["WorkshopItemsInstalled"][modid]
|
||||||
|
del self.dict["AppWorkshop"]["WorkshopItemDetails"][modid]
|
||||||
+10
-8
@@ -71,21 +71,21 @@ def get_local_signatures(version_file: Path) -> dict[str, int]:
|
|||||||
for line in lines:
|
for line in lines:
|
||||||
data = line.split(",")
|
data = line.split(",")
|
||||||
_id = data[0]
|
_id = data[0]
|
||||||
_hash = int(data[1])
|
mod_hash = int(data[1])
|
||||||
hashes[_id] = _hash
|
hashes[_id] = mod_hash
|
||||||
return hashes
|
return hashes
|
||||||
|
|
||||||
|
|
||||||
def get_needs_update(
|
def get_needs_update(
|
||||||
version_file: Path, remote_hashes: list[tuple[str, str, int, int]]
|
version_file: Path, remote_hashes: list[tuple[str, str, int, int]]
|
||||||
) -> list[tuple[str, str, int, int]]:
|
) -> list[tuple[str, str, int, int]]:
|
||||||
local_hashes = get_local_signatures(version_file)
|
local_stamps = get_local_signatures(version_file)
|
||||||
needs_update: list[tuple[str, str, int, int]] = []
|
needs_update: list[tuple[str, str, int, int]] = []
|
||||||
for title, _id, mod_hash, size in remote_hashes:
|
for title, _id, stamp, size in remote_hashes:
|
||||||
if _id not in local_hashes:
|
if _id not in local_stamps:
|
||||||
needs_update.append((title, _id, mod_hash, size))
|
needs_update.append((title, _id, stamp, size))
|
||||||
elif _hash != local_hashes[_id]:
|
elif stamp != local_stamps[_id]:
|
||||||
needs_update.append((title, _id, mod_hash, size))
|
needs_update.append((title, _id, stamp, size))
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
return needs_update
|
return needs_update
|
||||||
@@ -252,6 +252,7 @@ def subscribe(key: str, mod: int) -> None:
|
|||||||
def unsubscribe(key: str, mod: int) -> None:
|
def unsubscribe(key: str, mod: int) -> None:
|
||||||
update_workshop(key, mod, UNSUB_ENDPOINT)
|
update_workshop(key, mod, UNSUB_ENDPOINT)
|
||||||
|
|
||||||
|
|
||||||
def gen_shortcut() -> None:
|
def gen_shortcut() -> None:
|
||||||
# TODO:
|
# TODO:
|
||||||
"""
|
"""
|
||||||
@@ -265,6 +266,7 @@ def gen_shortcut() -> None:
|
|||||||
# STEAMID_64 & 0xFFFFFFFF
|
# STEAMID_64 & 0xFFFFFFFF
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@deprecated("Use subscribe()")
|
@deprecated("Use subscribe()")
|
||||||
def enqueue_mod(client: str, mod: str, appid: int) -> None:
|
def enqueue_mod(client: str, mod: str, appid: int) -> None:
|
||||||
client_args = concat_bash_args(client)
|
client_args = concat_bash_args(client)
|
||||||
|
|||||||
@@ -523,11 +523,11 @@ class Controller(GObject.GObject):
|
|||||||
ind = self.config_man.get_start_tab()
|
ind = self.config_man.get_start_tab()
|
||||||
self.get_servers().notebook.set_current_page(ind)
|
self.get_servers().notebook.set_current_page(ind)
|
||||||
|
|
||||||
def update_and_load_to_menu(self, raise_window: bool) -> None:
|
def update_and_load_to_menu(self) -> None:
|
||||||
self.connection_man.update_and_connect(raise_window, menu_only=True)
|
self.connection_man.update_and_connect(menu_only=True)
|
||||||
|
|
||||||
def update_and_connect(self, raise_window: bool) -> None:
|
def update_and_connect(self) -> None:
|
||||||
self.connection_man.update_and_connect(raise_window)
|
self.connection_man.update_and_connect()
|
||||||
|
|
||||||
def update_status(self) -> None:
|
def update_status(self) -> None:
|
||||||
self.mediator.preconnect.mark_finished()
|
self.mediator.preconnect.mark_finished()
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
- Preboot progress dialog
|
- Preboot progress dialog
|
||||||
- Choose to jump into splash screen instead of server
|
- Choose to jump into splash screen instead of server
|
||||||
- Collapsible connection panel
|
- Collapsible connection panel
|
||||||
|
- Play offline (load mods directly)
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
- Conform to PEP 440 versioning for beta versions
|
- Conform to PEP 440 versioning for beta versions
|
||||||
@@ -56,6 +57,7 @@
|
|||||||
- Disable overlay scrollbars on server tables
|
- Disable overlay scrollbars on server tables
|
||||||
- Reduce size of geolocation DB on disk (~100MB)
|
- Reduce size of geolocation DB on disk (~100MB)
|
||||||
- Enable LAN page Empty/Full filters on first run of app
|
- Enable LAN page Empty/Full filters on first run of app
|
||||||
|
- Propagate subscribed mods to Steam client
|
||||||
|
|
||||||
## Dropped
|
## Dropped
|
||||||
- Debug mode
|
- Debug mode
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ class ConnectionManager:
|
|||||||
self.controller.add_to_history(self.history, self.record)
|
self.controller.add_to_history(self.history, self.record)
|
||||||
self.controller.open_page(NotebookPage.SERVERS)
|
self.controller.open_page(NotebookPage.SERVERS)
|
||||||
|
|
||||||
def _update_mods(self, raise_window: bool, menu_only: bool = False) -> None:
|
def _update_mods(self, menu_only: bool = False) -> None:
|
||||||
prefs = self.controller.get_prefs()
|
prefs = self.controller.get_prefs()
|
||||||
config_man = self.controller.get_config_man()
|
config_man = self.controller.get_config_man()
|
||||||
key = config_man.lookup(Preferences.STEAM)
|
key = config_man.lookup(Preferences.STEAM)
|
||||||
@@ -305,10 +305,6 @@ class ConnectionManager:
|
|||||||
subscribe(key, int(mod))
|
subscribe(key, int(mod))
|
||||||
time.sleep(RATE_LIMIT_THRESHOLD)
|
time.sleep(RATE_LIMIT_THRESHOLD)
|
||||||
|
|
||||||
if raise_window is True:
|
|
||||||
logger.info("Bringing window to foreground")
|
|
||||||
GLib.idle_add(self.controller.present_window)
|
|
||||||
|
|
||||||
for title, mod, stamp, size in self.missing_mods:
|
for title, mod, stamp, size in self.missing_mods:
|
||||||
mod_path = self.workshop / mod
|
mod_path = self.workshop / mod
|
||||||
|
|
||||||
@@ -331,8 +327,8 @@ class ConnectionManager:
|
|||||||
self._connect_steam(menu_only)
|
self._connect_steam(menu_only)
|
||||||
|
|
||||||
@call_on_thread(waiting_for_mods, show_cancel=True)
|
@call_on_thread(waiting_for_mods, show_cancel=True)
|
||||||
def update_and_connect(self, raise_window: bool, menu_only: bool = False) -> None:
|
def update_and_connect(self, menu_only: bool = False) -> None:
|
||||||
if len(self.missing_mods) > 0:
|
if len(self.missing_mods) > 0:
|
||||||
self._update_mods(raise_window, menu_only)
|
self._update_mods(menu_only)
|
||||||
else:
|
else:
|
||||||
self._connect_steam(menu_only)
|
self._connect_steam(menu_only)
|
||||||
@@ -34,10 +34,18 @@ class OfflineManager:
|
|||||||
self.thread_man = ThreadingManager(controller)
|
self.thread_man = ThreadingManager(controller)
|
||||||
|
|
||||||
self.appid: int
|
self.appid: int
|
||||||
self.mission_folder: str
|
|
||||||
self.local_mods: list[str] | None
|
self.local_mods: list[str] | None
|
||||||
self.custom_mods: list[str] | None
|
self.custom_mods: list[str] | None
|
||||||
|
|
||||||
|
# TODO: more robust test
|
||||||
|
def is_custom_folder_valid(self, folder: str) -> bool:
|
||||||
|
return Path(folder).exists()
|
||||||
|
|
||||||
|
# TODO: set properties as members of offline manager on demand and check them here
|
||||||
|
# rather than passing strings again
|
||||||
|
def is_mission_valid(self, folder: str) -> bool:
|
||||||
|
return is_mission(Path(folder))
|
||||||
|
|
||||||
def get_mission(self) -> None:
|
def get_mission(self) -> None:
|
||||||
folder = self.open_folderpicker(dialogs.mission_dialog)
|
folder = self.open_folderpicker(dialogs.mission_dialog)
|
||||||
if folder is None:
|
if folder is None:
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ local_frame = "Installed mods"
|
|||||||
no_local_mods = "No local mods found"
|
no_local_mods = "No local mods found"
|
||||||
no_mods = "No valid mods found"
|
no_mods = "No valid mods found"
|
||||||
no_mission = "Not a valid mission"
|
no_mission = "Not a valid mission"
|
||||||
|
folder_changed = "Folder missing or changed on disk"
|
||||||
|
|
||||||
custom_eventbox = "Set the root folder. Mods must be in atomic folders and have a meta.cpp file at a minimum."
|
custom_eventbox = "Set the root folder. Mods must be in atomic folders and have a meta.cpp file at a minimum."
|
||||||
mission_eventbox = "Select a single mission folder containing an init.c file."
|
mission_eventbox = "Select a single mission folder containing an init.c file."
|
||||||
|
|||||||
@@ -367,6 +367,7 @@ thanks = Thanks(
|
|||||||
"Johnofwrong",
|
"Johnofwrong",
|
||||||
"MatheusLasserr",
|
"MatheusLasserr",
|
||||||
"nolan-perez",
|
"nolan-perez",
|
||||||
|
"OnniSaarni",
|
||||||
"scandalouss",
|
"scandalouss",
|
||||||
"SnackSBR",
|
"SnackSBR",
|
||||||
"StevelDusa",
|
"StevelDusa",
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
from typing import Sequence
|
||||||
|
|
||||||
|
import gi
|
||||||
|
|
||||||
|
gi.require_version("Gtk", "3.0")
|
||||||
|
from gi.repository import Gtk # noqa
|
||||||
|
|
||||||
|
|
||||||
|
class GenericBox(Gtk.Box):
|
||||||
|
def __init__(self, orientation: Gtk.Orientation, spacing: int = 0) -> None:
|
||||||
|
super().__init__(orientation=orientation, spacing=spacing)
|
||||||
|
|
||||||
|
def extend(self, els: Sequence[Gtk.Widget]) -> None:
|
||||||
|
for el in els:
|
||||||
|
self.add(el)
|
||||||
|
|
||||||
|
|
||||||
|
class HBox(GenericBox):
|
||||||
|
def __init__(self, spacing: int = 0) -> None:
|
||||||
|
super().__init__(orientation=Gtk.Orientation.HORIZONTAL, spacing=spacing)
|
||||||
|
|
||||||
|
|
||||||
|
class VBox(GenericBox):
|
||||||
|
def __init__(self, spacing: int = 0) -> None:
|
||||||
|
super().__init__(orientation=Gtk.Orientation.VERTICAL, spacing=spacing)
|
||||||
@@ -208,6 +208,8 @@ class SteamWorkshopButton(SteamTextButton):
|
|||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__(label=buttons.workshop)
|
super().__init__(label=buttons.workshop)
|
||||||
self.set_tooltip_text(buttons.workshop_tooltip)
|
self.set_tooltip_text(buttons.workshop_tooltip)
|
||||||
|
self.set_margin_top(10)
|
||||||
|
self.set_margin_bottom(10)
|
||||||
|
|
||||||
|
|
||||||
class AddButton(IconTextButton):
|
class AddButton(IconTextButton):
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from pathlib import Path
|
|||||||
from typing import Self, TYPE_CHECKING
|
from typing import Self, TYPE_CHECKING
|
||||||
from dzgui.api.steam import find_user_id
|
from dzgui.api.steam import find_user_id
|
||||||
from dzgui.const.enum import NotebookPage, Preferences
|
from dzgui.const.enum import NotebookPage, Preferences
|
||||||
|
from dzgui.views.components.box import HBox
|
||||||
from dzgui.views.components.buttons import SteamWorkshopButton
|
from dzgui.views.components.buttons import SteamWorkshopButton
|
||||||
from dzgui.views.components.scrollable import NoOverlayScrolledWindow
|
from dzgui.views.components.scrollable import NoOverlayScrolledWindow
|
||||||
from dzgui.views.trees.tree_mods import ModTreeView
|
from dzgui.views.trees.tree_mods import ModTreeView
|
||||||
@@ -36,10 +37,8 @@ class Mods(Gtk.Box):
|
|||||||
uid = find_user_id(steam_path)
|
uid = find_user_id(steam_path)
|
||||||
|
|
||||||
pretty_uid = "" if uid is None else uid
|
pretty_uid = "" if uid is None else uid
|
||||||
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
|
hbox = HBox(spacing=10)
|
||||||
workshop_button = SteamWorkshopButton()
|
workshop_button = SteamWorkshopButton()
|
||||||
workshop_button.set_margin_top(10)
|
|
||||||
workshop_button.set_margin_bottom(10)
|
|
||||||
workshop_button.connect(
|
workshop_button.connect(
|
||||||
"clicked", lambda _: self.controller.open_user_workshop(pretty_uid)
|
"clicked", lambda _: self.controller.open_user_workshop(pretty_uid)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Self, Sequence, TYPE_CHECKING, Union
|
from typing import Self, TYPE_CHECKING, Union
|
||||||
|
|
||||||
from dzgui.util import css
|
from dzgui.util import css
|
||||||
from dzgui.const.constants import (
|
from dzgui.const.constants import (
|
||||||
@@ -16,6 +16,7 @@ from dzgui.const.constants import (
|
|||||||
from dzgui.const.enum import ContextMenuGroup, NotebookPage
|
from dzgui.const.enum import ContextMenuGroup, NotebookPage
|
||||||
from dzgui.managers.offline import OfflineManager
|
from dzgui.managers.offline import OfflineManager
|
||||||
from dzgui.strings import generic, offline
|
from dzgui.strings import generic, offline
|
||||||
|
from dzgui.views.components.box import HBox, VBox
|
||||||
from dzgui.views.components.buttons import Icon, IconTextButton
|
from dzgui.views.components.buttons import Icon, IconTextButton
|
||||||
from dzgui.views.components.eventbox import InfoEventBox
|
from dzgui.views.components.eventbox import InfoEventBox
|
||||||
from dzgui.views.components.frame import HeadingFrame
|
from dzgui.views.components.frame import HeadingFrame
|
||||||
@@ -37,25 +38,7 @@ if TYPE_CHECKING:
|
|||||||
class FolderError(Enum):
|
class FolderError(Enum):
|
||||||
NO_VALID_MODS = 1
|
NO_VALID_MODS = 1
|
||||||
NO_VALID_MISSION = 2
|
NO_VALID_MISSION = 2
|
||||||
|
FOLDER_CHANGED = 3
|
||||||
|
|
||||||
class GenericBox(Gtk.Box):
|
|
||||||
def __init__(self, orientation: Gtk.Orientation, spacing: int = 0) -> None:
|
|
||||||
super().__init__(orientation=orientation, spacing=spacing)
|
|
||||||
|
|
||||||
def extend(self, els: Sequence[Gtk.Widget]) -> None:
|
|
||||||
for el in els:
|
|
||||||
self.add(el)
|
|
||||||
|
|
||||||
|
|
||||||
class HBox(GenericBox):
|
|
||||||
def __init__(self, spacing: int = 0) -> None:
|
|
||||||
super().__init__(orientation=Gtk.Orientation.HORIZONTAL, spacing=spacing)
|
|
||||||
|
|
||||||
|
|
||||||
class VBox(GenericBox):
|
|
||||||
def __init__(self, spacing: int = 0) -> None:
|
|
||||||
super().__init__(orientation=Gtk.Orientation.VERTICAL, spacing=spacing)
|
|
||||||
|
|
||||||
|
|
||||||
class PageHeading(Gtk.Label):
|
class PageHeading(Gtk.Label):
|
||||||
@@ -83,6 +66,10 @@ class ErrorPopover(Gtk.Popover):
|
|||||||
prefix = offline.no_mods
|
prefix = offline.no_mods
|
||||||
case FolderError.NO_VALID_MISSION:
|
case FolderError.NO_VALID_MISSION:
|
||||||
prefix = offline.no_mission
|
prefix = offline.no_mission
|
||||||
|
case FolderError.FOLDER_CHANGED:
|
||||||
|
prefix = offline.folder_changed
|
||||||
|
self.label.set_label(prefix)
|
||||||
|
return
|
||||||
self.label.set_label(f"{prefix}: '{msg}'")
|
self.label.set_label(f"{prefix}: '{msg}'")
|
||||||
|
|
||||||
|
|
||||||
@@ -123,6 +110,11 @@ class FolderHBox(HBox):
|
|||||||
self.pop.set_relative_to(self.button)
|
self.pop.set_relative_to(self.button)
|
||||||
self.pop.connect("unmap", lambda _: self.grab_focus())
|
self.pop.connect("unmap", lambda _: self.grab_focus())
|
||||||
|
|
||||||
|
self.sidepop = ErrorPopover()
|
||||||
|
self.sidepop.set_position(Gtk.PositionType.BOTTOM)
|
||||||
|
self.sidepop.set_relative_to(self.scrolled_label)
|
||||||
|
self.sidepop.connect("unmap", lambda _: self.grab_focus())
|
||||||
|
|
||||||
self.connect("map", self._on_map)
|
self.connect("map", self._on_map)
|
||||||
self.connect("unmap", self._on_unmap)
|
self.connect("unmap", self._on_unmap)
|
||||||
|
|
||||||
@@ -168,6 +160,10 @@ class FolderHBox(HBox):
|
|||||||
self.unset_button.show()
|
self.unset_button.show()
|
||||||
|
|
||||||
def present_error(self, error: FolderError, msg: str) -> None:
|
def present_error(self, error: FolderError, msg: str) -> None:
|
||||||
|
if error == FolderError.FOLDER_CHANGED:
|
||||||
|
self.sidepop.set_label(error, msg)
|
||||||
|
self.sidepop.popup()
|
||||||
|
return
|
||||||
self.folder = ""
|
self.folder = ""
|
||||||
self.label.set_text("")
|
self.label.set_text("")
|
||||||
self.unset_button.hide()
|
self.unset_button.hide()
|
||||||
@@ -318,6 +314,9 @@ class CustomModFrame(ModFrame):
|
|||||||
self.tree_vbox.hide()
|
self.tree_vbox.hide()
|
||||||
self.no_mods.hide()
|
self.no_mods.hide()
|
||||||
|
|
||||||
|
def present_folder_changed(self, folder: str) -> None:
|
||||||
|
self.custom_hbox.present_error(FolderError.FOLDER_CHANGED, folder)
|
||||||
|
|
||||||
def present_error(self, folder: str) -> None:
|
def present_error(self, folder: str) -> None:
|
||||||
self.hide_tree()
|
self.hide_tree()
|
||||||
self.custom_hbox.present_error(FolderError.NO_VALID_MODS, folder)
|
self.custom_hbox.present_error(FolderError.NO_VALID_MODS, folder)
|
||||||
@@ -381,6 +380,9 @@ class MissionFrame(HeadingFrame):
|
|||||||
def get_mission(self) -> str:
|
def get_mission(self) -> str:
|
||||||
return self.mission_hbox.get_folder()
|
return self.mission_hbox.get_folder()
|
||||||
|
|
||||||
|
def present_folder_changed(self, folder: str) -> None:
|
||||||
|
self.mission_hbox.present_error(FolderError.FOLDER_CHANGED, folder)
|
||||||
|
|
||||||
|
|
||||||
class RadioFrame(HeadingFrame):
|
class RadioFrame(HeadingFrame):
|
||||||
def __init__(self, parent: OfflineLoader, controller: "Controller") -> None:
|
def __init__(self, parent: OfflineLoader, controller: "Controller") -> None:
|
||||||
@@ -500,4 +502,12 @@ class OfflineLoader(Gtk.Box):
|
|||||||
local_mods = self.local_frame.get_mods()
|
local_mods = self.local_frame.get_mods()
|
||||||
custom_folder = self.custom_frame.get_folder()
|
custom_folder = self.custom_frame.get_folder()
|
||||||
custom_mods = self.custom_frame.get_mods()
|
custom_mods = self.custom_frame.get_mods()
|
||||||
|
|
||||||
|
if custom_folder and not self.offline_man.is_custom_folder_valid(custom_folder):
|
||||||
|
self.custom_frame.present_folder_changed(mission)
|
||||||
|
return
|
||||||
|
|
||||||
|
if mission and not self.offline_man.is_mission_valid(mission):
|
||||||
|
self.mission_frame.present_folder_changed(mission)
|
||||||
|
return
|
||||||
self.offline_man.launch(appid, mission, local_mods, custom_folder, custom_mods)
|
self.offline_man.launch(appid, mission, local_mods, custom_folder, custom_mods)
|
||||||
@@ -112,18 +112,6 @@ class PreConnectionAssistant(Gtk.Box):
|
|||||||
tooltip_text=preconnect.connect_last_tooltip,
|
tooltip_text=preconnect.connect_last_tooltip,
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: abstract
|
|
||||||
self.raise_window = Gtk.CheckButton(
|
|
||||||
label="Foreground DZGUI while downloading",
|
|
||||||
halign=Gtk.Align.END,
|
|
||||||
hexpand=True,
|
|
||||||
valign=Gtk.Align.END,
|
|
||||||
visible=False,
|
|
||||||
has_tooltip=True,
|
|
||||||
sensitive=False,
|
|
||||||
tooltip_text="Foreground the DZGUI window after mod downloads are queued",
|
|
||||||
active=True,
|
|
||||||
)
|
|
||||||
self.button_box = Gtk.Box(
|
self.button_box = Gtk.Box(
|
||||||
orientation=Gtk.Orientation.VERTICAL,
|
orientation=Gtk.Orientation.VERTICAL,
|
||||||
valign=Gtk.Align.END,
|
valign=Gtk.Align.END,
|
||||||
@@ -133,8 +121,7 @@ class PreConnectionAssistant(Gtk.Box):
|
|||||||
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
|
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
|
||||||
for button in self.back, self.ok, self.connect_last:
|
for button in self.back, self.ok, self.connect_last:
|
||||||
box.add(button)
|
box.add(button)
|
||||||
for el in self.raise_window, box:
|
self.button_box.add(box)
|
||||||
self.button_box.add(el)
|
|
||||||
|
|
||||||
self.back.connect("clicked", self._on_back_clicked)
|
self.back.connect("clicked", self._on_back_clicked)
|
||||||
self.ok.connect("clicked", self._on_ok_clicked)
|
self.ok.connect("clicked", self._on_ok_clicked)
|
||||||
@@ -217,8 +204,6 @@ class PreConnectionAssistant(Gtk.Box):
|
|||||||
for child in widgets:
|
for child in widgets:
|
||||||
child.set_visible(True)
|
child.set_visible(True)
|
||||||
|
|
||||||
self.raise_window.set_visible(False)
|
|
||||||
self.raise_window.set_sensitive(False)
|
|
||||||
self.ok.set_sensitive(True)
|
self.ok.set_sensitive(True)
|
||||||
self.ok.set_label(preconnect.update_mods)
|
self.ok.set_label(preconnect.update_mods)
|
||||||
|
|
||||||
@@ -230,10 +215,10 @@ class PreConnectionAssistant(Gtk.Box):
|
|||||||
self.ok.emit("clicked")
|
self.ok.emit("clicked")
|
||||||
|
|
||||||
def _on_connect_last_clicked(self, button: Gtk.Button) -> None:
|
def _on_connect_last_clicked(self, button: Gtk.Button) -> None:
|
||||||
self.controller.update_and_load_to_menu(self.raise_window.get_active())
|
self.controller.update_and_load_to_menu()
|
||||||
|
|
||||||
def _on_ok_clicked(self, button: Gtk.Button) -> None:
|
def _on_ok_clicked(self, button: Gtk.Button) -> None:
|
||||||
self.controller.update_and_connect(self.raise_window.get_active())
|
self.controller.update_and_connect()
|
||||||
|
|
||||||
def _on_back_clicked(self, button: Gtk.Button) -> None:
|
def _on_back_clicked(self, button: Gtk.Button) -> None:
|
||||||
self.controller.open_page(NotebookPage.SERVERS)
|
self.controller.open_page(NotebookPage.SERVERS)
|
||||||
@@ -317,10 +302,6 @@ class PreConnectionAssistant(Gtk.Box):
|
|||||||
|
|
||||||
if prereqs.required_space == 0:
|
if prereqs.required_space == 0:
|
||||||
self.ok.set_label(preconnect.connect)
|
self.ok.set_label(preconnect.connect)
|
||||||
self.raise_window.set_visible(False)
|
|
||||||
else:
|
|
||||||
self.raise_window.set_visible(True)
|
|
||||||
self.raise_window.set_sensitive(True)
|
|
||||||
|
|
||||||
pretty = number(prereqs.required_space)
|
pretty = number(prereqs.required_space)
|
||||||
suffix = f" Need to download {pretty} MiB of mod updates."
|
suffix = f" Need to download {pretty} MiB of mod updates."
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ description = "DayZ server browser and mod manager for Linux"
|
|||||||
authors = [
|
authors = [
|
||||||
{name = "aclist"}
|
{name = "aclist"}
|
||||||
]
|
]
|
||||||
version = "7.0.0b11"
|
version = "7.0.0b12"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
license-files = ["LICENSE"]
|
license-files = ["LICENSE"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|||||||
Reference in new issue
Block a user