diff --git a/src/sakia/gui/agent/model.py b/src/sakia/gui/agent/model.py
deleted file mode 100644
index 61a2d366bd93c60c1ed4ec9d386983fcdf822511..0000000000000000000000000000000000000000
--- a/src/sakia/gui/agent/model.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from PyQt5.QtCore import QObject
-
-
-class AgentModel(QObject):
-    """
-    An agent
-    """
-
-    def __init__(self, parent):
-        """
-        Constructor of an agent
-
-        :param sakia.core.gui.agent.controller.AbstractAgentController controller: the controller
-        """
-        super().__init__(parent)
-
-    @property
-    def account(self):
-        return self.app.current_account
diff --git a/src/sakia/gui/agent/__init__.py b/src/sakia/gui/component/__init__.py
similarity index 100%
rename from src/sakia/gui/agent/__init__.py
rename to src/sakia/gui/component/__init__.py
diff --git a/src/sakia/gui/agent/controller.py b/src/sakia/gui/component/controller.py
similarity index 61%
rename from src/sakia/gui/agent/controller.py
rename to src/sakia/gui/component/controller.py
index 334ad3b71561ad400ac4fc31d66eb82c6ede4872..a98e7c0a910c0e69c13d2516c2e1d4cdf0bd6295 100644
--- a/src/sakia/gui/agent/controller.py
+++ b/src/sakia/gui/component/controller.py
@@ -1,14 +1,14 @@
 from PyQt5.QtCore import QObject
 
 
-class AgentController(QObject):
+class ComponentController(QObject):
     """
     The navigation panel
     """
 
     def __init__(self, parent, view, model):
         """
-        Constructor of the navigation agent
+        Constructor of the navigation component
 
         :param PyQt5.QtWidgets.QWidget presentation: the presentation
         :param sakia.core.gui.navigation.model.NavigationModel model: the model
@@ -17,12 +17,16 @@ class AgentController(QObject):
         self.view = view
         self.model = model
 
+    @classmethod
+    def create(cls, parent, app, **kwargs):
+        raise NotImplementedError("Create method not implemented")
+
     def attach(self, controller):
         """
-        Attach an agent controller to this controller
-        :param AgentController controller: the attached controller
+        Attach an component controller to this controller
+        :param ComponentController controller: the attached controller
         :return: the attached controller
