diff --git a/CMakeLists.txt b/CMakeLists.txt index a90817ea538c593d4e17829a34e909961d1aa5b7..0d7c51ca6c53b4abd999c0a5615c36c5606aca08 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 4bc2430eb830bbe5eb23a1b9f83fd2d0f69179c6..06d8f86879d091b2a3a408b8cf33178f362d845b 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 761fd99c159c4f6b46e736d57e8c4c6291bf33ee..97c136b37c713e56542afdbf08d2352b149af9a0 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 beee74aa2b0382c23ee8d86a210c7a8e7a12e4f5..0000000000000000000000000000000000000000 --- 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 919e283aacdb1b245efd1d2adab5d90a5b5f618f..0000000000000000000000000000000000000000 --- 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 759ab35144875960babfc8316686e3bcb7a163a1..03b9905843934ca8556c91a645a3a6381db53fff 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 d395e3e3b3f0116be942359afe78ccf80a94f25c..0000000000000000000000000000000000000000 --- 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 447641e69c57c66774e2c2041c15f825a1ab1397..0000000000000000000000000000000000000000 --- 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 e3683593b5328fb2c0e520a093817b8e5e97f7e9..f7306e8a4a16c9f864c9affc98aa6b632acc700d 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 8fbaa7573365dd9950476bea1c200e0537899029..0000000000000000000000000000000000000000 --- 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 0b942e1d13bbfc66680454216be4fc4e6e73f3c1..0000000000000000000000000000000000000000 --- 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 87bb67f6307a617887bdc6f841bd1732dfaf12a1..cec6a7d85e867ff5db1dbf0c01e5fe6a560e045f 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 b5b5ca2814ea46eec096f0e18aea9daf0872165d..4a29b30ba4a1de39573b9d7cabaaa0ee2448def5 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 6c1a093e61c08ceabafd552e272d8541485853e7..c3caafda6ad16e030f3d1c8a49ba2e045a144b53 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 92c61c80c65943dcd9c42a574b0053897388223b..72afe87673d190d52275d055449217b97c615169 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 d480e0ede550ffcb65f53d260f75cdecaad9dbbd..db92aa75d8138452ef28a74ac3485dde486c2148 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 752b45327a2bba070980807e9474dfdbf390381b..0000000000000000000000000000000000000000 --- 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 ce6ae70c6724170a14311d78ef24119119f930d2..0000000000000000000000000000000000000000 --- 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 4bb02157af5b195df089f2b238156ac4350ec200..0000000000000000000000000000000000000000 --- 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 458eebc88d0e526125abc7071832c4e39e6a4268..0000000000000000000000000000000000000000 --- 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 df23d450b343b10073297c75252270584468a55e..0000000000000000000000000000000000000000 --- 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 5db18f8604c78b53b680f6fbe30f9ae2084e2a86..a2323f3e9bc948c85edf4907f0448e49013a4d26 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 efef9d089a76df2ec536bc4f1c9d44f1e77e61b5..20629b80bea8d13f0efccbba36929fbfe1e5fccf 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 24ed563279ba2730713c3c4197b39a108fc4eae1..0000000000000000000000000000000000000000 --- 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 97d89b919682ac8597f6f0332c865d4859858c4c..0000000000000000000000000000000000000000 --- 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 96a67b01525de2e45fb0eef789b4718d3a0b1353..0000000000000000000000000000000000000000 --- 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 6969cf91efd782b0063e2e27d81402f2da580c29..0000000000000000000000000000000000000000 --- 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 7a634e5373b2fafe4cc63e759a32c8d67f151057..0000000000000000000000000000000000000000 --- 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 e251a5c3d24f0b830a1b98553523deaa9d51baf0..0000000000000000000000000000000000000000 --- 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 a38d08a5a543ce4ed792b81a7e33e82dacf31041..0000000000000000000000000000000000000000 --- 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 24567d8a7471388d41212a56d841504194d586e9..0000000000000000000000000000000000000000 --- 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 8c6bacb507a705796542de65211973cde7fdb8e2..4de5a3f247bd69ac1426856840d892634ff9c2bd 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 25edb776543b1fabbf5044106b8acdca14052dbb..0000000000000000000000000000000000000000 --- 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 e93759c40bc6f6fea94f8b1679ffd7ad929999c4..0000000000000000000000000000000000000000 --- 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 894083af106286096ef07a975a3e976fa185211a..0000000000000000000000000000000000000000 --- 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 4cfeaa43d6179d50cc5aa999208d27ffb2bfb4b7..0000000000000000000000000000000000000000 --- 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 abe282c0045ba5a64db4820363058ae8f1f56723..8b1fe4ce4b925db70f09f9e7763bb6275b44606e 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 31322f5e3b7d3e7a055b1e4c2bd57ba81b1d9c19..fba17050512f4801121f4d7d7ed0f41aa246e5c5 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 353095637c15911e883362c339e3f1a5bb8d31c1..e4b8abf21ff27717769003aa4cde1692b992a294 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 a366800329f5a2434ee019e60494fa6c2814c099..d5c055f0146699201f640debb962dc21e85bf0f1 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 a2048c750454cd58137ad2c6230b7dfd991fa113..32a99e73343650307d8cc52c9e4d754cf229a749 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 1e63b17ee29e194eb3455ef34005e38afccfcd50..15d96e3bf09662e4450bc70ab5835510deb1b6d9 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 e66c53b0f897db41d90de276cffadc6e52782564..21827285869220ac5b61cd6e94024c3b418e9a99 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 4cc61f2d0ac2af5dc57d1b7e13723088acb2129b..0000000000000000000000000000000000000000 --- 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 828bc605492054cf33b780ffaed13de031215e7c..0000000000000000000000000000000000000000 --- 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 7943fcc1ea4dd5d7418403bd234b5d9abc51eb3c..0000000000000000000000000000000000000000 --- 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 b88f04f30b285b4020281e02f4cd780e6d4f0af2..0000000000000000000000000000000000000000 --- 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 d4d6314863f1275e434589f5606e9029c45e33a8..0000000000000000000000000000000000000000 --- 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 900dbb473db77a5ffa4e19d92b63376a3d26b3dd..0000000000000000000000000000000000000000 --- 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 2c73b92c6d7b3c03871ef8d4527febb9346b3593..0000000000000000000000000000000000000000 --- 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 3d1d311c620bc2ae15d4d74cf67418b243a4ffb1..121a9bace696b02a38fe3a9d25d0c479b9fc61e3 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 fd1b3c165c14b365bce107af4a266baa9a1c9cc9..0000000000000000000000000000000000000000 --- 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 291e3d305a75e542865fe6b635c118646a9cbc0d..0000000000000000000000000000000000000000 --- 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 09ae21fd9cd9a3b9efc304d84a5b7815d94c2174..0000000000000000000000000000000000000000 --- 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 ; -}; -