diff --git a/dzgui/api/mods.py b/dzgui/api/mods.py index f8a9814..722e3dc 100644 --- a/dzgui/api/mods.py +++ b/dzgui/api/mods.py @@ -24,14 +24,6 @@ from typing import Any logger = logging.getLogger(APP_NAME) -@dataclass -class ModMeta: - protocol: str - published_id: str - name: str - timestamp: str - - def get_local_mod_ids(steam_path: Path) -> list[int]: workshop_path = get_local_mod_path(steam_path) mods = get_local_mods(workshop_path) diff --git a/dzgui/app_init.py b/dzgui/app_init.py index 1a942ab..4903b20 100644 --- a/dzgui/app_init.py +++ b/dzgui/app_init.py @@ -22,7 +22,6 @@ from dzgui.init.migrate import ( copy_state_files, migrate_cols_file, ) -from dzgui.init.flock import lock_acquire from dzgui.init.prereqs import has_flatpak_client, has_steam_client from dzgui.strings import boot @@ -122,8 +121,6 @@ def load_steam_icon() -> None: def build_gui(version: str, is_debug: bool) -> App | None: - lock = lock_acquire() # noqa - set_locale() # NOTE: consider aborting this check if steam deck xdg_paths = get_xdg_paths() @@ -158,9 +155,6 @@ def build_gui(version: str, is_debug: bool) -> App | None: f.truncate(0) if _is_steam_deck is False: - # TODO: sudo escalation dialog - # count = get_map_count() - # TODO: move into module if FLATPAK_ROOT_PATH in lookup(XDG.config, Preferences.DEFAULT): has_client = has_flatpak_client() else: diff --git a/dzgui/main.py b/dzgui/main.py index 5e660cf..a32d021 100644 --- a/dzgui/main.py +++ b/dzgui/main.py @@ -43,6 +43,9 @@ def main() -> None: # NOTE: only import ligbirepository modules after the above check from dzgui.app_init import build_gui + from dzgui.init.flock import lock_acquire + + lock = lock_acquire() # noqa app = build_gui(version, args.debug) if app is None: diff --git a/dzgui/managers/connection.py b/dzgui/managers/connection.py index c246d31..a57a421 100644 --- a/dzgui/managers/connection.py +++ b/dzgui/managers/connection.py @@ -48,7 +48,7 @@ from dzgui.strings.dialogs import ( waiting_for_directories, ) from dzgui.strings import kb -from dzgui.strings.server_mods import checkmark, resync +from dzgui.strings.server_mods import checkmark, resync, invalid_mod from dzgui.util.format import format_exception, format_mib from dzgui.util.strings import dialog, server_timeout from dzgui.util.symlink import rebuild_symlinks @@ -192,9 +192,8 @@ class ConnectionManager: is_last = self.is_last_server() - # TODO: strings invalid_mods = [ - (mod[0], mod[1]) for mod in remote_mods if mod[2] == "Invalid mod" + (mod[0], mod[1]) for mod in remote_mods if mod[2] == invalid_mod ] prereqs = Prerequisites( @@ -272,8 +271,7 @@ class ConnectionManager: for mod in alpha_mods: # NOTE: if the mod is neither synched or out of date, it is a malformed mod if mod[2] == "": - # TODO: strings - mod[2] = "Invalid mod" + mod[2] = invalid_mod return alpha_mods, missing_mods diff --git a/dzgui/managers/filter.py b/dzgui/managers/filter.py index 357318f..5204d35 100644 --- a/dzgui/managers/filter.py +++ b/dzgui/managers/filter.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING from dzgui.model.model_factory import ModelFactory from dzgui.util import strings -from dzgui.util.strings import all_maps +from dzgui.strings.filters import all_maps if TYPE_CHECKING: from dzgui.model.model_factory import FastInsertListStore @@ -105,17 +105,11 @@ class FilterManager: self.reinit_map_store() maps.sort() - for m in maps: - # TODO: strings - if m == "All maps": - continue + clean = [m for m in maps if m != all_maps] + for m in clean: self.append_map([m]) - # TODO: currently unused - 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() diff --git a/dzgui/model/proxy_model.py b/dzgui/model/proxy_model.py index 023da66..5cb3d97 100644 --- a/dzgui/model/proxy_model.py +++ b/dzgui/model/proxy_model.py @@ -6,6 +6,7 @@ from typing import Any, TYPE_CHECKING, Union from dzgui.const.enum import FilterMode from dzgui.model.model_factory import ModelFactory from dzgui.util import strings +from dzgui.strings import filters as str_filters if TYPE_CHECKING: from dzgui.managers.filter import FilterManager @@ -188,7 +189,7 @@ class ProxyModelManager: rows = self.filtered sel_map = self.filter_man.get_active_map_name() - if sel_map == strings.all_maps: + if sel_map == str_filters.all_maps: return rows rows = [row for row in rows if row[1] == sel_map] diff --git a/dzgui/strings/buttons.py b/dzgui/strings/buttons.py index faa00a0..539b7a0 100644 --- a/dzgui/strings/buttons.py +++ b/dzgui/strings/buttons.py @@ -1,2 +1,16 @@ +clipboard_button = "Copy to clipboard" +clipboard_ip_button = "Copy IP to clipboard" + +dock_button_collapse = "Collapse the connection panel" +dock_button_expand = "Expand the connection panel" + workshop = "Steam Workshop" workshop_tooltip = "Open your Workshop subscriptions" + +version_notifier = "Copied!" +version_tooltip = "Click to copy to clipboard" + +update_button = "Updates available" + +unset_button_label = "Unset" +unset_button_tooltip = "Unset this server as favorite" diff --git a/dzgui/strings/dialogs.py b/dzgui/strings/dialogs.py index b895ba0..b31f58a 100644 --- a/dzgui/strings/dialogs.py +++ b/dzgui/strings/dialogs.py @@ -29,3 +29,5 @@ toggle_calc = "Toggle calculator" server_details = "Server details" server_message = "Server message" + +caught_cancel_signal = "Caught cancel signal, cleaning up" diff --git a/dzgui/strings/filters.py b/dzgui/strings/filters.py new file mode 100644 index 0000000..b6e6bc6 --- /dev/null +++ b/dzgui/strings/filters.py @@ -0,0 +1,4 @@ +all_maps = "All maps" +filters_heading = "Filters" +keyword_placeholder = "Filter by keyword" +map_placeholder = "Filter by map" diff --git a/dzgui/strings/generic.py b/dzgui/strings/generic.py index 1aff78a..68b9cd9 100644 --- a/dzgui/strings/generic.py +++ b/dzgui/strings/generic.py @@ -1 +1,2 @@ +tab_changed_label = "*" selectable_tree = "Ctrl-click to select multiple; Shift-click to select a range." diff --git a/dzgui/strings/notes.py b/dzgui/strings/notes.py new file mode 100644 index 0000000..77d53da --- /dev/null +++ b/dzgui/strings/notes.py @@ -0,0 +1,5 @@ +dialog_title = "Add a short note/reminder" +dialog_subtitle = "Limit 30 chars" +delete_button = "Delete note" +ok_button = "Update note" +current_note = "Current note: '{0}'" diff --git a/dzgui/strings/options.py b/dzgui/strings/options.py index a105f07..fd505f2 100644 --- a/dzgui/strings/options.py +++ b/dzgui/strings/options.py @@ -16,7 +16,9 @@ lan_combo = "LAN" fullscreen_eventbox = "This option is not available on Steam Deck." save_button = "Save" +api_placeholder = "Enter API key" api_failed = "API validation failed" +api_validate = "Validate" flatpak_label = "Flatpak client" flatpak_standard = "Standard" diff --git a/dzgui/strings/server_mods.py b/dzgui/strings/server_mods.py index c41b443..d5a2e42 100644 --- a/dzgui/strings/server_mods.py +++ b/dzgui/strings/server_mods.py @@ -3,4 +3,5 @@ mod_id = "ID" up_to_date = "Up to date" modlist = "Modlist" checkmark = "✓" -resync="⟳" +resync = "⟳" +invalid_mod = "Invalid mod" diff --git a/dzgui/util/strings.py b/dzgui/util/strings.py index 931ca88..095d49a 100644 --- a/dzgui/util/strings.py +++ b/dzgui/util/strings.py @@ -159,9 +159,6 @@ filter_unofficial = "Unofficial" filter_modded = "Modded" filter_unmodded = "Unmodded" -# maps -all_maps = "All maps" - # state unknown = "Unknown" none_provided = "None provided" diff --git a/dzgui/views/components/buttons.py b/dzgui/views/components/buttons.py index 0120462..33165cc 100644 --- a/dzgui/views/components/buttons.py +++ b/dzgui/views/components/buttons.py @@ -104,8 +104,7 @@ class ClipboardButton(IconTextButton): self.controller = controller self.connect("clicked", self._on_button_clicked, func) - # TODO: strings - self.set_tooltip_text("Copy to clipboard") + self.set_tooltip_text(buttons.clipboard_button) def _on_button_clicked(self, button: Self, func: Callable[[], str]) -> None: def revert() -> Literal[False]: @@ -122,16 +121,14 @@ class CopyIpButton(ClipboardButton): def __init__(self, func: Callable[[], str]) -> None: super().__init__(func) - # TODO: strings - self.set_tooltip_text("Copy IP to clipboard") + self.set_tooltip_text(buttons.clipboard_ip_button) class CloseButton(IconTextButton): def __init__(self, label: str) -> None: super().__init__(icon=ICON_CLOSE, label=label) - # TODO: strings - self.set_tooltip_text("Unset this server as favorite") + self.set_tooltip_text(buttons.unset_button_tooltip) class WebButton(IconTextButton): diff --git a/dzgui/views/components/connect_panel.py b/dzgui/views/components/connect_panel.py index 28d9724..7ea9a34 100644 --- a/dzgui/views/components/connect_panel.py +++ b/dzgui/views/components/connect_panel.py @@ -4,6 +4,11 @@ from dzgui.const.icons import ICON_CARET_DOWN, ICON_CARET_UP from dzgui.const.constants import UDP_PORT from dzgui.model.servers import ServerModelManager from dzgui.strings import connect_panel +from dzgui.strings.buttons import ( + dock_button_collapse, + dock_button_expand, + unset_button_label, +) from dzgui.util.keys import is_ctrl_mask from dzgui.views.components.buttons import ( AddButton, @@ -37,21 +42,18 @@ class DockButton(IconButton): self.child = child self.connect("clicked", self._on_click) - self.collapse_text = "Collapse the connection panel" - self.expand_text = "Expand the connection panel" - self.set_margin_top(10) - self.set_tooltip_text(self.collapse_text) + self.set_tooltip_text(dock_button_collapse) def collapse(self) -> None: self.set_image(Icon(ICON_CARET_UP)) self.child.hide() - self.set_tooltip_text(self.expand_text) + self.set_tooltip_text(dock_button_expand) def expand(self) -> None: self.set_image(Icon(ICON_CARET_DOWN)) self.child.show() - self.set_tooltip_text(self.collapse_text) + self.set_tooltip_text(dock_button_collapse) def _on_click(self, button: Self) -> None: if self.expanded: @@ -82,7 +84,6 @@ class LanPanel(Gtk.Frame): self.scan = Gtk.Button(label=connect_panel.lan_scan_button) self.scan.connect("clicked", self._on_scan_clicked) - # TODO: strings self.early_abort = Gtk.CheckButton(label=connect_panel.lan_checkbox) self.early_abort.set_active(True) self.early_abort.set_tooltip_text(connect_panel.lan_abort_tooltip) @@ -190,8 +191,7 @@ class FavPanel(Gtk.Frame): self.fav_button.connect("clicked", self._on_connect_clicked) self.copy_button = CopyIpButton(self.get_fav_ip) - # TODO: strings - self.unset_button = CloseButton("Unset") + self.unset_button = CloseButton(unset_button_label) self.unset_button.connect("clicked", self._on_unset_clicked) if favorite is None: diff --git a/dzgui/views/components/entry.py b/dzgui/views/components/entry.py index adc3ea0..db3fb94 100644 --- a/dzgui/views/components/entry.py +++ b/dzgui/views/components/entry.py @@ -4,6 +4,7 @@ from dzgui.api.servers import validate_ip from dzgui.const.icons import ICON_VIEW_CONCEAL, ICON_VIEW_REVEAL from dzgui.util.css import add_class, remove_class from dzgui.strings import connect_panel +from dzgui.strings.options import api_placeholder, api_validate from dzgui.strings.errors import api_popover import gi @@ -142,9 +143,8 @@ class APIEntry(Gtk.Box): self.func: Callable[[str], None] | None = None - # TODO: strings self.entry = Gtk.Entry( - width_chars=60, hexpand=True, placeholder_text="Enter API key" + width_chars=60, hexpand=True, placeholder_text=api_placeholder ) self.entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, ICON_VIEW_REVEAL) self.entry.set_icon_activatable(Gtk.EntryIconPosition.SECONDARY, True) @@ -153,8 +153,7 @@ class APIEntry(Gtk.Box): self.entry.connect("icon-release", self._on_icon_release) self.entry.connect("activate", self._on_field_activated) - # TODO: strings - self.submit = Gtk.Button(label="Validate") + self.submit = Gtk.Button(label=api_validate) self.submit.set_sensitive(False) self.submit.connect("clicked", self._on_submit) diff --git a/dzgui/views/components/filter_panel.py b/dzgui/views/components/filter_panel.py index 0fe8aa8..b3bc584 100644 --- a/dzgui/views/components/filter_panel.py +++ b/dzgui/views/components/filter_panel.py @@ -6,7 +6,12 @@ from dzgui.const.constants import ( ) from dzgui.const.icons import ICON_SEARCH from dzgui.util.format import format_exception -from dzgui.util.strings import all_maps +from dzgui.strings.filters import ( + all_maps, + filters_heading, + keyword_placeholder, + map_placeholder, +) from dzgui.views.components.maps_combo import MapsCombo from dzgui.views.components.labels import BoldLabel @@ -98,8 +103,7 @@ class ButtonGrid(Gtk.Grid): class KeywordEntry(Gtk.Entry): def __init__(self, controller: "Controller") -> None: - # TODO :strings - super().__init__(placeholder_text="Filter by keyword") + super().__init__(placeholder_text=keyword_placeholder) self.keyword = "" self.controller = controller @@ -173,8 +177,7 @@ class FilterPanel(Gtk.Box): self.keyword_entry = KeywordEntry(self.controller) self.button_grid = ButtonGrid(self.controller, defaults, tooltips) - # TODO: strings - self.filters_label = BoldLabel("Filters") + self.filters_label = BoldLabel(filters_heading) self.emitter.connect( "request_keyword_focus", lambda _: self.keyword_entry.grab_focus() @@ -194,8 +197,7 @@ class FilterPanel(Gtk.Box): self.maps_entry: Gtk.Entry = self.maps_combo.get_child() # type: ignore self.maps_entry.set_completion(completion) - # TODO: strings - self.maps_entry.set_placeholder_text("Filter by map") + self.maps_entry.set_placeholder_text(map_placeholder) self.maps_entry.connect("changed", self._on_map_completion, True) self.maps_entry.connect("key-press-event", self._on_map_entry_keypress) self.maps_entry.connect("activate", self._on_maps_activated) diff --git a/dzgui/views/components/right_panel.py b/dzgui/views/components/right_panel.py index d91bd7c..c04bba7 100644 --- a/dzgui/views/components/right_panel.py +++ b/dzgui/views/components/right_panel.py @@ -9,6 +9,7 @@ from dzgui.const.constants import ( ) from dzgui.const.enum import ServerTab from dzgui.managers.update import UpdateManager +from dzgui.strings.buttons import update_button, version_notifier, version_tooltip from dzgui.util.clip import copy_clipboard from dzgui.util.file import is_writeable from dzgui.views.components.buttonbox import ButtonBox @@ -61,8 +62,7 @@ class RightPanel(Gtk.Box): vexpand=True, halign=Gtk.Align.END, valign=Gtk.Align.END, - # TODO: strings - tooltip_text="Click to copy to clipboard", + tooltip_text=version_tooltip, ) eb = Gtk.EventBox(halign=Gtk.Align.END, valign=Gtk.Align.END) eb.add(self.version_label) @@ -74,7 +74,7 @@ class RightPanel(Gtk.Box): self.pack_start(self.sel_panel, expand=False, fill=False, padding=0) self.update_button = IconTextButton( - "dialog-information-symbolic", label="Updates available" + "dialog-information-symbolic", label=update_button ) self.gutter_box = Gtk.Box( @@ -127,7 +127,6 @@ class RightPanel(Gtk.Box): return self.copying = True version = self.version_label.get_text() - # TODO: strings - self.version_label.set_text("Copied!") + self.version_label.set_text(version_notifier) copy_clipboard(version) GLib.timeout_add_seconds(1, revert) diff --git a/dzgui/views/dialogs/generic.py b/dzgui/views/dialogs/generic.py index cd04c9d..da46346 100644 --- a/dzgui/views/dialogs/generic.py +++ b/dzgui/views/dialogs/generic.py @@ -139,8 +139,7 @@ class WaitDialog(GenericDialog): self.cur_job += 1 def _on_cancel_clicked(self, button: Gtk.Button) -> None: - # TODO: strings - GLib.idle_add(self.update_text, "Caught cancel signal, cleaning up") + GLib.idle_add(self.update_text, dialogs.caught_cancel_signal) self.controller.set_cancel_event() def show_cancel(self, state: bool) -> None: diff --git a/dzgui/views/dialogs/note.py b/dzgui/views/dialogs/note.py index a1cf7fb..362f1d8 100644 --- a/dzgui/views/dialogs/note.py +++ b/dzgui/views/dialogs/note.py @@ -1,5 +1,6 @@ from typing import Self, TYPE_CHECKING +from dzgui.strings import notes from dzgui.views.components.entry import ValidatedEntry from dzgui.views.dialogs.generic import GenericDialog @@ -14,23 +15,20 @@ if TYPE_CHECKING: class NoteDialog(GenericDialog): def __init__(self, controller: "Controller"): - # TODO: add to strings - title = "Add a short note/reminder." - secondary = "Limit 30 chars" super().__init__( controller=controller, - text=title, + text=notes.dialog_title, buttons=Gtk.ButtonsType.NONE, mtype=Gtk.MessageType.INFO, - secondary=secondary, + secondary=notes.dialog_subtitle, ) self.controller = controller - delete_button = Gtk.Button(label="Delete note") + delete_button = Gtk.Button(label=notes.delete_button) delete_button.set_sensitive(False) self.add_action_widget(delete_button, Gtk.ResponseType.CANCEL) - self.ok = self.add_button("Update note", Gtk.ResponseType.OK) + self.ok = self.add_button(notes.ok_button, Gtk.ResponseType.OK) self.ok.grab_default() self.entry = ValidatedEntry(controller, self.validate) @@ -42,7 +40,7 @@ class NoteDialog(GenericDialog): self.entry.set_text(note) if len(note) > 0: delete_button.set_sensitive(True) - self.format_secondary_text(f"Current note: '{note}'") + self.format_secondary_text(notes.current_note.format(note)) elif len(note) == 0: self.ok.set_sensitive(False) @@ -55,9 +53,6 @@ class NoteDialog(GenericDialog): self.entry.connect("changed", self._on_text_changed) def _on_text_changed(self, entry: Gtk.Entry) -> None: - """ - Called in conjunction with signal callback in the parent class - """ if len(entry.get_text()) == 0: self.ok.set_sensitive(False) @@ -71,14 +66,11 @@ class NoteDialog(GenericDialog): def _on_response(self, dialog: Self, response: Gtk.ResponseType) -> None: match response: - case Gtk.ResponseType.DELETE_EVENT: - self.destroy() case Gtk.ResponseType.OK: note = self.entry.get_text() self.controller.add_note(note) - self.destroy() case Gtk.ResponseType.CANCEL: self.controller.delete_note() - self.destroy() - case Gtk.ResponseType.CANCEL | Gtk.ResponseType.CLOSE: - self.destroy() + case _: + pass + self.destroy() diff --git a/dzgui/views/pages/servers.py b/dzgui/views/pages/servers.py index 61e333b..92090ba 100644 --- a/dzgui/views/pages/servers.py +++ b/dzgui/views/pages/servers.py @@ -5,6 +5,7 @@ from typing import Self, TYPE_CHECKING from dzgui.const.constants import APP_NAME from dzgui.const.enum import ContextMenuGroup, ServerTab from dzgui.views.trees.tree_servers import ServerTreeView +from dzgui.strings.generic import tab_changed_label from dzgui.util.strings import server_labels import gi @@ -147,8 +148,7 @@ class ServerNotebook(Gtk.ScrolledWindow): label = self.notebook.get_tab_label_text(child) if label is not None: - # TODO: strings - text = label.strip("*") + text = label.strip(tab_changed_label) self.notebook.set_tab_label_text(child, text) tree = child.get_tree() diff --git a/tests/test_paused_downloads.py b/tests/test_paused_downloads.py index 86bbb70..1c45ca2 100644 --- a/tests/test_paused_downloads.py +++ b/tests/test_paused_downloads.py @@ -16,7 +16,7 @@ from dzgui.api.steam import is_dayz_downloading (["state_221100_1111"], False), ], ) -def test_dayz_patch_pending(monkeypatch, file_list, expect) -> None: +def test_dayz_patch_pending(monkeypatch, file_list: list[str], expect: bool) -> None: def mock_get_pending_downloads(steam_path: Path, appid: int) -> None: files = [Path(file) for file in file_list] return files