chore: register signals

This commit is contained in:
aclist 2026-01-24 13:30:01 +09:00
parent c952fef5e8
commit f05374bc7d
10 changed files with 139 additions and 137 deletions

View File

@ -227,7 +227,7 @@ class Controller(GObject.GObject):
c = self.mediator.statusbar.statusbar.get_context_id(context)
self.mediator.statusbar.statusbar.pop(c)
# TODO: use set_by_context()
@deprecated("use set_by_context")
def set_statusbar(self, text: str, context: str) -> int:
msg_id = self.mediator.statusbar.set_text(text, context)
return msg_id
@ -319,12 +319,8 @@ class Controller(GObject.GObject):
notebook = self.mediator.grid.notebook
notebook.focus_current()
def set_statusbar_by_row(self, row: "RowType") -> None:
self.mediator.statusbar.refresh(row)
def toggle_server_panels(self, state: bool) -> None:
# TODO: this is going to be signal dependent now
# cf. map/unmap
# TODO: this is going to be signal dependent now, cf. map/unmap
#self.mediator.grid.emit("toggle panels", state)
self.mediator.grid.toggle_filter_panel(state)
self.mediator.grid.toggle_connect_panel(state)
@ -579,7 +575,6 @@ class Controller(GObject.GObject):
for row in data:
manager.append_row(row)
treeview.set_loaded(True)
# TODO: emit custom "servers finished loading" signal
self.mediator.statusbar.emit("server_page_changed", context)
treeview.grab_focus()

View File

@ -310,9 +310,6 @@ class Grid(Gtk.Grid):
MainController.register_widget("grid", self)
self.statusbar = Statusbar(MainController)
self.right_panel = RightPanel(MainController)
# self.bu = Gtk.Button(label="Shrink to fit", halign=Gtk.Align.END)
# self.bu.connect("clicked", self._shrink)
# self.crumb_box.add(self.bu)
@ -320,6 +317,9 @@ class Grid(Gtk.Grid):
self.notebook = Notebook()
self.conpan = ConnectPanel(MainController)
self.statusbar = Statusbar(MainController)
self.right_panel = RightPanel(MainController)
self.breadcrumbs = Breadcrumbs(MainController)
self.crumb_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.crumb_box.add(self.breadcrumbs)

View File

@ -5,12 +5,14 @@ from dzgui.util.css import add_class, remove_class
from dzgui.util.strings import connect_panel, lan_panel
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, GObject # noqa E402
from gi.repository import Gtk, Gdk, GObject # noqa E402
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
def validate_port(text: str) -> bool:
if text.isdigit():
if int(text) < 1:
@ -21,6 +23,7 @@ def validate_port(text: str) -> bool:
else:
return False
def validate_ip_or_id(text: str) -> bool:
try:
validate_ip(text)
@ -31,15 +34,13 @@ def validate_ip_or_id(text: str) -> bool:
else:
return False
class ValidatedEntry(Gtk.Entry):
__gsignals__ = {
"string_validated": (GObject.SignalFlags.RUN_FIRST, None, (object,)),
}
def __init__(self, controller: "Controller", func: Callable) -> None:
super().__init__(
hexpand=True,
placeholder_text=connect_panel.placeholder,
tooltip_text=connect_panel.entry_tooltip
tooltip_text=connect_panel.entry_tooltip,
)
self.func: Callable
@ -50,6 +51,10 @@ class ValidatedEntry(Gtk.Entry):
self.connect("key-press-event", self._on_entry_keypress)
self.connect("changed", self._on_text_changed)
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=(bool,))
def string_validated(self, valid: bool) -> None:
pass
def mark_valid(self) -> None:
self.emit("string_validated", True)
remove_class(self, self.classname)
@ -66,7 +71,9 @@ class ValidatedEntry(Gtk.Entry):
self.func = func
def insert_icon(self) -> None:
self.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "edit-clear-symbolic")
self.set_icon_from_icon_name(
Gtk.EntryIconPosition.SECONDARY, "edit-clear-symbolic"
)
self.set_icon_activatable(Gtk.EntryIconPosition.SECONDARY, True)
self.connect("icon-release", self._on_icon_release)
@ -98,7 +105,6 @@ class ValidatedEntry(Gtk.Entry):
entry.set_text("")
self.remove_icon()
def _on_entry_keypress(self, entry: Gtk.Entry, event: Gdk.EventKey) -> None:
if event.keyval == Gdk.KEY_Escape:
# NOTE: unselect text
@ -112,6 +118,7 @@ class IpEntry(ValidatedEntry):
self.set_placeholder_text(connect_panel.placeholder)
self.set_tooltip_text(connect_panel.entry_tooltip)
class PortEntry(ValidatedEntry):
def __init__(self, controller: "Controller") -> None:
super().__init__(controller, func=validate_port)

