Forked from HYCAR-Hydro / airGR
Source project has a limited visibility.
Window.py 7.78 KiB
# Window.py -- Pamhyr
# Copyright (C) 2023-2024  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 <https://www.gnu.org/licenses/>.

# -*- coding: utf-8 -*-

import os
import logging

from tools import trace, timer, logger_exception

from View.Tools.PamhyrWindow import PamhyrWindow

from PyQt5.QtGui import (
    QKeySequence, QIcon,
)

from PyQt5.QtCore import (
    Qt, QVariant, QAbstractTableModel,
    QCoreApplication, QModelIndex, pyqtSlot,
    QRect, QItemSelectionModel,
)

from PyQt5.QtWidgets import (
    QDialogButtonBox, QPushButton, QLineEdit,
    QFileDialog, QTableView, QAbstractItemView,
    QUndoStack, QShortcut, QAction, QItemDelegate,
    QComboBox, QVBoxLayout, QHeaderView, QTabWidget,
    QVBoxLayout, QToolBar, QAction, QToolButton,
)

from Modules import Modules

from View.InitialConditionsAdisTS.UndoCommand import (
    SetCommand,
)

from View.D90AdisTS.TableDefault import (
    D90TableDefaultModel,
)

from View.D90AdisTS.Table import (
    D90TableModel, ComboBoxDelegate,
)

from View.D90AdisTS.translate import D90AdisTSTranslate

from Solver.Mage import Mage8

_translate = QCoreApplication.translate

logger = logging.getLogger()


class D90AdisTSWindow(PamhyrWindow):
    _pamhyr_ui = "D90AdisTS"
    _pamhyr_name = "D90 AdisTS"

    def __init__(self, data=None, study=None, config=None, parent=None):
        self._data = []
        self._data.append(data)
        trad = D90AdisTSTranslate()

        name = (
            trad[self._pamhyr_name] +
            " - " + study.name +
            " - " + self._data[0].name
        )

        super(D90AdisTSWindow, self).__init__(
            title=name,
            study=study,
            config=config,
            trad=trad,
            parent=parent
        )

        self._hash_data.append(data)

        self._d90_adists_lst = study.river.d90_adists

        self.setup_table()

        self.ui.setWindowTitle(self._title)

    def setup_table(self):

        path_icons = os.path.join(self._get_ui_directory(), f"ressources")

        table_default = self.find(QTableView, f"tableView")

        self._table = D90TableDefaultModel(
            table_view=table_default,
            table_headers=self._trad.get_dict("table_headers"),
            editable_headers=["name", "d90"],
            delegates={},
            data=self._data,
            undo=self._undo_stack,
            trad=self._trad
        )

        table_default.setModel(self._table)
        table_default.setSelectionBehavior(QAbstractItemView.SelectRows)
        table_default.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        table_default.setAlternatingRowColors(True)

        layout = self.find(QVBoxLayout, f"verticalLayout_1")
        toolBar = QToolBar()
        layout.addWidget(toolBar)

        action_add = QAction(self)
        action_add.setIcon(QIcon(os.path.join(path_icons, f"add.png")))
        action_add.triggered.connect(self.add)
        action_delete = QAction(self)
        action_delete.setIcon(QIcon(os.path.join(path_icons, f"del.png")))
        action_delete.triggered.connect(self.delete)

        toolBar.addAction(action_add)
        toolBar.addAction(action_delete)

        self.table_spec = QTableView()
        layout.addWidget(self.table_spec)

        self._delegate_reach = ComboBoxDelegate(
            trad=self._trad,
            data=self._study.river,
            ic_spec_lst=self._data[0]._data,
            parent=self,
            mode="reaches"
        )
        self._delegate_rk = ComboBoxDelegate(
            trad=self._trad,
            data=self._study.river,
            ic_spec_lst=self._data[0]._data,
            parent=self,
            mode="rk"
        )

        self._table_spec = D90TableModel(
            table_view=self.table_spec,
            table_headers=self._trad.get_dict("table_headers_spec"),
            editable_headers=["name", "reach", "start_rk", "end_rk", "d90"],
            delegates={
                "reach": self._delegate_reach,
                "start_rk": self._delegate_rk,
                "end_rk": self._delegate_rk
            },
            data=self._data[0],
            undo=self._undo_stack,
            trad=self._trad,
            river=self._study.river
        )

        self.table_spec.setModel(self._table_spec)
        self.table_spec.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_spec.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.table_spec.setAlternatingRowColors(True)

        selectionModel = self.table_spec.selectionModel()
        index = self.table_spec.model().index(0, 0)

        selectionModel.select(
            index,
            QItemSelectionModel.Rows |
            QItemSelectionModel.ClearAndSelect |
            QItemSelectionModel.Select
        )
        self.table_spec.scrollTo(index)

    def index_selected_row(self):
        #table = self.find(QTableView, f"tableView")
        table = self.table_spec
        rows = table.selectionModel()\
                    .selectedRows()

        if len(rows) == 0:
            return 0

        return rows[0].row()

    def index_selected_rows(self):
        #table = self.find(QTableView, f"tableView")
        table = self.table_spec
        return list(
            # Delete duplicate
            set(
                map(
                    lambda i: i.row(),
                    table.selectedIndexes()
                )
            )
        )

    def move_up(self):
        row = self.index_selected_row()
        self._table.move_up(row)
        self._update()

    def move_down(self):
        row = self.index_selected_row()
        self._table.move_down(row)
        self._update()

    def _copy(self):
        rows = list(
            map(
                lambda row: row.row(),
                self.tableView.selectionModel().selectedRows()
            )
        )

        table = list(
            map(
                lambda eic: list(
                    map(
                        lambda k: eic[1][k],
                        ["rk", "discharge", "elevation"]
                    )
                ),
                filter(
                    lambda eic: eic[0] in rows,
                    enumerate(self._ics.lst())
                )
            )
        )

        self.copyTableIntoClipboard(table)

    def _paste(self):
        header, data = self.parseClipboardTable()

        if len(data) + len(header) == 0:
            return

        logger.debug(
            "D90: Paste: " +
            f"header = {header}, " +
            f"data = {data}"
        )

        try:
            row = self.index_selected_row()
            # self._table.paste(row, header, data)
            self._table.paste(row, [], data)
        except Exception as e:
            logger_exception(e)

        self._update()

    def _undo(self):
        self._table.undo()
        self._update()

    def _redo(self):
        self._table.redo()
        self._update()

    def add(self):
        rows = self.index_selected_rows()
        if len(self._data[0]._data) == 0 or len(rows) == 0:
            self._table_spec.add(0)
        else:
            self._table_spec.add(rows[0])

    def delete(self):
        print("del")
        rows = self.index_selected_rows()
        if len(rows) == 0:
            print("len 0")
            return
        self._table_spec.delete(rows)