diff --git a/bec_widgets/widgets/control/scan_control/scan_selection_dialog.py b/bec_widgets/widgets/control/scan_control/scan_selection_dialog.py index 7e18f69f..a2b4a6bd 100644 --- a/bec_widgets/widgets/control/scan_control/scan_selection_dialog.py +++ b/bec_widgets/widgets/control/scan_control/scan_selection_dialog.py @@ -10,6 +10,7 @@ from qtpy.QtWidgets import ( QHBoxLayout, QListWidget, QListWidgetItem, + QPushButton, QSizePolicy, QToolButton, QVBoxLayout, @@ -76,6 +77,16 @@ class ScanSelectionDialog(QDialog): item.setSizeHint(row.sizeHint()) self.scan_list.setItemWidget(item, row) + controls = QHBoxLayout() + controls.setContentsMargins(4, 4, 4, 0) + self.select_all_button = QPushButton("Select all", self) + self.clear_button = QPushButton("Clear", self) + self.select_all_button.clicked.connect(lambda: self.set_all_checked(True)) + self.clear_button.clicked.connect(lambda: self.set_all_checked(False)) + controls.addWidget(self.select_all_button) + controls.addWidget(self.clear_button) + controls.addStretch(1) + buttons = QDialogButtonBox( QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel, parent=self ) @@ -86,10 +97,16 @@ class ScanSelectionDialog(QDialog): layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(4) + layout.addLayout(controls) layout.addWidget(self.scan_list) layout.addWidget(buttons) self.resize(360, 420) + def set_all_checked(self, checked: bool) -> None: + """Check or uncheck every scan in the list.""" + for checkbox in self._scan_checkboxes.values(): + checkbox.setChecked(checked) + def checkbox_for_scan(self, scan_name: str) -> QCheckBox: """Return the checkbox belonging to ``scan_name``.""" return self._scan_checkboxes[scan_name] diff --git a/tests/unit_tests/test_scan_control.py b/tests/unit_tests/test_scan_control.py index bc07ef67..141e4a92 100644 --- a/tests/unit_tests/test_scan_control.py +++ b/tests/unit_tests/test_scan_control.py @@ -468,6 +468,36 @@ def test_scan_selector_settings_dialog_is_released_after_use(scan_control, monke delete_later.assert_called_once() +def test_scan_selector_dialog_select_all_and_clear_buttons(qtbot): + dialog = ScanSelectionDialog( + scan_names=["line_scan", "grid_scan"], selected_scans=["line_scan"] + ) + qtbot.addWidget(dialog) + dialog.show() + qtbot.waitExposed(dialog) + + qtbot.mouseClick(dialog.select_all_button, Qt.MouseButton.LeftButton) + assert dialog.selected_scans() == ["line_scan", "grid_scan"] + + qtbot.mouseClick(dialog.clear_button, Qt.MouseButton.LeftButton) + assert dialog.selected_scans() == [] + + +def test_scan_selector_dialog_select_all_clears_the_filter(scan_control, monkeypatch, qtbot): + scan_control.allowed_scans = ["line_scan"] + + def select_all(dialog): + dialog.set_all_checked(True) + return QDialog.DialogCode.Accepted + + monkeypatch.setattr(ScanSelectionDialog, "exec", select_all) + + qtbot.mouseClick(scan_control.scan_selector_settings_button, Qt.MouseButton.LeftButton) + + assert scan_control.allowed_scans is None + assert scan_control.comboBox_scan_selection.count() == 2 + + def test_scan_selector_dialog_whole_row_click_toggles_checkbox(qtbot): dialog = ScanSelectionDialog( scan_names=["line_scan", "grid_scan"], selected_scans=["line_scan"]