From 7df0750c58e09c034ce7a82aedbcc7d9320aa61c Mon Sep 17 00:00:00 2001
From: Youcef AOUAD <youcef.aouad@inrae.fr>
Date: Mon, 10 Jun 2024 16:26:56 +0200
Subject: [PATCH] INI Default

---
 .../InitialConditionsAdisTS.py                |   4 +-
 .../InitialConditionsAdisTSList.py            |   6 +
 src/Model/River.py                            |   4 +
 .../DialogDischarge.py                        |  54 -----
 .../InitialConditionsAdisTS/DialogHeight.py   |  54 -----
 src/View/InitialConditionsAdisTS/PlotDKP.py   | 107 ----------
 .../InitialConditionsAdisTS/PlotDischarge.py  |  69 ------
 src/View/InitialConditionsAdisTS/Table.py     |   5 +-
 .../InitialConditionsAdisTS/TableDefault.py   | 149 +++++++++++++
 src/View/InitialConditionsAdisTS/Window.py    | 197 ++----------------
 src/View/InitialConditionsAdisTS/translate.py |  26 +--
 src/View/Pollutants/Table.py                  |   4 +-
 src/View/Pollutants/UndoCommand.py            |  18 +-
 src/View/Pollutants/Window.py                 |  24 +--
 src/View/Translate.py                         |   2 +
 src/View/ui/InitialConditionsAdisTS.ui        |  99 +++++++++
 tests_cases/Enlargement/Enlargement.pamhyr    | Bin 184320 -> 184320 bytes
 17 files changed, 325 insertions(+), 497 deletions(-)
 delete mode 100644 src/View/InitialConditionsAdisTS/DialogDischarge.py
 delete mode 100644 src/View/InitialConditionsAdisTS/DialogHeight.py
 delete mode 100644 src/View/InitialConditionsAdisTS/PlotDKP.py
 delete mode 100644 src/View/InitialConditionsAdisTS/PlotDischarge.py
 create mode 100644 src/View/InitialConditionsAdisTS/TableDefault.py
 create mode 100644 src/View/ui/InitialConditionsAdisTS.ui

diff --git a/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTS.py b/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTS.py
index d1a78587..d8bab326 100644
--- a/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTS.py
+++ b/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTS.py
@@ -35,7 +35,7 @@ class InitialConditionsAdisTS(SQLSubModel):
     _id_cnt = 0
 
     def __init__(self, id: int = -1, name: str = "default",
-                 status=None):
+                 pollutant: int = -1, status=None):
         super(InitialConditionsAdisTS, self).__init__()
 
         self._status = status
@@ -46,7 +46,7 @@ class InitialConditionsAdisTS(SQLSubModel):
             self.id = id
 
         self._name = name
-        self._pollutant = None
+        self._pollutant = pollutant
         self._concentration = None
         self._eg = None
         self._em = None
diff --git a/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTSList.py b/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTSList.py
index 9c30d5b7..e45aba04 100644
--- a/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTSList.py
+++ b/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTSList.py
@@ -51,6 +51,12 @@ class InitialConditionsAdisTSList(PamhyrModelList):
 
         return True
 
+    def new(self, index, pollutant):
+        n = InitialConditionsAdisTS(pollutant=pollutant, status=self._status)
+        self._lst.insert(index, n)
+        self._status.modified()
+        return n
+
 
 
 