-        :rtype: AgentController
+        :rtype: ComponentController
         """
         if controller:
             controller.setParent(self)
diff --git a/src/sakia/gui/component/model.py b/src/sakia/gui/component/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ca16fdfd455cbe4c599e158ca6921f8d17debfa
--- /dev/null
+++ b/src/sakia/gui/component/model.py
@@ -0,0 +1,15 @@
+from PyQt5.QtCore import QObject
+
+
+class ComponentModel(QObject):
+    """
+    An component
+    """
+
+    def __init__(self, parent):
+        """
+        Constructor of an component
+
+        :param sakia.core.gui.component.controller.AbstractAgentController controller: the controller
+        """
+        super().__init__(parent)
diff --git a/src/sakia/gui/homescreen.py b/src/sakia/gui/homescreen.py
deleted file mode 100644
index 0f0618b11f6ff38018cccc0dbd64ed634ddc364b..0000000000000000000000000000000000000000
--- a/src/sakia/gui/homescreen.py
+++ /dev/null
@@ -1,101 +0,0 @@
-"""
-Created on 31 janv. 2015
-
-@author: vit
-"""
-
-from PyQt5.QtWidgets import QWidget, QFrame, QGridLayout, QAction
-from PyQt5.QtCore import QEvent, Qt, pyqtSlot, pyqtSignal
-from ..presentation.homescreen_uic import Ui_HomescreenWidget
-from .community_tile import CommunityTile
-from ..core.community import Community
-import logging
-
-
-class FrameCommunities(QFrame):
-    community_tile_clicked = pyqtSignal(Community)
-
-    def __init__(self, parent):
-        super().__init__(parent)
-        self.grid_layout = QGridLayout()
-        self.setLayout(self.grid_layout)
-        self.grid_layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
-        self.setFrameShape(QFrame.StyledPanel)
-        self.setFrameShadow(QFrame.Raised)
-        self.tiles = []
-
-    def sizeHint(self):
-        return self.parentWidget().size()
-
-    def refresh(self, app):
-        for t in self.tiles:
-            t.cancel_refresh()
-            t.setParent(None)
-        self.tiles = []
-        if app.current_account:
-            for c in app.current_account.communities:
-                community_tile = CommunityTile(self, app, c)
-                community_tile.clicked.connect(self.click_on_tile)
-                self.layout().addWidget(community_tile)
-                self.tiles.append(community_tile)
-
-    def refresh_content(self):
-        for t in self.tiles:
-            t.refresh()
-
-    @pyqtSlot()
-    def click_on_tile(self):
-        tile = self.sender()
-        logging.debug("Click on tile")
-        self.community_tile_clicked.emit(tile.community)
-
-
-class HomeScreenWidget(QWidget, Ui_HomescreenWidget):
-    """
-    classdocs
-    """
-
-    def __init__(self, app, status_label):
-        """
-        Constructor
-        """
-        super().__init__()
-        self.setupUi(self)
-        self.app = app
-        self.frame_communities = FrameCommunities(self)
-        self.layout().addWidget(self.frame_communities)
-        self.status_label = status_label
-
-    def refresh(self):
-        self.frame_communities.refresh(self.app)
-        if self.app.current_account:
-            self.frame_connected.show()
-            self.label_connected.setText(self.tr("Connected as {0}".format(self.app.current_account.name)))
-            self.frame_disconnected.hide()
-        else:
-            self.frame_disconnected.show()
-            self.frame_connected.hide()
-
-    def referential_changed(self):
-        self.frame_communities.refresh_content()
-
-    def showEvent(self, QShowEvent):
-        """
-
-        :param QShowEvent:
-        :return:
-        """
-        self.frame_communities.refresh_content()
-        self.status_label.setText("")
-
-    def changeEvent(self, event):
-        """
-        Intercepte LanguageChange event to translate UI
-        :param QEvent QEvent: Event
-        :return:
-        """
-        if event.type() == QEvent.LanguageChange:
-            self.retranslateUi(self)
-        return super(HomeScreenWidget, self).changeEvent(event)
-
-
diff --git a/src/sakia/gui/homescreen/__init__.py b/src/sakia/gui/homescreen/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/sakia/gui/homescreen/controller.py b/src/sakia/gui/homescreen/controller.py
new file mode 100644
index 0000000000000000000000000000000000000000..bad5bec1620d460b85468a7130bc3059ddb5b4a8
--- /dev/null
+++ b/src/sakia/gui/homescreen/controller.py
@@ -0,0 +1,33 @@
+from ..component.controller import ComponentController
+from .view import HomeScreenView
+from .model import HomeScreenModel
+
+
+class HomeScreenController(ComponentController):
+    """
+    The navigation panel
+    """
+
+    def __init__(self, parent, view, model):
+        """
+        Constructor of the navigation component
+
+        :param PyQt5.QtWidgets.QWidget presentation: the presentation
+        :param sakia.core.gui.navigation.model.NavigationModel model: the model
+        """
+        super().__init__(parent, view, model)
+
+    @classmethod
+    def create(cls, parent, app, **kwargs):
+        """
+        Instanciate a homescreen component
+        :param sakia.gui.agent.controller.AgentController parent:
+        :return: a new Homescreen controller
+        :rtype: NavigationController
+        """
+        view = HomeScreenView(parent.view)
+        model = HomeScreenModel(None, app)
+        homescreen = cls(parent, view, model)
+        model.setParent(homescreen)
+        return homescreen
+
diff --git a/src/sakia/gui/homescreen/homescreen.py b/src/sakia/gui/homescreen/homescreen.py
new file mode 100644
index 0000000000000000000000000000000000000000..081f313358d69736dc9134bde521dd7baaeec58c
--- /dev/null
+++ b/src/sakia/gui/homescreen/homescreen.py
@@ -0,0 +1,56 @@
+"""
+Created on 31 janv. 2015
+
+@author: vit
+"""
+
+
+class HomeScreenWidget(QWidget, Ui_HomescreenWidget):
+    """
+    classdocs
+    """
+
+    def __init__(self, parent, app, status_label):
+        """
+        Constructor
+        """
+        super().__init__()
+        self.setupUi(self)
+        self.app = app
+        self.frame_communities = FrameCommunities(self)
+        self.layout().addWidget(self.frame_communities)
+        self.status_label = status_label
+
+    def refresh(self):
+        self.frame_communities.refresh(self.app)
+        if self.app.current_account:
+            self.frame_connected.show()
+            self.label_connected.setText(self.tr("Connected as {0}".format(self.app.current_account.name)))
+            self.frame_disconnected.hide()
+        else:
+            self.frame_disconnected.show()
+            self.frame_connected.hide()
+
+    def referential_changed(self):
+        self.frame_communities.refresh_content()
+
+    def showEvent(self, QShowEvent):
+        """
+
+        :param QShowEvent:
+        :return:
+        """
+        self.frame_communities.refresh_content()
+        self.status_label.setText("")
+
+    def changeEvent(self, event):
+        """
+        Intercepte LanguageChange event to translate UI
+        :param QEvent QEvent: Event
+        :return:
+        """
+        if event.type() == QEvent.LanguageChange:
+            self.retranslateUi(self)
+        return super(HomeScreenWidget, self).changeEvent(event)
+
+
diff --git a/res/ui/homescreen.ui b/src/sakia/gui/homescreen/homescreen.ui
similarity index 100%
rename from res/ui/homescreen.ui
rename to src/sakia/gui/homescreen/homescreen.ui
diff --git a/src/sakia/gui/homescreen/model.py b/src/sakia/gui/homescreen/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..af5b2f6cba174e0e714acc637010ed1b85f40ecc
--- /dev/null
+++ b/src/sakia/gui/homescreen/model.py
@@ -0,0 +1,11 @@
+from sakia.gui.component.model import ComponentModel
+
+
+class HomeScreenModel(ComponentModel):
+    """
+    The model of Navigation component
+    """
+
+    def __init__(self, parent, app):
+        super().__init__(parent)
+        self.app = app
diff --git a/src/sakia/gui/homescreen/view.py b/src/sakia/gui/homescreen/view.py
new file mode 100644
index 0000000000000000000000000000000000000000..dd4e7040a527151254a7dae2f1bc6ad583425967
--- /dev/null
+++ b/src/sakia/gui/homescreen/view.py
@@ -0,0 +1,16 @@
+from PyQt5.QtWidgets import QWidget
+from .homescreen_uic import Ui_HomescreenWidget
+
+
+class HomeScreenView(QWidget, Ui_HomescreenWidget):
+    """
+    classdocs
+    """
+
+    def __init__(self, app):
+        """
+        Constructor
+        """
+        super().__init__()
+        self.setupUi(self)
+        self.app = app
diff --git a/src/sakia/gui/main_window/controller.py b/src/sakia/gui/main_window/controller.py
index 77180d8e5019ae0d6dc92033480f510433ae369d..5fdab5f359929cf5b487aa7b80980a4b987ca29a 100644
--- a/src/sakia/gui/main_window/controller.py
+++ b/src/sakia/gui/main_window/controller.py
@@ -14,15 +14,16 @@ from PyQt5.QtGui import QIcon
 from ..password_asker import PasswordAskerDialog
 from ...__init__ import __version__
 from ..widgets import toast
-from ..agent.controller import AgentController
+from ..component.controller import ComponentController
 from .view import MainWindowView
 from .model import MainWindowModel
 from ..status_bar.controller import StatusBarController
 from ..toolbar.controller import ToolbarController
 from ..navigation.controller import NavigationController
+from ..txhistory.controller import TxHistoryController
 
 
-class MainWindowController(AgentController):
+class MainWindowController(ComponentController):
     """
     classdocs
     """
@@ -30,10 +31,10 @@ class MainWindowController(AgentController):
     def __init__(self, view, model, password_asker, status_bar, toolbar, navigation):
         """
         Init
-        :param MainWindowView view: the ui of the mainwindow agent
-        :param sakia.gui.main_window.model.MainWindowModel: the model of the mainwindow agent
-        :param sakia.gui.status_bar.controller.StatusBarController status_bar: the controller of the status bar agent
-        :param sakia.gui.toolbar.controller.ToolbarController toolbar: the controller of the toolbar agent
+        :param MainWindowView view: the ui of the mainwindow component
+        :param sakia.gui.main_window.model.MainWindowModel: the model of the mainwindow component
+        :param sakia.gui.status_bar.controller.StatusBarController status_bar: the controller of the status bar component
+        :param sakia.gui.toolbar.controller.ToolbarController toolbar: the controller of the toolbar component
         :param sakia.gui.navigation.contoller.NavigationController navigation: the controller of the navigation
 
         :param PasswordAsker password_asker: the password asker of the application
@@ -46,6 +47,7 @@ class MainWindowController(AgentController):
         self.status_bar = self.attach(status_bar)
         self.toolbar = self.attach(toolbar)
         self.navigation = self.attach(navigation)
+        self.stacked_widgets = {}
 
         QApplication.setWindowIcon(QIcon(":/icons/sakia_logo"))
 
@@ -55,12 +57,16 @@ class MainWindowController(AgentController):
         model = MainWindowModel(None, app)
         password_asker = PasswordAskerDialog(None)
         main_window = cls(view, model, password_asker, None, None, None)
+
         main_window.status_bar = main_window.attach(StatusBarController.create(main_window, app))
         view.setStatusBar(main_window.status_bar.view)
+
         main_window.toolbar = main_window.attach(ToolbarController.create(main_window, password_asker))
         view.top_layout.addWidget(main_window.toolbar.view)
