# Window.py -- Pamhyr # Copyright (C) 2023-2025 INRAE # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -*- coding: utf-8 -*- from tools import trace, timer from View.Tools.PamhyrWindow import PamhyrWindow from PyQt5.QtGui import ( QKeySequence, ) from PyQt5.QtCore import ( Qt, QVariant, QAbstractTableModel, QCoreApplication, QModelIndex, QRect, QThread, pyqtSlot, pyqtSignal, ) from PyQt5.QtWidgets import ( QDialogButtonBox, QPushButton, QLineEdit, QFileDialog, QTableView, QAbstractItemView, QUndoStack, QShortcut, QAction, QItemDelegate, QComboBox, QVBoxLayout, QHeaderView, QTabWidget, QProgressBar, QLabel, ) from View.CheckList.Table import TableModel from View.CheckList.Worker import Worker from View.CheckList.Translate import CheckListTranslate _translate = QCoreApplication.translate class CheckListWindow(PamhyrWindow): _pamhyr_ui = "CheckList" _pamhyr_name = "Check list" signalStatus = pyqtSignal(str) def __init__(self, autorun: bool = True, study=None, config=None, solver=None, parent=None): trad = CheckListTranslate() self._autorun = autorun self._solver = solver name = trad[self._pamhyr_name] + " - " + study.name super(CheckListWindow, self).__init__( title=name, study=study, config=config, trad=trad, options=[], parent=parent ) # Add solver to hash computation data self._hash_data.append(self._solver) self._checker_list = ( self._study.checkers() + self._solver.checkers() ) self.setup_table() self.setup_progress_bar() self.setup_connections() self.setup_thread() self.setup_statusbar() def setup_table(self): table = self.find(QTableView, f"tableView") self._table = TableModel( table_view=table, table_headers=self._trad.get_dict("table_headers"), data=self._checker_list, ) def setup_progress_bar(self): self._progress = self.find(QProgressBar, f"progressBar") self._p = 0 # Progress current step self._progress.setRange(0, len(self._checker_list)) self._progress.setValue(self._p) def setup_connections(self): self.find(QPushButton, "pushButton_ok").clicked.connect(self.accept) self.find(QPushButton, "pushButton_retry").clicked.connect(self.retry) self.find(QPushButton, "pushButton_cancel")\ .clicked.connect(self.reject) def setup_thread(self): self._worker = Worker(self._study, self._checker_list) self._worker_thread = QThread() self._worker.moveToThread(self._worker_thread) # Connect any worker signals self._worker.signalStatus.connect(self.update) self._worker_thread.started.connect(self._worker.process) self._worker_thread.start() def retry(self): self._worker_thread.terminate() self._worker_thread.wait() self.find(QPushButton, "pushButton_retry").setEnabled(False) self.find(QPushButton, "pushButton_ok").setEnabled(False) self.setup_thread() def _compute_status(self): ok = len(list(filter(lambda c: c.is_ok(), self._checker_list))) warning = len( list(filter(lambda c: c.is_warning(), self._checker_list))) error = len(list(filter(lambda c: c.is_error(), self._checker_list))) return ok, warning, error def _compute_status_label(self): ok, warning, error = self._compute_status() return (f"Ok: {ok} |" + f"Warning: {warning} |" + f"Error: {error}") def setup_statusbar(self): txt = self._compute_status_label() self._status_label = QLabel(txt) self.statusbar.addPermanentWidget(self._status_label) def update_statusbar(self): txt = self._compute_status_label() self._status_label.setText(txt) def progress(self): self._p += 1 self._progress.setValue(self._p) self._table.update() def start_compute(self): self._p = 0 self._progress.setValue(self._p) def info_compute(self, str): self.statusbar.showMessage(str, 3000) def end_compute(self): self._table.layoutChanged.emit() self.find(QPushButton, "pushButton_retry").setEnabled(True) errors = any(filter(lambda c: c.is_error(), self._checker_list)) if not errors: self.find(QPushButton, "pushButton_ok").setEnabled(True) if self._autorun: self._parent.solver_log(self._solver) self.end() self.update_statusbar() def update(self, key: str): if key == "start": self.start_compute() self.info_compute("Starting ...") elif key == "end": self.info_compute("Finish") self.end_compute() elif key == "progress": self.progress() else: self.info_compute(key) self.update_statusbar() def end(self): # self._worker.join()b self.close() def reject(self): self.end() def accept(self): self._parent.solver_log(self._solver) # self.end()