From fa56fc88026521f6f13690c4ec621c79e318f434 Mon Sep 17 00:00:00 2001 From: David Perl Date: Wed, 21 Jan 2026 11:05:52 +0100 Subject: [PATCH] fix: tooltip logic and disable button on running scan --- .../device_manager_display_widget.py | 77 ++++++++++++------- .../bec_progressbar/bec_progressbar.py | 1 + 2 files changed, 52 insertions(+), 26 deletions(-) diff --git a/bec_widgets/applications/views/device_manager_view/device_manager_display_widget.py b/bec_widgets/applications/views/device_manager_view/device_manager_display_widget.py index 92d036e2..db47a99a 100644 --- a/bec_widgets/applications/views/device_manager_view/device_manager_display_widget.py +++ b/bec_widgets/applications/views/device_manager_view/device_manager_display_widget.py @@ -7,9 +7,11 @@ from typing import TYPE_CHECKING, List, Literal, get_args import yaml from bec_lib import config_helper from bec_lib.bec_yaml_loader import yaml_load +from bec_lib.callback_handler import EventType +from bec_lib.endpoints import MessageEndpoints from bec_lib.file_utils import DeviceConfigWriter from bec_lib.logger import bec_logger -from bec_lib.messages import ConfigAction +from bec_lib.messages import ConfigAction, ScanStatusMessage from bec_lib.plugin_helper import plugin_package_name, plugin_repo_path from bec_qthemes import apply_theme, material_icon from qtpy.QtCore import QMetaObject, Qt, QThreadPool, Signal @@ -158,6 +160,10 @@ class DeviceManagerDisplayWidget(DockAreaWidget): # State variable for config upload self._config_upload_active: bool = False + self._config_in_sync: bool = False + scan_status = self.bec_dispatcher.client.connector.get(MessageEndpoints.scan_status()) + initial_status = scan_status.status if scan_status is not None else "closed" + self._scan_is_running: bool = initial_status not in ["open", "paused"] # Push to Redis dialog self._upload_redis_dialog: UploadRedisDialog | None = None @@ -213,22 +219,37 @@ class DeviceManagerDisplayWidget(DockAreaWidget): ), ( self.device_table_view.device_config_in_sync_with_redis, - (self._update_config_enabled_button,), + (self._update_config_in_sync,), ), (self.device_table_view.device_row_dbl_clicked, (self._edit_device_action,)), ]: for slot in slots: signal.connect(slot) + self._scan_status_callback_id = self.bec_dispatcher.client.callbacks.register( + EventType.SCAN_STATUS, self._update_scan_running + ) + # Add toolbar self._add_toolbar() # Build dock layout using shared helpers self._build_docks() + def cleanup(self): + self.bec_dispatcher.client.callbacks.remove(self._scan_status_callback_id) + super().cleanup() + def closeEvent(self, event): - self._about_to_quit_handler() - return super().closeEvent(event) + """If config upload is active when application is exiting, cancel it.""" + logger.info("Application is quitting, checking for active config upload...") + if self._config_upload_active: + logger.info("Application is quitting, cancelling active config upload...") + self._config_helper.send_config_request( + action="cancel", config=None, wait_for_response=True, timeout_s=10 + ) + logger.info("Config upload cancelled.") + super().closeEvent(event) ############################## ### Custom set busy widget ### @@ -240,20 +261,6 @@ class DeviceManagerDisplayWidget(DockAreaWidget): widget.cancel_requested.connect(self._cancel_device_config_upload) return widget - ################################ - ### Application quit handler ### - ################################ - - def _about_to_quit_handler(self): - """Handle application about to quit event. If config upload is active, cancel it.""" - logger.info("Application is quitting, checking for active config upload...") - if self._config_upload_active: - logger.info("Application is quitting, cancelling active config upload...") - self._config_helper.send_config_request( - action="cancel", config=None, wait_for_response=True, timeout_s=10 - ) - logger.info("Config upload cancelled.") - def _set_busy_wrapper(self, enabled: bool): """Thin wrapper around set_busy to flip the state variable.""" self._busy_overlay.set_opacity(0.92) @@ -445,6 +452,32 @@ class DeviceManagerDisplayWidget(DockAreaWidget): # Add load config from plugin dir self.toolbar.add_bundle(table_bundle) + ###################################### + ### Update button state management ### + ###################################### + + @SafeSlot(dict, dict) + def _update_scan_running(self, scan_info: dict, _: dict): + """disable editing when scans are running and enable editing when they are finished""" + msg = ScanStatusMessage.model_validate(scan_info) + self._scan_is_running = msg.status in ["open", "paused"] + self._update_config_enabled_button() + + def _update_config_in_sync(self, in_sync: bool): + self._config_in_sync = in_sync + self._update_config_enabled_button() + + def _update_config_enabled_button(self): + action = self.toolbar.components.get_action("update_config_redis") + enabled = not self._config_in_sync and not self._scan_is_running + action.action.setEnabled(enabled) + if enabled: # button is enabled + action.action.setToolTip("Push current config to BEC Server") + elif self._scan_is_running: + action.action.setToolTip("Scan is currently running, config updates disabled.") + else: + action.action.setToolTip("Current config is in sync with BEC Server, updates disabled.") + ####################### ### Action Handlers ### ####################### @@ -465,14 +498,6 @@ class DeviceManagerDisplayWidget(DockAreaWidget): ) self.request_ophyd_validation.emit(configs, True, connect) - def _update_config_enabled_button(self, enabled: bool): - action = self.toolbar.components.get_action("update_config_redis") - action.action.setEnabled(not enabled) - if enabled: - action.action.setToolTip("Push current config to BEC Server") - else: - action.action.setToolTip("Current config is in sync with BEC Server, button disabled.") - @SafeSlot() def _load_file_action(self): """Action for the 'load' action to load a config from disk for the io_bundle of the toolbar.""" diff --git a/bec_widgets/widgets/progress/bec_progressbar/bec_progressbar.py b/bec_widgets/widgets/progress/bec_progressbar/bec_progressbar.py index 7db45975..2e758e22 100644 --- a/bec_widgets/widgets/progress/bec_progressbar/bec_progressbar.py +++ b/bec_widgets/widgets/progress/bec_progressbar/bec_progressbar.py @@ -109,6 +109,7 @@ class BECProgressBar(BECWidget, QWidget): self.center_label = QLabel(self) self.center_label.setAlignment(Qt.AlignHCenter) self.center_label.setMinimumSize(0, 0) + self.center_label.setStyleSheet("background: transparent; color: white;") layout = QVBoxLayout(self) layout.setContentsMargins(10, 0, 10, 0)