diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6d6cf27d83d6350f76c66eb91deca10df08124e7..c0188e6ca06fe92d8fe441765844c29595281728 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -281,6 +281,7 @@ SET( libringclient_LIB_SRCS
   src/private/vcardutils.cpp
   src/private/videorenderermanager.cpp
   src/video/previewmanager.cpp
+  src/private/sortproxies.cpp
 
   #Extension
   src/extensions/presencecollectionextension.cpp
@@ -494,6 +495,7 @@ ENDIF()
 SET(libringclient_PRIVATE_HDRS
    src/private/call_p.h
    src/private/account_p.h
+   src/private/sortproxies.h
    src/private/accountmodel_p.h
    src/private/phonedirectorymodel_p.h
    src/private/instantmessagingmodel_p.h
diff --git a/src/categorizedcontactmodel.cpp b/src/categorizedcontactmodel.cpp
index 4a6f33da13901ff4baf5ddcf70be1257e1af5b09..09e5b55af354d8c7dd4de44faab6cd41c394c329 100644
--- a/src/categorizedcontactmodel.cpp
+++ b/src/categorizedcontactmodel.cpp
@@ -33,6 +33,7 @@
 #include "uri.h"
 #include "mime.h"
 #include "personmodel.h"
+#include "private/sortproxies.h"
 
 class ContactTreeNode;
 
@@ -82,14 +83,16 @@ public:
    QString category(const Person* ct) const;
 
    //Attributes
-   QHash<Person*, time_t>          m_hContactByDate   ;
-   QVector<ContactTreeNode*>       m_lCategoryCounter ;
-   QHash<QString,ContactTreeNode*> m_hCategories      ;
-   int                             m_Role             ;
-   QStringList                     m_lMimes           ;
-   bool                            m_SortAlphabetical ;
-   QString                         m_DefaultCategory  ;
-   bool                            m_UnreachableHidden;
+   QHash<Person*, time_t>               m_hContactByDate   ;
+   QVector<ContactTreeNode*>            m_lCategoryCounter ;
+   QHash<QString,ContactTreeNode*>      m_hCategories      ;
+   int                                  m_Role             ;
+   QStringList                          m_lMimes           ;
+   bool                                 m_SortAlphabetical ;
+   QString                              m_DefaultCategory  ;
+   bool                                 m_UnreachableHidden;
+   SortingCategory::ModelTuple*         m_pSortedProxy     ;
+   CategorizedContactModel::SortedProxy m_pProxies         ;
 
    //Helper
    ContactTreeNode* getContactTopLevelItem(const QString& category);
@@ -185,7 +188,7 @@ void ContactTreeNode::slotContactMethodCountAboutToChange(int count, int oldCoun
 }
 
 CategorizedContactModelPrivate::CategorizedContactModelPrivate(CategorizedContactModel* parent) : QObject(parent), q_ptr(parent),
-m_lCategoryCounter(),m_Role(Qt::DisplayRole),m_SortAlphabetical(true),m_UnreachableHidden(false)
+m_lCategoryCounter(),m_Role(Qt::DisplayRole),m_SortAlphabetical(true),m_UnreachableHidden(false),m_pSortedProxy(nullptr)
 {
 
 }
@@ -595,4 +598,33 @@ void CategorizedContactModelPrivate::reloadTreeVisibility( ContactTreeNode* node
    };
 }
 
+QSortFilterProxyModel* CategorizedContactModel::SortedProxy::model() const
+{
+   if (!CategorizedContactModel::instance()->d_ptr->m_pSortedProxy)
+      CategorizedContactModel::instance()->d_ptr->m_pSortedProxy = SortingCategory::getContactProxy();
+
+   return CategorizedContactModel::instance()->d_ptr->m_pSortedProxy->model;
+}
+
+QAbstractItemModel* CategorizedContactModel::SortedProxy::categoryModel() const
+{
+   if (!CategorizedContactModel::instance()->d_ptr->m_pSortedProxy)
+      CategorizedContactModel::instance()->d_ptr->m_pSortedProxy = SortingCategory::getContactProxy();
+
+   return CategorizedContactModel::instance()->d_ptr->m_pSortedProxy->categories;
+}
+
+QItemSelectionModel* CategorizedContactModel::SortedProxy::categorySelectionModel() const
+{
+   if (!CategorizedContactModel::instance()->d_ptr->m_pSortedProxy)
+      CategorizedContactModel::instance()->d_ptr->m_pSortedProxy = SortingCategory::getContactProxy();
+
+   return CategorizedContactModel::instance()->d_ptr->m_pSortedProxy->selectionModel;
+}
+
+CategorizedContactModel::SortedProxy* CategorizedContactModel::SortedProxy::instance()
+{
+   return &CategorizedContactModel::instance()->d_ptr->m_pProxies;
+}
+
 #include <categorizedcontactmodel.moc>
diff --git a/src/categorizedcontactmodel.h b/src/categorizedcontactmodel.h
index d35baf85f1d605c52cffaa9ae86d1302e31afa44..00a85896ec07b4a6ec76d0df60a472ca47443870 100644
--- a/src/categorizedcontactmodel.h
+++ b/src/categorizedcontactmodel.h
@@ -30,6 +30,8 @@ class ContactTreeNode;
 class TopLevelItem;
 class ContactTreeBinder;
 class CategorizedContactModelPrivate;
+class QSortFilterProxyModel;
+class QItemSelectionModel;
 
 class LIB_EXPORT CategorizedContactModel :  public QAbstractItemModel
 {
@@ -41,7 +43,8 @@ public:
    friend class PersonModel      ;
    friend class ContactTreeNode  ;
    friend class ContactTreeBinder;
-   explicit CategorizedContactModel(int role = Qt::DisplayRole);
+   friend class SortedProxy      ;
+
    virtual ~CategorizedContactModel();
 
    //Setters
@@ -70,10 +73,28 @@ public:
    QString    defaultCategory     () const;
    bool       areUnreachableHidden() const;
 
+   struct SortedProxy {
+      enum class Categories {
+         NAME        ,
+         ORGANIZATION,
+         RECENTLYUSED,
+         GROUP       ,
+         DEPARTMENT  ,
+         COUNT__
+      };
+
+      QSortFilterProxyModel* model                 () const;
+      QAbstractItemModel   * categoryModel         () const;
+      QItemSelectionModel  * categorySelectionModel() const;
+      static CategorizedContactModel::SortedProxy* instance();
+   };
+
    //Singleton
    static CategorizedContactModel* instance();
 
 private:
+   explicit CategorizedContactModel(int role = Qt::DisplayRole);
+
    QScopedPointer<CategorizedContactModelPrivate> d_ptr;
    Q_DECLARE_PRIVATE(CategorizedContactModel)
 };
diff --git a/src/categorizedhistorymodel.cpp b/src/categorizedhistorymodel.cpp
index 0e245d360b574967f9da9d6236b36159a033030b..06c16b7dffca878cab5f51045a2e4853e5ea910d 100644
--- a/src/categorizedhistorymodel.cpp
+++ b/src/categorizedhistorymodel.cpp
@@ -25,6 +25,7 @@
 #include <QCoreApplication>
 
 //Ring lib
+#include "private/sortproxies.h"
 #include "mime.h"
 #include "dbus/callmanager.h"
 #include "dbus/configurationmanager.h"
@@ -76,8 +77,10 @@ public:
    QVector<HistoryTopLevelItem*>       m_lCategoryCounter ;
    QHash<int,HistoryTopLevelItem*>     m_hCategories      ;
    QHash<QString,HistoryTopLevelItem*> m_hCategoryByName  ;
+   SortingCategory::ModelTuple*        m_pSortedProxy     ;
    int                          m_Role             ;
    QStringList                  m_lMimes           ;
+   CategorizedHistoryModel::SortedProxy m_pProxies;
 
 private:
    CategorizedHistoryModel* q_ptr;
@@ -182,7 +185,7 @@ Call* CategorizedHistoryModelPrivate::HistoryItem::call() const
  ****************************************************************************/
 
 CategorizedHistoryModelPrivate::CategorizedHistoryModelPrivate(CategorizedHistoryModel* parent) : QObject(parent), q_ptr(parent),
-m_Role(static_cast<int>(Call::Role::FuzzyDate))
+m_Role(static_cast<int>(Call::Role::FuzzyDate)),m_pSortedProxy(nullptr)
 {
 }
 
@@ -482,6 +485,7 @@ int CategorizedHistoryModel::rowCount( const QModelIndex& parentIdx ) const
             return 0;
       };
    }
