From f93f3fe12278b05d904cc6e2745dc3b6ed1bb743 Mon Sep 17 00:00:00 2001
From: Pierre-Antoine Rouby <pierre-antoine.rouby@inrae.fr>
Date: Wed, 27 Sep 2023 09:00:18 +0200
Subject: [PATCH] doc: dev: Update Table and UndoCommand.

---
 doc/dev/documentation.org | 52 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 48 insertions(+), 4 deletions(-)

diff --git a/doc/dev/documentation.org b/doc/dev/documentation.org
index ed4bc222..f12426b2 100644
--- a/doc/dev/documentation.org
+++ b/doc/dev/documentation.org
@@ -485,6 +485,7 @@ generic value from optional parameters, for examples:
 #+begin_src python :python python3 :results output :noweb yes
     from View.Tools.PamhyrWindow import PamhyrWindow
     from View.My.Translate import MyTranslate
+    from View.My.Table import MyTableModel
 
     class MyWindow(PamhyrWindow):
         _pamhyr_ui = "MyUI"
@@ -532,8 +533,11 @@ QAbstractTableModel shortly. In simple cases, there are only =data=
 and =setData= methode to implement, but the constructor needs more
 information than a classic QAbstractTableModel class.
 
+#+NAME: table-src
+#+CAPTION: Definition of a table model from =PamhyrTableModel= in a file =View/My/Table.py=.
 #+begin_src python :python python3 :results output :noweb yes
-  # Table model definition (Table.py)
+  from View.Tools.PamhyrTable import PamhyrTableModel
+
   class MyTableModel(PamhyrTableModel):
       def data(self, index, role):
           # Retrun data at INDEX...
@@ -541,8 +545,11 @@ information than a classic QAbstractTableModel class.
       @pyqtSlot()
       def setData(self, index, value, role=Qt.EditRole):
           # Set VALUE at INDEX...
+#+end_src
 
-  # Table model creation (Window.py)
+#+CAPTION: Using the table model defined in Listing [[table-src]] in window funtion =setup_table= defined Listing [[window]].
+#+begin_src python :python python3 :results output :noweb yes
+  # Table model creation (Window.py: setup_table)
   table_headers = self._trad.get_dict("table_headers")
   self._model = MyTableModel(
       table_view = table,         # The table view object
@@ -553,11 +560,48 @@ information than a classic QAbstractTableModel class.
           "bar": self.my_delegate, # Custom delegate for column 'bar'
       },
       data = self._my_lst,         # The data
-      undo = self._undo_stack,     # The undo command stack
+      undo = self._undo_stack,     # The window undo command stack
+  )
+#+end_src
+
+*** UndoCommand
+
+All model modification must be done by an QUndoCommand, this command
+allow to undo and redo an action. This a Qt class wi can inherit to
+define custom undo command (see example Listing [[undo-cmd]])
+
+#+NAME: undo-cmd
+#+CAPTION: Example of custom UndoCommand, this command allow to add a node to graph in river network window (method redo), and delete it to graph with undo method
+#+begin_src python :python python3 :results output :noweb yes
+class AddNodeCommand(QUndoCommand):
+    def __init__(self, graph, node):
+        QUndoCommand.__init__(self)
+
+        self._graph = graph
+        self._node = node
+
+    def undo(self):
+        self._graph.remove_node(self._node.name)
+
+    def redo(self):
+        self._graph.insert_node(self._node)
+#+end_src
+
+All undo command must be push into a =QUndoStack= (see Listing
+[[undo-cmd-push]]) to perform the action and allow user undo and redo this
+action. In PamhyrWindow (and PamhyrDialog) the undo stack is
+automatically create if the option ="undo"= is activate at window
+creation, this stack is accessible at =self._undo_stack=.
+
+#+begin_src python :python python3 :results output :noweb yes
+  self._undo_stack.push(
+      AddNodeCommand(
+          self._graph,
+          node
+      )
   )
 #+end_src
 
-*** TODO UndoCommand
 *** TODO Plot
 *** TODO Mainwindow
 ** TODO Solver
-- 
GitLab