diff --git a/dzgui/const/constants.py b/dzgui/const/constants.py index ab43f3f..ed3f578 100644 --- a/dzgui/const/constants.py +++ b/dzgui/const/constants.py @@ -31,14 +31,15 @@ HEX_RED = "#FF0000" HEX_ORANGE = "#FFAC1C" CLIPBOARD = "edit-copy-symbolic" +HELP_BUBBLE = "help-about-symbolic" +INPUT_KEYBOARD = "input-keyboard-symbolic" LIST_ADD = "list-add-symbolic" +REFRESH_ICON = "view-refresh-symbolic" +SEARCH_ICON = "system-search-symbolic" STEAM_ICON = "steam_tray_mono" VIEW_CONCEAL = "view-conceal-symbolic" -SEARCH_ICON = "system-search-symbolic" VIEW_REVEAL = "view-reveal-symbolic" -INPUT_KEYBOARD = "input-keyboard-symbolic" -HELP_BUBBLE = "help-about-symbolic" -REFRESH_ICON = "view-refresh-symbolic" +WARNING = "dialog-warning-symbolic" WEB_BROWSER = "web-browser-symbolic" SEPARATOR = "SEPARATOR" diff --git a/dzgui/controllers/mc.py b/dzgui/controllers/mc.py index 8838770..13891dc 100644 --- a/dzgui/controllers/mc.py +++ b/dzgui/controllers/mc.py @@ -36,6 +36,7 @@ from dzgui.const.enum import ( from dzgui.config.query import lookup from dzgui.config.userprefs import UserPrefs from dzgui.controllers.emitter import Emitter +from dzgui.managers.log import LogManager from dzgui.managers.config import ConfigManager from dzgui.managers.connection import ConnectionManager from dzgui.managers.contextmenu import ContextMenuManager @@ -638,3 +639,11 @@ class Controller(GObject.GObject): def set_active_keyword(self, keyword: str) -> None: self.get_filter_man().set_active_keyword(keyword) + + def set_alerts(self, count: tuple[int]) -> None: + self.alerts = count + + def get_alerts(self) -> tuple[int]: + log_man = LogManager() + alerts = log_man.get_alerts(self.prefs.paths.debug) + return alerts diff --git a/dzgui/util/strings.py b/dzgui/util/strings.py index a4d5145..9f0ef25 100644 --- a/dzgui/util/strings.py +++ b/dzgui/util/strings.py @@ -613,3 +613,5 @@ steam_icon_missing = "Steam icon not found in IconTheme" missing_changelog = "Error: failed to read changelog" esc_to_return = "Press ESC to return" question_to_return = "Press ? to return" + +alert_button_tooltip = "Click to open debug log" diff --git a/dzgui/views/components/buttons.py b/dzgui/views/components/buttons.py index bc596b7..8a08e63 100644 --- a/dzgui/views/components/buttons.py +++ b/dzgui/views/components/buttons.py @@ -1,13 +1,15 @@ from typing import Callable, Literal, Self, TYPE_CHECKING from dzgui.util.clip import copy_clipboard -from dzgui.util.strings import atomic_buttons, connect_panel +from dzgui.util.format import pluralize +from dzgui.util.strings import alert_button_tooltip, atomic_buttons, connect_panel from dzgui.const.constants import ( CLIPBOARD, INPUT_KEYBOARD, LIST_ADD, REFRESH_ICON, STEAM_ICON, + WARNING, WEB_BROWSER, ) @@ -157,3 +159,26 @@ class AddButton(IconTextButton): def __init__(self) -> None: super().__init__(icon=LIST_ADD, label=connect_panel.add) 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) diff --git a/dzgui/views/components/statusbar.py b/dzgui/views/components/statusbar.py index 4e8f789..7b5682a 100644 --- a/dzgui/views/components/statusbar.py +++ b/dzgui/views/components/statusbar.py @@ -2,6 +2,7 @@ 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 @@ -32,13 +33,22 @@ class Statusbar(Gtk.Grid): self.attach(self.statusbar, 0, 0, 3, 1) self.attach_next_to(self.spinner, self.statusbar, Gtk.PositionType.RIGHT, 3, 1) + warnings, errors = self.controller.get_alerts() + + if warnings + errors > 0: + alert_button = LoggerAlertsButton(warnings, errors) + self.attach_next_to( + alert_button, self.spinner, Gtk.PositionType.RIGHT, 3, 1 + ) + alert_button.connect("clicked", self._on_alerts_clicked) + # TODO: pack version event box in right panel into hbox with update button # TODO: spawns a modal or just jumps right to install page - #from dzgui.views.components.buttons import IconTextButton - #b = IconTextButton("dialog-information-symbolic", label="Updates available") - #b.set_halign(Gtk.Align.END) - #b.set_hexpand(True) - #self.attach_next_to(b, self.spinner, Gtk.PositionType.RIGHT, 3, 1) + # from dzgui.views.components.buttons import IconTextButton + # b = IconTextButton("dialog-information-symbolic", label="Updates available") + # b.set_halign(Gtk.Align.END) + # b.set_hexpand(True) + # self.attach_next_to(b, self.spinner, Gtk.PositionType.RIGHT, 3, 1) self.players = "" @@ -52,6 +62,12 @@ class Statusbar(Gtk.Grid): self.emitter.connect("servers_loaded", self._on_servers_loaded) self.emitter.connect("mod_page_loaded", self._on_mod_page_loaded) + def _on_alerts_clicked(self, button: LoggerAlertsButton) -> None: + button.hide() + # FIXME: hitting ESC from here goes to help list instead of main menu + # need some kind of flag + self.controller.populate_log() + def _on_mod_page_loaded(self, emitter: "Emitter") -> None: msg = self.controller.format_mod_statusbar() self.set_by_context(NotebookPage.MODS, msg) @@ -80,13 +96,6 @@ class Statusbar(Gtk.Grid): match enum: case NotebookPage.HELP: bar = self.controller.get_help_row() - # TODO: drop - # case NotebookPage.MODS: - # return - # case NotebookPage.SERVERS: - # context = self.controller.get_active_context() - # # self.emitter.emit("servers_loaded", context) - # return case NotebookPage.KEYS: bar = question_to_return case _: diff --git a/dzgui/views/pages/log.py b/dzgui/views/pages/log.py index dcd717a..837435f 100644 --- a/dzgui/views/pages/log.py +++ b/dzgui/views/pages/log.py @@ -22,7 +22,10 @@ class Log(CursorMixin, HelpMenuMixin, Gtk.Box): # type: ignore self.check_bar = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) # TODO: strings - active = ("WARNING", "CRITICAL", "INFO") + active = ( + "WARNING", + "CRITICAL", + ) for check in ("WARNING", "CRITICAL", "INFO", "DEBUG"): c = Gtk.CheckButton(label=check) self.check_bar.pack_start(c, False, False, 0) diff --git a/dzgui/views/trees/tree_log.py b/dzgui/views/trees/tree_log.py index 3a479de..34e64a6 100644 --- a/dzgui/views/trees/tree_log.py +++ b/dzgui/views/trees/tree_log.py @@ -33,15 +33,18 @@ class LogTreeView(ContextMixin, TreeView): self.set_model(None) self.filter: Gtk.TreeModelFilter - # TODO: strings - self.filters = ["INFO", "CRITICAL", "WARNING"] + # TODO: strings + # NOTE: default filters that should be shown on startup + self.filters = ["CRITICAL", "WARNING"] for i, column_title in enumerate(strings.log_cols): renderer = Gtk.CellRendererText() column = Gtk.TreeViewColumn(column_title, renderer, text=i) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_resizable(True) column.set_sort_column_id(i) + if i == 1: + column.set_fixed_width(100) self.append_column(column) self.connect("button-press-event", self._on_log_buttonpress)