+   return 0;
 }
 
 Qt::ItemFlags CategorizedHistoryModel::flags( const QModelIndex& idx ) const
@@ -644,4 +648,33 @@ void CategorizedHistoryModel::setCategoryRole(int role)
    }
 }
 
+QSortFilterProxyModel* CategorizedHistoryModel::SortedProxy::model() const
+{
+   if (!CategorizedHistoryModel::instance()->d_ptr->m_pSortedProxy)
+      CategorizedHistoryModel::instance()->d_ptr->m_pSortedProxy = SortingCategory::getHistoryProxy();
+
+   return CategorizedHistoryModel::instance()->d_ptr->m_pSortedProxy->model;
+}
+
+QAbstractItemModel* CategorizedHistoryModel::SortedProxy::categoryModel() const
+{
+   if (!CategorizedHistoryModel::instance()->d_ptr->m_pSortedProxy)
+      CategorizedHistoryModel::instance()->d_ptr->m_pSortedProxy = SortingCategory::getHistoryProxy();
+
+   return CategorizedHistoryModel::instance()->d_ptr->m_pSortedProxy->categories;
+}
+
+QItemSelectionModel* CategorizedHistoryModel::SortedProxy::categorySelectionModel() const
+{
+   if (!CategorizedHistoryModel::instance()->d_ptr->m_pSortedProxy)
+      CategorizedHistoryModel::instance()->d_ptr->m_pSortedProxy = SortingCategory::getHistoryProxy();
+
+   return CategorizedHistoryModel::instance()->d_ptr->m_pSortedProxy->selectionModel;
+}
+
+CategorizedHistoryModel::SortedProxy* CategorizedHistoryModel::SortedProxy::instance()
+{
+   return &CategorizedHistoryModel::instance()->d_ptr->m_pProxies;
+}
+
 #include <categorizedhistorymodel.moc>
