diff --git a/doc/dev/documentation.org b/doc/dev/documentation.org
index c5266896898db85756e0052a953547ac88543a68..ed4bc2228c41806fc54e9b822f0f496e6aaa96e9 100644
--- a/doc/dev/documentation.org
+++ b/doc/dev/documentation.org
@@ -443,49 +443,83 @@ than hand made windows and widget creation, and saves us some purely
 descriptive code. The UI files are saved into =src/View/ui= for
 window, and =/src/View/ui/Widgets= for custom widget.
 
+*** Translate
+
+#+NAME: pamhyr-trad
+#+CAPTION: Example of =PamhyrTranslate= class implementation with a global traduction for /FooBar/ and a additional dictionary =table_headers=
+#+begin_src python :python python3 :results output :noweb yes
+  from PyQt5.QtCore import QCoreApplication
+  from View.Tools.PamhyrTranslate import PamhyrTranslate
+  _translate = QCoreApplication.translate
+
+  class MyTranslate(PamhyrTranslate):
+      def __init__(self):
+          super(MyTranslate, self).__init__()
+
+          # Add traduction to global dictionary
+          self._dict["My"] = _translate("My", "FooBar")
+          # Add an additional translate dictionary
+          self._sub_dict["table_headers"] = {
+              "foo": _translate("My", "Foo"),
+              "bar": _translate("My", "Bar"),
+              "baz": _translate("My", "Baz"),
+          }
+#+end_src
+
 *** Window
 
 The abstract class PamhyrWindow and PamhyrDialog are used for most of
 Pamhyr2 window. These class allow to create an window for Pamhyr2 GUI
-and implemente some useful methods.
+and implemente some useful methods. The super class method difine some
+generic value from optional parameters, for examples:
+- =self._study=: The study giving in constructor parameters =study=
+  (typically a =Model.Study= class object)
+- =self._config=: The configuration giving in constructor parameters
+  =config= (typically a =Config= class object)
+- =self._trad=: The traductor dictionary giving in constructor
+  parameters =trad= (typically a =Model.Tools.PamhyrTranslate= class
+  object)
 
 #+NAME: window
 #+CAPTION: Example of Pamhyr2 window
 #+begin_src python :python python3 :results output :noweb yes
-  from View.Tools.PamhyrWindow import PamhyrWindow
-
-  class MyWindow(PamhyrWindow):
-      _pamhyr_ui = "MyUI"
-      _pamhyr_name = "My window"
-
-      def __init__(self, my_data=None,
-                   study=None, config=None,
-                   parent=None):
-          self._my_data = my_data
-
-          super(MyWindow, self).__init__(
-              # Window title
-              title = self._pamhyr_name + " - " + study.name,
-              # Window standard data
-              study = study, config = config, parent = parent,
-              # Activate undo/redo and copy/paste shortcut
-              options = ["undo", "copy"]
-          )
+    from View.Tools.PamhyrWindow import PamhyrWindow
+    from View.My.Translate import MyTranslate
+
+    class MyWindow(PamhyrWindow):
+        _pamhyr_ui = "MyUI"
+        _pamhyr_name = "My window"
+
+        def __init__(self, my_data=None,
+                     study=None, config=None,
+                     parent=None):
+            self._my_data = my_data
+
+            super(MyWindow, self).__init__(
+                # Window title
+                title = self._pamhyr_name + " - " + study.name,
+                # Window standard data
+                study = study, config = config,
+                trad = MyTranslate(),
+                parent = parent,
+                # Activate undo/redo and copy/paste shortcut
+                options = ["undo", "copy"]
+            )
 
-          # Add custom data to hash window computation
-          self._hash_data.append(self._my_data)
+            # Add custom data to hash window computation
+            self._hash_data.append(self._my_data)
 
-          # Setup custom window components
-          self.setup_table()
-          self.setup_connections()
+            # Setup custom window components
+            self.setup_table()
+            self.setup_connections()
 
-      def setup_table(self):
-          # Init table(s)...
+        def setup_table(self):
+            # Init table(s)...
 
-      def setup_connections(self):
-          # Init action connection(s)...
+        def setup_connections(self):
+            # Init action connection(s)...
 
