diff --git a/src/Model/Geometry/Reach.py b/src/Model/Geometry/Reach.py
index 26cdefc920dd9f81877c561d792eda2595d7f655..36fca25f6302e63a11f75c083f9d9b29ed0c5482 100644
--- a/src/Model/Geometry/Reach.py
+++ b/src/Model/Geometry/Reach.py
@@ -106,6 +106,9 @@ class Reach(SQLSubModel):
 
         return self._parent.name
 
+    def __len__(self):
+        return len(self._profiles)
+
     @property
     def profiles(self):
         return self._profiles.copy()
diff --git a/src/View/Geometry/PlotAC.py b/src/View/Geometry/PlotAC.py
index e43f39e962d0170c2f029840388f2b941af77f4e..974706aa20419210ddf59089ad71b39343ba3ec6 100644
--- a/src/View/Geometry/PlotAC.py
+++ b/src/View/Geometry/PlotAC.py
@@ -19,7 +19,7 @@
 import logging
 
 from tools import timer
-from View.Plot.APlot import APlot
+from View.Tools.PamhyrPlot import PamhyrPlot
 
 from PyQt5.QtCore import (
     QCoreApplication
@@ -29,12 +29,15 @@ _translate = QCoreApplication.translate
 
 logger = logging.getLogger()
 
-class PlotAC(APlot):
-    def __init__(self, canvas=None, data=None, toolbar=None, plot_xy=None):
+class PlotAC(PamhyrPlot):
+    def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
+                 plot_xy=None, parent=None):
         super(PlotAC, self).__init__(
-            canvas=canvas,
-            data=data,
-            toolbar=toolbar
+            canvas = canvas,
+            trad = trad,
+            data = data,
+            toolbar = toolbar,
+            parent = parent
         )
 
         self.plot_xy = plot_xy
diff --git a/src/View/Geometry/PlotKPZ.py b/src/View/Geometry/PlotKPZ.py
index eb7d5e28b8660bf62ef11874522ad3c646290784..f216443c411dcbb8196d169b7776b0b3db07251a 100644
--- a/src/View/Geometry/PlotKPZ.py
+++ b/src/View/Geometry/PlotKPZ.py
@@ -19,7 +19,7 @@
 import logging
 
 from tools import timer
-from View.Plot.APlot import APlot
+from View.Tools.PamhyrPlot import PamhyrPlot
 
 from PyQt5.QtCore import (
     QCoreApplication
@@ -29,13 +29,15 @@ _translate = QCoreApplication.translate
 
 logger = logging.getLogger()
 
-class PlotKPZ(APlot):
-    def __init__(self, canvas=None, data=None, toolbar=None,
-                 display_current=True):
+class PlotKPZ(PamhyrPlot):
+    def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
+                 display_current=True, parent=None):
         super(PlotKPZ, self).__init__(
-            canvas=canvas,
-            data=data,
-            toolbar=toolbar
+            canvas = canvas,
+            trad = trad,
+            data = data,
+            toolbar = toolbar,
+            parent = parent
         )
 
         self.display_current = display_current
diff --git a/src/View/Geometry/PlotXY.py b/src/View/Geometry/PlotXY.py
index 54e056a910050ab661e472685ce1fd7eb107de4b..ce93fa24ba52f68ede41a70fc61c9dd367a5e29d 100644
--- a/src/View/Geometry/PlotXY.py
+++ b/src/View/Geometry/PlotXY.py
@@ -17,7 +17,7 @@
 # -*- coding: utf-8 -*-
 
 from tools import timer, trace