diff --git a/src/categorizedhistorymodel.h b/src/categorizedhistorymodel.h
index 6272bd063a40719e869d09a22102ea45c0becc5d..1094969a77efe2d9d619cafa3ce16becfb575fae 100644
--- a/src/categorizedhistorymodel.h
+++ b/src/categorizedhistorymodel.h
@@ -36,6 +36,9 @@ typedef QList<Call*>       CallList;
 class HistoryItemNode;
 class AbstractHistoryBackend;
 class CategorizedHistoryModelPrivate;
+class QSortFilterProxyModel;
+class QItemSelectionModel;
+
 //TODO split ASAP
 ///CategorizedHistoryModel: History call manager
 class LIB_EXPORT CategorizedHistoryModel : public QAbstractItemModel, public CollectionManagerInterface<Call>
@@ -83,6 +86,22 @@ public:
    virtual bool          insertRows  ( int row, int count, const QModelIndex & parent = QModelIndex() ) override;
    virtual QHash<int,QByteArray> roleNames() const override;
 
+   struct SortedProxy {
+      enum class Categories {
+         DATE      ,
+         NAME      ,
+         POPULARITY,
+         LENGTH    ,
+         SPENT_TIME,
+         COUNT__
+      };
+
+      QSortFilterProxyModel* model                 () const;
+      QAbstractItemModel   * categoryModel         () const;
+      QItemSelectionModel  * categorySelectionModel() const;
+      static CategorizedHistoryModel::SortedProxy* instance();
+   };
+
 private:
    //Constructor
    explicit CategorizedHistoryModel();
