From 8d3bfa4c8c3602b21325e90ea8c30b5480316858 Mon Sep 17 00:00:00 2001
From: Pierre-Antoine Rouby <pierre-antoine.rouby@inrae.fr>
Date: Fri, 28 Apr 2023 16:29:31 +0200
Subject: [PATCH] BC: Add BC list object and some change.

---
 .../BoundaryCondition/BoundaryCondition.py    | 42 +++++++--
 src/Model/Network/Node.py                     | 10 ++-
 src/Model/River.py                            | 12 ++-
 .../BoundaryConditionWindow.py                | 85 +++++++++++++++++++
 4 files changed, 136 insertions(+), 13 deletions(-)

diff --git a/src/Model/BoundaryCondition/BoundaryCondition.py b/src/Model/BoundaryCondition/BoundaryCondition.py
index 17b7336f..b3ebd29a 100644
--- a/src/Model/BoundaryCondition/BoundaryCondition.py
+++ b/src/Model/BoundaryCondition/BoundaryCondition.py
@@ -1,7 +1,30 @@
 # -*- coding: utf-8 -*-
 
+from copy import copy
+
 from Model.Except import NotImplementedMethodeError
 
+class BoundaryConditionList(object):
+    def __init__(self):
+        self._data = []
+
+    def __len__(self):
+        return len(self._data)
+
+    def __getitem__(self, index):
+        return self._data[index]
+
+    def __setitem__(self, index, value):
+        self._data[index] = value
+
+    def __copy__(self):
+        new = BoundaryConditionList()
+        new._data = self._data.copy()
+        return new
+
+    def copy(self):
+        return copy(self)
+
 class BoundaryCondition(object):
     def __init__(self, name:str = ""):
         super(BoundaryCondition, self).__init__()
@@ -10,8 +33,8 @@ class BoundaryCondition(object):
         self._type = ""
         self._node = None
         self._data = []
-        self.header = []
-        self.types = [int, float]
+        self._header = []
+        self._types = [int, float]
 
     @property
     def name(self):
@@ -68,16 +91,19 @@ class BoundaryCondition(object):
     def sort(self, _reverse):
         self._data.sort(reverse=_reverse)
 
+    def get_i(self, index):
+        return self.data[index]
+
     def _set_i_c_v(self, index, column, value):
         v = list(self._data[index])
-        v[column] = self.types[column](value)
+        v[column] = self._types[column](value)
         self._data[index] = tuple(v)
 
     def set_i_0(self, index:int, value):
-        self._set_i_c_v(index, 0, value):
+        self._set_i_c_v(index, 0, value)
 
     def set_i_1(self, index:int, value):
-        self._set_i_c_v(index, 1, value):
+        self._set_i_c_v(index, 1, value)
 
     def convert(self, cls):
         new = cls(name = self.name)
@@ -86,14 +112,14 @@ class BoundaryCondition(object):
 
         for i in [0,1]:
             for j in [0,1]:
-                if self.header[i] == new.header[j]:
+                if self._header[i] == new.header[j]:
                     for ind, v in self.data:
                         new._set_i_c_v(ind, j, v[i])
 
         return new
 
     def _default_0(self):
-        return self.types[0](0)
+        return self._types[0](0)
 
     def _default_1(self):
-        return self.types[1](0.0)
+        return self._types[1](0.0)
diff --git a/src/Model/Network/Node.py b/src/Model/Network/Node.py
index 32bff349..8adf7ccb 100644
--- a/src/Model/Network/Node.py
+++ b/src/Model/Network/Node.py
@@ -8,14 +8,14 @@ class Node(object):
         super(Node, self).__init__()
 
         self.id = id
-        self.name = name
+        self._name = name
         self.pos = Point(x, y)
 
     def __getitem__(self, name):
         ret = None
 
         if name == "name":
-            ret = self.name
+            ret = self._name
         elif name == "id":
             ret = self.id
         elif name == "pos":
@@ -25,10 +25,14 @@ class Node(object):
 
     def __setitem__(self, name, value):
         if name == "name":
-            self.name = value
+            self._name = value
         elif name == "id":
             self.id = value
 
+    @property
+    def name(self):
+        return self._name
+
     def setPos(self, x, y):
         self.pos.x = x
         self.pos.y = y
