diff --git a/src/Model/OutputKpAdists/OutputKpAdists.py b/src/Model/OutputKpAdists/OutputKpAdists.py index af1c6df0903cc54196a3b59954f8750271927efb..d8ab6f566b786ac4624ce43308f6861e2387bfd7 100644 --- a/src/Model/OutputKpAdists/OutputKpAdists.py +++ b/src/Model/OutputKpAdists/OutputKpAdists.py @@ -86,7 +86,7 @@ class OutputKpAdists(SQLSubModel): CREATE TABLE OutputKpAdists( id INTEGER NOT NULL PRIMARY KEY, reach INTEGER NOT NULL, - kp INTEGER NOT NULL, + kp REAL NOT NULL, title TEXT NOT NULL, FOREIGN KEY(edge) REFERENCES river_reach(id) ) @@ -130,9 +130,18 @@ class OutputKpAdists(SQLSubModel): def _db_save(self, execute, data=None): + print("print output kp unit") + print("id : ", self.id) + print("reach : ", self._reach) + print("kp : ", self._kp) + print("title : ", self._title) + print("title format : ", self._db_format(self._title)) + + execute(f"DELETE FROM OutputKpAdists WHERE id = {self.id}") + sql = ( "INSERT INTO " + - "OutputKpAdists(id, reach, kp, title " + + "OutputKpAdists(id, reach, kp, title) " + "VALUES (" + f"{self.id}, {self._reach}, " + f"{self._kp}, '{self._db_format(self._title)}'" + diff --git a/src/Model/OutputKpAdists/OutputKpListAdists.py b/src/Model/OutputKpAdists/OutputKpListAdists.py index d6560e6847c5357de3bc241f02fb293d57b95afe..741cb2291a920a1e367fe9b0d260e27c7f99d144 100644 --- a/src/Model/OutputKpAdists/OutputKpListAdists.py +++ b/src/Model/OutputKpAdists/OutputKpListAdists.py @@ -35,6 +35,7 @@ class OutputKpAdistsList(PamhyrModelList): return new def _db_save(self, execute, data=None): + print("save outputkpadists") ok = True # Delete previous data diff --git a/src/Model/Pollutants/Pollutants.py b/src/Model/Pollutants/Pollutants.py index f2ca9e60dfa20fbf1f2b0653b660e4b950c8b5e6..42d5698c1d8ca97a5eb854c52e479d8255b307b7 100644 --- a/src/Model/Pollutants/Pollutants.py +++ b/src/Model/Pollutants/Pollutants.py @@ -47,7 +47,7 @@ class Pollutants(SQLSubModel): self._name = str(name) self._enabled = True - self._characteristics = [] + self._data = [] Pollutants._id_cnt = max( Pollutants._id_cnt + 1, self.id) @@ -61,6 +61,9 @@ class Pollutants(SQLSubModel): self._name = name self._status.modified() + @property + def data(self): + return self._data.copy() @classmethod def _db_create(cls, execute): @@ -125,7 +128,7 @@ class Pollutants(SQLSubModel): for t in table: new_data.append(t) - new_pollutant._characteristics = new_data + new_pollutant._data.append(new_data) new.append(new_pollutant) @@ -133,6 +136,8 @@ class Pollutants(SQLSubModel): def _db_save(self, execute, data=None): + print("save in data base for pollutants") + execute(f"DELETE FROM Pollutants WHERE id = {self.id}") execute(f"DELETE FROM Pollutants_characteristics WHERE pollutant = {self.id}") @@ -147,13 +152,13 @@ class Pollutants(SQLSubModel): execute(sql) - for d in self._characteristics: + for d in self._data: sql = ( "INSERT INTO " + "Pollutants_characteristics(type, diametre, rho, porosity, " + - "cdc_riv, cdc_cas, apd, ac, bc) " + - f"VALUES ({d[1]}, {d[2]}, {d[3]},{d[4]}, {d[5]}, " - f"{d[6]}, {d[7]}, {d[8]}, {d[9]}, {self.id})" + "cdc_riv, cdc_cas, apd, ac, bc, pollutant) " + + f"VALUES ({d[0]}, {d[1]}, {d[2]},{d[3]}, {d[4]}, " + f"{d[5]}, {d[6]}, {d[7]}, {d[8]}, {self.id})" ) execute(sql) @@ -168,6 +173,13 @@ class Pollutants(SQLSubModel): self._enabled = enabled self._status.modified() + def is_define(self): + return len(self._data) != 0 + + def __len__(self): + return len(self._data) + + diff --git a/src/Model/Pollutants/PollutantsList.py b/src/Model/Pollutants/PollutantsList.py index 2526329a76b0f356f803dee125218eb598aa695f..e2fa44043128f47f0b58b008bc8028b5ee66d2e0 100644 --- a/src/Model/Pollutants/PollutantsList.py +++ b/src/Model/Pollutants/PollutantsList.py @@ -35,6 +35,7 @@ class PollutantsList(PamhyrModelList): return new def _db_save(self, execute, data=None): + print("save pollutantsList") ok = True # Delete previous data diff --git a/src/Model/River.py b/src/Model/River.py index 066dbaaf79e96544fa9818a28025df65fd034c8d..d380220dbb85b42433e551c3816d368c8be81da3 100644 --- a/src/Model/River.py +++ b/src/Model/River.py @@ -232,6 +232,7 @@ class River(Graph, SQLSubModel): AddFileList, REPLineList, OutputKpAdistsList, + PollutantsList, ] def __init__(self, status=None): diff --git a/src/View/Pollutants/BasicHydraulicStructures/Table.py b/src/View/Pollutants/BasicHydraulicStructures/Table.py deleted file mode 100644 index f69a4099f458accc233412f1cfbc4fa6fcf361d4..0000000000000000000000000000000000000000 --- a/src/View/Pollutants/BasicHydraulicStructures/Table.py +++ /dev/null @@ -1,277 +0,0 @@ -# Table.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 logging -import traceback - -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, QMessageBox, -) - -from View.Tools.PamhyrTable import PamhyrTableModel - -from View.HydraulicStructures.BasicHydraulicStructures.UndoCommand import ( - SetNameCommand, SetTypeCommand, - SetEnabledCommand, AddCommand, DelCommand, - SetValueCommand, -) -from Model.HydraulicStructures.Basic.Types import BHS_types - -logger = logging.getLogger() - -_translate = QCoreApplication.translate - - -class ComboBoxDelegate(QItemDelegate): - def __init__(self, data=None, trad=None, parent=None): - super(ComboBoxDelegate, self).__init__(parent) - - self._data = data - self._trad = trad - - self._long_types = {} - if self._trad is not None: - self._long_types = self._trad.get_dict("long_types") - - def createEditor(self, parent, option, index): - self.editor = QComboBox(parent) - - lst = list( - map( - lambda k: self._long_types[k], - BHS_types.keys() - ) - ) - self.editor.addItems(lst) - - 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: - if 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(PamhyrTableModel): - def __init__(self, trad=None, **kwargs): - self._trad = trad - self._long_types = {} - if self._trad is not None: - self._long_types = self._trad.get_dict("long_types") - - super(TableModel, self).__init__(trad=trad, **kwargs) - - def rowCount(self, parent): - return len(self._lst) - - 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._data.basic_structure(row).name - elif self._headers[column] == "type": - return self._long_types[self._data.basic_structure(row).type] - - 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() - - try: - if self._headers[column] == "name": - self._undo.push( - SetNameCommand( - self._data, row, value - ) - ) - elif self._headers[column] == "type": - old_type = self._data.basic_structure(row).type - - if old_type == "ND" or self._question_set_type(): - key = next( - k for k, v in self._long_types.items() - if v == value - ) - - self._undo.push( - SetTypeCommand( - self._data, row, BHS_types[key] - ) - ) - except Exception as e: - logger.error(e) - logger.debug(traceback.format_exc()) - - self.dataChanged.emit(index, index) - return True - - def _question_set_type(self): - question = QMessageBox(self._parent) - - question.setWindowTitle(self._trad['msg_type_change_title']) - question.setText(self._trad['msg_type_change_text']) - question.setStandardButtons(QMessageBox.Cancel | QMessageBox.Ok) - question.setIcon(QMessageBox.Question) - - res = question.exec() - return res == QMessageBox.Ok - - 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() - self.layoutChanged.emit() - - def enabled(self, row, enabled, parent=QModelIndex()): - self._undo.push( - SetEnabledCommand( - self._lst, row, enabled - ) - ) - self.layoutChanged.emit() - - def undo(self): - self._undo.undo() - self.layoutChanged.emit() - - def redo(self): - self._undo.redo() - self.layoutChanged.emit() - - -class ParametersTableModel(PamhyrTableModel): - def __init__(self, trad=None, **kwargs): - self._trad = trad - self._long_types = {} - - if self._trad is not None: - self._long_types = self._trad.get_dict("long_types") - - self._hs_index = None - - super(ParametersTableModel, self).__init__(trad=trad, **kwargs) - - def rowCount(self, parent): - if self._hs_index is None: - return 0 - - return len( - self._data.basic_structure(self._hs_index) - ) - - def data(self, index, role): - if role != Qt.ItemDataRole.DisplayRole: - return QVariant() - - if self._hs_index is None: - return QVariant() - - row = index.row() - column = index.column() - - hs = self._data.basic_structure(self._hs_index) - - if self._headers[column] == "name": - return self._trad[hs.parameters[row].name] - elif self._headers[column] == "value": - return str(hs.parameters[row].value) - - return QVariant() - - def setData(self, index, value, role=Qt.EditRole): - if not index.isValid() or role != Qt.EditRole: - return False - - if self._hs_index is None: - return QVariant() - - row = index.row() - column = index.column() - - try: - if self._headers[column] == "value": - self._undo.push( - SetValueCommand( - self._data.basic_structure(self._hs_index), - row, value - ) - ) - except Exception as e: - logger.error(e) - logger.debug(traceback.format_exc()) - - self.dataChanged.emit(index, index) - return True - - def update_hs_index(self, index): - self._hs_index = index - self.layoutChanged.emit() diff --git a/src/View/Pollutants/BasicHydraulicStructures/Translate.py b/src/View/Pollutants/BasicHydraulicStructures/Translate.py deleted file mode 100644 index f55fb2d778e212588520e94dafd133c101c38413..0000000000000000000000000000000000000000 --- a/src/View/Pollutants/BasicHydraulicStructures/Translate.py +++ /dev/null @@ -1,155 +0,0 @@ -# translate.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 -*- - -from PyQt5.QtCore import QCoreApplication - -from View.Translate import MainTranslate - -_translate = QCoreApplication.translate - - -class BasicHydraulicStructuresTranslate(MainTranslate): - def __init__(self): - super(BasicHydraulicStructuresTranslate, self).__init__() - - self._dict["Basic Hydraulic Structures"] = _translate( - "BasicHydraulicStructures", "Basic Hydraulic Structures" - ) - - self._dict['msg_type_change_title'] = _translate( - "BasicHydraulicStructures", - "Change hydraulic structure type" - ) - - self._dict['msg_type_change_text'] = _translate( - "BasicHydraulicStructures", - "Do you want to change the hydraulic structure type and reset \ -hydraulic structure values?" - ) - - # BHSValues translation - - self._dict['width'] = self._dict["unit_width"] - self._dict['height'] = self._dict["unit_thickness"] - self._dict['elevation'] = self._dict["unit_elevation"] - self._dict['diameter'] = self._dict["unit_diameter"] - self._dict['discharge_coefficient'] = _translate( - "BasicHydraulicStructures", "Discharge coefficient" - ) - self._dict['loading_elevation'] = _translate( - "BasicHydraulicStructures", "Upper elevation (m)" - ) - self._dict['half-angle_tangent'] = _translate( - "BasicHydraulicStructures", "Half-angle tangent" - ) - self._dict['maximal_loading_elevation'] = _translate( - "BasicHydraulicStructures", "Maximal loading elevation" - ) - self._dict['siltation_height'] = _translate( - "BasicHydraulicStructures", "Siltation height (m)" - ) - self._dict['top_of_the_vault'] = _translate( - "BasicHydraulicStructures", "Top of the vault (m)" - ) - self._dict['bottom_of_the_vault'] = _translate( - "BasicHydraulicStructures", "Bottom of the vault (m)" - ) - self._dict['opening'] = _translate( - "BasicHydraulicStructures", "Opening" - ) - self._dict['maximal_opening'] = _translate( - "BasicHydraulicStructures", "Maximal opening" - ) - self._dict['step_space'] = _translate( - "BasicHydraulicStructures", "Step space" - ) - self._dict['weir'] = _translate( - "BasicHydraulicStructures", "Weir" - ) - self._dict['coefficient'] = _translate( - "BasicHydraulicStructures", "Coefficient" - ) - - # Dummy parameters - - self._dict['parameter_1'] = _translate( - "BasicHydraulicStructures", "Parameter 1" - ) - self._dict['parameter_2'] = _translate( - "BasicHydraulicStructures", "Parameter 2" - ) - self._dict['parameter_3'] = _translate( - "BasicHydraulicStructures", "Parameter 3" - ) - self._dict['parameter_4'] = _translate( - "BasicHydraulicStructures", "Parameter 4" - ) - self._dict['parameter_5'] = _translate( - "BasicHydraulicStructures", "Parameter 5" - ) - - # BHS types long names - - self._sub_dict["long_types"] = { - "ND": self._dict["not_defined"], - "S1": _translate( - "BasicHydraulicStructures", "Discharge weir" - ), - "S2": _translate( - "BasicHydraulicStructures", "Trapezoidal weir" - ), - "S3": _translate( - "BasicHydraulicStructures", "Triangular weir" - ), - "OR": _translate( - "BasicHydraulicStructures", "Rectangular orifice" - ), - "OC": _translate( - "BasicHydraulicStructures", "Circular orifice" - ), - "OV": _translate( - "BasicHydraulicStructures", "Vaulted orifice" - ), - "V1": _translate( - "BasicHydraulicStructures", "Rectangular gate" - ), - "V2": _translate( - "BasicHydraulicStructures", "Simplified rectangular gate" - ), - "BO": _translate( - "BasicHydraulicStructures", "Borda-type head loss" - ), - "CV": _translate( - "BasicHydraulicStructures", "Check valve" - ), - "UD": _translate( - "BasicHydraulicStructures", "User defined" - ), - } - - # Tables - - self._sub_dict["table_headers"] = { - "name": self._dict["name"], - "type": self._dict["type"], - } - - self._sub_dict["table_headers_parameters"] = { - "name": self._dict["name"], - "value": self._dict["value"], - } diff --git a/src/View/Pollutants/BasicHydraulicStructures/UndoCommand.py b/src/View/Pollutants/BasicHydraulicStructures/UndoCommand.py deleted file mode 100644 index 78fa3d62ea3f06c45c7d11d4c79b8b7c8b81e6d8..0000000000000000000000000000000000000000 --- a/src/View/Pollutants/BasicHydraulicStructures/UndoCommand.py +++ /dev/null @@ -1,153 +0,0 @@ -# UndoCommand.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 -*- - -from copy import deepcopy -from tools import trace, timer - -from PyQt5.QtWidgets import ( - QMessageBox, QUndoCommand, QUndoStack, -) - - -class SetNameCommand(QUndoCommand): - def __init__(self, hs, index, new_value): - QUndoCommand.__init__(self) - - self._hs = hs - self._index = index - self._old = self._hs.basic_structure(self._index).name - self._new = str(new_value) - - def undo(self): - self._hs.basic_structure(self._index).name = self._old - - def redo(self): - self._hs.basic_structure(self._index).name = self._new - - -class SetTypeCommand(QUndoCommand): - def __init__(self, hs, index, new_type): - QUndoCommand.__init__(self) - - self._hs = hs - self._index = index - self._type = new_type - self._old = self._hs.basic_structure(self._index) - self._new = self._hs.basic_structure(self._index)\ - .convert(self._type) - - def undo(self): - self._hs.delete_i([self._index]) - self._hs.insert(self._index, self._old) - - def redo(self): - self._hs.delete_i([self._index]) - self._hs.insert(self._index, self._new) - - -class SetEnabledCommand(QUndoCommand): - def __init__(self, hs, index, enabled): - QUndoCommand.__init__(self) - - self._hs = hs - self._index = index - self._old = not enabled - self._new = enabled - - def undo(self): - self._hs.basic_structure(self._index).enabled = self._old - - def redo(self): - self._hs.basic_structure(self._index).enabled = self._new - - -class AddCommand(QUndoCommand): - def __init__(self, hs, index): - QUndoCommand.__init__(self) - - self._hs = hs - - self._index = index - self._new = None - - def undo(self): - self._hs.delete_i([self._index]) - - def redo(self): - if self._new is None: - self._new = self._hs.add(self._index) - else: - self._hs.insert(self._index, self._new) - - -class DelCommand(QUndoCommand): - def __init__(self, hs, rows): - QUndoCommand.__init__(self) - - self._hs = hs - - self._rows = rows - - self._bhs = [] - for row in rows: - self._bhs.append((row, self._hs.basic_structure(row))) - - def undo(self): - for row, el in self._bhs: - self._hs.insert(row, el) - - def redo(self): - self._hs.delete_i(self._rows) - - -class PasteCommand(QUndoCommand): - def __init__(self, hs, row, h_s): - QUndoCommand.__init__(self) - - self._hs = hs - - self._row = row - self._bhs = deepcopy(h_s) - self._bhs.reverse() - - def undo(self): - self._hs.delete_i(range(self._row, self._row + len(self._bhs))) - - def redo(self): - for r in self._bhs: - self._hs.insert(self._row, r) - -#################################### -# Basic hydraulic structure values # -#################################### - - -class SetValueCommand(QUndoCommand): - def __init__(self, bhs, index, value): - QUndoCommand.__init__(self) - - self._bhs = bhs - self._index = index - self._old = self._bhs.parameters[self._index].value - self._new = self._bhs.parameters[self._index].type(value) - - def undo(self): - self._bhs.parameters[self._index].value = self._old - - def redo(self): - self._bhs.parameters[self._index].value = self._new diff --git a/src/View/Pollutants/BasicHydraulicStructures/Window.py b/src/View/Pollutants/BasicHydraulicStructures/Window.py deleted file mode 100644 index 9a39f49c64749b995b3ac3733038ee0e720003b5..0000000000000000000000000000000000000000 --- a/src/View/Pollutants/BasicHydraulicStructures/Window.py +++ /dev/null @@ -1,270 +0,0 @@ -# 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 logging - -from tools import timer, trace - -from View.Tools.PamhyrWindow import PamhyrWindow - -from PyQt5 import QtCore -from PyQt5.QtCore import ( - Qt, QVariant, QAbstractTableModel, QCoreApplication, - pyqtSlot, pyqtSignal, QItemSelectionModel, -) - -from PyQt5.QtWidgets import ( - QDialogButtonBox, QPushButton, QLineEdit, - QFileDialog, QTableView, QAbstractItemView, - QUndoStack, QShortcut, QAction, QItemDelegate, - QHeaderView, QDoubleSpinBox, QVBoxLayout, QCheckBox -) - -from View.Tools.Plot.PamhyrCanvas import MplCanvas -from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar - -from View.HydraulicStructures.PlotAC import PlotAC - -from View.HydraulicStructures.BasicHydraulicStructures.Table import ( - ComboBoxDelegate, TableModel, ParametersTableModel, -) - -from View.Network.GraphWidget import GraphWidget -from View.HydraulicStructures.BasicHydraulicStructures.Translate import ( - BasicHydraulicStructuresTranslate -) - -_translate = QCoreApplication.translate - -logger = logging.getLogger() - - -class BasicHydraulicStructuresWindow(PamhyrWindow): - _pamhyr_ui = "BasicHydraulicStructures" - _pamhyr_name = "Basic Hydraulic Structures" - - def __init__(self, data=None, study=None, config=None, parent=None): - trad = BasicHydraulicStructuresTranslate() - name = " - ".join([ - trad[self._pamhyr_name], data.name, study.name - ]) - - super(BasicHydraulicStructuresWindow, self).__init__( - title=name, - study=study, - config=config, - trad=trad, - parent=parent - ) - - self._hash_data.append(data) - - self._hs = data - - self.setup_table() - self.setup_checkbox() - self.setup_plot() - self.setup_connections() - - self.update() - - def setup_table(self): - self.setup_table_bhs() - self.setup_table_bhs_parameters() - - def setup_table_bhs(self): - self._table = None - - self._delegate_type = ComboBoxDelegate( - trad=self._trad, - parent=self - ) - - table = self.find(QTableView, f"tableView") - self._table = TableModel( - table_view=table, - table_headers=self._trad.get_dict("table_headers"), - editable_headers=["name", "type"], - delegates={ - "type": self._delegate_type, - }, - trad=self._trad, - data=self._hs, - undo=self._undo_stack, - parent=self, - ) - - selectionModel = table.selectionModel() - index = table.model().index(0, 0) - - selectionModel.select( - index, - QItemSelectionModel.Rows | - QItemSelectionModel.ClearAndSelect | - QItemSelectionModel.Select - ) - table.scrollTo(index) - - def setup_table_bhs_parameters(self): - self._table_parameters = None - - table = self.find(QTableView, f"tableView_2") - self._table_parameters = ParametersTableModel( - table_view=table, - table_headers=self._trad.get_dict("table_headers_parameters"), - editable_headers=["value"], - delegates={}, - trad=self._trad, - data=self._hs, - undo=self._undo_stack, - parent=self, - ) - - def setup_checkbox(self): - self._checkbox = self.find(QCheckBox, f"checkBox") - self._set_checkbox_state() - - def setup_plot(self): - self.canvas = MplCanvas(width=5, height=4, dpi=100) - self.canvas.setObjectName("canvas") - self.toolbar = PamhyrPlotToolbar( - self.canvas, self - ) - self.plot_layout = self.find(QVBoxLayout, "verticalLayout") - self.plot_layout.addWidget(self.toolbar) - self.plot_layout.addWidget(self.canvas) - - reach = self._hs.input_reach - profile_kp = self._hs.input_kp - if profile_kp is not None: - profiles = reach.reach.get_profiles_from_kp(float(profile_kp)) - else: - profiles = None - if profiles is not None: - profile = profiles[0] - else: - profile = None - - self.plot_ac = PlotAC( - canvas=self.canvas, - river=self._study.river, - reach=self._hs.input_reach, - profile=profile, - trad=self._trad, - toolbar=self.toolbar - ) - self.plot_ac.draw() - - def setup_connections(self): - self.find(QAction, "action_add").triggered.connect(self.add) - self.find(QAction, "action_delete").triggered.connect(self.delete) - self._checkbox.clicked.connect(self._set_basic_structure_state) - - table = self.find(QTableView, "tableView") - table.selectionModel()\ - .selectionChanged\ - .connect(self.update) - - self._table.dataChanged.connect(self.update) - self._table.layoutChanged.connect(self.update) - - def index_selected(self): - table = self.find(QTableView, "tableView") - r = table.selectionModel().selectedRows() - - if len(r) > 0: - return r[0] - else: - return None - - def index_selected_row(self): - table = self.find(QTableView, "tableView") - r = table.selectionModel().selectedRows() - - if len(r) > 0: - return r[0].row() - else: - return None - - def index_selected_rows(self): - table = self.find(QTableView, "tableView") - return list( - # Delete duplicate - set( - map( - lambda i: i.row(), - table.selectedIndexes() - ) - ) - ) - - def add(self): - rows = self.index_selected_rows() - - if len(self._hs) == 0 or len(rows) == 0: - self._table.add(0) - else: - self._table.add(rows[0]) - - def delete(self): - rows = self.index_selected_rows() - - if len(rows) == 0: - return - - self._table.delete(rows) - - def _copy(self): - logger.info("TODO: copy") - - def _paste(self): - logger.info("TODO: paste") - - def _undo(self): - self._table.undo() - - def _redo(self): - self._table.redo() - - def _set_checkbox_state(self): - row = self.index_selected_row() - - if row is None: - self._checkbox.setEnabled(False) - self._checkbox.setChecked(True) - else: - self._checkbox.setEnabled(True) - self._checkbox.setChecked(self._hs.basic_structure(row).enabled) - - def _set_basic_structure_state(self): - rows = self.index_selected_rows() - if len(rows) != 0: - for row in rows: - if row is not None: - self._table.enabled( - row, - self._checkbox.isChecked() - ) - - def update(self): - self._set_checkbox_state() - self._update_parameters_table() - - def _update_parameters_table(self): - row = self.index_selected_row() - self._table_parameters.update_hs_index(row) diff --git a/src/View/Pollutants/Edit/Table.py b/src/View/Pollutants/Edit/Table.py new file mode 100644 index 0000000000000000000000000000000000000000..aa3c919b0f0cd997b562efbfd8edec37d0319aa6 --- /dev/null +++ b/src/View/Pollutants/Edit/Table.py @@ -0,0 +1,106 @@ +# Table.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 logging +import traceback + +from datetime import date, time, datetime, timedelta + +from tools import trace, timer + +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, QItemDelegate, +) + +from View.Pollutants.Edit.UndoCommand import ( + SetDataCommand, PasteCommand, +) + +_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() + + return self._data.data[row][column] + + 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: + if self._headers[column] == "type": + self._undo.push( + SetDataCommand( + self._data, row, column, int(value) + ) + ) + else: + self._undo.push( + SetDataCommand( + self._data, row, column, float(value) + ) + ) + except Exception as e: + logger.info(e) + logger.debug(traceback.format_exc()) + + self.dataChanged.emit(index, index) + return True + + def paste(self, row, 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(d), + data + ) + ) + ) + ) + + self.layoutAboutToBeChanged.emit() + self.layoutChanged.emit() diff --git a/src/View/Pollutants/Edit/Translate.py b/src/View/Pollutants/Edit/Translate.py new file mode 100644 index 0000000000000000000000000000000000000000..acdcab31f3948eb3ee6fd7b847a235cfe0994482 --- /dev/null +++ b/src/View/Pollutants/Edit/Translate.py @@ -0,0 +1,46 @@ +# translate.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 -*- + +from PyQt5.QtCore import QCoreApplication + +from View.Translate import MainTranslate + +from View.Pollutants.Translate import PollutantsTranslate + +_translate = QCoreApplication.translate + + +class EditPollutantTranslate(PollutantsTranslate): + def __init__(self): + super(EditPollutantTranslate, self).__init__() + + self._dict["Edit Pollutant"] = _translate( + "Pollutants", "Edit Pollutant" + ) + + self._sub_dict["table_headers"] = { + "type": self._dict["type"], + "diametre": self._dict["unit_area"], + "rho": self._dict["unit_rho"], + "porosity": self._dict["unit_porosity"], + "cdc_riv": self._dict["unit_cdc_riv"], + "cdc_cas": self._dict["unit_cdc_cas"], + "apd": self._dict["unit_apd"], + "ac": self._dict["unit_ac"], + "bc": self._dict["unit_bc"], + } diff --git a/src/View/Pollutants/Edit/UndoCommand.py b/src/View/Pollutants/Edit/UndoCommand.py new file mode 100644 index 0000000000000000000000000000000000000000..4a30340adfce2b5d88a5855d52c48ae5f5ae7e69 --- /dev/null +++ b/src/View/Pollutants/Edit/UndoCommand.py @@ -0,0 +1,65 @@ +# UndoCommand.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 logging + +from copy import deepcopy +from tools import trace, timer + +from PyQt5.QtWidgets import ( + QMessageBox, QUndoCommand, QUndoStack, +) + +from Model.Pollutants.Pollutants import Pollutants + +logger = logging.getLogger() + + +class SetDataCommand(QUndoCommand): + def __init__(self, data, index, column, new_value): + QUndoCommand.__init__(self) + + self._data = data + self._index = index + self._column = column + self._old = self._data.data[self._index][self._column] + self._new = new_value + + def undo(self): + self._data.data[self._index][self._column] = self._old + + def redo(self): + self._data.data[self._index][self._column] = self._new + +class PasteCommand(QUndoCommand): + def __init__(self, data, row, hs): + QUndoCommand.__init__(self) + + self._data = data + self._row = row + self._h = hs + self._h.reverse() + + def undo(self): + self._data.delete_i( + range(self._row, self._row + len(self._h)) + ) + + def redo(self): + for h in self._h: + self._data.insert(self._row, h) diff --git a/src/View/Pollutants/Edit/Window.py b/src/View/Pollutants/Edit/Window.py new file mode 100644 index 0000000000000000000000000000000000000000..735d1b20ade9bc42b1d78a7f2f0df5178a919677 --- /dev/null +++ b/src/View/Pollutants/Edit/Window.py @@ -0,0 +1,149 @@ +# 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 logging + +from tools import timer, trace + +from View.Tools.PamhyrWindow import PamhyrWindow +from View.Tools.PamhyrWidget import PamhyrWidget + +from PyQt5.QtGui import ( + QKeySequence, +) + +from PyQt5 import QtCore +from PyQt5.QtCore import ( + Qt, QVariant, QAbstractTableModel, QCoreApplication, + pyqtSlot, pyqtSignal, +) + +from PyQt5.QtWidgets import ( + QDialogButtonBox, QPushButton, QLineEdit, + QFileDialog, QTableView, QAbstractItemView, + QUndoStack, QShortcut, QAction, QItemDelegate, + QHeaderView, QDoubleSpinBox, QVBoxLayout, +) + +from View.Pollutants.Edit.Translate import EditPollutantTranslate +from View.Pollutants.Edit.Table import TableModel + +_translate = QCoreApplication.translate + +logger = logging.getLogger() + + +class EditPolluantWindow(PamhyrWindow): + _pamhyr_ui = "Pollutant" + _pamhyr_name = "Edit Pollutant" + + def __init__(self, data=None, study=None, config=None, parent=None): + self._data = data + trad = EditPollutantTranslate() + + name = trad[self._pamhyr_name] + print(name) + if self._data is not None: + name += ( + f" - {study.name} " + + f" - {self._data.name}" + ) + + super(EditPolluantWindow, self).__init__( + title=name, + study=study, + config=config, + trad=trad, + parent=parent + ) + + self._hash_data.append(data) + + self.setup_table() + + def setup_table(self): + headers = {} + table_headers = self._trad.get_dict("table_headers") + + table = self.find(QTableView, "tableView") + self._table = TableModel( + table_view=table, + table_headers=table_headers, + editable_headers=table_headers, + delegates={}, + data=self._data, + undo=self._undo_stack, + opt_data=self._study.time_system + ) + + table.setModel(self._table) + table.setSelectionBehavior(QAbstractItemView.SelectRows) + table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) + table.setAlternatingRowColors(True) + + def index_selected_row(self): + table = self.find(QTableView, "tableView") + return table.selectionModel()\ + .selectedRows()[0]\ + .row() + + def index_selected_rows(self): + table = self.find(QTableView, "tableView") + return list( + # Delete duplicate + set( + map( + lambda i: i.row(), + table.selectedIndexes() + ) + ) + ) + + def _copy(self): + rows = self.index_selected_rows() + + table = [] + # table.append(self._data.header) + table.append(self._trad.get_dict("table_headers")) + + data = self._data.data + for row in rows: + table.append(list(data[row])) + + self.copyTableIntoClipboard(table) + + def _paste(self): + header, data = self.parseClipboardTable() + + logger.debug(f"paste: h:{header}, d:{data}") + + if len(data) == 0: + return + + row = 0 + rows = self.index_selected_rows() + if len(rows) != 0: + row = rows[0] + + self._table.paste(row, data) + + def _undo(self): + self._table.undo() + + def _redo(self): + self._table.redo() diff --git a/src/View/Pollutants/PlotAC.py b/src/View/Pollutants/PlotAC.py deleted file mode 100644 index c63dc9bfdef5fb2e311b54eb90cf85e4937a4b1c..0000000000000000000000000000000000000000 --- a/src/View/Pollutants/PlotAC.py +++ /dev/null @@ -1,120 +0,0 @@ -# PlotAC.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 -*- - -from tools import timer -from View.Tools.PamhyrPlot import PamhyrPlot -from matplotlib import pyplot as plt - - -class PlotAC(PamhyrPlot): - def __init__(self, canvas=None, trad=None, toolbar=None, - river=None, reach=None, profile=None, - parent=None): - super(PlotAC, self).__init__( - canvas=canvas, - trad=trad, - data=river, - toolbar=toolbar, - parent=parent - ) - - self._current_reach = reach - self._current_profile = profile - - self.label_x = self._trad["x"] - self.label_y = self._trad["unit_elevation"] - - self._isometric_axis = False - - self._auto_relim_update = True - self._autoscale_update = True - - @property - def river(self): - return self.data - - @river.setter - def river(self, river): - self.data = river - - @timer - def draw(self): - self.init_axes() - - if self.data is None: - self.line_kp = None - return - - if self._current_reach is None: - self.line_kp = None - return - - self.draw_data() - - self.idle() - self._init = True - - def draw_data(self): - reach = self._current_reach - - if self._current_profile is None: - self.line_kp = None - else: - profile = self._current_profile - x = profile.get_station() - z = profile.z() - - self.line_kp, = self.canvas.axes.plot( - x, z, - color=self.color_plot_river_bottom, - **self.plot_default_kargs - ) - - def set_reach(self, reach): - self._current_reach = reach - self.update() - - def set_profile(self, profile): - self._current_profile = profile - self.update() - - def update(self): - if self.line_kp is None: - self.draw() - return - - if self._current_reach is None or self._current_profile is None: - self.update_clear() - else: - self.update_data() - - self.update_idle() - - def update_data(self): - profile = self._current_profile - x = profile.get_station() - z = profile.z() - - self.line_kp.set_data(x, z) - - def clear(self): - self.update_clear() - - def update_clear(self): - if self.line_kp is not None: - self.line_kp.set_data([], []) diff --git a/src/View/Pollutants/PlotKPC.py b/src/View/Pollutants/PlotKPC.py deleted file mode 100644 index 3327f6e627114ac8513dda1ca57670b0cdf722e8..0000000000000000000000000000000000000000 --- a/src/View/Pollutants/PlotKPC.py +++ /dev/null @@ -1,165 +0,0 @@ -# PlotKPC.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 -*- - -from tools import timer -from View.Tools.PamhyrPlot import PamhyrPlot - -from PyQt5.QtCore import ( - QCoreApplication -) - -from matplotlib.collections import LineCollection - -_translate = QCoreApplication.translate - - -class PlotKPC(PamhyrPlot): - def __init__(self, canvas=None, trad=None, toolbar=None, - river=None, reach=None, profile=None, - parent=None): - super(PlotKPC, self).__init__( - canvas=canvas, - trad=trad, - data=river, - toolbar=toolbar, - parent=parent - ) - - self._current_reach = reach - self._current_profile = profile - - self.label_x = self._trad["unit_kp"] - self.label_y = self._trad["unit_elevation"] - - self._isometric_axis = False - - self._auto_relim_update = True - self._autoscale_update = True - - @property - def river(self): - return self.data - - @river.setter - def river(self, river): - self.data = river - - @timer - def draw(self, highlight=None): - self.init_axes() - - if self.data is None: - self.profile = None - self.line_kp_zmin_zmax = None - self.line_kp_zmin = None - return - - if self._current_reach is None: - self.profile = None - self.line_kp_zmin_zmax = None - self.line_kp_zmin = None - return - - self.draw_data() - self.draw_current() - - self.idle() - self._init = True - - def draw_data(self): - reach = self._current_reach - - kp = reach.reach.get_kp() - z_min = reach.reach.get_z_min() - z_max = reach.reach.get_z_max() - - self.line_kp_zmin, = self.canvas.axes.plot( - kp, z_min, - color=self.color_plot_river_bottom, - lw=1. - ) - - if len(kp) != 0: - self.line_kp_zmin_zmax = self.canvas.axes.vlines( - x=kp, - ymin=z_min, ymax=z_max, - color=self.color_plot, - lw=1. - ) - - def draw_current(self): - if self._current_profile is None: - self.profile = None - else: - kp = [self._current_profile.kp, - self._current_profile.kp] - min_max = [self._current_profile.z_min(), - self._current_profile.z_max()] - - self.profile = self.canvas.axes.plot( - kp, min_max, - color=self.color_plot_current, - lw=1. - ) - - def set_reach(self, reach): - self._current_reach = reach - self._current_profile = None - self.update() - - def set_profile(self, profile): - self._current_profile = profile - self.update_current_profile() - - def update(self): - self.draw() - - def update_current_profile(self): - reach = self._current_reach - kp = reach.reach.get_kp() - z_min = reach.reach.get_z_min() - z_max = reach.reach.get_z_max() - - if self.profile is None: - self.draw() - else: - self.profile.set_data( - [self._current_profile.kp, self._current_profile.kp], - [self._current_profile.z_min(), self._current_profile.z_max()], - ) - - self.update_idle() - - def clear(self): - if self.profile is not None: - self.profile[0].set_data([], []) - - if self.line_kp_zmin_zmax is not None: - self.line_kp_zmin_zmax.remove() - self.line_kp_zmin_zmax = None - - if self.line_kp_zmin is not None: - self.line_kp_zmin.set_data([], []) - - self.canvas.figure.canvas.draw_idle() - - def clear_profile(self): - if self.profile is not None: - self.profile.set_data([], []) - - self.canvas.figure.canvas.draw_idle() diff --git a/src/View/Pollutants/UndoCommand.py b/src/View/Pollutants/UndoCommand.py index 213bf0207bec8dc1d142f85c949fa9f404425be8..843db085c3217c2b9d569d2ce8108701cee085d9 100644 --- a/src/View/Pollutants/UndoCommand.py +++ b/src/View/Pollutants/UndoCommand.py @@ -74,6 +74,7 @@ class AddCommand(QUndoCommand): def redo(self): if self._new is None: self._new = self._pollutants_lst.new(self._pollutants_lst, self._index) + self._new._data = [[0, 0., 0., 0., 0., 0., 0., 0., 0.]] else: self._pollutants_lst.insert(self._index, self._new) diff --git a/src/View/Pollutants/Window.py b/src/View/Pollutants/Window.py index 430061c9e10a2ba9428963e255d9d0ba91c5f0b0..a9dc2059c224fd10c85df7c3adad41ad9b503707 100644 --- a/src/View/Pollutants/Window.py +++ b/src/View/Pollutants/Window.py @@ -35,22 +35,13 @@ from PyQt5.QtWidgets import ( QHeaderView, QDoubleSpinBox, QVBoxLayout, QCheckBox ) -from View.Tools.Plot.PamhyrCanvas import MplCanvas -from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar - -from View.Pollutants.PlotAC import PlotAC -from View.Pollutants.PlotKPC import PlotKPC - from View.Pollutants.Table import ( TableModel ) -from View.Network.GraphWidget import GraphWidget from View.Pollutants.Translate import PollutantsTranslate -from View.Pollutants.BasicHydraulicStructures.Window import ( - BasicHydraulicStructuresWindow -) +from View.Pollutants.Edit.Window import EditPolluantWindow logger = logging.getLogger() @@ -183,12 +174,12 @@ class PollutantsWindow(PamhyrWindow): data = self._pollutants_lst.get(row) if self.sub_window_exists( - BasicHydraulicStructuresWindow, + EditPolluantWindow, data=[self._study, None, data] ): continue - win = BasicHydraulicStructuresWindow( + win = EditPolluantWindow( data=data, study=self._study, parent=self diff --git a/src/View/Translate.py b/src/View/Translate.py index 7d22a04269e9e6f0923f5a0c2ba2270495a2a469..bc809481f789f6a954b50bab3e9412064b8094af 100644 --- a/src/View/Translate.py +++ b/src/View/Translate.py @@ -72,6 +72,14 @@ class UnitTranslate(CommonWordTranslate): self._dict["unit_date_s"] = _translate("Unit", "Date (sec)") self._dict["unit_date_iso"] = _translate("Unit", "Date (ISO format)") + self._dict["unit_area"] = _translate("Unit", "Area") + self._dict["unit_rho"] = _translate("Unit", "Rho") + self._dict["unit_porosity"] = _translate("Unit", "Porosity") + self._dict["unit_cdc_riv"] = _translate("Unit", "CDC_RIV") + self._dict["unit_cdc_cas"] = _translate("Unit", "CDC_CAS") + self._dict["unit_apd"] = _translate("Unit", "APD") + self._dict["unit_ac"] = _translate("Unit", "AC") + self._dict["unit_bc"] = _translate("Unit", "BC") class MainTranslate(UnitTranslate): def __init__(self): diff --git a/src/View/ui/Pollutant.ui b/src/View/ui/Pollutant.ui new file mode 100644 index 0000000000000000000000000000000000000000..e842bacae69422f03322464664570f854efa5503 --- /dev/null +++ b/src/View/ui/Pollutant.ui @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QSplitter" name="splitter"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <widget class="QTableView" name="tableView"> + <property name="minimumSize"> + <size> + <width>300</width> + <height>0</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </widget> + <widget class="QWidget" name="verticalLayoutWidget"> + <layout class="QVBoxLayout" name="verticalLayout"/> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>22</height> + </rect> + </property> + </widget> + <widget class="QStatusBar" name="statusbar"/> + <widget class="QToolBar" name="toolBar"> + <property name="windowTitle"> + <string>toolBar</string> + </property> + <attribute name="toolBarArea"> + <enum>TopToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + </widget> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/View/ui/Pollutants.ui b/src/View/ui/Pollutants.ui index 213d583eecdea8caec6d9605815f40b1b63d06e1..16960d920a52b5b61ee239aab37aed4f6198d81c 100644 --- a/src/View/ui/Pollutants.ui +++ b/src/View/ui/Pollutants.ui @@ -122,12 +122,8 @@ </property> </action> <action name="action_edit"> - <property name="icon"> - <iconset> - <normaloff>ressources/edit.png</normaloff>ressources/edit.png</iconset> - </property> <property name="text"> - <string>Edit</string> + <string>Characteristics</string> </property> <property name="toolTip"> <string>Edit selected hydraulic structure</string> diff --git a/tests_cases/Ardeche/Ardeche.pamhyr b/tests_cases/Ardeche/Ardeche.pamhyr index d0c55c708be0c428de5ad820953f73592f5b09ba..0951c307eaddec127fdc2ffe676ce37bcf6d6f17 100644 Binary files a/tests_cases/Ardeche/Ardeche.pamhyr and b/tests_cases/Ardeche/Ardeche.pamhyr differ