+
         main_window.navigation = main_window.attach(NavigationController.create(main_window, app))
-        view.bottom_layout.addWidget(main_window.navigation.view)
+        view.bottom_layout.insertWidget(0, main_window.navigation.view)
+
         #app.version_requested.connect(main_window.latest_version_requested)
         #app.account_imported.connect(main_window.import_account_accepted)
         #app.account_changed.connect(main_window.change_account)
@@ -69,12 +75,14 @@ class MainWindowController(AgentController):
         main_window.refresh()
         return main_window
 
-    def change_account(self):
-        if self.account:
-            self.account.contacts_changed.disconnect(self.refresh_contacts)
-        self.account = self.app.current_account
-        self.password_asker.change_account(self.account)
-        self.refresh()
+    def add_to_stack(self, index, widget):
+        """
+        Add a view to the stack
+        :param int index: the index of the page
+        :param PyQt5.QtWidgets.QWidget widget: the view
+        """
+        self.stack.addWidget(widget)
+        self.stacked_widgets[index] = widget
 
     @pyqtSlot(str)
     def display_error(self, error):
@@ -84,11 +92,7 @@ class MainWindowController(AgentController):
 
     @pyqtSlot(int)
     def referential_changed(self, index):
-        if self.account:
-            self.account.set_display_referential(index)
-            if self.community_view:
-                self.community_view.referential_changed()
-                self.homescreen.referential_changed()
+        pass
 
     @pyqtSlot()
     def latest_version_requested(self):
diff --git a/src/sakia/gui/main_window/model.py b/src/sakia/gui/main_window/model.py
index 4febb459242150fbd6c27818f71145ac2d4d5eb9..d504aaa88cc53e5482db5d807dbdf2bc320a4c9a 100644
--- a/src/sakia/gui/main_window/model.py
+++ b/src/sakia/gui/main_window/model.py
@@ -1,9 +1,9 @@
-from sakia.gui.agent.model import AgentModel
+from sakia.gui.component.model import ComponentModel
 
 
-class MainWindowModel(AgentModel):
+class MainWindowModel(ComponentModel):
     """
-    The model of Navigation agent
+    The model of Navigation component
     """
 
     def __init__(self, parent, app):
diff --git a/src/sakia/gui/main_window/view.py b/src/sakia/gui/main_window/view.py
index 784bc7ddeb257be8d18997ff08728bf027998cea..2cd838a2ef6982eaa3995d8ea2cbdc2ada0b9446 100644
--- a/src/sakia/gui/main_window/view.py
+++ b/src/sakia/gui/main_window/view.py
@@ -4,7 +4,7 @@ from .mainwindow_uic import Ui_MainWindow
 
 class MainWindowView(QMainWindow, Ui_MainWindow):
     """
-    The model of Navigation agent
+    The model of Navigation component
     """
 
     def __init__(self, parent):
diff --git a/src/sakia/gui/navigation/controller.py b/src/sakia/gui/navigation/controller.py
index 9da1479de45e366444b97383dac75a013e2131f1..ef7f5b554e9d25b95f84e0a773a8cdad5e430de0 100644
--- a/src/sakia/gui/navigation/controller.py
+++ b/src/sakia/gui/navigation/controller.py
@@ -1,28 +1,34 @@
-from PyQt5.QtWidgets import QTreeView
 from .model import NavigationModel
-from ..agent.controller import AgentController
+from ..component.controller import ComponentController
 from .view import NavigationView
+from ..txhistory.controller import TxHistoryController
+from ..homescreen.controller import HomeScreenController
 
 
-class NavigationController(AgentController):
+class NavigationController(ComponentController):
     """
     The navigation panel
     """
 
     def __init__(self, parent, view, model):
         """
-        Constructor of the navigation agent
+        Constructor of the navigation component
 
-        :param PyQt5.QtWidgets.QTreeView view: the presentation
-        :param sakia.core.gui.navigation.model.NavigationModel model: the model
+        :param sakia.gui.navigation.view view: the view
+        :param sakia.gui.navigation.model.NavigationModel model: the model
         """
         super().__init__(parent, view, model)
-        self.view.setModel(model.tree())
+        self.components = {
+            'TxHistory': TxHistoryController,
+            'HomeScreen': HomeScreenController,
+            'Network': TxHistoryController,
+            'Identities': TxHistoryController
+        }
 
     @classmethod
     def create(cls, parent, app):
         """
-        Instanciate a navigation agent
+        Instanciate a navigation component
         :param sakia.gui.agent.controller.AgentController parent:
         :return: a new Navigation controller
         :rtype: NavigationController
@@ -31,5 +37,24 @@ class NavigationController(AgentController):
         model = NavigationModel(None, app)
         navigation = cls(parent, view, model)
         model.setParent(navigation)
+        navigation.init_navigation()
         return navigation
 
+    def init_navigation(self):
+        def parse_node(node_data):
+            if 'component' in node_data['node']:
+                component_class = self.components[node_data['node']['component']]
+                component = component_class.create(self, self.model.app, **node_data['node'])
+                widget = self.view.add_widget(component.view)
+                node_data['node']['widget'] = widget
+            if 'children' in node_data:
+                for child in node_data['children']:
+                    parse_node(child)
+            return node
+        self.model.init_navigation_data()
+
+        for node in self.model.navigation:
+            parse_node(node)
+
+        self.view.set_model(self.model)
+
diff --git a/src/sakia/gui/navigation/model.py b/src/sakia/gui/navigation/model.py
index e1c5ab12c963d0b6dc89498eef14dec75e2f8480..ea51af900d256e3efc8a6b528b923a2c0cd4864f 100644
--- a/src/sakia/gui/navigation/model.py
+++ b/src/sakia/gui/navigation/model.py
@@ -1,43 +1,67 @@
-from ..agent.model import AgentModel
+from ..component.model import ComponentModel
 from sakia.models.generic_tree import GenericTreeModel
+from PyQt5.QtCore import pyqtSignal
 
 
-class NavigationModel(AgentModel):
+class NavigationModel(ComponentModel):
     """
