diff --git a/src/Model/River.py b/src/Model/River.py index a4dd8fa54318371139a4d8f9cef965cd819902f9..d995d2c389b6133be698e826608acd800b9ffc5c 100644 --- a/src/Model/River.py +++ b/src/Model/River.py @@ -376,8 +376,8 @@ class River(Graph, SQLSubModel): return self._reservoir @property - def hydraulics_structures(self): - return self._hydraulics_structures + def hydraulic_structures(self): + return self._hydraulic_structures @property def parameters(self): diff --git a/src/Solver/Mage.py b/src/Solver/Mage.py index 80793357dbeef7df62ce600ec8f605f54b2e11f8..5dc5920754696588fc2a08ebae3474abaf771286 100644 --- a/src/Solver/Mage.py +++ b/src/Solver/Mage.py @@ -455,7 +455,7 @@ class Mage(CommandLineSolver): reach_id = study.river.get_edge_id(hs.reach) params = [p.value for p in hs.basic_hydraulic_structure.param] param_str = ' '.join([f'{p.value:>10.3f}' for p in hs.basic_hydraulic_structure.param]) - f.write(f"{reach_id} {hs.kp:>12.3f} {params} {hs.name}\n") + f.write(f"{hs.basic_hydraulic_structure.type} {reach_id} {hs.kp:>12.3f} {params} {hs.name}\n") return files diff --git a/src/View/HydraulicStructures/BasicHydraulicStructures/Table.py b/src/View/HydraulicStructures/BasicHydraulicStructures/Table.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0522af555679571f817f2bad2e2fc925da874ba4 100644 --- a/src/View/HydraulicStructures/BasicHydraulicStructures/Table.py +++ b/src/View/HydraulicStructures/BasicHydraulicStructures/Table.py @@ -0,0 +1,20 @@ +# 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 <https://www.gnu.org/licenses/>. + +# -*- coding: utf-8 -*- + +import logging +import traceback diff --git a/src/View/HydraulicStructures/BasicHydraulicStructures/Translate.py b/src/View/HydraulicStructures/BasicHydraulicStructures/Translate.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f2d74d02529c6ac24646c5f6e3219826385e7ee3 100644 --- a/src/View/HydraulicStructures/BasicHydraulicStructures/Translate.py +++ b/src/View/HydraulicStructures/BasicHydraulicStructures/Translate.py @@ -0,0 +1,23 @@ +# translate.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 <https://www.gnu.org/licenses/>. + +# -*- coding: utf-8 -*- + +from PyQt5.QtCore import QCoreApplication + +from View.Tools.PamhyrTranslate import PamhyrTranslate + +_translate = QCoreApplication.translate diff --git a/src/View/HydraulicStructures/BasicHydraulicStructures/UndoCommand.py b/src/View/HydraulicStructures/BasicHydraulicStructures/UndoCommand.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ca18efaa83e126490b58714fbe6cf34775dfb5e9 100644 --- a/src/View/HydraulicStructures/BasicHydraulicStructures/UndoCommand.py +++ b/src/View/HydraulicStructures/BasicHydraulicStructures/UndoCommand.py @@ -0,0 +1,17 @@ +# UndoCommand.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 <https://www.gnu.org/licenses/>. + +# -*- coding: utf-8 -*- diff --git a/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py b/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..43e78cefde37ebc935e71267888843bc9eda55d8 100644 --- a/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py +++ b/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py @@ -0,0 +1,17 @@ +# Window.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 <https://www.gnu.org/licenses/>. + +# -*- coding: utf-8 -*- diff --git a/src/View/HydraulicStructures/Table.py b/src/View/HydraulicStructures/Table.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..44e5d1690ea6bd5e44263c08d411274f36160dd8 100644 --- a/src/View/HydraulicStructures/Table.py +++ b/src/View/HydraulicStructures/Table.py @@ -0,0 +1,198 @@ +# 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 <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, +) + +from View.Tools.PamhyrTable import PamhyrTableModel + +from View.HydraulicStructures.UndoCommand import ( + SetNameCommand, SetReachCommand, SetKpCommand, + AddCommand, DelCommand, +) + +logger = logging.getLogger() + +_translate = QCoreApplication.translate + + +class ComboBoxDelegate(QItemDelegate): + def __init__(self, data=None, trad=None, parent=None, mode="reaches"): + super(ComboBoxDelegate, self).__init__(parent) + + self._data = data + self._trad = trad + self._mode = mode + + def createEditor(self, parent, option, index): + self.editor = QComboBox(parent) + + val = [] + if self._mode == "kp": + reach = self._data.hydraulic_structures.get(index.row()).input_reach + if reach is not None: + val = list( + map( + lambda kp: str(kp), reach.reach.get_kp() + ) + ) + else: + val = list( + map( + lambda n: n.name, self._data.edges() + ) + ) + + self.editor.addItems( + [_translate("Hydraulic structure", "Not associated")] + + val + ) + + 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 _setup_lst(self): + self._lst = self._data._hydraulic_structures + + 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._lst.get(row).name + elif self._headers[column] == "reach": + n = self._lst.get(row).input_reach + if n is None: + return _translate("Hydraulic structure", "Not associated") + return n.name + elif self._headers[column] == "kp": + n = self._lst.get(row).input_kp + if n is None: + return _translate("Hydraulic structure", "Not associated") + return n + + 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._lst, row, value + ) + ) + elif self._headers[column] == "reach": + self._undo.push( + SetReachCommand( + self._lst, row, self._data.edge(value) + ) + ) + elif self._headers[column] == "kp": + self._undo.push( + SetKpCommand( + self._lst, row, 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._lst, row + ) + ) + + self.endInsertRows() + self.layoutChanged.emit() + + def delete(self, rows, parent=QModelIndex()): + self.beginRemoveRows(parent, rows[0], rows[-1]) + + self._undo.push( + DelCommand( + self._lst, rows + ) + ) + + self.endRemoveRows() + self.layoutChanged.emit() + + def undo(self): + self._undo.undo() + self.layoutChanged.emit() + + def redo(self): + self._undo.redo() + self.layoutChanged.emit() diff --git a/src/View/HydraulicStructures/Translate.py b/src/View/HydraulicStructures/Translate.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1db3faeca39e54c5d391af1f631598809e3c3d52 100644 --- a/src/View/HydraulicStructures/Translate.py +++ b/src/View/HydraulicStructures/Translate.py @@ -0,0 +1,34 @@ +# translate.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 <https://www.gnu.org/licenses/>. + +# -*- coding: utf-8 -*- + +from PyQt5.QtCore import QCoreApplication + +from View.Tools.PamhyrTranslate import PamhyrTranslate + +_translate = QCoreApplication.translate + + +class HydraulicStructuresTranslate(PamhyrTranslate): + def __init__(self): + super(HydraulicStructuresTranslate, self).__init__() + + self._sub_dict["table_headers"] = { + "name": _translate("HydraulicStructures", "Name"), + "reach": _translate("HydraulicStructures", "Reach"), + "kp": _translate("HydraulicStructures", "Kp"), + } diff --git a/src/View/HydraulicStructures/UndoCommand.py b/src/View/HydraulicStructures/UndoCommand.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c1a53f0dfe36821e7311600429993d62e63733e7 100644 --- a/src/View/HydraulicStructures/UndoCommand.py +++ b/src/View/HydraulicStructures/UndoCommand.py @@ -0,0 +1,139 @@ +# UndoCommand.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 <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, h_s_lst, index, new_value): + QUndoCommand.__init__(self) + + self._h_s_lst = h_s_lst + self._index = index + self._old = self._h_s_lst.get(self._index).name + self._new = str(new_value) + + def undo(self): + self._h_s_lst.get(self._index).name = self._old + + def redo(self): + self._h_s_lst.get(self._index).name = self._new + + +class SetReachCommand(QUndoCommand): + def __init__(self, h_s_lst, index, reach): + QUndoCommand.__init__(self) + + self._h_s_lst = h_s_lst + self._index = index + self._old = self._h_s_lst.get(self._index).input_reach + self._new = reach + self._old_kp = self._h_s_lst.get(self._index).input_kp + self._new_kp = None + + def undo(self): + i = self._h_s_lst.get(self._index) + i.input_reach = self._old + i.input_kp = self._old_kp + + def redo(self): + i = self._h_s_lst.get(self._index) + i.input_reach = self._new + i.input_kp = self._new_kp + + +class SetKpCommand(QUndoCommand): + def __init__(self, h_s_lst, index, kp): + QUndoCommand.__init__(self) + + self._h_s_lst = h_s_lst + self._index = index + self._old = self._h_s_lst.get(self._index).input_kp + self._new = kp + + def undo(self): + self._h_s_lst.get(self._index).input_kp = self._old + + def redo(self): + self._h_s_lst.get(self._index).input_kp = self._new + + +class AddCommand(QUndoCommand): + def __init__(self, h_s_lst, index): + QUndoCommand.__init__(self) + + self._h_s_lst = h_s_lst + + self._index = index + self._new = None + + def undo(self): + self._h_s_lst.delete_i([self._index]) + + def redo(self): + if self._new is None: + self._new = self._h_s_lst.new(self._h_s_lst, self._index) + else: + self._h_s_lst.insert(self._index, self._new) + + +class DelCommand(QUndoCommand): + def __init__(self, h_s_lst, rows): + QUndoCommand.__init__(self) + + self._h_s_lst = h_s_lst + + self._rows = rows + + self._h_s = [] + for row in rows: + self._h_s.append((row, self._h_s_lst.get(row))) + self._h_s.sort() + + def undo(self): + for row, el in self._h_s: + self._h_s_lst.insert(row, el) + + def redo(self): + self._h_s_lst.delete_i(self._rows) + + +class PasteCommand(QUndoCommand): + def __init__(self, h_s_lst, row, h_s): + QUndoCommand.__init__(self) + + self._h_s_lst = h_s_lst + + self._row = row + self._h_s = deepcopy(h_s) + self._h_s.reverse() + + def undo(self): + self._h_s_lst.delete_i( + self._tab, + range(self._row, self._row + len(self._h_s)) + ) + + def redo(self): + for r in self._h_s: + self._h_s_lst.insert(self._row, r) diff --git a/src/View/HydraulicStructures/Window.py b/src/View/HydraulicStructures/Window.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0620d4a4715c415cd14e7b045e560b40b66e07d2 100644 --- a/src/View/HydraulicStructures/Window.py +++ b/src/View/HydraulicStructures/Window.py @@ -0,0 +1,208 @@ +# Window.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 <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.HydraulicStructures.Table import ( + TableModel, ComboBoxDelegate +) + +from View.Network.GraphWidget import GraphWidget +from View.HydraulicStructures.Translate import HydraulicStructuresTranslate + +_translate = QCoreApplication.translate + +logger = logging.getLogger() + + +class HydraulicStructuresWindow(PamhyrWindow): + _pamhyr_ui = "HydraulicStructures" + _pamhyr_name = "Hydraulic Structures" + + def __init__(self, study=None, config=None, parent=None): + name = self._pamhyr_name + " - " + study.name + + super(HydraulicStructuresWindow, self).__init__( + title=name, + study=study, + config=config, + trad=HydraulicStructuresTranslate(), + parent=parent + ) + + self._hs_lst = self._study.river._hydraulic_structures + + self.setup_table() + self.setup_checkbox() + self.setup_plots() + self.setup_connections() + + def setup_table(self): + self._table = None + + self._delegate_reach = ComboBoxDelegate( + trad=self._trad, + data=self._study.river, + parent=self, + mode = "reaches" + ) + self._delegate_kp = ComboBoxDelegate( + trad=self._trad, + data=self._study.river, + parent=self, + mode = "kp" + ) + + table = self.find(QTableView, f"tableView") + self._table = TableModel( + table_view=table, + table_headers=self._trad.get_dict("table_headers"), + editable_headers=["name", "reach", "kp"], + delegates={ + "reach": self._delegate_reach, + "kp": self._delegate_kp, + }, + trad=self._trad, + data=self._study.river, + undo=self._undo_stack, + ) + + selectionModel = table.selectionModel() + index = table.model().index(0, 0) + + selectionModel.select( + index, + QItemSelectionModel.Rows | + QItemSelectionModel.ClearAndSelect | + QItemSelectionModel.Select + ) + table.scrollTo(index) + + def setup_checkbox(self): + self._checkbox = self.find(QCheckBox, f"checkBox") + self._set_checkbox_state + + def setup_plots(self): + return + + def setup_connections(self): + self.find(QAction, "action_add").triggered.connect(self.add) + self.find(QAction, "action_delete").triggered.connect(self.delete) + self.find(QAction, "action_edit").triggered.connect(self.edit) + self._checkbox.stateChanged.connect(self._set_structure_state) + + table = self.find(QTableView, "tableView") + table.selectionModel()\ + .selectionChanged\ + .connect(self._set_checkbox_state) + + 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_lst) == 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 edit(self): + rows = self.index_selected_rows() + for row in rows: + data = self._hs_lst.get(row) + + if self.sub_window_exists( + BasicHydraulicStructuresWindow, + data=[self._study, None, data] + ): + continue + + win = BasicHydraulicStructuresWindow( + data=data, + study=self._study, + parent=self + ) + win.show() + + 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_lst.get(row).enabled) + + def _set_structure_state(self): + row = self.index_selected_row() + #self._checkbox.setChecked(self._hs_lst.get(row).enabled) + self._hs_lst.get(row).enabled = self._checkbox.isChecked() diff --git a/src/View/MainWindow.py b/src/View/MainWindow.py index 04ed5f94267aad9aad4e2419b6aea1fab59b47f1..a9d98062dbab2b1e1aa5091477bb00b6af6cf0c5 100644 --- a/src/View/MainWindow.py +++ b/src/View/MainWindow.py @@ -48,6 +48,7 @@ from View.Network.Window import NetworkWindow from View.Geometry.Window import GeometryWindow from View.BoundaryCondition.Window import BoundaryConditionWindow from View.Reservoir.Window import ReservoirWindow +from View.HydraulicStructures.Window import HydraulicStructuresWindow from View.LateralContribution.Window import LateralContributionWindow from View.InitialConditions.Window import InitialConditionsWindow from View.Stricklers.Window import StricklersWindow @@ -102,7 +103,8 @@ define_model_action = [ "action_menu_boundary_conditions", "action_menu_initial_conditions", "action_menu_edit_friction", "action_menu_edit_lateral_contribution", "action_menu_run_solver", "action_menu_sediment_layers", - "action_menu_edit_reach_sediment_layers", "action_menu_edit_reservoirs" + "action_menu_edit_reach_sediment_layers", "action_menu_edit_reservoirs", + "action_menu_edit_hydraulic_structures" ] action = ( @@ -193,6 +195,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit): "action_menu_edit_geometry": self.open_geometry, "action_menu_boundary_conditions": self.open_boundary_cond, "action_menu_edit_reservoirs": self.open_reservoir, + "action_menu_edit_hydraulic_structures": self.open_hydraulic_structures, "action_menu_initial_conditions": self.open_initial_conditions, "action_menu_edit_friction": self.open_frictions, "action_menu_edit_lateral_contribution": self.open_lateral_contrib, @@ -628,6 +631,16 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit): reservoir = ReservoirWindow(study=self._study, parent=self) reservoir.show() + def open_hydraulic_structures(self): + if self.sub_window_exists( + HydraulicStructuresWindow, + data=[self._study, None] + ): + return + + hydraulic_structures = HydraulicStructuresWindow(study=self._study, parent=self) + hydraulic_structures.show() + def open_lateral_contrib(self): if self.sub_window_exists( LateralContributionWindow, diff --git a/src/View/ui/BasicHydraulicStructures.ui b/src/View/ui/BasicHydraulicStructures.ui index 28ffae5448207582664bfadee6530cc36082f7fa..add59b7c8c5d4de7cdde19a8eaec49f1789c0e3a 100644 --- a/src/View/ui/BasicHydraulicStructures.ui +++ b/src/View/ui/BasicHydraulicStructures.ui @@ -40,6 +40,9 @@ </item> <item> <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="leftMargin"> + <number>5</number> + </property> <item> <widget class="QCheckBox" name="checkBox"> <property name="text"> diff --git a/src/View/ui/HydraulicStructures.ui b/src/View/ui/HydraulicStructures.ui index 0464f0180be53ebb86170ac78b2b778a8a715482..813da5b5f48ef45a2e14e4c473eb3263ed35f1b4 100644 --- a/src/View/ui/HydraulicStructures.ui +++ b/src/View/ui/HydraulicStructures.ui @@ -40,6 +40,9 @@ </item> <item> <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="leftMargin"> + <number>5</number> + </property> <item> <widget class="QCheckBox" name="checkBox"> <property name="text"> diff --git a/src/View/ui/MainWindow.ui b/src/View/ui/MainWindow.ui index e4d00954ccfff566746cfb1c98d94be09c52d6b1..bf73c3d3cb232511420f01a2fd72ad73438b235e 100644 --- a/src/View/ui/MainWindow.ui +++ b/src/View/ui/MainWindow.ui @@ -132,6 +132,7 @@ <addaction name="action_menu_edit_friction"/> <addaction name="action_menu_edit_lateral_contribution"/> <addaction name="action_menu_edit_reservoirs"/> + <addaction name="action_menu_edit_hydraulic_structures"/> </widget> <widget class="QMenu" name="menu_results"> <property name="title"> @@ -934,6 +935,14 @@ <string>Edit reservoirs</string> </property> </action> + <action name="action_menu_edit_hydraulic_structures"> + <property name="text"> + <string>Hydraulic structures</string> + </property> + <property name="toolTip"> + <string>Edit hydraulic structures</string> + </property> + </action> </widget> <resources/> <connections>