mirror of https://gitlab.com/pamhyr/pamhyr2
261 lines
7.8 KiB
Python
261 lines
7.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import time
|
|
from functools import reduce
|
|
from itertools import groupby
|
|
from operator import itemgetter
|
|
|
|
import numpy as np
|
|
import pandas as pd
|
|
|
|
from PyQt5 import (
|
|
QtGui, QtWidgets
|
|
)
|
|
from PyQt5.QtCore import (
|
|
Qt, QAbstractTableModel, QModelIndex,
|
|
QVariant, pyqtSlot, QCoreApplication,
|
|
)
|
|
from PyQt5.QtWidgets import (
|
|
QMessageBox, QUndoCommand, QUndoStack,
|
|
)
|
|
|
|
from Model.Geometry import Reach
|
|
from View.Geometry.ReachUndoCommand import *
|
|
|
|
|
|
_translate = QCoreApplication.translate
|
|
|
|
|
|
class PandasModelEditable(QAbstractTableModel):
|
|
def __init__(self, reach, headers=None):
|
|
QAbstractTableModel.__init__(self)
|
|
data_list = []
|
|
|
|
self._undo_stack = QUndoStack()
|
|
|
|
self._reach = reach
|
|
|
|
if headers is None:
|
|
self.headers = [
|
|
_translate("Geometry", "Name"),
|
|
_translate("Geometry", "Kp (m)"),
|
|
_translate("Geometry", "Type")
|
|
]
|
|
else:
|
|
self.headers = headers
|
|
|
|
def rowCount(self, parent=QModelIndex()):
|
|
return self._reach.number_profiles
|
|
|
|
def columnCount(self, parent=QModelIndex()):
|
|
return len(self.headers)
|
|
|
|
def data(self, index, role=Qt.DisplayRole):
|
|
if not index.isValid():
|
|
return QVariant()
|
|
|
|
if role == Qt.DisplayRole and index.column() == 0:
|
|
return self._reach.profile(index.row()).name
|
|
|
|
if role == Qt.DisplayRole and index.column() == 1:
|
|
kp = self._reach.profile(index.row()).kp
|
|
return f"{kp:.4f}"
|
|
|
|
if role == Qt.DisplayRole and index.column() == 2:
|
|
return self._reach.profile(index.row()).profile_type
|
|
|
|
if role == Qt.TextAlignmentRole:
|
|
return Qt.AlignHCenter | Qt.AlignVCenter
|
|
|
|
if role == Qt.ForegroundRole and index.column() == 0:
|
|
name = self._reach.profile(index.row()).name\
|
|
.strip()\
|
|
.lower()
|
|
if (name == "upstream" or name == "up" or
|
|
name == _translate("Geometry", "upstream")):
|
|
return QtGui.QColor("Green")
|
|
elif (name == "downstream" or name == "down" or
|
|
name == _translate("Geometry", "downstream")):
|
|
return QtGui.QColor("Red")
|
|
|
|
return QVariant()
|
|
|
|
def headerData(self, section, orientation, role=Qt.DisplayRole):
|
|
if role == Qt.DisplayRole:
|
|
if orientation == Qt.Horizontal:
|
|
if section < len(self.headers):
|
|
return self.headers[section]
|
|
else:
|
|
return str(section + 1)
|
|
|
|
return QVariant()
|
|
|
|
def setData(self, index, value, role=Qt.EditRole):
|
|
row = index.row()
|
|
column = index.column()
|
|
|
|
if role == Qt.EditRole and index.column() != 2:
|
|
if index.column() == 0:
|
|
self._undo_stack.push(
|
|
SetNameCommand(
|
|
self._reach, index.row(),
|
|
self._reach.profile(index.row()).name,
|
|
value
|
|
)
|
|
)
|
|
|
|
if index.column() == 1:
|
|
self._undo_stack.push(
|
|
SetKPCommand(
|
|
self._reach, index.row(),
|
|
self._reach.profile(index.row()).kp,
|
|
value
|
|
)
|
|
)
|
|
|
|
self.dataChanged.emit(index, index)
|
|
self.layoutChanged.emit()
|
|
|
|
return True
|
|
|
|
self.dataChanged.emit(index, index)
|
|
self.layoutChanged.emit()
|
|
|
|
return False
|
|
|
|
def index(self, row, column, parent=QModelIndex()):
|
|
if not self.hasIndex(row, column, parent):
|
|
return QModelIndex()
|
|
|
|
return self.createIndex(row, column, QModelIndex())
|
|
|
|
def flags(self, index):
|
|
flg = Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
|
|
|
if index.column() == 2:
|
|
return flg
|
|
else:
|
|
return Qt.ItemIsEditable | flg
|
|
|
|
# @QtCore.pyqtSlot()
|
|
def insert_row(self, row, parent=QModelIndex()):
|
|
self.beginInsertRows(parent, row, row - 1)
|
|
|
|
self._undo_stack.push(
|
|
AddCommand(
|
|
self._reach, row
|
|
)
|
|
)
|
|
|
|
self.endInsertRows()
|
|
self.layoutChanged.emit()
|
|
|
|
def remove_rows(self, list_row_selected, parent=QModelIndex()):
|
|
self.beginRemoveRows(parent, list_row_selected[0], list_row_selected[-1])
|
|
|
|
if len(list_row_selected) >= 1:
|
|
if len(list_row_selected) == 1:
|
|
self._reach.delete_profile(list_row_selected[0])
|
|
elif len(list_row_selected) > 1:
|
|
self._reach.delete_profile_rows(list_row_selected)
|
|
|
|
self.endRemoveRows()
|
|
self.layoutChanged.emit()
|
|
|
|
def sort_profiles(self, _reverse):
|
|
self.layoutAboutToBeChanged.emit()
|
|
|
|
self._undo_stack.push(
|
|
SortCommand(
|
|
self._reach, _reverse
|
|
)
|
|
)
|
|
|
|
self.layoutAboutToBeChanged.emit()
|
|
self.layoutChanged.emit()
|
|
|
|
def moveRowDown(self, row_to_move, parent=QModelIndex()):
|
|
target = row_to_move + 2
|
|
self.beginMoveRows(parent, row_to_move, row_to_move, parent, target)
|
|
|
|
self._reach.move_down_profile(row_to_move)
|
|
|
|
self.endMoveRows()
|
|
self.layoutChanged.emit()
|
|
|
|
def moveRowUp(self, row_to_move, parent=QModelIndex()):
|
|
target = row_to_move + 1
|
|
self.beginMoveRows(parent, row_to_move - 1, row_to_move - 1, parent, target)
|
|
|
|
self._reach.move_up_profile(row_to_move)
|
|
|
|
self.endMoveRows()
|
|
self.layoutChanged.emit()
|
|
|
|
def undo(self):
|
|
self._undo_stack.undo()
|
|
self.layoutChanged.emit()
|
|
|
|
def redo(self):
|
|
self._undo_stack.redo()
|
|
self.layoutChanged.emit()
|
|
|
|
|
|
class Delegate(QtWidgets.QStyledItemDelegate):
|
|
def __init__(self, parent=None, setModelDataEvent=None):
|
|
super(Delegate, self).__init__(parent)
|
|
self.setModelDataEvent = setModelDataEvent
|
|
|
|
def createEditor(self, parent, option, index):
|
|
index.model().data(index, Qt.DisplayRole)
|
|
return QtWidgets.QLineEdit(parent)
|
|
|
|
def setEditorData(self, editor, index):
|
|
value = index.model().data(index, Qt.DisplayRole) # DisplayRole
|
|
editor.setText(str(value)) # récupère la valeur de la cellule applique la méthode définie dans setData
|
|
|
|
def setModelData(self, editor, model, index):
|
|
model.setData(index, editor.text())
|
|
|
|
if not self.setModelDataEvent is None:
|
|
self.setModelDataEvent()
|
|
|
|
def updateEditorGeometry(self, editor, option, index):
|
|
editor.setGeometry(option.rect)
|
|
|
|
class Delegate1(QtWidgets.QStyledItemDelegate):
|
|
def __init__(self, owner, choices):
|
|
super().__init__(owner)
|
|
self.items = choices
|
|
|
|
def paint(self, painter, option, index):
|
|
if isinstance(self.parent(), QtWidgets.QAbstractItemView):
|
|
self.parent().openPersistentEditor(index)
|
|
super(Delegate1, self).paint(painter, option, index)
|
|
|
|
def createEditor(self, parent, option, index):
|
|
editor = QtWidgets.QComboBox(parent)
|
|
# editor.currentIndexChanged.connect(self.commit_editor)
|
|
editor.addItems(self.items)
|
|
return editor
|
|
|
|
def setEditorData(self, editor, index):
|
|
editor.blockSignals(True)
|
|
text = index.model().data(index, Qt.DisplayRole)
|
|
try:
|
|
i = self.items.index(text)
|
|
except ValueError:
|
|
i = 0
|
|
editor.setCurrentIndex(i)
|
|
editor.blockSignals(False)
|
|
|
|
def setModelData(self, editor, model, index):
|
|
model.setData(index, editor.currentText(), Qt.DisplayRole)
|
|
|
|
def updateEditorGeometry(self, editor, option, index):
|
|
editor.setGeometry(option.rect)
|
|
|
|
@pyqtSlot()
|
|
def currentIndexChanged(self):
|
|
self.commitData.emit(self.sender())
|