diff --git a/doc/dev/documentation.org b/doc/dev/documentation.org
index ed4bc2228c41806fc54e9b822f0f496e6aaa96e9..f12426b21d09fbdcd6b42bb2437d705f477a7a72 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