-    The model of Navigation agent
+    The model of Navigation component
     """
+    navigation_changed = pyqtSignal(GenericTreeModel)
+
     def __init__(self, parent, app):
+        """
+
+        :param sakia.gui.component.controller.ComponentController parent:
+        :param sakia.core.app.Application app:
+        """
         super().__init__(parent)
         self.app = app
+        self.navigation = {}
 
-    def tree(self):
-        navigation = [{'node': {
-                            'title': self.app.current_account.name
-                        },
-                        'children': []
-                        }
-                    ]
+    def init_navigation_data(self):
+        self.navigation = [
+            {
+                'node': {
+                    'title': self.app.current_account.name,
+                    'component': "HomeScreen"
+                },
+                'children': []
+            }
+        ]
         for c in self.app.current_account.communities:
-            navigation[0]['children'].append({
+            self.navigation[0]['children'].append({
                 'node': {
-                    'title': c.currency
+                    'title': c.currency,
                 },
                 'children': [
                     {
                         'node': {
-                            'title': self.tr('Transfers')
+                            'title': self.tr('Transfers'),
+                            'component': "TxHistory",
+                            'community': c,
+                            'account': self.app.current_account
                         }
                     },
                     {
                         'node': {
-                            'title': self.tr('Network')
+                            'title': self.tr('Network'),
+                            'component': "Network",
+                            'community': c,
+                            'account': self.app.current_account
                         }
                     },
                     {
                         'node': {
-                            'title': self.tr('Network')
+                            'title': self.tr('Identities'),
+                            'component': "Identities",
+                            'community': c,
+                            'account': self.app.current_account
                         }
                     }
                 ]
             })
-        return GenericTreeModel.create("Navigation", navigation)
+        return self.navigation
+
+    def generic_tree(self):
+        return GenericTreeModel.create("Navigation", self.navigation)
diff --git a/src/sakia/gui/navigation/navigation.ui b/src/sakia/gui/navigation/navigation.ui
new file mode 100644
index 0000000000000000000000000000000000000000..0da57f788436ddbfe80153f08eda624ea2ad030f
--- /dev/null
+++ b/src/sakia/gui/navigation/navigation.ui
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Navigation</class>
+ <widget class="QFrame" name="Navigation">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>685</width>
+    <height>477</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Frame</string>
+  </property>
+  <property name="frameShape">
+   <enum>QFrame::StyledPanel</enum>
+  </property>
+  <property name="frameShadow">
+   <enum>QFrame::Raised</enum>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <item>
+    <widget class="QTreeView" name="tree_view">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Maximum" vsizetype="Expanding">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QStackedWidget" name="stacked_widget">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/sakia/gui/navigation/view.py b/src/sakia/gui/navigation/view.py
index eb1dd54783ecb44007f098ae73695dccbbe8c26f..63c01cf5c90566fa145f5379810df3eebebb4d08 100644
--- a/src/sakia/gui/navigation/view.py
+++ b/src/sakia/gui/navigation/view.py
@@ -1,11 +1,42 @@
-from PyQt5.QtWidgets import QTreeView, QSizePolicy
+from PyQt5.QtWidgets import QFrame, QSizePolicy
+from PyQt5.QtCore import QModelIndex
+from .navigation_uic import Ui_Navigation
+from ...models.generic_tree import GenericTreeModel
 
 
-class NavigationView(QTreeView):
+class NavigationView(QFrame, Ui_Navigation):
     """
     The view of navigation panel
     """
 
     def __init__(self, parent):
         super().__init__(parent)
-        self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding)
\ No newline at end of file
+        self.setupUi(self)
+        self.tree_view.clicked.connect(self.handle_click)
+
+    def set_model(self, model):
+        """
+        Change the navigation pane
+        :param sakia.gui.navigation.model.NavigationModel
+        """
+        self.tree_view.setModel(model.generic_tree())
+
+    def add_widget(self, widget):
+        """
+        Add a widget to the stacked_widget
+        :param PyQt5.QtWidgets.QWidget widget: the new widget
+        """
+        self.stacked_widget.addWidget(widget)
+        return widget
+
+    def handle_click(self, index):
+        """
+        Click on the navigation pane
+        :param PyQt5.QtCore.QModelIndex index: the index
+        :return:
+        """
+        if index.isValid():
+            raw_data = self.tree_view.model().data(index, GenericTreeModel.ROLE_RAW_DATA)
+            widget = raw_data['widget']
+            if self.stacked_widget.indexOf(widget):
+                self.stacked_widget.setCurrentWidget(widget)
\ No newline at end of file
diff --git a/src/sakia/gui/status_bar/controller.py b/src/sakia/gui/status_bar/controller.py
index 9cf519ccf500f711e0ab6ec578a029a8765a8643..2791714d9970226d74f5de7e55a780201b996bea 100644
--- a/src/sakia/gui/status_bar/controller.py
+++ b/src/sakia/gui/status_bar/controller.py
@@ -1,18 +1,18 @@
 from PyQt5.QtCore import QLocale, pyqtSlot, QDateTime, QTimer
-from ..agent.controller import AgentController
+from ..component.controller import ComponentController
 from .model import StatusBarModel
 from .view import StatusBarView
 import logging
 
 
-class StatusBarController(AgentController):
+class StatusBarController(ComponentController):
     """
     The navigation panel
     """
 
     def __init__(self, parent, view, model):
         """
-        Constructor of the navigation agent
+        Constructor of the navigation component
 
         :param sakia.gui.status_bar.view.StatusBarView view: the presentation
         :param sakia.core.status_bar.model.StatusBarModel model: the model
@@ -24,7 +24,7 @@ class StatusBarController(AgentController):
     @classmethod
     def create(cls, parent, app):
         """
-        Instanciate a navigation agent
+        Instanciate a navigation component
         :param sakia.gui.main_window.controller.MainWindowController parent:
         :return: a new Navigation controller
         :rtype: NavigationController
diff --git a/src/sakia/gui/status_bar/model.py b/src/sakia/gui/status_bar/model.py
index f3865bbd42afbd356e270af7702d3a9d99f2e79b..cd3649cac7296445064e52a4398c7f989b895e7f 100644
--- a/src/sakia/gui/status_bar/model.py
+++ b/src/sakia/gui/status_bar/model.py
@@ -1,16 +1,21 @@
-from sakia.gui.agent.model import AgentModel
+from sakia.gui.component.model import ComponentModel
 from sakia.core.money import Referentials
 import logging
 
-class StatusBarModel(AgentModel):
+
+class StatusBarModel(ComponentModel):
     """
-    The model of Navigation agent
+    The model of Navigation component
     """
 
     def __init__(self, parent, app):
         super().__init__(parent)
         self.app = app
 
+    @property
+    def account(self):
+        return self.app.current_account
+
     def referentials(self):
         return Referentials
 
diff --git a/src/sakia/gui/status_bar/view.py b/src/sakia/gui/status_bar/view.py
index 5f631e69bdcdaf93df00beb6eca243608e9176ce..e5dbdc5b45151234730e58b60cc46928b35a74e6 100644
--- a/src/sakia/gui/status_bar/view.py
+++ b/src/sakia/gui/status_bar/view.py
@@ -5,7 +5,7 @@ from PyQt5.QtCore import Qt
 
 class StatusBarView(QStatusBar):
     """
