# PamhyrTable.py -- Pamhyr abstract table model # Copyright (C) 2023 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 -*- import logging import traceback from tools import trace, timer from Model.Except import NotImplementedMethodeError from PyQt5.QtCore import ( Qt, QVariant, QAbstractTableModel, QCoreApplication, QModelIndex, pyqtSlot, QRect, ) from PyQt5.QtWidgets import ( QDialogButtonBox, QPushButton, QLineEdit, QFileDialog, QTableView, QAbstractItemView, QUndoStack, QShortcut, QAction, QItemDelegate, QComboBox, QStyledItemDelegate, QHeaderView, ) logger = logging.getLogger() class PamhyrTextDelegate(QStyledItemDelegate): def __init__(self, parent=None): super(PamhyrTextDelegate, self).__init__(parent) def createEditor(self, parent, option, index): index.model().data(index, Qt.DisplayRole) return QLineEdit(parent) def setEditorData(self, editor, index): value = index.model().data(index, Qt.DisplayRole) editor.setText(str(value)) def setModelData(self, editor, model, index): model.setData(index, editor.text()) def updateEditorGeometry(self, editor, option, index): editor.setGeometry(option.rect) class PamhyrTableModel(QAbstractTableModel): def _setup_delegates(self): if self._table_view is None: return for h in self._headers: if h in self._delegates: self._table_view.setItemDelegateForColumn( self._headers.index(h), self._delegates[h] ) else: self._table_view.setItemDelegateForColumn( self._headers.index(h), PamhyrTextDelegate( parent=self ) ) def __init__(self, table_view = None, table_headers = {}, editable_headers = [], delegates = {}, trad = None, data = None, undo = None, opt_data = None): super(PamhyrTableModel, self).__init__() self._table_view = table_view self._table_headers = table_headers self._headers = list(table_headers.keys()) self._editable_headers = editable_headers self._delegates = delegates self._trad = trad self._data = data self._opt_data = opt_data self._undo = undo self._lst = [] self._setup_delegates() self._setup_lst() self._table_view_configure() def _setup_lst(self): self._lst = self._data def _table_view_configure(self): self._table_view.setModel(self) self._table_view.setSelectionBehavior(QAbstractItemView.SelectRows) self._table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self._table_view.setAlternatingRowColors(True) self._table_view.resizeColumnsToContents() def flags(self, index): column = index.column() options = Qt.ItemIsEnabled | Qt.ItemIsSelectable if (self._editable_headers or self._headers[column] in self._editable_headers): options |= Qt.ItemIsEditable return options def rowCount(self, parent=QModelIndex()): return len(self._lst) def columnCount(self, parent=QModelIndex()): return len(self._headers) def headerData(self, section, orientation, role): if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal: return self._table_headers[self._headers[section]] return QVariant() def data(self, index, role): raise NotImplementedMethodeError(self, self.data) def setData(self, index, value, role=Qt.EditRole): raise NotImplementedMethodeError(self, self.setData) def undo(self): self._undo.undo() self.layoutChanged.emit() def redo(self): self._undo.redo() self.layoutChanged.emit() def update(self): self.layoutChanged.emit()