# Table.py -- Pamhyr # 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 datetime import date, time, datetime, timedelta from tools import trace, timer from View.ASubWindow import ASubMainWindow, AWidget from View.ListedSubWindow import ListedSubWindow from View.Tools.PamhyrTable import PamhyrTableModel from PyQt5.QtCore import ( Qt, QVariant, QAbstractTableModel, QCoreApplication, QModelIndex, pyqtSlot, QRect, QTime, QDateTime, ) from PyQt5.QtWidgets import ( QTableView, QAbstractItemView, QSpinBox, QTimeEdit, QDateTimeEdit, QItemDelegate, ) from Model.LateralContribution.LateralContributionTypes import ( NotDefined, LateralContrib, Rain, Evaporation, ) from View.LateralContribution.Edit.UndoCommand import ( SetDataCommand, AddCommand, DelCommand, SortCommand, MoveCommand, PasteCommand, DuplicateCommand, ) from View.LateralContribution.Edit.translate import * _translate = QCoreApplication.translate logger = logging.getLogger() class TableModel(PamhyrTableModel): def data(self, index, role): if role == Qt.TextAlignmentRole: return Qt.AlignHCenter | Qt.AlignVCenter if role != Qt.ItemDataRole.DisplayRole: return QVariant() row = index.row() column = index.column() value = QVariant() if 0 <= column < 2: v = self._data.get_i(row)[column] if self._data.get_type_column(column) == float: value = f"{v:.4f}" elif self._data.header[column] == "time": if self._opt_data == "time": t0 = datetime.fromtimestamp(0) t = datetime.fromtimestamp(v) value = str(t - t0) else: value = str(datetime.fromtimestamp(v)) else: value = f"{v}" return value def setData(self, index, value, role=Qt.EditRole): if not index.isValid() or role != Qt.EditRole: return False row = index.row() column = index.column() try: self._undo.push( SetDataCommand( self._data, row, column, value ) ) except Exception as e: logger.info(e) logger.debug(traceback.format_exc()) self.dataChanged.emit(index, index) return True def add(self, row, parent=QModelIndex()): self.beginInsertRows(parent, row, row - 1) self._undo.push( AddCommand( self._data, row ) ) self.endInsertRows() self.layoutChanged.emit() def delete(self, rows, parent=QModelIndex()): self.beginRemoveRows(parent, rows[0], rows[-1]) self._undo.push( DelCommand( self._data, rows ) ) self.endRemoveRows() def sort(self, _reverse, parent=QModelIndex()): self.layoutAboutToBeChanged.emit() self._undo.push( SortCommand( self._data, _reverse ) ) 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._data, "up", row ) ) self.endMoveRows() self.layoutChanged.emit() def move_down(self, index, parent=QModelIndex()): if row > len(self._data): return target = row self.beginMoveRows(parent, row + 1, row + 1, parent, target) self._undo_stack.push( MoveCommand( self._data, "down", row ) ) self.endMoveRows() self.layoutChanged.emit() def paste(self, row, header, data): if len(data) == 0: return self.layoutAboutToBeChanged.emit() self._undo.push( PasteCommand( self._data, row, list( map( lambda d: self._data.new_from_data(header, d), data ) ) ) ) self.layoutAboutToBeChanged.emit() self.layoutChanged.emit()