-    The model of Navigation agent
+    The model of Navigation component
     """
 
     def __init__(self, parent):
diff --git a/src/sakia/gui/toolbar/controller.py b/src/sakia/gui/toolbar/controller.py
index 6b538c7d4edb189566a12150461c032400f50b42..6edb59a906caf6e59b7069ca404f0dcd99877641 100644
--- a/src/sakia/gui/toolbar/controller.py
+++ b/src/sakia/gui/toolbar/controller.py
@@ -1,6 +1,6 @@
 from PyQt5.QtWidgets import QDialog, QMessageBox
 from PyQt5.QtCore import QT_TRANSLATE_NOOP, Qt
-from ..agent.controller import AgentController
+from ..component.controller import ComponentController
 from .model import ToolbarModel
 from .view import ToolbarView
 from ...tools.decorators import asyncify, once_at_a_time, cancel_once_task
@@ -9,7 +9,7 @@ from ..widgets import toast
 import logging
 
 
-class ToolbarController(AgentController):
+class ToolbarController(ComponentController):
     """
     The navigation panel
     """
@@ -32,7 +32,7 @@ class ToolbarController(AgentController):
     @classmethod
     def create(cls, parent, password_asker):
         """
-        Instanciate a navigation agent
+        Instanciate a navigation component
         :param sakia.gui.agent.controller.AgentController parent:
         :return: a new Toolbar controller
         :rtype: ToolbarController
diff --git a/src/sakia/gui/toolbar/model.py b/src/sakia/gui/toolbar/model.py
index 5e6250e96c61d883494e47c8b6f0daffbd69e666..6d8d4ce41e719462c5cc561d52632b3ca093fdd4 100644
--- a/src/sakia/gui/toolbar/model.py
+++ b/src/sakia/gui/toolbar/model.py
@@ -1,9 +1,9 @@
-from sakia.gui.agent.model import AgentModel
+from sakia.gui.component.model import ComponentModel
 
 
-class ToolbarModel(AgentModel):
+class ToolbarModel(ComponentModel):
     """
-    The model of Navigation agent
+    The model of Navigation component
     """
 
     def __init__(self, parent):
diff --git a/src/sakia/gui/toolbar/toolbar.ui b/src/sakia/gui/toolbar/toolbar.ui
index b90226b937cf566c22bb009f306d835036056ef5..63f494287f7f137dc243514a1975b9520cb4d43c 100644
--- a/src/sakia/gui/toolbar/toolbar.ui
+++ b/src/sakia/gui/toolbar/toolbar.ui
@@ -6,10 +6,16 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>690</width>
-    <height>240</height>
+    <width>666</width>
+    <height>237</height>
    </rect>
   </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
   <property name="windowTitle">
    <string>Frame</string>
   </property>
@@ -26,7 +32,7 @@
       <string>Send money</string>
      </property>
      <property name="icon">
-      <iconset resource="../icons/icons.qrc">
+      <iconset resource="../../../../res/icons/icons.qrc">
        <normaloff>:/icons/payment_icon</normaloff>:/icons/payment_icon</iconset>
      </property>
      <property name="iconSize">
@@ -43,7 +49,7 @@
       <string>Certification</string>
      </property>
      <property name="icon">
-      <iconset resource="../icons/icons.qrc">
+      <iconset resource="../../../../res/icons/icons.qrc">
        <normaloff>:/icons/certification_icon</normaloff>:/icons/certification_icon</iconset>
      </property>
      <property name="iconSize">
@@ -60,7 +66,7 @@
       <string>Renew membership</string>
      </property>
      <property name="icon">
-      <iconset resource="../icons/icons.qrc">
+      <iconset resource="../../../../res/icons/icons.qrc">
        <normaloff>:/icons/renew_membership</normaloff>:/icons/renew_membership</iconset>
      </property>
      <property name="iconSize">
@@ -78,7 +84,7 @@
      </property>
      <property name="sizeHint" stdset="0">
       <size>
-       <width>169</width>
+       <width>1000</width>
        <height>221</height>
       </size>
      </property>
@@ -90,7 +96,7 @@
       <string/>
      </property>
      <property name="icon">
-      <iconset resource="../icons/icons.qrc">
+      <iconset resource="../../../../res/icons/icons.qrc">
        <normaloff>:/icons/menu_icon</normaloff>:/icons/menu_icon</iconset>
      </property>
      <property name="iconSize">
@@ -113,7 +119,7 @@
   </layout>
  </widget>
  <resources>
-  <include location="../icons/icons.qrc"/>
+  <include location="../../../../res/icons/icons.qrc"/>
  </resources>
  <connections/>
 </ui>
diff --git a/src/sakia/gui/toolbar/view.py b/src/sakia/gui/toolbar/view.py
index df1dfd1f487deb17d957c8b55465bee7154e8f0b..c53cadb2185b8509ad4dd5247b3badd8ccc50ee2 100644
--- a/src/sakia/gui/toolbar/view.py
+++ b/src/sakia/gui/toolbar/view.py
@@ -6,7 +6,7 @@ from .toolbar_uic import Ui_SakiaToolbar
 
 class ToolbarView(QFrame, Ui_SakiaToolbar):
     """
-    The model of Navigation agent
+    The model of Navigation component
     """
     _action_showinfo_text = QT_TRANSLATE_NOOP("ToolbarView", "Show informations")
     _action_explore_text = QT_TRANSLATE_NOOP("ToolbarView", "Explore the Web of Trust")