diff --git a/src/Model/River.py b/src/Model/River.py
index 2bef4b3b..420a8c70 100644
--- a/src/Model/River.py
+++ b/src/Model/River.py
@@ -495,6 +495,10 @@ Last export at: @date."""
     def Pollutants(self):
         return self._Pollutants
 
+    @property
+    def initial_conditions_adists(self):
+        return self._InitialConditionsAdisTS
+
     def get_params(self, solver):
         if solver in self._parameters:
             return self._parameters[solver]
diff --git a/src/View/InitialConditionsAdisTS/DialogDischarge.py b/src/View/InitialConditionsAdisTS/DialogDischarge.py
deleted file mode 100644
index 9b63bdab..00000000
--- a/src/View/InitialConditionsAdisTS/DialogDischarge.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# DialogDischarge.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 View.Tools.PamhyrWindow import PamhyrDialog
-
-from PyQt5.QtGui import (
-    QKeySequence,
-)
-
-from PyQt5.QtCore import (
-    Qt, QVariant, QAbstractTableModel,
-)
-
-from PyQt5.QtWidgets import (
-    QDialogButtonBox, QComboBox, QUndoStack, QShortcut,
-    QDoubleSpinBox,
-)
-
-
-class DischargeDialog(PamhyrDialog):
-    _pamhyr_ui = "InitialConditions_Dialog_Generator_Discharge"
-    _pamhyr_name = "Discharge"
-
-    def __init__(self, title="Discharge", trad=None, parent=None):
-        super(DischargeDialog, self).__init__(
-            title=trad[self._pamhyr_name],
-            options=[],
-            trad=trad,
-            parent=parent
-        )
-
-        self.value = None
-
-    def accept(self):
-        self.value = self.find(QDoubleSpinBox, "doubleSpinBox").value()
-        super().accept()
-
-    def reject(self):
-        self.close()
diff --git a/src/View/InitialConditionsAdisTS/DialogHeight.py b/src/View/InitialConditionsAdisTS/DialogHeight.py
deleted file mode 100644
index 40821232..00000000
--- a/src/View/InitialConditionsAdisTS/DialogHeight.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# DialogHeight.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 View.Tools.PamhyrWindow import PamhyrDialog
-
-from PyQt5.QtGui import (
-    QKeySequence,
-)
-
-from PyQt5.QtCore import (
-    Qt, QVariant, QAbstractTableModel,
-)
-
-from PyQt5.QtWidgets import (
-    QDialogButtonBox, QComboBox, QUndoStack, QShortcut,
-    QDoubleSpinBox,
-)
-
-
-class HeightDialog(PamhyrDialog):
-    _pamhyr_ui = "InitialConditions_Dialog_Generator_Height"
-    _pamhyr_name = "Height"
-
-    def __init__(self, trad=None, parent=None):
-        super(HeightDialog, self).__init__(
-            title=trad[self._pamhyr_name],
-            options=[],
-            trad=trad,
-            parent=parent
-        )
-
-        self.value = None
-
-    def accept(self):
-        self.value = self.find(QDoubleSpinBox, "doubleSpinBox").value()
-        super().accept()
-
-    def reject(self):
-        self.close()
diff --git a/src/View/InitialConditionsAdisTS/PlotDKP.py b/src/View/InitialConditionsAdisTS/PlotDKP.py
deleted file mode 100644
index d29356fa..00000000
--- a/src/View/InitialConditionsAdisTS/PlotDKP.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# PlotDKP.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
-from View.Tools.PamhyrPlot import PamhyrPlot
-
-from PyQt5.QtCore import (
-    QCoreApplication
-)
-
-logger = logging.getLogger()
-
-_translate = QCoreApplication.translate
-
-
-class PlotDKP(PamhyrPlot):
-    def __init__(self, canvas=None, trad=None, toolbar=None,
-                 data=None, parent=None):
-        super(PlotDKP, self).__init__(
-            canvas=canvas,
-            trad=trad,
-            data=data,
-            toolbar=toolbar,
-            parent=parent
-        )
-
-        self.label_x = self._trad["kp"]
-        self.label_y = self._trad["elevation"]
-
-        self._isometric_axis = False
-
-        self._auto_relim_update = True
-        self._autoscale_update = True
-
-    @timer
-    def draw(self, highlight=None):
-        self.init_axes()
-
-        if self.data is None:
-            return
-
-        self.draw_river_bottom()
-        self.draw_water()
-
-        self.idle()
-        self._init = True
-
-    def draw_river_bottom(self):
-        kp = self.data.reach.reach.get_kp()
-        z_min = self.data.reach.reach.get_z_min()
-
-        self.line_kp_zmin = self.canvas.axes.plot(
-            kp, z_min,
-            color=self.color_plot_river_bottom,
-            lw=1.
-        )
-
-    def draw_water(self):
-        if len(self.data) != 0:
-            kp = self.data.get_kp()
-            elevation = self.data.get_elevation()
-
-            self.line_kp_elevation = self.canvas.axes.plot(
-                kp, elevation,
-                color=self.color_plot_river_water,
-                **self.plot_default_kargs
-            )
-
-            z_min = self.data.reach.reach.get_z_min()
-            geometry_kp = self.data.reach.reach.get_kp()
-
-            filtred_elevation = list(
-                map(
-                    lambda x: elevation[x[0]],
-                    filter(
-                        lambda x: x[1] in geometry_kp,
-                        enumerate(kp)
-                    )
-                )
-            )
-
-            self.collection = self.canvas.axes.fill_between(
-                geometry_kp, z_min, filtred_elevation,
-                color=self.color_plot_river_water_zone,
-                alpha=0.7, interpolate=True
-            )
-
-    @timer
-    def update(self, ind=None):
-        self.draw()
diff --git a/src/View/InitialConditionsAdisTS/PlotDischarge.py b/src/View/InitialConditionsAdisTS/PlotDischarge.py
deleted file mode 100644
index 7c43c1e5..00000000
--- a/src/View/InitialConditionsAdisTS/PlotDischarge.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# PlotDischarge.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
-
-
-class PlotDischarge(PamhyrPlot):
-    def __init__(self, canvas=None, trad=None, toolbar=None,
-                 data=None, parent=None):
-        super(PlotDischarge, self).__init__(
-            canvas=canvas,
-            trad=trad,
-            data=data,
-            toolbar=toolbar,
-            parent=parent
-        )
-
-        self.label_x = self._trad["kp"]
-        self.label_y = self._trad["discharge"]
-
-        self._isometric_axis = False
-
-        self._auto_relim_update = True
-        self._autoscale_update = True
-
-    @timer
-    def draw(self):
-        self.init_axes()
-
-        if self.data is None:
-            return
-
-        self.draw_data()
-
-        self.idle()
-        self._init = True
-
-    def draw_data(self):
-        kp = self.data.reach.reach.get_kp()
-
-        if len(self.data) != 0:
-            kp = self.data.get_kp()
-            discharge = self.data.get_discharge()
-
-            self.line_kp_zmin = self.canvas.axes.plot(
-                kp, discharge,
-                color=self.color_plot,
-                **self.plot_default_kargs
-            )
-
-    @timer
-    def update(self, ind=None):
-        self.draw()
diff --git a/src/View/InitialConditionsAdisTS/Table.py b/src/View/InitialConditionsAdisTS/Table.py
index 5461e862..c2c8af48 100644
--- a/src/View/InitialConditionsAdisTS/Table.py
+++ b/src/View/InitialConditionsAdisTS/Table.py
@@ -47,11 +47,14 @@ _translate = QCoreApplication.translate
 
 
 class ComboBoxDelegate(QItemDelegate):
-    def __init__(self, reach=None, parent=None):
+    def __init__(self, data=None, reach=None, parent=None, mode="reaches"):
         super(ComboBoxDelegate, self).__init__(parent)
 
         self._reach = reach.reach
 
+        self._data = data
+        self._mode = mode
+
     def createEditor(self, parent, option, index):
         self.editor = QComboBox(parent)
 
diff --git a/src/View/InitialConditionsAdisTS/TableDefault.py b/src/View/InitialConditionsAdisTS/TableDefault.py
new file mode 100644
index 00000000..03c90b09
--- /dev/null
+++ b/src/View/InitialConditionsAdisTS/TableDefault.py
@@ -0,0 +1,149 @@
+# 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,
+)
+
+from View.Tools.PamhyrTable import PamhyrTableModel
+
+from View.InitialConditionsAdisTS.UndoCommand import (
+    SetCommand, AddCommand, DelCommand,
+    SortCommand, MoveCommand, InsertCommand,
+    DuplicateCommand, GenerateCommand,
+)
+
+logger = logging.getLogger()
+
+_translate = QCoreApplication.translate
+
+class InitialConditionTableDefaultModel(PamhyrTableModel):
+    def __init__(self, **kwargs):
+        super(InitialConditionTableDefaultModel, self).__init__(**kwargs)
+
+    def data(self, index, role):
+        if role != Qt.ItemDataRole.DisplayRole:
+            return QVariant()
+
+        row = index.row()
+        column = index.column()
+
+        if self._headers[column] is "name":
+            return self._data[row].name
+        elif self._headers[column] is "concentration":
+            n = self._data[row].concentration
+            if n is None:
+                return self._trad['not_associated']
+            return n
+        elif self._headers[column] is "eg":
+            n = self._data[row].eg
+            if n is None:
+                return self._trad['not_associated']
+            return n
+        elif self._headers[column] is "em":
+            n = self._data[row].em
+            if n is None:
+                return self._trad['not_associated']
+            return n
+        elif self._headers[column] is "ed":
+            n = self._data[row].ed
+            if n is None:
+                return self._trad['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] is not None:
+                self._undo.push(
+                    SetCommand(
+                        self._lst, row, self._headers[column], value
+                    )
+                )
+        except Exception as e:
+            logger.info(e)
+            logger.debug(traceback.format_exc())
+
+        self.dataChanged.emit(index, index)
+        return True
+
+    def paste(self, index, header, data):
+        if len(header) != 0:
+            logger.error("Unexpected header in IC past data")
+            return
+
+        if len(data) == 0:
+            logger.error("Empty data")
+            return
+
+        if len(data[0]) != 3:
+            logger.error(f"Unexpected data size: [{data[0]}, ...]")
+            return
+
+        self.layoutAboutToBeChanged.emit()
+
+        self._undo.push(
+            InsertCommand(
+                self._lst, index,
+                list(
+                    map(
+                        lambda d: self._lst.new_from_data(*d),
+                        data
+                    )
+                )
+            )
+        )
+
+        self.layoutAboutToBeChanged.emit()
+        self.layoutChanged.emit()
+
+    def undo(self):
+        self._undo.undo()
+        self.layoutChanged.emit()
+
+    def redo(self):
+        self._undo.redo()
+        self.layoutChanged.emit()
+
+    def generate(self, generator, param):
+        self._undo.push(
+            GenerateCommand(
+                self._lst, generator, param
+            )
+        )
+        self.layoutChanged.emit()
diff --git a/src/View/InitialConditionsAdisTS/Window.py b/src/View/InitialConditionsAdisTS/Window.py
index 9562f68d..93630c45 100644
--- a/src/View/InitialConditionsAdisTS/Window.py
+++ b/src/View/InitialConditionsAdisTS/Window.py
@@ -48,19 +48,11 @@ from View.InitialConditionsAdisTS.UndoCommand import (
     DuplicateCommand,
 )
 
-from View.InitialConditionsAdisTS.Table import (
-    InitialConditionTableModel, ComboBoxDelegate,
+from View.InitialConditionsAdisTS.TableDefault import (
+    InitialConditionTableDefaultModel,
 )
 
-from View.Tools.Plot.PamhyrCanvas import MplCanvas
-from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
-
-from View.InitialConditionsAdisTS.PlotDKP import PlotDKP
-from View.InitialConditionsAdisTS.PlotDischarge import PlotDischarge
-from View.InitialConditionsAdisTS.translate import ICTranslate
-from View.InitialConditionsAdisTS.DialogHeight import HeightDialog
-from View.InitialConditionsAdisTS.DialogDischarge import DischargeDialog
-from View.Results.ReadingResultsDialog import ReadingResultsDialog
+from View.InitialConditionsAdisTS.translate import IcAdisTSTranslate
 
 from Solver.Mage import Mage8
 
@@ -69,25 +61,23 @@ _translate = QCoreApplication.translate
 logger = logging.getLogger()
 
 
-class InitialConditionsWindow(PamhyrWindow):
-    _pamhyr_ui = "InitialConditions"
-    _pamhyr_name = "Initial condition"
-
-    def __init__(self, study=None, config=None, reach=None, parent=None):
-        trad = ICTranslate()
+class InitialConditionsAdisTSWindow(PamhyrWindow):
+    _pamhyr_ui = "InitialConditionsAdisTS"
+    _pamhyr_name = "Initial condition AdisTS"
 
-        if reach is not None:
-            self._reach = reach
-        else:
-            self._reach = study.river.current_reach()
+    def __init__(self, data=None, study=None, config=None, parent=None):
+        self._data = []
+        self._data.append(data)
+        #print(self._data.name, self._data.concentration, self._data.eg, self._data.em, self._data.ed)
+        trad = IcAdisTSTranslate()
 
         name = (
             trad[self._pamhyr_name] +
             " - " + study.name +
-            " - " + self._reach.name
+            " - " + self._data[0].name
         )
 
-        super(InitialConditionsWindow, self).__init__(
+        super(InitialConditionsAdisTSWindow, self).__init__(
             title=name,
             study=study,
             config=config,
@@ -95,31 +85,22 @@ class InitialConditionsWindow(PamhyrWindow):
             parent=parent
         )
 
-        # Add reach to hash computation data
-        self._hash_data.append(self._reach)
+        self._hash_data.append(data)
 
-        self._ics = study.river.initial_conditions.get(self._reach)
+        self._ics_adists_lst = study.river.initial_conditions_adists
 
         self.setup_table()
-        self.setup_plot()
-        self.setup_connections()
-
         self.ui.setWindowTitle(self._title)
 
     def setup_table(self):
         table = self.find(QTableView, f"tableView")
-        self._delegate_kp = ComboBoxDelegate(
-            reach=self._reach,
-            parent=self
-        )
 
-        self._table = InitialConditionTableModel(
-            reach=self._reach,
+        self._table = InitialConditionTableDefaultModel(
             table_view=table,
             table_headers=self._trad.get_dict("table_headers"),
-            editable_headers=["kp", "discharge", "elevation", "height"],
-            delegates={"kp": self._delegate_kp},
-            data=self._study,
+            editable_headers=["name", "concentration", "eg", "em", "ed"],
+            delegates={},
+            data=self._data,
             undo=self._undo_stack,
             trad=self._trad
         )
@@ -127,62 +108,9 @@ class InitialConditionsWindow(PamhyrWindow):
         table.setModel(self._table)
         table.setSelectionBehavior(QAbstractItemView.SelectRows)
         table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+        #table.verticalHeader()
         table.setAlternatingRowColors(True)
 
-    def setup_plot(self):
-        self.canvas_1 = MplCanvas(width=5, height=4, dpi=100)
-        self.canvas_1.setObjectName("canvas_1")
-        self.toolbar_1 = PamhyrPlotToolbar(
-            self.canvas_1, self
-        )
-        self.plot_layout_1 = self.find(QVBoxLayout, "verticalLayout_1")
-        self.plot_layout_1.addWidget(self.toolbar_1)
-        self.plot_layout_1.addWidget(self.canvas_1)
-
-        self.plot_1 = PlotDKP(
-            canvas=self.canvas_1,
-            data=self._ics,
-            trad=self._trad,
-            toolbar=self.toolbar_1,
-            parent=self
-        )
-        self.plot_1.draw()
-
-        self.canvas_2 = MplCanvas(width=5, height=4, dpi=100)
-        self.canvas_2.setObjectName("canvas_2")
-        self.toolbar_2 = PamhyrPlotToolbar(
-            self.canvas_2, self
-        )
-        self.plot_layout_2 = self.find(QVBoxLayout, "verticalLayout_2")
-        self.plot_layout_2.addWidget(self.toolbar_2)
-        self.plot_layout_2.addWidget(self.canvas_2)
-
-        self.plot_2 = PlotDischarge(
-            canvas=self.canvas_2,
-            data=self._ics,
-            trad=self._trad,
-            toolbar=self.toolbar_2,
-            parent=self
-        )
-        self.plot_2.draw()
-
-    def setup_connections(self):
-        self.find(QAction, "action_add").triggered.connect(self.add)
-        self.find(QAction, "action_del").triggered.connect(self.delete)
-        self.find(QAction, "action_sort").triggered.connect(self.sort)
-        self.find(QAction, "action_import").triggered\
-                                           .connect(self.import_from_file)
-
-        self.find(QPushButton, "pushButton_generate_1").clicked.connect(
-            self.generate_growing_constante_height
-        )
-
-        self.find(QPushButton, "pushButton_generate_2").clicked.connect(
-            self.generate_discharge
-        )
-
-        self._table.dataChanged.connect(self._update_plot)
-
     def index_selected_row(self):
         table = self.find(QTableView, f"tableView")
         rows = table.selectionModel()\
@@ -193,20 +121,6 @@ class InitialConditionsWindow(PamhyrWindow):
 
         return rows[0].row()
 
-    def update(self):
-        self._update_plot()
-        self._propagate_update(key=Modules.INITIAL_CONDITION)
-
-    def _update_plot(self):
-        self.plot_1.draw()
-        self.plot_2.draw()
-
-    def _propagated_update(self, key=Modules(0)):
-        if Modules.GEOMETRY not in key:
-            return
-
-        self.update()
-
     def index_selected_rows(self):
         table = self.find(QTableView, f"tableView")
         return list(
@@ -219,63 +133,6 @@ class InitialConditionsWindow(PamhyrWindow):
             )
         )
 
-    def add(self):
-        rows = self.index_selected_rows()
-        if len(self._ics) == 0 or len(rows) == 0:
-            self._table.add(0)
-        else:
-            self._table.add(rows[0])
-
-        self._update()
-
-    def delete(self):
-        rows = self.index_selected_rows()
-        if len(rows) == 0:
-            return
-
-        self._table.delete(rows)
-        self._update()
-
-    def sort(self):
-        self._table.sort(False)
-        self._update()
-
-    def import_from_file(self):
-        workdir = os.path.dirname(self._study.filename)
-
-        return self.file_dialog(
-            callback=lambda d: self._import_from_file(d[0]),
-            directory=workdir,
-            default_suffix=".BIN",
-            file_filter=["Mage (*.BIN)"],
-        )
-
-    def _import_from_file(self, file_name):
-        solver = Mage8("dummy")
-        name = os.path.basename(file_name)\
-                      .replace(".BIN", "")
-
-        def reading():
-            self._tmp_results = solver.results(
-                self._study,
-                os.path.dirname(file_name),
-                name=name
-            )
-
-        dlg = ReadingResultsDialog(
-            reading_fn=reading,
-            parent=self
-        )
-        dlg.exec_()
-        results = self._tmp_results
-        self._import_from_results(results)
-
-    def _import_from_results(self, results):
-        logger.debug(f"import from results: {results}")
-        row = self.index_selected_row()
-
-        self._table.import_from_results(row, results)
-
     def move_up(self):
         row = self.index_selected_row()
         self._table.move_up(row)
@@ -339,17 +196,3 @@ class InitialConditionsWindow(PamhyrWindow):
     def _redo(self):
         self._table.redo()
         self._update()
-
-    def generate_growing_constante_height(self):
-        dlg = HeightDialog(trad=self._trad, parent=self)
-        if dlg.exec():
-            value = dlg.value
-            self._table.generate("growing", value)
-            self._update()
-
-    def generate_discharge(self):
-        dlg = DischargeDialog(trad=self._trad, parent=self)
-        if dlg.exec():
-            value = dlg.value
-            self._table.generate("discharge", value)
-            self._update()
diff --git a/src/View/InitialConditionsAdisTS/translate.py b/src/View/InitialConditionsAdisTS/translate.py
index 46d5f404..cfbae22f 100644
--- a/src/View/InitialConditionsAdisTS/translate.py
+++ b/src/View/InitialConditionsAdisTS/translate.py
@@ -23,27 +23,19 @@ from View.Translate import MainTranslate
 _translate = QCoreApplication.translate
 
 
-class ICTranslate(MainTranslate):
+class IcAdisTSTranslate(MainTranslate):
     def __init__(self):
-        super(ICTranslate, self).__init__()
+        super(IcAdisTSTranslate, self).__init__()
 
-        self._dict["Initial condition"] = _translate(
-            "InitialCondition", "Initial condition")
-        self._dict["Discharge"] = _translate(
-            "InitialCondition", "Discharge")
-        self._dict["Height"] = _translate(
-            "InitialCondition", "Height")
+        self._dict["Initial condition AdisTS"] = _translate(
+            "InitialConditionAdisTS", "Initial condition AdisTS")
 
-        self._dict["elevation"] = self._dict["unit_elevation"]
-        self._dict["discharge"] = self._dict["unit_discharge"]
         self._dict["kp"] = self._dict["unit_kp"]
 
         self._sub_dict["table_headers"] = {
-            # "name": _translate("InitialCondition", "Name"),
-            "kp": self._dict["unit_kp"],
-            "discharge": self._dict["unit_discharge"],
-            "elevation": self._dict["unit_elevation"],
-            "height": self._dict["unit_height"],
-            "speed": self._dict["unit_speed"],
-            # "comment": _translate("InitialCondition", "Comment"),
+            "name": self._dict["name"],
+            "concentration": self._dict["unit_concentration"],
+            "eg": _translate("Unit", "EG (m)"),
+            "em": _translate("Unit", "EM (m)"),
+            "ed": _translate("Unit", "ED (m)"),
         }
diff --git a/src/View/Pollutants/Table.py b/src/View/Pollutants/Table.py
index 1a92742c..c3bbcd4d 100644
--- a/src/View/Pollutants/Table.py
+++ b/src/View/Pollutants/Table.py
@@ -90,7 +90,7 @@ class TableModel(PamhyrTableModel):
 
         self._undo.push(
             AddCommand(
-                self._lst, row
+                self._lst, row, self._data.initial_conditions_adists
             )
         )
 
@@ -102,7 +102,7 @@ class TableModel(PamhyrTableModel):
 
         self._undo.push(
             DelCommand(
-                self._lst, rows
+                self._lst, rows, self._data.initial_conditions_adists
             )
         )
 
diff --git a/src/View/Pollutants/UndoCommand.py b/src/View/Pollutants/UndoCommand.py
index 843db085..b60181ae 100644
--- a/src/View/Pollutants/UndoCommand.py
+++ b/src/View/Pollutants/UndoCommand.py
@@ -60,44 +60,58 @@ class SetEnabledCommand(QUndoCommand):
 
 
 class AddCommand(QUndoCommand):
-    def __init__(self, pollutants_lst, index):
+    def __init__(self, pollutants_lst, index, data):
         QUndoCommand.__init__(self)
 
         self._pollutants_lst = pollutants_lst
 
         self._index = index
         self._new = None
+        self._new_ic_adists = None
+        self._data = data
 
     def undo(self):
         self._pollutants_lst.delete_i([self._index])
+        self._data.delete_i([self._index])
 
     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.]]
+            self._new_ic_adists = self._data.new(self._index, self._new.id)
         else:
             self._pollutants_lst.insert(self._index, self._new)
+            self._data.insert(self._index, self._new_ic_adists)
 
 
 class DelCommand(QUndoCommand):
-    def __init__(self, pollutants_lst, rows):
+    def __init__(self, pollutants_lst, rows, data):
         QUndoCommand.__init__(self)
 
         self._pollutants_lst = pollutants_lst
+        self._inc_pollutants_lst = data
 
         self._rows = rows
 
         self._pollutants = []
+        self._inc_pollutants = []
+
         for row in rows:
             self._pollutants.append((row, self._pollutants_lst.get(row)))
+            self._inc_pollutants.append((row, self._inc_pollutants_lst))
         self._pollutants.sort()
+        self._inc_pollutants.sort()
 
     def undo(self):
         for row, el in self._pollutants:
             self._pollutants_lst.insert(row, el)
 
+        for row, el in self._inc_pollutants:
+            self._inc_pollutants_lst.insert(row, el)
+
     def redo(self):
         self._pollutants_lst.delete_i(self._rows)
+        self._inc_pollutants_lst.delete_i(self._rows)
 
 
 class PasteCommand(QUndoCommand):
diff --git a/src/View/Pollutants/Window.py b/src/View/Pollutants/Window.py
index cabf5eb7..8ad0deb1 100644
--- a/src/View/Pollutants/Window.py
+++ b/src/View/Pollutants/Window.py
@@ -43,7 +43,7 @@ from View.Pollutants.Translate import PollutantsTranslate
 
 from View.Pollutants.Edit.Window import EditPolluantWindow
 
-from View.InitialConditionsAdisTS.Window import InitialConditionsWindow
+from View.InitialConditionsAdisTS.Window import InitialConditionsAdisTSWindow
 
 logger = logging.getLogger()
 
@@ -190,25 +190,25 @@ class PollutantsWindow(PamhyrWindow):
             win.show()
 
     def initial_conditions(self):
-        if self._study.river.has_current_reach():
-            reach = self._study.river.current_reach()
+        rows = self.index_selected_rows()
+
+        for row in rows:
+            pollutant_id = self._pollutants_lst.get(row).id
+            ics_adists = next(filter(lambda x: x.pollutant == pollutant_id,
+                                     self._study.river.initial_conditions_adists.lst))
 
             if self.sub_window_exists(
-                InitialConditionsWindow,
-                #data=[self._study, self.conf, reach]
-                data=[self._study, None, reach]
+                InitialConditionsAdisTSWindow,
+                data=[self._study, None, ics_adists]
             ):
                 return
 
-            initial = InitialConditionsWindow(
+            initial = InitialConditionsAdisTSWindow(
                 study=self._study,
-                #config=self.conf,
-                reach=reach,
-                parent=self
+                parent=self,
+                data=ics_adists
             )
             initial.show()
-        else:
-            self.msg_select_reach()
 
     def _set_checkbox_state(self):
         row = self.index_selected_row()
diff --git a/src/View/Translate.py b/src/View/Translate.py
index bc809481..5b906534 100644
--- a/src/View/Translate.py
+++ b/src/View/Translate.py
@@ -81,6 +81,8 @@ class UnitTranslate(CommonWordTranslate):
         self._dict["unit_ac"] = _translate("Unit", "AC")
         self._dict["unit_bc"] = _translate("Unit", "BC")
 
+        self._dict["unit_concentration"] = _translate("Unit", "Concentration (g/l)")
+
 class MainTranslate(UnitTranslate):
     def __init__(self):
         super(MainTranslate, self).__init__()
diff --git a/src/View/ui/InitialConditionsAdisTS.ui b/src/View/ui/InitialConditionsAdisTS.ui
new file mode 100644
index 00000000..94792877
--- /dev/null
+++ b/src/View/ui/InitialConditionsAdisTS.ui
@@ -0,0 +1,99 @@
+<?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>1024</width>
+    <height>576</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_2">
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+      <widget class="QWidget" name="layoutWidget">
+       <layout class="QVBoxLayout" name="verticalLayout_3">
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout"/>
+        </item>
+        <item>
+         <widget class="QTableView" name="tableView"/>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QSplitter" name="splitter">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <widget class="QWidget" name="verticalLayoutWidget">
+        <layout class="QVBoxLayout" name="verticalLayout_1"/>
+       </widget>
+       <widget class="QWidget" name="verticalLayoutWidget_2">
+        <layout class="QVBoxLayout" name="verticalLayout_2"/>
+       </widget>
+      </widget>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>1024</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>
+   <addaction name="action_add"/>
+   <addaction name="action_del"/>
+  </widget>
+  <action name="action_add">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/add.png</normaloff>ressources/add.png</iconset>
+   </property>
+   <property name="text">
+    <string>Add</string>
+   </property>
+   <property name="toolTip">
+    <string>Add new initial condition</string>
+   </property>
+  </action>
+  <action name="action_del">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/del.png</normaloff>ressources/del.png</iconset>
+   </property>
+   <property name="text">
+    <string>delete</string>
+   </property>
+   <property name="toolTip">
+    <string>Delete inital condition</string>
+   </property>
+  </action>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests_cases/Enlargement/Enlargement.pamhyr b/tests_cases/Enlargement/Enlargement.pamhyr
index 529aabb07ed8109ecaf6c3172dbdabb10f1878bb..8a4f35c6a2cdb182b55fbfeb16d26ec8cf662e67 100644
GIT binary patch
delta 56
zcmZozz}>Kbdqb-{pM`;uiJ7Ufo~e<Up^4Gv$?}C8HnVK_%fFfN0rLkS>kmI8*Jj2I
M%nDmsnEspx044+!kpKVy

delta 1110
zcmY+DTS!zv7=X{rSv}{tXJ%ZTb=9M;w;tLDQA>9<tm*R5Lj^sogpg5W>4T8AM2NL(
z<pnE2>?H#+@Fgp+4?#!|5hO?#Fp6HhU=KprMi-KZYIet&Xr5-iZ|491ng5*Fs5>_5
zp6d4FU{$atSXEsX+EEd#3e67r+olec+9MkIO5TyjWQ+`uHqt;2kTT-I-|!NCi67x%
zd<mb$NAWJa4V&mAdV`*!2{eczs1Y4R6^Pou?R9&>p0G!zyN=jVTxw|mAqxUfqOViv
zl!&zfjAAxWKYqLX38s7gB*!nOSji%Gvo(C?)!r{k(jqBAA-i!+OAHEWp`w0veOSbU
zj(>|rfl<Kvr$r=|JflHxfv^x5`FahNnC7ccd8}_~D-_LB)M35fMI`7rk{Y?J*G>jj
zl{&dfMsrwC@&A{kInsh`)?Kp|5N8X@-^mC2DfIf}+Q@<zRE<uSJZyN`mHD;4rdyN$
zq*qDGx>ld3FKmyVP?l0@K_-j+l-J8tG=s%52kKqfL;O`U6!oyn$JXW+8+thPD4NbX
z`^R65T>Zd1nl7n9SjSx3Qp>~r>M5cQQ5Lg{pF;7SZ|^GW#X|B%AkeNbMiK)XH1fQ*
zi~-y%g2I(2JM(y6x1>fIYp)g6$X+^WLPq&_X0db4qCwJ9OCAL#YYmK_e!3arX-q{8
z*3uomQ)kTcMi_$f8dJ4NRil$CHybJJRILahzhjyrWixQG<AM9t9b}Lva7hew7G4oG
zK}VO=fb4MK-jI7`Sv4&eTAIawAASv17kKb~efK`)+`!UI?o0qEoLO;wHX+&2$PcnH
z>tU<JZvtKOMVih>Dh*B7yop&F&k0FfBby}7H?5I;Q}<b7kM1=S6O`PttdTfbp7oS3
ak|GRk4VYp8%auxiSSJ`Tp`J1ZU;hPvAo<(?

-- 
GitLab