From 9d3830850c0f685c2706a95973e6707d6b70e219 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby <pierre-antoine.rouby@inrae.fr> Date: Thu, 4 May 2023 16:08:19 +0200 Subject: [PATCH] BC: New file Table. --- .../BoundaryConditionWindow.py | 216 +---------------- src/View/BoundaryCondition/Table.py | 225 ++++++++++++++++++ src/View/BoundaryCondition/translate.py | 19 ++ 3 files changed, 249 insertions(+), 211 deletions(-) create mode 100644 src/View/BoundaryCondition/Table.py diff --git a/src/View/BoundaryCondition/BoundaryConditionWindow.py b/src/View/BoundaryCondition/BoundaryConditionWindow.py index 0688b700..d1597c13 100644 --- a/src/View/BoundaryCondition/BoundaryConditionWindow.py +++ b/src/View/BoundaryCondition/BoundaryConditionWindow.py @@ -33,221 +33,15 @@ from Model.BoundaryCondition.BoundaryConditionTypes import ( TimeOverZ, TimeOverDebit, ZOverDebit ) -from View.BoundaryCondition.translate import long_types +from View.BoundaryCondition.Table import ( + TableModel, ComboBoxDelegate +) + +from View.BoundaryCondition.translate import * from View.BoundaryCondition.Edit.Window import EditBoundaryConditionWindow _translate = QCoreApplication.translate -table_headers = { - "name": _translate("BoundaryCondition", "Name"), - "type": _translate("BoundaryCondition", "Type"), - "node": _translate("BoundaryCondition", "Node") -} - -BC_types = { - "ND": NotDefined, - "PC": PonctualContribution, - "TZ": TimeOverZ, - "TD": TimeOverDebit, - "ZD": ZOverDebit -} - - -class ComboBoxDelegate(QItemDelegate): - def __init__(self, data=None, mode="type", parent=None): - super(ComboBoxDelegate, self).__init__(parent) - - self._data = data - self._mode = mode - - def createEditor(self, parent, option, index): - self.editor = QComboBox(parent) - - if self._mode == "type": - self.editor.addItems([long_types[k] for k in BC_types.keys()]) - else: - self.editor.addItems( - [_translate("BoundaryCondition", "Not associate")] + - self._data.nodes_names() - ) - - self.editor.setCurrentText(index.data(Qt.DisplayRole)) - return self.editor - - def setEditorData(self, editor, index): - value = index.data(Qt.DisplayRole) - self.editor.currentTextChanged.connect(self.currentItemChanged) - - def setModelData(self, editor, model, index): - text = str(editor.currentText()) - model.setData(index, text) - editor.close() - editor.deleteLater() - - def updateEditorGeometry(self, editor, option, index): - r = QRect(option.rect) - if self.editor.windowFlags() & Qt.Popup and editor.parent() is not None: - r.setTopLeft(self.editor.parent().mapToGlobal(r.topLeft())) - editor.setGeometry(r) - - @pyqtSlot() - def currentItemChanged(self): - self.commitData.emit(self.sender()) - - -class TableModel(QAbstractTableModel): - def __init__(self, data=None, undo=None): - super(QAbstractTableModel, self).__init__() - self._headers = list(table_headers.keys()) - self._data = data - self._undo = undo - self._lst = self._data.boundary_condition - - def flags(self, index): - options = Qt.ItemIsEnabled | Qt.ItemIsSelectable - options |= Qt.ItemIsEditable - - return options - - def rowCount(self, parent): - return len(self._lst) - - def columnCount(self, parent): - return len(self._headers) - - def data(self, index, role): - if role != Qt.ItemDataRole.DisplayRole: - return QVariant() - - row = index.row() - column = index.column() - - if self._headers[column] == "name": - return self._lst[row].name - elif self._headers[column] == "type": - t = self._lst[row].bctype - return long_types[t] - elif self._headers[column] == "node": - n = self._lst[row].node - if n is None: - return _translate("BoundaryCondition", "Not associate") - return n.name - - return QVariant() - - def headerData(self, section, orientation, role): - if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal: - return table_headers[self._headers[section]] - - return QVariant() - - def setData(self, index, value, role=Qt.EditRole): - if not index.isValid() or role != Qt.EditRole: - return False - - row = index.row() - column = index.column() - - if self._headers[column] == "name": - self._undo.push( - SetNameCommand( - self._lst, row, value - ) - ) - elif self._headers[column] == "type": - key = next(k for k, v in long_types.items() if v == value) - self._undo.push( - SetTypeCommand( - self._lst, row, BC_types[key] - ) - ) - elif self._headers[column] == "node": - self._undo.push( - SetNodeCommand( - self._lst, row, self._data.node(value) - ) - ) - - self.dataChanged.emit(index, index) - return True - - def add(self, row, parent=QModelIndex()): - self.beginInsertRows(parent, row, row - 1) - - self._undo.push( - AddCommand( - self._lst, row - ) - ) - - self.endInsertRows() - self.layoutChanged.emit() - - def delete(self, rows, parent=QModelIndex()): - self.beginRemoveRows(parent, rows[0], rows[-1]) - - self._undo.push( - DelCommand( - self._lst, rows - ) - ) - - self.endRemoveRows() - - def sort(self, _reverse, parent=QModelIndex()): - self.layoutAboutToBeChanged.emit() - - self._undo.push( - SortCommand( - self._lst, False - ) - ) - - self.layoutAboutToBeChanged.emit() - self.layoutChanged.emit() - - def move_up(self, row, parent=QModelIndex()): - if row <= 0: - return - - target = row + 2 - - self.beginMoveRows(parent, row - 1, row - 1, parent, target) - - self._undo_stack.push( - MoveCommand( - self._lst, "up", row - ) - ) - - self.endMoveRows() - self.layoutChanged.emit() - - def move_down(self, index, parent=QModelIndex()): - if row > len(self._lst): - return - - target = row - - self.beginMoveRows(parent, row + 1, row + 1, parent, target) - - self._undo_stack.push( - MoveCommand( - self._lst, "down", row - ) - ) - - self.endMoveRows() - self.layoutChanged.emit() - - def undo(self): - self._undo.undo() - self.layoutChanged.emit() - - def redo(self): - self._undo.redo() - self.layoutChanged.emit() - class BoundaryConditionWindow(ASubMainWindow, ListedSubWindow): def __init__(self, title="BoundaryConditions", study=None, parent=None): diff --git a/src/View/BoundaryCondition/Table.py b/src/View/BoundaryCondition/Table.py new file mode 100644 index 00000000..850d3b21 --- /dev/null +++ b/src/View/BoundaryCondition/Table.py @@ -0,0 +1,225 @@ +# -*- coding: utf-8 -*- + +from tools import trace, timer + +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, +) + +from View.BoundaryCondition.BCUndoCommand import ( + SetNameCommand, SetNodeCommand, SetTypeCommand, + AddCommand, DelCommand, SortCommand, + MoveCommand, PasteCommand, DuplicateCommand, +) + +from Model.BoundaryCondition.BoundaryConditionTypes import ( + NotDefined, PonctualContribution, + TimeOverZ, TimeOverDebit, ZOverDebit +) +from View.BoundaryCondition.translate import * + +_translate = QCoreApplication.translate + +class ComboBoxDelegate(QItemDelegate): + def __init__(self, data=None, mode="type", parent=None): + super(ComboBoxDelegate, self).__init__(parent) + + self._data = data + self._mode = mode + + def createEditor(self, parent, option, index): + self.editor = QComboBox(parent) + + if self._mode == "type": + self.editor.addItems([long_types[k] for k in BC_types.keys()]) + else: + self.editor.addItems( + [_translate("BoundaryCondition", "Not associate")] + + self._data.nodes_names() + ) + + self.editor.setCurrentText(index.data(Qt.DisplayRole)) + return self.editor + + def setEditorData(self, editor, index): + value = index.data(Qt.DisplayRole) + self.editor.currentTextChanged.connect(self.currentItemChanged) + + def setModelData(self, editor, model, index): + text = str(editor.currentText()) + model.setData(index, text) + editor.close() + editor.deleteLater() + + def updateEditorGeometry(self, editor, option, index): + r = QRect(option.rect) + if self.editor.windowFlags() & Qt.Popup and editor.parent() is not None: + r.setTopLeft(self.editor.parent().mapToGlobal(r.topLeft())) + editor.setGeometry(r) + + @pyqtSlot() + def currentItemChanged(self): + self.commitData.emit(self.sender()) + + +class TableModel(QAbstractTableModel): + def __init__(self, data=None, undo=None): + super(QAbstractTableModel, self).__init__() + self._headers = list(table_headers.keys()) + self._data = data + self._undo = undo + self._lst = self._data.boundary_condition + + def flags(self, index): + options = Qt.ItemIsEnabled | Qt.ItemIsSelectable + options |= Qt.ItemIsEditable + + return options + + def rowCount(self, parent): + return len(self._lst) + + def columnCount(self, parent): + return len(self._headers) + + def data(self, index, role): + if role != Qt.ItemDataRole.DisplayRole: + return QVariant() + + row = index.row() + column = index.column() + + if self._headers[column] == "name": + return self._lst[row].name + elif self._headers[column] == "type": + t = self._lst[row].bctype + return long_types[t] + elif self._headers[column] == "node": + n = self._lst[row].node + if n is None: + return _translate("BoundaryCondition", "Not associate") + return n.name + + return QVariant() + + def headerData(self, section, orientation, role): + if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal: + return table_headers[self._headers[section]] + + return QVariant() + + def setData(self, index, value, role=Qt.EditRole): + if not index.isValid() or role != Qt.EditRole: + return False + + row = index.row() + column = index.column() + + if self._headers[column] == "name": + self._undo.push( + SetNameCommand( + self._lst, row, value + ) + ) + elif self._headers[column] == "type": + key = next(k for k, v in long_types.items() if v == value) + self._undo.push( + SetTypeCommand( + self._lst, row, BC_types[key] + ) + ) + elif self._headers[column] == "node": + self._undo.push( + SetNodeCommand( + self._lst, row, self._data.node(value) + ) + ) + + self.dataChanged.emit(index, index) + return True + + def add(self, row, parent=QModelIndex()): + self.beginInsertRows(parent, row, row - 1) + + self._undo.push( + AddCommand( + self._lst, row + ) + ) + + self.endInsertRows() + self.layoutChanged.emit() + + def delete(self, rows, parent=QModelIndex()): + self.beginRemoveRows(parent, rows[0], rows[-1]) + + self._undo.push( + DelCommand( + self._lst, rows + ) + ) + + self.endRemoveRows() + + def sort(self, _reverse, parent=QModelIndex()): + self.layoutAboutToBeChanged.emit() + + self._undo.push( + SortCommand( + self._lst, False + ) + ) + + self.layoutAboutToBeChanged.emit() + self.layoutChanged.emit() + + def move_up(self, row, parent=QModelIndex()): + if row <= 0: + return + + target = row + 2 + + self.beginMoveRows(parent, row - 1, row - 1, parent, target) + + self._undo_stack.push( + MoveCommand( + self._lst, "up", row + ) + ) + + self.endMoveRows() + self.layoutChanged.emit() + + def move_down(self, index, parent=QModelIndex()): + if row > len(self._lst): + return + + target = row + + self.beginMoveRows(parent, row + 1, row + 1, parent, target) + + self._undo_stack.push( + MoveCommand( + self._lst, "down", row + ) + ) + + self.endMoveRows() + self.layoutChanged.emit() + + def undo(self): + self._undo.undo() + self.layoutChanged.emit() + + def redo(self): + self._undo.redo() + self.layoutChanged.emit() diff --git a/src/View/BoundaryCondition/translate.py b/src/View/BoundaryCondition/translate.py index bcd1be54..762ca867 100644 --- a/src/View/BoundaryCondition/translate.py +++ b/src/View/BoundaryCondition/translate.py @@ -2,6 +2,11 @@ from PyQt5.QtCore import QCoreApplication +from Model.BoundaryCondition.BoundaryConditionTypes import ( + NotDefined, PonctualContribution, + TimeOverZ, TimeOverDebit, ZOverDebit +) + _translate = QCoreApplication.translate long_types = { @@ -11,3 +16,17 @@ long_types = { "TD": _translate("BoundaryCondition", "Time over Debit"), "ZD": _translate("BoundaryCondition", "Z over Debit"), } + +table_headers = { + "name": _translate("BoundaryCondition", "Name"), + "type": _translate("BoundaryCondition", "Type"), + "node": _translate("BoundaryCondition", "Node") +} + +BC_types = { + "ND": NotDefined, + "PC": PonctualContribution, + "TZ": TimeOverZ, + "TD": TimeOverDebit, + "ZD": ZOverDebit +} -- GitLab