diff --git a/src/sakia/gui/transactions_tab.py b/src/sakia/gui/transactions_tab.py
deleted file mode 100644
index 656b855b7658946c130d81882301e1c48b522144..0000000000000000000000000000000000000000
--- a/src/sakia/gui/transactions_tab.py
+++ /dev/null
@@ -1,222 +0,0 @@
-import logging
-
-from duniterpy.api import errors
-from PyQt5.QtWidgets import QWidget, QAbstractItemView, QHeaderView
-from PyQt5.QtCore import Qt, QObject, QDateTime, QTime, QModelIndex, pyqtSignal, pyqtSlot, QEvent
-from PyQt5.QtGui import QCursor
-
-from ..presentation.transactions_tab_uic import Ui_transactionsTabWidget
-from ..models.txhistory import HistoryTableModel, TxFilterProxyModel
-from ..tools.exceptions import NoPeerAvailable
-from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
-from .widgets.context_menu import ContextMenu
-from .widgets import toast
-
-
-class TransactionsTabWidget(QObject):
-    """
-    classdocs
-    """
-    view_in_wot = pyqtSignal(object)
-
-    def __init__(self, app, account=None, community=None, password_asker=None,
-                 widget=QWidget, view=Ui_transactionsTabWidget):
-        """
-        Init
-
-        :param sakia.core.app.Application app: Application instance
-        :param sakia.core.Account account: The account displayed in the widget
-        :param sakia.core.Community community: The community displayed in the widget
-        :param sakia.gui.Password_Asker: password_asker: The widget to ask for passwords
-        :param class widget: The class of the PyQt5 widget used for this tab
-        :param class view: The class of the UI View for this tab
-        """
-
-        super().__init__()
-        self.widget = widget()
-        self.ui = view()
-        self.ui.setupUi(self.widget)
-        self.app = app
-        self.account = account
-        self.community = community
-        self.password_asker = password_asker
-        self.ui.busy_balance.hide()
-
-        ts_from = self.ui.date_from.dateTime().toTime_t()
-        ts_to = self.ui.date_to.dateTime().toTime_t()
-        model = HistoryTableModel(self.app, self.account, self.community)
-        proxy = TxFilterProxyModel(ts_from, ts_to)
-        proxy.setSourceModel(model)
-        proxy.setDynamicSortFilter(True)
-        proxy.setSortRole(Qt.DisplayRole)
-
-        self.ui.table_history.setModel(proxy)
-        self.ui.table_history.setSelectionBehavior(QAbstractItemView.SelectRows)
-        self.ui.table_history.setSortingEnabled(True)
-        self.ui.table_history.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
-        self.ui.table_history.resizeColumnsToContents()
-
-        self.ui.table_history.customContextMenuRequested['QPoint'].connect(self.history_context_menu)
-        self.ui.date_from.dateChanged['QDate'].connect(self.dates_changed)
-        self.ui.date_to.dateChanged['QDate'].connect(self.dates_changed)
-
-        model.modelAboutToBeReset.connect(lambda: self.ui.table_history.setEnabled(False))
-        model.modelReset.connect(lambda: self.ui.table_history.setEnabled(True))
-        self.app.refresh_transfers.connect(self.refresh)
-
-        self.ui.progressbar.hide()
-        self.refresh()
-
-    def cancel_once_tasks(self):
-        cancel_once_task(self, self.refresh_minimum_maximum)
-        cancel_once_task(self, self.refresh_balance)
-        cancel_once_task(self, self.history_context_menu)
-
-    def change_account(self, account, password_asker):
-        self.cancel_once_tasks()
-        self.account = account
-        self.password_asker = password_asker
-        self.ui.table_history.model().sourceModel().change_account(account)
-        if account:
-            self.connect_progress()
-
-    def change_community(self, community):
-        self.cancel_once_tasks()
-        self.community = community
-        self.ui.progressbar.hide()
-        self.ui.table_history.model().sourceModel().change_community(self.community)
-        self.refresh()
-
-    @once_at_a_time
-    @asyncify
-    async def refresh_minimum_maximum(self):
-        try:
-            block = await self.community.get_block(1)
-            minimum_datetime = QDateTime()
-            minimum_datetime.setTime_t(block['medianTime'])
-            minimum_datetime.setTime(QTime(0, 0))
-
-            self.ui.date_from.setMinimumDateTime(minimum_datetime)
-            self.ui.date_from.setDateTime(minimum_datetime)
-            self.ui.date_from.setMaximumDateTime(QDateTime().currentDateTime())
-
-            self.ui.date_to.setMinimumDateTime(minimum_datetime)
-            tomorrow_datetime = QDateTime().currentDateTime().addDays(1)
-            self.ui.date_to.setDateTime(tomorrow_datetime)
-            self.ui.date_to.setMaximumDateTime(tomorrow_datetime)
-        except NoPeerAvailable as e:
-            logging.debug(str(e))
-        except errors.DuniterError as e:
-            logging.debug(str(e))
-
-    def refresh(self):
-        if self.community:
-            refresh_task = self.ui.table_history.model().sourceModel().refresh_transfers()
-            refresh_task.add_done_callback(lambda fut: self.ui.table_history.resizeColumnsToContents())
-            self.refresh_minimum_maximum()
-            self.refresh_balance()
-
-    def connect_progress(self):
-        def progressing(community, value, maximum):
-            if community == self.community:
-                self.ui.progressbar.show()
-                self.ui.progressbar.setValue(value)
-                self.ui.progressbar.setMaximum(maximum)
-        self.account.loading_progressed.connect(progressing)
-        self.account.loading_finished.connect(self.stop_progress)
-
-    def stop_progress(self, community, received_list):
-        if community == self.community:
-            self.ui.progressbar.hide()
-            self.ui.table_history.model().sourceModel().refresh_transfers()
-            self.ui.table_history.resizeColumnsToContents()
-            self.notification_reception(received_list)
-
-    @asyncify
-    async def notification_reception(self, received_list):
-        if len(received_list) > 0:
-            amount = 0
-            for r in received_list:
-                amount += r.metadata['amount']
-            localized_amount = await self.app.current_account.current_ref.instance(amount, self.community, self.app)\
-                                            .localized(units=True,
-                                    international_system=self.app.preferences['international_system_of_units'])
-            text = self.tr("Received {amount} from {number} transfers").format(amount=localized_amount ,
-                                                                            number=len(received_list))
-            if self.app.preferences['notifications']:
-                toast.display(self.tr("New transactions received"), text)
-
-    @once_at_a_time
-    @asyncify
-    async def refresh_balance(self):
-        self.ui.busy_balance.show()
-        try:
-            amount = await self.app.current_account.amount(self.community)
-            localized_amount = await self.app.current_account.current_ref.instance(amount, self.community,
-                                                                           self.app).localized(units=True,
-                                        international_system=self.app.preferences['international_system_of_units'])
-
-            # set infos in label
-            self.ui.label_balance.setText(
-                self.tr("{:}")
-                .format(
-                    localized_amount
-                )
-            )
-        except NoPeerAvailable as e:
-            logging.debug(str(e))
-        except errors.DuniterError as e:
-            logging.debug(str(e))
-        self.ui.busy_balance.hide()
-
-    @once_at_a_time
-    @asyncify
-    async def history_context_menu(self, point):
-        index = self.ui.table_history.indexAt(point)
-        model = self.ui.table_history.model()
-        if index.isValid() and index.row() < model.rowCount(QModelIndex()):
-            source_index = model.mapToSource(index)
-
-            pubkey_col = model.sourceModel().columns_types.index('pubkey')
-            pubkey_index = model.sourceModel().index(source_index.row(),
-                                                    pubkey_col)
-            pubkey = model.sourceModel().data(pubkey_index, Qt.DisplayRole)
-
-            identity = await self.app.identities_registry.future_find(pubkey, self.community)
-
-            transfer = model.sourceModel().transfers()[source_index.row()]
-            menu = ContextMenu.from_data(self.widget, self.app, self.account, self.community, self.password_asker,
-                                         (identity, transfer))
-            menu.view_identity_in_wot.connect(self.view_in_wot)
-
-            # Show the context menu.
-            menu.qmenu.popup(QCursor.pos())
-
-    def dates_changed(self):
-        logging.debug("Changed dates")
-        if self.ui.table_history.model():
-            qdate_from = self.ui.date_from
-            qdate_from.setTime(QTime(0, 0, 0))
-            qdate_to = self.ui.date_to
-            qdate_to.setTime(QTime(0, 0, 0))
-            ts_from = qdate_from.dateTime().toTime_t()
-            ts_to = qdate_to.dateTime().toTime_t()
-
-            self.ui.table_history.model().set_period(ts_from, ts_to)
-
-            self.refresh_balance()
-
-    def resizeEvent(self, event):
-        self.ui.busy_balance.resize(event.size())
-        super().resizeEvent(event)
-
-    def changeEvent(self, event):
-        """
-        Intercepte LanguageChange event to translate UI
-        :param QEvent QEvent: Event
-        :return:
-        """
-        if event.type() == QEvent.LanguageChange:
-            self.retranslateUi(self)
-            self.refresh()
-        return super(TransactionsTabWidget, self).changeEvent(event)
diff --git a/src/sakia/gui/txhistory/__init__.py b/src/sakia/gui/txhistory/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/sakia/gui/txhistory/controller.py b/src/sakia/gui/txhistory/controller.py
new file mode 100644
index 0000000000000000000000000000000000000000..b6e3549b4bb98b23abb41a2e3aade5d8f9268a8d
--- /dev/null
+++ b/src/sakia/gui/txhistory/controller.py
@@ -0,0 +1,165 @@
+import logging
+
+from duniterpy.api import errors
+from PyQt5.QtCore import QDateTime, QTime, pyqtSignal, QEvent
+
+from ..component.controller import ComponentController
+from .view import TxHistoryView
+from .model import TxHistoryModel
+from ...tools.exceptions import NoPeerAvailable
+from ...tools.decorators import asyncify, once_at_a_time, cancel_once_task
+from ..widgets import toast
+
+
+class TxHistoryController(ComponentController):
+    """
+    Transfer history component controller
+    """
+    view_in_wot = pyqtSignal(object)
+
+    def __init__(self, parent, view, model, password_asker=None):
+        """
+        Init
+        :param sakia.gui.txhistory.view.TxHistoryView view:
+        :param sakia.gui.txhistory.model.TxHistoryModel model:
+        :param password_asker:
+        """
+
+        super().__init__(parent, view, model)
+        self.password_asker = password_asker
+
+        ts_from = self.view.date_from.dateTime().toTime_t()
+        ts_to = self.view.date_to.dateTime().toTime_t()
+        model = self.model.history_table_model(ts_from, ts_to)
+        self.view.table_history.setModel(model)
+
+        self.view.date_from.dateChanged['QDate'].connect(self.dates_changed)
+        self.view.date_to.dateChanged['QDate'].connect(self.dates_changed)
+
+        model.modelAboutToBeReset.connect(lambda: self.view.table_history.setEnabled(False))
+        model.modelReset.connect(lambda: self.view.table_history.setEnabled(True))
+        #self.app.refresh_transfers.connect(self.refresh)
+
+        self.view.progressbar.hide()
+        self.refresh()
+
+    @classmethod
+    def create(cls, parent, app, **kwargs):
+        account = kwargs['account']
+        community = kwargs['community']
+
+        view = TxHistoryView(parent.view)
+        model = TxHistoryModel(None, app, account, community)
+        txhistory = cls(parent, view, model)
+        model.setParent(txhistory)
+        return txhistory
+
+    @once_at_a_time
+    @asyncify
+    async def refresh_minimum_maximum(self):
+        try:
+            block = await self.community.get_block(1)
+            minimum_datetime = QDateTime()
+            minimum_datetime.setTime_t(block['medianTime'])
+            minimum_datetime.setTime(QTime(0, 0))
+
+            self.view.date_from.setMinimumDateTime(minimum_datetime)
+            self.view.date_from.setDateTime(minimum_datetime)
+            self.view.date_from.setMaximumDateTime(QDateTime().currentDateTime())
+
+            self.view.date_to.setMinimumDateTime(minimum_datetime)
+            tomorrow_datetime = QDateTime().currentDateTime().addDays(1)
+            self.view.date_to.setDateTime(tomorrow_datetime)
+            self.view.date_to.setMaximumDateTime(tomorrow_datetime)
+        except NoPeerAvailable as e:
+            logging.debug(str(e))
+        except errors.DuniterError as e:
+            logging.debug(str(e))
+
+    def refresh(self):
+        refresh_task = self.view.table_history.model().sourceModel().refresh_transfers()
+        refresh_task.add_done_callback(lambda fut: self.view.table_history.resizeColumnsToContents())
+        self.refresh_minimum_maximum()
+        self.refresh_balance()
+
+    def connect_progress(self):
+        def progressing(community, value, maximum):
+            if community == self.community:
+                self.view.progressbar.show()
+                self.view.progressbar.setValue(value)
+                self.view.progressbar.setMaximum(maximum)
+        self.account.loading_progressed.connect(progressing)
+        self.account.loading_finished.connect(self.stop_progress)
+
+    def stop_progress(self, community, received_list):
+        if community == self.community:
+            self.view.progressbar.hide()
+            self.view.table_history.model().sourceModel().refresh_transfers()
+            self.view.table_history.resizeColumnsToContents()
+            self.notification_reception(received_list)
+
+    @asyncify
+    async def notification_reception(self, received_list):
+        if len(received_list) > 0:
+            amount = 0
+            for r in received_list:
+                amount += r.metadata['amount']
+            localized_amount = await self.app.current_account.current_ref.instance(amount, self.community, self.app)\
+                                            .localized(units=True,
+                                    international_system=self.app.preferences['international_system_of_units'])
+            text = self.tr("Received {amount} from {number} transfers").format(amount=localized_amount ,
+                                                                            number=len(received_list))
+            if self.app.preferences['notifications']:
+                toast.display(self.tr("New transactions received"), text)
+
+    @once_at_a_time
+    @asyncify
+    async def refresh_balance(self):
+        self.view.busy_balance.show()
+        try:
+            amount = await self.app.current_account.amount(self.community)
+            localized_amount = await self.app.current_account.current_ref.instance(amount, self.community,
+                                                                           self.app).localized(units=True,
+                                        international_system=self.app.preferences['international_system_of_units'])
+
+            # set infos in label
+            self.view.label_balance.setText(
+                self.tr("{:}")
+                .format(
+                    localized_amount
+                )
+            )
+        except NoPeerAvailable as e:
+            logging.debug(str(e))
+        except errors.DuniterError as e:
+            logging.debug(str(e))
+        self.view.busy_balance.hide()
+
+    def dates_changed(self):
+        logging.debug("Changed dates")
+        if self.view.table_history.model():
+            qdate_from = self.view.date_from
+            qdate_from.setTime(QTime(0, 0, 0))
+            qdate_to = self.view.date_to
+            qdate_to.setTime(QTime(0, 0, 0))
+            ts_from = qdate_from.dateTime().toTime_t()
+            ts_to = qdate_to.dateTime().toTime_t()
+
+            self.view.table_history.model().set_period(ts_from, ts_to)
+
+            self.refresh_balance()
+
+    def resizeEvent(self, event):
+        self.view.busy_balance.resize(event.size())
+        super().resizeEvent(event)
+
+    def changeEvent(self, event):
+        """
+        Intercepte LanguageChange event to translate UI
+        :param QEvent QEvent: Event
+        :return:
+        """
+        if event.type() == QEvent.LanguageChange:
+            self.retranslateUi(self)
+            self.refresh()
+        return super(TxHistoryController).changeEvent(event)
diff --git a/src/sakia/gui/txhistory/model.py b/src/sakia/gui/txhistory/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..51fc48d23fc74101017758a7b355c6caad02684e
--- /dev/null
+++ b/src/sakia/gui/txhistory/model.py
@@ -0,0 +1,29 @@
+from sakia.gui.component.model import ComponentModel
+from .table_model import HistoryTableModel, TxFilterProxyModel
+from PyQt5.QtCore import Qt
+
+
+class TxHistoryModel(ComponentModel):
+    """
+    The model of Navigation component
+    """
+
+    def __init__(self, parent, app, account, community):
+        super().__init__(parent)
+        self.app = app
+        self.account = account
+        self.community = community
+
+    def history_table_model(self, ts_from, ts_to):
+        """
+        Generates a history table model
+        :param int ts_from: date from where to filter tx
+        :param int ts_to: date to where to filter tx
+        :return:
+        """
+        model = HistoryTableModel(self.app, self.account, self.community)
+        proxy = TxFilterProxyModel(ts_from, ts_to)
+        proxy.setSourceModel(model)
+        proxy.setDynamicSortFilter(True)
+        proxy.setSortRole(Qt.DisplayRole)
+        return proxy
\ No newline at end of file
diff --git a/src/sakia/models/txhistory.py b/src/sakia/gui/txhistory/table_model.py
similarity index 98%
rename from src/sakia/models/txhistory.py
rename to src/sakia/gui/txhistory/table_model.py
index 5ea783e80ea738d7c5069a6faefd41b0b63ff15b..a0cb25ce0182a950bdbde505582fec2f4c953a7b 100644
--- a/src/sakia/models/txhistory.py
+++ b/src/sakia/gui/txhistory/table_model.py
@@ -8,10 +8,10 @@ import datetime
 import logging
 import asyncio
 import math