-from View.Plot.APlot import APlot
+from View.Tools.PamhyrPlot import PamhyrPlot
 
 from PyQt5.QtCore import (
     QCoreApplication
@@ -25,12 +25,15 @@ from PyQt5.QtCore import (
 
 _translate = QCoreApplication.translate
 
-class PlotXY(APlot):
-    def __init__(self, canvas=None, data=None, toolbar=None, display_current=True):
+class PlotXY(PamhyrPlot):
+    def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
+                 display_current=True, parent=None):
         super(PlotXY, self).__init__(
-            canvas=canvas,
-            data=data,
-            toolbar=toolbar
+            canvas = canvas,
+            trad = trad,
+            data = data,
+            toolbar = toolbar,
+            parent = parent
         )
 
         self.display_current = display_current
@@ -60,11 +63,11 @@ class PlotXY(APlot):
 
         # Axes
         self.canvas.axes.set_xlabel(
-            _translate("MainWindow_reach", "X (m)"),
+            _translate("Geometry", "X (m)"),
             color='green', fontsize=12
         )
         self.canvas.axes.set_ylabel(
-            _translate("MainWindow_reach", "Y (m)"),
+            _translate("Geometry", "Y (m)"),
             color='green', fontsize=12
         )
         self.canvas.axes.axis("equal")
diff --git a/src/View/Geometry/Table.py b/src/View/Geometry/Table.py
index 1b055209d9fb4feeadd26d6ab40ea381f7acf24c..0ff5e0c871a6edda6104beb9c4681181b168d482 100644
--- a/src/View/Geometry/Table.py
+++ b/src/View/Geometry/Table.py
@@ -35,6 +35,8 @@ from PyQt5.QtWidgets import (
     QComboBox,
 )
 
+from View.Tools.PamhyrTable import PamhyrTableModel
+
 from Model.Geometry import Reach
 from Model.Geometry.ProfileXYZ import ProfileXYZ
 from View.Geometry.UndoCommand import *
@@ -44,53 +46,26 @@ logger = logging.getLogger()
 _translate = QCoreApplication.translate
 
 
-class TableEditableModel(QAbstractTableModel):
-    def __init__(self, reach, headers=None, undo=None):
-        QAbstractTableModel.__init__(self)
-        data_list = []
-
-        self._undo_stack = undo
-        self._reach = reach
-
-        # Hack for qtlinguist
-        _ = _translate("Geometry", "Name")
-        _ = _translate("Geometry", "Kp (m)")
-        _ = _translate("Geometry", "Type")
-
-        if headers is None:
-            self.headers = [
-                "Name",
-                "Kp (m)",
-                "Type"
-            ]
-        else:
-            self.headers = headers
-
-    def rowCount(self, parent=QModelIndex()):
-        return self._reach.number_profiles
-
-    def columnCount(self, parent=QModelIndex()):
-        return len(self.headers)
-
+class TableEditableModel(PamhyrTableModel):
     def data(self, index, role=Qt.DisplayRole):
         if not index.isValid():
             return QVariant()
 
         if role == Qt.DisplayRole and index.column() == 0:
-            return self._reach.profile(index.row()).name
+            return self._data.profile(index.row()).name
 
         if role == Qt.DisplayRole and index.column() == 1:
-            kp = self._reach.profile(index.row()).kp
+            kp = self._data.profile(index.row()).kp
             return f"{kp:.4f}"
 
         if role == Qt.DisplayRole and index.column() == 2:
-            return self._reach.profile(index.row()).profile_type
+            return self._data.profile(index.row()).profile_type
 
         if role == Qt.TextAlignmentRole:
             return Qt.AlignHCenter | Qt.AlignVCenter
 
         if role == Qt.ForegroundRole and index.column() == 0:
-            name = self._reach.profile(index.row()).name\
+            name = self._data.profile(index.row()).name\
                                                    .strip()\
                                                    .lower()
             if (name == "upstream" or name == "up" or
@@ -102,16 +77,6 @@ class TableEditableModel(QAbstractTableModel):
 
         return QVariant()
 
-    def headerData(self, section, orientation, role=Qt.DisplayRole):
-        if role == Qt.DisplayRole:
-            if orientation == Qt.Horizontal:
-                if section < len(self.headers):
-                    return _translate("Geometry", self.headers[section])
-            else:
-                return str(section + 1)
-
-        return QVariant()
-
     def setData(self, index, value, role=Qt.EditRole):
         row = index.row()
         column = index.column()
@@ -119,19 +84,19 @@ class TableEditableModel(QAbstractTableModel):
         if role == Qt.EditRole and index.column() != 2:
             try:
                 if index.column() == 0:
-                    self._undo_stack.push(
+                    self._undo.push(
                         SetNameCommand(
-                            self._reach, index.row(),
-                            self._reach.profile(index.row()).name,
+                            self._data, index.row(),
+                            self._data.profile(index.row()).name,
                             value
                         )
                     )
 
                 if index.column() == 1:
-                    self._undo_stack.push(
+                    self._undo.push(
                         SetKPCommand(
-                            self._reach, index.row(),
-                            self._reach.profile(index.row()).kp,
+                            self._data, index.row(),
+                            self._data.profile(index.row()).kp,
                         value
                         )
                     )
@@ -149,27 +114,13 @@ class TableEditableModel(QAbstractTableModel):
 
         return False
 
-    def index(self, row, column, parent=QModelIndex()):
-        if not self.hasIndex(row, column, parent):
-            return QModelIndex()
-
-        return self.createIndex(row, column, QModelIndex())
-
-    def flags(self, index):
-        flg = Qt.ItemIsEnabled | Qt.ItemIsSelectable
-
-        if index.column() == 2:
-            return flg
-        else:
-            return Qt.ItemIsEditable | flg
-
     # @QtCore.pyqtSlot()
     def insert_row(self, row, parent=QModelIndex()):
         self.beginInsertRows(parent, row, row - 1)
 
-        self._undo_stack.push(
+        self._undo.push(
             AddCommand(
-                self._reach, row
+                self._data, row
             )
         )
 
@@ -179,9 +130,9 @@ class TableEditableModel(QAbstractTableModel):
     def remove_rows(self, rows, parent=QModelIndex()):
         self.beginRemoveRows(parent, rows[0], rows[-1])
 
-        self._undo_stack.push(
+        self._undo.push(
             DelCommand(
-                self._reach, rows
+                self._data, rows
             )
         )
 
@@ -191,9 +142,9 @@ class TableEditableModel(QAbstractTableModel):
     def sort_profiles(self, _reverse):
         self.layoutAboutToBeChanged.emit()
 
-        self._undo_stack.push(
+        self._undo.push(
             SortCommand(
-                self._reach, _reverse
+                self._data, _reverse
             )
         )
 
@@ -209,9 +160,9 @@ class TableEditableModel(QAbstractTableModel):
 
         self.beginMoveRows(parent, row - 1, row - 1, parent, target)
 
-        self._undo_stack.push(
+        self._undo.push(
             MoveCommand(
-                self._reach, "up", row
+                self._data, "up", row
             )
         )
 
@@ -219,16 +170,16 @@ class TableEditableModel(QAbstractTableModel):
         self.layoutChanged.emit()
 
     def move_row_down(self, row, parent=QModelIndex()):
-        if row > self._reach.number_profiles:
+        if row > self._data.number_profiles:
             return
 
         target = row
 
         self.beginMoveRows(parent, row + 1, row + 1, parent, target)
 
-        self._undo_stack.push(
+        self._undo.push(
             MoveCommand(
-                self._reach, "down", row
+                self._data, "down", row
             )
         )
 
@@ -238,9 +189,9 @@ class TableEditableModel(QAbstractTableModel):
     def duplicate(self, rows, profiles):
         self.layoutAboutToBeChanged.emit()
 
-        self._undo_stack.push(
+        self._undo.push(
             DuplicateCommand(
-                self._reach, rows,
+                self._data, rows,
                 profiles
             )
         )
@@ -250,7 +201,7 @@ class TableEditableModel(QAbstractTableModel):
 
 
     def paste(self, row, header, data):
-        if row > self._reach.number_profiles:
+        if row > self._data.number_profiles:
             return
 
         if len(data) == 0:
@@ -258,9 +209,9 @@ class TableEditableModel(QAbstractTableModel):
 
         self.layoutAboutToBeChanged.emit()
 
-        self._undo_stack.push(
+        self._undo.push(
             PasteCommand(
-                self._reach, row,
+                self._data, row,
                 list(
                     map(
                         lambda d: ProfileXYZ.from_data(header, d),
@@ -273,16 +224,7 @@ class TableEditableModel(QAbstractTableModel):
         self.layoutAboutToBeChanged.emit()
         self.layoutChanged.emit()
 
-
-    def undo(self):
-        self._undo_stack.undo()
-        self.layoutChanged.emit()
-
-    def redo(self):
-        self._undo_stack.redo()
-        self.layoutChanged.emit()
-
-
+# TODO: Delete useless delegate
 class Delegate(QStyledItemDelegate):
     def __init__(self, parent=None, setModelDataEvent=None):
         super(Delegate, self).__init__(parent)
diff --git a/src/View/Geometry/Translate.py b/src/View/Geometry/Translate.py
new file mode 100644
index 0000000000000000000000000000000000000000..c583732db9d1b8b0ac4ccc408215a8e64eac567d
--- /dev/null
+++ b/src/View/Geometry/Translate.py
@@ -0,0 +1,45 @@
+# Translate.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
+
+from View.Tools.PamhyrTranslate import PamhyrTranslate
+
+_translate = QCoreApplication.translate
+
+class GeometryTranslate(PamhyrTranslate):
+    def __init__(self):
+        super(GeometryTranslate, self).__init__()
+
+        self._dict["open_file"] = _translate("Geometry", "Open a file")
+        self._dict["file_st"] = _translate("Geometry", "File mage geometry (*.ST)")
+        self._dict["file_m"] = _translate("Geometry", "File mage meshed geometry (*.M)")
+        self._dict["file_all"] = _translate("Geometry", "All file (*)")
+
+        self._dict["reach"] = _translate("Geometry", "reach")
+        self._dict["reachs"] = _translate("Geometry", "reachs")
+
+        self._dict["cross_section"] = _translate("Geometry", "cross-section")
+        self._dict["cross_sections"] = _translate("Geometry", "cross-sections")
+        self._dict["profile"] = _translate("Geometry", "cross-section")
+        self._dict["profiles"] = _translate("Geometry", "cross-sections")
+
+        self._sub_dict["table_headers"] = {
+            "name": _translate("Geometry", "Name"),
+            "kp": _translate("Geometry", "KP"),
+        }
diff --git a/src/View/Geometry/Window.py b/src/View/Geometry/Window.py
index a66ed7812225cd52e8b7514814d0d80bb84602a8..1b334bb724f024ec5fef0e3f979cdc08a15b2ca1 100644
--- a/src/View/Geometry/Window.py
+++ b/src/View/Geometry/Window.py
@@ -34,118 +34,168 @@ from PyQt5.QtCore import (
 )
 from PyQt5.QtWidgets import (
     QApplication, QMainWindow, QFileDialog, QCheckBox,
-    QUndoStack, QShortcut,
+    QUndoStack, QShortcut, QTableView, QHeaderView,
+    QAction, QSlider, QPushButton, QVBoxLayout,
+    QLabel,
 )
 
 from View.Geometry.PlotXY import PlotXY
 from View.Geometry.PlotKPZ import PlotKPZ
 from View.Geometry.PlotAC import PlotAC
 
-from View.Tools.ASubWindow import ASubMainWindow, WindowToolKit
-from View.Tools.ListedSubWindow import ListedSubWindow
+from View.Tools.PamhyrWindow import PamhyrWindow
+from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
+from View.Tools.Plot.PamhyrCanvas import MplCanvas
 
-from View.Geometry.mainwindow_ui_reach import Ui_MainWindow
 from View.Geometry.Table import *
-from View.Geometry.Profile.Window import ProfileWindow
+from View.Geometry.Translate import GeometryTranslate
+# from View.Geometry.Profile.Window import ProfileWindow
 
 _translate = QCoreApplication.translate
 
 
-class GeometryWindow(ASubMainWindow, ListedSubWindow):
-    def __init__(self, model=None, title="Geometry", parent=None):
-        self._title = title
-        self.parent = parent
-        super(GeometryWindow, self).__init__(
-            name=self._title,
-            parent=parent
-        )
+class GeometryWindow(PamhyrWindow):
+    _pamhyr_ui = "GeometryReach"
+    _pamhyr_name = "Geometry"
 
-        self._model = model
-        self._reach = model.river.current_reach().reach
+    def __init__(self, reach=None, study=None, config=None, parent=None):
+        if reach is None:
+            self._reach = study.river.current_reach().reach
+        else:
+            self._reach = reach
 
-        self.ui = Ui_MainWindow()
-        self.ui.setupUi(self)
+        name = f"{self._pamhyr_name} - {self._reach.name}"
 
-        self.tableView = self.ui.tableView
-        self.tableView_header = self.ui.tableView_header
+        super(GeometryWindow, self).__init__(
+            title = name,
+            study = study,
+            config = config,
+            trad = GeometryTranslate(),
+            parent = parent
+        )
 
         self._tablemodel = None
         self._profile_window = []
-        self._clipboard = None
 
-        self.setup_window()
-        self.setup_sc()
-        self.setup_model()
+        self.setup_table()
         self.setup_plots()
+        self.setup_statusbar()
         self.setup_connections()
         self.changed_slider_value()
 
-    def setup_window(self):
-        self._title = f"{self.ui.mainwindow_title} - {self._reach.name}"
-        self.setWindowTitle(self._title)
-
-    def setup_sc(self):
-        self._undo_stack = QUndoStack()
+    def setup_table(self):
+        table_headers = self._trad.get_dict("table_headers")
 
-        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_model(self):
+        table = self.find(QTableView, "tableView")
         self._tablemodel = TableEditableModel(
-            headers = self.ui.tableView_header,
-            reach = self._reach,
+            table_view = table,
+            table_headers = table_headers,
+            editable_headers = ["name", "kp"],
+            data = self._reach,
             undo = self._undo_stack
         )
-        self.tableView.setModel(self._tablemodel)
-        self.tableView.setItemDelegate(Delegate())
+        table.setModel(self._tablemodel)
+        table.setSelectionBehavior(QAbstractItemView.SelectRows)
+        table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+        table.setAlternatingRowColors(True)
 
     def setup_plots(self):
+        self._canvas_xy = MplCanvas(width=3, height=4, dpi=100)
+        self._canvas_xy.setObjectName("canvas_xy")
+        self._toolbar_xy = PamhyrPlotToolbar(
+            self._canvas_xy, self,
+            items = ["home", "zoom", "save", "iso", "back/forward", "move"]
+        )
+        self._plot_layout_xy = self.find(QVBoxLayout, "verticalLayout")
+        self._plot_layout_xy.addWidget(self._toolbar_xy)
+        self._plot_layout_xy.addWidget(self._canvas_xy)
         self.plot_xy()
+
+        self._canvas_kpc = MplCanvas(width=6, height=4, dpi=100)
+        self._canvas_kpc.setObjectName("canvas_kpc")
+        self._toolbar_kpc = PamhyrPlotToolbar(
+            self._canvas_kpc, self,
+            items = ["home", "zoom", "save", "iso", "back/forward", "move"]
+        )
+        self._plot_layout_kpc = self.find(QVBoxLayout, "verticalLayout_2")
+        self._plot_layout_kpc.addWidget(self._toolbar_kpc)
+        self._plot_layout_kpc.addWidget(self._canvas_kpc)
         self.plot_kpc()
+
+        self._canvas_ac = MplCanvas(width=9, height=4, dpi=100)
+        self._canvas_ac.setObjectName("canvas_ac")
+        self._toolbar_ac = PamhyrPlotToolbar(
+            self._canvas_ac, self,
+            items = ["home", "zoom", "save", "iso", "back/forward", "move"]
+        )
+        self._plot_layout_ac = self.find(QVBoxLayout, "verticalLayout_3")
+        self._plot_layout_ac.addWidget(self._toolbar_ac)
+        self._plot_layout_ac.addWidget(self._canvas_ac)
         self.plot_ac()
 
+    def _compute_status_label(self):
+        row = self.index_selected_row()
+        profile = self._reach.profile(row)
+
+        name = profile.name + " " + str(profile.kp)
+
+        return (
+            f"<font color=\"Grey\">{self._trad['reach']}: {self._reach.name}" + " - "
+            f"{self._trad['cross_section']}:</font> {name}"
+        )
+
+    def setup_statusbar(self):
+        txt = ""
+        self._status_label = QLabel(txt)
+        self.statusbar.addPermanentWidget(self._status_label)
+
+    def update_statusbar(self):
+        txt = self._compute_status_label()
+        self._status_label.setText(txt)
+
     def setup_connections(self):
-        self.ui.btn_open.triggered.connect(self.open_file_dialog)
-        self.ui.btn_sort_asc.triggered.connect(self.sort_ascending)
-        self.ui.btn_sort_desc.triggered.connect(self.sort_descending)
-        self.ui.btn_move_up.triggered.connect(self.move_row_up)
-        self.ui.btn_move_down.triggered.connect(self.move_row_down)
-        # self.ui.btn_end_editing.triggered.connect(self.handleSave)
-        self.ui.btn_add.triggered.connect(self.insert_row)
-        self.ui.btn_delete.triggered.connect(self.delete_rows)
-        self.ui.btn_edit.triggered.connect(self.edit_profile)
-        self.ui.verticalSlider.valueChanged.connect(self.changed_slider_value)
-
-        self.ui.btn_slider_up.clicked.connect(self.decrement_value_slider)
-        self.ui.btn_slider_down.clicked.connect(self.increment_value_slider)
-        self.ui.btn_move_up.triggered.connect(self.changed_profile_slot)
-
-        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)
+        actions = {
+            "action_import": self.import_from_file,
+            # "action_export": self.export_to_file,
+            "action_sort_asc": self.sort_ascending,
+            "action_sort_des": self.sort_descending,
+            "action_up": self.move_up,
+            "action_down": self.move_down,
+            "action_add": self.add,
+            "action_delete": self.delete,
+            "action_edit": self.edit_profile,
+        }
+
+        for action in actions:
+            self.find(QAction, action)\
+                .triggered.connect(actions[action])
+
+        self.find(QSlider, "verticalSlider").valueChanged.connect(self.changed_slider_value)
+        self.find(QPushButton, "pushButton_up").clicked.connect(self.decrement_value_slider)
+        self.find(QPushButton, "pushButton_down").clicked.connect(self.increment_value_slider)
 
         # Profile selection when line change in table
-        self.tableView.selectionModel()\
-                      .selectionChanged\
-                      .connect(self.select_current_profile)
+        self.find(QTableView, "tableView").selectionModel()\
+                                          .selectionChanged\
+                                          .connect(self.select_current_profile)
 
-    def open_file_dialog(self):
+
+    def import_from_file(self):
         options = QFileDialog.Options()
         settings = QSettings(QSettings.IniFormat, QSettings.UserScope, 'MyOrg', )
         options |= QFileDialog.DontUseNativeDialog
 
+        file_types = [
+            self._trad["file_st"],
+            self._trad["file_m"],
+            self._trad["file_all"],
+        ]
+
         filename, _ = QtWidgets.QFileDialog.getOpenFileName(
             self,
-            _translate("MainWindow_reach", "Ouvrir un fichier"),
+            self._trad["open_file"],
             "",
-            _translate("MainWindow_reach", "Fichiers .ST (*.ST)") +
-            ";; " +
-            _translate("MainWindow_reach", "Fichiers .M (*.M)") +
-            ";; " +
-            _translate("MainWindow_reach", "Tous les fichiers (*)"),
+            ";; ".join(file_types),
             options=options
         )
 
@@ -159,20 +209,6 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
             self.plot_kpc()
             self.plot_ac()
 
-    def messagebox_profile_editing(self):
-        msg_box = QtWidgets.QMessageBox()
-        msg_box.setIcon(QtWidgets.QMessageBox.Information)
-        msg_box.setWindowTitle(_translate("MainWindow_reach",
-                                          "Édition des profils sélectionnés"))
-        msg_box.setText(_translate("MainWindow_reach",
-                                   "Vous avez sélectionné plus de 5 profils."
-                                   " \nSeuls les 5 premiers seront édités."))
-        msg_box.setStandardButtons(QtWidgets.QMessageBox.Ok)
-
-        return_value = msg_box.exec()
-        # if return_value == QtWidgets.QMessageBox.Ok:
-        #     print('OK clicked')
-
     def edit_profile(self):
         self.tableView.model().blockSignals(True)
 
@@ -215,9 +251,9 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
         self.tableView.model().blockSignals(True)
 
         self._plot_xy = PlotXY(
-            canvas = self.ui.canvas_1,
+            canvas = self._canvas_xy,
             data = self._reach,
-            toolbar = self.ui.toolbar_1
+            toolbar = self._toolbar_xy
         )
         self._plot_xy.draw()
 
@@ -232,9 +268,9 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
         self.tableView.model().blockSignals(True)
 
         self._plot_kpc = PlotKPZ(
-            canvas = self.ui.canvas_2,
+            canvas = self._canvas_kpc,
             data = self._reach,
-            toolbar = self.ui.toolbar_2
+            toolbar = self._toolbar_kpc
         )
         self._plot_kpc.draw()
 
@@ -249,9 +285,9 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
         self.tableView.model().blockSignals(True)
 
         self._plot_ac = PlotAC(
-            canvas = self.ui.canvas_3,
+            canvas = self._canvas_ac,
             data = self._reach,
-            toolbar = self.ui.toolbar_3,
+            toolbar = self._toolbar_ac,
             plot_xy = self._plot_xy
         )
         self._plot_ac.draw()
@@ -304,7 +340,7 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
         if len(self.tableView.selectedIndexes()) > 0:
             row = self.index_selected_row()
 
-            self.ui.verticalSlider.setValue(row)
+            self.find(QSlider, "verticalSlider").setValue(row)
             self.select_plot_xy(row)
             self.select_plot_kpc(row)
             self.select_plot_ac(row)
@@ -315,41 +351,37 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
         self.tableView.model().blockSignals(True)
 
         if self._tablemodel.rowCount() != 0:
-            self.ui.verticalSlider.setMaximum(self._tablemodel.rowCount() - 1)
+            slider = self.find(QSlider, "verticalSlider")
+            slider.setMaximum(self._tablemodel.rowCount() - 1)
 
-            slider_value = self.ui.verticalSlider.value()
+            slider_value = slider.value()
             kp = self._reach.profile(slider_value).kp
 
-            self.ui.vertical_slider_label.setText(
-                _translate("MainWindow_reach", "Kp : ") +
-                f"{kp}" + "\n" +
-                _translate("MainWindow_reach",
-                           "Profil N° : ") +
-                f"{slider_value + 1}"
-            )
-
             self.select_plot_xy(slider_value)
             self.select_plot_kpc(slider_value)
             self.select_row_profile_slider(slider_value)
+            self.update_statusbar()
 
         self.tableView.model().blockSignals(False)
 
     def increment_value_slider(self):
-        if 0 <= self.ui.verticalSlider.value() < self._tablemodel.rowCount() - 1:
-            self.ui.verticalSlider.setValue(self.ui.verticalSlider.value() + 1)
+        slider = self.find(QSlider, "verticalSlider")
+        if 0 <= slider.value() < self._tablemodel.rowCount() - 1:
+            slider.setValue(slider.value() + 1)
 
     def decrement_value_slider(self):
-        if 0 < self.ui.verticalSlider.value() < self._tablemodel.rowCount():
-            self.ui.verticalSlider.setValue(self.ui.verticalSlider.value() - 1)
+        slider = self.find(QSlider, "verticalSlider")
+        if 0 < slider.value() < self._tablemodel.rowCount():
+            slider.setValue(slider.value() - 1)
 
-    def insert_row(self):
+    def add(self):
         if len(self.tableView.selectedIndexes()) == 0:
-            self._tablemodel.insert_row(self._tablemodel.rowCount())
+            self._tablemodel.add(self._tablemodel.rowCount())
         else:
             row = self.index_selected_row()
-            self._tablemodel.insert_row(row + 1)
+            self._tablemodel.add(row + 1)
 
-    def delete_rows(self):
+    def delete(self):
         rows = sorted(
             list(
                 set(
@@ -384,14 +416,14 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
         self.select_current_profile()
         self.changed_slider_value()
 
-    def move_row_up(self):
+    def move_up(self):
         row = self.index_selected_row()
-        self._tablemodel.move_row_up(row)
+        self._tablemodel.move_up(row)
         self.select_current_profile()
 
-    def move_row_down(self):
+    def move_down(self):
         row = self.index_selected_row()
-        self._tablemodel.move_row_down(row)
+        self._tablemodel.move_down(row)
         self.select_current_profile()
 
     def duplicate(self):
@@ -412,7 +444,7 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
         self._tablemodel.duplicate(rows, profiles)
         self.select_current_profile()
 
-    def copy(self):
+    def _copy(self):
         rows = self.tableView\
                    .selectionModel()\
                    .selectedRows()
@@ -428,7 +460,7 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
 
         self.copyTableIntoClipboard(table)
 
-    def paste(self):
+    def _paste(self):
         header, data = self.parseClipboardTable()
 
         if len(data) == 0:
@@ -443,19 +475,19 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
         self._tablemodel.paste(row, header, data)
         self.select_current_profile()
 
-    def undo(self):
+    def _undo(self):
         self._tablemodel.undo()
         self.select_current_profile()
         self.update_plot_xy()
         self.update_plot_kpc()
 
-    def redo(self):
+    def _redo(self):
         self._tablemodel.redo()
         self.select_current_profile()
         self.update_plot_xy()
         self.update_plot_kpc()
 
-    def handleSave(self):
+    def export_to_file(self):
         options = QFileDialog.Options()
         DEFAULT_DIRECTORY = '/home/'
         settings = QSettings(QSettings.IniFormat, QSettings.UserScope, 'MyOrg', )
@@ -464,32 +496,11 @@ class GeometryWindow(ASubMainWindow, ListedSubWindow):
 
         filename, filters = QFileDialog.getSaveFileName(
             self,
-            filter=_translate("MainWindow_reach",
-                              "Files .ST(*.ST or *.st)")
-            + ";; " +
-            _translate("MainWindow_reach", "All files "
-                       "(*)"),
-            options=options
+            filter = self._trad["file_st"] + ";; " + self._trad["file_all"],
+            options = options
         )
 
         current_dir = os.path.split(filename)[0] or DEFAULT_DIRECTORY
 
         if filename != '':
             self._tablemodel.export_reach(filename)
-
-    def handleOpen(self):
-        filename, filterName = QFileDialog.getOpenFileName(self)
-
-        if filename != '':
-            with open(filename, 'r') as f:
-                reader = csv.reader(f, delimiter='\t')
-                header = next(reader)
-                buf = []
-                for row in reader:
-                    row[0] = QCheckBox("-")
-                    buf.append(row)
-
-                self._tablemodel = None
-                self._tablemodel = TableEditableModel(buf)
-                self.tableView.setModel(self._tablemodel)
-                filename = ''
diff --git a/src/View/MainWindow.py b/src/View/MainWindow.py
index 58a2a031c0d2e9fbf0ccb6b217c41408635a2950..8162807e377723ad1bafeb207883f18644eb92b1 100644
--- a/src/View/MainWindow.py
+++ b/src/View/MainWindow.py
@@ -44,7 +44,7 @@ from View.Configure.Window import ConfigureWindow
 from View.Study.Window import NewStudyWindow
 from View.About.Window import AboutWindow
 from View.Network.Window import NetworkWindow
-# from View.Geometry.Window import GeometryWindow
+from View.Geometry.Window import GeometryWindow
 # from View.BoundaryCondition.Window import BoundaryConditionWindow
 # from View.LateralContribution.Window import LateralContributionWindow
 # from View.InitialConditions.Window import InitialConditionsWindow
@@ -534,7 +534,7 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
             )
 
             if geometry is None:
-                geometry = GeometryWindow(model=self._study, parent=self)
+                geometry = GeometryWindow(study=self._study, config=self.conf, parent=self)
                 geometry.show()
             else:
                 geometry.activateWindow()
diff --git a/src/View/Tools/PamhyrTable.py b/src/View/Tools/PamhyrTable.py
index 08e36c8430e5e225b5e43ce70ba78035b57b3957..65cd7687a0ce3eee14824f72748580227985a699 100644
--- a/src/View/Tools/PamhyrTable.py
+++ b/src/View/Tools/PamhyrTable.py
@@ -115,10 +115,10 @@ class PamhyrTableModel(QAbstractTableModel):
 
         return options
 
-    def rowCount(self, parent):
+    def rowCount(self, parent=QModelIndex()):
         return len(self._lst)
 
-    def columnCount(self, parent):
+    def columnCount(self, parent=QModelIndex()):
         return len(self._headers)
 
     def headerData(self, section, orientation, role):
diff --git a/src/View/ui/GeometryCrossSection.ui b/src/View/ui/GeometryCrossSection.ui
new file mode 100644
index 0000000000000000000000000000000000000000..b0c12393d47714d27691d2701903f2d6b82374d0
--- /dev/null
+++ b/src/View/ui/GeometryCrossSection.ui
@@ -0,0 +1,134 @@
+<?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>1120</width>
+    <height>630</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">
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+      <widget class="QTableView" name="tableView"/>
+      <widget class="QWidget" name="verticalLayoutWidget">
+       <layout class="QVBoxLayout" name="verticalLayout"/>
+      </widget>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>1120</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_delete"/>
+   <addaction name="action_sort"/>
+   <addaction name="action_resort"/>
+   <addaction name="action_up"/>
+   <addaction name="action_down"/>
+  </widget>
+  <action name="action_add">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/gtk-add.png</normaloff>ressources/gtk-add.png</iconset>
+   </property>
+   <property name="text">
+    <string>add</string>
+   </property>
+   <property name="toolTip">
+    <string>Add a point on cross-section</string>
+   </property>
+  </action>
+  <action name="action_delete">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/gtk-remove.png</normaloff>ressources/gtk-remove.png</iconset>
+   </property>
+   <property name="text">
+    <string>delete</string>
+   </property>
+   <property name="toolTip">
+    <string>Delete selected point(s)</string>
+   </property>
+  </action>
+  <action name="action_up">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/up.png</normaloff>ressources/up.png</iconset>
+   </property>
+   <property name="text">
+    <string>up</string>
+   </property>
+   <property name="toolTip">
+    <string>Move up selected point(s)</string>
+   </property>
+  </action>
+  <action name="action_down">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/down.png</normaloff>ressources/down.png</iconset>
+   </property>
+   <property name="text">
+    <string>down</string>
+   </property>
+   <property name="toolTip">
+    <string>Mode down selected point(s)</string>
+   </property>
+  </action>
+  <action name="action_sort">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/gtk-sort-ascending.png</normaloff>ressources/gtk-sort-ascending.png</iconset>
+   </property>
+   <property name="text">
+    <string>sort</string>
+   </property>
+   <property name="toolTip">
+    <string>Sort points by nearest neighbor</string>
+   </property>
+  </action>
+  <action name="action_resort">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/gtk-sort-descending.png</normaloff>ressources/gtk-sort-descending.png</iconset>
+   </property>
+   <property name="text">
+    <string>resort</string>
+   </property>
+   <property name="toolTip">
+    <string>Sort reversed points by nearest neighbor</string>
+   </property>
+  </action>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/View/ui/GeometryReach.ui b/src/View/ui/GeometryReach.ui
new file mode 100644
index 0000000000000000000000000000000000000000..e09d9d359ac1e163f710498e2a1f2214c1e17ff9
--- /dev/null
+++ b/src/View/ui/GeometryReach.ui
@@ -0,0 +1,231 @@
+<?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>1280</width>
+    <height>720</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>MainWindow</string>
+  </property>
+  <property name="locale">
+   <locale language="English" country="Europe"/>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QGridLayout" name="gridLayout">
+    <item row="0" column="0">
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <widget class="QSplitter" name="splitter_3">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <widget class="QTableView" name="tableView"/>
+        <widget class="QSplitter" name="splitter_2">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <widget class="QSplitter" name="splitter">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <widget class="QWidget" name="verticalLayoutWidget">
+           <layout class="QVBoxLayout" name="verticalLayout"/>
+          </widget>
+          <widget class="QWidget" name="verticalLayoutWidget_2">
+           <layout class="QVBoxLayout" name="verticalLayout_2"/>
+          </widget>
+         </widget>
+         <widget class="QWidget" name="verticalLayoutWidget_3">
+          <layout class="QVBoxLayout" name="verticalLayout_3"/>
+         </widget>
+        </widget>
+       </widget>
+      </item>
+      <item>
+       <layout class="QVBoxLayout" name="verticalLayout_4">
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_2">
+          <item>
+           <widget class="QSlider" name="verticalSlider">
+            <property name="orientation">
+             <enum>Qt::Vertical</enum>
+            </property>
+            <property name="invertedAppearance">
+             <bool>true</bool>
+            </property>
+            <property name="invertedControls">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <widget class="QPushButton" name="pushButton_up">
+          <property name="text">
+           <string/>
+          </property>
+          <property name="icon">
+           <iconset>
+            <normaloff>ressources/go-up2.png</normaloff>ressources/go-up2.png</iconset>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="pushButton_down">
+          <property name="text">
+           <string/>
+          </property>
+          <property name="icon">
+           <iconset>
+            <normaloff>ressources/go-down1.png</normaloff>ressources/go-down1.png</iconset>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>1280</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_import"/>
+   <addaction name="action_add"/>
+   <addaction name="action_delete"/>
+   <addaction name="action_edit"/>
+   <addaction name="action_sort_asc"/>
+   <addaction name="action_sort_des"/>
+   <addaction name="action_up"/>
+   <addaction name="action_down"/>
+   <addaction name="action_export"/>
+  </widget>
+  <action name="action_import">
+   <property name="text">
+    <string>import</string>
+   </property>
+   <property name="toolTip">
+    <string>Import geometry</string>
+   </property>
+  </action>
+  <action name="action_export">
+   <property name="text">
+    <string>export</string>
+   </property>
+   <property name="toolTip">
+    <string>Export geometry</string>
+   </property>
+  </action>
+  <action name="action_add">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/gtk-add.png</normaloff>ressources/gtk-add.png</iconset>
+   </property>
+   <property name="text">
+    <string>add</string>
+   </property>
+   <property name="toolTip">
+    <string>Add a cross-section</string>
+   </property>
+  </action>
+  <action name="action_delete">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/gtk-remove.png</normaloff>ressources/gtk-remove.png</iconset>
+   </property>
+   <property name="text">
+    <string>delete</string>
+   </property>
+   <property name="toolTip">
+    <string>Delete selected cross-section(s)</string>
+   </property>
+  </action>
+  <action name="action_edit">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/edit.png</normaloff>ressources/edit.png</iconset>
+   </property>
+   <property name="text">
+    <string>edit</string>
+   </property>
+   <property name="toolTip">
+    <string>Edit selected cross section(s)</string>
+   </property>
+  </action>
+  <action name="action_sort_asc">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/gtk-sort-ascending.png</normaloff>ressources/gtk-sort-ascending.png</iconset>
+   </property>
+   <property name="text">
+    <string>sort_asc</string>
+   </property>
+   <property name="toolTip">
+    <string>Sort cross-sections by ascending KP</string>
+   </property>
+  </action>
+  <action name="action_sort_des">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/gtk-sort-descending.png</normaloff>ressources/gtk-sort-descending.png</iconset>
+   </property>
+   <property name="text">
+    <string>sort_des</string>
+   </property>
+   <property name="toolTip">
+    <string>Sort cross-sections by descending KP</string>
+   </property>
+  </action>
+  <action name="action_up">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/up.png</normaloff>ressources/up.png</iconset>
+   </property>
+   <property name="text">
+    <string>up</string>
+   </property>
+   <property name="toolTip">
+    <string>Move up selected cross-section(s)</string>
+   </property>
+  </action>
+  <action name="action_down">
+   <property name="icon">
+    <iconset>
+     <normaloff>ressources/down.png</normaloff>ressources/down.png</iconset>
+   </property>
+   <property name="text">
+    <string>down</string>
+   </property>
+   <property name="toolTip">
+    <string>Move down selected cross-section(s)</string>
+   </property>
+  </action>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>