diff --git a/bec_widgets/widgets/services/scan_history_browser/components/scan_history_view.py b/bec_widgets/widgets/services/scan_history_browser/components/scan_history_view.py index 9bf5f8aa..1a417f21 100644 --- a/bec_widgets/widgets/services/scan_history_browser/components/scan_history_view.py +++ b/bec_widgets/widgets/services/scan_history_browser/components/scan_history_view.py @@ -11,6 +11,7 @@ from qtpy import QtCore, QtGui, QtWidgets from bec_widgets.utils.bec_widget import BECWidget, ConnectionConfig from bec_widgets.utils.colors import get_accent_colors from bec_widgets.utils.error_popups import SafeSlot +from bec_widgets.widgets.utility.spinner.spinner import SpinnerWidget if TYPE_CHECKING: from bec_lib.client import BECClient @@ -112,6 +113,11 @@ class ScanHistoryView(BECWidget, QtWidgets.QTreeWidget): header.setToolTip(f"Last {self.max_length} scans in history.") self.bec_scan_history_manager.scan_history_updated.connect(self.update_history) self.bec_scan_history_manager.scan_history_refreshed.connect(self.update_full_history) + self._container = QtWidgets.QStackedLayout() + self._container.setStackingMode(QtWidgets.QStackedLayout.StackAll) + self.setLayout(self._container) + self._add_overlay() + self._start_waiting_display() self.refresh() def _set_policies(self): @@ -155,6 +161,29 @@ class ScanHistoryView(BECWidget, QtWidgets.QTreeWidget): self.status_icons = self._create_status_icons() self.repaint() + def _add_overlay(self): + self._overlay_widget = QtWidgets.QWidget() + self._overlay_widget.setStyleSheet("background-color: rgba(240, 240, 240, 180);") + self._overlay_widget.setAutoFillBackground(True) + self._overlay_layout = QtWidgets.QVBoxLayout() + self._overlay_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter) + self._overlay_widget.setLayout(self._overlay_layout) + + self._spinner = SpinnerWidget(parent=self) + self._spinner.setFixedSize(QtCore.QSize(32, 32)) + self._overlay_layout.addWidget(self._spinner) + self._container.addWidget(self._overlay_widget) + + def _start_waiting_display(self): + self._overlay_widget.setVisible(True) + self._spinner.start() + QtWidgets.QApplication.processEvents() + + def _stop_waiting_display(self): + self._overlay_widget.setVisible(False) + self._spinner.stop() + QtWidgets.QApplication.processEvents() + def _current_item_changed( self, current: QtWidgets.QTreeWidgetItem, previous: QtWidgets.QTreeWidgetItem ): @@ -173,9 +202,8 @@ class ScanHistoryView(BECWidget, QtWidgets.QTreeWidget): @SafeSlot() def refresh(self): """Refresh the scan history view.""" - if ( - self.client.history._scan_history_loaded_event.is_set() - ): # pylint: disable=protected-access + # pylint: disable=protected-access + if self.client.history._scan_history_loaded_event.is_set(): while len(self.scan_history) > 0: self.remove_scan(index=0) self.bec_scan_history_manager.refresh_scan_history() @@ -202,6 +230,7 @@ class ScanHistoryView(BECWidget, QtWidgets.QTreeWidget): messages.sort(key=lambda m: m.scan_number, reverse=False) self.add_scans(messages) self.ensure_history_max_length() + self._stop_waiting_display() def ensure_history_max_length(self) -> None: """ diff --git a/tests/unit_tests/test_scan_history_browser.py b/tests/unit_tests/test_scan_history_browser.py index 2988017f..4ddf24e7 100644 --- a/tests/unit_tests/test_scan_history_browser.py +++ b/tests/unit_tests/test_scan_history_browser.py @@ -287,6 +287,23 @@ def test_scan_history_view_refresh(qtbot, scan_history_view, scan_history_msg, s assert scan_history_view.topLevelItemCount() == 0 +def test_scan_history_update_full_history( + qtbot, scan_history_view, scan_history_msg, scan_history_msg_2 +): + """Test the update_full_history method of ScanHistoryView.""" + # Wait spinner should be visible + scan_history_view.update_full_history( + [scan_history_msg.model_dump(), scan_history_msg_2.model_dump()] + ) + assert len(scan_history_view.scan_history) == 2 + assert scan_history_view.topLevelItemCount() == 2 + assert scan_history_view.scan_history[0] == scan_history_msg_2 # new first item + assert scan_history_view.scan_history[1] == scan_history_msg # old second item + # Wait spinner should be hidden + assert scan_history_view._overlay_widget.isVisible() is False + assert scan_history_view._spinner.isVisible() is False + + def test_scan_history_browser(qtbot, scan_history_browser, scan_history_msg, scan_history_msg_2): """Test the initialization of ScanHistoryBrowser.""" assert isinstance(scan_history_browser.scan_history_view, ScanHistoryView)