diff --git a/gui/src/aaregui/panels/sample_queue_panel.py b/gui/src/aaregui/panels/sample_queue_panel.py index 91ebc47f..0f50c670 100644 --- a/gui/src/aaregui/panels/sample_queue_panel.py +++ b/gui/src/aaregui/panels/sample_queue_panel.py @@ -5,6 +5,7 @@ from PySide6.QtGui import QKeySequence, QShortcut from aaredaqlib.models import SampleShortInfoList, SampleShortInfo from aaregui.models.sample_queue_model import SampleQueueSpreadsheet +from aaregui.threads.automation_worker import FSMWorker from aaregui.widgets.title_label import TitleLabel @@ -128,3 +129,171 @@ class SampleQueuePanel(QFrame): self.__pause = True self.play_button.setText("▶ Run") self._current_db_id = None + +# class MainWindow(QMainWindow): +# def __init__(self): +# super().__init__() +# self.setWindowTitle("FSM Queue Runner") +# self.resize(900, 400) +# +# # Sample queue - in a real app this is editable by user +# samples = [ +# Sample(id="S1"), +# Sample(id="S2"), +# Sample(id="S3"), +# ] +# self.queue = samples +# +# # server client: replace DummyServerClient with your actual client +# self.server = DummyServerClient() +# +# # UI pieces +# central = QWidget() +# layout = QVBoxLayout(central) +# +# # controls +# controls = QHBoxLayout() +# self.btn_start = QPushButton("Start") +# self.btn_pause = QPushButton("Pause") +# self.btn_resume = QPushButton("Resume") +# self.btn_stop = QPushButton("Stop") +# self.btn_next = QPushButton("Next Sample") +# controls.addWidget(self.btn_start) +# controls.addWidget(self.btn_pause) +# controls.addWidget(self.btn_resume) +# controls.addWidget(self.btn_stop) +# controls.addWidget(self.btn_next) +# +# layout.addLayout(controls) +# +# # table showing queue and state toggles +# self.table = QTableWidget(len(self.queue), 1 + len(ALL_STATES)) +# headers = ["Sample ID"] + [s.value for s in ALL_STATES] +# self.table.setHorizontalHeaderLabels(headers) +# self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) +# self._populate_table() +# +# layout.addWidget(self.table) +# +# # status label +# self.status_label = QLabel("Idle") +# layout.addWidget(self.status_label) +# +# self.setCentralWidget(central) +# +# # worker thread and object will be created on start +# self.worker_thread = None +# self.worker = None +# +# # connect buttons +# self.btn_start.clicked.connect(self.start_worker) +# self.btn_pause.clicked.connect(self._on_pause) +# self.btn_resume.clicked.connect(self._on_resume) +# self.btn_stop.clicked.connect(self._on_stop) +# self.btn_next.clicked.connect(self._on_next_sample) +# +# def _populate_table(self): +# for row, s in enumerate(self.queue): +# self.table.setItem(row, 0, QTableWidgetItem(s.id)) +# for col_idx, state in enumerate(ALL_STATES, start=1): +# cb = QCheckBox() +# cb.setChecked(s.run_states.get(state, True)) +# # store mapping from widget to sample/state +# cb.state_enum = state +# cb.sample_index = row +# cb.stateChanged.connect(self._make_checkbox_handler(cb)) +# self.table.setCellWidget(row, col_idx, cb) +# +# def _make_checkbox_handler(self, checkbox): +# def handler(_): +# row = checkbox.sample_index +# state = checkbox.state_enum +# checked = checkbox.isChecked() +# self.queue[row].run_states[state] = checked +# self.status_label.setText(f"Sample {self.queue[row].id}: set {state.value} -> {checked}") +# return handler +# +# def start_worker(self): +# if self.worker is not None: +# QMessageBox.warning(self, "Already running", "Worker is already running.") +# return +# +# # create worker & thread +# self.worker_thread = QThread() +# self.worker = FSMWorker(self.queue, self.server) +# self.worker.moveToThread(self.worker_thread) +# +# # connect thread start to worker.run +# self.worker_thread.started.connect(self.worker.run) +# # connect signals +# self.worker.progress.connect(self.on_progress) +# self.worker.state_changed.connect(self.on_state_changed) +# self.worker.error.connect(self.on_error) +# self.worker.sample_complete.connect(self.on_sample_complete) +# self.worker.finished.connect(self.on_finished) +# +# # start thread +# self.worker_thread.start() +# self.status_label.setText("Worker started.") +# +# @Slot(int, str) +# def on_progress(self, sample_idx, message): +# # update GUI (runs in GUI thread) +# if sample_idx >= 0: +# self.status_label.setText(f"[S{sample_idx}] {message}") +# else: +# self.status_label.setText(message) +# print("PROGRESS:", sample_idx, message) +# +# @Slot(int, str) +# def on_state_changed(self, sample_idx, state_name): +# # highlight table row, set status text +# self.status_label.setText(f"Sample {self.queue[sample_idx].id} - {state_name}") +# print("STATE_CHANGED:", sample_idx, state_name) +# +# @Slot(int, str) +# def on_error(self, sample_idx, err_msg): +# QMessageBox.critical(self, "Error", f"Sample {sample_idx}: {err_msg}") +# print("ERROR:", sample_idx, err_msg) +# +# @Slot(int) +# def on_sample_complete(self, sample_idx): +# print("SAMPLE COMPLETE:", sample_idx) +# +# @Slot() +# def on_finished(self): +# self.status_label.setText("Worker finished.") +# # clean up thread & worker +# try: +# self.worker_thread.quit() +# self.worker_thread.wait(timeout=1000) +# except Exception: +# pass +# self.worker = None +# self.worker_thread = None +# +# def _on_pause(self): +# if not self.worker: +# return +# # set pause flag on worker +# self.worker.request_pause() +# self.status_label.setText("Pause requested.") +# +# def _on_resume(self): +# if not self.worker: +# return +# self.worker.pause_requested = False +# self.worker.request_resume() +# self.status_label.setText("Resume requested.") +# +# def _on_stop(self): +# if not self.worker: +# return +# self.worker.request_stop() +# self.status_label.setText("Stop requested.") +# +# def _on_next_sample(self): +# if not self.worker: +# return +# self.worker.request_next_sample() +# self.status_label.setText("Next sample requested.")