diff --git a/src/Model/River.py b/src/Model/River.py
index daaf0afb..51f9b2ef 100644
--- a/src/Model/River.py
+++ b/src/Model/River.py
@@ -7,7 +7,11 @@ from Model.Network.Graph import Graph
 from Model.Geometry.Profile import Profile
 from Model.Geometry.Reach import Reach
 
-from Model.BoundaryCondition.BoundaryCondition import BoundaryCondition
+from Model.BoundaryCondition.BoundaryCondition import (
+    BoundaryCondition,
+    BoundaryConditionList,
+)
+
 
 class RiverNode(Node):
     def __init__(self, id:str, name:str,
@@ -53,7 +57,11 @@ class River(Graph):
         self._edge_ctor = RiverReach
 
         self._current_reach = None
-        self._boundary_condition = []
+        self._boundary_condition = BoundaryConditionList()
+
+    @property
+    def boundary_condition(self):
+        return self._boundary_condition.copy()
 
     def has_current_reach(self):
         return self._current_reach is not None
diff --git a/src/View/BoundaryCondition/BoundaryConditionWindow.py b/src/View/BoundaryCondition/BoundaryConditionWindow.py
index 13f3f288..70f8b346 100644
--- a/src/View/BoundaryCondition/BoundaryConditionWindow.py
+++ b/src/View/BoundaryCondition/BoundaryConditionWindow.py
@@ -5,6 +5,7 @@ from View.ListedSubWindow import ListedSubWindow
 
 from PyQt5.QtCore import (
     Qt, QVariant, QAbstractTableModel,
+    QCoreApplication,
 )
 
 from PyQt5.QtWidgets import (
@@ -14,6 +15,84 @@ from PyQt5.QtWidgets import (
 
 from View.BoundaryCondition.EditBoundaryConditionWindow import EditBoundaryConditionWindow
 
+_translate = QCoreApplication.translate
+
+long_types = {
+    "PC": _translate("BoundaryCondition", "Ponctual contribution"),
+    "TZ": _translate("BoundaryCondition", "Time over Z"),
+    "TD": _translate("BoundaryCondition", "Time over Debit"),
+    "ZD": _translate("BoundaryCondition", "Z over Debit"),
+}
+
+table_headers = {
+    "name": _translate("BoundaryCondition", "Name"),
+    "type": _translate("BoundaryCondition", "Type"),
+    "node": _translate("BoundaryCondition", "Node")
+}
+
+class TableModel(QAbstractTableModel):
+    def __init__(self, data=None):
+        super(QAbstractTableModel, self).__init__()
+        self._headers = list(table_headers.keys())
+        self._data = data
+        self._lst = self._data.boundary_condition
+
+    def flags(self, index):
+        options = Qt.ItemIsEnabled | Qt.ItemIsSelectable
+        options |= Qt.ItemIsEditable
+
+        return options
+
+    def rowCount(self, parent):
+        return len(self._lst)
+
+    def columnCount(self, parent):
+        return len(self._headers)
+
+    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":
+            t = self.lst[row].bctype
+            return long_types[t]
+        elif self._headers[column] == "node":
+            n = self.lst[row].node
+            if n is None:
+                return "-"
+            return n.name
+
+        return QVariant()
+
+    def headerData(self, section, orientation, role):
+        if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
+            return table_headers[self._headers[section]]
+
+        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()
+
+        if self._headers[column] == "name":
+            self.lst[row].name = value
+        elif self._headers[column] == "type":
+            self.lst[row].bctype = value
+        elif self._headers[column] == "node":
+            self.lst[row].node = value
+
+        self.dataChanged.emit(index, index)
+        return True
+
+
 class BoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
     def __init__(self, title="BoundaryConditions", study=None, parent=None):
         super(BoundaryConditionWindow, self).__init__(
@@ -22,6 +101,12 @@ class BoundaryConditionWindow(ASubMainWindow, ListedSubWindow):
 
         self._study = study
 
+        table = self.find(QTableView, "tableView")
+        self._table = TableModel(
+            data = self._study.river
+        )
+        table.setModel(self._table)
+
         self.ui.setWindowTitle(title)
 
     def edit(self):
-- 
GitLab