diff --git a/src/aare/gui/main_window.py b/src/aare/gui/main_window.py index 8963be34..e94cbc2a 100644 --- a/src/aare/gui/main_window.py +++ b/src/aare/gui/main_window.py @@ -596,6 +596,9 @@ class MainWindow(QMainWindow): # Tracks beamline-state TRANSITIONS for the default sample-tab switch # (see _apply_default_sample_tab). self._last_beamline_state: BeamlineStateEnum | None = None + # None = not yet evaluated, so the first status tick always applies + # the gate (the GUI may start while a visitor pgroup is active). + self._beamline_tab_gated: bool | 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 @@ -2578,10 +2581,33 @@ class MainWindow(QMainWindow): else: self.sample_lists_tabs.setCurrentIndex(0) + def _apply_pgroup_gate(self, pgroup: str | None) -> None: + # Switching to a pgroup outside the token's own (admin) pgroups means + # running a visitor's experiment: the Beamline tab is then off-limits, + # and the Experiment tab comes up with Dataset path + Exp. Config. + # open. Applied only on gate TRANSITIONS so a manual tab choice + # survives the 1 Hz status ticks. + gated = pgroup is not None and pgroup not in (self._decoded_token.pgroups or []) + if gated == self._beamline_tab_gated: + return + self._beamline_tab_gated = gated + self.left_column_tabs.setTabEnabled(0, not gated) + self.left_column_tabs.setTabToolTip( + 0, "Only accessible for beamline scientists" if gated else "" + ) + if gated: + self.left_column_tabs.setCurrentIndex(1) + # persist=False: programmatic open must not overwrite the user's + # saved per-panel collapse choice (same rule as the session gate). + for banner in self.data_collection.findChildren(TitleLabel): + if banner.text() in ("Dataset path", "Experiment configuration"): + banner.set_collapsed(False, persist=False) + @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)) + self._apply_pgroup_gate(getattr(getattr(s, "session", None), "current_pgroup", None)) # Default tab only on state TRANSITIONS — a manual tab choice # survives while the state stays put.