diff --git a/src/aare/gui/main_window.py b/src/aare/gui/main_window.py index 99a437e6..cc254268 100644 --- a/src/aare/gui/main_window.py +++ b/src/aare/gui/main_window.py @@ -593,6 +593,10 @@ class MainWindow(QMainWindow): # click is caught in eventFilter via the geometric tabAt() instead. self.sample_lists_tabs.tabBar().installEventFilter(self) + # Tracks beamline-state TRANSITIONS for the default sample-tab switch + # (see _apply_default_sample_tab). + self._last_beamline_state: BeamlineStateEnum | None = None + # Wrapper for the left inset: QTabWidget ignores its own contents # margins for the tab bar, so the padding lives one level up. Aligns # the panel's left edge with the left column above (Loop centering). @@ -2554,11 +2558,37 @@ class MainWindow(QMainWindow): for widget in hide_in_watch_mode + self.findChildren(QDockWidget): widget.hide() + # Alignment/maintenance states mount reference pins, so the sample dock + # defaults to the Auxiliary puck there; every other state defaults back + # to the Dewar list. + _AUX_PUCK_STATES = frozenset( + { + BeamlineStateEnum.Maintenance, + BeamlineStateEnum.BeamLocation, + BeamlineStateEnum.BeamstopAlignment, + BeamlineStateEnum.FluxMeasurement, + } + ) + + def _apply_default_sample_tab(self, state: BeamlineStateEnum | None) -> None: + # Index 1 = Auxiliary puck; disabled for non-staff, never force it. + if state in self._AUX_PUCK_STATES and self.sample_lists_tabs.isTabEnabled(1): + self.sample_lists_tabs.setCurrentIndex(1) + else: + self.sample_lists_tabs.setCurrentIndex(0) + @Slot(DAQStatusModel) def update_daq_status(self, s: DAQStatusModel): self._latest_daq_status = s self._apply_session_gate(getattr(getattr(s, "session", None), "session", None)) + # Default tab only on state TRANSITIONS — a manual tab choice + # survives while the state stays put. + new_beamline_state = getattr(s, "state", None) + if new_beamline_state != self._last_beamline_state: + self._last_beamline_state = new_beamline_state + self._apply_default_sample_tab(new_beamline_state) + if self._is_automation_active(): self._refresh_idle_activity(report_backend=False) diff --git a/src/aare/gui/panels/reference_tools_panel.py b/src/aare/gui/panels/reference_tools_panel.py index de489191..8710db23 100644 --- a/src/aare/gui/panels/reference_tools_panel.py +++ b/src/aare/gui/panels/reference_tools_panel.py @@ -40,7 +40,10 @@ class ReferenceToolsModel(QAbstractTableModel): self.samples: list[SampleShortInfo] = rows or [] self.current_reference = current_reference + # Column 0 is display-only: the row position ("#"), matching the + # Dewar samples table; the vertical header is hidden in the panel. self.header = [ + "#", "Position", "Sample name", "Mount count", @@ -48,7 +51,7 @@ class ReferenceToolsModel(QAbstractTableModel): "Rotation count", "Screening count", ] - self._sort_col = 0 + self._sort_col = 1 self._sort_order = Qt.SortOrder.AscendingOrder self._sorted_samples: list[SampleShortInfo] = [] if self.samples: @@ -70,7 +73,9 @@ class ReferenceToolsModel(QAbstractTableModel): return None if role == Qt.ItemDataRole.DisplayRole: - return get_entry(self._sorted_samples[index.row()], index.column()) + if index.column() == 0: + return str(index.row() + 1) + return get_entry(self._sorted_samples[index.row()], index.column() - 1) elif role == Qt.ItemDataRole.TextAlignmentRole: return Qt.AlignmentFlag.AlignCenter elif role == Qt.ItemDataRole.BackgroundRole: @@ -109,6 +114,9 @@ class ReferenceToolsModel(QAbstractTableModel): self.endResetModel() def sort(self, column, order): + # The "#" column is display-only — nothing to sort by. + if column == 0: + return self.layoutAboutToBeChanged.emit() self._sort_order = order self._sort_col = column @@ -121,14 +129,14 @@ class ReferenceToolsModel(QAbstractTableModel): self._sorted_samples = [] return - if self._sort_col == 0: + if self._sort_col == 1: # Special sorting for location (Position column) self._sorted_samples = sorted( self.samples, key=lambda row: row.loc_str_sort(), reverse=(self._sort_order == Qt.SortOrder.DescendingOrder), ) - elif self._sort_col == 2: + elif self._sort_col == 3: # Numeric sort for Mount count; place None last on ascending, first on descending none_sentinel = ( float("inf") if self._sort_order == Qt.SortOrder.AscendingOrder else float("-inf") @@ -141,10 +149,11 @@ class ReferenceToolsModel(QAbstractTableModel): reverse=(self._sort_order == Qt.SortOrder.DescendingOrder), ) else: - # String sort with empty fallback + # String sort with empty fallback (get_entry columns sit one left + # of the view columns because of the display-only "#"). self._sorted_samples = sorted( self.samples, - key=lambda row: get_entry(row, self._sort_col) or "", + key=lambda row: get_entry(row, self._sort_col - 1) or "", reverse=(self._sort_order == Qt.SortOrder.DescendingOrder), ) @@ -221,7 +230,9 @@ class ReferenceToolsPanel(QFrame): header.setStretchLastSection(True) # No bold column titles when cells are selected. header.setHighlightSections(False) - self.table_view.verticalHeader().setVisible(True) + # Row numbers live in the display-only "#" column (like the Dewar + # table), not the vertical header. + self.table_view.verticalHeader().setVisible(False) logger.debug("Setting up table view sorting") # Adopt the model's current order first — a second panel on a shared # model must not re-sort it on open.