-from ..core.transfer import Transfer, TransferState
-from ..core.net.network import MAX_CONFIRMATIONS
-from ..tools.exceptions import NoPeerAvailable
-from ..tools.decorators import asyncify, once_at_a_time, cancel_once_task
+from ...core.transfer import Transfer, TransferState
+from ...core.net.network import MAX_CONFIRMATIONS
+from ...tools.exceptions import NoPeerAvailable
+from ...tools.decorators import asyncify, once_at_a_time, cancel_once_task
 from PyQt5.QtCore import QAbstractTableModel, Qt, QVariant, QSortFilterProxyModel, \
     QDateTime, QLocale, QModelIndex
 
diff --git a/res/ui/transactions_tab.ui b/src/sakia/gui/txhistory/txhistory.ui
similarity index 95%
rename from res/ui/transactions_tab.ui
rename to src/sakia/gui/txhistory/txhistory.ui
index 737ecfa4aa93d0e094da40eed917ae4b71e16457..8aa79961a224b47b29042bc02e8f62d752040095 100644
--- a/res/ui/transactions_tab.ui
+++ b/src/sakia/gui/txhistory/txhistory.ui
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <class>transactionsTabWidget</class>
- <widget class="QWidget" name="transactionsTabWidget">
+ <class>TxHistoryWidget</class>
+ <widget class="QWidget" name="TxHistoryWidget">
   <property name="geometry">
    <rect>
     <x>0</x>