-      # ...
+        # ...
 #+end_src
 
 Typically we called method =setup_*=, the method to initialize some
@@ -499,20 +533,6 @@ and =setData= methode to implement, but the constructor needs more
 information than a classic QAbstractTableModel class.
 
 #+begin_src python :python python3 :results output :noweb yes
-  # Table headers with display name translatable (translate.py)
-  table_headers = {
-      "foo": _translate("My", "Foo"),
-      "bar": _translate("My", "Bar"),
-      "baz": _translate("My", "Baz"),
-  }
-
-  def retranslate():
-      # Hack because dict definition is not able to be
-      # translate... (need to be called in window '__init__')
-      table_headers["foo"] = _translate("My", "Foo")
-      table_headers["bar"] = _translate("My", "Bar")
-      table_headers["baz"] = _translate("My", "Baz")
-
   # Table model definition (Table.py)
   class MyTableModel(PamhyrTableModel):
       def data(self, index, role):
@@ -523,6 +543,7 @@ information than a classic QAbstractTableModel class.
           # Set VALUE at INDEX...
 
   # Table model creation (Window.py)
+  table_headers = self._trad.get_dict("table_headers")
   self._model = MyTableModel(
       table_view = table,         # The table view object
       table_headers = table_headers, # The table column headers dict
diff --git a/src/View/Network/Window.py b/src/View/Network/Window.py
index a54c0527b4a1a57a976f78e02fb1360020977831..f045859680e845dbffc75991b2aa410ed38ca649 100644
--- a/src/View/Network/Window.py
+++ b/src/View/Network/Window.py
@@ -41,10 +41,7 @@ from Model.River import RiverNode, RiverReach, River
 from View.Tools.PamhyrWindow import PamhyrWindow
 from View.Network.GraphWidget import GraphWidget
 from View.Network.UndoCommand import *
-from View.Network.translate import (
-    table_headers_node, table_headers_edge,
-    retranslate,
-)
+from View.Network.translate import NetworkTranslate
 from View.Network.Table import (
     ComboBoxDelegate, NodeTableModel, EdgeTableModel,
 )
@@ -63,24 +60,25 @@ class NetworkWindow(PamhyrWindow):
             title = self._pamhyr_name + " - " + study.name,
             study = study,
             config = config,
+            trad = NetworkTranslate(),
             options = ['undo'],
             parent=parent,
         )
 
         self._graph = study.river
+        self._table_headers_node = self._trad.get_dict("table_headers_node")
+        self._table_headers_edge = self._trad.get_dict("table_headers_edge")
 
         self.setup_graph()
         self.setup_table()
         self.setup_connections()
 
     def setup_table(self):
