From 71b99cb15a6ae181bd30712ca545b258cce8e55c Mon Sep 17 00:00:00 2001
From: Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>
Date: Mon, 24 Nov 2014 19:58:05 +0100
Subject: [PATCH] [ #60972 ] Port CallModel class to D-Pointer

---
 src/call.cpp                 |  82 +++++------
 src/call.h                   | 116 ++++-----------
 src/callmodel.cpp            | 273 +++++++++++++++++++----------------
 src/callmodel.h              |  44 +-----
 src/legacyhistorybackend.cpp |   1 +
 src/private/call_p.h         |  65 +++++++++
 6 files changed, 294 insertions(+), 287 deletions(-)

diff --git a/src/call.cpp b/src/call.cpp
index ef4413da..839e8ade 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -261,7 +261,7 @@ Call::Call(const QString& confId, const QString& account)
       d_ptr->initTimer();
       CallManagerInterface& callManager = DBus::CallManager::instance();
       MapStringString        details    = callManager.getConferenceDetails(id())  ;
-      d_ptr->m_CurrentState             = d_ptr->confStatetoCallState(details[ConfDetailsMapFields::CONF_STATE]);
+      d_ptr->m_CurrentState             = d_ptr->confStatetoCallState(details[CallPrivate::ConfDetailsMapFields::CONF_STATE]);
       emit stateChanged();
    }
 }
@@ -284,7 +284,7 @@ Call::~Call()
  ****************************************************************************/
 
 ///Build a call from its ID