@@ -117,7 +117,7 @@
   </customwidget>
  </customwidgets>
  <resources>
-  <include location="../icons/icons.qrc"/>
+  <include location="../../../../res/icons/icons.qrc"/>
  </resources>
  <connections/>
 </ui>
diff --git a/src/sakia/gui/txhistory/view.py b/src/sakia/gui/txhistory/view.py
new file mode 100644
index 0000000000000000000000000000000000000000..5466d544e2ae99dfc4d0a6188d13c3a50af44148
--- /dev/null
+++ b/src/sakia/gui/txhistory/view.py
@@ -0,0 +1,46 @@
+from PyQt5.QtWidgets import QWidget, QAbstractItemView, QHeaderView
+from PyQt5.QtGui import QCursor
+from PyQt5.QtCore import Qt, QModelIndex
+from .txhistory_uic import Ui_TxHistoryWidget
+from ...tools.decorators import asyncify, once_at_a_time
+from ..widgets.context_menu import ContextMenu
+
+
+class TxHistoryView(QWidget, Ui_TxHistoryWidget):
+    """
+    The model of Navigation component
+    """
+
+    def __init__(self, parent):
+        super().__init__(parent)
+        self.setupUi(self)
+        self.busy_balance.hide()
+
+        self.table_history.setSelectionBehavior(QAbstractItemView.SelectRows)
+        self.table_history.setSortingEnabled(True)
+        self.table_history.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
+        self.table_history.resizeColumnsToContents()
+        self.table_history.customContextMenuRequested['QPoint'].connect(self.history_context_menu)
+
+    @once_at_a_time
+    @asyncify
+    async def history_context_menu(self, point):
+        index = self.table_history.indexAt(point)
+        model = self.table_history.model()
+        if index.isValid() and index.row() < model.rowCount(QModelIndex()):
+            source_index = model.mapToSource(index)
+
+            pubkey_col = model.sourceModel().columns_types.index('pubkey')
+            pubkey_index = model.sourceModel().index(source_index.row(),
+                                                     pubkey_col)
+            pubkey = model.sourceModel().data(pubkey_index, Qt.DisplayRole)
+
+            identity = await self.app.identities_registry.future_find(pubkey, self.community)
+
+            transfer = model.sourceModel().transfers()[source_index.row()]
+            menu = ContextMenu.from_data(self, self.app, self.account, self.community, self.password_asker,
+                                         (identity, transfer))
+            menu.view_identity_in_wot.connect(self.view_in_wot)
+
+            # Show the context menu.
+            menu.qmenu.popup(QCursor.pos())
diff --git a/src/sakia/models/generic_tree.py b/src/sakia/models/generic_tree.py
index 4703d03b9ff3ddeaa8acc55c06da51fd6e07b95d..c7b49ce05813f4e783fc17420cb69752cce2a740 100644
--- a/src/sakia/models/generic_tree.py
+++ b/src/sakia/models/generic_tree.py
@@ -38,6 +38,9 @@ class NodeItem(QAbstractItemModel):
         if role == Qt.DecorationRole and 'icon' in self.node:
             return QIcon(self.node['icon'])
 
+        if role == GenericTreeModel.ROLE_RAW_DATA:
+            return self.node
+
     def row(self):
         if self.parent_item:
             return self.parent_item.row() + self.parent_item.children.index(self)
@@ -59,6 +62,9 @@ class GenericTreeModel(QAbstractItemModel):
 
     """
 
+    ROLE_RAW_DATA = 101
+
+
     def __init__(self, title, root_item):
         """
         Constructor
@@ -95,6 +101,8 @@ class GenericTreeModel(QAbstractItemModel):
 
         if role == Qt.DisplayRole and index.column() == 0:
             return item.data(0, role)
+        elif role == GenericTreeModel.ROLE_RAW_DATA:
+            return item.data(0, role)
 
         return None