diff --git a/src/delegates/pixmapmanipulationdelegate.cpp b/src/delegates/pixmapmanipulationdelegate.cpp
index fe10e8fee0662af985e5b6ed229b723e5e586c13..052c7eea73e28cd68179448fef5edb928be59423 100644
--- a/src/delegates/pixmapmanipulationdelegate.cpp
+++ b/src/delegates/pixmapmanipulationdelegate.cpp
@@ -103,3 +103,14 @@ QVariant PixmapManipulationDelegate::securityLevelIcon(const SecurityEvaluationM
    return QVariant();
 }
 
+QVariant PixmapManipulationDelegate::historySortingCategoryIcon(const CategorizedHistoryModel::SortedProxy::Categories cat) const
+{
+   Q_UNUSED(cat)
+   return QVariant();
+}
+
+QVariant PixmapManipulationDelegate::contactSortingCategoryIcon(const CategorizedContactModel::SortedProxy::Categories cat) const
+{
+   Q_UNUSED(cat)
+   return QVariant();
+}
diff --git a/src/delegates/pixmapmanipulationdelegate.h b/src/delegates/pixmapmanipulationdelegate.h
index bcd239999d0579bb96d595db01be051a1aa403bf..c82969e69a34cb5623177183e6c9500326f3821c 100644
--- a/src/delegates/pixmapmanipulationdelegate.h
+++ b/src/delegates/pixmapmanipulationdelegate.h
@@ -25,6 +25,8 @@
 
 //Ring
 #include <securityevaluationmodel.h>
+#include <categorizedcontactmodel.h>
+#include <categorizedhistorymodel.h>
 class  Person             ;
 class  ContactMethod      ;
 class  Call               ;
@@ -67,6 +69,8 @@ public:
    virtual QVariant   personPhoto(const QByteArray& data, const QString& type = "PNG");
    virtual QVariant   collectionIcon(const CollectionInterface* interface, PixmapManipulationDelegate::CollectionIconHint hint = PixmapManipulationDelegate::CollectionIconHint::NONE) const;
    virtual QVariant   securityLevelIcon(const SecurityEvaluationModel::SecurityLevel level) const;
