Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions BlocksScreen/lib/panels/filamentTab.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import logging
from collections import deque
from typing import Deque

from devices.amu import AMUManager
from devices.amu.models import GateStatus
Expand Down Expand Up @@ -52,7 +51,7 @@ def __init__(

self._previous_gate_states: dict[int, bool] = {}
self.pre_gate_idx = {}
self.popup_gates: Deque = deque()
self.popup_gates: deque = deque()
self._spool_id_map: dict[str, dict] = {}
self._current_field: QtWidgets.QLineEdit | None = None
self._color_target_field = None
Expand Down Expand Up @@ -118,7 +117,7 @@ def __init__(
def handle_moonraker_components(self):
if self.moonraker_run:
components = self.ws._moonRest.get_server_info()
if "spoolman" not in components["result"].get("components", []):
if "spoolman" not in components.get("result", {}).get("components", []):
self.fp_button_2.hide()
self._popup_stack.addWidget(self._build_form_page())
self._popup_stack.addWidget(self._build_spool_page())
Expand Down
21 changes: 12 additions & 9 deletions BlocksScreen/lib/panels/mainWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from devices.amu import AMUManager
from devices.storage import USBManager
from lib.files import Files
from lib.klipper_message_filter import ( # noqa: F405
from lib.klipper_message_filter import (
MessageSource,
Severity,
match_message,
Expand Down Expand Up @@ -120,7 +120,7 @@ class MainWindow(QtWidgets.QMainWindow):

def __init__(self):
"""Set up UI, instantiate subsystems, and wire all inter-component signals."""
super(MainWindow, self).__init__()
super().__init__()
self.config: BlocksScreenConfig = get_configparser()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
Expand Down Expand Up @@ -320,7 +320,7 @@ def __init__(self):
)
self.loadscreen.add_widget(self.loadwidget)
self.controlPanel.toggle_conn_page.connect(self.conn_window.set_toggle)
self.cancelpage = CancelPage(self, ws=self.ws)
self.cancelpage = CancelPage(self)
self.cancelpage.request_file_info.connect(self.file_data.on_request_fileinfo)
self.cancelpage.run_gcode.connect(self.ws.api.run_gcode)
self.printer.print_stats_update[str, str].connect(
Expand Down Expand Up @@ -388,11 +388,14 @@ def show_loadscreen(
if not force:
if _sender is self.update_page:
self._update_in_progress = show
if not show and self._post_update_reconnect:
return
elif not show and self._update_in_progress:
return
elif not show and self._klipper_auto_restart_pending:
if (
not show
and self._post_update_reconnect
or not show
and self._update_in_progress
or not show
and self._klipper_auto_restart_pending
):
return

if _sender == self.filamentPanel:
Expand Down Expand Up @@ -1052,7 +1055,7 @@ def _on_probe_notification(
@api_handler
def _handle_notify_gcode_response_message(self, method, data, metadata) -> None:
"""Handle websocket gcode responses messages"""
_gcode_response = data.get("params")
_gcode_response = data.get("params", [])
self.gcode_response[list].emit(_gcode_response)
if _gcode_response:
if self._popup_toggle:
Expand Down
54 changes: 33 additions & 21 deletions BlocksScreen/lib/panels/networkWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
from lib.utils.icon_button import IconButton
from lib.utils.list_model import EntryDelegate, EntryListModel, ListItem
from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtCore import QTimer, pyqtSlot

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -255,15 +254,15 @@ def _prefill_ip_from_os(self) -> None:
except OSError:
continue

@pyqtSlot()
@QtCore.pyqtSlot()
def _on_reconnect_complete(self) -> None:
"""Navigate back to the main panel after a static-IP or DHCP-reset operation."""
logger.debug("reconnect_complete received — navigating to main_network_page")
self.setCurrentIndex(self.indexOf(self.main_network_page))

def _init_timers(self) -> None:
"""Initialize timers."""
self._load_timer = QTimer(self)
self._load_timer = QtCore.QTimer(self)
self._load_timer.setSingleShot(True)
self._load_timer.timeout.connect(self._handle_load_timeout)

Expand All @@ -277,7 +276,7 @@ def _init_model_view(self) -> None:
self._entry_delegate.item_selected.connect(self._on_ssid_item_clicked)
self._configure_list_view_palette()

@pyqtSlot(NetworkState)
@QtCore.pyqtSlot(NetworkState)
def _on_network_state_changed(self, state: NetworkState) -> None:
"""React to a NetworkState update: sync toggles, populate header and connection info."""
logger.debug(
Expand Down Expand Up @@ -438,7 +437,7 @@ def _on_network_state_changed(self, state: NetworkState) -> None:
self._emit_status_icon(state)
self._sync_active_network_list_icon(state)

@pyqtSlot(list)
@QtCore.pyqtSlot(list)
def _on_scan_complete(self, networks: list[NetworkInfo]) -> None:
"""Receive scan results, filter/sort them, and rebuild the SSID list view.

Expand All @@ -457,9 +456,11 @@ def _on_scan_complete(self, networks: list[NetworkInfo]) -> None:
# Stamp the connected AP as ACTIVE so the list is correct on first
# render even when the scan ran before the connection fully settled.
filtered = [
replace(net, network_status=NetworkStatus.ACTIVE)
if net.ssid == current_ssid
else net
(
replace(net, network_status=NetworkStatus.ACTIVE)
if net.ssid == current_ssid
else net
)
for net in filtered
]
active = next((n for n in filtered if n.ssid == current_ssid), None)
Expand All @@ -478,12 +479,12 @@ def _on_scan_complete(self, networks: list[NetworkInfo]) -> None:
state = self._nm.current_state
self._emit_status_icon(state)

@pyqtSlot(list)
@QtCore.pyqtSlot(list)
def _on_saved_networks_loaded(self, networks: list[SavedNetwork]) -> None:
"""Receive saved-network data and update the priority spinbox for the active SSID."""
logger.debug("Loaded %d saved networks", len(networks))

@pyqtSlot(ConnectionResult)
@QtCore.pyqtSlot(ConnectionResult)
def _on_operation_complete(self, result: ConnectionResult) -> None:
"""Handle network operation completion."""
logger.debug("Operation: success=%s, msg=%s", result.success, result.message)
Expand Down Expand Up @@ -570,15 +571,15 @@ def _on_operation_complete(self, result: ConnectionResult) -> None:
result.message,
)
ssid = self._target_ssid
QTimer.singleShot(
QtCore.QTimer.singleShot(
2000, lambda _ssid=ssid: self._nm.connect_network(_ssid)
)
return # Keep loading visible; state machine handles completion

self._clear_loading()
self._show_error_popup(result.message)

@pyqtSlot(str, str)
@QtCore.pyqtSlot(str, str)
def _on_network_error(self, operation: str, message: str) -> None:
"""Log network errors and surface critical failures in the info box."""
logger.error("Network error [%s]: %s", operation, message)
Expand Down Expand Up @@ -658,13 +659,15 @@ def _sync_active_network_list_icon(self, state: NetworkState) -> None:

# Update the cached entry with the authoritative signal and status
updated = [
replace(
net,
signal_strength=self._active_signal,
network_status=NetworkStatus.ACTIVE,
(
replace(
net,
signal_strength=self._active_signal,
network_status=NetworkStatus.ACTIVE,
)
if net.ssid == state.current_ssid
else net
)
if net.ssid == state.current_ssid
else net
for net in self._cached_scan_networks
]

Expand Down Expand Up @@ -1063,7 +1066,9 @@ def _handle_wifi_toggle(self, is_on: bool) -> None:
# Non-blocking: disable hotspot then connect
self._nm.toggle_hotspot(False)
_ssid_to_connect = self._target_ssid
QTimer.singleShot(500, lambda: self._nm.connect_network(_ssid_to_connect))
QtCore.QTimer.singleShot(
500, lambda: self._nm.connect_network(_ssid_to_connect)
)

def _handle_hotspot_toggle(self, is_on: bool) -> None:
"""Enable or disable the hotspot, enforcing the ethernet/Wi-Fi mutual-exclusion rule."""
Expand Down Expand Up @@ -3716,7 +3721,9 @@ def _setup_keyboard(self) -> None:
(self.wifi_sip_dns2_field, self.wifi_static_ip_page),
]:
field.clicked.connect(
lambda _=False, f=field, p=page: self._on_show_keyboard(p, f)
lambda _=False, f=field, p=page: self._on_show_keyboard(
p, f, numeric=True
)
)

def _setup_scrollbar_signals(self) -> None:
Expand Down Expand Up @@ -3759,11 +3766,16 @@ def _configure_list_view_palette(self) -> None:
self.listView.setPalette(palette)

def _on_show_keyboard(
self, panel: QtWidgets.QWidget, field: QtWidgets.QLineEdit
self,
panel: QtWidgets.QWidget,
field: QtWidgets.QLineEdit,
numeric: bool = False,
) -> None:
"""Show the QWERTY keyboard panel, saving the originating panel and input field."""
self._previous_panel = panel
self._current_field = field
self._qwerty.setPattern("ip" if numeric else "")
self._qwerty.setNumericOnly(numeric)
self._qwerty.set_value(field.text())
self._qwerty.show()
field.clearFocus()
Expand Down
16 changes: 10 additions & 6 deletions BlocksScreen/lib/panels/utilitiesTab.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
import re
import typing
from dataclasses import dataclass
Expand All @@ -15,6 +16,8 @@
from lib.utils.toggleAnimatedButton import ToggleAnimatedButton
from PyQt6 import QtCore, QtGui, QtWidgets

logger = logging.getLogger(__name__)


@dataclass
class LedState:
Expand Down Expand Up @@ -113,8 +116,8 @@ def __init__(
self.x_inputshaper: dict = {}
self.stepper_limits: dict = {}

self.current_object: typing.Optional[str] = None
self.current_process: typing.Optional[Process] = None
self.current_object: str | None = None
self.current_process: Process | None = None
self.axis_in: str = "x"
self.amount: int = 1
self.tb: bool = False
Expand Down Expand Up @@ -254,8 +257,9 @@ def handle_gcode_response(self, data: list[str]) -> None:
"""

if not isinstance(data, list) or len(data) != 1 or not isinstance(data[0], str):
print(
f"WARNING: Invalid input format. Expected a list with one string. Received: {data}"
logger.warning(
"handle_gcode_response: invalid input format. Expected list[str], received: %r",
data,
)
return

Expand Down Expand Up @@ -322,7 +326,7 @@ def handle_gcode_response(self, data: list[str]) -> None:

self.is_page.set_type_dictionary(self.is_types)
first_key = next(iter(reordered.keys()), None)
for key in reordered.keys():
for key in reordered:
if key == first_key:
self.is_page.add_type_entry(key, "Recommended type")
else:
Expand Down Expand Up @@ -375,7 +379,7 @@ def on_object_list(self, object_list: list) -> None:

@QtCore.pyqtSlot(dict, name="on_object_config")
@QtCore.pyqtSlot(list, name="on_object_config")
def on_object_config(self, config: typing.Union[dict, list]) -> None:
def on_object_config(self, config: dict | list) -> None:
"""Handle receiving printer object configurations"""
if not config:
return
Expand Down
34 changes: 11 additions & 23 deletions BlocksScreen/lib/panels/widgets/basePopup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import typing

from PyQt6 import QtCore, QtGui, QtWidgets


Expand Down Expand Up @@ -47,40 +45,33 @@ def __init__(
self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground, True)
self.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal)
else:
self.setStyleSheet(
"""
self.setStyleSheet("""
#MyParent {
background-image: url(:/background/media/1st_background.png);
}
"""
)
""")

def _update_button_style(self) -> None:
"""Applies the current color variables and adds the central border to the stylesheets."""
if not self.dialog:
return

if not self.floating:
self.confirm_button.setStyleSheet(
f"""
self.confirm_button.setStyleSheet(f"""
background-color: {self.confirm_bk_color};
color: {self.confirm_ft_color};
border: none;
padding: 10px;
"""
)
""")

self.cancel_button.setStyleSheet(
f"""
self.cancel_button.setStyleSheet(f"""
background-color: {self.cancel_bk_color};
color: {self.cancel_ft_color};
border: none;
padding: 10px;
"""
)
""")
else:
self.confirm_button.setStyleSheet(
f"""
self.confirm_button.setStyleSheet(f"""
background-color: {self.confirm_bk_color};
color: {self.confirm_ft_color};
border-top: none;
Expand All @@ -89,20 +80,17 @@ def _update_button_style(self) -> None:
border-right: 1px solid #80807e;
border-bottom-left-radius: 16px;
padding: 10px;
"""
)
""")

self.cancel_button.setStyleSheet(
f"""
self.cancel_button.setStyleSheet(f"""
background-color: {self.cancel_bk_color};
color: {self.cancel_ft_color};
border-left: 1px solid #80807e;;
border-bottom: 2px solid #80807e;
border-right: 2px solid #80807e;
border-bottom-right-radius: 16px;
padding: 10px;
"""
)
""")

def set_message(self, message: str) -> None:
self.label.setText(message)
Expand Down Expand Up @@ -152,7 +140,7 @@ def add_widget(self, widget: QtWidgets.QWidget) -> None:
layout.insertWidget(index, self.ui)
self.ui.show()

def _get_mainWindow_widget(self) -> typing.Optional[QtWidgets.QMainWindow]:
def _get_mainWindow_widget(self) -> QtWidgets.QMainWindow | None:
"""Get the main application window"""
app_instance = QtWidgets.QApplication.instance()
if not app_instance:
Expand Down
Loading
Loading