-        retranslate()
-
         # Nodes table
         table = self.find(QTableView, "tableView_nodes")
         self._nodes_model = NodeTableModel(
             table_view = table,
-            table_headers = table_headers_node,
+            table_headers = self._table_headers_node,
             editable_headers = ["name"],
             data = self._graph,
             undo = self._undo_stack,
@@ -99,7 +97,7 @@ class NetworkWindow(PamhyrWindow):
 
         self._reachs_model = EdgeTableModel(
             table_view = table,
-            table_headers = table_headers_edge,
+            table_headers = self._table_headers_edge,
             editable_headers = ["name", "node1", "node2"],
             delegates = {
                 "node1": self.delegate_combobox,
diff --git a/src/View/Network/translate.py b/src/View/Network/translate.py
index 24935e1be5935f0668a10a4067af9f7913c3b820..44e97cf50f3b2deac34b319a009ce0e2506f6ec5 100644
--- a/src/View/Network/translate.py
+++ b/src/View/Network/translate.py
@@ -18,23 +18,21 @@
 
 from PyQt5.QtCore import QCoreApplication
 
-_translate = QCoreApplication.translate
+from View.Tools.PamhyrTranslate import PamhyrTranslate
 
-table_headers_node = {
-    "name": _translate("Network", "Name"),
-    "type": _translate("Network", "Type"),
-}
+_translate = QCoreApplication.translate
 
-table_headers_edge = {
-    "name": _translate("Network", "Name"),
-    "node1": _translate("Network", "Source node"),
-    "node2": _translate("Network", "Destination node"),
-}
+class NetworkTranslate(PamhyrTranslate):
+    def __init__(self):
+        super(NetworkTranslate, self).__init__()
 
-def retranslate():
-    table_headers_node["name"] = _translate("Network", "Name")
-    table_headers_node["type"] = _translate("Network", "Type")
+        self._sub_dict["table_headers_node"] = {
+            "name": _translate("Network", "Name"),
+            "type": _translate("Network", "Type"),
+        }
 
-    table_headers_edge["name"] = _translate("Network", "Name")
-    table_headers_edge["node1"] = _translate("Network", "Source node")
-    table_headers_edge["node2"] = _translate("Network", "Destination node")
+        self._sub_dict["table_headers_edge"] = {
+            "name": _translate("Network", "Name"),
+            "node1": _translate("Network", "Source node"),
+            "node2": _translate("Network", "Destination node"),
+        }
diff --git a/src/View/Tools/PamhyrTranslate.py b/src/View/Tools/PamhyrTranslate.py
new file mode 100644
index 0000000000000000000000000000000000000000..83c8da644d3ed35da282f961526789bcde610904
--- /dev/null
+++ b/src/View/Tools/PamhyrTranslate.py
@@ -0,0 +1,56 @@
+# PamhyrTranslate.py -- Pamhyr
+# Copyright (C) 2023  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 PyQt5.QtCore import QCoreApplication
+
+_translate = QCoreApplication.translate
+
+
+class PamhyrTranslate(object):
+    def __init__(self):
+        # Module global dictionnary
+        self._dict = {}
+        # Module sub dictionnary
+        self._sub_dict = {}
+
+    def __getitem__(self, index):
+        if index not in self._dict:
+            return None
+        return self._dict[index]
+
+    def _get_in_sub_dict(self, dictionary, index):
+        if dictionary not in self._sub_dict:
+            return None
+        return self._sub_dict[index]
+
+    def get(self, dictionary, index):
+        if dictionary == "global":
+            return self[index]
+
+        return self._get_in_sub_dict(dictionary, index)
+
+    def get_dict(self, dictionary):
+        _dict = None
+
+        if dictionary == "global":
+            _dict = self._dict
+
+        if dictionary in self._sub_dict:
+            _dict = self._sub_dict[dictionary]
+
+        return _dict
diff --git a/src/View/Tools/PamhyrWindow.py b/src/View/Tools/PamhyrWindow.py
index 34ff547fb04126e3119ca937866c76950bcc2949..fb4bf1a12cf76a77574a14f3c0db41658a2756cc 100644
--- a/src/View/Tools/PamhyrWindow.py
+++ b/src/View/Tools/PamhyrWindow.py
@@ -140,12 +140,13 @@ class PamhyrWindow(ASubMainWindow, ListedSubWindow, PamhyrWindowTools):
 
     def __init__(self,
                  title = "Pamhyr2",
-                 study = None, config = None,
+                 study = None, config = None, trad = None,
                  options = ["undo", "copy"],
                  parent = None):
         self._title = title
         self._study = study
         self._config = config
+        self._trad = trad
         self._parent = parent
 
         super(PamhyrWindow, self).__init__(
@@ -166,21 +167,22 @@ class PamhyrDialog(ASubWindow, ListedSubWindow, PamhyrWindowTools):
 
     def __init__(self,
                  title = "Pamhyr2",
-                 study = None, config = None,
+                 study = None, config = None, trad = None,
                  options = ["undo", "copy"],
                  parent = None):
         self._title = title
         self._study = study
         self._config = config
+        self._trad = trad
         self._parent = parent
 
-        logger.info(self._pamhyr_name)
-        logger.info(self._pamhyr_ui)
-
         super(PamhyrDialog, self).__init__(
             name = self._pamhyr_name,
             ui = self._pamhyr_ui,
             parent = parent,
         )
 
+        self._hash_data.append(self._study)
+        self._hash_data.append(self._config)
+
         self._set_title()