diff --git a/src/Model/River.py b/src/Model/River.py
index 2ff98bd8..59b47957 100644
--- a/src/Model/River.py
+++ b/src/Model/River.py
@@ -282,6 +282,7 @@ class River(Graph, SQLSubModel):
objs.append(self._boundary_condition)
objs.append(self._initial_conditions)
objs.append(self._lateral_contribution)
+ objs.append(self._sediment_layers)
objs.append(self._stricklers)
for solver in self._parameters:
diff --git a/src/Model/SedimentLayer/SedimentLayer.py b/src/Model/SedimentLayer/SedimentLayer.py
index 65684bd8..7f8f1fa4 100644
--- a/src/Model/SedimentLayer/SedimentLayer.py
+++ b/src/Model/SedimentLayer/SedimentLayer.py
@@ -16,7 +16,6 @@ class Layer(SQLSubModel):
super(Layer, self).__init__()
self._status = status
- self._sl = sl
self._name = name
self._type = type
@@ -27,6 +26,31 @@ class Layer(SQLSubModel):
else:
self.id = id
+ Layer._id_cnt = max(id, Layer._id_cnt+1)
+
+ @property
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, name):
+ self._name = name
+
+ @property
+ def type(self):
+ return self._type
+
+ @type.setter
+ def type(self, type):
+ self._type = type
+
+ @property
+ def height(self):
+ return self._height
+
+ @height.setter
+ def height(self, height):
+ self._height = height
@classmethod
def _sql_create(cls, execute):
@@ -56,7 +80,7 @@ class Layer(SQLSubModel):
table = execute(
"SELECT id, ind, name, type, height " +
"FROM sedimentary_layer_layer " +
- f"WHERE sl = {sl.id}"
+ f"WHERE sl = {sl}"
)
for _ in table:
@@ -77,13 +101,14 @@ class Layer(SQLSubModel):
def _sql_save(self, execute, data = None):
ind = data["ind"]
+ sl = data["sl"]
sql = (
"INSERT INTO " +
"sedimentary_layer_layer(id, ind, name, type, height, sl) "+
"VALUES (" +
f"{self.id}, {ind}, '{self._sql_format(self._name)}', " +
- f"'{self._sql_format(self._type)}', '{self._height}', {self._sl.id}" +
+ f"'{self._sql_format(self._type)}', '{self._height}', {sl}" +
")"
)
execute(sql)
@@ -110,6 +135,9 @@ class SedimentLayer(SQLSubModel):
else:
self.id = id
+ def __len__(self):
+ return len(self._layers)
+
@property
def name(self):
return self._name
@@ -147,7 +175,7 @@ class SedimentLayer(SQLSubModel):
new = []
table = execute(
- "SELECT id, name, comment" +
+ "SELECT id, name, comment " +
"FROM sedimentary_layer "
)
@@ -171,11 +199,14 @@ class SedimentLayer(SQLSubModel):
data = {}
sql = (
- "INSERT INTO sedimentary_layer (id, name) "+
- f"VALUES ({self.id}, '{self._sql_format(self._name)}')"
+ "INSERT INTO sedimentary_layer (id, name, comment) " +
+ f"VALUES ({self.id}, '{self._sql_format(self._name)}', " +
+ f"'{self._sql_format(self._comment)}')"
)
execute(sql)
+ data["sl"] = self
+
ind = 0
for l in self._layers:
data["ind"] = ind
@@ -196,7 +227,7 @@ class SedimentLayer(SQLSubModel):
self._status.modified()
def new(self, index):
- n = Layer(status = self._status)
+ n = Layer(sl=self, status = self._status)
self.insert(index, n)
self._status.modified()
return n
diff --git a/src/View/SedimentLayers/Edit/Table.py b/src/View/SedimentLayers/Edit/Table.py
index e69de29b..6bd59387 100644
--- a/src/View/SedimentLayers/Edit/Table.py
+++ b/src/View/SedimentLayers/Edit/Table.py
@@ -0,0 +1,153 @@
+# -*- coding: utf-8 -*-
+
+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.SedimentLayers.Edit.UndoCommand import *
+from View.SedimentLayers.Edit.translate import *
+
+_translate = QCoreApplication.translate
+
+
+class TableModel(QAbstractTableModel):
+ def __init__(self, study=None, sl=None, undo=None):
+ super(QAbstractTableModel, self).__init__()
+ self._headers = list(table_headers.keys())
+ self._study = study
+ self._undo = undo
+ self._sl = sl
+
+ def flags(self, index):
+ options = Qt.ItemIsEnabled | Qt.ItemIsSelectable
+ options |= Qt.ItemIsEditable
+
+ return options
+
+ def rowCount(self, parent):
+ return len(self._sl)
+
+ 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._sl.get(row).name
+ elif self._headers[column] == "type":
+ return self._sl.get(row).type
+ elif self._headers[column] == "height":
+ return self._sl.get(row).height
+
+ return QVariant()
+
+ def headerData(self, friction, orientation, role):
+ if role == Qt.ItemDataRole.DisplayRole and orientation == Qt.Orientation.Horizontal:
+ return table_headers[self._headers[friction]]
+
+ 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._undo.push(
+ SetNameCommand(
+ self._sl, row, value
+ )
+ )
+ if self._headers[column] == "comment":
+ self._undo.push(
+ SetCommentCommand(
+ self._sl, row, value
+ )
+ )
+
+ self.dataChanged.emit(index, index)
+ return True
+
+ def add(self, row, parent=QModelIndex()):
+ self.beginInsertRows(parent, row, row - 1)
+
+ self._undo.push(
+ AddCommand(
+ self._sl, row
+ )
+ )
+
+ self.endInsertRows()
+ self.layoutChanged.emit()
+
+ def delete(self, rows, parent=QModelIndex()):
+ self.beginRemoveRows(parent, rows[0], rows[-1])
+
+ self._undo.push(
+ DelCommand(
+ self._sl, rows
+ )
+ )
+
+ self.endRemoveRows()
+ self.layoutChanged.emit()
+
+ def move_up(self, row, parent=QModelIndex()):
+ if row <= 0:
+ return
+
+ target = row + 2
+
+ self.beginMoveRows(parent, row - 1, row - 1, parent, target)
+
+ self._undo_stack.push(
+ MoveCommand(
+ self._sl, "up", row
+ )
+ )
+
+ self.endMoveRows()
+ self.layoutChanged.emit()
+
+ def move_down(self, index, parent=QModelIndex()):
+ if row > len(self._sl):
+ return
+
+ target = row
+
+ self.beginMoveRows(parent, row + 1, row + 1, parent, target)
+
+ self._undo_stack.push(
+ MoveCommand(
+ self._sl, "down", row
+ )
+ )
+
+ self.endMoveRows()
+ 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/SedimentLayers/Edit/UndoCommand.py b/src/View/SedimentLayers/Edit/UndoCommand.py
index e69de29b..9e630a6e 100644
--- a/src/View/SedimentLayers/Edit/UndoCommand.py
+++ b/src/View/SedimentLayers/Edit/UndoCommand.py
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+
+from copy import deepcopy
+from tools import trace, timer
+
+from PyQt5.QtWidgets import (
+ QMessageBox, QUndoCommand, QUndoStack,
+)
+
+from Model.SedimentLayer.SedimentLayer import SedimentLayer
+from Model.SedimentLayer.SedimentLayerList import SedimentLayerList
+
+class SetNameCommand(QUndoCommand):
+ def __init__(self, sediment_layers, index, new_value):
+ QUndoCommand.__init__(self)
+
+ self._sediment_layers = sediment_layers
+ self._index = index
+ self._old = self._sediment_layers.get(self._index).name
+ self._new = new_value
+
+ def undo(self):
+ self._sediment_layers.get(self._index).name = self._old
+
+ def redo(self):
+ self._sediment_layers.get(self._index).name = self._new
+
+class SetHeightCommand(QUndoCommand):
+ def __init__(self, sediment_layers, index, new_value):
+ QUndoCommand.__init__(self)
+
+ self._sediment_layers = sediment_layers
+ self._index = index
+ self._old = self._sediment_layers.get(self._index).height
+ self._new = new_value
+
+ def undo(self):
+ self._sediment_layers.get(self._index).height = self._old
+
+ def redo(self):
+ self._sediment_layers.get(self._index).height = self._new
+
+class AddCommand(QUndoCommand):
+ def __init__(self, sediment_layers, index):
+ QUndoCommand.__init__(self)
+
+ self._sediment_layers = sediment_layers
+ self._index = index
+ self._new = None
+
+ def undo(self):
+ self._sediment_layers.delete_i([self._index])
+
+ def redo(self):
+ if self._new is None:
+ self._new = self._sediment_layers.new(self._index)
+ else:
+ self._sediment_layers.insert(self._index, self._new)
+
+class DelCommand(QUndoCommand):
+ def __init__(self, sediment_layers, rows):
+ QUndoCommand.__init__(self)
+
+ self._sediment_layers = sediment_layers
+ self._rows = rows
+
+ self._sl_pos = []
+ for row in rows:
+ self._sl_pos.append((row, self._sediment_layers.get(row)))
+ self._sl_pos.sort()
+
+ def undo(self):
+ for row, el in self._sl_pos:
+ self._sediment_layers.insert(row, el)
+
+ def redo(self):
+ self._sediment_layers.delete_i(self._rows)
+
+class MoveCommand(QUndoCommand):
+ def __init__(self, sediment_layers, up, i):
+ QUndoCommand.__init__(self)
+
+ self._sediment_layers = sediment_layers
+ self._up = up == "up"
+ self._i = i
+
+ def undo(self):
+ if self._up:
+ self._sediment_layers.move_up(self._i)
+ else:
+ self._sediment_layers.move_down(self._i)
+
+ def redo(self):
+ if self._up:
+ self._sediment_layers.move_up(self._i)
+ else:
+ self._sediment_layers.move_down(self._i)
diff --git a/src/View/SedimentLayers/Edit/Window.py b/src/View/SedimentLayers/Edit/Window.py
index e69de29b..44100d6f 100644
--- a/src/View/SedimentLayers/Edit/Window.py
+++ b/src/View/SedimentLayers/Edit/Window.py
@@ -0,0 +1,150 @@
+# -*- coding: utf-8 -*-
+
+import logging
+
+from tools import trace, timer
+
+from View.ASubWindow import ASubMainWindow
+from View.ListedSubWindow import ListedSubWindow
+
+from PyQt5.QtGui import (
+ QKeySequence,
+)
+
+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, QVBoxLayout, QHeaderView, QTabWidget,
+)
+
+from View.Plot.MplCanvas import MplCanvas
+
+from View.SedimentLayers.Edit.UndoCommand import *
+from View.SedimentLayers.Edit.Table import *
+from View.SedimentLayers.Edit.translate import *
+
+_translate = QCoreApplication.translate
+
+logger = logging.getLogger()
+
+class EditSedimentLayersWindow(ASubMainWindow, ListedSubWindow):
+ def __init__(self, title="Edit Sediment Layers",
+ study=None, sl=None, parent=None):
+ self._study = study
+ self._sl = sl
+
+ self.setup_title(title)
+
+ super(EditSedimentLayersWindow, self).__init__(
+ name=self._title, ui="EditSedimentLayers", parent=parent
+ )
+
+ self.setup_sc()
+ self.setup_table()
+ self.setup_graph()
+ self.setup_connections()
+
+ self.ui.setWindowTitle(self._title)
+
+ def setup_title(self, title):
+ name = self._sl.name
+ if name == "":
+ name = _translate("SedimentLayers", "(no name)")
+
+ self._title = (
+ title + " - " + self._study.name + " - " + name
+ )
+
+ def setup_sc(self):
+ self._undo_stack = QUndoStack()
+
+ self.undo_sc = QShortcut(QKeySequence.Undo, self)
+ self.redo_sc = QShortcut(QKeySequence.Redo, self)
+ self.copy_sc = QShortcut(QKeySequence.Copy, self)
+ self.paste_sc = QShortcut(QKeySequence.Paste, self)
+
+ def setup_table(self):
+ self._table = {}
+
+ table = self.find(QTableView, f"tableView")
+ self._table = TableModel(
+ study = self._study,
+ sl = self._sl,
+ undo = self._undo_stack,
+ )
+ table.setModel(self._table)
+
+ table.setSelectionBehavior(QAbstractItemView.SelectRows)
+ table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+ table.setAlternatingRowColors(True)
+
+ def setup_graph(self):
+ self.canvas = MplCanvas(width=5, height=4, dpi=100)
+ self.canvas.setObjectName("canvas")
+ self.plot_layout = self.find(QVBoxLayout, "verticalLayout")
+ self.plot_layout.addWidget(self.canvas)
+
+ # self.plot = PlotKPC(
+ # canvas = self.canvas,
+ # data = self._reach.reach,
+ # toolbar = None,
+ # display_current = False
+ # )
+ # self.plot.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_move_up").triggered.connect(self.delete)
+ self.find(QAction, "action_move_down").triggered.connect(self.delete)
+
+ self.undo_sc.activated.connect(self.undo)
+ self.redo_sc.activated.connect(self.redo)
+ self.copy_sc.activated.connect(self.copy)
+ self.paste_sc.activated.connect(self.paste)
+
+ def index_selected_rows(self):
+ table = self.find(QTableView, f"tableView")
+ return list(
+ # Delete duplicate
+ set(
+ map(
+ lambda i: i.row(),
+ table.selectedIndexes()
+ )
+ )
+ )
+
+ def add(self):
+ rows = self.index_selected_rows()
+ if len(self._sl) == 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()
diff --git a/src/View/SedimentLayers/Edit/translate.py b/src/View/SedimentLayers/Edit/translate.py
index e69de29b..3b61d18c 100644
--- a/src/View/SedimentLayers/Edit/translate.py
+++ b/src/View/SedimentLayers/Edit/translate.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+
+from PyQt5.QtCore import QCoreApplication
+
+_translate = QCoreApplication.translate
+
+table_headers = {
+ "name": _translate("SedimentLayers", "Name"),
+ "type": _translate("SedimentLayers", "Type"),
+ "height": _translate("Sedimentlayers", "Height"),
+}
diff --git a/src/View/SedimentLayers/Window.py b/src/View/SedimentLayers/Window.py
index 22b61318..b2e8f1fa 100644
--- a/src/View/SedimentLayers/Window.py
+++ b/src/View/SedimentLayers/Window.py
@@ -30,7 +30,7 @@ from View.SedimentLayers.Table import *
from View.Plot.MplCanvas import MplCanvas
from View.SedimentLayers.translate import *
-# from View.SedimentLayers.Edit.Window import EditSedimentLayersWindow
+from View.SedimentLayers.Edit.Window import EditSedimentLayersWindow
_translate = QCoreApplication.translate
@@ -150,7 +150,7 @@ class SedimentLayersWindow(ASubMainWindow, ListedSubWindow):
for row in rows:
slw = EditSedimentLayersWindow(
study = self._study,
- sl = self.__sediment_layers[row],
+ sl = self._sediment_layers.get(row),
parent = self
)
slw.show()
diff --git a/src/View/ui/EditSedimentLayers.ui b/src/View/ui/EditSedimentLayers.ui
index 7e236641..6fe4c11b 100644
--- a/src/View/ui/EditSedimentLayers.ui
+++ b/src/View/ui/EditSedimentLayers.ui
@@ -49,12 +49,12 @@
false
-
-
+
+
-
+
ressources/gtk-add.pngressources/gtk-add.png
@@ -69,7 +69,7 @@
Ctrl+N
-
+
ressources/gtk-remove.pngressources/gtk-remove.png