+   virtual QVariant   historySortingCategoryIcon(const CategorizedHistoryModel::SortedProxy::Categories cat) const;
+   virtual QVariant   contactSortingCategoryIcon(const CategorizedContactModel::SortedProxy::Categories cat) const;
 
    /**
     * Return the icons associated with the action and its state
diff --git a/src/private/matrixutils.h b/src/private/matrixutils.h
index 5ab46152f28b951297c3c17785ba96c5a96b5a7e..2f5e69baa84ba9bea728c4eebd805072d8e91b55 100644
--- a/src/private/matrixutils.h
+++ b/src/private/matrixutils.h
@@ -22,6 +22,9 @@
 #include <initializer_list>
 #include <type_traits>
 
+//Ring
+#include <typedefs.h>
+
 template<class T, class E>
 struct TypedStateMachine
 {
diff --git a/src/private/sortproxies.cpp b/src/private/sortproxies.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3a01f7ed23acd39e9bc8c7741efcb2e33badf9a2
--- /dev/null
+++ b/src/private/sortproxies.cpp
@@ -0,0 +1,297 @@
+/****************************************************************************
+ *   Copyright (C) 2015 by Savoir-Faire Linux                               *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library 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      *
+ *   Lesser 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 <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#include "sortproxies.h"
+
+//LibSTDC++
+#include <functional>
+
+//Qt
+#include <QtCore/QAbstractListModel>
+#include <QtCore/QItemSelectionModel>
+#include <QtCore/QSortFilterProxyModel>
+
+//Ring
+#include "matrixutils.h"
+#include <categorizedcontactmodel.h>
+#include <categorizedhistorymodel.h>
+#include <delegates/pixmapmanipulationdelegate.h>
+
+namespace CategoryModelCommon {
+   inline Qt::ItemFlags flags(const QModelIndex& idx) {
+      return idx.isValid()?Qt::ItemIsEnabled|Qt::ItemIsSelectable : Qt::NoItemFlags;
+   }
+
+   bool setData( const QModelIndex& index, const QVariant &value, int role);
+   bool setData( const QModelIndex& index, const QVariant &value, int role) {
+      Q_UNUSED(index)
+      Q_UNUSED(value)
+      Q_UNUSED(role)
+      return false;
+   }
+
+   static const Matrix1D<CategorizedContactModel::SortedProxy::Categories,QString> contactSortNames = {{
+      QObject::tr("Name"         ),
+      QObject::tr("Organisation" ),
+      QObject::tr("Recently used"),
+      QObject::tr("Group"        ),
+      QObject::tr("Department"   ),
+   }};
+
+   static const Matrix1D<CategorizedHistoryModel::SortedProxy::Categories,QString> historySortNames = {{
+      QObject::tr("Date"       ),
+      QObject::tr("Name"       ),
+      QObject::tr("Popularity" ),
+      QObject::tr("Length"     ),
+      QObject::tr("Spent time" ),
+   }};
+
+}
+
+class RemoveDisabledProxy : public QSortFilterProxyModel
+{
+   Q_OBJECT
+public:
+   explicit RemoveDisabledProxy(QObject* parent) : QSortFilterProxyModel(parent) {
+      setDynamicSortFilter(true);
+   }
+protected:
+   virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const override;
+};
+
+class ContactSortingCategoryModel : public QAbstractListModel
+{
+   Q_OBJECT
+public:
+   ContactSortingCategoryModel(QObject* parent = nullptr);
+   virtual QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const override;
+   virtual int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const override;
+   virtual Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const override;
+   virtual bool          setData  ( const QModelIndex& index, const QVariant &value, int role)       override;
+   virtual ~ContactSortingCategoryModel();
+};
+
+class HistorySortingCategoryModel : public QAbstractListModel
+{
+   Q_OBJECT
+public:
+   HistorySortingCategoryModel(QObject* parent = nullptr);
+   virtual QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const override;
+   virtual int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const override;
+   virtual Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const override;
+   virtual bool          setData  ( const QModelIndex& index, const QVariant &value, int role)       override;
+   virtual ~HistorySortingCategoryModel();
+};
+
+bool RemoveDisabledProxy::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
+{
+   const Qt::ItemFlags flags = sourceModel()->index(source_row,0,source_parent).flags();
+   if (!(flags & Qt::ItemIsEnabled))
+      return false;
+   else if (!source_parent.isValid() || source_parent.parent().isValid())
+      return true;
+
+   return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
+}
+
+ContactSortingCategoryModel::ContactSortingCategoryModel(QObject* parent) : QAbstractListModel(parent)
+{
+
+}
+
+ContactSortingCategoryModel::~ContactSortingCategoryModel()
+{
+
+}
+
+void sortContact(QSortFilterProxyModel* p, int roleIdx);
+void sortContact(QSortFilterProxyModel* p, int roleIdx)
+{
+   static CategorizedContactModel* m = CategorizedContactModel::instance();
+   switch(static_cast<CategorizedContactModel::SortedProxy::Categories>(roleIdx)) {
+      case CategorizedContactModel::SortedProxy::Categories::NAME:
+         m->setSortAlphabetical(true);
+         m->setDefaultCategory(QObject::tr("Empty"));
+         m->setRole(Qt::DisplayRole);
+         p->setSortRole(Qt::DisplayRole);
+         break;
+      case CategorizedContactModel::SortedProxy::Categories::ORGANIZATION:
+         m->setSortAlphabetical(false);
+         m->setDefaultCategory(QObject::tr("Unknown"));
+         p->setSortRole((int)Person::Role::Organization);
+         m->setRole((int)Person::Role::Organization);
+         break;
+      case CategorizedContactModel::SortedProxy::Categories::RECENTLYUSED:
+         m->setSortAlphabetical(false);
+         m->setDefaultCategory(QObject::tr("Never"));
+         m->setRole((int)Person::Role::FormattedLastUsed);
+         p->setSortRole((int)Person::Role::IndexedLastUsed);
+         break;
+      case CategorizedContactModel::SortedProxy::Categories::GROUP:
+         m->setSortAlphabetical(false);
+         m->setDefaultCategory(QObject::tr("Other"));
+         m->setRole((int)Person::Role::Group);
+         p->setSortRole((int)Person::Role::Group);
+         break;
+      case CategorizedContactModel::SortedProxy::Categories::DEPARTMENT:
+         m->setSortAlphabetical(false);
+         m->setDefaultCategory(QObject::tr("Unknown"));
+         m->setRole((int)Person::Role::Department);
+         p->setSortRole((int)Person::Role::Department);
+         break;
+      case CategorizedContactModel::SortedProxy::Categories::COUNT__:
+         break;
+   };
+}
+
+QVariant ContactSortingCategoryModel::data( const QModelIndex& index, int role ) const
+{
+   if (index.isValid()) {
+      switch (role) {
+         case Qt::DisplayRole:
+            return CategoryModelCommon::contactSortNames[static_cast<CategorizedContactModel::SortedProxy::Categories>(index.row())];
+         case Qt::DecorationRole:
+            return PixmapManipulationDelegate::instance()->contactSortingCategoryIcon(static_cast<CategorizedContactModel::SortedProxy::Categories>(index.row()));
+      }
+   }
+   return QVariant();
+}
+
+int ContactSortingCategoryModel::rowCount( const QModelIndex& parent) const
+{
+   return parent.isValid()? 0 : enum_class_size<CategorizedContactModel::SortedProxy::Categories>();
+}
+
+Qt::ItemFlags ContactSortingCategoryModel::flags( const QModelIndex& index ) const
+{
+   return CategoryModelCommon::flags(index);
+}
+
+bool ContactSortingCategoryModel::setData( const QModelIndex& index, const QVariant &value, int role)
+{
+   return CategoryModelCommon::setData(index,value,role);
+}
+
+void sortHistory(QSortFilterProxyModel* p, int role);
+void sortHistory(QSortFilterProxyModel* p, int role)
+{
+   switch (static_cast<CategorizedHistoryModel::SortedProxy::Categories>(role)) {
+      case CategorizedHistoryModel::SortedProxy::Categories::DATE:
+         CategorizedHistoryModel::instance()->setCategoryRole(static_cast<int>(Call::Role::FuzzyDate));
+         p->setSortRole(static_cast<int>(Call::Role::Date));
+         break;
+      case CategorizedHistoryModel::SortedProxy::Categories::NAME:
+         CategorizedHistoryModel::instance()->setCategoryRole(static_cast<int>(Call::Role::Name));
+         p->setSortRole(static_cast<int>(Call::Role::Name));
+         break;
+      case CategorizedHistoryModel::SortedProxy::Categories::POPULARITY:
+         CategorizedHistoryModel::instance()->setCategoryRole(static_cast<int>(Call::Role::CallCount));
+         p->setSortRole(static_cast<int>(Call::Role::CallCount));
+         break;
+      case CategorizedHistoryModel::SortedProxy::Categories::LENGTH:
+         CategorizedHistoryModel::instance()->setCategoryRole(static_cast<int>(Call::Role::Length));
+         p->setSortRole(static_cast<int>(Call::Role::Length));
+         break;
+      case CategorizedHistoryModel::SortedProxy::Categories::SPENT_TIME:
+         CategorizedHistoryModel::instance()->setCategoryRole(static_cast<int>(Call::Role::TotalSpentTime));
+         p->setSortRole(static_cast<int>(Call::Role::TotalSpentTime));
+         break;
+      case CategorizedHistoryModel::SortedProxy::Categories::COUNT__:
+         break;
+   }
+}
+
+HistorySortingCategoryModel::HistorySortingCategoryModel(QObject* parent) : QAbstractListModel(parent)
+{
+   
+}
+
+HistorySortingCategoryModel::~HistorySortingCategoryModel()
+{
+
+}
+
+QVariant HistorySortingCategoryModel::data( const QModelIndex& index, int role) const
+{
+   if (index.isValid()) {
+      switch(role) {
+         case Qt::DisplayRole:
+            return CategoryModelCommon::historySortNames[static_cast<CategorizedHistoryModel::SortedProxy::Categories>(index.row())];
+         case Qt::DecorationRole:
+            return PixmapManipulationDelegate::instance()->historySortingCategoryIcon(static_cast<CategorizedHistoryModel::SortedProxy::Categories>(index.row()));
+      }
+   }
+
+   return QVariant();
+}
+
+int HistorySortingCategoryModel::rowCount( const QModelIndex& parent) const
+{
+   return parent.isValid()? 0 : enum_class_size<CategorizedHistoryModel::SortedProxy::Categories>();
+}
+
+Qt::ItemFlags HistorySortingCategoryModel::flags( const QModelIndex& index ) const
+{
+   return CategoryModelCommon::flags(index);
+}
+
+bool HistorySortingCategoryModel::setData( const QModelIndex& index, const QVariant &value, int role)
+{
+   return CategoryModelCommon::setData(index,value,role);
+}
+
+template<typename T>
+SortingCategory::ModelTuple* createModels(QAbstractItemModel* src, int role, std::function<void(QSortFilterProxyModel*,const QModelIndex&)> callback)
+{
+   SortingCategory::ModelTuple* ret = new SortingCategory::ModelTuple;
+
+   ret->categories = new T(src);
+
+   QSortFilterProxyModel* proxy = new RemoveDisabledProxy(src);
+   proxy->setSortRole              ( Qt::DisplayRole           );
+   proxy->setSortLocaleAware       ( true                      );
+   proxy->setFilterRole            ( role );
+   proxy->setSortCaseSensitivity   ( Qt::CaseInsensitive       );
+   proxy->setFilterCaseSensitivity ( Qt::CaseInsensitive       );
+   ret->model = proxy;
+   ret->model->setSourceModel(src);
+
+   ret->selectionModel = new QItemSelectionModel(ret->model);
+   QObject::connect(ret->selectionModel, &QItemSelectionModel::currentChanged,[proxy,callback](const QModelIndex& idx) {
+      callback(proxy,idx);
+   });
+
+   return ret;
+}
+
+SortingCategory::ModelTuple* SortingCategory::getContactProxy()
+{
+   return createModels<ContactSortingCategoryModel>(CategorizedContactModel::instance(),(int)Person::Role::Filter, [](QSortFilterProxyModel* proxy,const QModelIndex& idx) {
+      qDebug() << "Selection changed" << idx.row();
+      sortContact(proxy,idx.row());
+   });
+}
+
+SortingCategory::ModelTuple* SortingCategory::getHistoryProxy()
+{
+   return createModels<HistorySortingCategoryModel>(CategorizedHistoryModel::instance(),static_cast<int>(Call::Role::Date), [](QSortFilterProxyModel* proxy,const QModelIndex& idx) {
+      qDebug() << "Selection changed" << idx.row();
+      sortHistory(proxy,idx.row());
+   });
+}
+
+#include <sortproxies.moc>
diff --git a/src/private/sortproxies.h b/src/private/sortproxies.h
new file mode 100644
index 0000000000000000000000000000000000000000..3cbe794dc0c70b1ddedc0bf3c9ec26b31e9740c3
--- /dev/null
+++ b/src/private/sortproxies.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ *   Copyright (C) 2015 by Savoir-Faire Linux                               *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library 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      *
+ *   Lesser 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 <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#ifndef SORTPROXIES_H
+#define SORTPROXIES_H
+
+class QAbstractListModel;
+class QItemSelectionModel;
+class QSortFilterProxyModel;
+
+/*
+ * This file is dedicated to store the various sorting possibilities
+ *
+ * As they can share some helper code in common and would only add noise
+ * to their "real" source model, They are placed here.
+ */
+
+namespace SortingCategory {
+   struct ModelTuple {
+      QAbstractListModel*     categories    ;
+      QSortFilterProxyModel*  model         ;
+      QItemSelectionModel*    selectionModel;
+   };
+
+   ModelTuple* getContactProxy();
+   ModelTuple* getHistoryProxy();
+}
+
+#endif
\ No newline at end of file