diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index dd8178d4..61a4ab6f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -122,7 +122,7 @@ test-pep8:
- pip3 install -r ./requirements.txt
- pip3 install -U -r ./requirements.txt
- pip3 install pycodestyle
- - pycodestyle ./src
+ - pycodestyle --exclude="*_to_*.py" ./src
allow_failure: true
#########
diff --git a/src/Model/Friction/Friction.py b/src/Model/Friction/Friction.py
index ecc4a559..d3be3cf5 100644
--- a/src/Model/Friction/Friction.py
+++ b/src/Model/Friction/Friction.py
@@ -24,6 +24,7 @@ from Model.Tools.PamhyrDB import SQLSubModel
logger = logging.getLogger()
+
class Friction(SQLSubModel):
def __init__(self, name: str = "", status=None):
super(Friction, self).__init__()
diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py
index 495fbac1..34146bc1 100644
--- a/src/Model/Geometry/ProfileXYZ.py
+++ b/src/Model/Geometry/ProfileXYZ.py
@@ -437,42 +437,57 @@ class ProfileXYZ(Profile, SQLSubModel):
return abs(rg.dist(rd))
def get_water_limits(self, z):
-#==============================================================================
-# détermination des points limites RG et RD pour un niveau d'eau donné
-#
-# irg et ird sont les premiers indices en partant des rives gauche et
-# droite qui correspondent à des points sous la surface de l'eau
-# ptX et ptY sont les points interpolés où le plan d'eau intersecte le profil
-# known_level est le niveau d'eau pour lequel on a obtenu irg, ird, ptX et ptY
-#==============================================================================
+ # ====================================================================
+ # détermination des points limites RG et RD pour un niveau
+ # d'eau donné
+ #
+ # irg et ird sont les premiers indices en partant des rives
+ # gauche et droite qui correspondent à des points sous la
+ # surface de l'eau ptX et ptY sont les points interpolés où
+ # le plan d'eau intersecte le profil known_level est le
+ # niveau d'eau pour lequel on a obtenu irg, ird, ptX et ptY
+ # ====================================================================
+
# initialisation
- irg = -1 ; ird = -1
+ irg = -1
+ ird = -1
+
for i in range(self.number_points):
if self.point(i).z <= z:
irg = i
+
for i in reversed(range(self.number_points)):
if self.point(i).z <= z:
ird = i
+
# interpolation des points ptX et ptY
- if (irg < self.number_points-1):
- x=np.interp(z,
- [self.point(irg).z,self.point(irg+1).z],
- [self.point(irg).x,self.point(irg+1).x])
- y=np.interp(z,
- [self.point(irg).z,self.point(irg+1).z],
- [self.point(irg).y,self.point(irg+1).y])
- ptX=PointXYZ(x,y,z)
+ if (irg < self.number_points - 1):
+ x = np.interp(
+ z,
+ [self.point(irg).z, self.point(irg + 1).z],
+ [self.point(irg).x, self.point(irg + 1).x]
+ )
+ y = np.interp(
+ z,
+ [self.point(irg).z, self.point(irg + 1).z],
+ [self.point(irg).y, self.point(irg + 1).y]
+ )
+ ptX = PointXYZ(x, y, z)
else:
ptX = self.point(0)
if (ird > 0):
- x=np.interp(z,
- [self.point(ird-1).z,self.point(ird).z],
- [self.point(ird-1).x,self.point(ird).x])
- y=np.interp(z,
- [self.point(ird).z,self.point(ird-1).z],
- [self.point(ird).y,self.point(ird-1).y])
- ptY=PointXYZ(x,y,z)
+ x = np.interp(
+ z,
+ [self.point(ird-1).z, self.point(ird).z],
+ [self.point(ird-1).x, self.point(ird).x]
+ )
+ y = np.interp(
+ z,
+ [self.point(ird).z, self.point(ird - 1).z],
+ [self.point(ird).y, self.point(ird - 1).y]
+ )
+ ptY = PointXYZ(x, y, z)
else:
- ptY = self.point(self.number_points-1)
+ ptY = self.point(self.number_points - 1)
- return ptX,ptY
+ return ptX, ptY
diff --git a/src/Model/HydraulicStructures/Basic/HydraulicStructures.py b/src/Model/HydraulicStructures/Basic/HydraulicStructures.py
index 691cf60c..e624d2ef 100644
--- a/src/Model/HydraulicStructures/Basic/HydraulicStructures.py
+++ b/src/Model/HydraulicStructures/Basic/HydraulicStructures.py
@@ -29,6 +29,7 @@ from Model.HydraulicStructures.Basic.Value import (
logger = logging.getLogger()
+
class BasicHS(SQLSubModel):
_sub_classes = [
BHSValue,
@@ -142,7 +143,7 @@ class BasicHS(SQLSubModel):
data['bhs_id'] = self.id
execute(
- "DELETE FROM hydraulic_structures_basic_value "+
+ "DELETE FROM hydraulic_structures_basic_value " +
f"WHERE bhs = {bhs_id}"
)
diff --git a/src/Model/HydraulicStructures/Basic/Types.py b/src/Model/HydraulicStructures/Basic/Types.py
index a976aaa3..98ded30b 100644
--- a/src/Model/HydraulicStructures/Basic/Types.py
+++ b/src/Model/HydraulicStructures/Basic/Types.py
@@ -16,18 +16,22 @@
# -*- coding: utf-8 -*-
-from Model.Except import NotImplementedMethodeError
-
from Model.HydraulicStructures.Basic.HydraulicStructures import (
BasicHS
)
+
from Model.HydraulicStructures.Basic.Value import (
BHSValue
)
+
class NotDefined(BasicHS):
- def __init__(self, id: int = -1, name: str = "", status=None):
- super(NotDefined, self).__init__(id=id, name=name, status=status)
+ def __init__(self, id: int = -1, name: str = "",
+ status=None):
+ super(NotDefined, self).__init__(
+ id=id, name=name,
+ status=status
+ )
self._type = "ND"
self._data = [
diff --git a/src/Model/HydraulicStructures/Basic/Value.py b/src/Model/HydraulicStructures/Basic/Value.py
index dccd41e5..ebf4744e 100644
--- a/src/Model/HydraulicStructures/Basic/Value.py
+++ b/src/Model/HydraulicStructures/Basic/Value.py
@@ -18,11 +18,12 @@
from Model.Tools.PamhyrDB import SQLSubModel
+
class BHSValue(SQLSubModel):
_sub_classes = []
_id_cnt = 0
- def __init__(self, name: str = "", type = float, value = 0.0,
+ def __init__(self, name: str = "", type=float, value=0.0,
status=None):
super(BHSValue, self).__init__()
@@ -117,7 +118,7 @@ class BHSValue(SQLSubModel):
"hydraulic_structures_basic_value(name, type, value, bhs) " +
"VALUES (" +
f"'{self._db_format(self._name)}', " +
- f"'{self._db_format(self._type_to_str(self._type))}', "+
+ f"'{self._db_format(self._type_to_str(self._type))}', " +
f"'{self._db_format(self._value)}', " +
f"{bhs_id}" +
")"
diff --git a/src/Model/HydraulicStructures/HydraulicStructures.py b/src/Model/HydraulicStructures/HydraulicStructures.py
index 6d1a4734..3cb68f97 100644
--- a/src/Model/HydraulicStructures/HydraulicStructures.py
+++ b/src/Model/HydraulicStructures/HydraulicStructures.py
@@ -30,6 +30,7 @@ from Model.HydraulicStructures.Basic.Types import (
logger = logging.getLogger()
+
class HydraulicStructure(SQLSubModel):
_sub_classes = [
BasicHS,
@@ -55,7 +56,10 @@ class HydraulicStructure(SQLSubModel):
self._enabled = True
self._data = []
- HydraulicStructure._id_cnt = max(HydraulicStructure._id_cnt + 1, self.id)
+ HydraulicStructure._id_cnt = max(
+ HydraulicStructure._id_cnt + 1,
+ self.id
+ )
@classmethod
def _db_create(cls, execute):
diff --git a/src/Model/HydraulicStructures/HydraulicStructuresList.py b/src/Model/HydraulicStructures/HydraulicStructuresList.py
index 0e1039fd..549d8074 100644
--- a/src/Model/HydraulicStructures/HydraulicStructuresList.py
+++ b/src/Model/HydraulicStructures/HydraulicStructuresList.py
@@ -22,6 +22,7 @@ from tools import trace, timer
from Model.Tools.PamhyrList import PamhyrModelList
from Model.HydraulicStructures.HydraulicStructures import HydraulicStructure
+
class HydraulicStructureList(PamhyrModelList):
_sub_classes = [
HydraulicStructure,
diff --git a/src/Model/InitialConditions/InitialConditions.py b/src/Model/InitialConditions/InitialConditions.py
index 439445fa..a71f3133 100644
--- a/src/Model/InitialConditions/InitialConditions.py
+++ b/src/Model/InitialConditions/InitialConditions.py
@@ -376,7 +376,7 @@ class InitialConditions(SQLSubModel):
* (abs(incline) ** (0.5)))
)
- elevation= max(
+ elevation = max(
profile.z_min() + height,
previous_elevation
)
@@ -422,7 +422,7 @@ class InitialConditions(SQLSubModel):
((width * 0.8) * strickler * (abs(incline) ** (0.5)))
) ** (0.6)
- elevation= max(
+ elevation = max(
profile.z_min() + height,
previous_elevation
)
diff --git a/src/Model/Network/Graph.py b/src/Model/Network/Graph.py
index e3616d0e..7836a89c 100644
--- a/src/Model/Network/Graph.py
+++ b/src/Model/Network/Graph.py
@@ -213,7 +213,7 @@ class Graph(object):
def is_enable_edge(self, edge):
return edge._enable
- #def get_edge_id(self, reach):
+ # def get_edge_id(self, reach):
# for i, e in enumerate(self.enable_edges):
# if e.id == reach.id:
# return i
diff --git a/src/Model/Reservoir/Reservoir.py b/src/Model/Reservoir/Reservoir.py
index 97a63113..ebf7e24c 100644
--- a/src/Model/Reservoir/Reservoir.py
+++ b/src/Model/Reservoir/Reservoir.py
@@ -94,7 +94,11 @@ class Reservoir(SQLSubModel):
new_reservoir._node = None
if node_id != -1:
- new_reservoir._node = next(filter(lambda n: n.id == node_id, data["nodes"]))
+ new_reservoir._node = next(
+ filter(
+ lambda n: n.id == node_id, data["nodes"]
+ )
+ )
new_data = []
table = execute(
diff --git a/src/Model/River.py b/src/Model/River.py
index 2ba5a54f..99cf8d21 100644
--- a/src/Model/River.py
+++ b/src/Model/River.py
@@ -242,7 +242,9 @@ class River(Graph, SQLSubModel):
self._parameters = {}
self._sediment_layers = SedimentLayerList(status=self._status)
self._reservoir = ReservoirList(status=self._status)
- self._hydraulic_structures = HydraulicStructureList(status=self._status)
+ self._hydraulic_structures = HydraulicStructureList(
+ status=self._status
+ )
@classmethod
def _db_create(cls, execute):
diff --git a/src/Model/Tools/PamhyrDict.py b/src/Model/Tools/PamhyrDict.py
index c8cab70a..31bc12a6 100644
--- a/src/Model/Tools/PamhyrDict.py
+++ b/src/Model/Tools/PamhyrDict.py
@@ -67,7 +67,7 @@ class PamhyrModelDict(SQLSubModel):
if key in self._dict:
v = self._dict[key]
- if type(v) == types.GeneratorType:
+ if type(v) is types.GeneratorType:
return list(v)
return v
diff --git a/src/Solver/Mage.py b/src/Solver/Mage.py
index 5dc59207..7326d674 100644
--- a/src/Solver/Mage.py
+++ b/src/Solver/Mage.py
@@ -453,9 +453,20 @@ class Mage(CommandLineSolver):
for hs in hydraulic_structures:
if hs.reach.is_enable:
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"{hs.basic_hydraulic_structure.type} {reach_id} {hs.kp:>12.3f} {params} {hs.name}\n")
+ 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"{hs.basic_hydraulic_structure.type} " +
+ f"{reach_id} {hs.kp:>12.3f} {params} " +
+ "{hs.name}\n"
+ )
return files
@@ -465,7 +476,11 @@ class Mage(CommandLineSolver):
qlog.put("Export REP file")
# Write header
- with mage_file_open(os.path.join(repertory, f"{name}.REP"), "w+") as f:
+ with mage_file_open(
+ os.path.join(
+ repertory, f"{name}.REP"
+ ), "w+"
+ ) as f:
f.write("confirmation=non\n")
for file in files:
@@ -832,12 +847,13 @@ class Mage8(Mage):
# Set data for profile RI
reach.set(ri, timestamp, key, d)
if key == "Z":
- profile = study.river.current_reach().reach.profile(ri)
- ptX,ptY = profile.get_water_limits(d)
+ profile = study.river\
+ .current_reach()\
+ .reach.profile(ri)
+ ptX, ptY = profile.get_water_limits(d)
reach.set(ri, timestamp, "ptX", ptX)
reach.set(ri, timestamp, "ptY", ptY)
-
endline()
end = newline().size <= 0
diff --git a/src/View/BoundaryCondition/Edit/Window.py b/src/View/BoundaryCondition/Edit/Window.py
index ccec087b..4bdbb5ae 100644
--- a/src/View/BoundaryCondition/Edit/Window.py
+++ b/src/View/BoundaryCondition/Edit/Window.py
@@ -160,7 +160,7 @@ class EditBoundaryConditionWindow(PamhyrWindow):
table_headers=headers,
editable_headers=self._data.header,
delegates={
- #"time": self._delegate_time,
+ # "time": self._delegate_time,
},
data=self._data,
undo=self._undo_stack,
diff --git a/src/View/BoundaryCondition/Table.py b/src/View/BoundaryCondition/Table.py
index 024dc288..aad78fc3 100644
--- a/src/View/BoundaryCondition/Table.py
+++ b/src/View/BoundaryCondition/Table.py
@@ -115,13 +115,13 @@ class ComboBoxDelegate(QItemDelegate):
class TableModel(PamhyrTableModel):
- def __init__(self, trad = None, **kwargs):
+ 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)
+ super(TableModel, self).__init__(trad=trad, **kwargs)
def _setup_lst(self):
self._lst = self._data.boundary_condition
diff --git a/src/View/HydraulicStructures/BasicHydraulicStructures/Table.py b/src/View/HydraulicStructures/BasicHydraulicStructures/Table.py
index 0522af55..983a5ad0 100644
--- a/src/View/HydraulicStructures/BasicHydraulicStructures/Table.py
+++ b/src/View/HydraulicStructures/BasicHydraulicStructures/Table.py
@@ -18,3 +18,160 @@
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.BasicHydraulicStructures.UndoCommand import (
+ SetNameCommand, SetTypeCommand,
+ AddCommand, DelCommand,
+)
+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 _setup_lst(self):
+ self._lst = self._data.basic_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[row].name
+ elif self._headers[column] == "type":
+ n = self._lst[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":
+ self._undo.push(
+ SetTypeCommand(
+ self._data, row, type
+ )
+ )
+ 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()
+ 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/BasicHydraulicStructures/Translate.py b/src/View/HydraulicStructures/BasicHydraulicStructures/Translate.py
index f2d74d02..b267fc42 100644
--- a/src/View/HydraulicStructures/BasicHydraulicStructures/Translate.py
+++ b/src/View/HydraulicStructures/BasicHydraulicStructures/Translate.py
@@ -21,3 +21,17 @@ from PyQt5.QtCore import QCoreApplication
from View.Tools.PamhyrTranslate import PamhyrTranslate
_translate = QCoreApplication.translate
+
+
+class BasicHydraulicStructuresTranslate(PamhyrTranslate):
+ def __init__(self):
+ super(BasicHydraulicStructuresTranslate, self).__init__()
+
+ self._sub_dict["long_types"] = {
+ "ND": _translate("BasicHydraulicStructures", "Not defined"),
+ }
+
+ self._sub_dict["table_headers"] = {
+ "name": _translate("BasicHydraulicStructures", "Name"),
+ "type": _translate("BasicHydraulicStructures", "Type"),
+ }
diff --git a/src/View/HydraulicStructures/BasicHydraulicStructures/UndoCommand.py b/src/View/HydraulicStructures/BasicHydraulicStructures/UndoCommand.py
index ca18efaa..2d7e4067 100644
--- a/src/View/HydraulicStructures/BasicHydraulicStructures/UndoCommand.py
+++ b/src/View/HydraulicStructures/BasicHydraulicStructures/UndoCommand.py
@@ -15,3 +15,104 @@
# along with this program. If not, see .
# -*- 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, reach):
+ QUndoCommand.__init__(self)
+
+ self._hs = hs
+ self._index = index
+ self._type = _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.basic_structure(self._index).convert(self._old)
+
+ def redo(self):
+ self._hs.basic_structure(self._index).convert(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(
+ self._tab,
+ range(self._row, self._row + len(self._bhs))
+ )
+
+ def redo(self):
+ for r in self._bhs:
+ self._hs.insert(self._row, r)
diff --git a/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py b/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py
index 43e78cef..a555c2bf 100644
--- a/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py
+++ b/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py
@@ -15,3 +15,207 @@
# along with this program. If not, see .
# -*- 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 (
+ TableModel, ComboBoxDelegate
+)
+
+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):
+ name = self._pamhyr_name + " - " + study.name
+
+ super(BasicHydraulicStructuresWindow, self).__init__(
+ title=name,
+ study=study,
+ config=config,
+ trad=BasicHydraulicStructuresTranslate(),
+ parent=parent
+ )
+
+ self._hash_data.append(data)
+
+ self._hs = data
+
+ self.setup_table()
+ self.setup_checkbox()
+ self.setup_plot()
+ self.setup_connections()
+
+ def setup_table(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,
+ )
+
+ 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_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)
+
+ self.plot_ac = PlotAC(
+ canvas=self.canvas,
+ river=self._study.river,
+ reach=None,
+ profile=None,
+ 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.stateChanged.connect(self._set_basic_structure_state)
+
+ table = self.find(QTableView, "tableView")
+ table.selectionModel()\
+ .selectionChanged\
+ .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):
+ row = self.index_selected_row()
+ if row is None:
+ self._checkbox.setEnabled(False)
+ else:
+ self._hs.basic_structure(row).enabled = self._checkbox.isChecked()
+
+ def update(self):
+ self._set_checkbox_state()
+ self._update_clear_plot()
+
+ def _update_clear_plot(self):
+ rows = self.index_selected_rows()
diff --git a/src/View/HydraulicStructures/PlotAC.py b/src/View/HydraulicStructures/PlotAC.py
index 35584203..028d6573 100644
--- a/src/View/HydraulicStructures/PlotAC.py
+++ b/src/View/HydraulicStructures/PlotAC.py
@@ -126,5 +126,5 @@ class PlotAC(PamhyrPlot):
def clear(self):
if self.line_kp is not None:
- self.line_kp.set_data([],[])
+ self.line_kp.set_data([], [])
self.canvas.figure.canvas.draw_idle()
diff --git a/src/View/HydraulicStructures/PlotKPC.py b/src/View/HydraulicStructures/PlotKPC.py
index 15a5a1a4..d3070c88 100644
--- a/src/View/HydraulicStructures/PlotKPC.py
+++ b/src/View/HydraulicStructures/PlotKPC.py
@@ -110,7 +110,6 @@ class PlotKPC(PamhyrPlot):
color='red', lw=1.
)
-
self.canvas.figure.tight_layout()
self.canvas.figure.canvas.draw_idle()
if self.toolbar is not None:
@@ -144,16 +143,15 @@ class PlotKPC(PamhyrPlot):
def clear(self):
if self.profile is not None:
- self.profile.set_data([],[])
+ self.profile.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.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.profile.set_data([], [])
self.canvas.figure.canvas.draw_idle()
-
diff --git a/src/View/HydraulicStructures/Table.py b/src/View/HydraulicStructures/Table.py
index e61d9094..58e08684 100644
--- a/src/View/HydraulicStructures/Table.py
+++ b/src/View/HydraulicStructures/Table.py
@@ -59,7 +59,9 @@ class ComboBoxDelegate(QItemDelegate):
val = []
if self._mode == "kp":
- reach = self._data.hydraulic_structures.get(index.row()).input_reach
+ reach = self._data.hydraulic_structures\
+ .get(index.row())\
+ .input_reach
if reach is not None:
val = list(
map(
@@ -138,6 +140,7 @@ class TableModel(PamhyrTableModel):
row = index.row()
column = index.column()
+ na = _translate("Hydraulic structure", "Not associated")
try:
if self._headers[column] == "name":
@@ -147,12 +150,18 @@ class TableModel(PamhyrTableModel):
)
)
elif self._headers[column] == "reach":
+ if value == na:
+ value = None
+
self._undo.push(
SetReachCommand(
self._lst, row, self._data.edge(value)
)
)
elif self._headers[column] == "kp":
+ if value == na:
+ value = None
+
self._undo.push(
SetKpCommand(
self._lst, row, value
diff --git a/src/View/HydraulicStructures/UndoCommand.py b/src/View/HydraulicStructures/UndoCommand.py
index 75e2886b..826cd268 100644
--- a/src/View/HydraulicStructures/UndoCommand.py
+++ b/src/View/HydraulicStructures/UndoCommand.py
@@ -99,6 +99,7 @@ class SetEnabledCommand(QUndoCommand):
logger.info(f"Undo {self._old} -> {self._new}")
self._h_s_lst.get(self._index).enabled = self._new
+
class AddCommand(QUndoCommand):
def __init__(self, h_s_lst, index):
QUndoCommand.__init__(self)
diff --git a/src/View/HydraulicStructures/Window.py b/src/View/HydraulicStructures/Window.py
index ce90eafd..7c139dd3 100644
--- a/src/View/HydraulicStructures/Window.py
+++ b/src/View/HydraulicStructures/Window.py
@@ -84,13 +84,13 @@ class HydraulicStructuresWindow(PamhyrWindow):
trad=self._trad,
data=self._study.river,
parent=self,
- mode = "reaches"
+ mode="reaches"
)
self._delegate_kp = ComboBoxDelegate(
trad=self._trad,
data=self._study.river,
parent=self,
- mode = "kp"
+ mode="kp"
)
table = self.find(QTableView, f"tableView")
@@ -177,7 +177,7 @@ class HydraulicStructuresWindow(PamhyrWindow):
table = self.find(QTableView, "tableView")
r = table.selectionModel().selectedRows()
- if len(r)>0:
+ if len(r) > 0:
return r[0]
else:
return None
@@ -186,7 +186,7 @@ class HydraulicStructuresWindow(PamhyrWindow):
table = self.find(QTableView, "tableView")
r = table.selectionModel().selectedRows()
- if len(r)>0:
+ if len(r) > 0:
return r[0].row()
else:
return None
@@ -233,7 +233,8 @@ class HydraulicStructuresWindow(PamhyrWindow):
rows = self.index_selected_rows()
for row in rows:
data = self._hs_lst.get(row)
-
+ print(row)
+ print(data)
if self.sub_window_exists(
BasicHydraulicStructuresWindow,
data=[self._study, None, data]
@@ -266,37 +267,43 @@ class HydraulicStructuresWindow(PamhyrWindow):
def update(self):
self._set_checkbox_state()
+ self._update_clear_plot()
+ def _update_clear_plot(self):
rows = self.index_selected_rows()
- if len(rows) > 0 and len(self._hs_lst) > 0:
- reach = self._hs_lst.get(rows[0]).input_reach
- else:
- reach=None
- self.plot_kpc.clear()
- self.plot_ac.clear()
+ if len(rows) == 0 or len(self._hs_lst) == 0:
+ self._update_clear_all()
return
- profile_kp = self._hs_lst.get(rows[0]).input_kp
- if profile_kp is None or profile_kp == "Not associated":
- profile = None
- self.plot_ac.clear()
- self.plot_kpc.clear_profile()
- else:
- profile = reach.reach.get_profiles_from_kp(float(profile_kp))
-
- if reach is not None and reach != "Not associated":
+ reach = self._hs_lst.get(rows[0]).input_reach
+ if reach is not None:
self.plot_kpc.set_reach(reach)
self.plot_ac.set_reach(reach)
- else:
- self.plot_kpc.clear()
- self.plot_ac.clear()
- return
+ profile_kp = self._hs_lst.get(rows[0]).input_kp
+ if profile_kp is not None:
+ profiles = reach.reach\
+ .get_profiles_from_kp(
+ float(profile_kp)
+ )
- if profile is not None:
- self.plot_kpc.set_profile(profile[0])
- self.plot_ac.set_profile(profile[0])
+ if profiles is not None:
+ profile = profiles[0]
+
+ self.plot_kpc.set_profile(profile)
+ self.plot_ac.set_profile(profile)
+ else:
+ self._update_clear_profile()
+ else:
+ self._update_clear_profile()
else:
- self.plot_ac.clear()
- self.plot_kpc.clear_profile()
+ self._update_clear_all()
+
+ def _update_clear_all(self):
+ self.plot_kpc.clear()
+ self.plot_ac.clear()
+
+ def _update_clear_profile(self):
+ self.plot_ac.clear()
+ self.plot_kpc.clear_profile()
diff --git a/src/View/LateralContribution/Edit/Window.py b/src/View/LateralContribution/Edit/Window.py
index 745fd15e..897703a4 100644
--- a/src/View/LateralContribution/Edit/Window.py
+++ b/src/View/LateralContribution/Edit/Window.py
@@ -101,7 +101,7 @@ class EditLateralContributionWindow(PamhyrWindow):
table_headers=headers,
editable_headers=self._data.header,
delegates={
- #"time": self._delegate_time,
+ # "time": self._delegate_time,
},
data=self._data,
undo=self._undo_stack,
diff --git a/src/View/MainWindow.py b/src/View/MainWindow.py
index a9d98062..89df56f3 100644
--- a/src/View/MainWindow.py
+++ b/src/View/MainWindow.py
@@ -195,7 +195,8 @@ 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_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,
@@ -282,8 +283,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
Nothing
"""
self.update_enable_action()
- # Maximise window
- #self.showMaximized()
+ # self.showMaximized()
def set_debug_lvl(self, debug=True):
if debug:
@@ -638,7 +638,10 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
):
return
- hydraulic_structures = HydraulicStructuresWindow(study=self._study, parent=self)
+ hydraulic_structures = HydraulicStructuresWindow(
+ study=self._study,
+ parent=self
+ )
hydraulic_structures.show()
def open_lateral_contrib(self):
@@ -648,7 +651,10 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
):
return
- lateral = LateralContributionWindow(study=self._study, parent=self)
+ lateral = LateralContributionWindow(
+ study=self._study,
+ parent=self
+ )
lateral.show()
def open_stricklers(self):
diff --git a/src/View/Reservoir/Edit/Plot.py b/src/View/Reservoir/Edit/Plot.py
index 8f8f49b8..8c75a199 100644
--- a/src/View/Reservoir/Edit/Plot.py
+++ b/src/View/Reservoir/Edit/Plot.py
@@ -69,7 +69,7 @@ class Plot(PamhyrPlot):
)
# Plot label
- #header = self.data.header
+ # header = self.data.header
self.canvas.axes.set_xlabel(
self._table_headers["z"], color='black', fontsize=10
)
diff --git a/src/View/Reservoir/Edit/Window.py b/src/View/Reservoir/Edit/Window.py
index 34724bea..865ae6c8 100644
--- a/src/View/Reservoir/Edit/Window.py
+++ b/src/View/Reservoir/Edit/Window.py
@@ -88,18 +88,13 @@ class EditReservoirWindow(PamhyrWindow):
def setup_table(self):
headers = {}
table_headers = self._trad.get_dict("table_headers")
- #for h in self._data.header:
- #headers[h] = table_headers[h]
table = self.find(QTableView, "tableView")
self._table = TableModel(
table_view=table,
table_headers=table_headers,
editable_headers=table_headers,
- #editable_headers=self._data.header,
- delegates={
- #"time": self._delegate_time,
- },
+ delegates={},
data=self._data,
undo=self._undo_stack,
opt_data=self._study.time_system
@@ -181,7 +176,7 @@ class EditReservoirWindow(PamhyrWindow):
rows = self.index_selected_rows()
table = []
- #table.append(self._data.header)
+ # table.append(self._data.header)
table.append(self._trad.get_dict("table_headers"))
data = self._data.data
diff --git a/src/View/Results/PlotH.py b/src/View/Results/PlotH.py
index 5709efb4..3494cfa5 100644
--- a/src/View/Results/PlotH.py
+++ b/src/View/Results/PlotH.py
@@ -175,12 +175,12 @@ class PlotH(PamhyrPlot):
def set_timestamp(self, timestamp):
self._current_timestamp = timestamp
- #self.update()
+ # self.update()
def update(self):
reach = self.results.river.reach(self._current_reach_id)
profile = reach.profile(self._current_profile_id)
x = self.ts
y = profile.get_key("Q")
- self._line.set_data(x,y)
+ self._line.set_data(x, y)
self.canvas.figure.canvas.draw_idle()
diff --git a/src/View/Results/PlotKPC.py b/src/View/Results/PlotKPC.py
index 93f91c9f..34ed91f9 100644
--- a/src/View/Results/PlotKPC.py
+++ b/src/View/Results/PlotKPC.py
@@ -105,8 +105,14 @@ class PlotKPC(PamhyrPlot):
)
self.profile, = self.canvas.axes.plot(
- [kp[self._current_profile_id], kp[self._current_profile_id]],
- [z_max[self._current_profile_id],z_min[self._current_profile_id]],
+ [
+ kp[self._current_profile_id],
+ kp[self._current_profile_id]
+ ],
+ [
+ z_max[self._current_profile_id],
+ z_min[self._current_profile_id]
+ ],
color='red', lw=1.
)
@@ -137,7 +143,13 @@ class PlotKPC(PamhyrPlot):
z_min = reach.geometry.get_z_min()
z_max = reach.geometry.get_z_max()
self.profile.set_data(
- [kp[self._current_profile_id], kp[self._current_profile_id]],
- [z_max[self._current_profile_id],z_min[self._current_profile_id]]
+ [
+ kp[self._current_profile_id],
+ kp[self._current_profile_id]
+ ],
+ [
+ z_max[self._current_profile_id],
+ z_min[self._current_profile_id]
+ ]
)
self.canvas.figure.canvas.draw_idle()
diff --git a/src/View/Results/PlotXY.py b/src/View/Results/PlotXY.py
index 559fd9a6..3d0e2281 100644
--- a/src/View/Results/PlotXY.py
+++ b/src/View/Results/PlotXY.py
@@ -136,10 +136,14 @@ class PlotXY(PamhyrPlot):
poly_x = [0]
poly_y = [0]
- self.fill = self.canvas.axes.fill(poly_x, poly_y, color='skyblue', alpha=0.7)
+ self.fill = self.canvas.axes.fill(
+ poly_x, poly_y,
+ color='skyblue',
+ alpha=0.7
+ )
- #self.canvas.axes.autoscale_view(True, True, True)
- #self.canvas.axes.autoscale()
+ # self.canvas.axes.autoscale_view(True, True, True)
+ # self.canvas.axes.autoscale()
self.canvas.figure.tight_layout()
self.canvas.figure.canvas.draw_idle()
if self.toolbar is not None:
@@ -166,7 +170,7 @@ class PlotXY(PamhyrPlot):
# Current profile
profile = reach.profile(self._current_profile_id).geometry
- self.plot_selected.set_data(profile.x(),profile.y())
+ self.plot_selected.set_data(profile.x(), profile.y())
self.plot_selected.set_visible(True)
self.canvas.draw_idle()
@@ -196,12 +200,12 @@ class PlotXY(PamhyrPlot):
poly_r_x.append(ptY.x)
poly_r_y.append(ptY.y)
- #self.canvas.axes.plot(
- #x, y, lw=1.,
- #color='b',
- #markersize=1,
- #marker='o'
- #)
+ # self.canvas.axes.plot(
+ # x, y, lw=1.,
+ # color='b',
+ # markersize=1,
+ # marker='o'
+ # )
poly_x = poly_l_x + list(reversed(poly_r_x))
poly_y = poly_l_y + list(reversed(poly_r_y))
diff --git a/src/View/Results/Window.py b/src/View/Results/Window.py
index 9933f189..68a38b34 100644
--- a/src/View/Results/Window.py
+++ b/src/View/Results/Window.py
@@ -125,9 +125,13 @@ class ResultsWindow(PamhyrWindow):
self._slider_time.setValue(len(self._timestamps) - 1)
self._icon_start = QIcon()
- self._icon_start.addPixmap(QPixmap('./src/View/ui/ressources/media-playback-start.png'))
+ self._icon_start.addPixmap(
+ QPixmap('./src/View/ui/ressources/media-playback-start.png')
+ )
self._icon_pause = QIcon()
- self._icon_pause.addPixmap(QPixmap('./src/View/ui/ressources/media-playback-pause.png'))
+ self._icon_pause.addPixmap(
+ QPixmap('./src/View/ui/ressources/media-playback-pause.png')
+ )
self._button_play = self.find(QPushButton, f"playButton")
self._button_play.setIcon(self._icon_start)
self._button_back = self.find(QPushButton, f"backButton")
diff --git a/src/tools.py b/src/tools.py
index b6f78857..1ad8c382 100644
--- a/src/tools.py
+++ b/src/tools.py
@@ -67,6 +67,7 @@ def logger_color_reset():
return f"{Style.RESET_ALL}"
return ""
+
def logger_exception(exception):
logger.error(
f"[{Fore.RED}ERROR{Style.RESET_ALL}] " +
diff --git a/tests.sh b/tests.sh
index 06c8fd84..ff235027 100755
--- a/tests.sh
+++ b/tests.sh
@@ -16,7 +16,7 @@ cd ..
echo " PEP8"
-pycodestyle ./src
+pycodestyle --exclude="*_to_*.py" ./src
if [ $? -eq 0 ]
then