diff --git a/src/aare/gui/panels/tell_sample_panel.py b/src/aare/gui/panels/tell_sample_panel.py index de664539..9e640b7b 100644 --- a/src/aare/gui/panels/tell_sample_panel.py +++ b/src/aare/gui/panels/tell_sample_panel.py @@ -237,6 +237,16 @@ class TellSamplePanel(QFrame): # handler only uses the row, which both views share). self.table_view.frozen.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.table_view.frozen.customContextMenuRequested.connect(self.context_menu) + # "#" holds no sortable data; clicking its header selects all rows + # instead (Ctrl+A) — the quick way to act on everything visible. + # The frozen overlay owns the visible "#" header (not sorting-enabled, + # so its sections need explicit clickability); the main header is + # connected too in case the overlay is ever dropped. + self.table_view.frozen.horizontalHeader().setSectionsClickable(True) + self.table_view.frozen.horizontalHeader().sectionClicked.connect( + self._select_all_from_status_header + ) + header.sectionClicked.connect(self._select_all_from_status_header) header.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) header.customContextMenuRequested.connect(self.header_context_menu) @@ -292,6 +302,17 @@ class TellSamplePanel(QFrame): chip.setChecked(True) return + @Slot(int) + def _select_all_from_status_header(self, section: int) -> None: + if section != COL_STATUS: + return + self.table_view.selectAll() + # The click also dragged the sort indicator onto "#" (the model + # ignores sorting there) — put it back where the data actually is. + self.table_view.horizontalHeader().setSortIndicator( + self.table_model._sort_col, self.table_model._sort_order + ) + def _selected_samples(self, clicked_row: int) -> list[SampleShortInfo]: """Selected rows if the clicked row is part of the selection, else just the clicked row — so right-click on an unselected row acts on it.""" diff --git a/tests/unit/gui/test_tell_sample_panel.py b/tests/unit/gui/test_tell_sample_panel.py index c8882ad9..2774afb0 100644 --- a/tests/unit/gui/test_tell_sample_panel.py +++ b/tests/unit/gui/test_tell_sample_panel.py @@ -124,6 +124,16 @@ def test_queue_drop_chip_accepts_sample_payloads(panel, qtbot, samples): chip.dropEvent(drop(bad)) +def test_status_header_click_selects_all(panel): + header = panel.table_view.frozen.horizontalHeader() + header.sectionClicked.emit(0) + assert len(panel.table_view.selectionModel().selectedRows()) == 3 + # Other sections keep their normal sort-click behavior. + panel.table_view.clearSelection() + header.sectionClicked.emit(1) + assert len(panel.table_view.selectionModel().selectedRows()) == 0 + + def test_selected_samples_follow_the_click(panel): view = panel.table_view view.selectRow(0)