-Call* Call::buildExistingCall(const QString& callId)
+Call* CallPrivate::buildExistingCall(const QString& callId)
 {
    CallManagerInterface& callManager = DBus::CallManager::instance();
    MapStringString       details     = callManager.getCallDetails(callId).value();
@@ -292,18 +292,18 @@ Call* Call::buildExistingCall(const QString& callId)
    //Too noisy
    //qDebug() << "Constructing existing call with details : " << details;
 
-   const QString peerNumber    = details[ Call::DetailsMapFields::PEER_NUMBER ];
-   const QString peerName      = details[ Call::DetailsMapFields::PEER_NAME   ];
-   const QString account       = details[ Call::DetailsMapFields::ACCOUNT_ID  ];
-   Call::State   startState    = startStateFromDaemonCallState(details[Call::DetailsMapFields::STATE], details[Call::DetailsMapFields::TYPE]);
+   const QString peerNumber    = details[ CallPrivate::DetailsMapFields::PEER_NUMBER ];
+   const QString peerName      = details[ CallPrivate::DetailsMapFields::PEER_NAME   ];
+   const QString account       = details[ CallPrivate::DetailsMapFields::ACCOUNT_ID  ];
+   Call::State   startState    = startStateFromDaemonCallState(details[CallPrivate::DetailsMapFields::STATE], details[CallPrivate::DetailsMapFields::TYPE]);
    Account*      acc           = AccountModel::instance()->getById(account);
    PhoneNumber*  nb            = PhoneDirectoryModel::instance()->getNumber(peerNumber,acc);
    Call*         call          = new Call(startState, callId, peerName, nb, acc);
    call->d_ptr->m_Recording    = callManager.getIsRecording(callId);
    call->d_ptr->m_HistoryState = historyStateFromType(details[Call::HistoryMapFields::STATE]);
 
-   if (!details[ Call::DetailsMapFields::TIMESTAMP_START ].isEmpty())
-      call->d_ptr->setStartTimeStamp(details[ Call::DetailsMapFields::TIMESTAMP_START ].toInt());
+   if (!details[ CallPrivate::DetailsMapFields::TIMESTAMP_START ].isEmpty())
+      call->d_ptr->setStartTimeStamp(details[ CallPrivate::DetailsMapFields::TIMESTAMP_START ].toInt());
    else {
       time_t curTime;
       ::time(&curTime);
@@ -320,7 +320,7 @@ Call* Call::buildExistingCall(const QString& callId)
 } //buildExistingCall
 
 ///Build a call from a dialing call (a call that is about to exist)
-Call* Call::buildDialingCall(const QString& callId, const QString & peerName, Account* account)
+Call* CallPrivate::buildDialingCall(const QString& callId, const QString & peerName, Account* account)
 {
    Call* call = new Call(Call::State::DIALING, callId, peerName, nullptr, account);
    call->d_ptr->m_HistoryState = Call::LegacyHistoryState::NONE;
@@ -333,14 +333,14 @@ Call* Call::buildDialingCall(const QString& callId, const QString & peerName, Ac
 }
 
 ///Build a call from a dbus event
-Call* Call::buildIncomingCall(const QString& callId)
+Call* CallPrivate::buildIncomingCall(const QString& callId)
 {
    CallManagerInterface & callManager = DBus::CallManager::instance();
    MapStringString details = callManager.getCallDetails(callId).value();
 
-   const QString from          = details[ Call::DetailsMapFields::PEER_NUMBER ];
-   const QString account       = details[ Call::DetailsMapFields::ACCOUNT_ID  ];
-   const QString peerName      = details[ Call::DetailsMapFields::PEER_NAME   ];
+   const QString from          = details[ CallPrivate::DetailsMapFields::PEER_NUMBER ];
+   const QString account       = details[ CallPrivate::DetailsMapFields::ACCOUNT_ID  ];
+   const QString peerName      = details[ CallPrivate::DetailsMapFields::PEER_NAME   ];
    Account*      acc           = AccountModel::instance()->getById(account);
    PhoneNumber*  nb            = PhoneDirectoryModel::instance()->getNumber(from,acc);
    Call* call                  = new Call(Call::State::INCOMING, callId, peerName, nb, acc);
@@ -353,18 +353,18 @@ Call* Call::buildIncomingCall(const QString& callId)
 } //buildIncomingCall
 
 ///Build a ringing call (from dbus)
-Call* Call::buildRingingCall(const QString & callId)
+Call* CallPrivate::buildRingingCall(const QString & callId)
 {
    CallManagerInterface& callManager = DBus::CallManager::instance();
    MapStringString details = callManager.getCallDetails(callId).value();
 
-   const QString from          = details[ Call::DetailsMapFields::PEER_NUMBER ];
-   const QString account       = details[ Call::DetailsMapFields::ACCOUNT_ID  ];
-   const QString peerName      = details[ Call::DetailsMapFields::PEER_NAME   ];
+   const QString from          = details[ CallPrivate::DetailsMapFields::PEER_NUMBER ];
+   const QString account       = details[ CallPrivate::DetailsMapFields::ACCOUNT_ID  ];
+   const QString peerName      = details[ CallPrivate::DetailsMapFields::PEER_NAME   ];
    Account*      acc           = AccountModel::instance()->getById(account);
    PhoneNumber*  nb            = PhoneDirectoryModel::instance()->getNumber(from,acc);
    Call* call                  = new Call(Call::State::RINGING, callId, peerName, nb, acc);
-   call->d_ptr->m_HistoryState = LegacyHistoryState::OUTGOING;
+   call->d_ptr->m_HistoryState = Call::LegacyHistoryState::OUTGOING;
    call->d_ptr->m_Direction    = Call::Direction::OUTGOING;
 
    if (call->peerPhoneNumber()) {
@@ -415,7 +415,7 @@ Call* Call::buildHistoryCall(const QMap<QString,QString>& hc)
    call->d_ptr->m_pStopTimeStamp  = stopTimeStamp ;
    call->d_ptr->m_History         = true;
    call->d_ptr->setStartTimeStamp(startTimeStamp);
-   call->d_ptr->m_HistoryState    = historyStateFromType(type);
+   call->d_ptr->m_HistoryState    = CallPrivate::historyStateFromType(type);
    call->d_ptr->m_Account         = AccountModel::instance()->getById(accId);
 
    //BEGIN In ~2015, remove the old logic and clean this
@@ -424,11 +424,11 @@ Call* Call::buildHistoryCall(const QMap<QString,QString>& hc)
       call->d_ptr->m_HistoryState = Call::LegacyHistoryState::MISSED;
    }
    if (!direction.isEmpty()) {
-      if (direction == HistoryStateName::INCOMING) {
+      if (direction == Call::HistoryStateName::INCOMING) {
          call->d_ptr->m_Direction    = Call::Direction::INCOMING         ;
          call->d_ptr->m_HistoryState = Call::LegacyHistoryState::INCOMING;
       }
-      else if (direction == HistoryStateName::OUTGOING) {
+      else if (direction == Call::HistoryStateName::OUTGOING) {
          call->d_ptr->m_Direction    = Call::Direction::OUTGOING         ;
          call->d_ptr->m_HistoryState = Call::LegacyHistoryState::OUTGOING;
       }
@@ -466,7 +466,7 @@ Call* Call::operator<<( Call::Action& c)
 }
 
 ///Get the history state from the type (see Call.cpp header)
-Call::LegacyHistoryState Call::historyStateFromType(const QString& type)
+Call::LegacyHistoryState CallPrivate::historyStateFromType(const QString& type)
 {
    if(type == Call::HistoryStateName::MISSED        )
       return Call::LegacyHistoryState::MISSED   ;
@@ -478,21 +478,21 @@ Call::LegacyHistoryState Call::historyStateFromType(const QString& type)
 }
 
 ///Get the start sate from the daemon state
-Call::State Call::startStateFromDaemonCallState(const QString& daemonCallState, const QString& daemonCallType)
+Call::State CallPrivate::startStateFromDaemonCallState(const QString& daemonCallState, const QString& daemonCallType)
 {
-   if(daemonCallState      == Call::DaemonStateInit::CURRENT  )
+   if(daemonCallState      == CallPrivate::DaemonStateInit::CURRENT  )
       return Call::State::CURRENT  ;
-   else if(daemonCallState == Call::DaemonStateInit::HOLD     )
+   else if(daemonCallState == CallPrivate::DaemonStateInit::HOLD     )
       return Call::State::HOLD     ;
-   else if(daemonCallState == Call::DaemonStateInit::BUSY     )
+   else if(daemonCallState == CallPrivate::DaemonStateInit::BUSY     )
       return Call::State::BUSY     ;
-   else if(daemonCallState == Call::DaemonStateInit::INACTIVE && daemonCallType == Call::CallDirection::INCOMING )
+   else if(daemonCallState == CallPrivate::DaemonStateInit::INACTIVE && daemonCallType == CallPrivate::CallDirection::INCOMING )
       return Call::State::INCOMING ;
-   else if(daemonCallState == Call::DaemonStateInit::INACTIVE && daemonCallType == Call::CallDirection::OUTGOING )
+   else if(daemonCallState == CallPrivate::DaemonStateInit::INACTIVE && daemonCallType == CallPrivate::CallDirection::OUTGOING )
       return Call::State::RINGING  ;
-   else if(daemonCallState == Call::DaemonStateInit::INCOMING )
+   else if(daemonCallState == CallPrivate::DaemonStateInit::INCOMING )
       return Call::State::INCOMING ;
-   else if(daemonCallState == Call::DaemonStateInit::RINGING  )
+   else if(daemonCallState == CallPrivate::DaemonStateInit::RINGING  )
       return Call::State::RINGING  ;
    else
       return Call::State::FAILURE  ;
@@ -508,19 +508,19 @@ Call::State Call::startStateFromDaemonCallState(const QString& daemonCallState,
 ///Transfer state from internal to daemon internal syntaz
 Call::DaemonState CallPrivate::toDaemonCallState(const QString& stateName)
 {
-   if(stateName == Call::StateChange::HUNG_UP        )
+   if(stateName == CallPrivate::StateChange::HUNG_UP        )
       return Call::DaemonState::HUNG_UP ;
-   if(stateName == Call::StateChange::RINGING        )
+   if(stateName == CallPrivate::StateChange::RINGING        )
       return Call::DaemonState::RINGING ;
-   if(stateName == Call::StateChange::CURRENT        )
+   if(stateName == CallPrivate::StateChange::CURRENT        )
       return Call::DaemonState::CURRENT ;
-   if(stateName == Call::StateChange::UNHOLD_CURRENT )
+   if(stateName == CallPrivate::StateChange::UNHOLD_CURRENT )
       return Call::DaemonState::CURRENT ;
-   if(stateName == Call::StateChange::HOLD           )
+   if(stateName == CallPrivate::StateChange::HOLD           )
       return Call::DaemonState::HOLD    ;
-   if(stateName == Call::StateChange::BUSY           )
+   if(stateName == CallPrivate::StateChange::BUSY           )
       return Call::DaemonState::BUSY    ;
-   if(stateName == Call::StateChange::FAILURE        )
+   if(stateName == CallPrivate::StateChange::FAILURE        )
       return Call::DaemonState::FAILURE ;
 
    qDebug() << "stateChanged signal received with unknown state.";
@@ -530,9 +530,9 @@ Call::DaemonState CallPrivate::toDaemonCallState(const QString& stateName)
 ///Transform a conference call state to a proper call state
 Call::State CallPrivate::confStatetoCallState(const QString& stateName)
 {
-   if      ( stateName == Call::ConferenceStateChange::HOLD   )
+   if      ( stateName == CallPrivate::ConferenceStateChange::HOLD   )
       return Call::State::CONFERENCE_HOLD;
-   else if ( stateName == Call::ConferenceStateChange::ACTIVE )
+   else if ( stateName == CallPrivate::ConferenceStateChange::ACTIVE )
       return Call::State::CONFERENCE;
    else
       return Call::State::ERROR; //Well, this may bug a little
@@ -917,8 +917,8 @@ Call::State CallPrivate::stateChanged(const QString& newStateName)
 
       CallManagerInterface & callManager = DBus::CallManager::instance();
       MapStringString details = callManager.getCallDetails(m_CallId).value();
-      if (details[Call::DetailsMapFields::PEER_NAME] != m_PeerName)
-         m_PeerName = details[Call::DetailsMapFields::PEER_NAME];
+      if (details[CallPrivate::DetailsMapFields::PEER_NAME] != m_PeerName)
+         m_PeerName = details[CallPrivate::DetailsMapFields::PEER_NAME];
 
       try {
          (this->*(stateChangedFunctionMap[previousState][dcs]))();
diff --git a/src/call.h b/src/call.h
index 4904f046..a94d7841 100644
--- a/src/call.h
+++ b/src/call.h
@@ -77,6 +77,8 @@ class  LIB_EXPORT Call : public QObject
    #pragma GCC diagnostic pop
 public:
    friend class CallModel;
+   friend class CallModelPrivate;
+
    //Enum
 
    ///Model roles
@@ -165,86 +167,6 @@ public:
    };
    Q_ENUMS(Direction)
 
-   ///@class HistoryStateName history map fields state names
-   class HistoryStateName {
-   public:
-      constexpr static const char* MISSED         = "missed"  ;
-      constexpr static const char* INCOMING       = "incoming";
-      constexpr static const char* OUTGOING       = "outgoing";
-   };
-
-   ///@class ConferenceStateChange Possible values from "conferencechanged" signal
-   class ConferenceStateChange {
-   public:
-      constexpr static const char* HOLD           = "HOLD"           ;
-      constexpr static const char* ACTIVE         = "ACTIVE_ATTACHED";
-   };
-
-   class StateChange {
-   public:
-      constexpr static const char* HUNG_UP        = "HUNGUP" ;
-      constexpr static const char* RINGING        = "RINGING";
-      constexpr static const char* CURRENT        = "CURRENT";
-      constexpr static const char* HOLD           = "HOLD"   ;
-      constexpr static const char* BUSY           = "BUSY"   ;
-      constexpr static const char* FAILURE        = "FAILURE";
-      constexpr static const char* UNHOLD_CURRENT = "UNHOLD" ;
-   };
-
-   class DaemonStateInit {
-   public:
-      constexpr static const char* CURRENT  = "CURRENT"  ;
-      constexpr static const char* HOLD     = "HOLD"     ;
-      constexpr static const char* BUSY     = "BUSY"     ;
-      constexpr static const char* INCOMING = "INCOMING" ;
-      constexpr static const char* RINGING  = "RINGING"  ;
-      constexpr static const char* INACTIVE = "INACTIVE" ;
-   };
-
-   ///"getHistory()" fields
-   class HistoryMapFields {
-   public:
-      constexpr static const char* ACCOUNT_ID        = "accountid"      ;
-      constexpr static const char* CALLID            = "callid"         ;
-      constexpr static const char* DISPLAY_NAME      = "display_name"   ;
-      constexpr static const char* PEER_NUMBER       = "peer_number"    ;
-      constexpr static const char* RECORDING_PATH    = "recordfile"     ;
-      constexpr static const char* STATE             = "state"          ;
-      constexpr static const char* TIMESTAMP_START   = "timestamp_start";
-      constexpr static const char* TIMESTAMP_STOP    = "timestamp_stop" ;
-      constexpr static const char* MISSED            = "missed"         ;
-      constexpr static const char* DIRECTION         = "direction"      ;
-      constexpr static const char* CONTACT_USED      = "contact_used"   ;
-      constexpr static const char* CONTACT_UID       = "contact_uid"    ;
-      constexpr static const char* NUMBER_TYPE       = "number_type"    ;
-   };
-
-   ///"getCallDetails()" fields
-   class DetailsMapFields {
-   public:
-      constexpr static const char* PEER_NAME         = "DISPLAY_NAME"   ;
-      constexpr static const char* PEER_NUMBER       = "PEER_NUMBER"    ;
-      constexpr static const char* ACCOUNT_ID        = "ACCOUNTID"      ;
-      constexpr static const char* STATE             = "CALL_STATE"     ;
-      constexpr static const char* TYPE              = "CALL_TYPE"      ;
-      constexpr static const char* TIMESTAMP_START   = "TIMESTAMP_START";
-      constexpr static const char* CONF_ID           = "CONF_ID"        ;
-   };
-
-   ///"getConferenceDetails()" fields
-   class ConfDetailsMapFields {
-   public:
-      constexpr static const char* CONF_STATE        = "CONF_STATE"     ;
-      constexpr static const char* CONFID            = "CONFID"         ;
-   };
-
-   ///If the call is incoming or outgoing
-   class CallDirection {
-   public:
-      constexpr static const char* INCOMING = "0";
-      constexpr static const char* OUTGOING = "1";
-   };
-
    ///Is the call between one or more participants
    enum class Type {
       CALL      , /** A simple call                  */
@@ -292,6 +214,32 @@ public:
       __COUNT
    };
 
+   ///"getHistory()" fields
+   class HistoryMapFields {
+   public:
+      constexpr static const char* ACCOUNT_ID        = "accountid"      ;
+      constexpr static const char* CALLID            = "callid"         ;
+      constexpr static const char* DISPLAY_NAME      = "display_name"   ;
+      constexpr static const char* PEER_NUMBER       = "peer_number"    ;
+      constexpr static const char* RECORDING_PATH    = "recordfile"     ;
+      constexpr static const char* STATE             = "state"          ;
+      constexpr static const char* TIMESTAMP_START   = "timestamp_start";
+      constexpr static const char* TIMESTAMP_STOP    = "timestamp_stop" ;
+      constexpr static const char* MISSED            = "missed"         ;
+      constexpr static const char* DIRECTION         = "direction"      ;
+      constexpr static const char* CONTACT_USED      = "contact_used"   ;
+      constexpr static const char* CONTACT_UID       = "contact_uid"    ;
+      constexpr static const char* NUMBER_TYPE       = "number_type"    ;
+   };
+
+   ///@class HistoryStateName history map fields state names
+   class HistoryStateName {
+   public:
+      constexpr static const char* MISSED         = "missed"  ;
+      constexpr static const char* INCOMING       = "incoming";
+      constexpr static const char* OUTGOING       = "outgoing";
+   };
+
    //Read only properties
    Q_PROPERTY( Call::State        state            READ state             NOTIFY stateChanged     )
    Q_PROPERTY( QString            id               READ id                                        )
@@ -320,16 +268,10 @@ public:
    Q_PROPERTY( QString            dialNumber       READ dialNumber        WRITE setDialNumber      NOTIFY dialNumberChanged(QString))
 
    //Constructors & Destructors
-   ~Call();
-   static Call* buildDialingCall  (const QString& callId, const QString & peerName, Account* account = nullptr );
-   static Call* buildIncomingCall (const QString& callId                                                       );
-   static Call* buildRingingCall  (const QString& callId                                                       );
    static Call* buildHistoryCall  (const QMap<QString,QString>& hc                                             );
-   static Call* buildExistingCall (const QString& callId                                                       );
+   ~Call();
 
    //Static getters
-   static Call::LegacyHistoryState historyStateFromType    ( const QString& type                                           );
-   static Call::State        startStateFromDaemonCallState ( const QString& daemonCallState, const QString& daemonCallType );
    static const QString      toHumanStateName              ( const Call::State                                             );
 
    //Getters
diff --git a/src/callmodel.cpp b/src/callmodel.cpp
index e44595c1..f8c56a57 100644
--- a/src/callmodel.cpp
+++ b/src/callmodel.cpp
@@ -56,6 +56,51 @@ struct InternalStruct {
 //Static member
 CallModel*   CallModel::m_spInstance = nullptr;
 
+class CallModelPrivate : public QObject
+{
+   Q_OBJECT
+public:
+      CallModelPrivate(CallModel* parent);
+      void init();
+      Call* addCall          ( Call* call                , Call* parent = nullptr );
+      Call* addConference    ( const QString& confID                              );
+      void  removeConference ( const QString& confId                              );
+      void  removeCall       ( Call* call       , bool noEmit = false             );
+      Call* addIncomingCall  ( const QString& callId                              );
+      Call* addRingingCall   ( const QString& callId                              );
+
+      //Attributes
+      QList<InternalStruct*> m_lInternalModel;
+      QHash< Call*       , InternalStruct* > m_sPrivateCallList_call   ;
+      QHash< QString     , InternalStruct* > m_sPrivateCallList_callId ;
+
+
+      //Helpers
+      bool isPartOf(const QModelIndex& confIdx, Call* call);
+      void initRoles();
+      void removeConference       ( Call* conf                    );
+      void removeInternal(InternalStruct* internal);
+
+   private:
+      CallModel* q_ptr;
+
+   private Q_SLOTS:
+      void slotCallStateChanged   ( const QString& callID    , const QString &state   );
+      void slotIncomingCall       ( const QString& accountID , const QString & callID );
+      void slotIncomingConference ( const QString& confID                             );
+      void slotChangingConference ( const QString& confID    , const QString &state   );
+      void slotConferenceRemoved  ( const QString& confId                             );
+      void slotAddPrivateCall     ( Call* call                                        );
+      void slotNewRecordingAvail  ( const QString& callId    , const QString& filePath);
+      void slotCallChanged        ( Call* call                                        );
+      void slotDTMFPlayed         ( const QString& str                                );
+      void slotRecordStateChanged ( const QString& callId    , bool state             );
+      #ifdef ENABLE_VIDEO
+      void slotStartedDecoding    ( const QString& callId    , const QString& shmKey  );
+      void slotStoppedDecoding    ( const QString& callId    , const QString& shmKey  );
+      #endif
+};
+
 
 /*****************************************************************************
  *                                                                           *
@@ -67,19 +112,24 @@ CallModel*   CallModel::m_spInstance = nullptr;
 CallModel* CallModel::instance() {
    if (!m_spInstance) {
       m_spInstance = new CallModel();
-      m_spInstance->init();
+      m_spInstance->d_ptr->init();
    }
    return m_spInstance;
 }
 
+CallModelPrivate::CallModelPrivate(CallModel* parent) : QObject(parent),q_ptr(parent)
+{
+   
+}
+
 ///Retrieve current and older calls from the daemon, fill history, model and enable drag n' drop
-CallModel::CallModel() : QAbstractItemModel(QCoreApplication::instance())
+CallModel::CallModel() : QAbstractItemModel(QCoreApplication::instance()),d_ptr(new CallModelPrivate(this))
 {
    setObjectName("CallModel");
 } //CallModel
 
 ///Constructor (there fix an initializationn loop)
-void CallModel::init()
+void CallModelPrivate::init()
 {
    static bool dbusInit = false;
    initRoles();
@@ -109,9 +159,6 @@ void CallModel::init()
       dbusInit = true;
 
       HistoryModel::instance();
-//       foreach(Call* call,){
-//          addCall(call,nullptr);
-//       }
    }
    static bool m_sInstanceInit = false;
    if (!m_sInstanceInit)
@@ -121,34 +168,34 @@ void CallModel::init()
    CallManagerInterface& callManager = DBus::CallManager::instance();
    const QStringList callList = callManager.getCallList();
    foreach (const QString& callId, callList) {
-      Call* tmpCall = Call::buildExistingCall(callId);
+      Call* tmpCall = CallPrivate::buildExistingCall(callId);
       addCall(tmpCall);
    }
 
    const QStringList confList = callManager.getConferenceList();
    foreach (const QString& confId, confList) {
       Call* conf = addConference(confId);
-      emit conferenceCreated(conf);
+      emit q_ptr->conferenceCreated(conf);
    }
 }
 
 ///Destructor
 CallModel::~CallModel()
 {
-   const QList<Call*> keys = m_sPrivateCallList_call.keys();
-   const QList<InternalStruct*> values = m_sPrivateCallList_call.values();
+   const QList<Call*> keys = d_ptr->m_sPrivateCallList_call.keys();
+   const QList<InternalStruct*> values = d_ptr->m_sPrivateCallList_call.values();
    foreach (Call* call, keys )
       delete call;
    foreach (InternalStruct* s,  values )
       delete s;
-   m_sPrivateCallList_call.clear  ();
-   m_sPrivateCallList_callId.clear();
+   d_ptr->m_sPrivateCallList_call.clear  ();
+   d_ptr->m_sPrivateCallList_callId.clear();
    m_spInstance = nullptr;
 }
 
-void CallModel::initRoles()
+void CallModelPrivate::initRoles()
 {
-   QHash<int, QByteArray> roles = roleNames();
+   QHash<int, QByteArray> roles = q_ptr->roleNames();
    roles.insert(Call::Role::Name          ,QByteArray("name"));
    roles.insert(Call::Role::Number        ,QByteArray("number"));
    roles.insert(Call::Role::Direction2    ,QByteArray("direction"));
@@ -174,7 +221,7 @@ void CallModel::initRoles()
    roles.insert(Call::Role::DTMFAnimState ,QByteArray("dTMFAnimState"));
    roles.insert(Call::Role::LastDTMFidx   ,QByteArray("lastDTMFidx"));
    roles.insert(Call::Role::IsRecording   ,QByteArray("isRecording"));
-   setRoleNames(roles);
+   q_ptr->setRoleNames(roles);
 }
 
 
@@ -187,7 +234,7 @@ void CallModel::initRoles()
 ///Return the active call count
 int CallModel::size()
 {
-   return m_lInternalModel.size();
+   return d_ptr->m_lInternalModel.size();
 }
 
 ///Return the action call list
@@ -195,7 +242,7 @@ int CallModel::size()
 {
    CallList callList;
    #pragma GCC diagnostic ignored "-Wshadow"
-   foreach(InternalStruct* internalS, m_lInternalModel) {
+   foreach(InternalStruct* internalS, d_ptr->m_lInternalModel) {
       callList.push_back(internalS->call_real);
       if (internalS->m_lChildren.size()) {
          #pragma GCC diagnostic ignored "-Wshadow"
@@ -215,10 +262,10 @@ CallList CallModel::getConferenceList()
    //That way it can not be invalid
    const QStringList confListS = DBus::CallManager::instance().getConferenceList();
    foreach (const QString& confId, confListS) {
-      InternalStruct* internalS = m_sPrivateCallList_callId[confId];
+      InternalStruct* internalS = d_ptr->m_sPrivateCallList_callId[confId];
       if (!internalS) {
          qDebug() << "Warning: Conference not found, creating it, this should not happen";
-         Call* conf = addConference(confId);
+         Call* conf = d_ptr->addConference(confId);
          confList << conf;
          emit conferenceCreated(conf);
       }
@@ -230,7 +277,7 @@ CallList CallModel::getConferenceList()
 
 bool CallModel::hasConference() const
 {
-   foreach(const InternalStruct* s, m_lInternalModel) {
+   foreach(const InternalStruct* s, d_ptr->m_lInternalModel) {
       if (s->m_lChildren.size())
          return true;
    }
@@ -260,14 +307,14 @@ Call* CallModel::getCall( const QModelIndex& idx              ) const
 ///Get the call associated with this ID
 Call* CallModel::getCall( const QString& callId ) const
 {
-   if (m_sPrivateCallList_callId[callId]) {
-      return m_sPrivateCallList_callId[callId]->call_real;
+   if (d_ptr->m_sPrivateCallList_callId[callId]) {
+      return d_ptr->m_sPrivateCallList_callId[callId]->call_real;
    }
    return nullptr;
 }
 
 ///Add a call in the model structure, the call must exist before being added to the model
-Call* CallModel::addCall(Call* call, Call* parentCall)
+Call* CallModelPrivate::addCall(Call* call, Call* parentCall)
 {
    //The current History implementation doesn't support conference
    //if something try to add an history conference, something went wrong
@@ -296,20 +343,20 @@ Call* CallModel::addCall(Call* call, Call* parentCall)
 
    m_sPrivateCallList_call  [ call       ] = aNewStruct;
    if (call->lifeCycleState() != Call::LifeCycleState::FINISHED) {
-      beginInsertRows(QModelIndex(),m_lInternalModel.size(),m_lInternalModel.size());
+      q_ptr->beginInsertRows(QModelIndex(),m_lInternalModel.size(),m_lInternalModel.size());
       m_lInternalModel << aNewStruct;
-      endInsertRows();
+      q_ptr->endInsertRows();
    }
    m_sPrivateCallList_callId[ call->id() ] = aNewStruct;
 
    //If the call is already finished, there is no point to track it here
    if (call->lifeCycleState() != Call::LifeCycleState::FINISHED) {
-      emit callAdded(call,parentCall);
-      const QModelIndex idx = index(m_lInternalModel.size()-1,0,QModelIndex());
-      emit dataChanged(idx, idx);
+      emit q_ptr->callAdded(call,parentCall);
+      const QModelIndex idx = q_ptr->index(m_lInternalModel.size()-1,0,QModelIndex());
+      emit q_ptr->dataChanged(idx, idx);
       connect(call,SIGNAL(changed(Call*)),this,SLOT(slotCallChanged(Call*)));
       connect(call,SIGNAL(dtmfPlayed(QString)),this,SLOT(slotDTMFPlayed(QString)));
-      emit layoutChanged();
+      emit q_ptr->layoutChanged();
    }
    return call;
 } //addCall
@@ -326,13 +373,13 @@ Call* CallModel::dialingCall(const QString& peerName, Account* account)
 
    //No dialing call found, creating one
    Account* acc = (account)?account:AccountModel::currentAccount();
-   return (!acc)?nullptr:addCall(Call::buildDialingCall(QString::number(qrand()), peerName, acc));
+   return (!acc)?nullptr:d_ptr->addCall(CallPrivate::buildDialingCall(QString::number(qrand()), peerName, acc));
 }  //dialingCall
 
 ///Create a new incoming call when the daemon is being called
-Call* CallModel::addIncomingCall(const QString& callId)
+Call* CallModelPrivate::addIncomingCall(const QString& callId)
 {
-   Call* call = addCall(Call::buildIncomingCall(callId));
+   Call* call = addCall(CallPrivate::buildIncomingCall(callId));
    //Call without account is not possible
    if (dynamic_cast<Account*>(call->account())) {
       if (call->account()->isAutoAnswer()) {
@@ -347,13 +394,13 @@ Call* CallModel::addIncomingCall(const QString& callId)
 }
 
 ///Create a ringing call
-Call* CallModel::addRingingCall(const QString& callId)
+Call* CallModelPrivate::addRingingCall(const QString& callId)
 {
-   return addCall(Call::buildRingingCall(callId));
+   return addCall(CallPrivate::buildRingingCall(callId));
 }
 
 ///Properly remove an internal from the Qt model
-void CallModel::removeInternal(InternalStruct* internal)
+void CallModelPrivate::removeInternal(InternalStruct* internal)
 {
    if (!internal) return;
 
@@ -365,13 +412,13 @@ void CallModel::removeInternal(InternalStruct* internal)
    }
 
    //Using layoutChanged would SEGFAULT when an editor is open
-   beginRemoveRows(QModelIndex(),idx,idx);
+   q_ptr->beginRemoveRows(QModelIndex(),idx,idx);
    m_lInternalModel.removeAt(idx);
-   endRemoveRows();
+   q_ptr->endRemoveRows();
 }
 
 ///Remove a call and update the internal structure
-void CallModel::removeCall(Call* call, bool noEmit)
+void CallModelPrivate::removeCall(Call* call, bool noEmit)
 {
    Q_UNUSED(noEmit)
    InternalStruct* internal = m_sPrivateCallList_call[call];
@@ -397,9 +444,9 @@ void CallModel::removeCall(Call* call, bool noEmit)
    if (internal->m_lChildren.size()) {
       foreach(InternalStruct* child,internal->m_lChildren) {
          if (child->call_real->state() != Call::State::OVER && child->call_real->state() != Call::State::ERROR) {
-            beginInsertRows(QModelIndex(),m_lInternalModel.size(),m_lInternalModel.size());
+            q_ptr->beginInsertRows(QModelIndex(),m_lInternalModel.size(),m_lInternalModel.size());
             m_lInternalModel << child;
-            endInsertRows();
+            q_ptr->endInsertRows();
          }
       }
    }
@@ -418,22 +465,22 @@ void CallModel::removeCall(Call* call, bool noEmit)
             removeConference(topLevel->call_real);
    }
 //    if (!noEmit)
-      emit layoutChanged();
+      emit q_ptr->layoutChanged();
 } //removeCall
 
 
 QModelIndex CallModel::getIndex(Call* call)
 {
-   InternalStruct* internal = m_sPrivateCallList_call[call];
-   int idx = m_lInternalModel.indexOf(internal);
+   InternalStruct* internal = d_ptr->m_sPrivateCallList_call[call];
+   int idx = d_ptr->m_lInternalModel.indexOf(internal);
    if (idx != -1) {
       return index(idx,0);
    }
    else {
-      foreach(InternalStruct* str,m_lInternalModel) {
+      foreach(InternalStruct* str,d_ptr->m_lInternalModel) {
          idx = str->m_lChildren.indexOf(internal);
          if (idx != -1)
-            return index(idx,0,index(m_lInternalModel.indexOf(str),0));
+            return index(idx,0,index(d_ptr->m_lInternalModel.indexOf(str),0));
       }
    }
    return QModelIndex();
@@ -469,7 +516,7 @@ void CallModel::transfer(Call* toTransfer, const PhoneNumber* target)
  ****************************************************************************/
 
 ///Add a new conference, get the call list and update the interface as needed
-Call* CallModel::addConference(const QString& confID)
+Call* CallModelPrivate::addConference(const QString& confID)
 {
    qDebug() << "Notified of a new conference " << confID;
    CallManagerInterface& callManager = DBus::CallManager::instance();
@@ -497,9 +544,9 @@ Call* CallModel::addConference(const QString& confID)
 
       m_sPrivateCallList_call[newConf]  = aNewStruct;
       m_sPrivateCallList_callId[confID] = aNewStruct;
-      beginInsertRows(QModelIndex(),m_lInternalModel.size(),m_lInternalModel.size());
+      q_ptr->beginInsertRows(QModelIndex(),m_lInternalModel.size(),m_lInternalModel.size());
       m_lInternalModel << aNewStruct;
-      endInsertRows();
+      q_ptr->endInsertRows();
 
       foreach(const QString& callId,callList) {
          InternalStruct* callInt = m_sPrivateCallList_callId[callId];
@@ -516,9 +563,9 @@ Call* CallModel::addConference(const QString& confID)
             qDebug() << "References to unknown call";
          }
       }
-      const QModelIndex idx = index(m_lInternalModel.size()-1,0,QModelIndex());
-      emit dataChanged(idx, idx);
-      emit layoutChanged();
+      const QModelIndex idx = q_ptr->index(m_lInternalModel.size()-1,0,QModelIndex());
+      emit q_ptr->dataChanged(idx, idx);
+      emit q_ptr->layoutChanged();
       connect(newConf,SIGNAL(changed(Call*)),this,SLOT(slotCallChanged(Call*)));
    }
 
@@ -561,34 +608,16 @@ bool CallModel::mergeConferences(Call* conf1, Call* conf2)
    return true;
 }
 
-///Executed when the daemon signal a modification in an existing conference. Update the call list and update the TreeView
-// bool CallModel::changeConference(const QString& confId, const QString& state)
-// {
-//    Q_UNUSED(state)
-//    qDebug() << "Conf changed";
-// 
-//    if (!m_sPrivateCallList_callId[confId]) {
-//       qDebug() << "The conference does not exist" << ;
-//       return false;
-//    }
-// 
-//    if (!m_sPrivateCallList_callId[confId]->index.isValid()) {
-//       qDebug() << "The conference item does not exist";
-//       return false;
-//    }
-//    return true;
-// } //changeConference
-
 ///Remove a conference from the model and the TreeView
-void CallModel::removeConference(const QString &confId)
+void CallModelPrivate::removeConference(const QString &confId)
 {
    if (m_sPrivateCallList_callId[confId])
       qDebug() << "Ending conversation containing " << m_sPrivateCallList_callId[confId]->m_lChildren.size() << " participants";
-   removeConference(getCall(confId));
+   removeConference(q_ptr->getCall(confId));
 }
 
 ///Remove a conference using it's call object
-void CallModel::removeConference(Call* call)
+void CallModelPrivate::removeConference(Call* call)
 {
    const InternalStruct* internal = m_sPrivateCallList_call[call];
 
@@ -651,10 +680,10 @@ QVariant CallModel::data( const QModelIndex& idx, int role) const
    if (!idx.isValid())
       return QVariant();
    Call* call = nullptr;
-   if (!idx.parent().isValid() && m_lInternalModel.size() > idx.row() && m_lInternalModel[idx.row()])
-      call = m_lInternalModel[idx.row()]->call_real;
-   else if (idx.parent().isValid() && m_lInternalModel.size() > idx.parent().row()) {
-      InternalStruct* intList = m_lInternalModel[idx.parent().row()];
+   if (!idx.parent().isValid() && d_ptr->m_lInternalModel.size() > idx.row() && d_ptr->m_lInternalModel[idx.row()])
+      call = d_ptr->m_lInternalModel[idx.row()]->call_real;
+   else if (idx.parent().isValid() && d_ptr->m_lInternalModel.size() > idx.parent().row()) {
+      InternalStruct* intList = d_ptr->m_lInternalModel[idx.parent().row()];
       if (intList->conference == true && intList->m_lChildren.size() > idx.row() && intList->m_lChildren[idx.row()])
          call = intList->m_lChildren[idx.row()]->call_real;
    }
@@ -674,7 +703,7 @@ QVariant CallModel::headerData(int section, Qt::Orientation orientation, int rol
 int CallModel::rowCount( const QModelIndex& parentIdx ) const
 {
    if (!parentIdx.isValid() || !parentIdx.internalPointer())
-      return m_lInternalModel.size();
+      return d_ptr->m_lInternalModel.size();
 
    const InternalStruct* modelItem = static_cast<InternalStruct*>(parentIdx.internalPointer());
    if (modelItem) {
@@ -730,7 +759,7 @@ QModelIndex CallModel::parent( const QModelIndex& idx) const
       return QModelIndex();
    const InternalStruct* modelItem = (InternalStruct*)idx.internalPointer();
    if (modelItem && modelItem->m_pParent) {
-      const int rowidx = m_lInternalModel.indexOf(modelItem->m_pParent);
+      const int rowidx = d_ptr->m_lInternalModel.indexOf(modelItem->m_pParent);
       if (rowidx != -1) {
          return CallModel::index(rowidx,0,QModelIndex());
       }
@@ -741,11 +770,11 @@ QModelIndex CallModel::parent( const QModelIndex& idx) const
 ///Get the call index at row,column (active call only)
 QModelIndex CallModel::index( int row, int column, const QModelIndex& parentIdx) const
 {
-   if (row >= 0 && !parentIdx.isValid() && m_lInternalModel.size() > row) {
-      return createIndex(row,column,m_lInternalModel[row]);
+   if (row >= 0 && !parentIdx.isValid() && d_ptr->m_lInternalModel.size() > row) {
+      return createIndex(row,column,d_ptr->m_lInternalModel[row]);
    }
-   else if (row >= 0 && parentIdx.isValid() && m_lInternalModel[parentIdx.row()]->m_lChildren.size() > row) {
-      return createIndex(row,column,m_lInternalModel[parentIdx.row()]->m_lChildren[row]);
+   else if (row >= 0 && parentIdx.isValid() && d_ptr->m_lInternalModel[parentIdx.row()]->m_lChildren.size() > row) {
+      return createIndex(row,column,d_ptr->m_lInternalModel[parentIdx.row()]->m_lChildren[row]);
    }
 //    if (!parentIdx.isValid())
 //       qWarning() << "Invalid index" << row << column << "model size" << m_lInternalModel.size();
@@ -779,7 +808,7 @@ QMimeData* CallModel::mimeData(const QModelIndexList& indexes) const
    return mData;
 }
 
-bool CallModel::isPartOf(const QModelIndex& confIdx, Call* call)
+bool CallModelPrivate::isPartOf(const QModelIndex& confIdx, Call* call)
 {
    if (!confIdx.isValid() || !call) return false;
 
@@ -813,7 +842,7 @@ bool CallModel::dropMimeData(const QMimeData* mimedata, Qt::DropAction action, i
       switch (mimedata->property("dropAction").toInt()) {
          case Call::DropAction::Conference:
             //Call or conference dropped on part of itself -> cannot merge conference with itself
-            if (isPartOf(targetIdx,call) || isPartOf(targetIdx.parent(),call) || (call && targetIdx.parent().data(Call::Role::Id) == encodedCallId)) {
+            if (d_ptr->isPartOf(targetIdx,call) || d_ptr->isPartOf(targetIdx.parent(),call) || (call && targetIdx.parent().data(Call::Role::Id) == encodedCallId)) {
                qDebug() << "Call/Conf dropped on its own conference (doing nothing)";
                return false;
             }
@@ -900,7 +929,7 @@ bool CallModel::dropMimeData(const QMimeData* mimedata, Qt::DropAction action, i
  ****************************************************************************/
 
 ///When a call state change
-void CallModel::slotCallStateChanged(const QString& callID, const QString& stateName)
+void CallModelPrivate::slotCallStateChanged(const QString& callID, const QString& stateName)
 {
    //This code is part of the CallModel interface too
    qDebug() << "Call State Changed for call  " << callID << " . New state : " << stateName;
@@ -909,7 +938,7 @@ void CallModel::slotCallStateChanged(const QString& callID, const QString& state
    Call::State previousState = Call::State::RINGING;
    if(!internal) {
       qDebug() << "Call not found";
-      if(stateName == Call::StateChange::RINGING) {
+      if(stateName == CallPrivate::StateChange::RINGING) {
          call = addRingingCall(callID);
       }
       else {
@@ -925,7 +954,7 @@ void CallModel::slotCallStateChanged(const QString& callID, const QString& state
       const Call::State          oldState          = call->state();
       call->d_ptr->stateChanged(stateName);
       //Remove call when they end normally, keep errors and failure one
-      if ((stateName == Call::StateChange::HUNG_UP)
+      if ((stateName == CallPrivate::StateChange::HUNG_UP)
          || ((oldState == Call::State::OVER) && (call->state() == Call::State::OVER))
          || (oldLifeCycleState != Call::LifeCycleState::FINISHED && call->state() == Call::State::OVER)) {
          removeCall(call);
@@ -937,30 +966,30 @@ void CallModel::slotCallStateChanged(const QString& callID, const QString& state
       HistoryModel::instance()->add(call);
    }
 
-   emit callStateChanged(call,previousState);
+   emit q_ptr->callStateChanged(call,previousState);
 
 } //slotCallStateChanged
 
 ///When a new call is incoming
-void CallModel::slotIncomingCall(const QString& accountID, const QString& callID)
+void CallModelPrivate::slotIncomingCall(const QString& accountID, const QString& callID)
 {
    Q_UNUSED(accountID)
    qDebug() << "Signal : Incoming Call ! ID = " << callID;
-   emit incomingCall(addIncomingCall(callID));
+   emit q_ptr->incomingCall(addIncomingCall(callID));
 }
 
 ///When a new conference is incoming
-void CallModel::slotIncomingConference(const QString& confID)
+void CallModelPrivate::slotIncomingConference(const QString& confID)
 {
-   if (!getCall(confID)) {
+   if (!q_ptr->getCall(confID)) {
       Call* conf = addConference(confID);
       qDebug() << "Adding conference" << conf << confID;
-      emit conferenceCreated(conf);
+      emit q_ptr->conferenceCreated(conf);
    }
 }
 
 ///When a conference change
-void CallModel::slotChangingConference(const QString &confID, const QString& state)
+void CallModelPrivate::slotChangingConference(const QString &confID, const QString& state)
 {
    InternalStruct* confInt = m_sPrivateCallList_callId[confID];
    if (!confInt) {
@@ -970,7 +999,7 @@ void CallModel::slotChangingConference(const QString &confID, const QString& sta
    Call* conf = confInt->call_real;
    qDebug() << "Changing conference state" << conf << confID;
    if (conf && dynamic_cast<Call*>(conf)) { //Prevent a race condition between call and conference
-      if (!getIndex(conf).isValid()) {
+      if (!q_ptr->getIndex(conf).isValid()) {
          qWarning() << "The conference item does not exist";
          return;
       }
@@ -986,10 +1015,10 @@ void CallModel::slotChangingConference(const QString &confID, const QString& sta
          if (participants.indexOf(child->call_real->id()) == -1 && child->call_real->lifeCycleState() != Call::LifeCycleState::FINISHED) {
             qDebug() << "Remove" << child->call_real << "from" << conf;
             child->m_pParent = nullptr;
-            beginInsertRows(QModelIndex(),m_lInternalModel.size(),m_lInternalModel.size());
+            q_ptr->beginInsertRows(QModelIndex(),m_lInternalModel.size(),m_lInternalModel.size());
             m_lInternalModel << child;
-            endInsertRows();
-            const QModelIndex idx = getIndex(child->call_real);
+            q_ptr->endInsertRows();
+            const QModelIndex idx = q_ptr->getIndex(child->call_real);
          }
       }
       confInt->m_lChildren.clear();
@@ -1020,7 +1049,7 @@ void CallModel::slotChangingConference(const QString &confID, const QString& sta
          const QMap<QString,QString> callDetails = callManager.getCallDetails(callId);
          InternalStruct* callInt = m_sPrivateCallList_callId[callId];
          if (callInt) {
-            const QString confId = callDetails[Call::DetailsMapFields::CONF_ID];
+            const QString confId = callDetails[CallPrivate::DetailsMapFields::CONF_ID];
             if (callInt->m_pParent) {
                if (!confId.isEmpty()  && callInt->m_pParent->call_real->id() != confId) {
                   qWarning() << "Conference parent mismatch";
@@ -1048,10 +1077,10 @@ void CallModel::slotChangingConference(const QString &confID, const QString& sta
 
       //TODO force reload all conferences too
 
-      const QModelIndex idx = index(m_lInternalModel.indexOf(confInt),0,QModelIndex());
-      emit layoutChanged();
-      emit dataChanged(idx, idx);
-      emit conferenceChanged(conf);
+      const QModelIndex idx = q_ptr->index(m_lInternalModel.indexOf(confInt),0,QModelIndex());
+      emit q_ptr->layoutChanged();
+      emit q_ptr->dataChanged(idx, idx);
+      emit q_ptr->conferenceChanged(conf);
    }
    else {
       qDebug() << "Trying to affect a conference that does not exist (anymore)";
@@ -1059,30 +1088,30 @@ void CallModel::slotChangingConference(const QString &confID, const QString& sta
 } //slotChangingConference
 
 ///When a conference is removed
-void CallModel::slotConferenceRemoved(const QString &confId)
+void CallModelPrivate::slotConferenceRemoved(const QString &confId)
 {
-   Call* conf = getCall(confId);
+   Call* conf = q_ptr->getCall(confId);
    removeConference(confId);
-   emit layoutChanged();
-   emit conferenceRemoved(conf);
+   emit q_ptr->layoutChanged();
+   emit q_ptr->conferenceRemoved(conf);
 }
 
 ///Make the call aware it has a recording
-void CallModel::slotNewRecordingAvail( const QString& callId, const QString& filePath)
+void CallModelPrivate::slotNewRecordingAvail( const QString& callId, const QString& filePath)
 {
-   getCall(callId)->setRecordingPath(filePath);
+   q_ptr->getCall(callId)->setRecordingPath(filePath);
 }
 
 #ifdef ENABLE_VIDEO
 ///Updating call state when video is added
-void CallModel::slotStartedDecoding(const QString& callId, const QString& shmKey)
+void CallModelPrivate::slotStartedDecoding(const QString& callId, const QString& shmKey)
 {
    Q_UNUSED(callId)
    Q_UNUSED(shmKey)
 }
 
 ///Updating call state when video is removed
-void CallModel::slotStoppedDecoding(const QString& callId, const QString& shmKey)
+void CallModelPrivate::slotStoppedDecoding(const QString& callId, const QString& shmKey)
 {
    Q_UNUSED(callId)
    Q_UNUSED(shmKey)
@@ -1090,13 +1119,13 @@ void CallModel::slotStoppedDecoding(const QString& callId, const QString& shmKey
 #endif
 
 ///Update model if the data change
-void CallModel::slotCallChanged(Call* call)
+void CallModelPrivate::slotCallChanged(Call* call)
 {
    switch(call->state()) {
       //Transfer is "local" state, it doesn't require the daemon, so it need to be
       //handled "manually" instead of relying on the backend signals
       case Call::State::TRANSFERRED:
-         emit callStateChanged(call, Call::State::TRANSFERRED);
+         emit q_ptr->callStateChanged(call, Call::State::TRANSFERRED);
          break;
       //Same goes for some errors
       case Call::State::__COUNT:
@@ -1124,21 +1153,21 @@ void CallModel::slotCallChanged(Call* call)
 
    InternalStruct* callInt = m_sPrivateCallList_call[call];
    if (callInt) {
-      const QModelIndex idx = getIndex(call);
+      const QModelIndex idx = q_ptr->getIndex(call);
       if (idx.isValid())
-         emit dataChanged(idx,idx);
+         emit q_ptr->dataChanged(idx,idx);
    }
 }
 
 ///Add call slot
-void CallModel::slotAddPrivateCall(Call* call) {
+void CallModelPrivate::slotAddPrivateCall(Call* call) {
    if (m_sPrivateCallList_call[call])
       return;
    addCall(call,nullptr);
 }
 
 ///Notice views that a dtmf have been played
-void CallModel::slotDTMFPlayed( const QString& str )
+void CallModelPrivate::slotDTMFPlayed( const QString& str )
 {
    Call* call = qobject_cast<Call*>(QObject::sender());
    if (str.size()==1) {
@@ -1153,17 +1182,19 @@ void CallModel::slotDTMFPlayed( const QString& str )
       else                           idx = -1          ;
       call->setProperty("latestDtmfIdx",idx);
    }
-   const QModelIndex& idx = getIndex(call);
-   setData(idx,50, Call::Role::DTMFAnimState);
+   const QModelIndex& idx = q_ptr->getIndex(call);
+   q_ptr->setData(idx,50, Call::Role::DTMFAnimState);
 }
 
 ///Called when a recording state change
-void CallModel::slotRecordStateChanged (const QString& callId, bool state)
+void CallModelPrivate::slotRecordStateChanged (const QString& callId, bool state)
 {
-   Call* call = getCall(callId);
+   Call* call = q_ptr->getCall(callId);
    if (call) {
       call->d_ptr->m_Recording = state;
       emit call->changed();
       emit call->changed(call);
    }
 }
+
+#include <callmodel.moc>
diff --git a/src/callmodel.h b/src/callmodel.h
index 75888f7a..191b7b3a 100644
--- a/src/callmodel.h
+++ b/src/callmodel.h
@@ -28,6 +28,7 @@
 class Account;
 struct InternalStruct;
 class PhoneNumber;
+class CallModelPrivate;
 
 //Typedef
 typedef QMap<uint, Call*>  CallMap;
@@ -79,6 +80,9 @@ class LIB_EXPORT CallModel : public QAbstractItemModel
       Q_INVOKABLE int      acceptedPayloadTypes();
       Q_INVOKABLE bool     hasConference       () const;
 
+      Q_INVOKABLE Call* getCall ( const QString& callId  ) const;
+      Q_INVOKABLE Call* getCall ( const QModelIndex& idx ) const;
+
       //Model implementation
       virtual bool          setData      ( const QModelIndex& index, const QVariant &value, int role   );
       virtual QVariant      data         ( const QModelIndex& index, int role = Qt::DisplayRole        ) const;
@@ -95,50 +99,14 @@ class LIB_EXPORT CallModel : public QAbstractItemModel
       //Singleton
       static CallModel* instance();
 
-      Q_INVOKABLE Call* getCall ( const QString& callId  ) const;
-      Q_INVOKABLE Call* getCall ( const QModelIndex& idx ) const;
-
    private:
       explicit CallModel();
-      void init();
-      Call* addCall          ( Call* call                , Call* parent = nullptr );
-      Call* addConference    ( const QString& confID                              );
-//       bool  changeConference ( const QString& confId, const QString& state        );
-      void  removeConference ( const QString& confId                              );
-      void  removeCall       ( Call* call       , bool noEmit = false             );
-      Call* addIncomingCall  ( const QString& callId                              );
-      Call* addRingingCall   ( const QString& callId                              );
-
-      //Attributes
-      QList<InternalStruct*> m_lInternalModel;
-      QHash< Call*       , InternalStruct* > m_sPrivateCallList_call   ;
-      QHash< QString     , InternalStruct* > m_sPrivateCallList_callId ;
+      QScopedPointer<CallModelPrivate> d_ptr;
+      Q_DECLARE_PRIVATE(CallModel)
 
       //Singleton
       static CallModel* m_spInstance;
 
-      //Helpers
-      bool isPartOf(const QModelIndex& confIdx, Call* call);
-      void initRoles();
-      void removeConference       ( Call* conf                    );
-      void removeInternal(InternalStruct* internal);
-
-   private Q_SLOTS:
-      void slotCallStateChanged   ( const QString& callID    , const QString &state   );
-      void slotIncomingCall       ( const QString& accountID , const QString & callID );
-      void slotIncomingConference ( const QString& confID                             );
-      void slotChangingConference ( const QString& confID    , const QString &state   );
-      void slotConferenceRemoved  ( const QString& confId                             );
-      void slotAddPrivateCall     ( Call* call                                        );
-      void slotNewRecordingAvail  ( const QString& callId    , const QString& filePath);
-      void slotCallChanged        ( Call* call                                        );
-      void slotDTMFPlayed         ( const QString& str                                );
-      void slotRecordStateChanged ( const QString& callId    , bool state             );
-      #ifdef ENABLE_VIDEO
-      void slotStartedDecoding    ( const QString& callId    , const QString& shmKey  );
-      void slotStoppedDecoding    ( const QString& callId    , const QString& shmKey  );
-      #endif
-
    Q_SIGNALS:
       ///Emitted when a call state change
       void callStateChanged        ( Call* call, Call::State previousState   );
diff --git a/src/legacyhistorybackend.cpp b/src/legacyhistorybackend.cpp
index e2972153..9583f8d9 100644
--- a/src/legacyhistorybackend.cpp
+++ b/src/legacyhistorybackend.cpp
@@ -21,6 +21,7 @@
 //SFLPhone
 #include "dbus/configurationmanager.h"
 #include "call.h"
+#include "private/call_p.h"
 
 LegacyHistoryBackend::LegacyHistoryBackend(QObject* parent) : AbstractHistoryBackend(nullptr,parent)
 {
diff --git a/src/private/call_p.h b/src/private/call_p.h
index 5b4e591a..1a01d8e0 100644
--- a/src/private/call_p.h
+++ b/src/private/call_p.h
@@ -40,6 +40,61 @@ class CallPrivate : public QObject
    Q_OBJECT
 public:
    friend class CallModel;
+   friend class CallModelPrivate;
+
+   ///@class ConferenceStateChange Possible values from "conferencechanged" signal
+   class ConferenceStateChange {
+   public:
+      constexpr static const char* HOLD           = "HOLD"           ;
+      constexpr static const char* ACTIVE         = "ACTIVE_ATTACHED";
+   };
+
+   class StateChange {
+   public:
+      constexpr static const char* HUNG_UP        = "HUNGUP" ;
+      constexpr static const char* RINGING        = "RINGING";
+      constexpr static const char* CURRENT        = "CURRENT";
+      constexpr static const char* HOLD           = "HOLD"   ;
+      constexpr static const char* BUSY           = "BUSY"   ;
+      constexpr static const char* FAILURE        = "FAILURE";
+      constexpr static const char* UNHOLD_CURRENT = "UNHOLD" ;
+   };
+
+   class DaemonStateInit {
+   public:
+      constexpr static const char* CURRENT  = "CURRENT"  ;
+      constexpr static const char* HOLD     = "HOLD"     ;
+      constexpr static const char* BUSY     = "BUSY"     ;
+      constexpr static const char* INCOMING = "INCOMING" ;
+      constexpr static const char* RINGING  = "RINGING"  ;
+      constexpr static const char* INACTIVE = "INACTIVE" ;
+   };
+
+   ///"getCallDetails()" fields
+   class DetailsMapFields {
+   public:
+      constexpr static const char* PEER_NAME         = "DISPLAY_NAME"   ;
+      constexpr static const char* PEER_NUMBER       = "PEER_NUMBER"    ;
+      constexpr static const char* ACCOUNT_ID        = "ACCOUNTID"      ;
+      constexpr static const char* STATE             = "CALL_STATE"     ;
+      constexpr static const char* TYPE              = "CALL_TYPE"      ;
+      constexpr static const char* TIMESTAMP_START   = "TIMESTAMP_START";
+      constexpr static const char* CONF_ID           = "CONF_ID"        ;
+   };
+
+   ///"getConferenceDetails()" fields
+   class ConfDetailsMapFields {
+   public:
+      constexpr static const char* CONF_STATE        = "CONF_STATE"     ;
+      constexpr static const char* CONFID            = "CONFID"         ;
+   };
+
+   ///If the call is incoming or outgoing
+   class CallDirection {
+   public:
+      constexpr static const char* INCOMING = "0";
+      constexpr static const char* OUTGOING = "1";
+   };
 
    CallPrivate(Call* parent);
 
@@ -149,6 +204,16 @@ public:
    void setStartTimeStamp(time_t stamp);
    void initTimer();
 
+   //Static getters
+   static Call::LegacyHistoryState historyStateFromType    ( const QString& type                                           );
+   static Call::State        startStateFromDaemonCallState ( const QString& daemonCallState, const QString& daemonCallType );
+
+   //Constructor
+   static Call* buildDialingCall  (const QString& callId, const QString & peerName, Account* account = nullptr );
+   static Call* buildIncomingCall (const QString& callId                                                       );
+   static Call* buildRingingCall  (const QString& callId                                                       );
+   static Call* buildExistingCall (const QString& callId                                                       );
+
 private:
    Call* q_ptr;
 
-- 
GitLab