From b5eff5f3cf62e7908b9b2bffbeafede8d63072a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= <sebastien.blin@savoirfairelinux.com> Date: Fri, 29 Jun 2018 12:01:27 -0400 Subject: [PATCH] refacto: remove unused models from LRC A lot of old models is now migrated to another part of the code. This patch is the first to remove unused code from all clients. In this patch, lot of models are now in the new account settings or in the smartlist or just unused. Change-Id: I46ab85b33332f615a911aaaf07507af0f2d2a178 Gitlab: #358 --- CMakeLists.txt | 36 - src/account.cpp | 203 +-- src/account.h | 29 - src/accountlistcolorizerdefault.cpp | 36 - src/accountlistcolorizerdefault.h | 31 - src/accountmodel.cpp | 49 - src/accountstatusmodel.cpp | 233 ---- src/accountstatusmodel.h | 82 -- src/bannedcontactmodel.cpp | 1 - src/bootstrapmodel.cpp | 446 ------- src/bootstrapmodel.h | 91 -- src/call.cpp | 10 +- src/call.h | 3 - src/callmodel.cpp | 15 +- src/callmodel.h | 2 - src/categorizedhistorymodel.cpp | 2 - src/codecmodel.cpp | 631 ---------- src/codecmodel.h | 127 -- src/credential.cpp | 82 -- src/credential.h | 68 - src/credentialmodel.h | 104 -- src/globalinstances.cpp | 24 - src/globalinstances.h | 5 - src/interfaces/accountlistcolorizeri.h | 35 - src/lastusednumbermodel.cpp | 147 --- src/lastusednumbermodel.h | 54 - src/localbookmarkcollection.cpp | 288 ----- src/localbookmarkcollection.h | 55 - src/localhistorycollection.h | 49 - src/localmacrocollection.cpp | 263 ---- src/localmacrocollection.h | 54 - src/lrc.cpp | 1 + src/numbercompletionmodel.cpp | 646 ---------- src/numbercompletionmodel.h | 88 -- src/pendingcontactrequestmodel.cpp | 174 --- src/pendingcontactrequestmodel.h | 70 -- src/person.cpp | 7 +- src/personmodel.cpp | 8 - src/phonedirectorymodel.h | 5 +- src/pixmapmanipulatordefault.cpp | 3 - src/private/account_p.h | 9 - src/private/accountmodel_p.h | 2 - src/private/call_p.h | 2 - src/private/pendingcontactrequestmodel_p.h | 39 - src/private/ringdevicemodel_p.h | 40 - src/recentmodel.cpp | 1300 -------------------- src/recentmodel.h | 73 -- src/ringdevice.cpp | 76 -- src/ringdevice.h | 55 - src/ringdevicemodel.h | 51 - src/ringtonemodel.h | 2 +- src/transitionalpersonbackend.cpp | 166 --- src/transitionalpersonbackend.h | 69 -- src/useractionmodel.h | 182 --- 54 files changed, 17 insertions(+), 6306 deletions(-) delete mode 100644 src/accountlistcolorizerdefault.cpp delete mode 100644 src/accountlistcolorizerdefault.h delete mode 100644 src/accountstatusmodel.cpp delete mode 100644 src/accountstatusmodel.h delete mode 100644 src/bootstrapmodel.cpp delete mode 100644 src/bootstrapmodel.h delete mode 100644 src/codecmodel.cpp delete mode 100644 src/codecmodel.h delete mode 100644 src/credential.cpp delete mode 100644 src/credential.h delete mode 100644 src/credentialmodel.h delete mode 100644 src/interfaces/accountlistcolorizeri.h delete mode 100644 src/lastusednumbermodel.cpp delete mode 100644 src/lastusednumbermodel.h delete mode 100644 src/localbookmarkcollection.cpp delete mode 100644 src/localbookmarkcollection.h delete mode 100644 src/localhistorycollection.h delete mode 100644 src/localmacrocollection.cpp delete mode 100644 src/localmacrocollection.h delete mode 100644 src/numbercompletionmodel.cpp delete mode 100644 src/numbercompletionmodel.h delete mode 100644 src/pendingcontactrequestmodel.cpp delete mode 100644 src/pendingcontactrequestmodel.h delete mode 100644 src/private/pendingcontactrequestmodel_p.h delete mode 100644 src/private/ringdevicemodel_p.h delete mode 100644 src/recentmodel.cpp delete mode 100644 src/recentmodel.h delete mode 100644 src/ringdevice.cpp delete mode 100644 src/ringdevice.h delete mode 100644 src/ringdevicemodel.h delete mode 100644 src/transitionalpersonbackend.cpp delete mode 100644 src/transitionalpersonbackend.h delete mode 100644 src/useractionmodel.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a90817ea..0d7c51ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -271,9 +271,7 @@ SET( libringclient_LIB_SRCS #Data objects src/call.cpp src/uri.cpp - src/ringdevice.cpp src/account.cpp - src/credential.cpp src/person.cpp src/contactmethod.cpp src/numbercategory.cpp @@ -297,16 +295,12 @@ SET( libringclient_LIB_SRCS src/media/textrecording.cpp #Models - src/bootstrapmodel.cpp - src/ringdevicemodel.cpp src/accountmodel.cpp src/availableaccountmodel.cpp src/callmodel.cpp src/categorizedhistorymodel.cpp src/categorizedbookmarkmodel.cpp - src/credentialmodel.cpp src/categorizedcontactmodel.cpp - src/useractionmodel.cpp src/presencestatusmodel.cpp src/phonedirectorymodel.cpp src/historytimecategorymodel.cpp @@ -315,10 +309,8 @@ SET( libringclient_LIB_SRCS src/keyexchangemodel.cpp src/tlsmethodmodel.cpp src/protocolmodel.cpp - src/numbercompletionmodel.cpp src/profilemodel.cpp src/ringtonemodel.cpp - src/lastusednumbermodel.cpp src/securityevaluationmodel.cpp src/personmodel.cpp src/collectionmodel.cpp @@ -327,11 +319,7 @@ SET( libringclient_LIB_SRCS src/networkinterfacemodel.cpp src/certificatemodel.cpp src/ciphermodel.cpp - src/accountstatusmodel.cpp - src/codecmodel.cpp - src/recentmodel.cpp src/chainoftrustmodel.cpp - src/pendingcontactrequestmodel.cpp src/video/devicemodel.cpp src/video/sourcemodel.cpp src/video/channel.cpp @@ -363,7 +351,6 @@ SET( libringclient_LIB_SRCS src/directrenderer.cpp #Data collections - src/transitionalpersonbackend.cpp src/collectioninterface.cpp src/collectioneditor.cpp src/fallbackpersoncollection.cpp @@ -371,10 +358,7 @@ SET( libringclient_LIB_SRCS src/foldercertificatecollection.cpp src/localrecordingcollection.cpp src/localtextrecordingcollection.cpp - src/localhistorycollection.cpp src/localprofilecollection.cpp - src/localmacrocollection.cpp - src/localbookmarkcollection.cpp src/localringtonecollection.cpp src/peerprofilecollection.cpp @@ -387,7 +371,6 @@ SET( libringclient_LIB_SRCS #Default interface implementations src/globalinstances.cpp - src/accountlistcolorizerdefault.cpp src/presenceserializerdefault.cpp src/pixmapmanipulatordefault.cpp src/shortcutcreatordefault.cpp @@ -416,8 +399,6 @@ SET( libringclient_LIB_SRCS # Public API SET( libringclient_LIB_HDRS src/account.h - src/ringdevice.h - src/credential.h src/accountmodel.h src/availableaccountmodel.h src/call.h @@ -425,40 +406,29 @@ SET( libringclient_LIB_HDRS src/callmodel.h src/categorizedhistorymodel.h src/person.h - src/bootstrapmodel.h - src/ringdevicemodel.h src/collectioninterface.h src/collectioninterface.hpp src/categorizedbookmarkmodel.h - src/credentialmodel.h src/categorizedcontactmodel.h - src/useractionmodel.h src/presencestatusmodel.h src/contactmethod.h src/phonedirectorymodel.h src/historytimecategorymodel.h src/numbercategorymodel.h src/keyexchangemodel.h - src/codecmodel.h src/tlsmethodmodel.h src/protocolmodel.h - src/numbercompletionmodel.h src/profilemodel.h src/numbercategory.h src/ringtonemodel.h src/localrecordingcollection.h - src/localbookmarkcollection.h src/localringtonecollection.h - src/localmacrocollection.h - src/localhistorycollection.h src/localprofilecollection.h src/localtextrecordingcollection.h src/peerprofilecollection.h - src/lastusednumbermodel.h src/securityevaluationmodel.h src/certificate.h src/personmodel.h - src/transitionalpersonbackend.h src/collectionmodel.h src/collectionextensionmodel.h src/collectionextensionmodel.hpp @@ -478,7 +448,6 @@ SET( libringclient_LIB_HDRS src/networkinterfacemodel.h src/certificatemodel.h src/ciphermodel.h - src/accountstatusmodel.h src/collectionmediator.h src/collectionmediator.hpp src/collectioneditor.h @@ -489,12 +458,9 @@ SET( libringclient_LIB_HDRS src/securityflaw.h src/collectioncreationinterface.h src/collectionconfigurationinterface.h - src/recentmodel.h src/chainoftrustmodel.h - src/pendingcontactrequestmodel.h src/contactrequest.h src/globalinstances.h - src/accountlistcolorizerdefault.h src/presenceserializerdefault.h src/pixmapmanipulatordefault.h src/shortcutcreatordefault.h @@ -570,7 +536,6 @@ SET(libringclient_media_LIB_HDRS ) SET(libringclient_interface_LIB_HDRS - src/interfaces/accountlistcolorizeri.h src/interfaces/contactmethodselectori.h src/interfaces/presenceserializeri.h src/interfaces/itemmodelstateserializeri.h @@ -675,7 +640,6 @@ ENDIF() # Manually wrap private files and interfaces SET(libringclient_PRIVATE_HDRS src/private/call_p.h - src/private/ringdevicemodel_p.h src/private/namedirectory_p.h src/private/account_p.h src/private/sortproxies.h diff --git a/src/account.cpp b/src/account.cpp index 4bc2430e..06d8f868 100644 --- a/src/account.cpp +++ b/src/account.cpp @@ -38,26 +38,18 @@ #include "dbus/videomanager.h" #include "dbus/presencemanager.h" #include "globalinstances.h" -#include "interfaces/accountlistcolorizeri.h" #include "certificate.h" #include "certificatemodel.h" #include "accountmodel.h" #include "private/certificatemodel_p.h" #include "private/account_p.h" #include "private/accountmodel_p.h" -#include "credentialmodel.h" #include "ciphermodel.h" #include "protocolmodel.h" -#include "bootstrapmodel.h" -#include "ringdevicemodel.h" #include "contactrequest.h" #include "person.h" #include "profile.h" #include "profilemodel.h" -#include "pendingcontactrequestmodel.h" -#include "private/pendingcontactrequestmodel_p.h" -#include "accountstatusmodel.h" -#include "codecmodel.h" #include "networkinterfacemodel.h" #include "contactmethod.h" #include "phonedirectorymodel.h" @@ -101,16 +93,14 @@ const Matrix2D<Account::EditState, Account::EditAction, account_function> Accoun //when objects have a different status for each account static uint p_sAutoIncrementId = 0; -AccountPrivate::AccountPrivate(Account* acc) : QObject(acc),q_ptr(acc),m_pCredentials(nullptr),m_pCodecModel(nullptr), +AccountPrivate::AccountPrivate(Account* acc) : QObject(acc),q_ptr(acc), m_LastErrorCode(-1),m_VoiceMailCount(0),m_CurrentState(Account::EditState::READY), m_pAccountNumber(nullptr),m_pKeyExchangeModel(nullptr),m_pSecurityEvaluationModel(nullptr),m_pTlsMethodModel(nullptr), -m_pCaCert(nullptr),m_pTlsCert(nullptr),m_isLoaded(true),m_pCipherModel(nullptr), -m_pStatusModel(nullptr),m_LastTransportCode(0),m_RegistrationState(Account::RegistrationState::UNREGISTERED), -m_UseDefaultPort(false),m_pProtocolModel(nullptr),m_pBootstrapModel(nullptr),m_RemoteEnabledState(false), +m_pCaCert(nullptr),m_pTlsCert(nullptr),m_isLoaded(true),m_pCipherModel(nullptr),m_LastTransportCode(0),m_RegistrationState(Account::RegistrationState::UNREGISTERED), +m_UseDefaultPort(false),m_pProtocolModel(nullptr),m_RemoteEnabledState(false), m_pKnownCertificates(nullptr), m_pBannedCertificates(nullptr), m_pAllowedCertificates(nullptr),m_InternalId(++p_sAutoIncrementId), -m_pNetworkInterfaceModel(nullptr),m_pAllowedCerts(nullptr),m_pBannedCerts(nullptr),m_pPendingContactRequestModel(nullptr), -m_pRingDeviceModel(nullptr) +m_pNetworkInterfaceModel(nullptr),m_pAllowedCerts(nullptr),m_pBannedCerts(nullptr) { } @@ -156,15 +146,9 @@ Account* Account::buildExistingAccountFromId(const QByteArray& _accountId) auto person = VCardUtils::mapToPersonFromReceivedProfile(contactMethod, payload); auto contactRequest = new ContactRequest(a, person, ringID, timeReceived); - a->pendingContactRequestModel()->d_ptr->addRequest(contactRequest); } } - // Connects the account to the signal of the model. - connect(a->pendingContactRequestModel() , &PendingContactRequestModel::requestAccepted, [a] (ContactRequest* r) { - emit a->contactRequestAccepted(r); - }); - // Load the contacts associated from the daemon and create the cms. const auto account_contacts = static_cast<QVector<QMap<QString, QString>>>(ConfigurationManager::instance() .getContacts(a->id().data())); @@ -220,13 +204,7 @@ Account* Account::buildNewAccountFromAlias(Account::Protocol proto, const QStrin a->d_ptr->m_hAccountDetails[iter.key()] = iter.value(); } - if (proto == Account::Protocol::RING) - { - /* Set LRC-provided bootstrap servers */ - a->bootstrapModel() << BootstrapModel::EditAction::RESET; - a->bootstrapModel() << BootstrapModel::EditAction::SAVE; - } - else + if (proto != Account::Protocol::RING) { a->setHostname(a->d_ptr->m_hAccountDetails[DRing::Account::ConfProperties::HOSTNAME]); } @@ -241,8 +219,6 @@ Account* Account::buildNewAccountFromAlias(Account::Protocol proto, const QStrin Account::~Account() { disconnect(); - if (d_ptr->m_pCredentials) delete d_ptr->m_pCredentials ; - if (d_ptr->m_pCodecModel) delete d_ptr->m_pCodecModel ; } /***************************************************************************** @@ -442,59 +418,12 @@ QModelIndex Account::index() const return QModelIndex(); } -///Return status color name -QString Account::stateColorName() const -{ - switch(registrationState()) { - case RegistrationState::READY: - return "darkGreen"; - case RegistrationState::UNREGISTERED: - return "black"; - case RegistrationState::TRYING: - case RegistrationState::INITIALIZING: - return "orange"; - case RegistrationState::ERROR: - return "red"; - case RegistrationState::COUNT__: - break; - }; - return QString(); -} - ///I bool Account::isLoaded() const { return d_ptr->m_isLoaded; } -///Return status Qt color, QColor is not part of QtCore, use using the global variant -QVariant Account::stateColor() const -{ - return GlobalInstances::accountListColorizer().color(this); -} - -///Create and return the credential model -CredentialModel* Account::credentialModel() const -{ - if (!d_ptr->m_pCredentials) { - d_ptr->m_pCredentials = new CredentialModel(const_cast<Account*>(this)); - connect(d_ptr->m_pCredentials, &CredentialModel::primaryCredentialChanged,[this]() { - Account* a = const_cast<Account*>(this); - emit a->changed(a); - }); - } - return d_ptr->m_pCredentials; -} - -///Create and return the audio codec model -CodecModel* Account::codecModel() const -{ - if (!d_ptr->m_pCodecModel) { - d_ptr->m_pCodecModel = new CodecModel(const_cast<Account*>(this)); - } - return d_ptr->m_pCodecModel; -} - KeyExchangeModel* Account::keyExchangeModel() const { if (!d_ptr->m_pKeyExchangeModel) { @@ -511,14 +440,6 @@ CipherModel* Account::cipherModel() const return d_ptr->m_pCipherModel; } -AccountStatusModel* Account::statusModel() const -{ - if (!d_ptr->m_pStatusModel) { - d_ptr->m_pStatusModel = new AccountStatusModel(const_cast<Account*>(this)); - } - return d_ptr->m_pStatusModel; -} - SecurityEvaluationModel* Account::securityEvaluationModel() const { if (!d_ptr->m_pSecurityEvaluationModel) { @@ -543,26 +464,6 @@ ProtocolModel* Account::protocolModel() const return d_ptr->m_pProtocolModel; } -BootstrapModel* Account::bootstrapModel() const -{ - if (protocol() != Account::Protocol::RING) - return nullptr; - - if (!d_ptr->m_pBootstrapModel ) { - d_ptr->m_pBootstrapModel = new BootstrapModel(const_cast<Account*>(this)); - } - - return d_ptr->m_pBootstrapModel; -} - -RingDeviceModel* Account::ringDeviceModel() const -{ - if (!d_ptr->m_pRingDeviceModel) - d_ptr->m_pRingDeviceModel = new RingDeviceModel(const_cast<Account*>(this)); - - return d_ptr->m_pRingDeviceModel; -} - QAbstractItemModel* Account::knownCertificateModel() const { if (!d_ptr->m_pKnownCertificates) { @@ -612,14 +513,6 @@ QAbstractItemModel* Account::allowedCertificatesModel() const return d_ptr->m_pAllowedCertificates; } -PendingContactRequestModel* Account::pendingContactRequestModel() const -{ - if (!d_ptr->m_pPendingContactRequestModel) - d_ptr->m_pPendingContactRequestModel = new PendingContactRequestModel(const_cast<Account*>(this)); - - return d_ptr->m_pPendingContactRequestModel; -} - BannedContactModel* Account::bannedContactModel() const { @@ -750,8 +643,6 @@ QString Account::password() const { switch (protocol()) { case Account::Protocol::SIP: - if (credentialModel()->primaryCredential(Credential::Type::SIP)) - return credentialModel()->primaryCredential(Credential::Type::SIP)->password(); break; case Account::Protocol::RING: return tlsPassword(); @@ -901,24 +792,6 @@ QString Account::ringtonePath() const return d_ptr->accountDetail(DRing::Account::ConfProperties::Ringtone::PATH); } -///Return the last error message received -QString Account::lastErrorMessage() const -{ - return statusModel()->lastErrorMessage(); -} - -///Return the last error code (useful for debugging) -int Account::lastErrorCode() const -{ - return statusModel()->lastErrorCode(); -} - -///Get the last transport error code, this is used to debug why registration failed -int Account::lastTransportErrorCode() const -{ - return d_ptr->m_LastTransportCode; -} - ///Get the last transport error message, this is used to debug why registration failed QString Account::lastTransportErrorMessage() const { @@ -1185,9 +1058,9 @@ QVariant Account::roleData(int role) const case Qt::CheckStateRole: return QVariant(isEnabled() ? Qt::Checked : Qt::Unchecked); case Qt::BackgroundRole: - return stateColor(); + return QVariant(); case Qt::DecorationRole: - return GlobalInstances::accountListColorizer().icon(this); + return QVariant(); //Specialized case CAST(Account::Role::Alias): @@ -1303,8 +1176,6 @@ QVariant Account::roleData(int role) const return isUpnpEnabled(); case CAST(Account::Role::HasCustomUserAgent ): return hasCustomUserAgent(); - case CAST(Account::Role::LastTransportErrorCode ): - return lastTransportErrorCode(); case CAST(Account::Role::LastTransportErrorMessage): return lastTransportErrorMessage(); case CAST(Account::Role::PushnotiticationToken ): @@ -1329,27 +1200,16 @@ QVariant Account::roleData(int role) const return displayName(); case CAST(Account::Role::SrtpEnabled ): return isSrtpEnabled(); - case CAST(Account::Role::HasCustomBootstrap ): - //Do not create the model for nothing - return protocol() == Account::Protocol::RING ? bootstrapModel()->isCustom() : false; - case CAST(Account::Role::CredentialModel ): - return QVariant::fromValue(credentialModel()); - case CAST(Account::Role::CodecModel ): - return QVariant::fromValue(codecModel()); case CAST(Account::Role::KeyExchangeModel ): return QVariant::fromValue(keyExchangeModel()); case CAST(Account::Role::CipherModel ): return QVariant::fromValue(cipherModel()); - case CAST(Account::Role::StatusModel ): - return QVariant::fromValue(statusModel()); case CAST(Account::Role::SecurityEvaluationModel ): return QVariant::fromValue(securityEvaluationModel()); case CAST(Account::Role::TlsMethodModel ): return QVariant::fromValue(tlsMethodModel()); case CAST(Account::Role::ProtocolModel ): return QVariant::fromValue(protocolModel()); - case CAST(Account::Role::BootstrapModel ): - return QVariant::fromValue(bootstrapModel()); case CAST(Account::Role::NetworkInterfaceModel ): return QVariant::fromValue(networkInterfaceModel()); case CAST(Account::Role::KnownCertificateModel ): @@ -1380,8 +1240,6 @@ QVariant Account::roleData(int role) const return extension<SecurityEvaluationExtension>()->securityLevelIcon(this); } break; - case CAST(Account::Role::LastStatusChangeTimeStamp): - return QVariant::fromValue(statusModel()->lastTimeStamp()); case CAST(Account::Role::RegisteredName): return registeredName(); default: @@ -1617,10 +1475,6 @@ void Account::setHostname(const QString& detail) { if (d_ptr->m_HostName != detail) { d_ptr->m_HostName = detail; - if (protocol() == Account::Protocol::RING) - { - bootstrapModel() << BootstrapModel::EditAction::RELOAD; - } d_ptr->setAccountProperty(DRing::Account::ConfProperties::HOSTNAME, detail); } } @@ -1654,14 +1508,6 @@ void Account::setUsername(const QString& detail) //nothing to do break; case Account::Protocol::SIP: - if (credentialModel()->primaryCredential(Credential::Type::SIP)) { - credentialModel()->primaryCredential(Credential::Type::SIP)->setUsername(detail); - credentialModel() << CredentialModel::EditAction::MODIFY; - } - else { - const QModelIndex idx = credentialModel()->addCredentials(Credential::Type::SIP); - credentialModel()->setData(idx,detail,CredentialModel::Role::NAME); - } break; }; } @@ -1684,19 +1530,11 @@ void Account::setNameServiceURL(const QString& detail) d_ptr->setAccountProperty(DRing::Account::ConfProperties::RingNS::URI, detail); } -///Set the main credential password +///Set the main password void Account::setPassword(const QString& detail) { switch (protocol()) { case Account::Protocol::SIP: - if (credentialModel()->primaryCredential(Credential::Type::SIP)) { - credentialModel()->primaryCredential(Credential::Type::SIP)->setPassword(detail); - credentialModel() << CredentialModel::EditAction::MODIFY; - } - else { - const QModelIndex idx = credentialModel()->addCredentials(Credential::Type::SIP); - credentialModel()->setData(idx,detail,CredentialModel::Role::PASSWORD); - } break; case Account::Protocol::RING: setTlsPassword(detail); @@ -2328,21 +2166,12 @@ void Account::setRoleData(int role, const QVariant& value) case CAST(Account::Role::SrtpEnabled ): setSrtpEnabled(value.toBool()); break; - case CAST(Account::Role::HasCustomBootstrap ): - //Do not create the model for nothing - if (protocol() == Account::Protocol::RING && value.toBool()) - bootstrapModel()->reset(); - break; - //Read-only - case CAST(Account::Role::CredentialModel ): - case CAST(Account::Role::CodecModel ): case CAST(Account::Role::KeyExchangeModel ): case CAST(Account::Role::CipherModel ): case CAST(Account::Role::StatusModel ): case CAST(Account::Role::SecurityEvaluationModel ): case CAST(Account::Role::TlsMethodModel ): case CAST(Account::Role::ProtocolModel ): - case CAST(Account::Role::BootstrapModel ): case CAST(Account::Role::NetworkInterfaceModel ): case CAST(Account::Role::KnownCertificateModel ): case CAST(Account::Role::BannedCertificatesModel ): @@ -2488,7 +2317,6 @@ Account::RoleState Account::roleState(Account::Role role) const case Account::Role::AllowIncomingFromContact: case Account::Role::AllowIncomingFromUnknown: case Account::Role::RegisteredName : - case Account::Role::HasCustomBootstrap : return Account::RoleState::UNAVAILABLE; } break; @@ -2596,8 +2424,6 @@ void AccountPrivate::save() const QString currentId = configurationManager.addAccount(details); - q_ptr->codecModel() << CodecModel::EditAction::RELOAD; - q_ptr->setId(currentId.toLatin1()); } //New account else { //Existing account @@ -2615,9 +2441,6 @@ void AccountPrivate::save() } } - //Save the credentials if they changed - q_ptr->credentialModel() << CredentialModel::EditAction::SAVE; - if (!q_ptr->id().isEmpty()) { Account* acc = AccountModel::instance().getById(q_ptr->id()); if (acc != q_ptr) { @@ -2631,8 +2454,6 @@ void AccountPrivate::save() changeState(Account::EditState::READY); } - q_ptr->codecModel() << CodecModel::EditAction::SAVE; - emit q_ptr->changed(q_ptr); } @@ -2699,14 +2520,6 @@ void AccountPrivate::reload() connect(m_pAccountNumber,SIGNAL(presentChanged(bool)),this,SLOT(slotPresentChanged(bool))); } - //If the credential model is loaded, then update it - if (m_pCredentials) - m_pCredentials << CredentialModel::EditAction::RELOAD; - - //If the codec model is loaded, then update it - if (m_pCodecModel) - m_pCodecModel << CodecModel::EditAction::RELOAD; - emit q_ptr->changed(q_ptr); //The registration state is cached, update that cache diff --git a/src/account.h b/src/account.h index 761fd99c..97c136b3 100644 --- a/src/account.h +++ b/src/account.h @@ -35,19 +35,13 @@ class QString; #include "namedirectory.h" #include "usage_statistics.h" -class CredentialModel ; class ContactMethod ; class SecurityEvaluationModel ; class Certificate ; class CipherModel ; -class AccountStatusModel ; class ProtocolModel ; -class CodecModel ; -class BootstrapModel ; -class RingDeviceModel ; class NetworkInterfaceModel ; class KeyExchangeModelPrivate ; -class PendingContactRequestModel; class Profile; class ContactRequest; class BannedContactModel; @@ -122,8 +116,6 @@ class LIB_EXPORT Account : public ItemBase { Q_PROPERTY(DtmfType dTMFType READ DTMFType WRITE setDTMFType ) Q_PROPERTY(int voiceMailCount READ voiceMailCount WRITE setVoiceMailCount ) // Q_PROPERTY(QString typeName READ type WRITE setType ) - Q_PROPERTY(QString lastErrorMessage READ lastErrorMessage ) - Q_PROPERTY(int lastErrorCode READ lastErrorCode ) Q_PROPERTY(bool presenceStatus READ presenceStatus ) Q_PROPERTY(QString presenceMessage READ presenceMessage ) Q_PROPERTY(bool supportPresencePublish READ supportPresencePublish ) @@ -155,16 +147,11 @@ class LIB_EXPORT Account : public ItemBase { Q_PROPERTY(bool allowIncomingFromContact READ allowIncomingFromContact WRITE setAllowIncomingFromContact ) Q_PROPERTY(bool allowIncomingFromUnknown READ allowIncomingFromUnknown WRITE setAllowIncomingFromUnknown ) - Q_PROPERTY(CredentialModel* credentialModel READ credentialModel ) - Q_PROPERTY(CodecModel* codecModel READ codecModel ) Q_PROPERTY(KeyExchangeModel* keyExchangeModel READ keyExchangeModel ) Q_PROPERTY(CipherModel* cipherModel READ cipherModel ) - Q_PROPERTY(AccountStatusModel* statusModel READ statusModel ) Q_PROPERTY(SecurityEvaluationModel* securityEvaluationModel READ securityEvaluationModel ) Q_PROPERTY(TlsMethodModel* tlsMethodModel READ tlsMethodModel ) Q_PROPERTY(ProtocolModel* protocolModel READ protocolModel ) - Q_PROPERTY(BootstrapModel* bootstrapModel READ bootstrapModel ) - Q_PROPERTY(RingDeviceModel* ringDeviceModel READ ringDeviceModel ) Q_PROPERTY(NetworkInterfaceModel* networkInterfaceModel READ networkInterfaceModel ) Q_PROPERTY(QAbstractItemModel* knownCertificateModel READ knownCertificateModel ) Q_PROPERTY(QAbstractItemModel* bannedCertificatesModel READ bannedCertificatesModel ) @@ -286,17 +273,12 @@ class LIB_EXPORT Account : public ItemBase { HasProxy , DisplayName , SrtpEnabled , - HasCustomBootstrap , - CredentialModel , - CodecModel , KeyExchangeModel , CipherModel , StatusModel , SecurityEvaluationModel , TlsMethodModel , ProtocolModel , - BootstrapModel , - RingDeviceModel , NetworkInterfaceModel , KnownCertificateModel , BannedCertificatesModel , @@ -368,26 +350,18 @@ class LIB_EXPORT Account : public ItemBase { const QString toHumanStateName() const; const QString alias () const; QModelIndex index () const; - QString stateColorName () const; - QVariant stateColor () const; virtual bool isLoaded () const; bool isIp2ip () const; - CredentialModel* credentialModel () const; - CodecModel* codecModel () const; KeyExchangeModel* keyExchangeModel () const; CipherModel* cipherModel () const; - AccountStatusModel* statusModel () const; SecurityEvaluationModel* securityEvaluationModel () const; TlsMethodModel* tlsMethodModel () const; ProtocolModel* protocolModel () const; - BootstrapModel* bootstrapModel () const; - RingDeviceModel* ringDeviceModel () const; NetworkInterfaceModel* networkInterfaceModel () const; QAbstractItemModel* knownCertificateModel () const; QAbstractItemModel* bannedCertificatesModel () const; QAbstractItemModel* allowedCertificatesModel () const; - PendingContactRequestModel* pendingContactRequestModel () const; BannedContactModel* bannedContactModel() const; Q_INVOKABLE RoleState roleState (Account::Role role) const; @@ -425,8 +399,6 @@ class LIB_EXPORT Account : public ItemBase { bool isTlsEnabled () const; bool isRingtoneEnabled () const; QString ringtonePath () const; - QString lastErrorMessage () const; - int lastErrorCode () const; int localPort () const; int voiceMailCount () const; DtmfType DTMFType () const; @@ -442,7 +414,6 @@ class LIB_EXPORT Account : public ItemBase { int audioPortMax () const; bool isUpnpEnabled () const; bool hasCustomUserAgent () const; - int lastTransportErrorCode () const; QString lastTransportErrorMessage () const; QString userAgent () const; bool useDefaultPort () const; diff --git a/src/accountlistcolorizerdefault.cpp b/src/accountlistcolorizerdefault.cpp deleted file mode 100644 index beee74aa..00000000 --- a/src/accountlistcolorizerdefault.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2012-2018 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 "accountlistcolorizerdefault.h" - -namespace Interfaces { - -QVariant AccountListColorizerDefault::color(const Account* a) -{ - Q_UNUSED(a) - //The default implementation does nothing - return QVariant(); -} - -QVariant AccountListColorizerDefault::icon(const Account* a) -{ - Q_UNUSED(a) - //The default implementation does nothing - return QVariant(); -} - -} // namespace Interfaces diff --git a/src/accountlistcolorizerdefault.h b/src/accountlistcolorizerdefault.h deleted file mode 100644 index 919e283a..00000000 --- a/src/accountlistcolorizerdefault.h +++ /dev/null @@ -1,31 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2012-2018 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/>. * - ***************************************************************************/ -#pragma once - -#include "interfaces/accountlistcolorizeri.h" - -namespace Interfaces { - -///Default implementation of the AccountListColorizer interface which simply returns empty QVariants -class LIB_EXPORT AccountListColorizerDefault : public AccountListColorizerI { -public: - QVariant color(const Account* a) override; - QVariant icon(const Account* a) override; -}; - -} // namespace Interfaces diff --git a/src/accountmodel.cpp b/src/accountmodel.cpp index 759ab351..03b99058 100644 --- a/src/accountmodel.cpp +++ b/src/accountmodel.cpp @@ -40,17 +40,11 @@ #include "profilemodel.h" #include "protocolmodel.h" #include "contactrequest.h" -#include "pendingcontactrequestmodel.h" -#include "ringdevicemodel.h" #include "private/accountmodel_p.h" -#include "private/ringdevicemodel_p.h" -#include "accountstatusmodel.h" #include "dbus/configurationmanager.h" #include "dbus/callmanager.h" #include "dbus/instancemanager.h" #include "dbus/presencemanager.h" -#include "codecmodel.h" -#include "private/pendingcontactrequestmodel_p.h" #include "person.h" #include "private/vcardutils.h" #include "phonedirectorymodel.h" @@ -89,12 +83,8 @@ void AccountModelPrivate::init() SLOT(slotVoiceMailNotify(QString,int)) ); connect(&configurationManager, SIGNAL(volatileAccountDetailsChanged(QString,MapStringString)),this, SLOT(slotVolatileAccountDetailsChange(QString,MapStringString)), Qt::QueuedConnection); - connect(&configurationManager, SIGNAL(mediaParametersChanged(QString)) ,this , - SLOT(slotMediaParametersChanged(QString)), Qt::QueuedConnection); connect(&configurationManager, &ConfigurationManagerInterface::incomingTrustRequest, this, &AccountModelPrivate::slotIncomingContactRequest, Qt::QueuedConnection); - connect(&configurationManager, &ConfigurationManagerInterface::knownDevicesChanged, this, - &AccountModelPrivate::slotKownDevicesChanged, Qt::QueuedConnection); connect(&configurationManager, &ConfigurationManagerInterface::exportOnRingEnded, this, &AccountModelPrivate::slotExportOnRingEnded, Qt::QueuedConnection); connect(&configurationManager, &ConfigurationManagerInterface::migrationEnded, this, @@ -186,16 +176,11 @@ QHash<int,QByteArray> AccountModel::roleNames() const roles.insert(CAST(Account::Role::HasProxy ) ,QByteArray("hasProxy" )); roles.insert(CAST(Account::Role::DisplayName ) ,QByteArray("displayName" )); roles.insert(CAST(Account::Role::SrtpEnabled ) ,QByteArray("srtpEnabled" )); - roles.insert(CAST(Account::Role::HasCustomBootstrap ) ,QByteArray("hasCustomBootstrap" )); - roles.insert(CAST(Account::Role::CredentialModel ) ,QByteArray("credentialModel" )); - roles.insert(CAST(Account::Role::CodecModel ) ,QByteArray("codecModel" )); roles.insert(CAST(Account::Role::KeyExchangeModel ) ,QByteArray("keyExchangeModel" )); roles.insert(CAST(Account::Role::CipherModel ) ,QByteArray("cipherModel" )); - roles.insert(CAST(Account::Role::StatusModel ) ,QByteArray("statusModel" )); roles.insert(CAST(Account::Role::SecurityEvaluationModel ) ,QByteArray("securityEvaluationModel" )); roles.insert(CAST(Account::Role::TlsMethodModel ) ,QByteArray("tlsMethodModel" )); roles.insert(CAST(Account::Role::ProtocolModel ) ,QByteArray("protocolModel" )); - roles.insert(CAST(Account::Role::BootstrapModel ) ,QByteArray("bootstrapModel" )); roles.insert(CAST(Account::Role::NetworkInterfaceModel ) ,QByteArray("networkInterfaceModel" )); roles.insert(CAST(Account::Role::KnownCertificateModel ) ,QByteArray("knownCertificateModel" )); roles.insert(CAST(Account::Role::BannedCertificatesModel ) ,QByteArray("bannedCertificatesModel" )); @@ -326,7 +311,6 @@ void AccountModelPrivate::slotDaemonAccountChanged(const QString& account, const Q_UNUSED(registration_state); Account* a = q_ptr->getById(account.toLatin1()); - //TODO move this to AccountStatusModel if (!a || (a && a->lastSipRegistrationStatus() != status )) { if (status != "OK") //Do not pollute the log qDebug() << "Account" << account << "status changed to" << status; @@ -395,9 +379,6 @@ void AccountModelPrivate::slotDaemonAccountChanged(const QString& account, const else if (regStateChanged) emit q_ptr->registrationChanged(a,a->registrationState() == Account::RegistrationState::READY); - //Send the messages to AccountStatusModel for processing - a->statusModel()->addSipRegistrationEvent(status,code); - //Make sure volatile details get reloaded //TODO eventually remove this call and trust the signal slotVolatileAccountDetailsChange(account,configurationManager.getVolatileAccountDetails(account)); @@ -455,8 +436,6 @@ void AccountModelPrivate::slotVolatileAccountDetailsChange(const QString& accoun const QString transportDesc = details[DRing::Account::VolatileProperties::Transport::STATE_DESC]; const QString status = details[DRing::Account::VolatileProperties::Registration::STATUS]; - a->statusModel()->addTransportEvent(transportDesc,transportCode); - a->setLastTransportCode(transportCode); a->setLastTransportMessage(transportDesc); @@ -479,27 +458,11 @@ void AccountModelPrivate::slotIncomingContactRequest(const QString& accountId, c /* do not pass a person before the contact request was added to his model */ ContactRequest* r = new ContactRequest(a, nullptr, ringID, time); - a->pendingContactRequestModel()->d_ptr->addRequest(r); auto contactMethod = PhoneDirectoryModel::instance().getNumber(ringID, a); r->setPeer(VCardUtils::mapToPersonFromReceivedProfile(contactMethod, payload)); } -///Known Ring devices have changed -void AccountModelPrivate::slotKownDevicesChanged(const QString& accountId, const MapStringString& accountDevices) -{ - qDebug() << "Known devices changed" << accountId; - - Account* a = q_ptr->getById(accountId.toLatin1()); - - if (!a) { - qWarning() << "Known devices changed for unknown account" << accountId; - return; - } - - a->ringDeviceModel()->d_ptr->reload(accountDevices); -} - ///Export on Ring ended void AccountModelPrivate::slotExportOnRingEnded(const QString& accountId, int status, const QString& pin) { @@ -852,18 +815,6 @@ AccountModel::subscribeToBuddies(const QString &accountId) } } -///Called when codec bitrate changes -void AccountModelPrivate::slotMediaParametersChanged(const QString& accountId) -{ - Account* a = q_ptr->getById(accountId.toLatin1()); - if (a) { - if (auto codecModel = a->codecModel()) { - qDebug() << "reloading codecs"; - codecModel << CodecModel::EditAction::RELOAD; - } - } -} - /***************************************************************************** * * * Getters * diff --git a/src/accountstatusmodel.cpp b/src/accountstatusmodel.cpp deleted file mode 100644 index d395e3e3..00000000 --- a/src/accountstatusmodel.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015-2018 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 "accountstatusmodel.h" - -//System -#include <errno.h> - -#ifdef Q_OS_WIN -#include <winerror.h> -#define ESHUTDOWN WSAESHUTDOWN -#define ENODATA WSANO_DATA -#define ETIME WSAETIMEDOUT -#define EPFNOSUPPORT WSAEPROTONOSUPPORT -#define EHOSTDOWN WSAEHOSTDOWN -#define ESTALE WSAESTALE -#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT -#define ETOOMANYREFS WSAETOOMANYREFS -#define EUSERS WSAEUSERS -#define EBADMSG 9905 -#define ENOLINK 9918 -#define ENOSR 9922 -#define ENOSTR 9924 -#define EMULTIHOP 2004 -#endif - -//Qt -#include <QtCore/QCoreApplication> -#include <QtCore/QDateTime> - -//Ring daemon -#include <account_const.h> - -//Ring -#include "dbus/configurationmanager.h" -#include "account.h" - -struct AccountStatusRow { - AccountStatusRow(const QString& ,int, AccountStatusModel::Type); - QString description; - int code ; - QDateTime time ; - time_t timestamp ; - uint counter ; - AccountStatusModel::Type type ; -}; - -class AccountStatusModelPrivate { -public: - AccountStatusModelPrivate(Account* parent); - ~AccountStatusModelPrivate(); - - //Attributes - Account* m_pAccount; - QVector<AccountStatusRow*> m_lRows; - time_t m_FallbackTime_t; -}; - - -AccountStatusRow::AccountStatusRow(const QString& _description, int _code, AccountStatusModel::Type _type): -code(_code),counter(0), -time(QDateTime::currentDateTime()),type(_type) -{ - description = _description; - timestamp = time.toTime_t(); -} - -AccountStatusModelPrivate::AccountStatusModelPrivate(Account* parent) : m_pAccount(parent), -m_FallbackTime_t(QDateTime::currentDateTime().toTime_t()) -{ -} - -AccountStatusModelPrivate::~AccountStatusModelPrivate() -{ - for (int i=0;i<m_lRows.size();i++) - delete m_lRows[i]; - m_lRows.clear(); -} - -AccountStatusModel::AccountStatusModel(Account* parent) : QAbstractTableModel(parent), -d_ptr(new AccountStatusModelPrivate(parent)) -{} - -AccountStatusModel::~AccountStatusModel() -{ - delete d_ptr; -} - -QHash<int,QByteArray> AccountStatusModel::roleNames() const -{ - static QHash<int, QByteArray> roles = QAbstractItemModel::roleNames(); - /*static bool initRoles = false; - if (!initRoles) { - initRoles = true; - - }*/ - return roles; -} - -//Model functions -QVariant AccountStatusModel::data( const QModelIndex& index, int role) const -{ - if (!index.isValid()) return QVariant(); - switch(static_cast<Columns>(index.column())) { - case Columns::DESCRIPTION: - switch (role) { - case Qt::DisplayRole: - return d_ptr->m_lRows[index.row()]->description; - }; - break; - case Columns::CODE: - switch (role) { - case Qt::DisplayRole: - return d_ptr->m_lRows[index.row()]->code; - }; - break; - case Columns::TIME: - switch (role) { - case Qt::DisplayRole: - return d_ptr->m_lRows[index.row()]->time; - }; - break; - case Columns::COUNTER: - switch (role) { - case Qt::DisplayRole: - return d_ptr->m_lRows[index.row()]->counter; - }; - break; - }; - return QVariant(); -} - -int AccountStatusModel::rowCount( const QModelIndex& parent ) const -{ - Q_UNUSED(parent) - return d_ptr->m_lRows.size(); -} - -int AccountStatusModel::columnCount( const QModelIndex& parent ) const -{ - Q_UNUSED(parent) - return 4; -} - -Qt::ItemFlags AccountStatusModel::flags( const QModelIndex& index ) const -{ - return (index.isValid()) ? (Qt::ItemIsEnabled|Qt::ItemIsSelectable|Qt::ItemIsUserCheckable) : Qt::NoItemFlags; -} - -bool AccountStatusModel::setData( const QModelIndex& index, const QVariant &value, int role) -{ - Q_UNUSED(index) - Q_UNUSED(value) - Q_UNUSED(role ) - return false; -} - -QVariant AccountStatusModel::headerData( int section, Qt::Orientation o, int role) const -{ - if (o == Qt::Horizontal && role == Qt::DisplayRole) { - switch(section) { - case 0: - return QObject::tr("Message"); - case 1: - return QObject::tr("Code"); - case 2: - return QObject::tr("Time"); - case 3: - return QObject::tr("Counter"); - } - } - return QVariant(); -} - -void AccountStatusModel::addSipRegistrationEvent(const QString& fallbackMessage, int errorCode) -{ - if (errorCode != d_ptr->m_pAccount->lastErrorCode()) { - beginInsertRows(QModelIndex(), d_ptr->m_lRows.size(), d_ptr->m_lRows.size()); - d_ptr->m_lRows << new AccountStatusRow(fallbackMessage, errorCode, Type::SIP); - endInsertRows(); - } - else - d_ptr->m_lRows.last()->counter++; -} - -void AccountStatusModel::addTransportEvent(const QString& fallbackMessage, int errorCode) -{ - if ((!d_ptr->m_lRows.size()) || errorCode != d_ptr->m_pAccount->lastTransportErrorCode()) { - beginInsertRows(QModelIndex(), d_ptr->m_lRows.size(), d_ptr->m_lRows.size()); - d_ptr->m_lRows << new AccountStatusRow(fallbackMessage, errorCode, Type::TRANSPORT); - endInsertRows(); - } - else - d_ptr->m_lRows.last()->counter++; -} - -QString AccountStatusModel::lastErrorMessage() const -{ - if (d_ptr->m_lRows.isEmpty()) - return QString(); - - return d_ptr->m_lRows.last()->description; -} - -int AccountStatusModel::lastErrorCode() const -{ - if (d_ptr->m_lRows.isEmpty()) - return -1; - - return d_ptr->m_lRows.last()->code; -} - -time_t AccountStatusModel::lastTimeStamp() const -{ - if (d_ptr->m_lRows.isEmpty()) - return d_ptr->m_FallbackTime_t; - - return d_ptr->m_lRows.last()->timestamp; -} diff --git a/src/accountstatusmodel.h b/src/accountstatusmodel.h deleted file mode 100644 index 447641e6..00000000 --- a/src/accountstatusmodel.h +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015-2018 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/>. * - ***************************************************************************/ -#pragma once - -#include "typedefs.h" -#include <QtCore/QAbstractTableModel> - -class AccountStatusModelPrivate; -class Account; - -/**This model is used to track registration event. It can be used both - * for informational purpose like "was my account up at 10:30AM?" or - * as a generic container to handle various kind of network, - * configuration or runtime problems. - */ -class LIB_EXPORT AccountStatusModel : public QAbstractTableModel { - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - Q_OBJECT - #pragma GCC diagnostic pop - - friend class Account; - friend class AccountPrivate; - friend class AccountModelPrivate; - -public: - - enum class Type { - REGISTRATION, - TRANSPORT, - SIP, - }; - - enum class Columns { - DESCRIPTION, - CODE, - TIME, - COUNTER, - }; - - //Model functions - virtual QVariant data ( const QModelIndex& index, int role = Qt::DisplayRole ) const override; - virtual int rowCount ( const QModelIndex& parent = QModelIndex() ) const override; - virtual int columnCount ( 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 QVariant headerData ( int section, Qt::Orientation, int role = Qt::DisplayRole ) const override; - virtual QHash<int,QByteArray> roleNames() const override; - - //Getter - QString lastErrorMessage() const; - int lastErrorCode () const; - time_t lastTimeStamp () const; - -private: - //Private mutators - void addSipRegistrationEvent(const QString& fallbackMessage, int errorCode); - void addTransportEvent(const QString& description, int code); - - //Private constructor, can only be called by 'Account' - explicit AccountStatusModel(Account* parent); - virtual ~AccountStatusModel(); - - AccountStatusModelPrivate* d_ptr; - Q_DECLARE_PRIVATE(AccountStatusModel) -}; -Q_DECLARE_METATYPE(AccountStatusModel*) diff --git a/src/bannedcontactmodel.cpp b/src/bannedcontactmodel.cpp index e3683593..f7306e8a 100644 --- a/src/bannedcontactmodel.cpp +++ b/src/bannedcontactmodel.cpp @@ -28,7 +28,6 @@ #include <contactrequest.h> #include <certificate.h> #include <account.h> -#include "private/pendingcontactrequestmodel_p.h" #include "person.h" #include "contactmethod.h" diff --git a/src/bootstrapmodel.cpp b/src/bootstrapmodel.cpp deleted file mode 100644 index 8fbaa757..00000000 --- a/src/bootstrapmodel.cpp +++ /dev/null @@ -1,446 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015-2018 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 "bootstrapmodel.h" - -//Qt -#include <QtCore/QDir> -#include <QtCore/QFile> -#include <QtCore/QDirIterator> -#include <QtCore/QJsonDocument> -#include <QtCore/QJsonArray> -#include <QtCore/QJsonObject> -#include <QtCore/QStandardPaths> - -//Ring daemon -#include <account_const.h> - -//Ring -#include "account.h" -#include "private/matrixutils.h" - -typedef void (BootstrapModelPrivate::*BootstrapModelPrivateFct)(); - -class BootstrapModelPrivate -{ -public: - struct Lines { - QString hostname; - int port ; - }; - - BootstrapModelPrivate(BootstrapModel* q,Account* a); - - //Callbacks - void clear (); - void reload (); - void save (); - void nothing (); - void modify (); - void reset (); - - //Helper - void clearLines(); - inline void performAction(const BootstrapModel::EditAction action); - QVector<Lines*> loadDefaultBootstrapServers(); - - //Attributes - Account* m_pAccount ; - QVector<Lines*> m_lines ; - BootstrapModel* q_ptr ; - BootstrapModel::EditState m_EditState; - static Matrix2D<BootstrapModel::EditState, BootstrapModel::EditAction, BootstrapModelPrivateFct> m_mStateMachine; -}; - -BootstrapModelPrivate::BootstrapModelPrivate(BootstrapModel* q,Account* a) : q_ptr(q),m_pAccount(a) -{ - -} - -#define BMP &BootstrapModelPrivate -Matrix2D<BootstrapModel::EditState, BootstrapModel::EditAction, BootstrapModelPrivateFct> BootstrapModelPrivate::m_mStateMachine ={{ - /* SAVE MODIFY RELOAD CLEAR RESET */ - /* LOADING */ {{ BMP::nothing, BMP::nothing, BMP::reload , BMP::nothing , BMP::nothing }}, - /* READY */ {{ BMP::nothing, BMP::modify , BMP::reload , BMP::clear, BMP::reset }}, - /* MODIFIED */ {{ BMP::save , BMP::nothing, BMP::reload , BMP::clear, BMP::reset }}, - /* OUTDATED */ {{ BMP::save , BMP::nothing, BMP::reload , BMP::clear, BMP::reset }}, - /* RELOADING */ {{ BMP::nothing, BMP::nothing, BMP::nothing, BMP::nothing, BMP::nothing }}, - /* RESETING */ {{ BMP::nothing, BMP::modify, BMP::nothing, BMP::nothing, BMP::nothing }}, -}}; -#undef BMP - - -void BootstrapModelPrivate::performAction(const BootstrapModel::EditAction action) -{ - (this->*(m_mStateMachine[m_EditState][action]))(); -} - -void BootstrapModelPrivate::nothing() -{ - //nothing -} - -void BootstrapModelPrivate::save() -{ - QString ret; - for(const Lines* l : m_lines) { - if (!l->hostname.trimmed().isEmpty()) { - if (ret.size()) - ret += ';'; - ret += l->hostname + (l->port > -1? ':'+QString::number(l->port):QString()); - } - } - - //Clear empty lines - for(int i=0;i<m_lines.size();i++) { - Lines* l = m_lines[i]; - if (l->hostname.isEmpty() && l->port == -1) { - q_ptr->beginRemoveRows(QModelIndex(),i,i); - const int idx = m_lines.indexOf(l); - if (idx >= 0) - m_lines.removeAt(idx); - q_ptr->endRemoveRows(); - } - } - - m_pAccount->setAccountProperty(DRing::Account::ConfProperties::HOSTNAME,ret); - m_EditState = BootstrapModel::EditState::READY; -} - -void BootstrapModelPrivate::modify() -{ - m_EditState = BootstrapModel::EditState::MODIFIED; - m_pAccount << Account::EditAction::MODIFY; -} - -void BootstrapModelPrivate::reload() -{ - m_EditState = BootstrapModel::EditState::RELOADING; - clearLines(); - - for(const QString& line : m_pAccount->hostname().split(';')) { - const QStringList& fields = line.split(':'); - - if (line.size() && fields.size() && !(fields[0].isEmpty() && (fields.size()-1 && fields[1].isEmpty()))) { - BootstrapModelPrivate::Lines* l = new BootstrapModelPrivate::Lines(); - l->hostname = fields[0].trimmed(); - l->port = fields.size()>1?fields[1].toInt():-1; //-1 == default - - q_ptr->beginInsertRows(QModelIndex(),m_lines.size(), m_lines.size()); - m_lines << l; - q_ptr->endInsertRows(); - } - } - m_EditState = BootstrapModel::EditState::READY; -} - -void BootstrapModelPrivate::clear() -{ - clearLines(); - q_ptr << BootstrapModel::EditAction::MODIFY; -} - -void BootstrapModelPrivate::clearLines() -{ - if (m_lines.size() > 0) - { - q_ptr->beginRemoveRows(QModelIndex(), 0, m_lines.size()); - for (int i = 0; i < m_lines.size(); i++) - delete m_lines[i]; - m_lines.clear(); - q_ptr->endRemoveRows(); - } -} - -QVector<BootstrapModelPrivate::Lines*> BootstrapModelPrivate::loadDefaultBootstrapServers() -{ - auto servers = QVector<BootstrapModelPrivate::Lines*>(); - - /* get the bootstrap directory */ - QString bootstrapDirPath = QStandardPaths::locate( - QStandardPaths::DataLocation, - "bootstrap", - QStandardPaths::LocateDirectory - ); - QDir bootstrapDir = QDir(bootstrapDirPath); - - auto bootstrapFiles = QVector<QFileInfo>(); - - // Main bootstrap servers file - auto mainBootstrapFile = QFileInfo(bootstrapDir.path() + "/servers.json"); - if (mainBootstrapFile.exists() && mainBootstrapFile.isFile()) - { - bootstrapFiles << mainBootstrapFile; - } - - // Secondary bootstrap servers files - auto secondaryBootstrapServersDir = QFileInfo(bootstrapDir.path() + "/servers.json.d/"); - if (secondaryBootstrapServersDir.exists() && secondaryBootstrapServersDir.isDir()) - { - QDirIterator dirIter( - secondaryBootstrapServersDir.path(), - QDirIterator::Subdirectories - ); - while (dirIter.hasNext()) { - dirIter.next(); - auto secBootstrapFileInfo = QFileInfo(dirIter.filePath()); - if (secBootstrapFileInfo.isFile() && secBootstrapFileInfo.suffix() == "json") - { - bootstrapFiles << secBootstrapFileInfo; - } - } - } - - //Parse JSON files - foreach(const auto fileInfo, bootstrapFiles) - { - QFile bootstrapFile(fileInfo.filePath()); - if (bootstrapFile.open(QIODevice::ReadOnly | QIODevice::Text)) - { - auto jsonDoc = QJsonDocument::fromJson(bootstrapFile.readAll()); - bootstrapFile.close(); - if (jsonDoc.isNull() == false && jsonDoc.isArray() == true) - { - QJsonArray jsonArray = jsonDoc.array(); - foreach(const auto jsonValue, jsonArray) - { - auto hostObject = jsonValue.toObject(); - auto hostValue = hostObject.value("host"); - auto portValue = hostObject.value("port"); - - if (hostValue.isUndefined() == false && - hostValue.isString() && - portValue.isUndefined() == false && - portValue.isDouble()) - { - BootstrapModelPrivate::Lines* server = new BootstrapModelPrivate::Lines(); - server->hostname = hostValue.toString(); - server->port = portValue.toInt(-1); - servers << server; - } - } - } - } - } - - return servers; -} - -BootstrapModel::BootstrapModel(Account* a) : QAbstractTableModel(a), d_ptr(new BootstrapModelPrivate(this,a)) -{ - d_ptr->m_EditState = BootstrapModel::EditState::LOADING; - this << EditAction::RELOAD; -} - -BootstrapModel::~BootstrapModel() -{ - delete d_ptr; -} - -QHash<int,QByteArray> BootstrapModel::roleNames() const -{ - static QHash<int, QByteArray> roles = QAbstractItemModel::roleNames(); - /*static bool initRoles = false; - if (!initRoles) { - initRoles = true; - }*/ - return roles; -} - -//DEPRECATED -void BootstrapModel::reset() -{ - this << EditAction::RESET; -} - -bool BootstrapModel::setData( const QModelIndex& index, const QVariant &value, int role) -{ - if (!index.isValid()) - return false; - - BootstrapModelPrivate::Lines* l = index.row() < d_ptr->m_lines.size() ? d_ptr->m_lines[index.row()] : nullptr; - - if (!(role == Qt::DisplayRole || role == Qt::EditRole)) - return false; - - if (!l) { - l = new BootstrapModelPrivate::Lines(); - l->port = -1; - beginInsertRows(QModelIndex(),d_ptr->m_lines.size(), d_ptr->m_lines.size()); - d_ptr->m_lines << l; - endInsertRows(); - } - - switch (static_cast<BootstrapModel::Columns>(index.column())) { - case BootstrapModel::Columns::HOSTNAME: - l->hostname = value.toString(); - d_ptr->save(); - emit dataChanged(index,index); - break; - case BootstrapModel::Columns::PORT: - l->port = value.toInt(); - - if (l->port <= 0 || l->port > 65534) { - l->port = -1; - d_ptr->save(); - emit dataChanged(index,index); - } - - break; - } - - this << EditAction::MODIFY; - - return true; -} - -QVariant BootstrapModel::data( const QModelIndex& index, int role) const -{ - Q_UNUSED(role); - - if (!index.isValid()) - return QVariant(); - - BootstrapModelPrivate::Lines* l = index.row() < d_ptr->m_lines.size() ?d_ptr->m_lines[index.row()] : nullptr; - - if (!l) - return QVariant(); - - switch (static_cast<BootstrapModel::Columns>(index.column())) { - case BootstrapModel::Columns::PORT: - return QVariant(l->port == -1?QVariant():l->port); - case BootstrapModel::Columns::HOSTNAME: - return l->hostname; - }; - - return QVariant(); -} - -int BootstrapModel::rowCount( const QModelIndex& parent) const -{ - return parent.isValid()?0:d_ptr->m_lines.size()+1; //Add one for new entries -} - -int BootstrapModel::columnCount( const QModelIndex& parent) const -{ - return parent.isValid()?0:2; -} - -bool BootstrapModel::removeRows(int row, int count, const QModelIndex& parent) -{ - if (parent.isValid()) - return false; - - if ((row+count) > d_ptr->m_lines.size()) - return false; - - this->beginRemoveRows(QModelIndex(), row, row+count-1); - - for (int i = 0; i < count; i++) - { - BootstrapModelPrivate::Lines* l = d_ptr->m_lines[row+i]; - d_ptr->m_lines.remove(row); - delete l; - } - - d_ptr->save(); - this->endRemoveRows(); - - return true; -} - -Qt::ItemFlags BootstrapModel::flags( const QModelIndex& index) const -{ - return index.isValid() ? (Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable) : Qt::NoItemFlags; -} - -QVariant BootstrapModel::headerData( int section, Qt::Orientation ori, int role) const -{ - if (role == Qt::DisplayRole) { - if (ori == Qt::Vertical) - return section; - - switch (section) { - case static_cast<int>(BootstrapModel::Columns::HOSTNAME): - return tr("Hostname"); - case static_cast<int>(BootstrapModel::Columns::PORT): - return tr("Port"); - } - } - return QVariant(); -} - -bool BootstrapModel::isCustom() const -{ - for (const BootstrapModelPrivate::Lines* line : d_ptr->m_lines) { - if (line->hostname.size() && line->hostname != "bootstrap.ring.cx") - return true; - } - - return false; -} - -void BootstrapModelPrivate::reset() -{ - m_EditState = BootstrapModel::EditState::RESETING; - - clearLines(); - - auto defaultBootStrapServers = loadDefaultBootstrapServers(); - if (defaultBootStrapServers.size() >= 1) - { - q_ptr->beginInsertRows( - QModelIndex(), - m_lines.size(), - m_lines.size() + defaultBootStrapServers.size() - 1 - ); - m_lines << defaultBootStrapServers; - q_ptr->endInsertRows(); - } - else - { - /* If we can't load anything from file, default to bootstrap.ring.cx */ - BootstrapModelPrivate::Lines* l = new BootstrapModelPrivate::Lines(); - l->hostname = "bootstrap.ring.cx"; - l->port = -1; - - q_ptr->beginInsertRows(QModelIndex(), m_lines.size(), m_lines.size()); - m_lines << l; - q_ptr->endInsertRows(); - } - - q_ptr << BootstrapModel::EditAction::MODIFY; -} - -BootstrapModel* BootstrapModel::operator<<(BootstrapModel::EditAction& action) -{ - performAction(action); - return this; -} - -BootstrapModel* operator<<(BootstrapModel* a, BootstrapModel::EditAction action) -{ - return (!a)?nullptr : (*a) << action; -} - -///Change the current edition state -bool BootstrapModel::performAction(const BootstrapModel::EditAction action) -{ - BootstrapModel::EditState curState = d_ptr->m_EditState; - d_ptr->performAction(action); - return curState != d_ptr->m_EditState; -} diff --git a/src/bootstrapmodel.h b/src/bootstrapmodel.h deleted file mode 100644 index 0b942e1d..00000000 --- a/src/bootstrapmodel.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015-2018 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/>. * - ***************************************************************************/ -#pragma once - -#include <QtCore/QAbstractTableModel> - -#include <typedefs.h> - -class Account; - -class BootstrapModelPrivate; - -class LIB_EXPORT BootstrapModel : public QAbstractTableModel -{ - Q_OBJECT -public: - friend class Account; - - enum class Columns { - HOSTNAME, - PORT, - }; - - /// @enum BootstrapModel::EditAction Manage a BootstrapModel lifecycle - enum class EditAction { - SAVE = 0, /*!< Save the model, if there is a conflict, use "ours" */ - MODIFY = 1, /*!< Notify the state machine that the data has changed */ - RELOAD = 2, /*!< Reload from the account hostname, if there is a conflict, use "their" */ - CLEAR = 3, /*!< Remove all bootstrap servers */ - RESET = 4, /*!< Reset the model with default servers */ - COUNT__ - }; - - /// @enum BootstrapModel::EditState track the changes from both clients and daemon - enum class EditState { - LOADING = 0, /*!< The bootstrap servers are being loaded, they are not ready yet */ - READY = 1, /*!< Both side are synchronized */ - MODIFIED = 2, /*!< Our version differ from the remote one */ - OUTDATED = 3, /*!< The remote version differ from ours */ - RELOADING = 4, /*!< During a reload */ - RESETING = 5, /*!< During a reset */ - COUNT__ - }; - - virtual bool setData ( const QModelIndex& index, const QVariant &value, int role ) override; - virtual QVariant data ( const QModelIndex& index, int role = Qt::DisplayRole ) const override; - virtual int rowCount ( const QModelIndex& parent = QModelIndex() ) const override; - virtual bool removeRows ( int row, int count, const QModelIndex& parent = QModelIndex()) override; - virtual Qt::ItemFlags flags ( const QModelIndex& index ) const override; - virtual int columnCount ( const QModelIndex& parent = QModelIndex() ) const override; - virtual QVariant headerData ( int section, Qt::Orientation, int role = Qt::DisplayRole ) const override; - virtual QHash<int,QByteArray> roleNames() const override; - - //Getter - bool isCustom () const; - BootstrapModel::EditState editState () const; - - //Mutator - void reset ( ); // DEPRECATED - bool performAction ( BootstrapModel::EditAction action ); - - //Operator - BootstrapModel* operator<<(BootstrapModel::EditAction& action); - - void reload(); - -private: - explicit BootstrapModel(Account* a); - virtual ~BootstrapModel(); - - BootstrapModelPrivate* d_ptr; - Q_DECLARE_PRIVATE(BootstrapModel) - -}; - -BootstrapModel LIB_EXPORT *operator<<(BootstrapModel* a, BootstrapModel::EditAction action); diff --git a/src/call.cpp b/src/call.cpp index 87bb67f6..cec6a7d8 100644 --- a/src/call.cpp +++ b/src/call.cpp @@ -51,7 +51,6 @@ #include "private/videorenderermanager.h" #include "localrecordingcollection.h" #include "categorizedhistorymodel.h" -#include "useractionmodel.h" #include "callmodel.h" #include "certificate.h" #include "numbercategory.h" @@ -292,7 +291,7 @@ m_PeerName(),m_pPeerContactMethod(nullptr),m_HistoryConst(HistoryTimeCategoryMod m_pStartTimeStamp(0), m_pDialNumber(new TemporaryContactMethod()), m_History(false),m_Missed(false),m_Direction(Call::Direction::OUTGOING),m_Type(Call::Type::CALL), -m_pUserActionModel(nullptr), m_CurrentState(Call::State::ERROR),m_pCertificate(nullptr),m_mMedias({{ +m_CurrentState(Call::State::ERROR),m_pCertificate(nullptr),m_mMedias({{ /* IN OUT */ /* AUDIO */ {{ new QList<media::Media*>() /*Created lifecycle == progress*/, new QList<media::Media*>() /*Created lifecycle == progress*/}}, /* VIDEO */ {{ new QList<media::Media*>() /*On demand */, new QList<media::Media*>() /*On demand */}}, @@ -2194,13 +2193,6 @@ void CallPrivate::refuseAfterFailure() } } -UserActionModel* Call::userActionModel() const -{ - if (!d_ptr->m_pUserActionModel) - d_ptr->m_pUserActionModel = new UserActionModel(const_cast<Call*>(this)); - return d_ptr->m_pUserActionModel; -} - ///Check if creating a timer is necessary void CallPrivate::initTimer() { diff --git a/src/call.h b/src/call.h index b5b5ca28..4a29b30b 100644 --- a/src/call.h +++ b/src/call.h @@ -33,7 +33,6 @@ class QTimer; #include "itemdataroles.h" class Account ; class InstantMessagingModel ; -class UserActionModel ; class ContactMethod ; class TemporaryContactMethod; class CollectionInterface ; @@ -279,7 +278,6 @@ public: Q_PROPERTY( QString formattedName READ formattedName ) Q_PROPERTY( QString length READ length ) Q_PROPERTY( bool recordingAV READ isAVRecording ) - Q_PROPERTY( UserActionModel* userActionModel READ userActionModel CONSTANT ) Q_PROPERTY( QString toHumanStateName READ toHumanStateName ) Q_PROPERTY( bool missed READ isMissed ) Q_PROPERTY( Direction direction READ direction ) @@ -315,7 +313,6 @@ public: Video::Renderer* videoRenderer () const; const QString formattedName () const; QString length () const; - UserActionModel* userActionModel () const; QString toHumanStateName () const; bool isMissed () const; Call::Direction direction () const; diff --git a/src/callmodel.cpp b/src/callmodel.cpp index 6c1a093e..c3caafda 100644 --- a/src/callmodel.cpp +++ b/src/callmodel.cpp @@ -47,7 +47,6 @@ #include "globalinstances.h" #include "interfaces/contactmethodselectori.h" #include "personmodel.h" -#include "useractionmodel.h" #include "video/renderer.h" #include "media/audio.h" #include "media/video.h" @@ -94,8 +93,6 @@ public: QHash< Call* , InternalStruct* > m_shInternalMapping ; QHash< QString , InternalStruct* > m_shDringId ; QItemSelectionModel* m_pSelectionModel; - UserActionModel* m_pUserActionModel; - //Helpers bool isPartOf(const QModelIndex& confIdx, Call* call); @@ -144,8 +141,7 @@ CallModel& CallModel::instance() return *instance; } -CallModelPrivate::CallModelPrivate(CallModel* parent) : QObject(parent),q_ptr(parent),m_pSelectionModel(nullptr), -m_pUserActionModel(nullptr) +CallModelPrivate::CallModelPrivate(CallModel* parent) : QObject(parent),q_ptr(parent),m_pSelectionModel(nullptr) { } @@ -389,15 +385,6 @@ bool CallModel::isValid() return CallManager::instance().isValid(); } - -UserActionModel* CallModel::userActionModel() const -{ - if (!d_ptr->m_pUserActionModel) - d_ptr->m_pUserActionModel = new UserActionModel(const_cast<CallModel*>(this)); - return d_ptr->m_pUserActionModel; -} - - /***************************************************************************** * * * Call related code * diff --git a/src/callmodel.h b/src/callmodel.h index 92c61c80..72afe876 100644 --- a/src/callmodel.h +++ b/src/callmodel.h @@ -77,7 +77,6 @@ public: Q_PROPERTY(bool hasConference READ hasConference ) Q_PROPERTY(bool isConnected READ isConnected ) Q_PROPERTY(Call* selectedCall READ selectedCall ) - Q_PROPERTY(UserActionModel* userActionModel READ userActionModel CONSTANT) //Call related Q_INVOKABLE Call* dialingCall ( const QString& peerName=QString(), Account* account=nullptr, Call* parent = nullptr ); @@ -104,7 +103,6 @@ public: int size (); bool hasConference () const; bool isConnected () const; - UserActionModel* userActionModel () const; Q_INVOKABLE QItemSelectionModel* selectionModel() const; Q_INVOKABLE Call* getCall ( const QModelIndex& idx ) const; diff --git a/src/categorizedhistorymodel.cpp b/src/categorizedhistorymodel.cpp index d480e0ed..db92aa75 100644 --- a/src/categorizedhistorymodel.cpp +++ b/src/categorizedhistorymodel.cpp @@ -35,7 +35,6 @@ #include "callmodel.h" #include "collectioneditor.h" #include "historytimecategorymodel.h" -#include "lastusednumbermodel.h" #include "collectioninterface.h" /***************************************************************************** @@ -266,7 +265,6 @@ void CategorizedHistoryModelPrivate::add(Call* call) m_sHistoryCalls[(call->startTimeStamp() << 10)+qrand()%1024] = call; q_ptr->endInsertRows(); - LastUsedNumberModel::instance().addCall(call); emit q_ptr->historyChanged(); //When the categories goes from 0 items to many, its conceptual state change diff --git a/src/codecmodel.cpp b/src/codecmodel.cpp deleted file mode 100644 index 752b4532..00000000 --- a/src/codecmodel.cpp +++ /dev/null @@ -1,631 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2012-2018 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 "codecmodel.h" - -//Qt -#include <QtCore/QDebug> -#include <QtCore/QCoreApplication> -#include <QtCore/QSortFilterProxyModel> -#include <QtCore/QItemSelectionModel> -#include <QMimeData> - -//DRing -#include <account_const.h> - -//Ring -#include "account.h" -#include "dbus/configurationmanager.h" -#include "mime.h" -#include "callmodel.h" -#include <private/matrixutils.h> - -typedef void (CodecModelPrivate::*CodecModelFct)(); - -class CodecModelPrivate final : public QObject -{ - Q_OBJECT -public: - CodecModelPrivate(CodecModel* parent); - ///@struct CodecData store audio/video codec information - struct CodecData { - int id ; - QString name ; - QString bitrate ; - QString min_bitrate; - QString max_bitrate; - QString samplerate ; - QString type ; - QString quality ; - QString min_quality; - QString max_quality; - QString auto_quality_enabled; - }; - - //Attributes - QList<CodecData*> m_lCodecs ; - QMap<int,bool> m_lEnabledCodecs ; - Account* m_pAccount ; - QSortFilterProxyModel* m_pAudioProxy ; - QSortFilterProxyModel* m_pVideoProxy ; - QStringList m_lMimes ; - QItemSelectionModel* m_pSelectionModel; - CodecModel::EditState m_EditState ; - static Matrix2D<CodecModel::EditState, CodecModel::EditAction,CodecModelFct> m_mStateMachine; - - //Callbacks - QModelIndex add ( ); - void remove ( const QModelIndex& idx ); - void clear ( ); - void reload ( ); - void save ( ); - void nothing ( ); - void modify ( ); - - //Helpers - bool findCodec(int id); - QModelIndex getIndexofCodecByID(int id); - inline void performAction(const CodecModel::EditAction action); - -private: - CodecModel* q_ptr; -}; - -#define CMP &CodecModelPrivate -Matrix2D<CodecModel::EditState, CodecModel::EditAction,CodecModelFct> CodecModelPrivate::m_mStateMachine ={{ - /* SAVE MODIFY RELOAD CLEAR */ - /* LOADING */ {{ CMP::nothing, CMP::nothing, CMP::reload , CMP::nothing }}, - /* READY */ {{ CMP::nothing, CMP::modify , CMP::reload , CMP::clear }}, - /* MODIFIED */ {{ CMP::save , CMP::nothing, CMP::reload , CMP::clear }}, - /* OUTDATED */ {{ CMP::save , CMP::nothing, CMP::reload , CMP::clear }}, - /* RELOADING */ {{ CMP::nothing, CMP::nothing, CMP::nothing, CMP::nothing }}, -}}; -#undef CMP - -CodecModelPrivate::CodecModelPrivate(CodecModel* parent) : q_ptr(parent), -m_pAudioProxy(nullptr),m_pVideoProxy(nullptr),m_pSelectionModel(nullptr) -{ - -} - -///Constructor -CodecModel::CodecModel(Account* account) : -QAbstractListModel(account?(QObject*)account:(QObject*)QCoreApplication::instance()), d_ptr(new CodecModelPrivate(this)) -{ - Q_ASSERT(account); - d_ptr->m_EditState = CodecModel::EditState::LOADING; - d_ptr->m_pAccount = account; - - // New accounts don't have ID yet, avoid a warning - if (account && !account->isNew()) - setObjectName("CodecModel: "+(account?account->id():"Unknown")); - - d_ptr->m_lMimes << RingMimes::AUDIO_CODEC << RingMimes::VIDEO_CODEC; - this << EditAction::RELOAD; - d_ptr->m_EditState = CodecModel::EditState::READY; -} - -CodecModel::~CodecModel() -{ - while (d_ptr->m_lCodecs.size()) { - CodecModelPrivate::CodecData* c = d_ptr->m_lCodecs[0]; - d_ptr->m_lCodecs.removeAt(0); - delete c; - } -} - -QHash<int,QByteArray> CodecModel::roleNames() const -{ - static QHash<int, QByteArray> roles = QAbstractItemModel::roleNames(); - static bool initRoles = false; - if (!initRoles) { - initRoles = true; - roles.insert(CodecModel::Role::ID ,QByteArray("id")); - roles.insert(CodecModel::Role::NAME ,QByteArray("name")); - roles.insert(CodecModel::Role::BITRATE ,QByteArray("bitrate")); - roles.insert(CodecModel::Role::MIN_BITRATE,QByteArray("min_bitrate")); - roles.insert(CodecModel::Role::MAX_BITRATE,QByteArray("max_bitrate")); - roles.insert(CodecModel::Role::SAMPLERATE ,QByteArray("samplerate")); - roles.insert(CodecModel::Role::TYPE ,QByteArray("type")); - roles.insert(CodecModel::Role::QUALITY ,QByteArray("quality")); - roles.insert(CodecModel::Role::MIN_QUALITY,QByteArray("min_quality")); - roles.insert(CodecModel::Role::MAX_QUALITY,QByteArray("max_quality")); - roles.insert(CodecModel::Role::AUTO_QUALITY_ENABLED,QByteArray("autoQualityEnabled")); - } - return roles; -} - -QItemSelectionModel* CodecModel::selectionModel() const -{ - if (!d_ptr->m_pSelectionModel) - d_ptr->m_pSelectionModel = new QItemSelectionModel(const_cast<CodecModel*>(this)); - return d_ptr->m_pSelectionModel; -} - -///Model data -QVariant CodecModel::data(const QModelIndex& idx, int role) const -{ - if (idx.column() != 0) - return QVariant(); - - switch (role) { - case Qt::DisplayRole: - return QVariant(d_ptr->m_lCodecs[idx.row()]->name); - case Qt::CheckStateRole: - return QVariant(d_ptr->m_lEnabledCodecs[d_ptr->m_lCodecs[idx.row()]->id] ? Qt::Checked : Qt::Unchecked); - case CodecModel::Role::NAME: - return d_ptr->m_lCodecs[idx.row()]->name; - case CodecModel::Role::BITRATE: - return d_ptr->m_lCodecs[idx.row()]->bitrate; - case CodecModel::Role::MIN_BITRATE: - return d_ptr->m_lCodecs[idx.row()]->min_bitrate; - case CodecModel::Role::MAX_BITRATE: - return d_ptr->m_lCodecs[idx.row()]->max_bitrate; - case CodecModel::Role::SAMPLERATE: - return d_ptr->m_lCodecs[idx.row()]->samplerate; - case CodecModel::Role::ID: - return d_ptr->m_lCodecs[idx.row()]->id; - case CodecModel::Role::TYPE: - return d_ptr->m_lCodecs[idx.row()]->type; - case CodecModel::Role::QUALITY: - return d_ptr->m_lCodecs[idx.row()]->quality; - case CodecModel::Role::MIN_QUALITY: - return d_ptr->m_lCodecs[idx.row()]->min_quality; - case CodecModel::Role::MAX_QUALITY: - return d_ptr->m_lCodecs[idx.row()]->max_quality; - case CodecModel::Role::AUTO_QUALITY_ENABLED: - return d_ptr->m_lCodecs[idx.row()]->auto_quality_enabled; - default: - return QVariant(); - } - return QVariant(); -} - -///Number of audio codecs -int CodecModel::rowCount(const QModelIndex& par) const -{ - return par.isValid() ? 0 : d_ptr->m_lCodecs.size(); -} - -///Model flags -Qt::ItemFlags CodecModel::flags(const QModelIndex& idx) const -{ - if (idx.column() == 0) - return QAbstractItemModel::flags(idx) | Qt::ItemIsUserCheckable - | Qt::ItemIsEnabled - | Qt::ItemIsSelectable - | Qt::ItemIsDragEnabled - | Qt::ItemIsDropEnabled; - return QAbstractItemModel::flags(idx); -} - -///Set audio codec data -bool CodecModel::setData( const QModelIndex& idx, const QVariant &value, int role) -{ - if (idx.column() != 0) - return false; - - switch (role) { - case CodecModel::NAME : - d_ptr->m_lCodecs[idx.row()]->name = value.toString(); - break; - case CodecModel::BITRATE : - d_ptr->m_lCodecs[idx.row()]->bitrate = value.toString(); - break; - case CodecModel::MIN_BITRATE : - d_ptr->m_lCodecs[idx.row()]->min_bitrate = value.toString(); - break; - case CodecModel::MAX_BITRATE : - d_ptr->m_lCodecs[idx.row()]->max_bitrate = value.toString(); - break; - case Qt::CheckStateRole : - d_ptr->m_lEnabledCodecs[d_ptr->m_lCodecs[idx.row()]->id] = value.toBool(); - break; - case CodecModel::SAMPLERATE : - d_ptr->m_lCodecs[idx.row()]->samplerate = value.toString(); - break; - case CodecModel::ID : - d_ptr->m_lCodecs[idx.row()]->id = value.toInt(); - break; - case CodecModel::TYPE : - d_ptr->m_lCodecs[idx.row()]->type = value.toString(); - break; - case CodecModel::QUALITY : - d_ptr->m_lCodecs[idx.row()]->quality = value.toString(); - break; - case CodecModel::MIN_QUALITY : - d_ptr->m_lCodecs[idx.row()]->min_quality = value.toString(); - break; - case CodecModel::MAX_QUALITY : - d_ptr->m_lCodecs[idx.row()]->max_quality = value.toString(); - break; - case CodecModel::AUTO_QUALITY_ENABLED : - d_ptr->m_lCodecs[idx.row()]->auto_quality_enabled = value.toString(); - break; - default: - return false; - } - - //if we did not return yet, then we modified the codec - emit dataChanged(idx, idx); - this << EditAction::MODIFY; - return true; -} - -///Add a new audio codec -QModelIndex CodecModelPrivate::add() -{ - q_ptr->beginInsertRows(QModelIndex(), m_lCodecs.size()-1, m_lCodecs.size()-1); - m_lCodecs << new CodecModelPrivate::CodecData; - q_ptr->endInsertRows(); - emit q_ptr->dataChanged(q_ptr->index(m_lCodecs.size()-1,0), q_ptr->index(m_lCodecs.size()-1,0)); - q_ptr << CodecModel::EditAction::MODIFY; - return q_ptr->index(m_lCodecs.size()-1,0); -} - -///Remove audio codec at 'idx' -void CodecModelPrivate::remove(const QModelIndex& idx) -{ - if (idx.isValid()) { - q_ptr->beginRemoveRows(QModelIndex(), idx.row(), idx.row()); - CodecModelPrivate::CodecData* d = m_lCodecs[idx.row()]; - m_lCodecs.removeAt(idx.row()); - delete d; - q_ptr->endRemoveRows(); - emit q_ptr->dataChanged(idx, q_ptr->index(m_lCodecs.size()-1,0)); - q_ptr << CodecModel::EditAction::MODIFY; - } - else { - qDebug() << "Failed to remove an invalid audio codec"; - } -} - -///Remove everything -void CodecModelPrivate::clear() -{ - while(m_lCodecs.size()) { - CodecModelPrivate::CodecData* d = m_lCodecs[0]; - m_lCodecs.removeAt(0); - delete d; - } - m_lCodecs.clear(); - m_lEnabledCodecs.clear(); - m_EditState = CodecModel::EditState::READY; -} - -///Reload the codeclist -void CodecModelPrivate::reload() -{ - m_EditState = CodecModel::EditState::RELOADING; - - ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance(); - QVector<uint> codecIdList = configurationManager.getCodecList(); - - QVector<uint> activeCodecList = m_pAccount->isNew() ? codecIdList : - configurationManager.getActiveCodecList(m_pAccount->id()); - - QStringList tmpNameList; - - //TODO: the following method cannot update the order of the codecs if it - // changes in the daemon after it has been initially loaded in the client - - // load the active codecs first to get the correct order - foreach (const int aCodec, activeCodecList) { - - const QMap<QString,QString> codec = configurationManager.getCodecDetails( - m_pAccount->isNew()? QString() : m_pAccount->id(), aCodec - ); - - if (!findCodec(aCodec)) { - const QModelIndex& idx = add(); - q_ptr->setData(idx,QString::number(aCodec), CodecModel::Role::ID); - } - - // update the codec - - const auto& idx = getIndexofCodecByID(aCodec); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::NAME ] ,CodecModel::Role::NAME ); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::SAMPLE_RATE ] ,CodecModel::Role::SAMPLERATE ); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::BITRATE ] ,CodecModel::Role::BITRATE ); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::MIN_BITRATE ] ,CodecModel::Role::MIN_BITRATE); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::MAX_BITRATE ] ,CodecModel::Role::MAX_BITRATE); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::TYPE ] ,CodecModel::Role::TYPE ); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::QUALITY ] ,CodecModel::Role::QUALITY ); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::MIN_QUALITY ] ,CodecModel::Role::MIN_QUALITY); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::MAX_QUALITY ] ,CodecModel::Role::MAX_QUALITY); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::AUTO_QUALITY_ENABLED] ,CodecModel::Role::AUTO_QUALITY_ENABLED); - q_ptr->setData(idx, Qt::Checked ,Qt::CheckStateRole); - - // remove from list of all codecs, since we have already updated it - if (codecIdList.indexOf(aCodec)!=-1) - codecIdList.remove(codecIdList.indexOf(aCodec)); - } - - // now add add/update remaining (inactive) codecs - foreach (const int aCodec, codecIdList) { - - const QMap<QString,QString> codec = configurationManager.getCodecDetails( - m_pAccount->isNew()? QString() : m_pAccount->id(), aCodec - ); - - if (!findCodec(aCodec)) { - const QModelIndex& idx = add(); - q_ptr->setData(idx,QString::number(aCodec), CodecModel::Role::ID); - } - - // update the codec - const auto& idx = getIndexofCodecByID(aCodec); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::NAME ] ,CodecModel::Role::NAME ); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::SAMPLE_RATE ] ,CodecModel::Role::SAMPLERATE ); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::BITRATE ] ,CodecModel::Role::BITRATE ); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::MIN_BITRATE ] ,CodecModel::Role::MIN_BITRATE); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::MAX_BITRATE ] ,CodecModel::Role::MAX_BITRATE); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::TYPE ] ,CodecModel::Role::TYPE ); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::QUALITY ] ,CodecModel::Role::QUALITY ); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::MIN_QUALITY ] ,CodecModel::Role::MIN_QUALITY); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::MAX_QUALITY ] ,CodecModel::Role::MAX_QUALITY); - q_ptr->setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::AUTO_QUALITY_ENABLED] ,CodecModel::Role::AUTO_QUALITY_ENABLED); - q_ptr->setData(idx, Qt::Unchecked ,Qt::CheckStateRole); - } - - m_EditState = CodecModel::EditState::READY; -} - -///Save details -void CodecModelPrivate::save() -{ - //TODO there is a race condition, the account has to be saved first - - //Update active codec list - VectorUInt _codecList; - for (int i = 0; i < q_ptr->rowCount();i++) { - const QModelIndex& idx = q_ptr->index(i,0); - if (q_ptr->data(idx,Qt::CheckStateRole) == Qt::Checked) { - _codecList << q_ptr->data(idx,CodecModel::Role::ID).toInt(); - } - } - - ConfigurationManagerInterface& configurationManager = ConfigurationManager::instance(); - configurationManager.setActiveCodecList(m_pAccount->id(), _codecList); - - //Update codec details - for (int i=0; i < q_ptr->rowCount();i++) { - const QModelIndex& idx = q_ptr->index(i,0); - MapStringString codecDetails; - codecDetails[ DRing::Account::ConfProperties::CodecInfo::NAME ] = q_ptr->data(idx,CodecModel::Role::NAME).toString(); - codecDetails[ DRing::Account::ConfProperties::CodecInfo::SAMPLE_RATE ] = q_ptr->data(idx,CodecModel::Role::SAMPLERATE).toString(); - codecDetails[ DRing::Account::ConfProperties::CodecInfo::BITRATE ] = q_ptr->data(idx,CodecModel::Role::BITRATE).toString(); - codecDetails[ DRing::Account::ConfProperties::CodecInfo::MIN_BITRATE ] = q_ptr->data(idx,CodecModel::Role::MIN_BITRATE).toString(); - codecDetails[ DRing::Account::ConfProperties::CodecInfo::MAX_BITRATE ] = q_ptr->data(idx,CodecModel::Role::MAX_BITRATE).toString(); - codecDetails[ DRing::Account::ConfProperties::CodecInfo::TYPE ] = q_ptr->data(idx,CodecModel::Role::TYPE).toString(); - codecDetails[ DRing::Account::ConfProperties::CodecInfo::QUALITY ] = q_ptr->data(idx,CodecModel::Role::QUALITY).toString(); - codecDetails[ DRing::Account::ConfProperties::CodecInfo::MIN_QUALITY ] = q_ptr->data(idx,CodecModel::Role::MIN_QUALITY).toString(); - codecDetails[ DRing::Account::ConfProperties::CodecInfo::MAX_QUALITY ] = q_ptr->data(idx,CodecModel::Role::MAX_QUALITY).toString(); - codecDetails[ DRing::Account::ConfProperties::CodecInfo::AUTO_QUALITY_ENABLED] = q_ptr->data(idx,CodecModel::Role::AUTO_QUALITY_ENABLED).toString(); - - qDebug() << "setting codec details for " << q_ptr->data(idx,CodecModel::Role::NAME).toString(); - - configurationManager.setCodecDetails(m_pAccount->id(), q_ptr->data(idx,CodecModel::Role::ID).toUInt(), codecDetails); - } - m_EditState = CodecModel::EditState::READY; -} - -void CodecModelPrivate::nothing() -{ - //nothing -} - -void CodecModelPrivate::modify() -{ - m_EditState = CodecModel::EditState::MODIFIED; - m_pAccount << Account::EditAction::MODIFY; -} - -void CodecModelPrivate::performAction(const CodecModel::EditAction action) -{ - (this->*(m_mStateMachine[m_EditState][action]))();//FIXME don't use integer cast -} - -CodecModel* CodecModel::operator<<(CodecModel::EditAction& action) -{ - performAction(action); - return this; -} - -CodecModel* operator<<(CodecModel* a, CodecModel::EditAction action) -{ - return (!a)?nullptr : (*a) << action; -} - -///Change the current edition state -bool CodecModel::performAction(const CodecModel::EditAction action) -{ - CodecModel::EditState curState = d_ptr->m_EditState; - d_ptr->performAction(action); - return curState != d_ptr->m_EditState; -} - -///Move a codec up in the priority list (using the selectionModel) -bool CodecModel::moveUp() -{ - if (d_ptr->m_pSelectionModel) { - const QModelIndex& idx = d_ptr->m_pSelectionModel->currentIndex(); - if (dropMimeData(mimeData({idx}), Qt::MoveAction, idx.row()-1, idx.column(),idx.parent())) { - d_ptr->m_pSelectionModel->setCurrentIndex(index(idx.row()-1,idx.column()), QItemSelectionModel::ClearAndSelect); - return true; - } - } - return false; -} - -///Move a codec down in the priority list (using the selectionModel) -bool CodecModel::moveDown() -{ - if (d_ptr->m_pSelectionModel) { - const QModelIndex& idx = d_ptr->m_pSelectionModel->currentIndex(); - if (dropMimeData(mimeData({idx}), Qt::MoveAction, idx.row()+1, idx.column(),idx.parent())) { - d_ptr->m_pSelectionModel->setCurrentIndex(index(idx.row()+1,idx.column()), QItemSelectionModel::ClearAndSelect); - return true; - } - } - return false; -} - -///Check is a codec is already in the list -bool CodecModelPrivate::findCodec(int id) -{ - foreach(const CodecData* data, m_lCodecs) { - if (data->id == id) - return true; - } - return false; -} - -///Return valid payload types -int CodecModel::acceptedPayloadTypes() const -{ - return CallModel::DropPayloadType::AUDIO_CODEC | CallModel::DropPayloadType::VIDEO_CODEC; -} - - -QSortFilterProxyModel* CodecModel::videoCodecs() const -{ - if (!d_ptr->m_pVideoProxy) { - d_ptr->m_pVideoProxy = new QSortFilterProxyModel(const_cast<CodecModel*>(this)); - d_ptr->m_pVideoProxy->setSourceModel(const_cast<CodecModel*>(this)); - d_ptr->m_pVideoProxy->setFilterRole(CodecModel::Role::TYPE); - d_ptr->m_pVideoProxy->setFilterFixedString("VIDEO"); - } - return d_ptr->m_pVideoProxy; -} - - -QSortFilterProxyModel* CodecModel::audioCodecs() const -{ - if (!d_ptr->m_pAudioProxy) { - d_ptr->m_pAudioProxy = new QSortFilterProxyModel(const_cast<CodecModel*>(this)); - d_ptr->m_pAudioProxy->setSourceModel(const_cast<CodecModel*>(this)); - d_ptr->m_pAudioProxy->setFilterRole(CodecModel::Role::TYPE); - d_ptr->m_pAudioProxy->setFilterFixedString("AUDIO"); - } - return d_ptr->m_pAudioProxy; -} - -// ======== DnD Api ========= - -QModelIndex CodecModelPrivate::getIndexofCodecByID(int id) -{ - for (int i=0; i < q_ptr->rowCount();i++) { - const QModelIndex& idx = q_ptr->index(i,0); - if (q_ptr->data(idx, CodecModel::Role::ID) == id) - return idx; - } - return QModelIndex(); -} - -QStringList CodecModel::mimeTypes() const -{ - return d_ptr->m_lMimes; -} - -bool CodecModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) -{ - Q_UNUSED(action) - if(parent.isValid() || column > 0) { - qDebug() << "column invalid"; - return false; - } - - if (data->hasFormat(RingMimes::AUDIO_CODEC) || data->hasFormat(RingMimes::VIDEO_CODEC)) { - int destinationRow = -1; - - if(row < 0) { - //drop on top - destinationRow = d_ptr->m_lCodecs.size() - 1; - } - else if(row >= d_ptr->m_lCodecs.size()) { - destinationRow = 0; - } - else if(data->hasFormat(RingMimes::VIDEO_CODEC) && row >= rowCount()) { - destinationRow = 0; - } - else { - destinationRow = row; - } - - const int codecId = data->data(data->hasFormat(RingMimes::AUDIO_CODEC) - ? RingMimes::AUDIO_CODEC - : RingMimes::VIDEO_CODEC).toInt(); - - const QModelIndex codecIdx = d_ptr->getIndexofCodecByID(codecId); - -#ifdef Q_OS_WIN - /* To understand why qtDestinationRow is needed - http://doc.qt.io/qt-5/qabstractitemmodel.html#beginMoveRows */ - auto qtDestinationRow = destinationRow > codecIdx.row() ? destinationRow+1 : destinationRow; - beginMoveRows(parent, codecIdx.row(), codecIdx.row(), parent, qtDestinationRow); - d_ptr->m_lCodecs.move(codecIdx.row(), destinationRow); - endMoveRows(); -#else - beginRemoveRows(QModelIndex(), codecIdx.row(), codecIdx.row()); - CodecModelPrivate::CodecData* codecInfo = d_ptr->m_lCodecs[codecIdx.row()]; - d_ptr->m_lCodecs.removeAt(codecIdx.row()); - endRemoveRows(); - - beginInsertRows(QModelIndex(), destinationRow, destinationRow); - d_ptr->m_lCodecs.insert(destinationRow,codecInfo); - endInsertRows(); -#endif - - this << EditAction::MODIFY; - - return true; - } - - return false; -} - -QMimeData* CodecModel::mimeData(const QModelIndexList& indexes) const -{ - QMimeData* mMimeData = new QMimeData(); - - for (const QModelIndex& index : indexes) { - if (index.isValid()) { - qDebug() << "setting mime data for row: " << index.row(); - - const QByteArray mime = (index.data(CodecModel::Role::TYPE).toString() == "AUDIO") - ? RingMimes::AUDIO_CODEC - : RingMimes::VIDEO_CODEC; - - mMimeData->setData(mime, index.data(CodecModel::Role::ID).toByteArray()); - } - } - - return mMimeData; -} - -Qt::DropActions CodecModel::supportedDragActions() const -{ - return Qt::MoveAction | Qt::TargetMoveAction; -} - -Qt::DropActions CodecModel::supportedDropActions() const -{ - return Qt::MoveAction | Qt::TargetMoveAction; -} - -#include <codecmodel.moc> diff --git a/src/codecmodel.h b/src/codecmodel.h deleted file mode 100644 index ce6ae70c..00000000 --- a/src/codecmodel.h +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2012-2018 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/>. * - ***************************************************************************/ -#pragma once - -#include <QtCore/QAbstractListModel> - -//Qt -#include <QtCore/QString> -class QSortFilterProxyModel; -class QItemSelectionModel; - -//Ring -#include <typedefs.h> - -class Account; -class CodecModelPrivate; - -///AudioCodecModel: A model for account audio codec -class LIB_EXPORT CodecModel : public QAbstractListModel { - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - Q_OBJECT - #pragma GCC diagnostic pop - - //Only Account:: can create this type - friend class Account; - -public: - - //Roles - enum Role { - ID = 103, - NAME = 100, - BITRATE = 101, - MIN_BITRATE = 105, - MAX_BITRATE = 106, - SAMPLERATE = 102, - TYPE = 104, - QUALITY = 107, - MIN_QUALITY = 108, - MAX_QUALITY = 109, - AUTO_QUALITY_ENABLED = 110, - }; - - /// @enum CodecModel::Action Manage a CodecModel lifecycle - enum class EditAction { - SAVE = 0, /*!< Save the model, if there is a conflict, use "ours" */ - MODIFY = 1, /*!< Notify the state machine that the data has changed */ - RELOAD = 2, /*!< Reload from the daemon, if there is a conflict, use "their" */ - CLEAR = 3, /*!< Remove all codecs */ - COUNT__ - }; - - /// @enum CodecModel::EditState track the changes from both clients and daemon - enum class EditState { - LOADING = 0, /*!< The codecs are being loaded, they are not ready yet */ - READY = 1, /*!< Both side are synchronized */ - MODIFIED = 2, /*!< Our version differ from the remote one */ - OUTDATED = 3, /*!< The remote version differ from ours */ - RELOADING = 4, /*!< During a reload */ - COUNT__ - }; - - //Properties - Q_PROPERTY(QSortFilterProxyModel* audioCodecs READ audioCodecs ) - Q_PROPERTY(QSortFilterProxyModel* videoCodecs READ videoCodecs ) - Q_PROPERTY(QItemSelectionModel* selectionModel READ selectionModel ) - - //Abstract model member - 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 QHash<int,QByteArray> roleNames ( ) const override; - virtual QMimeData* mimeData ( const QModelIndexList &indexes ) const override; - virtual QStringList mimeTypes ( ) const override; - virtual bool dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override; - virtual Qt::DropActions supportedDragActions() const override; - virtual Qt::DropActions supportedDropActions() const override; - - //Proxies - QSortFilterProxyModel* audioCodecs() const; - QSortFilterProxyModel* videoCodecs() const; - - //Mutator - bool performAction(CodecModel::EditAction action); - - //Getter - int acceptedPayloadTypes() const; - QItemSelectionModel* selectionModel () const; - CodecModel::EditState editState () const; - - //Operator - CodecModel* operator<<(CodecModel::EditAction& action); - -public Q_SLOTS: - bool moveUp ( ); - bool moveDown ( ); - -private: - - //Constructor - explicit CodecModel(Account* account); - virtual ~CodecModel(); - - QScopedPointer<CodecModelPrivate> d_ptr; - Q_DECLARE_PRIVATE(CodecModel) -}; - -Q_DECLARE_METATYPE(CodecModel*) - -CodecModel LIB_EXPORT *operator<<(CodecModel* a, CodecModel::EditAction action); diff --git a/src/credential.cpp b/src/credential.cpp deleted file mode 100644 index 4bb02157..00000000 --- a/src/credential.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015-2018 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 <credential.h> - -struct CredentialPrivate -{ - QString m_Realm; - QString m_Username; - QString m_Password; - FlagPack<Credential::Type> m_Type {FlagPack<Credential::Type>()}; -}; - -Credential::Credential(const FlagPack<Credential::Type>& t) : d_ptr(new CredentialPrivate()) -{ - d_ptr->m_Type = t; -} - -Credential::~Credential() -{ - delete d_ptr; -} - -QString Credential::realm() const -{ - return d_ptr->m_Realm; -} - -QString Credential::username() const -{ - return d_ptr->m_Username; -} - -QString Credential::password() const -{ - return d_ptr->m_Password; -} - -FlagPack<Credential::Type> Credential::type() const -{ - return d_ptr->m_Type; -} - -void Credential::setRealm(const QString& value) -{ - d_ptr->m_Realm = value; - emit realmChanged(d_ptr->m_Realm); - emit changed(); -} - -void Credential::setUsername(const QString& value) -{ - d_ptr->m_Username = value; - emit usernameChanged(d_ptr->m_Username); - emit changed(); -} - -void Credential::setPassword(const QString& value) -{ - d_ptr->m_Password = value; - emit passwordChanged(d_ptr->m_Password); - emit changed(); -} - -void Credential::setType(const FlagPack<Type>& value) -{ - d_ptr->m_Type = value; -} diff --git a/src/credential.h b/src/credential.h deleted file mode 100644 index 458eebc8..00000000 --- a/src/credential.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015-2018 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/>. * - ***************************************************************************/ -#pragma once - -#include <QtCore/QObject> -#include <typedefs.h> - -struct CredentialPrivate; - -///A set of credential to be used by an account -class LIB_EXPORT Credential final : public QObject -{ - Q_OBJECT -public: - enum class Type { - SIP , - STUN, - TURN, //Does this exist? - COUNT__ - }; - - //Property - Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged) - Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged) - Q_PROPERTY(QString realm READ realm WRITE setRealm NOTIFY realmChanged ) - - //Constructor - explicit Credential(const FlagPack<Credential::Type>& t); - ~Credential(); - - //Getter - QString realm () const; - QString username() const; - QString password() const; - FlagPack<Type> type () const; - - //Setter - void setRealm (const QString& value ); - void setUsername(const QString& value ); - void setPassword(const QString& value ); - void setType (const FlagPack<Type>& value ); - -Q_SIGNALS: - void changed(); - void usernameChanged(const QString&); - void passwordChanged(const QString&); - void realmChanged (const QString&); - -private: - CredentialPrivate* d_ptr; -}; -Q_DECLARE_METATYPE(Credential*) -DECLARE_ENUM_FLAGS(Credential::Type) diff --git a/src/credentialmodel.h b/src/credentialmodel.h deleted file mode 100644 index df23d450..00000000 --- a/src/credentialmodel.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2012-2018 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/>. * - ***************************************************************************/ -#pragma once - -#include <QtCore/QAbstractListModel> - -#include "typedefs.h" - -//Qt -#include <QtCore/QString> -class QItemSelectionModel; - -//Ring -#include <credential.h> - -class CredentialModelPrivate; -class Account; - -///CredentialModel: A model for account credentials -class LIB_EXPORT CredentialModel : public QAbstractItemModel { - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - Q_OBJECT - #pragma GCC diagnostic pop -public: - //Roles - enum Role { - NAME = 100, - PASSWORD = 101, - REALM = 102, - }; - - /// @enum CredentialModel::Action Manage a CredentialModel lifecycle - enum class EditAction { - SAVE = 0, /*!< Save the model, if there is a conflict, use "ours" */ - MODIFY = 1, /*!< Notify the state machine that the data has changed */ - RELOAD = 2, /*!< Reload from the daemon, if there is a conflict, use "their" */ - CLEAR = 3, /*!< Remove all credentials */ - COUNT__ - }; - - /// @enum CredentialModel::EditState track the changes from both clients and daemon - enum class EditState { - LOADING = 0, /*!< The credentials are being loaded, they are not ready yet */ - READY = 1, /*!< Both side are synchronized */ - MODIFIED = 2, /*!< Our version differ from the remote one */ - OUTDATED = 3, /*!< The remote version differ from ours */ - COUNT__ - }; - - //Constructor - explicit CredentialModel(Account* acc); - virtual ~CredentialModel(); - - //Abstract model member - 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 QModelIndex parent ( const QModelIndex& index ) const override; - virtual int columnCount ( const QModelIndex& parent = QModelIndex() ) const override; - virtual QModelIndex index ( int row, int column, const QModelIndex& parent=QModelIndex()) const override; - virtual QHash<int,QByteArray> roleNames( ) const override; - - //Mutator - QModelIndex addCredentials(Credential::Type type); - QModelIndex addCredentials(); - void removeCredentials(const QModelIndex& idx); - bool performAction(CredentialModel::EditAction action); - - //Getter - CredentialModel::EditState editState() const; - QAbstractItemModel* availableTypeModel() const; - QItemSelectionModel* availableTypeSelectionModel() const; - Credential* primaryCredential(Credential::Type type = Credential::Type::SIP); - - //Operator - CredentialModel* operator<<(CredentialModel::EditAction& action); - -Q_SIGNALS: - void primaryCredentialChanged(Credential::Type type, Credential* c); - -private: - QScopedPointer<CredentialModelPrivate> d_ptr; - Q_DECLARE_PRIVATE(CredentialModel) -}; -Q_DECLARE_METATYPE(CredentialModel*) - -CredentialModel LIB_EXPORT *operator<<(CredentialModel* a, CredentialModel::EditAction action); diff --git a/src/globalinstances.cpp b/src/globalinstances.cpp index 5db18f86..a2323f3e 100644 --- a/src/globalinstances.cpp +++ b/src/globalinstances.cpp @@ -19,7 +19,6 @@ #include <memory> -#include "interfaces/accountlistcolorizeri.h" #include "interfaces/contactmethodselectori.h" #include "interfaces/dbuserrorhandleri.h" #include "interfaces/itemmodelstateserializeri.h" @@ -28,7 +27,6 @@ #include "interfaces/shortcutcreatori.h" #include "interfaces/actionextenderi.h" -#include "accountlistcolorizerdefault.h" #include "dbuserrorhandlerdefault.h" #include "pixmapmanipulatordefault.h" #include "presenceserializerdefault.h" @@ -39,7 +37,6 @@ namespace GlobalInstances { struct InstanceManager { - std::unique_ptr<Interfaces::AccountListColorizerI> m_accountListColorizer; std::unique_ptr<Interfaces::ContactMethodSelectorI> m_contactMethodSelector; std::unique_ptr<Interfaces::DBusErrorHandlerI> m_dBusErrorHandler; std::unique_ptr<Interfaces::ItemModelStateSerializerI> m_itemModelStateSerializer; @@ -55,26 +52,6 @@ instanceManager() static std::unique_ptr<InstanceManager> manager{new InstanceManager}; return *manager.get(); } - -Interfaces::AccountListColorizerI& -accountListColorizer() -{ - if (!instanceManager().m_accountListColorizer) - instanceManager().m_accountListColorizer.reset(new Interfaces::AccountListColorizerDefault); - return *instanceManager().m_accountListColorizer.get(); -} - -void -setAccountListColorizer(std::unique_ptr<Interfaces::AccountListColorizerI> instance) -{ - // do not allow empty pointers - if (!instance) { - qWarning() << "ignoring empty unique_ptr"; - return; - } - instanceManager().m_accountListColorizer = std::move(instance); -} - /** * LRC does not provide a default implementation of this interface, thus an exception will be thrown * if this getter is called without an instance being set by the client @@ -237,7 +214,6 @@ void setInterfaceInternal(I* i)\ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmissing-declarations" -REGISTER_INTERFACE(Interfaces::AccountListColorizerI , m_accountListColorizer ) REGISTER_INTERFACE(Interfaces::ContactMethodSelectorI , m_contactMethodSelector ) REGISTER_INTERFACE(Interfaces::DBusErrorHandlerI , m_dBusErrorHandler ) REGISTER_INTERFACE(Interfaces::ItemModelStateSerializerI, m_itemModelStateSerializer) diff --git a/src/globalinstances.h b/src/globalinstances.h index efef9d08..20629b80 100644 --- a/src/globalinstances.h +++ b/src/globalinstances.h @@ -22,7 +22,6 @@ #include <memory> namespace Interfaces { -class AccountListColorizerI; class ContactMethodSelectorI; class DBusErrorHandlerI; class ItemModelStateSerializerI; @@ -42,9 +41,6 @@ class ActionExtenderI; */ namespace GlobalInstances { -LIB_EXPORT Interfaces::AccountListColorizerI& accountListColorizer(); -void LIB_EXPORT setAccountListColorizer(std::unique_ptr<Interfaces::AccountListColorizerI> instance); - /** * LRC does not provide a default implementation of this interface, thus an exception will be thrown * if this getter is called without an instance being set by the client @@ -77,7 +73,6 @@ void LIB_EXPORT setActionExtender(std::unique_ptr<Interfaces::ActionExtenderI> i //Private use only -void setInterfaceInternal(Interfaces::AccountListColorizerI *); void setInterfaceInternal(Interfaces::ContactMethodSelectorI *); void setInterfaceInternal(Interfaces::DBusErrorHandlerI *); void setInterfaceInternal(Interfaces::ItemModelStateSerializerI*); diff --git a/src/interfaces/accountlistcolorizeri.h b/src/interfaces/accountlistcolorizeri.h deleted file mode 100644 index 24ed5632..00000000 --- a/src/interfaces/accountlistcolorizeri.h +++ /dev/null @@ -1,35 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2012-2018 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/>. * - ***************************************************************************/ -#pragma once - -#include <typedefs.h> - -class Account; - -namespace Interfaces { - -///Interface for getting the account color and icon -class AccountListColorizerI { -public: - virtual ~AccountListColorizerI() = default; - - virtual QVariant color(const Account* a) = 0; - virtual QVariant icon(const Account* a) = 0; -}; - -} // namespace Interfaces diff --git a/src/lastusednumbermodel.cpp b/src/lastusednumbermodel.cpp deleted file mode 100644 index 97d89b91..00000000 --- a/src/lastusednumbermodel.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2013-2018 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 "lastusednumbermodel.h" -#include "call.h" -#include "uri.h" -#include "contactmethod.h" - -struct ChainedContactMethod { - ChainedContactMethod(ContactMethod* n) : m_pPrevious(nullptr),m_pNext(nullptr),m_pSelf(n){} - ChainedContactMethod* m_pPrevious; - ChainedContactMethod* m_pNext; - ContactMethod* m_pSelf; -}; - -class LastUsedNumberModelPrivate -{ -public: - LastUsedNumberModelPrivate(); - - //Const - constexpr static const int MAX_ITEM = 15; - - //Attributes - ChainedContactMethod* m_pFirstNode; - QHash<ContactMethod*,ChainedContactMethod*> m_hNumbers; - bool m_IsValid; - ChainedContactMethod* m_lLastNumbers[MAX_ITEM] {}; -}; - -LastUsedNumberModelPrivate::LastUsedNumberModelPrivate():m_pFirstNode(nullptr),m_IsValid(false) -{} - -LastUsedNumberModel::LastUsedNumberModel() : QAbstractListModel(),d_ptr(new LastUsedNumberModelPrivate()) -{ - for (int i=0;i<LastUsedNumberModelPrivate::MAX_ITEM;i++) - d_ptr->m_lLastNumbers[i] = nullptr; -} - -LastUsedNumberModel::~LastUsedNumberModel() -{ - delete d_ptr; -} - -LastUsedNumberModel& LastUsedNumberModel::instance() -{ - static auto instance = new LastUsedNumberModel(); - return *instance; -} - -QHash<int,QByteArray> LastUsedNumberModel::roleNames() const -{ - static QHash<int, QByteArray> roles = QAbstractItemModel::roleNames(); - /*static bool initRoles = false; - if (!initRoles) { - initRoles = true; - - }*/ - return roles; -} - -///Push 'call' phoneNumber on the top of the stack -void LastUsedNumberModel::addCall(Call* call) -{ - ContactMethod* number = call->peerContactMethod(); - ChainedContactMethod* node = d_ptr->m_hNumbers[number]; - if (!number || ( node && d_ptr->m_pFirstNode == node) ) { - //TODO enable threaded numbers now - return; - } - - if (!node) { - node = new ChainedContactMethod(number); - d_ptr->m_hNumbers[number] = node; - } - else { - if (node->m_pPrevious) - node->m_pPrevious->m_pNext = node->m_pNext; - if (node->m_pNext) - node->m_pNext->m_pPrevious = node->m_pPrevious; - } - if (d_ptr->m_pFirstNode) { - d_ptr->m_pFirstNode->m_pPrevious = node; - node->m_pNext = d_ptr->m_pFirstNode; - } - d_ptr->m_pFirstNode = node; - d_ptr->m_IsValid = false; - emit layoutChanged(); -} - - -QVariant LastUsedNumberModel::data( const QModelIndex& index, int role) const -{ - if (!index.isValid()) - return QVariant(); - if (!d_ptr->m_IsValid) { - ChainedContactMethod* current = d_ptr->m_pFirstNode; - for (int i=0;i<LastUsedNumberModelPrivate::MAX_ITEM;i++) { //Can only grow, no need to clear - d_ptr->m_lLastNumbers[i] = current; - current = current->m_pNext; - if (!current) - break; - } - d_ptr->m_IsValid = true; - } - switch (role) { - case Qt::DisplayRole: { - return d_ptr->m_lLastNumbers[index.row()]->m_pSelf->uri(); - } - }; - return QVariant(); -} - -int LastUsedNumberModel::rowCount( const QModelIndex& parent) const -{ - if (parent.isValid()) - return 0; - return d_ptr->m_hNumbers.size() < LastUsedNumberModelPrivate::MAX_ITEM?d_ptr->m_hNumbers.size():LastUsedNumberModelPrivate::MAX_ITEM; -} - -Qt::ItemFlags LastUsedNumberModel::flags( const QModelIndex& index) const -{ - Q_UNUSED(index) - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; -} - -bool LastUsedNumberModel::setData( const QModelIndex& index, const QVariant &value, int role) -{ - Q_UNUSED(index) - Q_UNUSED(value) - Q_UNUSED(role) - return false; -} diff --git a/src/lastusednumbermodel.h b/src/lastusednumbermodel.h deleted file mode 100644 index 96a67b01..00000000 --- a/src/lastusednumbermodel.h +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2013-2018 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/>. * - ***************************************************************************/ -#pragma once - -#include "typedefs.h" - -#include <QtCore/QAbstractListModel> - -class Call; -class ContactMethod; - -class LastUsedNumberModelPrivate; - -class LIB_EXPORT LastUsedNumberModel : public QAbstractListModel -{ - Q_OBJECT - -public: - //Singleton - static LastUsedNumberModel& instance(); - - //Model functions - 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 QHash<int,QByteArray> roleNames() const override; - - //Mutator - Q_INVOKABLE void addCall(Call* call); - -private: - //Private constructor - explicit LastUsedNumberModel(); - virtual ~LastUsedNumberModel(); - - LastUsedNumberModelPrivate* d_ptr; - Q_DECLARE_PRIVATE(LastUsedNumberModel) -}; diff --git a/src/localbookmarkcollection.cpp b/src/localbookmarkcollection.cpp deleted file mode 100644 index 6969cf91..00000000 --- a/src/localbookmarkcollection.cpp +++ /dev/null @@ -1,288 +0,0 @@ -/************************************************************************************ - * Copyright (C) 2014-2018 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 Lesser General Public * - * License along with this library; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***********************************************************************************/ -#include "localbookmarkcollection.h" - -//Qt -#include <QtCore/QFile> -#include <QtCore/QHash> -#include <QtCore/QJsonDocument> -#include <QtCore/QJsonArray> -#include <QtCore/QJsonObject> -#include <QtCore/QStandardPaths> - -//Ring -#include <call.h> -#include <account.h> -#include <contactmethod.h> -#include <accountmodel.h> -#include <personmodel.h> -#include <phonedirectorymodel.h> -#include <collectioneditor.h> -#include <globalinstances.h> -#include <interfaces/pixmapmanipulatori.h> - -namespace Serializable { - class BookmarkNode - { - public: - Account* account ; - ContactMethod* cm ; - Person* contact ; - - void read (const QJsonObject &json); - void write(QJsonObject &json); - }; -} - -class LocalBookmarkEditor final : public CollectionEditor<ContactMethod> -{ -public: - LocalBookmarkEditor(CollectionMediator<ContactMethod>* m) - : CollectionEditor<ContactMethod>(m),m_Tracked(false) {} - virtual bool save ( const ContactMethod* item ) override; - virtual bool remove ( const ContactMethod* item ) override; - virtual bool addNew ( ContactMethod* item ) override; - virtual bool addExisting( const ContactMethod* item ) override; - - //Attributes - QVector<ContactMethod*> m_lNumbers; - QList<Serializable::BookmarkNode> m_Nodes; - bool m_Tracked; - -private: - virtual QVector<ContactMethod*> items() const override; -}; - -class LocalBookmarkCollectionPrivate -{ -public: - - //Attributes - constexpr static const char FILENAME[] = "bookmark.json"; -}; - -constexpr const char LocalBookmarkCollectionPrivate::FILENAME[]; - -LocalBookmarkCollection::LocalBookmarkCollection(CollectionMediator<ContactMethod>* mediator) : - CollectionInterface(new LocalBookmarkEditor(mediator)), d_ptr(new LocalBookmarkCollectionPrivate()) -{ - load(); -} - - -LocalBookmarkCollection::~LocalBookmarkCollection() -{ - delete d_ptr; -} - -bool LocalBookmarkCollection::load() -{ - QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLocation) - + QLatin1Char('/') - + LocalBookmarkCollectionPrivate::FILENAME); - if ( file.open(QIODevice::ReadOnly | QIODevice::Text) ) { - LocalBookmarkEditor* e = static_cast<LocalBookmarkEditor*>(editor<ContactMethod>()); - const QByteArray content = file.readAll(); - QJsonDocument loadDoc = QJsonDocument::fromJson(content); - QJsonArray a = loadDoc.array(); - - for (int i = 0; i < a.size(); ++i) { - QJsonObject o = a[i].toObject(); - Serializable::BookmarkNode n; - n.read(o); - - e->addExisting(n.cm); - - n.cm->setTracked (e->m_Tracked); - n.cm->setBookmarked(true ); - - e->m_Nodes << n; - } - - return true; - } - else - qWarning() << "Bookmarks doesn't exist or is not readable"; - return false; -} - -bool LocalBookmarkEditor::save(const ContactMethod* number) -{ - Q_UNUSED(number) - - QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLocation) - + QLatin1Char('/') - + LocalBookmarkCollectionPrivate::FILENAME); - if ( file.open(QIODevice::WriteOnly | QIODevice::Text) ) { - - QJsonArray a; - for (Serializable::BookmarkNode& g : m_Nodes) { - QJsonObject o; - g.write(o); - a.append(o); - } - - QJsonDocument doc(a); - - QTextStream streamFileOut(&file); - streamFileOut << doc.toJson(); - streamFileOut.flush(); - file.close(); - - return true; - } - else - qWarning() << "Unable to save bookmarks"; - - return false; -} - -bool LocalBookmarkEditor::remove(const ContactMethod* item) -{ - Q_UNUSED(item) - - if (m_lNumbers.indexOf(const_cast<ContactMethod*>(item)) != -1) { - m_lNumbers.removeAt(m_lNumbers.indexOf(const_cast<ContactMethod*>(item))); - mediator()->removeItem(item); - - for (int i =0;i<m_Nodes.size();i++) { - if (m_Nodes[i].cm == item) { - m_Nodes.removeAt(i); - break; - } - } - - return save(nullptr); - } - return false; -} - -bool LocalBookmarkEditor::addNew( ContactMethod* number) -{ - if (!number->isBookmarked()) { - number->setTracked(m_Tracked); - number->setBookmarked(true); - Serializable::BookmarkNode n; - - n.cm = number; - n.account = number->account(); - n.contact = number->contact(); - m_Nodes << n; - - if (!save(number)) - qWarning() << "Unable to save bookmarks"; - } - else - qDebug() << number->uri() << "is already bookmarked"; - - addExisting(number); - return save(number); -} - -bool LocalBookmarkEditor::addExisting(const ContactMethod* item) -{ - m_lNumbers << const_cast<ContactMethod*>(item); - mediator()->addItem(item); - return false; -} - -QVector<ContactMethod*> LocalBookmarkEditor::items() const -{ - return m_lNumbers; -} - -QString LocalBookmarkCollection::name () const -{ - return QObject::tr("Local bookmarks"); -} - -QString LocalBookmarkCollection::category () const -{ - return QObject::tr("Bookmark"); -} - -QVariant LocalBookmarkCollection::icon() const -{ - return GlobalInstances::pixmapManipulator().collectionIcon(this,Interfaces::PixmapManipulatorI::CollectionIconHint::BOOKMARK); -} - -bool LocalBookmarkCollection::isEnabled() const -{ - return true; -} - -bool LocalBookmarkCollection::reload() -{ - return false; -} - -FlagPack<CollectionInterface::SupportedFeatures> LocalBookmarkCollection::supportedFeatures() const -{ - return - CollectionInterface::SupportedFeatures::NONE | - CollectionInterface::SupportedFeatures::LOAD | - CollectionInterface::SupportedFeatures::CLEAR | - CollectionInterface::SupportedFeatures::ADD | - CollectionInterface::SupportedFeatures::MANAGEABLE| - CollectionInterface::SupportedFeatures::REMOVE ; -} - -bool LocalBookmarkCollection::clear() -{ - return QFile::remove(QStandardPaths::writableLocation(QStandardPaths::DataLocation) - + QLatin1Char('/') - + LocalBookmarkCollectionPrivate::FILENAME); -} - -QByteArray LocalBookmarkCollection::id() const -{ - return "localbookmark"; -} - - -void LocalBookmarkCollection::setPresenceTracked(bool tracked) -{ - static_cast<LocalBookmarkEditor*>(editor<ContactMethod>())->m_Tracked = tracked; -} - -bool LocalBookmarkCollection::isPresenceTracked() const -{ - return static_cast<LocalBookmarkEditor*>(editor<ContactMethod>())->m_Tracked; -} - -void Serializable::BookmarkNode::read(const QJsonObject &json) -{ - const QString& uri = json[ "uri" ].toString() ; - const QByteArray& accountId = json[ "accountId" ].toString().toLatin1(); - const QByteArray& contactId = json[ "contactId" ].toString().toLatin1(); - - account = accountId.isEmpty()?nullptr:AccountModel::instance ().getById ( accountId ); - contact = contactId.isEmpty()?nullptr:PersonModel::instance ().getPersonByUid( contactId ); - cm = uri.isEmpty()?nullptr:PhoneDirectoryModel::instance().getNumber ( uri, contact, account); -} - -void Serializable::BookmarkNode::write(QJsonObject& json) -{ - if (!account) - account = cm->account(); - - json[ "uri" ] = cm->uri() ; - json[ "accountId" ] = account?account->id():QString(); - json[ "contactId" ] = contact?contact->uid ():QString(); -} diff --git a/src/localbookmarkcollection.h b/src/localbookmarkcollection.h deleted file mode 100644 index 7a634e53..00000000 --- a/src/localbookmarkcollection.h +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************************ - * Copyright (C) 2014-2018 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 Lesser General Public * - * License along with this library; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***********************************************************************************/ -#pragma once - -#include <collectioninterface.h> - -class ContactMethod; - -class LocalBookmarkCollectionPrivate; - -class LIB_EXPORT LocalBookmarkCollection : public CollectionInterface -{ -public: - explicit LocalBookmarkCollection(CollectionMediator<ContactMethod>* mediator); - virtual ~LocalBookmarkCollection(); - - virtual bool load () override; - virtual bool reload() override; - virtual bool clear () override; - - virtual QString name () const override; - virtual QString category () const override; - virtual QVariant icon () const override; - virtual bool isEnabled() const override; - virtual QByteArray id () const override; - - virtual FlagPack<SupportedFeatures> supportedFeatures() const override; - - //Setter - void setPresenceTracked(bool tracked); - - //Getter - bool isPresenceTracked() const; - -private: - LocalBookmarkCollectionPrivate* d_ptr; - Q_DECLARE_PRIVATE(LocalBookmarkCollection) -}; - diff --git a/src/localhistorycollection.h b/src/localhistorycollection.h deleted file mode 100644 index e251a5c3..00000000 --- a/src/localhistorycollection.h +++ /dev/null @@ -1,49 +0,0 @@ -/************************************************************************************ - * Copyright (C) 2014-2018 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 Lesser General Public * - * License along with this library; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***********************************************************************************/ -#pragma once - -#include "collectioninterface.h" -#include "collectioneditor.h" - -class Call; - -template<typename T> class CollectionMediator; - -class LIB_EXPORT LocalHistoryCollection : public CollectionInterface -{ -public: - explicit LocalHistoryCollection(CollectionMediator<Call>* mediator); - virtual ~LocalHistoryCollection(); - - virtual bool load () override; - virtual bool reload() override; - virtual bool clear () override; - - virtual QString name () const override; - virtual QString category () const override; - virtual QVariant icon () const override; - virtual bool isEnabled() const override; - virtual QByteArray id () const override; - - virtual FlagPack<SupportedFeatures> supportedFeatures() const override; - -private: - CollectionMediator<Call>* m_pMediator; -}; - diff --git a/src/localmacrocollection.cpp b/src/localmacrocollection.cpp deleted file mode 100644 index a38d08a5..00000000 --- a/src/localmacrocollection.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2013-2018 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 "localmacrocollection.h" - -//Qt -#include <QtCore/QFile> -#include <QtCore/QHash> -#include <QtCore/QJsonDocument> -#include <QtCore/QJsonArray> -#include <QtCore/QJsonObject> -#include <QtCore/QStandardPaths> - -//Ring -#include <macro.h> -#include <collectioneditor.h> -#include <macromodel.h> -#include <globalinstances.h> -#include <interfaces/pixmapmanipulatori.h> - -namespace Serializable { - class MacroNode - { - public: - Macro* macro; - - void read (const QJsonObject &json); - void write(QJsonObject &json); - }; -} - -class LocalMacroEditor final : public CollectionEditor<Macro> -{ -public: - LocalMacroEditor(CollectionMediator<Macro>* m) : CollectionEditor<Macro>(m),m_Tracked(false) {} - virtual bool save ( const Macro* item ) override; - virtual bool remove ( const Macro* item ) override; - virtual bool addNew ( Macro* item ) override; - virtual bool addExisting( const Macro* item ) override; - - //Attributes - QVector<Macro*> m_lNumbers; - QList<Serializable::MacroNode> m_Nodes; - bool m_Tracked; - -private: - virtual QVector<Macro*> items() const override; -}; - -class LocalMacroCollectionPrivate -{ -public: - - //Attributes - constexpr static const char FILENAME[] = "macro.json"; -}; - -constexpr const char LocalMacroCollectionPrivate::FILENAME[]; - -LocalMacroCollection::LocalMacroCollection(CollectionMediator<Macro>* mediator) : - CollectionInterface(new LocalMacroEditor(mediator)) -{ - load(); -} - - -LocalMacroCollection::~LocalMacroCollection() -{ - delete d_ptr; -} - -bool LocalMacroCollection::load() -{ - QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') +LocalMacroCollectionPrivate::FILENAME); - if ( file.open(QIODevice::ReadOnly | QIODevice::Text) ) { - LocalMacroEditor* e = static_cast<LocalMacroEditor*>(editor<Macro>()); - const QByteArray content = file.readAll(); - QJsonDocument loadDoc = QJsonDocument::fromJson(content); - QJsonArray a = loadDoc.array(); - - for (int i = 0; i < a.size(); ++i) { - QJsonObject o = a[i].toObject(); - Serializable::MacroNode n; - n.read(o); - - n.macro->setCollection(this); - e->addExisting(n.macro); - - e->m_Nodes << n; - } - - return true; - } - else - qWarning() << "Macros doesn't exist or is not readable"; - return false; -} - -bool LocalMacroEditor::save(const Macro* macro) -{ - Q_UNUSED(macro) - - QFile file(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/')+LocalMacroCollectionPrivate::FILENAME); - if ( file.open(QIODevice::WriteOnly | QIODevice::Text) ) { - - QJsonArray a; - for (Serializable::MacroNode& g : m_Nodes) { - QJsonObject o; - g.write(o); - a.append(o); - } - - QJsonDocument doc(a); - - QTextStream streamFileOut(&file); - streamFileOut << doc.toJson(); - streamFileOut.flush(); - file.close(); - - return true; - } - else - qWarning() << "Unable to save macros"; - - return false; -} - -bool LocalMacroEditor::remove(const Macro* item) -{ - Q_UNUSED(item) - - if (m_lNumbers.indexOf(const_cast<Macro*>(item)) != -1) { - m_lNumbers.removeAt(m_lNumbers.indexOf(const_cast<Macro*>(item))); - mediator()->removeItem(item); - - for (int i =0;i<m_Nodes.size();i++) { - if (m_Nodes[i].macro == item) { - m_Nodes.removeAt(i); - break; - } - } - - return save(nullptr); - } - return false; -} - -bool LocalMacroEditor::addNew( Macro* macro) -{ - Serializable::MacroNode n; - - n.macro = macro; - m_Nodes << n; - - if (!save(macro)) - qWarning() << "Unable to save macros"; - - addExisting(macro); - return save(macro); -} - -bool LocalMacroEditor::addExisting(const Macro* item) -{ - m_lNumbers << const_cast<Macro*>(item); - mediator()->addItem(item); - return false; -} - -QVector<Macro*> LocalMacroEditor::items() const -{ - return m_lNumbers; -} - -QString LocalMacroCollection::name () const -{ - return QObject::tr("Local macros"); -} - -QString LocalMacroCollection::category () const -{ - return QObject::tr("Macro"); -} - -QVariant LocalMacroCollection::icon() const -{ - return GlobalInstances::pixmapManipulator().collectionIcon(this,Interfaces::PixmapManipulatorI::CollectionIconHint::MACRO); -} - -bool LocalMacroCollection::isEnabled() const -{ - return true; -} - -bool LocalMacroCollection::reload() -{ - return false; -} - -FlagPack<CollectionInterface::SupportedFeatures> LocalMacroCollection::supportedFeatures() const -{ - return - CollectionInterface::SupportedFeatures::NONE | - CollectionInterface::SupportedFeatures::LOAD | - CollectionInterface::SupportedFeatures::CLEAR | - CollectionInterface::SupportedFeatures::ADD | - CollectionInterface::SupportedFeatures::MANAGEABLE| - CollectionInterface::SupportedFeatures::REMOVE ; -} - -bool LocalMacroCollection::clear() -{ - return QFile::remove(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') + LocalMacroCollectionPrivate::FILENAME); -} - -QByteArray LocalMacroCollection::id() const -{ - return "localmacro"; -} - - -void LocalMacroCollection::setPresenceTracked(bool tracked) -{ - static_cast<LocalMacroEditor*>(editor<Macro>())->m_Tracked = tracked; -} - -bool LocalMacroCollection::isPresenceTracked() const -{ - return static_cast<LocalMacroEditor*>(editor<Macro>())->m_Tracked; -} - -void Serializable::MacroNode::read(const QJsonObject &json) -{ - macro = MacroModel::instance().newMacro(json["ID"].toString()); - macro->setName ( json[ "Name" ].toString ()); - macro->setSequence ( json[ "Seq" ].toString ()); - macro->setCategory ( json[ "Cat" ].toString ()); - macro->setDelay ( json[ "Delay" ].toInt ()); - macro->setDescription ( json[ "Desc" ].toString ()); -} - -void Serializable::MacroNode::write(QJsonObject& json) -{ - json[ "Name" ] = macro->name (); - json[ "Seq" ] = macro->sequence (); - json[ "Cat" ] = macro->category (); - json[ "Delay" ] = macro->delay (); - json[ "Desc" ] = macro->description (); - json[ "ID" ] = macro->id (); -} diff --git a/src/localmacrocollection.h b/src/localmacrocollection.h deleted file mode 100644 index 24567d8a..00000000 --- a/src/localmacrocollection.h +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2013-2018 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/>. * - ***************************************************************************/ -#pragma once - -#include <collectioninterface.h> - -class Macro; - -class LocalMacroCollectionPrivate; - -class LIB_EXPORT LocalMacroCollection : public CollectionInterface -{ -public: - explicit LocalMacroCollection(CollectionMediator<Macro>* mediator); - virtual ~LocalMacroCollection(); - - virtual bool load () override; - virtual bool reload() override; - virtual bool clear () override; - - virtual QString name () const override; - virtual QString category () const override; - virtual QVariant icon () const override; - virtual bool isEnabled() const override; - virtual QByteArray id () const override; - - virtual FlagPack<SupportedFeatures> supportedFeatures() const override; - - //Setter - void setPresenceTracked(bool tracked); - - //Getter - bool isPresenceTracked() const; - -private: - LocalMacroCollectionPrivate* d_ptr; - Q_DECLARE_PRIVATE(LocalMacroCollection) -}; - diff --git a/src/lrc.cpp b/src/lrc.cpp index 8c6bacb5..4de5a3f2 100644 --- a/src/lrc.cpp +++ b/src/lrc.cpp @@ -27,6 +27,7 @@ #include "callbackshandler.h" #include "dbus/configurationmanager.h" #include "dbus/instancemanager.h" +#include "dbus/configurationmanager.h" namespace lrc { diff --git a/src/numbercompletionmodel.cpp b/src/numbercompletionmodel.cpp deleted file mode 100644 index 25edb776..00000000 --- a/src/numbercompletionmodel.cpp +++ /dev/null @@ -1,646 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2013-2018 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 "numbercompletionmodel.h" - -//Qt -#include <QtCore/QCoreApplication> -#include <QtCore/QItemSelectionModel> - -//System -#include <cmath> - -//DRing -#include <account_const.h> - -//Ring -#include "phonedirectorymodel.h" -#include "contactmethod.h" -#include "call.h" -#include "uri.h" -#include "numbercategory.h" -#include "accountmodel.h" -#include "availableaccountmodel.h" -#include "numbercategorymodel.h" -#include "person.h" - -//Private -#include "private/phonedirectorymodel_p.h" - -class NumberCompletionModelPrivate final : public QObject -{ - Q_OBJECT -public: - - enum class Columns { - CONTENT = 0, - NAME = 1, - ACCOUNT = 2, - WEIGHT = 3, - }; - - //Constructor - NumberCompletionModelPrivate(NumberCompletionModel* parent); - - //Methods - void updateModel(); - - //Helper - void locateNameRange (const QString& prefix, QSet<ContactMethod*>& set); - void locateNumberRange(const QString& prefix, QSet<ContactMethod*>& set); - uint getWeight(ContactMethod* number); - uint getWeight(Account* account); - void getRange(QMap<QString,NumberWrapper*> map, const QString& prefix, QSet<ContactMethod*>& set) const; - - //Attributes - QMultiMap<int,ContactMethod*> m_hNumbers ; - URI m_Prefix ; - Call* m_pCall ; - bool m_Enabled ; - bool m_UseUnregisteredAccount; - bool m_DisplayMostUsedNumbers; - QItemSelectionModel* m_pSelectionModel ; - bool m_HasCustomSelection ; - - QHash<Account*,TemporaryContactMethod*> m_hSipTemporaryNumbers; - QHash<Account*,TemporaryContactMethod*> m_hRingTemporaryNumbers; - QHash<int, TemporaryContactMethod*> m_pPreferredTemporaryNumbers; - -public Q_SLOTS: - void setPrefix(const QString& str); - - bool accountAdded (Account* a); - void accountRemoved(Account* a); - - void resetSelectionModel(); - void slotSelectionChanged(const QModelIndex& sel, const QModelIndex& prev); - -private: - NumberCompletionModel* q_ptr; -}; - - -NumberCompletionModelPrivate::NumberCompletionModelPrivate(NumberCompletionModel* parent) : QObject(parent), q_ptr(parent), -m_pCall(nullptr),m_Enabled(false),m_UseUnregisteredAccount(true), m_Prefix(QString()),m_DisplayMostUsedNumbers(false), -m_pSelectionModel(nullptr),m_HasCustomSelection(false) -{ - //Create the temporary number list - bool hasNonIp2Ip = false; - Account* ip2ip = AccountModel::instance().ip2ip(); - - for (int i =0; i < AccountModel::instance().size();i++) { - Account* a = AccountModel::instance()[i]; - if (a != ip2ip) { - hasNonIp2Ip |= accountAdded(a); - } - } - - //If SIP accounts are present, IP2IP is not needed - if (!hasNonIp2Ip) { - TemporaryContactMethod* cm = new TemporaryContactMethod(); - cm->setAccount(ip2ip); - m_hSipTemporaryNumbers[ip2ip] = cm; - } - - connect(&AccountModel::instance(), &AccountModel::accountAdded , this, &NumberCompletionModelPrivate::accountAdded ); - connect(&AccountModel::instance(), &AccountModel::accountRemoved, this, &NumberCompletionModelPrivate::accountRemoved); -} - -NumberCompletionModel::NumberCompletionModel() : QAbstractTableModel(&PhoneDirectoryModel::instance()), d_ptr(new NumberCompletionModelPrivate(this)) -{ - setObjectName("NumberCompletionModel"); -} - -NumberCompletionModel::~NumberCompletionModel() -{ - QList<TemporaryContactMethod*> l = d_ptr->m_hSipTemporaryNumbers.values(); - - d_ptr->m_hSipTemporaryNumbers.clear(); - - while(l.size()) { - TemporaryContactMethod* cm = l.takeAt(0); - delete cm; - } - - l = d_ptr->m_hRingTemporaryNumbers.values(); - d_ptr->m_hRingTemporaryNumbers.clear(); - - while(l.size()) { - TemporaryContactMethod* cm = l.takeAt(0); - delete cm; - } - - delete d_ptr; -} - -QHash<int,QByteArray> NumberCompletionModel::roleNames() const -{ - static QHash<int, QByteArray> roles = QAbstractItemModel::roleNames(); - static bool initRoles = false; - - if (!initRoles) { - initRoles = true; - roles[Role::ALTERNATE_ACCOUNT]= "AlternateAccount"; - roles[Role::FORCE_ACCOUNT ]= "ForceAccount" ; - roles[Role::ACCOUNT ]= "Account" ; - } - - return roles; -} - -QVariant NumberCompletionModel::data(const QModelIndex& index, int role ) const -{ - if (!index.isValid()) - return QVariant(); - - const QMap<int,ContactMethod*>::iterator i = d_ptr->m_hNumbers.end()-1-index.row(); - const ContactMethod* n = i.value(); - const int weight = i.key (); - - bool needAcc = (role>=100 || role == Qt::UserRole) && n->account() /*&& n->account() != AvailableAccountModel::currentDefaultAccount()*/ - && !n->account()->isIp2ip(); - - switch (static_cast<NumberCompletionModelPrivate::Columns>(index.column())) { - case NumberCompletionModelPrivate::Columns::CONTENT: - switch (role) { - case Qt::DisplayRole: - return n->uri(); - case Qt::ToolTipRole: - return QString("<table><tr><td>%1</td></tr><tr><td>%2</td></tr></table>") - .arg(n->primaryName()) - .arg(n->category() ? n->category()->name() : QString()); - case Qt::DecorationRole: - return n->icon(); - case NumberCompletionModel::Role::ALTERNATE_ACCOUNT: - case Qt::UserRole: - if (needAcc) - return n->account()->alias(); - else - return QString(); - case NumberCompletionModel::Role::FORCE_ACCOUNT: - return needAcc; - case NumberCompletionModel::Role::PEER_NAME: - return n->primaryName(); - case NumberCompletionModel::Role::ACCOUNT: - if (needAcc) - return QVariant::fromValue(n->account()); - break; - case static_cast<int>(Ring::Role::ObjectType): - return QVariant::fromValue(Ring::ObjectType::ContactMethod); - case static_cast<int>(Ring::Role::Object): - return QVariant::fromValue(const_cast<ContactMethod*>(n)); - }; - break; - case NumberCompletionModelPrivate::Columns::NAME: - switch (role) { - case Qt::DisplayRole: - return n->primaryName(); - case Qt::DecorationRole: - if (n->contact()) - return n->contact()->photo(); - }; - break; - case NumberCompletionModelPrivate::Columns::ACCOUNT: - switch (role) { - case Qt::DisplayRole: - { - auto acc = n->account() ? n->account() : AvailableAccountModel::currentDefaultAccount(); - if (acc) - return acc->alias(); - } - }; - break; - case NumberCompletionModelPrivate::Columns::WEIGHT: - switch (role) { - case Qt::DisplayRole: - return weight; - }; - break; - }; - - return QVariant(); -} - -int NumberCompletionModel::rowCount(const QModelIndex& parent ) const -{ - if (parent.isValid()) - return 0; - - return d_ptr->m_hNumbers.size(); -} - -int NumberCompletionModel::columnCount(const QModelIndex& parent ) const -{ - if (parent.isValid()) - return 0; - - return 4; -} - -Qt::ItemFlags NumberCompletionModel::flags(const QModelIndex& index ) const -{ - if (!index.isValid()) - return Qt::NoItemFlags; - - return Qt::ItemIsEnabled|Qt::ItemIsSelectable; -} - -QVariant NumberCompletionModel::headerData (int section, Qt::Orientation orientation, int role) const -{ - Q_UNUSED(orientation) - static const QString headers[] = {tr("URI"), tr("Name"), tr("Account"), tr("Weight")}; - - if (role == Qt::DisplayRole) - return headers[section]; - - return QVariant(); -} - -bool NumberCompletionModel::setData(const QModelIndex& index, const QVariant &value, int role) -{ - Q_UNUSED( index ) - Q_UNUSED( value ) - Q_UNUSED( role ) - return false; -} - -//Set the current call -void NumberCompletionModel::setCall(Call* call) -{ - d_ptr->resetSelectionModel(); - - if (d_ptr->m_pCall) - disconnect(d_ptr->m_pCall,SIGNAL(dialNumberChanged(QString)),d_ptr,SLOT(setPrefix(QString))); - - d_ptr->m_pCall = call; - - if (d_ptr->m_pCall) - connect(d_ptr->m_pCall,SIGNAL(dialNumberChanged(QString)),d_ptr,SLOT(setPrefix(QString))); - - d_ptr->setPrefix(call?call->dialNumber():QString()); -} - -void NumberCompletionModelPrivate::setPrefix(const QString& str) -{ - m_Prefix = str; - const bool e = ((m_pCall && m_pCall->lifeCycleState() == Call::LifeCycleState::CREATION) || (!m_pCall)) && ((m_DisplayMostUsedNumbers || !str.isEmpty())); - - if (m_Enabled != e) { - m_Enabled = e; - emit q_ptr->enabled(e); - } - - if (m_Enabled) - updateModel(); - else { - q_ptr->beginRemoveRows(QModelIndex(), 0, m_hNumbers.size()-1); - m_hNumbers.clear(); - q_ptr->endRemoveRows(); - } - - if (m_Prefix.protocolHint() == URI::ProtocolHint::RING) { - for(TemporaryContactMethod* cm : m_hRingTemporaryNumbers) { - cm->setUri(m_Prefix); - } - } else { - for(auto cm : m_hSipTemporaryNumbers) { - if (cm) - cm->setUri(m_Prefix); - } - } -} - -Call* NumberCompletionModel::call() const -{ - return d_ptr->m_pCall; -} - -ContactMethod* NumberCompletionModel::number(const QModelIndex& idx) const -{ - if (idx.isValid()) { - //Keep the temporary contact methods private, export a copy - ContactMethod* m = (d_ptr->m_hNumbers.end()-1-idx.row()).value(); - return m->type() == ContactMethod::Type::TEMPORARY ? - PhoneDirectoryModel::instance().fromTemporary(qobject_cast<TemporaryContactMethod*>(m)) - : m; - } - - return nullptr; -} - -void NumberCompletionModelPrivate::updateModel() -{ - QSet<ContactMethod*> numbers; - q_ptr->beginRemoveRows(QModelIndex(), 0, m_hNumbers.size()-1); - m_hNumbers.clear(); - q_ptr->endRemoveRows(); - - if (!m_Prefix.isEmpty()) { - locateNameRange ( m_Prefix, numbers ); - locateNumberRange( m_Prefix, numbers ); - - if (m_Prefix.protocolHint() == URI::ProtocolHint::RING) { - for (TemporaryContactMethod* cm : m_hRingTemporaryNumbers) { - const int weight = getWeight(cm->account()); - if (weight) { - q_ptr->beginInsertRows(QModelIndex(), m_hNumbers.size(), m_hNumbers.size()); - m_hNumbers.insert(weight,cm); - q_ptr->endInsertRows(); - } - } - } else { - for (auto cm : m_hSipTemporaryNumbers) { - if (!cm) continue; - if (auto weight = getWeight(cm->account())) { - q_ptr->beginInsertRows(QModelIndex(), m_hNumbers.size(), m_hNumbers.size()); - m_hNumbers.insert(weight, cm); - q_ptr->endInsertRows(); - } - } - } - - for (ContactMethod* n : numbers) { - if (m_UseUnregisteredAccount || ((n->account() && n->account()->registrationState() == Account::RegistrationState::READY) - || !n->account())) { - q_ptr->beginInsertRows(QModelIndex(), m_hNumbers.size(), m_hNumbers.size()); - m_hNumbers.insert(getWeight(n),n); - q_ptr->endInsertRows(); - } - } - } - else if (m_DisplayMostUsedNumbers) { - //If enabled, display the most probable entries - const QVector<ContactMethod*> cl = PhoneDirectoryModel::instance().getNumbersByPopularity(); - - for (int i=0;i<((cl.size()>=10)?10:cl.size());i++) { - ContactMethod* n = cl[i]; - q_ptr->beginInsertRows(QModelIndex(), m_hNumbers.size(), m_hNumbers.size()); - m_hNumbers.insert(getWeight(n),n); - q_ptr->endInsertRows(); - } - } -} - -void NumberCompletionModelPrivate::getRange(QMap<QString,NumberWrapper*> map, const QString& prefix, QSet<ContactMethod*>& set) const -{ - if (prefix.isEmpty() || map.isEmpty()) - return; - - QMap<QString,NumberWrapper*>::iterator iBeg = map.begin(); - QMap<QString,NumberWrapper*>::iterator iEnd = map.end ()-1; - - const QString pref = prefix.toLower(); - - const int prefixLen = pref.size(); - int size = map.size()/2; - bool startOk(false),endOk(false); - - while (size > 1 && !(startOk&&endOk)) { - QMap<QString,NumberWrapper*>::iterator mid; - - if (size > 7) - mid = (iBeg+size); - else { - //We have to be careful with "::ceil" it may cause an overflow in some rare case - int toAdd = size-1; - mid = iBeg; - - while (toAdd && mid != map.end()) { - ++mid; - --toAdd; - } - - } - - if (mid != map.end() && mid.key().left(prefixLen) == pref && iBeg.key().left(prefixLen) < pref) { - //Too far, need to go back - iBeg = mid; - - while ((iBeg-1).key().left(prefixLen) == pref && iBeg != map.begin()) - iBeg--; - - startOk = true; - } - else if ((!startOk) && mid != map.end() && mid.key().left(prefixLen) < pref) { - iBeg = mid; - } - else if(!endOk) { - iEnd = mid; - } - - while ((iEnd).key().left(prefixLen) == pref && iEnd+1 != map.end()) { - ++iEnd; - } - - endOk = (iEnd.key().left(prefixLen) == pref); - - size = (int)::ceil((static_cast<float>(size))/2.0f); - } - - while (iBeg.key().left(prefixLen) != pref && iBeg != map.end() && iBeg != iEnd) - ++iBeg; - - if (iEnd == iBeg && iBeg.key().left(prefixLen) != pref) { - iEnd = map.end(); - iBeg = map.end(); - } - - while(iBeg != iEnd) { - foreach(ContactMethod* n,iBeg.value()->numbers) { - if (n) { - set << n; - } - } - - ++iBeg; - } -} - -void NumberCompletionModelPrivate::locateNameRange(const QString& prefix, QSet<ContactMethod*>& set) -{ - getRange(PhoneDirectoryModel::instance().d_ptr->m_lSortedNames,prefix,set); -} - -void NumberCompletionModelPrivate::locateNumberRange(const QString& prefix, QSet<ContactMethod*>& set) -{ - getRange(PhoneDirectoryModel::instance().d_ptr->m_hSortedNumbers,prefix,set); -} - -uint NumberCompletionModelPrivate::getWeight(ContactMethod* number) -{ - uint weight = 1; - - weight += (number->weekCount()+1)*150; - weight += (number->trimCount()+1)*75 ; - weight += (number->callCount()+1)*35 ; - weight *= (number->uri().indexOf(m_Prefix)!= -1?3:1); - weight *= (number->isPresent()?2:1); - - return weight; -} - -uint NumberCompletionModelPrivate::getWeight(Account* account) -{ - if ((!account) || account->registrationState() != Account::RegistrationState::READY) - return 0; //TODO handle the case where the account get registered during dialing - - uint weight = 1; - - weight += (account->weekCallCount ()+1)*15; - weight += (account->trimesterCallCount ()+1)*7 ; - weight += (account->totalCallCount ()+1)*3 ; - weight *= (account->isUsedForOutgogingCall()?3:1 ); - - return weight; -} - -QString NumberCompletionModel::prefix() const -{ - return d_ptr->m_Prefix; -} - -void NumberCompletionModel::setUseUnregisteredAccounts(bool value) -{ - d_ptr->m_UseUnregisteredAccount = value; -} - -bool NumberCompletionModel::isUsingUnregisteredAccounts() -{ - return d_ptr->m_UseUnregisteredAccount; -} - - -void NumberCompletionModel::setDisplayMostUsedNumbers(bool value) -{ - d_ptr->m_DisplayMostUsedNumbers = value; -} - -bool NumberCompletionModel::displayMostUsedNumbers() const -{ - return d_ptr->m_DisplayMostUsedNumbers; -} - -void NumberCompletionModelPrivate::resetSelectionModel() -{ - if (!m_pSelectionModel) - return; - - //const Account* preferredAccount = AvailableAccountModel::currentDefaultAccount(); - - //m_pSelectionModel->setCurrentIndex(index(idx,0), QItemSelectionModel::ClearAndSelect); - - m_HasCustomSelection = false; -} - -void NumberCompletionModelPrivate::slotSelectionChanged(const QModelIndex& sel, const QModelIndex& prev) -{ - Q_UNUSED(sel) - Q_UNUSED(prev) - m_HasCustomSelection = true; -} - -bool NumberCompletionModel::callSelectedNumber() -{ - if (!d_ptr->m_pSelectionModel || !d_ptr->m_pCall) - return false; - - const QModelIndex& idx = d_ptr->m_pSelectionModel->currentIndex(); - - if (!idx.isValid()) - return false; - - ContactMethod* nb = number(idx); - - if (!nb) - return false; - - if (d_ptr->m_pCall->lifeCycleState() != Call::LifeCycleState::CREATION) - return false; - - d_ptr->m_pCall->setDialNumber(nb); - d_ptr->m_pCall->setAccount(nb->account()); - - d_ptr->resetSelectionModel(); - - d_ptr->m_pCall->performAction(Call::Action::ACCEPT); - - setCall(nullptr); - - return true; -} - -QItemSelectionModel* NumberCompletionModel::selectionModel() const -{ - if (!d_ptr->m_pSelectionModel) { - d_ptr->m_pSelectionModel = new QItemSelectionModel(const_cast<NumberCompletionModel*>(this)); - connect(d_ptr->m_pSelectionModel, &QItemSelectionModel::currentChanged, d_ptr, &NumberCompletionModelPrivate::slotSelectionChanged); - } - - return d_ptr->m_pSelectionModel; -} - -bool NumberCompletionModelPrivate::accountAdded(Account* a) -{ - bool hasNonIp2Ip = false; - - switch(a->protocol()) { - case Account::Protocol::SIP : { - hasNonIp2Ip = true; - TemporaryContactMethod* cm = new TemporaryContactMethod(); - - if (!m_pPreferredTemporaryNumbers[(int)a->protocol()]) - m_pPreferredTemporaryNumbers[(int)a->protocol()] = cm; - - cm->setAccount(a); - m_hSipTemporaryNumbers[a] = cm; - } - break; - case Account::Protocol::RING: { - TemporaryContactMethod* cm = new TemporaryContactMethod(); - cm->setAccount(a); - m_hRingTemporaryNumbers[a] = cm; - - if (!m_pPreferredTemporaryNumbers[(int)Account::Protocol::RING]) - m_pPreferredTemporaryNumbers[(int)Account::Protocol::RING] = cm; - - } - break; - case Account::Protocol::COUNT__: - break; - } - - return hasNonIp2Ip; -} - -void NumberCompletionModelPrivate::accountRemoved(Account* a) -{ - TemporaryContactMethod* cm = m_hSipTemporaryNumbers[a]; - - if (!cm) - cm = m_hRingTemporaryNumbers[a]; - - m_hSipTemporaryNumbers[a] = nullptr; - m_hRingTemporaryNumbers [a] = nullptr; - - setPrefix(q_ptr->prefix()); - - if (cm) { - delete cm; - } -} - -#include <numbercompletionmodel.moc> diff --git a/src/numbercompletionmodel.h b/src/numbercompletionmodel.h deleted file mode 100644 index e93759c4..00000000 --- a/src/numbercompletionmodel.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2013-2018 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/>. * - ***************************************************************************/ -#pragma once - -#include <QtCore/QAbstractTableModel> -#include "typedefs.h" -#include "phonedirectorymodel.h" -#include <itemdataroles.h> - -//Qt -class QItemSelectionModel; - -//Ring -class ContactMethod; -class Call; - -//Private -class NumberCompletionModelPrivate; - -class LIB_EXPORT NumberCompletionModel : public QAbstractTableModel { - Q_OBJECT - -public: - - //Properties - Q_PROPERTY(QString prefix READ prefix) - Q_PROPERTY(bool displayMostUsedNumbers READ displayMostUsedNumbers WRITE setDisplayMostUsedNumbers) - - enum Role { - ALTERNATE_ACCOUNT= (int)Ring::Role::UserRole, - FORCE_ACCOUNT, - ACCOUNT , - PEER_NAME , - }; - - NumberCompletionModel(); - virtual ~NumberCompletionModel(); - - //Abstract model member - 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 int columnCount( const QModelIndex& parent = QModelIndex() ) const override; - virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; - - virtual QHash<int,QByteArray> roleNames() const override; - - //Setters - void setCall(Call* call); - void setUseUnregisteredAccounts(bool value); - void setDisplayMostUsedNumbers(bool value); - - //Getters - Call* call() const; - ContactMethod* number(const QModelIndex& idx) const; - bool isUsingUnregisteredAccounts(); - QString prefix() const; - bool displayMostUsedNumbers() const; - QItemSelectionModel* selectionModel() const; - -private: - NumberCompletionModelPrivate* d_ptr; - Q_DECLARE_PRIVATE(NumberCompletionModel) - -public Q_SLOTS: - bool callSelectedNumber(); - -Q_SIGNALS: - void enabled(bool); - -}; - diff --git a/src/pendingcontactrequestmodel.cpp b/src/pendingcontactrequestmodel.cpp deleted file mode 100644 index 894083af..00000000 --- a/src/pendingcontactrequestmodel.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015-2018 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 "pendingcontactrequestmodel.h" - -//Qt -#include <QtCore/QDateTime> - -//Ring -#include <contactrequest.h> -#include <certificate.h> -#include <account.h> -#include "private/pendingcontactrequestmodel_p.h" -#include "person.h" -#include "contactmethod.h" -#include "uri.h" - -PendingContactRequestModelPrivate::PendingContactRequestModelPrivate(PendingContactRequestModel* p) : q_ptr(p) -{} - -PendingContactRequestModel::PendingContactRequestModel(Account* a) : QAbstractTableModel(a), -d_ptr(new PendingContactRequestModelPrivate(this)) -{ - d_ptr->m_pAccount = a; -} - -PendingContactRequestModel::~PendingContactRequestModel() -{ - delete d_ptr; -} - -QVariant PendingContactRequestModel::data( const QModelIndex& index, int role ) const -{ - if (!index.isValid()) - return QVariant(); - - switch(index.column()) { - case Columns::PEER_ID: - switch(role) { - case Qt::DisplayRole: - return d_ptr->m_lRequests[index.row()]->peer()->phoneNumbers()[0]->bestId(); - } - break; - case Columns::TIME: - switch(role) { - case Qt::DisplayRole: - return d_ptr->m_lRequests[index.row()]->date(); - } - break; - case Columns::FORMATTED_NAME: - switch(role) { - case Qt::DisplayRole: - return d_ptr->m_lRequests[index.row()]->peer()->formattedName(); - } - break; - case Columns::COUNT__: - switch(role) { - case Qt::DisplayRole: - return static_cast<int>(PendingContactRequestModel::Columns::COUNT__); - } - break; - } - - return QVariant::fromValue(d_ptr->m_lRequests[index.row()]->roleData(role)); -} - -int PendingContactRequestModel::rowCount( const QModelIndex& parent ) const -{ - return parent.isValid()? 0 : d_ptr->m_lRequests.size(); -} - -int PendingContactRequestModel::columnCount( const QModelIndex& parent ) const -{ - return parent.isValid()? 0 : static_cast<int>(PendingContactRequestModel::Columns::COUNT__); -} - -Qt::ItemFlags PendingContactRequestModel::flags( const QModelIndex& index ) const -{ - Q_UNUSED(index); - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; -} - -bool PendingContactRequestModel::setData( const QModelIndex& index, const QVariant &value, int role) -{ - Q_UNUSED(index) - Q_UNUSED(value) - Q_UNUSED(role) - return false; -} - -QHash<int,QByteArray> PendingContactRequestModel::roleNames() const -{ - return {}; -} - -void PendingContactRequestModelPrivate::addRequest(ContactRequest* r) -{ - // do not add the same contact request several time - if(std::any_of(m_lRequests.begin(), m_lRequests.end(), - [&](ContactRequest* r_){ return *r_ == *r ;})) { - return; - } - - // update (remove old add new) contact request if the remoteIds match. - auto iter = std::find_if(m_lRequests.begin(), m_lRequests.end(), [&](ContactRequest* r_) { - return (r_->certificate()->remoteId() == r->certificate()->remoteId()); - }); - - if(iter) - removeRequest(*iter); - - q_ptr->beginInsertRows(QModelIndex(),m_lRequests.size(),m_lRequests.size()); - m_lRequests << r; - q_ptr->endInsertRows(); - - QObject::connect(r, &ContactRequest::requestAccepted, [this,r]() { - // the request was handled so it can be removed, from the pending list - removeRequest(r); - - // it's important to emit after the request was removed. - emit q_ptr->requestAccepted(r); - }); - - QObject::connect(r, &ContactRequest::requestDiscarded, [this,r]() { - // the request was handled so it can be removed, from the pending list - removeRequest(r); - - // it's important to emit after the request was removed. - emit q_ptr->requestDiscarded(r); - }); - - QObject::connect(r, &ContactRequest::requestBlocked, [this,r]() { - // the request was handled so it can be removed, from the pending list - removeRequest(r); - }); - - emit q_ptr->requestAdded(r); -} - -void PendingContactRequestModelPrivate::removeRequest(ContactRequest* r) -{ - const int index = m_lRequests.indexOf(r); - - if (index == -1) - return; - - q_ptr->beginRemoveRows(QModelIndex(), index, index); - m_lRequests.removeAt(index); - q_ptr->endRemoveRows(); -} - -ContactRequest* -PendingContactRequestModel::findContactRequestFrom(const ContactMethod* cm) const -{ - auto iter = std::find_if(d_ptr->m_lRequests.begin(), d_ptr->m_lRequests.end(), - [&](ContactRequest* r){ return r->certificate()->remoteId() == cm->uri(); }); - if (iter != std::end(d_ptr->m_lRequests)) - return *iter; - return nullptr; -} diff --git a/src/pendingcontactrequestmodel.h b/src/pendingcontactrequestmodel.h deleted file mode 100644 index 4cfeaa43..00000000 --- a/src/pendingcontactrequestmodel.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015-2018 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/>. * - ***************************************************************************/ -#pragma once - -#include <QtCore/QAbstractTableModel> -#include <typedefs.h> - -class Account; -class PendingContactRequestModelPrivate; -class ContactRequest; -class ContactMethod; - -/** - * List the pending (incoming) trust request for an account - */ -class LIB_EXPORT PendingContactRequestModel : public QAbstractTableModel -{ - Q_OBJECT - - friend class Account; - friend class AccountPrivate; - friend class AccountModelPrivate; -public: - - enum Columns { - PEER_ID, - TIME, - FORMATTED_NAME, - COUNT__ - }; - - //Model functions - virtual QVariant data ( const QModelIndex& index, int role = Qt::DisplayRole ) const override; - virtual int rowCount ( const QModelIndex& parent = QModelIndex() ) const override; - virtual int columnCount ( 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 QHash<int,QByteArray> roleNames() const override; - - // Helper - ContactRequest* findContactRequestFrom(const ContactMethod* cm) const; - -private: - explicit PendingContactRequestModel(Account* a); - virtual ~PendingContactRequestModel(); - - PendingContactRequestModelPrivate* d_ptr; - Q_DECLARE_PRIVATE(PendingContactRequestModel) - -Q_SIGNALS: - void requestAccepted (ContactRequest* r); - void requestDiscarded(ContactRequest* r); - void requestAdded(ContactRequest* r); -}; - diff --git a/src/person.cpp b/src/person.cpp index abe282c0..8b1fe4ce 100644 --- a/src/person.cpp +++ b/src/person.cpp @@ -28,7 +28,6 @@ #include "accountmodel.h" #include "certificatemodel.h" #include "collectioninterface.h" -#include "transitionalpersonbackend.h" #include "account.h" #include "private/vcardutils.h" #include "personmodel.h" @@ -209,7 +208,8 @@ PersonPrivate::~PersonPrivate() Person::Person(CollectionInterface* parent): ItemBase(nullptr), d_ptr(new PersonPrivate(this)) { - setCollection(parent ? parent : &TransitionalPersonBackend::instance()); + if(!parent) return; + setCollection(parent); d_ptr->m_isPlaceHolder = false; d_ptr->m_lParents << this; @@ -218,7 +218,8 @@ Person::Person(CollectionInterface* parent): ItemBase(nullptr), Person::Person(const QByteArray& content, Person::Encoding encoding, CollectionInterface* parent) : ItemBase(nullptr), d_ptr(new PersonPrivate(this)) { - setCollection(parent ? parent : &TransitionalPersonBackend::instance()); + if(!parent) return; + setCollection(parent); d_ptr->m_isPlaceHolder = false; d_ptr->m_lParents << this; switch (encoding) { diff --git a/src/personmodel.cpp b/src/personmodel.cpp index 31322f5e..fba17050 100644 --- a/src/personmodel.cpp +++ b/src/personmodel.cpp @@ -31,7 +31,6 @@ #include "collectioninterface.h" #include "collectionmodel.h" #include "collectioneditor.h" -#include "transitionalpersonbackend.h" //Qt #include <QtCore/QHash> @@ -348,13 +347,6 @@ bool PersonModel::addPeerProfile(Person* person) { if (!person or not person->collection()) return false; - // check if this person is saved in the PeerProfileCollection, "ppc" - if (person->collection() != &TransitionalPersonBackend::instance() and - person->collection()->id() != "ppc") - { - qWarning() << "About to add Person to the PeerProfileCollection which is part of another collection"; - } - for (auto col : collections(CollectionInterface::SupportedFeatures::ADD)) { //Only add profile to peer profile collection if (col->id() == "ppc") { diff --git a/src/phonedirectorymodel.h b/src/phonedirectorymodel.h index 35309563..e4b8abf2 100644 --- a/src/phonedirectorymodel.h +++ b/src/phonedirectorymodel.h @@ -38,12 +38,9 @@ class NumberTreeBackend; //Private class PhoneDirectoryModelPrivate; -///CredentialModel: A model for account credentials +///PhoneDirectoryModel: A model for account phonedirectory class LIB_EXPORT PhoneDirectoryModel : public QAbstractTableModel { - //NumberCompletionModel need direct access to the indexes - friend class NumberCompletionModel; - friend class NumberCompletionModelPrivate; friend class MostPopularNumberModel; friend class CategorizedBookmarkModel; diff --git a/src/pixmapmanipulatordefault.cpp b/src/pixmapmanipulatordefault.cpp index a3668003..d5c055f0 100644 --- a/src/pixmapmanipulatordefault.cpp +++ b/src/pixmapmanipulatordefault.cpp @@ -22,9 +22,6 @@ #include <QtCore/QVariant> #include <QtCore/QModelIndex> -//Ring -#include <useractionmodel.h> - // LRC #include "api/account.h" #include "api/conversation.h" diff --git a/src/private/account_p.h b/src/private/account_p.h index a2048c75..32a99e73 100644 --- a/src/private/account_p.h +++ b/src/private/account_p.h @@ -28,13 +28,10 @@ class AccountPrivate; class ContactMethod; class CipherModel; -class AccountStatusModel; class TlsMethodModel; class ProtocolModel; class NetworkInterfaceModel; -class BootstrapModel; class DaemonCertificateCollection; -class PendingContactRequestModel; class Profile; typedef void (AccountPrivate::*account_function)(); @@ -97,16 +94,11 @@ public: void save (); void reloadMod() {reload();modify();} - CredentialModel* m_pCredentials ; - CodecModel* m_pCodecModel ; KeyExchangeModel* m_pKeyExchangeModel ; CipherModel* m_pCipherModel ; - AccountStatusModel* m_pStatusModel ; SecurityEvaluationModel* m_pSecurityEvaluationModel ; TlsMethodModel* m_pTlsMethodModel ; ProtocolModel* m_pProtocolModel ; - BootstrapModel* m_pBootstrapModel ; - RingDeviceModel* m_pRingDeviceModel ; QAbstractItemModel* m_pKnownCertificates ; QAbstractItemModel* m_pBannedCertificates ; QAbstractItemModel* m_pAllowedCertificates ; @@ -117,7 +109,6 @@ public: QMetaObject::Connection m_cTlsCert ; QMetaObject::Connection m_cTlsCaCert ; Profile* m_pProfile {nullptr} ; - PendingContactRequestModel* m_pPendingContactRequestModel; Account::ContactMethods m_NumbersFromDaemon ; BannedContactModel* m_pBannedContactModel {nullptr}; diff --git a/src/private/accountmodel_p.h b/src/private/accountmodel_p.h index 1e63b17e..15d96e3b 100644 --- a/src/private/accountmodel_p.h +++ b/src/private/accountmodel_p.h @@ -70,9 +70,7 @@ public Q_SLOTS: void slotVoiceMailNotify( const QString& accountID , int count ); void slotAccountPresenceEnabledChanged(bool state); void slotVolatileAccountDetailsChange(const QString& accountId, const MapStringString& details); - void slotMediaParametersChanged(const QString& accountId); void slotIncomingContactRequest(const QString& accountId, const QString& hash, const QByteArray& payload, time_t time); - void slotKownDevicesChanged(const QString& accountId, const MapStringString& devices); void slotExportOnRingEnded(const QString& accountId, int status, const QString& pin); void slotMigrationEnded(const QString& accountId, const QString& result); void slotContactAdded(const QString &accountID, const QString &uri, bool confirmed); diff --git a/src/private/call_p.h b/src/private/call_p.h index e66c53b0..21827285 100644 --- a/src/private/call_p.h +++ b/src/private/call_p.h @@ -34,7 +34,6 @@ class QTimer; //Ring class Account; class ContactMethod; -class UserActionModel; class InstantMessagingModel; class Certificate; @@ -118,7 +117,6 @@ public: time_t m_pStopTimeStamp ; Call::State m_CurrentState ; QTimer* m_pTimer ; - UserActionModel* m_pUserActionModel ; bool m_History ; bool m_Missed ; Call::Direction m_Direction ; diff --git a/src/private/pendingcontactrequestmodel_p.h b/src/private/pendingcontactrequestmodel_p.h deleted file mode 100644 index 4cc61f2d..00000000 --- a/src/private/pendingcontactrequestmodel_p.h +++ /dev/null @@ -1,39 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015-2018 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/>. * - ***************************************************************************/ -#pragma once - -class PendingContactRequestModel; -class ContactRequest; - -class PendingContactRequestModelPrivate -{ -public: - //Constructor - PendingContactRequestModelPrivate(PendingContactRequestModel* parent); - - //Attributes - QVector<ContactRequest*> m_lRequests; - Account* m_pAccount ; - - //Helper - void addRequest (ContactRequest* r); - void removeRequest(ContactRequest* r); - -private: - PendingContactRequestModel* q_ptr; -}; diff --git a/src/private/ringdevicemodel_p.h b/src/private/ringdevicemodel_p.h deleted file mode 100644 index 828bc605..00000000 --- a/src/private/ringdevicemodel_p.h +++ /dev/null @@ -1,40 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2016-2018 Savoir-faire Linux * - * Author : Alexandre Viau <alexandre.viau@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/>. * - ***************************************************************************/ - -#pragma once - -#include "ringdevice.h" -#include "ringdevicemodel.h" - -typedef void (RingDeviceModelPrivate::*RingDeviceModelPrivateFct)(); - -class RingDeviceModelPrivate -{ -public: - RingDeviceModelPrivate(RingDeviceModel* q,Account* a); - - //Attributes - Account* m_pAccount ; - QVector<RingDevice*> m_lRingDevices ; - RingDeviceModel* q_ptr ; - - void reload(); - void reload(MapStringString accountDevices); - void clearLines(); - -}; diff --git a/src/recentmodel.cpp b/src/recentmodel.cpp deleted file mode 100644 index 7943fcc1..00000000 --- a/src/recentmodel.cpp +++ /dev/null @@ -1,1300 +0,0 @@ -/************************************************************************************ - * Copyright (C) 2015-2018 Savoir-faire Linux * - * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> * - * Alexandre Lision <alexandre.lision@savoirfairelinux.com> * - * Stepan Salenikovich <stepan.salenikovich@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 Lesser General Public * - * License along with this library; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***********************************************************************************/ -#include "recentmodel.h" - -//std -#include <algorithm> - -//Qt -#include <QtCore/QCoreApplication> -#include <QtCore/QSortFilterProxyModel> - -//Ring -#include <call.h> -#include <person.h> -#include <personmodel.h> -#include <contactmethod.h> -#include <phonedirectorymodel.h> -#include <callmodel.h> -#include <categorizedhistorymodel.h> -#include <media/recordingmodel.h> -#include <media/textrecording.h> -#include "accountmodel.h" -#include "contactrequest.h" -#include "certificate.h" -#include "availableaccountmodel.h" -#include "pendingcontactrequestmodel.h" - -struct CallGroup -{ - QVector<Call*> m_lCalls ; - Call::Direction m_Direction; - bool m_Missed ; - time_t m_LastUsed ; -}; - -struct RecentViewNode -{ - //Types - enum class Type { - PERSON , - CONTACT_METHOD , - CALL , - CALL_GROUP , - CONFERENCE , - TEXT_MESSAGE , - TEXT_MESSAGE_GROUP, - }; - - //Constructor - explicit RecentViewNode(); - RecentViewNode(Call* c, RecentModelPrivate* model); - RecentViewNode(const Person *p, RecentModelPrivate* model); - RecentViewNode(ContactMethod *cm, RecentModelPrivate* model); - virtual ~RecentViewNode(); - - //Attributes - RecentModelPrivate* m_pModel ; - long int m_Index ; - Type m_Type ; - RecentViewNode* m_pParent ; - QList<RecentViewNode*> m_lChildren; - QMetaObject::Connection m_ConnectionChanged; - union { - const Person* m_pPerson ; - ContactMethod* m_pContactMethod; - Call* m_pCall ; - CallGroup* m_pCallGroup ; - //ImConversationIterator; //TODO - //ImConversationIterator; - } m_uContent; - - //Helpers - inline time_t lastUsed ( ) const; - RecentViewNode* childNode(Call *call) const; - void slotChanged( ); -}; - -class PeopleProxy : public QSortFilterProxyModel -{ - Q_OBJECT -public: - PeopleProxy(RecentModel* source_model); - - virtual QVariant data(const QModelIndex& index, int role) const override; -protected: - virtual bool filterAcceptsRow ( int sourceRow, const QModelIndex & sourceParent ) const override; - -}; - -class RecentModelPrivate : public QObject -{ - Q_OBJECT -public: - RecentModelPrivate(RecentModel* p); - - /* - * m_lTopLevelReverted hold the elements in the reverse order of - * QAbstractItemModel::index. This cause most of the energy to be - * in the bottom half of the vector, preventing std::move every time - * someone is contacted - */ - QList<RecentViewNode*> m_lTopLevelReverted; - QHash<const Person*,RecentViewNode*> m_hPersonsToNodes ; - QHash<ContactMethod*,RecentViewNode*> m_hCMsToNodes ; - QHash<Call*,RecentViewNode*> m_hCallsToNodes ; - QHash<Call*,RecentViewNode*> m_hConfToNodes ; - - QItemSelectionModel* m_pSelectionModel ; - - //Helper - void insertNode (RecentViewNode* n, time_t t, bool isNew); - void removeNode (RecentViewNode* n ); - RecentViewNode* parentNode (Call *call ) const; - void insertCallNode(RecentViewNode* parent, RecentViewNode* callNode); - void moveCallNode (RecentViewNode* destination, RecentViewNode* callNode); - void removeCall (RecentViewNode* callNode ); - void selectNode (RecentViewNode* node ) const; - -private: - RecentModel* q_ptr; - -public Q_SLOTS: - void slotLastUsedTimeChanged(const Person* p , time_t t ); - void slotPersonAdded (const Person* p ); - void slotPersonRemoved (const Person* p ); - void slotLastUsedChanged (ContactMethod* cm, time_t t ); - void slotContactChanged (ContactMethod* cm, const Person* np, const Person* op); - void slotCallAdded (Call* call , Call* parent ); - void slotChanged (RecentViewNode* node ); - void slotCallStateChanged (Call* call , Call::State previousState); - void slotConferenceAdded (Call* conf ); - void slotConferenceRemoved (Call* conf ); - void slotConferenceChanged (Call* conf ); - void slotCurrentCallChanged (const QModelIndex ¤t, const QModelIndex &previous); -}; - -RecentModelPrivate::RecentModelPrivate(RecentModel* p) : q_ptr(p) -{ - m_pSelectionModel = nullptr; -} - -QItemSelectionModel* RecentModel::selectionModel() const -{ - if (!d_ptr->m_pSelectionModel) { - d_ptr->m_pSelectionModel = new QItemSelectionModel(const_cast<RecentModel*>(this)); - } - return d_ptr->m_pSelectionModel; -} - -QStringList -RecentModel::getParticipantName(Call* call) const -{ - if (not call || call->type() != Call::Type::CONFERENCE) { - qWarning() << "Invalid use of getParticipantName"; - return QStringList(); - } - if (auto node = d_ptr->m_hConfToNodes[call]) { - QStringList participants; - Q_FOREACH(auto child, node->m_lChildren) { - participants << data(getIndex(child->m_uContent.m_pCall), static_cast<int>(Ring::Role::Name)).toString(); - } - return participants; - } - return QStringList(); -} - -int -RecentModel::getParticipantNumber(Call *call) const -{ - if (not call || call->type() != Call::Type::CONFERENCE) { - qWarning() << "Invalid use of getParticipantNumber"; - return 0; - } - if (auto node = d_ptr->m_hConfToNodes[call]) { - return node->m_lChildren.size(); - } - return 0; -} - -void RecentModelPrivate::selectNode(RecentViewNode* node) const -{ - const auto idx = q_ptr->createIndex(node->m_Index, 0, node); - - q_ptr->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect); -} - - -RecentModel::RecentModel(QObject* parent) : QAbstractItemModel(parent), d_ptr(new RecentModelPrivate(this)) -{ - connect(&PersonModel::instance() , &PersonModel::lastUsedTimeChanged , d_ptr, &RecentModelPrivate::slotLastUsedTimeChanged); - connect(&PersonModel::instance() , &PersonModel::newPersonAdded , d_ptr, &RecentModelPrivate::slotPersonAdded ); - connect(&PersonModel::instance() , &PersonModel::personRemoved , d_ptr, &RecentModelPrivate::slotPersonRemoved ); - connect(&PhoneDirectoryModel::instance(), &PhoneDirectoryModel::lastUsedChanged, d_ptr, &RecentModelPrivate::slotLastUsedChanged ); - connect(&PhoneDirectoryModel::instance(), &PhoneDirectoryModel::contactChanged , d_ptr, &RecentModelPrivate::slotContactChanged ); - connect(&CallModel::instance() , &CallModel::callAdded , d_ptr, &RecentModelPrivate::slotCallAdded ); - connect(&CallModel::instance() , &CallModel::callStateChanged , d_ptr, &RecentModelPrivate::slotCallStateChanged ); - connect(&CallModel::instance() , &CallModel::conferenceCreated , d_ptr, &RecentModelPrivate::slotConferenceAdded ); - connect(&CallModel::instance() , &CallModel::conferenceRemoved , d_ptr, &RecentModelPrivate::slotConferenceRemoved ); - connect(&CallModel::instance() , &CallModel::conferenceChanged , d_ptr, &RecentModelPrivate::slotConferenceChanged ); - connect(CallModel::instance().selectionModel(), &QItemSelectionModel::currentChanged, d_ptr, &RecentModelPrivate::slotCurrentCallChanged); - - //Fill the contacts - for (int i=0; i < PersonModel::instance().rowCount(); i++) { - auto person = qvariant_cast<Person*>(PersonModel::instance().data( - PersonModel::instance().index(i,0), - static_cast<int>(Person::Role::Object) - )); - - if (person && person->lastUsedTime()) - d_ptr->slotLastUsedTimeChanged(person, person->lastUsedTime()); - } - - //Fill the "orphan" contact methods - for (int i = 0; i < PhoneDirectoryModel::instance().rowCount(); i++) { - auto cm = qvariant_cast<ContactMethod*>(PhoneDirectoryModel::instance().data( - PhoneDirectoryModel::instance().index(i,0), - static_cast<int>(PhoneDirectoryModel::Role::Object) - )); - - if (cm && cm->lastUsed() && (!cm->contact() || cm->contact()->isPlaceHolder())) - d_ptr->slotLastUsedChanged(cm, cm->lastUsed()); - } - - //Get any ongoing calls (except conferences) - auto callList = CallModel::instance().getActiveCalls(); - for (int i = 0; i < callList.size(); ++i) { - auto call = callList.at(i); - if (call->type() != Call::Type::CONFERENCE) - d_ptr->slotCallAdded(call, nullptr); - } - - //Add any ongoing conferences - auto confList = CallModel::instance().getActiveConferences(); - for (int i = 0; i < confList.size(); ++i) { - auto conf = confList.at(i); - d_ptr->slotConferenceAdded(conf); - } - - // sync initial selection with the CallModel in case there are any ongoing Calls - d_ptr->slotCurrentCallChanged(CallModel::instance().selectionModel()->currentIndex(), QModelIndex()); -} - -RecentModel::~RecentModel() -{ - for (RecentViewNode* n : d_ptr->m_lTopLevelReverted) - delete n; - - delete d_ptr; -} - -RecentViewNode::RecentViewNode() -{ - -} - -RecentViewNode::RecentViewNode(Call* c, RecentModelPrivate *model) -{ - m_pModel = model ; - m_Type = c->type() == Call::Type::CONFERENCE ? RecentViewNode::Type::CONFERENCE : RecentViewNode::Type::CALL; - m_uContent.m_pCall = c ; - m_pParent = nullptr ; - m_Index = 0 ; - m_ConnectionChanged = QObject::connect(c, &Call::changed, [this](){this->slotChanged();}); -} - -RecentViewNode::RecentViewNode(const Person* p, RecentModelPrivate *model) -{ - m_pModel = model ; - m_Type = RecentViewNode::Type::PERSON; - m_uContent.m_pPerson = p ; - m_pParent = nullptr ; - m_Index = 0 ; - m_ConnectionChanged = QObject::connect(p, &Person::changed, [this](){this->slotChanged();}); -} - -RecentViewNode::RecentViewNode(ContactMethod *cm, RecentModelPrivate *model) -{ - m_pModel = model ; - m_Type = RecentViewNode::Type::CONTACT_METHOD; - m_uContent.m_pContactMethod = cm ; - m_pParent = nullptr ; - m_Index = 0 ; - m_ConnectionChanged = QObject::connect(cm, &ContactMethod::changed, [this](){this->slotChanged();}); -} - -RecentViewNode::~RecentViewNode() -{ - QObject::disconnect(m_ConnectionChanged); - for (RecentViewNode* n : m_lChildren) { - delete n; - } -} - -time_t RecentViewNode::lastUsed() const -{ - switch(m_Type) { - case Type::PERSON : - return m_uContent.m_pPerson->lastUsedTime(); - case Type::CONTACT_METHOD : - return m_uContent.m_pContactMethod->lastUsed(); - case Type::CALL : - case Type::CONFERENCE: - return m_uContent.m_pCall->stopTimeStamp(); - case Type::CALL_GROUP : - return m_uContent.m_pCallGroup->m_LastUsed; - case Type::TEXT_MESSAGE : - case Type::TEXT_MESSAGE_GROUP: - //TODO - break; - } - return {}; -} - -// returns the child node containing the given call, if it exists -RecentViewNode* -RecentViewNode::childNode(Call *call) const -{ - if (!call) - return {}; - - // only Person and CM nodes contains calls as children for now, so no need to check other types - if ( !(m_Type == RecentViewNode::Type::PERSON || m_Type == RecentViewNode::Type::CONTACT_METHOD) ) - return {}; - - auto itEnd = m_lChildren.cend(); - auto it = std::find_if (m_lChildren.cbegin(), - itEnd, [call] (RecentViewNode* child) { - return child->m_uContent.m_pCall == call; - }); - - if (it == itEnd) - return {}; - - return *it; -} - -void -RecentViewNode::slotChanged() -{ - m_pModel->slotChanged(this); -} - -RecentModel& RecentModel::instance() -{ - static auto instance = new RecentModel(QCoreApplication::instance()); - return *instance; -} - -/** - * Tries to find the given call in the RecentModel and return - * the corresponding index - */ -QModelIndex -RecentModel::getIndex(Call *call) const -{ - // first check if it is a conference - if (auto confNode = d_ptr->m_hConfToNodes.value(call)) - return index(confNode->m_Index, 0); - - if (auto callNode = d_ptr->m_hCallsToNodes.value(call)) { - if (callNode->m_pParent) - return index(callNode->m_Index, 0, index(callNode->m_pParent->m_Index, 0)); - } - - return {}; -} - -/** - * Tries to find the given Person in the RecentModel and return - * the corresponding index - */ -QModelIndex -RecentModel::getIndex(Person *p) const -{ - if (d_ptr->m_hPersonsToNodes.contains(p)) { - if (auto node = d_ptr->m_hPersonsToNodes.value(p)) - return index(node->m_Index, 0); - } - - return {}; -} - -/** - * Tries to find the given CM in the RecentModel and return - * the corresponding index - */ -QModelIndex -RecentModel::getIndex(ContactMethod *cm) const -{ - // check if the CM is an item the RecentModel - if (d_ptr->m_hCMsToNodes.contains(cm)) { - if (auto node = d_ptr->m_hCMsToNodes.value(cm)) - return index(node->m_Index, 0); - } - - // otherwise, its possible the CM is contained within a Person item - if (auto person = cm->contact()) - return getIndex(person); - - return {}; -} - - -/** - * Returns if the given index corresponds to an item in the RecentModel which is a conference - */ -bool -RecentModel::isConference(const QModelIndex& idx) const -{ - if (idx.isValid()) { - auto object = idx.data(static_cast<int>(Ring::Role::Object)); - if (auto call = object.value<Call *>()) - return call->type() == Call::Type::CONFERENCE; - } - return false; -} - -/** - * Check if given index has an ongoing call - * returns true if one of its child is also in the CallModel - */ -bool RecentModel::hasActiveCall(const QModelIndex &idx) -{ - if (not idx.isValid()) - return false; - - auto node = static_cast<RecentViewNode*>(idx.internalPointer()); - QListIterator<RecentViewNode*> lIterator(node->m_lChildren); - lIterator.toBack(); - while (lIterator.hasPrevious()) { - auto child = lIterator.previous(); - if (child->m_Type == RecentViewNode::Type::CALL) { - return CallModel::instance().getIndex(child->m_uContent.m_pCall).isValid(); - } - } - return false; -} - -/** - * Helper function to extract all ContactMethod from a given index - * The index must be of type ContactMethod, Person or Call - */ -QVector<ContactMethod*> -RecentModel::getContactMethods(const QModelIndex& idx) const -{ - auto result = QVector<ContactMethod*>(); - - RecentViewNode* node = static_cast<RecentViewNode*>(idx.internalPointer()); - if (!idx.isValid() || !node) { - return result; - } - - switch(node->m_Type) { - case RecentViewNode::Type::PERSON : - result << node->m_uContent.m_pPerson->phoneNumbers(); - return result; - case RecentViewNode::Type::CONTACT_METHOD : - result << node->m_uContent.m_pContactMethod; - return result; - case RecentViewNode::Type::CALL : - result << node->m_uContent.m_pCall->peerContactMethod(); - return result; - case RecentViewNode::Type::CALL_GROUP : - case RecentViewNode::Type::TEXT_MESSAGE : - case RecentViewNode::Type::TEXT_MESSAGE_GROUP: - case RecentViewNode::Type::CONFERENCE : - break; - } - return result; -} - -/** - * Return the first found ongoing call of the given index - * Index can be the call itself or the associated parent - */ -Call* RecentModel::getActiveCall(const QModelIndex &idx) -{ - if (not idx.isValid()) - return nullptr; - - RecentViewNode* node = static_cast<RecentViewNode*>(idx.internalPointer()); - - if (node->m_Type == RecentViewNode::Type::CALL - || node->m_Type == RecentViewNode::Type::CONFERENCE ) { - return node->m_uContent.m_pCall; - } - - QListIterator<RecentViewNode*> lIterator(node->m_lChildren); - lIterator.toBack(); - while (lIterator.hasPrevious()) { - auto child = lIterator.previous(); - if (child->m_Type == RecentViewNode::Type::CALL) { - return child->m_uContent.m_pCall; - } - } - return nullptr; -} - -QHash<int,QByteArray> RecentModel::roleNames() const -{ - static QHash<int, QByteArray> roles = QAbstractItemModel::roleNames(); - /*static bool initRoles = false; - if (!initRoles) { - initRoles = true; - }*/ - - return roles; -} - -bool RecentModel::setData( const QModelIndex& index, const QVariant &value, int role) -{ - Q_UNUSED(index) - Q_UNUSED(value) - Q_UNUSED(role) - return false; -} - -QVariant RecentModel::data( const QModelIndex& index, int role ) const -{ - if (!index.isValid()) - return QVariant(); - - RecentViewNode* node = static_cast<RecentViewNode*>(index.internalPointer()); - - switch(node->m_Type) { - case RecentViewNode::Type::PERSON : - return node->m_uContent.m_pPerson->roleData(role); - case RecentViewNode::Type::CONTACT_METHOD : - return node->m_uContent.m_pContactMethod->roleData(role); - case RecentViewNode::Type::CALL : - case RecentViewNode::Type::CONFERENCE : - return node->m_uContent.m_pCall->roleData(role); - case RecentViewNode::Type::CALL_GROUP : - return node->m_uContent.m_pCallGroup->m_lCalls[0]->roleData(role); - case RecentViewNode::Type::TEXT_MESSAGE : - case RecentViewNode::Type::TEXT_MESSAGE_GROUP: - //TODO - break; - } - - return QVariant(); -} - -int RecentModel::rowCount( const QModelIndex& parent ) const -{ - if (!parent.isValid()) - return d_ptr->m_lTopLevelReverted.size(); - - RecentViewNode* node = static_cast<RecentViewNode*>(parent.internalPointer()); - return node->m_lChildren.size(); -} - -Qt::ItemFlags RecentModel::flags( const QModelIndex& index ) const -{ - return index.isValid() ? Qt::ItemIsEnabled | Qt::ItemIsSelectable : Qt::NoItemFlags; -} - -int RecentModel::columnCount( const QModelIndex& parent ) const -{ - Q_UNUSED(parent) - return 1; -} - -QModelIndex RecentModel::parent( const QModelIndex& index ) const -{ - if (!index.isValid()) - return QModelIndex(); - - RecentViewNode* node = static_cast<RecentViewNode*>(index.internalPointer()); - - if (!node->m_pParent) - return QModelIndex(); - - return createIndex(node->m_pParent->m_Index, 0, node->m_pParent); -} - -QModelIndex RecentModel::index( int row, int column, const QModelIndex& parent) const -{ - if (!parent.isValid() && row >= 0 && row < d_ptr->m_lTopLevelReverted.size() && !column) - return createIndex(row, 0, d_ptr->m_lTopLevelReverted[d_ptr->m_lTopLevelReverted.size() - 1 - row]); - - if (!parent.isValid()) - return QModelIndex(); - - RecentViewNode* node = static_cast<RecentViewNode*>(parent.internalPointer()); - - if (row >= 0 && row < node->m_lChildren.size()) - return createIndex(row, 0, node->m_lChildren[row]); - - return QModelIndex(); -} - -QVariant RecentModel::headerData( int section, Qt::Orientation orientation, int role) const -{ - if (!section && role == Qt::DisplayRole && orientation == Qt::Horizontal) - return tr("Recent persons"); - - return QVariant(); -} - -/* - * Move rows around to keep the person/contactmethods ordered - * - * Further optimization: - * * Invert m_Index to avoid the O(N) loop when adding an item - */ -void RecentModelPrivate::insertNode(RecentViewNode* n, time_t t, bool isNew) -{ - //Don't bother with the sorted insertion and indexes housekeeping - if (m_lTopLevelReverted.isEmpty()) { - q_ptr->beginInsertRows(QModelIndex(),0,0); - m_lTopLevelReverted << n; - q_ptr->endInsertRows(); - return; - } - - //Compute the bounds, this is needed to use beginMoveRows - int newPos = 0; - - if (m_lTopLevelReverted.last()->lastUsed() > t) { - //NOTE std::lower_bound need the "value" argument to be the same type as the iterator - //this use the m_Index field to hold the time_t - static RecentViewNode fake; - fake.m_Index = static_cast<long int>(t); - - //NOTE Using std::lower_bound is officially supported on QList on all platforms - auto lower = std::lower_bound(m_lTopLevelReverted.begin(), m_lTopLevelReverted.end(), &fake, - [t](const RecentViewNode* a, const RecentViewNode* t2) -> bool { - return a->lastUsed() < t2->m_Index; - }); - - // the value pointed by the iterator returned by this function may also - // be equivalent to val, and not only greater - if (!isNew && n->m_Index == (*lower)->m_Index) { - newPos = (*lower)->m_Index; - } else - newPos = (*lower)->m_Index+1; - } - - //Begin the transaction - if (!isNew) { - if (newPos == n->m_Index) - return; //Nothing to do - if (not q_ptr->beginMoveRows(QModelIndex(), n->m_Index, n->m_Index, QModelIndex(), newPos)) { - qWarning() << "RecentModel: Invalid move detected index : " << n->m_Index - << "newPos: " << newPos << "size: " << m_lTopLevelReverted.size(); - return; - } - m_lTopLevelReverted.removeAt(m_lTopLevelReverted.size()-1-n->m_Index); - } - else - q_ptr->beginInsertRows(QModelIndex(),newPos,newPos); - - //Apply the transaction - m_lTopLevelReverted.insert(m_lTopLevelReverted.size() - newPos,n); - for (int i = 0 ; i < m_lTopLevelReverted.size(); ++i) { - m_lTopLevelReverted[i]->m_Index = m_lTopLevelReverted.size() - 1 - i; - } - - //Notify that the transaction is complete - if (!isNew) - q_ptr->endMoveRows(); - else - q_ptr->endInsertRows(); - -#if 0 - //Uncomment if there is issues - qDebug() << "\n\nList:" << m_lTopLevelReverted.size() << isNew; - for (int i = 0; i<m_lTopLevelReverted.size();i++) { - qDebug() << "|||" << m_lTopLevelReverted[i]->lastUsed() << m_lTopLevelReverted[i]->m_Index << q_ptr->data(q_ptr->index(m_lTopLevelReverted.size()-1-i,0),Qt::DisplayRole); - for (auto child : m_lTopLevelReverted[i]->m_lChildren) { - qDebug() << "|||" << "|||" << child << child->m_uContent.m_pCall->formattedName(); - } - } -#endif -} - -void RecentModelPrivate::removeNode(RecentViewNode* n) -{ - const int idx = n->m_Index; - - q_ptr->beginRemoveRows(QModelIndex(), idx, idx); - - m_lTopLevelReverted.removeOne(n); - - delete n; - - // update all indices after this one - for (int i = m_lTopLevelReverted.size() - 1 - idx; i >= 0; --i) { - --m_lTopLevelReverted[i]->m_Index; - } - - q_ptr->endRemoveRows(); -} - -void RecentModelPrivate::slotPersonAdded(const Person* p) -{ - if (!p) return; - - // make sure all the CMs associated with this Person are moved into this Person's node - for ( const auto contactMethod : p->phoneNumbers() ) { - slotContactChanged(contactMethod, p, nullptr); - } -} - -void RecentModelPrivate::slotPersonRemoved(const Person* p) -{ - // delete p from contacts - RecentViewNode* n = m_hPersonsToNodes.value(p); - const bool isNewContact = !n; - - if ( isNewContact ) - return; - - removeNode(n); - - // but keep the conversation - for ( const auto cmToAdd : p->phoneNumbers() ) { - const bool isNewCm = !m_hCMsToNodes.value(cmToAdd); - n = new RecentViewNode(cmToAdd, this); - m_hCMsToNodes[cmToAdd] = n; - insertNode(n, cmToAdd->lastUsed(), isNewCm); - } -} - -void RecentModelPrivate::slotLastUsedTimeChanged(const Person* p, time_t t) -{ - RecentViewNode* n = m_hPersonsToNodes.value(p); - const bool isNew = !n; - - if (isNew) { - n = new RecentViewNode(p, this); - n->m_pParent = nullptr; - m_hPersonsToNodes[p] = n; - } - - insertNode(n, t, isNew); -} - -void RecentModelPrivate::slotLastUsedChanged(ContactMethod* cm, time_t t) -{ - //ContactMethod with a Person are handled elsewhere - if (!cm->contact() || cm->contact()->isPlaceHolder()) { - RecentViewNode* n = m_hCMsToNodes.value(cm); - const bool isNew = !n; - - if (isNew) { - n = new RecentViewNode(cm, this); - m_hCMsToNodes[cm] = n; - } - insertNode(n, t, isNew); - } -} - -///(Re)move the ContactMethod node once they are associated with a (new) Person -void RecentModelPrivate::slotContactChanged(ContactMethod* contactMethod, const Person* newPerson, const Person* oldPerson) -{ - // TODO: implement for when the Person of the CM changes, ie: oldPerson != nullptr - Q_UNUSED(oldPerson) - - if (not newPerson - or /* avoid to add en entry in recent model when a person was built for a contact request */ - (contactMethod->account() - and contactMethod->account()->pendingContactRequestModel()->findContactRequestFrom(contactMethod))) - return; - - // make sure the Person node exists first, then move any children of the CM nodes - slotLastUsedTimeChanged(newPerson, newPerson->lastUsedTime()); - - if (!newPerson->phoneNumbers().contains(contactMethod)) - qWarning() << "CM has new Person parent, but is not contained in its list of CMs"; - - // m_hCMsToNodes contains RecentViewNode pointers, take will return a default - // constructed ptr (e.g nullptr) if key is not in the QHash - if (auto oldParentNode = m_hCMsToNodes.take(contactMethod)) { - - // move any child nodes (Calls) to new Person - if (auto newParentNode = m_hPersonsToNodes.value(newPerson)) { - // we need to make a copy of the container since we're modifying it - const auto callListCopy = oldParentNode->m_lChildren; - for (const auto &callNode : callListCopy) { - moveCallNode(newParentNode, callNode); - } - - // check if the node we will remove is the selected node and select the new node - auto selectedIdx = q_ptr->selectionModel()->currentIndex(); - auto oldIdx = q_ptr->createIndex(oldParentNode->m_Index, 0, oldParentNode); - if (selectedIdx == oldIdx) - selectNode(newParentNode); - - removeNode(oldParentNode); - } else { - qWarning("RecentModel: ContactMethod has new Person, but corresponding Person node doesn't exist"); - } - } -} - -void -RecentModelPrivate::insertCallNode(RecentViewNode *parent, RecentViewNode* callNode) -{ - if (!parent) { - qWarning() << "parent node is null while trying to insert a call node"; - return; - } - - if (!callNode) { - qWarning() << "call node is null when trying to insert a call node"; - return; - } - - // make sure the parent is a Person or CM - // TODO: allow conference parent - if ( ! (parent->m_Type == RecentViewNode::Type::PERSON - || parent->m_Type == RecentViewNode::Type::CONTACT_METHOD) ) { - qWarning() << "parent of Call Node must be a Person or Contact Method"; - return; - } - - callNode->m_pParent = parent; - callNode->m_Index = parent->m_lChildren.size(); - - auto parentIdx = q_ptr->index(parent->m_Index,0); - - q_ptr->beginInsertRows(parentIdx, callNode->m_Index, callNode->m_Index); - parent->m_lChildren.append(callNode); - q_ptr->endInsertRows(); - - // emit dataChanged on parent, since number of children has changed - emit q_ptr->dataChanged(parentIdx, parentIdx); - - if (parent->m_lChildren.size() > 1) { - // emit a dataChanged on the first call so that the PeopleProxy - // now shows the first call (otherwise it will only show the 2nd +) - auto firstChild = q_ptr->index(0, 0, parentIdx); - emit q_ptr->dataChanged(firstChild, firstChild); - } - - /* in the case of a conference, we select the call; - * in case the parent only has one call, we select the parent; - * in case the parent has multiple calls, we select the call; - */ - auto callIdx = q_ptr->index(callNode->m_Index, 0, parentIdx); - if (q_ptr->isConference(callIdx) || q_ptr->isConference(parentIdx) || q_ptr->rowCount(parentIdx) > 1) - q_ptr->selectionModel()->setCurrentIndex(callIdx, QItemSelectionModel::ClearAndSelect); - else - q_ptr->selectionModel()->setCurrentIndex(callIdx.parent(), QItemSelectionModel::ClearAndSelect); -} - -void -RecentModelPrivate::moveCallNode(RecentViewNode* destination, RecentViewNode* callNode) -{ - if (not callNode->m_pParent) { - qWarning() << "Trying to move call node with invalid parent"; - return; - } - if (callNode->m_Type != RecentViewNode::Type::CALL) { - qWarning() << "cannot move node which is not of type call" << callNode; - return; - } - - auto parentNode = callNode->m_pParent; - auto parent = q_ptr->index(parentNode->m_Index, 0); - const auto removedIndex = callNode->m_Index; - - // check if this call was selected, so that we can re-select the same one after its moved - auto selected = false; - auto selectedIdx = q_ptr->selectionModel()->currentIndex(); - auto oldIdx = q_ptr->index(removedIndex, 0, parent); - if (selectedIdx == oldIdx) - selected = true; - - q_ptr->beginRemoveRows(parent, removedIndex, removedIndex); - - parentNode->m_lChildren.removeAt(removedIndex); - - // update the indices of the remaining children - for (int i = removedIndex; i < parentNode->m_lChildren.size(); ++i) { - if (auto child = parentNode->m_lChildren.at(i)) - --child->m_Index; - } - q_ptr->endRemoveRows(); - - callNode->m_pParent = destination; - callNode->m_Index = destination->m_lChildren.size(); - auto destIdx = q_ptr->index(destination->m_Index, 0); - q_ptr->beginInsertRows(destIdx, callNode->m_Index, callNode->m_Index); - destination->m_lChildren.append(callNode); - q_ptr->endInsertRows(); - - if (parentNode->m_lChildren.size() == 1) { - // there is now only one call, emit dataChanged on it so it becomes hidden in the PeopleProxy - auto firstChild = q_ptr->index(0, 0, parent); - emit q_ptr->dataChanged(firstChild, firstChild); - } - // emit dataChanged on the parent since the number of children has changed - emit q_ptr->dataChanged(parent, parent); - - if (selected) - selectNode(callNode); -} - -void -RecentModelPrivate::removeCall(RecentViewNode* callNode) -{ - if (callNode->m_Type != RecentViewNode::Type::CALL) { - qWarning() << "cannot remove node which is not of type call" << callNode; - return; - } - - m_hCallsToNodes.remove(callNode->m_uContent.m_pCall); - - // if it was in the RecentModel, then we need to emit rowsRemoved - if (auto parentNode = callNode->m_pParent) { - auto parent = q_ptr->index(parentNode->m_Index, 0); - const auto removedIndex = callNode->m_Index; - - q_ptr->beginRemoveRows(parent, removedIndex, removedIndex); - - parentNode->m_lChildren.removeAt(removedIndex); - - // update the indices of the remaining children - for (int i = removedIndex; i < parentNode->m_lChildren.size(); ++i) { - if (auto child = parentNode->m_lChildren.at(i)) - --child->m_Index; - } - q_ptr->endRemoveRows(); - - if (parentNode->m_lChildren.size() == 1) { - // there is now only one call, emit dataChanged on it so it becomes hidden in the PeopleProxy - auto firstChild = q_ptr->index(0, 0, parent); - emit q_ptr->dataChanged(firstChild, firstChild); - } - // emit dataChanted on the parent since the number of children has changed - emit q_ptr->dataChanged(parent, parent); - } - delete callNode; -} - -void -RecentModelPrivate::slotCallAdded(Call* call, Call* parent) -{ - Q_UNUSED(parent) - if(!call) { - qWarning() << "callAdded on nullptr"; - return; - } - - // new call, create Call node and try to find its parent - // if we find a parent, insert the Call node into the model, otherwise it will be done in slotChanged - auto callNode = new RecentViewNode(call, this); - m_hCallsToNodes[call] = callNode; - - // check if call is associated with a Person or CM yet - if (auto parent = parentNode(call)) { - insertCallNode(parent, callNode); - } -} - -// helper method to find parent node of a call, if it exists -RecentViewNode* -RecentModelPrivate::parentNode(Call *call) const -{ - if (!call) - return {}; - - if (auto p = call->peerContactMethod()->contact()) { - // if we don't find the Person in our list of nodes, then we want to check the list of CMs - if (m_hPersonsToNodes.contains(p)) - return m_hPersonsToNodes.value(p); - } - return m_hCMsToNodes.value(call->peerContactMethod()); -} - -void -RecentModelPrivate::slotChanged(RecentViewNode *node) -{ - if(!node) { - qWarning() << "changed called on null RecentViewNode"; - return; - } - switch (node->m_Type) { - case RecentViewNode::Type::PERSON: - case RecentViewNode::Type::CONTACT_METHOD: - case RecentViewNode::Type::CONFERENCE: - { - auto idx = q_ptr->index(node->m_Index, 0); - emit q_ptr->dataChanged(idx, idx); - } - break; - case RecentViewNode::Type::CALL: - { - // make sure the Call has a parent, else try to find one - if (node->m_pParent) { - auto parent = q_ptr->index(node->m_pParent->m_Index, 0); - auto idx = q_ptr->index(node->m_Index, 0, parent); - emit q_ptr->dataChanged(parent, parent); - emit q_ptr->dataChanged(idx, idx); - } else { - if (auto parent = parentNode(node->m_uContent.m_pCall)) { - insertCallNode(parent, node); - } - } - } - break; - case RecentViewNode::Type::CALL_GROUP: - case RecentViewNode::Type::TEXT_MESSAGE: - case RecentViewNode::Type::TEXT_MESSAGE_GROUP: - // nothing to do for now - break; - } -} - -void -RecentModelPrivate::slotCallStateChanged(Call* call, Call::State previousState) -{ - Q_UNUSED(previousState) - - if (auto callNode = m_hCallsToNodes.value(call)) { - switch(call->state()) { - case Call::State::COUNT__: - case Call::State::ERROR: - case Call::State::ABORTED: - case Call::State::OVER: - removeCall(callNode); - break; - case Call::State::TRANSFERRED: - case Call::State::INCOMING: - case Call::State::RINGING: - case Call::State::INITIALIZATION: - case Call::State::CONNECTED: - case Call::State::CURRENT: - case Call::State::DIALING: - case Call::State::NEW: - case Call::State::HOLD: - case Call::State::FAILURE: - case Call::State::BUSY: - case Call::State::TRANSF_HOLD: - case Call::State::CONFERENCE: - case Call::State::CONFERENCE_HOLD: - break; - }; - } -} - -void -RecentModelPrivate::slotConferenceRemoved(Call* conf) -{ - RecentViewNode* n = m_hConfToNodes[conf]; - - if (n) { - foreach (RecentViewNode* node, n->m_lChildren) { - if (node->m_uContent.m_pCall->lifeCycleState() != Call::LifeCycleState::PROGRESS) - removeCall(node); - else { - moveCallNode(parentNode(node->m_uContent.m_pCall), node); - } - } - removeNode(n); - m_hConfToNodes.remove(conf); - } -} - -void -RecentModelPrivate::slotConferenceAdded(Call* conf) -{ - RecentViewNode* n = m_hConfToNodes[conf]; - const bool isNew = !n; - - if (isNew) { - n = new RecentViewNode(conf, this); - m_hConfToNodes[conf] = n; - } - insertNode(n, conf->startTimeStamp(), isNew); - - // move the participants after inserting the node - auto pList = CallModel::instance().getConferenceParticipants(conf); - foreach (Call* p, pList) { - moveCallNode(n, m_hCallsToNodes.value(p)); - } - - // Select the newly created conference - q_ptr->selectionModel()->setCurrentIndex(q_ptr->getIndex(conf), QItemSelectionModel::ClearAndSelect); -} - -void RecentModelPrivate::slotConferenceChanged(Call* conf) -{ - if (auto confNode = m_hConfToNodes.value(conf)) { - auto pSet = QSet<Call*>::fromList(CallModel::instance().getConferenceParticipants(conf)); - if (pSet.isEmpty()) { - slotConferenceRemoved(conf); - return; - } - if (confNode->m_lChildren.size() == pSet.size()) - return; - QSet<Call*> confPSet; - foreach(const RecentViewNode* node, confNode->m_lChildren) { - confPSet.insert(node->m_uContent.m_pCall); - } - if (confPSet.size() > pSet.size()) { - confPSet = confPSet.subtract(pSet); - foreach(Call* call, confPSet) { - removeCall(m_hCallsToNodes.value(call)); - } - } else { - pSet = pSet.subtract(confPSet); - foreach(Call* call, pSet) { - moveCallNode(confNode, m_hCallsToNodes.value(call)); - } - // Reselect the conference - q_ptr->selectionModel()->setCurrentIndex(q_ptr->getIndex(conf), QItemSelectionModel::ClearAndSelect); - - } - } -} - -void -RecentModelPrivate::slotCurrentCallChanged(const QModelIndex ¤t, const QModelIndex &previous) -{ - Q_UNUSED(previous) - - auto callIdx = q_ptr->getIndex(CallModel::instance().getCall(current)); - if (callIdx.isValid()) { - /* in the case of a conference, we select the call; - * in case the parent only has one call, we select the parent; - * in case the parent has multiple calls, we select the call; - */ - auto parentIdx = callIdx.parent(); - if (q_ptr->isConference(callIdx) || q_ptr->isConference(parentIdx) || q_ptr->rowCount(parentIdx) > 1) - q_ptr->selectionModel()->setCurrentIndex(callIdx, QItemSelectionModel::ClearAndSelect); - else - q_ptr->selectionModel()->setCurrentIndex(callIdx.parent(), QItemSelectionModel::ClearAndSelect); - } else { - /* nothing is selected in the CallModel; however, if we still have a call selected in the - * RecentModel, we need to select it in the CallModel, or else all the actions of the call - * will be invalid, since the UserActionModel is based on the selection of the CallModel */ - auto recentIdx = q_ptr->selectionModel()->currentIndex(); - auto recentCall = q_ptr->getActiveCall(recentIdx); - if (recentIdx.isValid() && recentCall) { - CallModel::instance().selectCall(recentCall); - } - /* otherwise do not update the selection in the RecentModel, eg: if a Person was selected - * and the Call is over, we still want the Person to be selected */ - } -} - -///Filter out every data relevant to a person -QSortFilterProxyModel* -RecentModel::peopleProxy() const -{ - static PeopleProxy* p = new PeopleProxy(const_cast<RecentModel*>(this)); - return p; -} - -PeopleProxy::PeopleProxy(RecentModel* sourceModel) -{ - setSourceModel(sourceModel); - - /* since the filterAcceptsRow depends on the selected account, we need to re-run the filtering - * when the selected account changes automatically */ - connect( AvailableAccountModel::instance().selectionModel(), - &QItemSelectionModel::currentChanged, [this]() {this->invalidateFilter();}); -} - - - -/** - * This is the filtering function of the PeopleProxy. The PeopleProxy is essentially the "smart list" in - * the clients that implement one. The desired behaviour is to group ContactMethods which belong to the - * same contact (Person) under one item. Furthermore, we want to filter out items which do not belong to the - * currentDefaultAccount() of the AvailableAccountModel. The only exception are items which currently have - * an active Call since we always want the user to see any ongoing calls. We don't want the user to have - * to take any action to see ongoing Calls. - * - * We also implement a fitler based on the filterRegExp() string of the model. It will try to find any - * name or URI associated with the item which contains the string (case insensitive) and filter out - * eveything else. Again, the only exception is Calls, in case a user forgets to clear the search entry. - */ -bool -PeopleProxy::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const -{ - auto chosenAccount = AvailableAccountModel::instance().currentDefaultAccount(); - - //we filter only on top nodes - if (!sourceParent.isValid()) { - auto idx = sourceModel()->index(sourceRow, 0); - auto type = idx.data(static_cast<int>(Ring::Role::ObjectType)).value<Ring::ObjectType>(); - auto object = idx.data(static_cast<int>(Ring::Role::Object)); - - // get set of CMs with active calls - auto activeCalls = CallModel::instance().getActiveCalls(); - QSet<const ContactMethod *> activeCallCMs; - for (auto call : activeCalls) { - activeCallCMs << call->peerContactMethod(); - } - - Person *person = nullptr; - auto filterFunction = [&person, chosenAccount, this, activeCallCMs] (const ContactMethod* cm) { - auto passesFilter = false; - - // never filter out items with active calls - if (activeCallCMs.contains(cm)) return true; - - // filter everything out if there is no account chosen - if (not chosenAccount) return false; - - // only proceed if there is no account set yet, or if it matches the chosen account - if ( !cm->account() or (cm->account() == chosenAccount)) { - /* we need to check the Person name as well as any identifier of the - * ContactMethod. - * note: QString::contains() will return true for an empty param string - */ - passesFilter = - (person and person->formattedName().contains(filterRegExp())) or - cm->uri().full().contains(filterRegExp()) or - cm->registeredName().contains(filterRegExp()) or - cm->primaryName().contains(filterRegExp()); - } - return passesFilter; - }; - - //we want to filter on name and number; note that Person object may have many numbers - switch (type) { - case Ring::ObjectType::Person: - { - person = object.value<Person *>(); - const auto personCMs = person->phoneNumbers(); - - return std::any_of(std::begin(personCMs), std::end(personCMs), filterFunction); - } - case Ring::ObjectType::ContactMethod: - { - auto cm = object.value<ContactMethod *>(); - - return filterFunction(cm); - } - case Ring::ObjectType::Call: - return true; - - // top nodes are only of type Person, ContactMethod or Call - case Ring::ObjectType::Media: - case Ring::ObjectType::Certificate: - case Ring::ObjectType::ContactRequest: - case Ring::ObjectType::COUNT__: - break; - } - - return false; // no matches - } - //in the case of children, only show if there is more than one unless it is a conference - if (static_cast<RecentModel *>(sourceModel())->isConference(sourceParent) - || sourceModel()->rowCount(sourceParent) > 1 ) - return true; - return false; -} - -QVariant -PeopleProxy::data(const QModelIndex& index, int role) const -{ - auto indexSource = this->mapToSource(index); - - if (!indexSource.isValid()) - return QVariant(); - - //This proxy model filters out single calls, so in this case we want to forward certain data - //from the call to its parent - RecentViewNode* node = static_cast<RecentViewNode*>(indexSource.internalPointer()); - bool topNode = node->m_Type == RecentViewNode::Type::PERSON || - node->m_Type == RecentViewNode::Type::CONTACT_METHOD; - bool forwardRole = role == static_cast<int>(Ring::Role::State) || - role == static_cast<int>(Ring::Role::FormattedState) || - role == static_cast<int>(Ring::Role::Length); - if ( topNode && forwardRole ) { - if (sourceModel()->rowCount(indexSource) == 1) { - auto child = sourceModel()->index(0, 0, indexSource); - return sourceModel()->data(child, role); - } - } - - return sourceModel()->data(indexSource, role); -} - -#include <recentmodel.moc> diff --git a/src/recentmodel.h b/src/recentmodel.h deleted file mode 100644 index b88f04f3..00000000 --- a/src/recentmodel.h +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************************ - * Copyright (C) 2015-2018 Savoir-faire Linux * - * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> * - * Alexandre Lision <alexandre.lision@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 Lesser General Public * - * License along with this library; if not, write to the Free Software * - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***********************************************************************************/ -#pragma once - -#include <QtCore/QAbstractItemModel> -#include <QtCore/QItemSelectionModel> - -#include <typedefs.h> - -class QSortFilterProxyModel; -class RecentModelPrivate; -class Call; -class Person; -class ContactMethod; - -class LIB_EXPORT RecentModel : public QAbstractItemModel -{ - Q_OBJECT -public: - - //Model implementation - virtual bool setData ( const QModelIndex& index, const QVariant& value, int role ) override; - 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 int columnCount ( const QModelIndex& parent = QModelIndex() ) const override; - virtual QModelIndex parent ( const QModelIndex& index ) const override; - virtual QModelIndex index ( int row, int column, const QModelIndex& parent=QModelIndex()) const override; - virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; - virtual QHash<int,QByteArray> roleNames() const override; - - //Proxy - QSortFilterProxyModel* peopleProxy() const; - - //Singleton - static RecentModel& instance(); - - QModelIndex getIndex (Call* call ) const; - QModelIndex getIndex (Person* p ) const; - QModelIndex getIndex (ContactMethod* cm ) const; - bool isConference (const QModelIndex& idx ) const; - bool hasActiveCall(const QModelIndex& parent) ; - QVector<ContactMethod*> getContactMethods(const QModelIndex& idx) const; - Call* getActiveCall(const QModelIndex& parent) ; - QItemSelectionModel* selectionModel( ) const; - QStringList getParticipantName(Call* call ) const; - int getParticipantNumber(Call* call ) const; - -private: - explicit RecentModel(QObject* parent = nullptr); - virtual ~RecentModel(); - - RecentModelPrivate* d_ptr; - Q_DECLARE_PRIVATE(RecentModel) -}; -Q_DECLARE_METATYPE(RecentModel*) diff --git a/src/ringdevice.cpp b/src/ringdevice.cpp deleted file mode 100644 index d4d63148..00000000 --- a/src/ringdevice.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2016-2018 Savoir-faire Linux * - * Author : Alexandre Viau <alexandre.viau@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/>. * - ***************************************************************************/ - -// Qt -#include <QtCore/QObject> - -#include "ringdevice.h" - - -class RingDevicePrivate final : public QObject -{ -public: - Q_OBJECT - Q_DECLARE_PUBLIC(RingDevice) - - RingDevice* q_ptr ; - QString m_ID ; - QString m_Name ; - - // Constructor - explicit RingDevicePrivate(RingDevice* device); -}; - -RingDevicePrivate::RingDevicePrivate(RingDevice* device) : QObject(device), q_ptr(device) -{ -} - - ///Constructors -RingDevice::RingDevice(const QString& id, const QString& name) -{ - d_ptr = new RingDevicePrivate(this); - d_ptr->m_ID = id; - d_ptr->m_Name = name; -} - -const QString RingDevice::id() const -{ - return d_ptr->m_ID; -} - -const QString RingDevice::name() const -{ - return d_ptr->m_Name; -} - -#define CAST(item) static_cast<int>(item) -QVariant RingDevice::columnData(int column) const -{ - switch(column) { - case CAST(RingDevice::Column::Id): - return id(); - case CAST(RingDevice::Column::Name): - return name(); - default: - return QVariant(); - } -} -#undef CAST - - -#include <ringdevice.moc> diff --git a/src/ringdevice.h b/src/ringdevice.h deleted file mode 100644 index 900dbb47..00000000 --- a/src/ringdevice.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2016-2018 Savoir-faire Linux * - * Author : Alexandre Viau <alexandre.viau@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/>. * - ***************************************************************************/ -#pragma once - -#include <typedefs.h> -#include <itembase.h> - -class RingDevicePrivate; - - -class LIB_EXPORT RingDevice : public ItemBase -{ - Q_OBJECT - - friend class RingDeviceModel; - friend class RingDeviceModelPrivate; - -public: - - enum class Column { - Id = 0, - Name - }; - - Q_PROPERTY(QString id READ id ) - Q_PROPERTY(QString name READ name) - - //Getters - const QString id ( ) const; - const QString name ( ) const; - Q_INVOKABLE QVariant columnData (int column) const; - - -private: - RingDevice(const QString& id, const QString& name); - RingDevicePrivate* d_ptr; - Q_DECLARE_PRIVATE(RingDevice) -}; - -Q_DECLARE_METATYPE(RingDevice*) diff --git a/src/ringdevicemodel.h b/src/ringdevicemodel.h deleted file mode 100644 index 2c73b92c..00000000 --- a/src/ringdevicemodel.h +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2016-2018 Savoir-faire Linux * - * Author : Alexandre Viau <alexandre.viau@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/>. * - ***************************************************************************/ -#pragma once - -#include <QtCore/QAbstractTableModel> - -#include <typedefs.h> - -class Account; - -class RingDeviceModelPrivate; - -class LIB_EXPORT RingDeviceModel : public QAbstractTableModel -{ - Q_OBJECT -public: - friend class Account; - friend class AccountModelPrivate; - - //Abstract model accessors - virtual QVariant data ( const QModelIndex& index, int role = Qt::DisplayRole ) const override; - virtual QVariant headerData ( int section, Qt::Orientation orientation, int role ) const override; - virtual int rowCount ( const QModelIndex& parent = QModelIndex() ) const override; - virtual int columnCount ( const QModelIndex& parent = QModelIndex() ) const override; - virtual Qt::ItemFlags flags (const QModelIndex &index ) const override; - - virtual int size ( ) const; - -private: - explicit RingDeviceModel(Account* a); - virtual ~RingDeviceModel(); - - RingDeviceModelPrivate* d_ptr; - Q_DECLARE_PRIVATE(RingDeviceModel) - -}; diff --git a/src/ringtonemodel.h b/src/ringtonemodel.h index 3d1d311c..121a9bac 100644 --- a/src/ringtonemodel.h +++ b/src/ringtonemodel.h @@ -30,7 +30,7 @@ class Account; class RingtoneModelPrivate; class Ringtone; -///CredentialModel: A model for account credentials +///RingtoneModel: A model for account ringtons class LIB_EXPORT RingtoneModel : public QAbstractTableModel, public CollectionManagerInterface<Ringtone> { Q_OBJECT diff --git a/src/transitionalpersonbackend.cpp b/src/transitionalpersonbackend.cpp deleted file mode 100644 index fd1b3c16..00000000 --- a/src/transitionalpersonbackend.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2014-2018 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 "transitionalpersonbackend.h" -#include <personmodel.h> - -#include <collectioneditor.h> - -#include "globalinstances.h" -#include "interfaces/pixmapmanipulatori.h" - -class TransitionalPersonBackendPrivate -{ - -}; - -class TransitionalPersonEditor final : public CollectionEditor<Person> -{ -public: - TransitionalPersonEditor(CollectionMediator<Person>* m) : CollectionEditor<Person>(m) {} - virtual bool save ( const Person* item ) override; - virtual bool remove ( const Person* item ) override; - virtual bool edit ( Person* item ) override; - virtual bool addNew ( Person* item ) override; - virtual bool addExisting( const Person* item ) override; - -private: - virtual QVector<Person*> items() const override; -}; - -bool TransitionalPersonEditor::save(const Person* item) -{ - Q_UNUSED(item) - return false; -} - -bool TransitionalPersonEditor::remove(const Person* item) -{ - Q_UNUSED(item) - return false; -} - -bool TransitionalPersonEditor::edit( Person* item) -{ - Q_UNUSED(item) - return false; -} - -bool TransitionalPersonEditor::addNew( Person* item) -{ - Q_UNUSED(item) - return false; -} - -bool TransitionalPersonEditor::addExisting(const Person* item) -{ - Q_UNUSED(item) - return false; -} - - -QVector<Person*> TransitionalPersonEditor::items() const -{ - return QVector<Person*>(); -} - -CollectionInterface& TransitionalPersonBackend::instance() -{ - static auto instance = PersonModel::instance().addCollection<TransitionalPersonBackend>(); - return *instance; -} - -TransitionalPersonBackend::~TransitionalPersonBackend() -{ -} - -template<typename T> -TransitionalPersonBackend::TransitionalPersonBackend(CollectionMediator<T>* mediator) : -CollectionInterface(new TransitionalPersonEditor(mediator), nullptr) -{ -} - -bool TransitionalPersonBackend::load() -{ - return false; -} - -bool TransitionalPersonBackend::reload() -{ - return false; -} - -// bool TransitionalPersonBackend::append(const Person* item) -// { -// Q_UNUSED(item) -// return false; -// } - -// bool TransitionalPersonBackend::save(const Person* contact) -// { -// Q_UNUSED(contact) -// return false; -// } - -///Edit 'contact', the implementation may be a GUI or somehting else -// bool TransitionalPersonBackend::edit( Person* contact) -// { -// Q_UNUSED(contact) -// return false; -// } - -///Add a new contact to the backend -// bool TransitionalPersonBackend::addNew( Person* contact) -// { -// Q_UNUSED(contact) -// return false; -// } - -bool TransitionalPersonBackend::isEnabled() const -{ - return false; -} - -FlagPack<CollectionInterface::SupportedFeatures> TransitionalPersonBackend::supportedFeatures() const -{ - return CollectionInterface::SupportedFeatures::NONE; -} - -QString TransitionalPersonBackend::name () const -{ - return QObject::tr("Contact placeholders"); -} - -QString TransitionalPersonBackend::category () const -{ - return QObject::tr("Contact"); -} - -QVariant TransitionalPersonBackend::icon() const -{ - return GlobalInstances::pixmapManipulator().collectionIcon(this,Interfaces::PixmapManipulatorI::CollectionIconHint::CONTACT); -} - -QByteArray TransitionalPersonBackend::id() const -{ - return "trcb"; -} - -// QList<Person*> TransitionalPersonBackend::items() const -// { -// return QList<Person*>(); -// } diff --git a/src/transitionalpersonbackend.h b/src/transitionalpersonbackend.h deleted file mode 100644 index 291e3d30..00000000 --- a/src/transitionalpersonbackend.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2014-2018 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/>. * - ***************************************************************************/ -#pragma once - -#include "collectioninterface.h" - -#include "typedefs.h" - -class TransitionalPersonBackendPrivate; - -/** - * A temporary contact backend until concrete ones are loaded - * - * Some contacts are created early during the initialization process. - * This cause race issues between initialization of remote sources, - * such as GMail, and local one, such as history. As both contain some - * properties related to contact, if an incomplete one is loaded before - * the "real" one, then a temporary placeholder object have to be used. - * - * This object will then be silently replaced by the "real" copy. - * - * The old pointers will stay valid. - * - * This backend is the default one when such scenarios happen. It can also - * be used when contacts are created locally, but a "real" backend have - * yet to be selected. - */ -class LIB_EXPORT TransitionalPersonBackend : public CollectionInterface { -public: - template<typename T> - explicit TransitionalPersonBackend(CollectionMediator<T>* mediator); - - virtual ~TransitionalPersonBackend(); - - //Getters - virtual QByteArray id () const override; - virtual bool isEnabled() const override; - virtual QString name () const override; - virtual QString category () const override; - virtual QVariant icon () const override; - virtual FlagPack<SupportedFeatures> supportedFeatures() const override; - - //Mutators - virtual bool load ( ) override; - virtual bool reload ( ) override; - - //Singleton - static CollectionInterface& instance(); - -private: - - const QScopedPointer<TransitionalPersonBackendPrivate> d_ptr; -}; - diff --git a/src/useractionmodel.h b/src/useractionmodel.h deleted file mode 100644 index 09ae21fd..00000000 --- a/src/useractionmodel.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2012-2018 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/>. * - ***************************************************************************/ -#pragma once - -#include <QtCore/QString> -#include <QtCore/QAbstractItemModel> -#include "typedefs.h" - -//Qt -class QSortFilterProxyModel; -class QItemSelectionModel; - -//Ring -#include "call.h" -class Call; -class UserActionModelPrivate; - -/** - * @class UserActionModel Hold available actions for a given call state - * - **/ -class LIB_EXPORT UserActionModel : public QAbstractListModel { - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" - Q_OBJECT - #pragma GCC diagnostic pop -public: - - //Roles - enum Role { - VISIBLE = 100, - RELATIVEINDEX = 101, - ACTION = 102, - }; - - /** - * All assets currently available for the item. An item can have multiple - * assets. For example, a Call as a call, a contact method and probably a - * contact. - */ - enum class Asset { - NONE = 0x0 << 0, /*!< No assets */ - CALL = 0x1 << 0, /*!< A single live or history call */ - CALL_MODEL = 0x1 << 1, /*!< The current selected call from the CallModel */ - PERSON = 0x1 << 2, /*!< A person, contact or profile */ - CONTACT_METHOD = 0x1 << 3, /*!< A contact method or a bookmark */ - COUNT__ - }; - Q_FLAGS(Asset) - - ///If options are checkable or not - enum class ActionStatfulnessLevel { - UNISTATE = 0, /*!< The action has no state beside being available or not */ - CHECKABLE = 1, /*!< The action can be (un)available and "checked" */ - TRISTATE = 2, /*!< The action can be (un)available and unchecked, partially checked and fully checked */ - COUNT__, - }; - - ///(End)user action, all possibility, not only state aware ones like "Action" - enum class Action { - //Call - ACCEPT , /*!< Pickup incoming call(s) or send */ - HOLD , /*!< [Stateful] Hold (check) or Unhold (uncheck) call(s) */ - MUTE_AUDIO , /*!< [Stateful] Stop sending audio to call(s) */ - MUTE_VIDEO , /*!< [Stateful] Stop sending video to call(s) */ - SERVER_TRANSFER , /*!< [Stateful] Perform an unattended transfer */ - RECORD , /*!< [Stateful] Record the call(s) to .wav file(s) */ - HANGUP , /*!< Refuse an incoming call or hang up an in progress one */ - JOIN , /*!< [Stateful] Join all seclect calls into a conference */ - TOGGLE_VIDEO , /*!< Toggle the video media on that asset */ - - //Contact - ADD_CONTACT , /*!< Add a new contact for that asset contact method */ - ADD_TO_CONTACT , /*!< Add the asset contact method to an existing contact */ - DELETE_CONTACT , /*!< Delete the contact attached to the asset */ - EMAIL_CONTACT , /*!< Email the contact attached to the asset */ - COPY_CONTACT , /*!< Copy the vCard/HTML/Plain text contact data */ - BOOKMARK , /*!< Toogle the bookmarked state of that contact [method] */ - VIEW_CHAT_HISTORY , /*!< View the text recording associated with the CM */ - ADD_CONTACT_METHOD, /*!< Add a contact method to a contact */ - CALL_CONTACT , /*!< Call this contact [method] */ - EDIT_CONTACT , /*!< Edit fields of the contact (may involve GUI editor) */ - - //Call model - ADD_NEW , /*!< Add a new call */ - - //History - REMOVE_HISTORY , /*!< Remove this asset from the history */ - - //Multi selection - - //No selection - COUNT__, - }; - Q_ENUMS(Action) - - enum class Context { - NONE = 0x0 << 0, /*!< Nothing */ - MINIMAL = 0x1 << 0, /*!< The bare minimum required to work with the asset */ - RECOMMENDED = 0x1 << 1, /*!< Commonly useful actions related to an asset */ - ADVANCED = 0x1 << 2, /*!< Uncommon actions that can be performed on the asset */ - MANAGEMENT = 0x1 << 3, /*!< Manage the data related to this (bookmark, add contact...) */ - CONTACT = 0x1 << 4, /*!< Actions related to contacting this person (email, call...) */ - TREE_ELEMENTS = 0x1 << 5, /*!< All actions that require a second dimension to manage */ - ALL = - Context::MINIMAL | - Context::RECOMMENDED | - Context::ADVANCED | - Context::MANAGEMENT | - Context::CONTACT | - Context::TREE_ELEMENTS - }; - Q_FLAGS(Context) - - Q_PROPERTY(QAbstractItemModel* activeActionModel READ activeActionModel CONSTANT) - - //Constructor - explicit UserActionModel(Call* parent , const FlagPack<Context> c = FlagPack<Context>(Context::MINIMAL)| Context::RECOMMENDED); - UserActionModel(QAbstractItemModel* parent, const FlagPack<Context> c = FlagPack<Context>(Context::MINIMAL)| Context::RECOMMENDED); - virtual ~UserActionModel(); - - //Abstract model members - 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 QHash<int,QByteArray> roleNames() const override; - - //Getters - Q_INVOKABLE bool isActionEnabled ( UserActionModel::Action action ) const; - Q_INVOKABLE uint relativeIndex ( UserActionModel::Action action ) const; - QAbstractItemModel* activeActionModel() const; - - //Setters - void setSelectionModel(QItemSelectionModel* sm); - - //Mutators - Q_INVOKABLE bool execute( const Action action ) const; - bool execute( const QModelIndex& idx ) const; - - //Operators - UserActionModel* operator<<(UserActionModel::Action& action); - -private: - const QScopedPointer<UserActionModelPrivate> d_ptr; - Q_DECLARE_PRIVATE(UserActionModel) - -Q_SIGNALS: - ///The list of currently available actions has changed - void actionStateChanged(); -}; -Q_DECLARE_METATYPE(UserActionModel*) -Q_DECLARE_METATYPE(UserActionModel::Action) -DECLARE_ENUM_FLAGS(UserActionModel::Context) - - -UserActionModel* operator<<(UserActionModel* m,UserActionModel::Action action); - -/** - * "Java bean" used to avoid having a 5+ parameter pixmap delegate - */ -struct UserActionElement { - UserActionModel::Action action ; - QList<Call*> calls ; - Qt::CheckState checkState ; -}; - -- GitLab