Forked from HYCAR-Hydro / airGR
Source project has a limited visibility.
Window.py 8.00 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.InitialConditionsAdisTS.TableDefault import (
    InitialConditionTableDefaultModel,
)

from View.InitialConditionsAdisTS.Table import (
    InitialConditionTableModel, ComboBoxDelegate,
)

from View.InitialConditionsAdisTS.translate import IcAdisTSTranslate

from Solver.Mage import Mage8

_translate = QCoreApplication.translate

logger = logging.getLogger()


class InitialConditionsAdisTSWindow(PamhyrWindow):
    _pamhyr_ui = "InitialConditionsAdisTS"
    _pamhyr_name = "Initial condition AdisTS"

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

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

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

        self._hash_data.append(data)

        self._ics_adists_lst = study.river.initial_conditions_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 = InitialConditionTableDefaultModel(
            table_view=table_default,
            table_headers=self._trad.get_dict("table_headers"),
            editable_headers=["name", "concentration", "eg", "em", "ed"],
            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_kp = ComboBoxDelegate(
            trad=self._trad,
            data=self._study.river,
            ic_spec_lst=self._data[0]._data,
            parent=self,
            mode="kp"
        )

        self._table_spec = InitialConditionTableModel(
            table_view=self.table_spec,
            table_headers=self._trad.get_dict("table_headers_spec"),
            editable_headers=["name", "reach", "start_kp", "end_kp", "concentration", "eg", "em", "ed", "rate"],
            delegates={
                "reach": self._delegate_reach,
                "start_kp": self._delegate_kp,
                "end_kp": self._delegate_kp
            },
            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],
                        ["kp", "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(
            "IC: 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)