View File

@ -1,14 +1,20 @@
from typing import TYPE_CHECKING
from dzgui.const.constants import HELP_BUBBLE
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk # noqa E402
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
class InfoEventBox(Gtk.EventBox):
def __init__(self, text: str, parent: Gtk.Widget):
def __init__(self, text: str, controller: "Controller"):
super().__init__(margin_start=10)
self.parent = parent
self.controller = controller
self.text = text
self.icon = Gtk.Image.new_from_icon_name(
@ -26,14 +32,14 @@ class InfoEventBox(Gtk.EventBox):
self, eventbox: Gtk.EventBox, eventcrossing: Gdk.EventCrossing
) -> None:
self.icon.set_opacity(1)
self.parent.controller.set_statusbar(self.text, "Options")
self.controller.set_statusbar(self.text, "Options")
def _on_leave_tooltip(
self, eventbox: Gtk.EventBox, eventcrossing: Gdk.EventCrossing
) -> None:
self.icon.set_opacity(0.8)
#self.parent.controller.set_statusbar("", "Options")
self.parent.controller.remove_statusbar("Options")
# self.parent.controller.set_statusbar("", "Options")
self.controller.remove_statusbar("Options")
def set_text(self, text: str) -> None:
self.text = text

View File

@ -1,7 +1,7 @@
from warnings import deprecated
from typing import Self, Union, TYPE_CHECKING
from dzgui.const.enum import NotebookPage, RowType
from dzgui.const.enum import NotebookPage, ServerTab
import gi
@ -11,17 +11,11 @@ from gi.repository import Gtk, GObject # noqa E402
if TYPE_CHECKING:
from dzgui.const.enum import ServerTab
from dzgui.controllers.mc import Controller
from dzgui.views.trees.tree_base import TreeView
from dzgui.views.base import Notebook
class Statusbar(Gtk.Grid):
__gsignals__ = {
"server_page_changed": (GObject.SignalFlags.RUN_FIRST, None, (object,)),
"notebook_page_changed": (GObject.SignalFlags.RUN_FIRST, None, (object,)),
"notebook_page_returned": (GObject.SignalFlags.RUN_FIRST, None, (object,)),
"distcalc_ended": (GObject.SignalFlags.RUN_FIRST, None, (object, str)),
"server_row_changed": (GObject.SignalFlags.RUN_FIRST, None, ()),
}
def __init__(self, controller: "Controller") -> None:
super().__init__(orientation=Gtk.Orientation.HORIZONTAL)
@ -46,37 +40,58 @@ class Statusbar(Gtk.Grid):
self.players = ""
controller.mediator.menu.connect(
"generic_treesel_changed", self._help_row_changed
)
controller.mediator.notebook.connect_after(
"switch-page", self._on_notebook_page_changed
)
self.connect("server_row_changed", self._on_server_row_changed)
self.connect("server_page_changed", self._on_server_page_changed)
self.connect("notebook_page_changed", self._on_notebook_page_changed)
self.connect("notebook_page_returned", self._on_notebook_page_returned)
self.connect("distcalc_ended", self._on_distcalc_ended)
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=(object,))
def server_page_changed(self, tab: ServerTab) -> None:
pass
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
def server_row_changed(self) -> None:
pass
@GObject.Signal(
flags=GObject.SignalFlags.RUN_LAST,
arg_types=(
object,
object,
),
)
def distcalc_ended(
self, dist: Union[str, None], context: Union["ServerTab", NotebookPage]
) -> None:
pass
def _on_notebook_page_changed(
self, statusbar: Self, context: "NotebookPage"
self, notebook: "Notebook", child: Gtk.Widget, index: int
) -> None:
if self.controller.loaded is False:
return
status = context.dict["statusbar"]
bar = ""
if status is False:
self.set_by_context(context, "")
enum = notebook.get_page_by_enum()
show_statusbar = enum.dict["statusbar"]
if show_statusbar is False:
self.set_by_context(enum, "")
return
match context:
match enum:
case NotebookPage.MODS:
bar = self.controller.format_mod_statusbar()
case NotebookPage.HELP:
bar = self.controller.get_help_row()
case NotebookPage.SERVERS:
# TODO:
from dzgui.const.enum import ServerTab
self.emit("server_page_changed", ServerTab.BROWSER)
return
self.set_by_context(context, bar)
self.set_by_context(enum, bar)
def _on_notebook_page_returned(
self, statusbar: Self, prior_context: NotebookPage
@ -96,9 +111,12 @@ class Statusbar(Gtk.Grid):
if dist is None:
self.set_by_context(context, self.playercount)
else:
pretty = f"{self.playercount} | Distance: {dist}"
pretty = self.append_distance(dist)
self.set_by_context(context, pretty)
def append_distance(self, dist: str) -> str:
return f"{self.playercount} | Distance: {dist}"
def _on_server_page_changed(self, statusbar: Self, context: "ServerTab") -> None:
count = self.controller.get_player_count()
self.playercount = count
@ -134,16 +152,9 @@ class Statusbar(Gtk.Grid):
self.statusbar.push(meta, string)
self.set_cache(string)
@deprecated("use set_by_context()")
def refresh(self, row: "RowType") -> None:
# FIXME: brittle
if row is None:
formatted = ""
else:
formatted = self.format_metadata(row)
self.set_text(formatted, "Help")
@deprecated("use controller")
def format_metadata(self, row: "RowType") -> str:
prefix = row.dict["tooltip"]
return prefix
def _help_row_changed(self, tree: "TreeView", sel: Gtk.TreeSelection) -> None:
row = tree.get_value_at_index(1)
if self.controller.loaded is False:
return
tooltip = row.dict["tooltip"]
self.set_by_context(NotebookPage.HELP, tooltip)

View File

@ -28,15 +28,17 @@ from dzgui.const.constants import (
STEAM_CMD,
VIEW_CONCEAL,
VIEW_REVEAL,
)
)
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk # noqa
if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
class Options(Gtk.Box):
def __init__(self, controller: "Controller"):
super().__init__(
@ -115,8 +117,8 @@ class Options(Gtk.Box):
# NOTE: sensitivity state is updated after config file is loaded
self.force_button.set_sensitive(False)
eb = InfoEventBox(strings.options.dl_eventbox, self)
eb2 = InfoEventBox(strings.options.force_eventbox, self)
eb = InfoEventBox(strings.options.dl_eventbox, controller)
eb2 = InfoEventBox(strings.options.force_eventbox, controller)
mod_rows = [
[LeftLabel(strings.options.install_mode), self.mod_install_toggle, eb],
@ -131,7 +133,7 @@ class Options(Gtk.Box):
self.branch_combo.append_text(strings.options.testing)
self.branch_combo.set_active(0)
self.branch_combo.connect("changed", self._on_branch_changed)
self.branch_eb = InfoEventBox("", self)
self.branch_eb = InfoEventBox("", controller)
version_rows = [
[LeftLabel(APPNAME_DAYZ), self.dayz_version_label],
@ -149,7 +151,7 @@ class Options(Gtk.Box):
margin_top=5,
margin_bottom=10,
homogeneous=True,
spacing=10
spacing=10,
)
api_links_box.add(self.steam)
api_links_box.add(self.bm)
@ -167,15 +169,13 @@ class Options(Gtk.Box):
hexpand=True,
)
developers=Gtk.Button(label="Developers", halign=Gtk.Align.START)
developers = Gtk.Button(label="Developers", halign=Gtk.Align.START)
developers.connect("clicked", self._on_developers_clicked)
prefs = self.controller.get_prefs()
is_developer = prefs.is_developer
if is_developer:
grid.attach(
developers, 1, 0, self.DEFAULT_WIDTH, self.DEFAULT_HEIGHT
)
grid.attach(developers, 1, 0, self.DEFAULT_WIDTH, self.DEFAULT_HEIGHT)
for frame in [
self.make_frame(api_box, strings.options.api_keys),
@ -183,9 +183,7 @@ class Options(Gtk.Box):
self.make_frame(mods_grid, strings.options.mods),
self.make_frame(version_grid, strings.options.version),
]:
grid.attach(
frame, col, row, self.DEFAULT_WIDTH, self.DEFAULT_HEIGHT
)
grid.attach(frame, col, row, self.DEFAULT_WIDTH, self.DEFAULT_HEIGHT)
row += 1
self.scrollable = Gtk.ScrolledWindow(vexpand=True)
@ -221,13 +219,11 @@ class Options(Gtk.Box):
entry.connect("insert-text", self._on_text_typed, context, button)
entry.connect("activate", self._on_field_activated, context, button)
entry.get_property("buffer").connect(
"deleted-text", self._on_text_deleted, context, button
"deleted-text", self._on_text_deleted, context, button
)
if private:
entry.set_icon_from_icon_name(
Gtk.EntryIconPosition.SECONDARY, VIEW_REVEAL
)
entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, VIEW_REVEAL)
entry.set_icon_activatable(Gtk.EntryIconPosition.SECONDARY, True)
entry.connect("icon-release", self._on_icon_release)
entry.set_visibility(False)
@ -244,7 +240,7 @@ class Options(Gtk.Box):
return box
def _on_field_activated(
self, entry: Gtk.Entry, context: Preferences, button: Gtk.Button
self, entry: Gtk.Entry, context: Preferences, button: Gtk.Button
) -> None:
text = entry.get_text()
if not self._is_valid_text(text, context):
@ -265,9 +261,7 @@ class Options(Gtk.Box):
for record in rows:
col = 1
for el in record:
grid.attach(
el, col, row, self.DEFAULT_WIDTH, self.DEFAULT_HEIGHT
)
grid.attach(el, col, row, self.DEFAULT_WIDTH, self.DEFAULT_HEIGHT)
col += 1
row += 1
return grid
@ -299,9 +293,9 @@ class Options(Gtk.Box):
def _on_force_update_clicked(self, button: Gtk.Button) -> None:
# TODO: unimplemented
print("UNIMPLEMENTED")
#wait_msg = strings.dialog.updating_mods
#show_wait_dialog = True
#call_on_thread(show_wait_dialog, cmd, wait_msg, "")
# wait_msg = strings.dialog.updating_mods
# show_wait_dialog = True
# call_on_thread(show_wait_dialog, cmd, wait_msg, "")
def _on_client_changed(self, combo: Gtk.ComboBoxText) -> None:
# TODO: use two columns or constants here, not strings
@ -320,14 +314,12 @@ class Options(Gtk.Box):
print("UNIMPLEMENTED")
print(branch)
## TODO: needs to trigger download process
#self.controller.toggle_branch(branch)
#branch = combo.get_active_text().lower()
#self.controller.update_config("branch", branch)
#scripts/update
# self.controller.toggle_branch(branch)
# branch = combo.get_active_text().lower()
# self.controller.update_config("branch", branch)
# scripts/update
def _on_radio_toggled(
self, button: Gtk.RadioButton, context: Preferences
) -> None:
def _on_radio_toggled(self, button: Gtk.RadioButton, context: Preferences) -> None:
try:
self.controller.toggle_config(context)
except Exception:
@ -342,12 +334,11 @@ class Options(Gtk.Box):
self.controller,
strings.options.manual_sub_msg,
strings.self_workshop,
self.uid
self.uid,
)
else:
self.force_button.set_sensitive(False)
def _is_valid_text(self, text: str, context: Preferences) -> bool:
if text.isspace():
return False
@ -458,7 +449,7 @@ class Options(Gtk.Box):
for el, conf_state in [
(self.mod_install_toggle, install),
(self.fullscreen_toggle, config["fullscreen"]),
(self.distance_toggle, config["use_miles"])
(self.distance_toggle, config["use_miles"]),
]:
el.get_children()[conf_state].set_active(True)
self._suppress_toggles(False)
@ -473,18 +464,14 @@ class Options(Gtk.Box):
field[1].get_children()[1].set_sensitive(False)
try:
pe_file_path = PeFile.get_pefile_path(
steam_path, APPID_DAYZ
)
pe_file_path = PeFile.get_pefile_path(steam_path, APPID_DAYZ)
vers = PeFile.get_dayz_version(pe_file_path)
dayz_version = PeFile.dayz_version_to_str(vers)
except Exception:
dayz_version = strings.null
try:
exp_file_path = PeFile.get_pefile_path(
steam_path, APPID_DAYZ_EXP
)
exp_file_path = PeFile.get_pefile_path(steam_path, APPID_DAYZ_EXP)
vers = PeFile.get_dayz_version(exp_file_path)
dayz_exp_version = PeFile.dayz_version_to_str(vers)
except Exception:
@ -497,13 +484,16 @@ class Options(Gtk.Box):
active_combo = query.get_client_index(config["client"])
self.client_combo.set_active(active_combo)
active_combo = 1 if config["branch"] == BETA_REPO else 0
self.controller.suppress_signal(self, self.branch_combo, "_on_branch_changed", True)
self.controller.suppress_signal(
self, self.branch_combo, "_on_branch_changed", True
)
self.branch_combo.set_active(active_combo)
self.branch_combo.set_sensitive(prefs.allow_updates)
self.controller.suppress_signal(self, self.branch_combo, "_on_branch_changed", False)
self.controller.suppress_signal(
self, self.branch_combo, "_on_branch_changed", False
)
if prefs.allow_updates is True:
msg = strings.options.self_update
@ -517,7 +507,9 @@ class Options(Gtk.Box):
self.fullscreen_toggle,
self.distance_toggle,
]:
self.controller.suppress_signal(self, toggle.get_children()[0], "_on_radio_toggled", state)
self.controller.suppress_signal(
self, toggle.get_children()[0], "_on_radio_toggled", state
)
def _on_icon_release(
self,

View File

@ -7,6 +7,7 @@ from dzgui.util.keys import 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
@ -16,8 +17,11 @@ if TYPE_CHECKING:
from dzgui.controllers.mc import Controller
from dzgui.const.enum import ContextMenuGroup
class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
def __init__(self, controller: "Controller", menu: "ContextMenuGroup" = None) -> None:
def __init__(
self, controller: "Controller", menu: "ContextMenuGroup" = None
) -> None:
super().__init__(
enable_search=False,
search_column=-1,
@ -32,7 +36,6 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
self.selected_row = self.get_selection()
self.selected_row.set_mode(Gtk.SelectionMode.SINGLE)
self.selected_row.connect("changed", self._on_tree_selection_changed)
self.connect("row-activated", self._on_row_activated)
self.connect("key-press-event", self._on_keypress)
self.connect("key-release-event", self._on_key_release)
@ -41,22 +44,22 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
def generic_treesel_changed(self, selection: Gtk.TreeSelection) -> None:
pass
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST,
arg_types=(Gtk.TreePath, Gtk.TreeViewColumn)
@GObject.Signal(
flags=GObject.SignalFlags.RUN_LAST, arg_types=(Gtk.TreePath, Gtk.TreeViewColumn)
)
def generic_row_activated(self,
path: Gtk.TreePath,
column: Gtk.TreeViewColumn
def generic_row_activated(
self, path: Gtk.TreePath, column: Gtk.TreeViewColumn
) -> None:
pass
def signal_emission(func: Callable) -> Callable:
def wrapper(self, *args, **kwargs):
self.controller.block_signals()
func(self, *args, **kwargs)
self.controller.unblock_signals()
return wrapper
# @deprecated("signals are localized now")
# def signal_emission(func: Callable) -> Callable:
# def wrapper(self, *args, **kwargs):
# self.controller.block_signals()
# func(self, *args, **kwargs)
# self.controller.unblock_signals()
#
# return wrapper
def _separate(self, model: Gtk.ListStore, iter_: Gtk.TreeIter) -> bool:
if model[iter_][0] == SEPARATOR:
@ -83,9 +86,7 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
model, rows = sel.get_selected_rows()
return [model[row] for row in rows]
def _on_keypress(
self, treeview: Gtk.TreeView, event: Gdk.EventKey
) -> None:
def _on_keypress(self, treeview: Gtk.TreeView, event: Gdk.EventKey) -> None:
if is_navkey(event.keyval):
# TODO: if model is None
@ -101,14 +102,13 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
self._vim_nav(event)
return
def _on_key_release(
self, treeview: Gtk.TreeView, event: Gdk.EventKey
) -> None:
def _on_key_release(self, treeview: Gtk.TreeView, event: Gdk.EventKey) -> None:
# TODO: explain this better
"""
Suppresses spamming on keydown
"""
#if event.keyval is Gdk.KEY_space:
# TODO: multisel
# if event.keyval is Gdk.KEY_space:
# it = self.get_focused_row_iter()
# self.get_selection().select_iter(it)
# return True
@ -169,7 +169,7 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
path = pathlist[0]
return path
@signal_emission
# @signal_emission
def _on_row_activated(
self,
treeview: Gtk.TreeView,

View File

@ -41,7 +41,6 @@ class MenuTreeView(TreeView):
self.set_row_separator_func(self._separate)
self.connect("generic_row_activated", self._parent_row_activated)
self.connect("generic_treesel_changed", self._parent_selection_changed)
def _parent_row_activated(
self, tree: TreeView, path: Gtk.TreePath, column: Gtk.TreeViewColumn
@ -69,13 +68,3 @@ class MenuTreeView(TreeView):
if row_type in docs:
# FIXME: prior method is returning a str, not enum
open_link_by_rowtype(row_type)
def _parent_selection_changed(
self, base_class: TreeView, sel: Gtk.TreeSelection
) -> None:
row = self.get_value_at_index(1)
if row == "":
return
if self.controller.loaded is False:
return
self.controller.set_statusbar_by_row(row)

View File

@ -55,16 +55,16 @@ class ModTreeView(ModsMixin, ContextMixin, TreeView):
self.connect("button-press-event", self._on_mods_button_press)
self.connect("key-press-event", self._on_mods_keypress)
self.s = self.get_selection().get_selected_rows()
# self.s = self.get_selection().get_selected_rows()
def _on_mods_keypress(self, widget: Gtk.Widget, event: Gdk.EventKey) -> None:
# TODO: multiselect
# if event.keyval is Gdk.KEY_space:
# it = self.get_focused_row_iter()
# self.get_selection().select_iter(it)
# path = self.get_focused_row_path()
# self.set_cursor(path)
# return False
# TODO: parse keys
self.present_menu(widget, event)
def _on_mods_button_press(self, widget: Gtk.Widget, event: Gdk.EventButton) -> None:

View File

@ -34,8 +34,6 @@ class EnumeratedMenuItem(Gtk.MenuItem):
class ServerTreeView(TreeView):
__gsignals__ = {"distcalc_started": (GObject.SignalFlags.RUN_FIRST, None, ())}
def __init__(
self, controller: "Controller", enum: ServerTab, menu: ContextMenuGroup
) -> None:
@ -115,6 +113,10 @@ class ServerTreeView(TreeView):
GLib.timeout_add(QUEUE_CHECK_DELAY, self._check_result_queue)
@GObject.Signal(flags=GObject.SignalFlags.RUN_FIRST, arg_types=())
def distcalc_started(self) -> None:
pass
def filter(self, mode: FilterMode, label: str) -> None:
print("TOGGLE:", mode)
print("LABEL: ", label)