From 76def6d0f7fba7fcad7d7d93ac1d26bbb09d3807 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Tue, 13 Dec 2016 16:33:56 +0100 Subject: [PATCH] refactoring unstable --- tests/CMakeLists.txt | 6 +- tests/src/app/App.cpp | 4 + tests/src/components/contact/ContactModel.cpp | 25 + tests/src/components/contact/ContactModel.hpp | 63 +++ tests/src/components/contact/VcardModel.cpp | 328 ++++++++++++++ tests/src/components/contact/VcardModel.hpp | 67 +++ .../src/components/contacts/ContactModel.cpp | 428 ------------------ .../src/components/contacts/ContactModel.hpp | 103 ----- .../components/contacts/ContactsListModel.cpp | 32 +- .../components/contacts/ContactsListModel.hpp | 12 +- .../contacts/ContactsListProxyModel.cpp | 78 ++-- .../contacts/ContactsListProxyModel.hpp | 3 +- 12 files changed, 539 insertions(+), 610 deletions(-) create mode 100644 tests/src/components/contact/ContactModel.cpp create mode 100644 tests/src/components/contact/ContactModel.hpp create mode 100644 tests/src/components/contact/VcardModel.cpp create mode 100644 tests/src/components/contact/VcardModel.hpp delete mode 100644 tests/src/components/contacts/ContactModel.cpp delete mode 100644 tests/src/components/contacts/ContactModel.hpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e18fc7836..82e42802d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -58,7 +58,8 @@ set(SOURCES src/components/camera/Camera.cpp src/components/chat/ChatModel.cpp src/components/chat/ChatProxyModel.cpp - src/components/contacts/ContactModel.cpp + src/components/contact/ContactModel.cpp + src/components/contact/VcardModel.cpp src/components/contacts/ContactsListModel.cpp src/components/contacts/ContactsListProxyModel.cpp src/components/core/CoreManager.cpp @@ -80,7 +81,8 @@ set(HEADERS src/components/camera/Camera.hpp src/components/chat/ChatModel.hpp src/components/chat/ChatProxyModel.hpp - src/components/contacts/ContactModel.hpp + src/components/contact/ContactModel.hpp + src/components/contact/VcardModel.hpp src/components/contacts/ContactsListModel.hpp src/components/contacts/ContactsListProxyModel.hpp src/components/core/CoreManager.hpp diff --git a/tests/src/app/App.cpp b/tests/src/app/App.cpp index cb234f7d4..23feaf0cc 100644 --- a/tests/src/app/App.cpp +++ b/tests/src/app/App.cpp @@ -109,6 +109,10 @@ void App::registerTypes () { "Linphone", 1, 0, "ContactModel", "ContactModel is uncreatable" ); + qmlRegisterUncreatableType( + "Linphone", 1, 0, "VcardModel", "VcardModel is uncreatable" + ); + ContactsListProxyModel::initContactsListModel(new ContactsListModel()); qmlRegisterType("Linphone", 1, 0, "ContactsListProxyModel"); diff --git a/tests/src/components/contact/ContactModel.cpp b/tests/src/components/contact/ContactModel.cpp new file mode 100644 index 000000000..19d7406b0 --- /dev/null +++ b/tests/src/components/contact/ContactModel.cpp @@ -0,0 +1,25 @@ +#include "../../app/App.hpp" + +#include "ContactModel.hpp" + +using namespace std; + +// ============================================================================= + +const char *ContactModel::NAME = "contact-model"; + +ContactModel::ContactModel (shared_ptr linphone_friend) { + linphone_friend->setData(NAME, *this); + m_linphone_friend = linphone_friend; + m_vcard = make_shared(linphone_friend->getVcard()); + + App::getInstance()->getEngine()->setObjectOwnership(m_vcard.get(), QQmlEngine::CppOwnership); +} + +Presence::PresenceStatus ContactModel::getPresenceStatus () const { + return Presence::PresenceStatus::Offline; +} + +Presence::PresenceLevel ContactModel::getPresenceLevel () const { + return Presence::getPresenceLevel(getPresenceStatus()); +} diff --git a/tests/src/components/contact/ContactModel.hpp b/tests/src/components/contact/ContactModel.hpp new file mode 100644 index 000000000..e166e649e --- /dev/null +++ b/tests/src/components/contact/ContactModel.hpp @@ -0,0 +1,63 @@ +#ifndef CONTACT_MODEL_H_ +#define CONTACT_MODEL_H_ + +#include +#include + +#include "../presence/Presence.hpp" + +#include "VcardModel.hpp" + +// ============================================================================= + +class ContactModel : public QObject { + Q_OBJECT; + + Q_PROPERTY(Presence::PresenceStatus presenceStatus READ getPresenceStatus NOTIFY contactUpdated); + Q_PROPERTY(Presence::PresenceLevel presenceLevel READ getPresenceLevel NOTIFY contactUpdated); + Q_PROPERTY(VcardModel * vcard READ getVcardModelPtr NOTIFY contactUpdated); + + friend class ContactsListModel; + friend class ContactsListProxyModel; + +public: + ContactModel (std::shared_ptr linphone_friend); + + static const char *NAME; + +public slots: + void startEdit () { + m_linphone_friend->edit(); + } + + void endEdit () { + m_linphone_friend->done(); + } + + void abortEdit () { + // TODO. + // m_linphone_friend->abort(); + } + +signals: + void contactUpdated (); + +private: + Presence::PresenceStatus getPresenceStatus () const; + Presence::PresenceLevel getPresenceLevel () const; + + std::shared_ptr getVcardModel () const { + return m_vcard; + } + + VcardModel *getVcardModelPtr () const { + return m_vcard.get(); + } + + std::shared_ptr m_vcard; + std::shared_ptr m_linphone_friend; +}; + +Q_DECLARE_METATYPE(ContactModel *); + +#endif // CONTACT_MODEL_H_ diff --git a/tests/src/components/contact/VcardModel.cpp b/tests/src/components/contact/VcardModel.cpp new file mode 100644 index 000000000..f485949d1 --- /dev/null +++ b/tests/src/components/contact/VcardModel.cpp @@ -0,0 +1,328 @@ +#include +#include +#include +#include +#include + +#include "../../app/AvatarProvider.hpp" +#include "../../app/Database.hpp" +#include "../../utils.hpp" +#include "../core/CoreManager.hpp" + +#include "VcardModel.hpp" + +#define VCARD_SCHEME "linphone-desktop:/" + +using namespace std; + +// ============================================================================= + +template +inline shared_ptr findBelCardValue (const list > &list, const QString &value) { + string match = ::Utils::qStringToLinphoneString(value); + + auto it = find_if( + list.cbegin(), list.cend(), [&match](const shared_ptr &entry) { + return match == entry->getValue(); + } + ); + + return *it; +} + +// ----------------------------------------------------------------------------- + +QString VcardModel::getUsername () const { + return ::Utils::linphoneStringToQString(m_vcard->getFullName()); +} + +void VcardModel::setUsername (const QString &username) { + if (username.length() == 0 || username == getUsername()) + return; + + m_vcard->setFullName(::Utils::qStringToLinphoneString(username)); + emit vcardUpdated(); +} + +// ----------------------------------------------------------------------------- + +QString VcardModel::getAvatar () const { + // Find desktop avatar. + list > photos = m_vcard->getBelcard()->getPhotos(); + auto it = find_if( + photos.cbegin(), photos.cend(), [](const shared_ptr &photo) { + return !photo->getValue().compare(0, sizeof(VCARD_SCHEME) - 1, VCARD_SCHEME); + } + ); + + // No path found. + if (it == photos.cend()) + return ""; + + // Returns right path. + return QStringLiteral("image://%1/%2").arg(AvatarProvider::PROVIDER_ID).arg( + ::Utils::linphoneStringToQString((*it)->getValue().substr(sizeof(VCARD_SCHEME) - 1)) + ); +} + +void VcardModel::setAvatar (const QString &path) { + // 1. Try to copy photo in avatars folder. + QFile file(path); + + if (!file.exists() || QImageReader::imageFormat(path).size() == 0) + return; + + QFileInfo info(file); + QString uuid = QUuid::createUuid().toString(); + QString file_id = QStringLiteral("%1.%2") + .arg(uuid.mid(1, uuid.length() - 2)) // Remove `{}`. + .arg(info.suffix()); + + QString dest = ::Utils::linphoneStringToQString(Database::getAvatarsPath()) + file_id; + + if (!file.copy(dest)) + return; + + qInfo() << QStringLiteral("Update avatar of `%1`. (path=%2)").arg(getUsername()).arg(dest); + + // 2. Edit vcard. + shared_ptr belCard = m_vcard->getBelcard(); + list > photos = belCard->getPhotos(); + + // 3. Remove oldest photo. + auto it = find_if( + photos.begin(), photos.end(), [](const shared_ptr &photo) { + return !photo->getValue().compare(0, sizeof(VCARD_SCHEME) - 1, VCARD_SCHEME); + } + ); + + if (it != photos.end()) { + QString image_path( + ::Utils::linphoneStringToQString( + Database::getAvatarsPath() + (*it)->getValue().substr(sizeof(VCARD_SCHEME) - 1) + ) + ); + + if (!QFile::remove(image_path)) + qWarning() << QStringLiteral("Unable to remove `%1`.").arg(image_path); + belCard->removePhoto(*it); + } + + // 4. Update. + shared_ptr photo = + belcard::BelCardGeneric::create(); + photo->setValue(VCARD_SCHEME + ::Utils::qStringToLinphoneString(file_id)); + belCard->addPhoto(photo); + + emit vcardUpdated(); +} + +// ----------------------------------------------------------------------------- + +QVariantMap VcardModel::getAddress () const { + // TODO +} + +void VcardModel::setAddress (const QVariantMap &address) { + // TODO +} + +QVariantList VcardModel::getSipAddresses () const { + QVariantList list; + + for (const auto &address : m_vcard->getSipAddresses()) + list.append(::Utils::linphoneStringToQString(address->asString())); + + return list; +} + +bool VcardModel::addSipAddress (const QString &sip_address) { + qInfo() << QStringLiteral("Add new sip address: `%1`.").arg(sip_address); + m_vcard->addSipAddress(::Utils::qStringToLinphoneString(sip_address)); + + emit vcardUpdated(); + + return true; +} + +void VcardModel::removeSipAddress (const QString &sip_address) { + list > addresses = m_vcard->getSipAddresses(); + string match = ::Utils::qStringToLinphoneString(sip_address); + + auto it = find_if( + addresses.cbegin(), addresses.cend(), [&match](const shared_ptr &address) { + return match == address->asString(); + } + ); + + if (it == addresses.cend()) { + qWarning() << QStringLiteral("Unable to found sip address: `%1`.") + .arg(sip_address); + return; + } + + if (addresses.size() == 1) { + qWarning() << QStringLiteral("Unable to remove the only existing sip address: `%1`.") + .arg(sip_address); + return; + } + + qInfo() << QStringLiteral("Remove sip address: `%1`.").arg(sip_address); + m_vcard->removeSipAddress((*it)->asStringUriOnly()); + + emit vcardUpdated(); +} + +bool VcardModel::updateSipAddress (const QString &old_sip_address, const QString &sip_address) { + if (old_sip_address == sip_address || !addSipAddress(sip_address)) + return false; + + removeSipAddress(old_sip_address); + + return true; +} + +// ----------------------------------------------------------------------------- + +QVariantList VcardModel::getCompanies () const { + QVariantList list; + + for (const auto &company : m_vcard->getBelcard()->getRoles()) + list.append(::Utils::linphoneStringToQString(company->getValue())); + + return list; +} + +bool VcardModel::addCompany (const QString &company) { + shared_ptr belCard = m_vcard->getBelcard(); + shared_ptr value = belcard::BelCardGeneric::create(); + value->setValue(::Utils::qStringToLinphoneString(company)); + + qInfo() << QStringLiteral("Add new company: `%1`.").arg(company); + belCard->addRole(value); + + emit vcardUpdated(); + + return true; +} + +void VcardModel::removeCompany (const QString &company) { + shared_ptr belCard = m_vcard->getBelcard(); + shared_ptr value = findBelCardValue(belCard->getRoles(), company); + + if (!value) { + qWarning() << QStringLiteral("Unable to remove company: `%1`.").arg(company); + return; + } + + qInfo() << QStringLiteral("Remove company: `%1`.").arg(company); + belCard->removeRole(value); + + emit vcardUpdated(); +} + +bool VcardModel::updateCompany (const QString &old_company, const QString &company) { + if (old_company == company || !addCompany(company)) + return false; + + removeCompany(old_company); + + return true; +} + +// ----------------------------------------------------------------------------- + +QVariantList VcardModel::getEmails () const { + QVariantList list; + + for (const auto &email : m_vcard->getBelcard()->getEmails()) + list.append(::Utils::linphoneStringToQString(email->getValue())); + + return list; +} + +bool VcardModel::addEmail (const QString &email) { + shared_ptr belCard = m_vcard->getBelcard(); + shared_ptr value = + belcard::BelCardGeneric::create(); + value->setValue(::Utils::qStringToLinphoneString(email)); + + qInfo() << QStringLiteral("Add new email: `%1`.").arg(email); + belCard->addEmail(value); + + emit vcardUpdated(); + + return true; +} + +void VcardModel::removeEmail (const QString &email) { + shared_ptr belCard = m_vcard->getBelcard(); + shared_ptr value = findBelCardValue(belCard->getEmails(), email); + + if (!value) { + qWarning() << QStringLiteral("Unable to remove email: `%1`.").arg(email); + return; + } + + qInfo() << QStringLiteral("Remove email: `%1`.").arg(email); + belCard->removeEmail(value); + + emit vcardUpdated(); +} + +bool VcardModel::updateEmail (const QString &old_email, const QString &email) { + if (old_email == email || !addEmail(email)) + return false; + + removeEmail(old_email); + + return true; +} + +// ----------------------------------------------------------------------------- + +QVariantList VcardModel::getUrls () const { + QVariantList list; + + for (const auto &url : m_vcard->getBelcard()->getURLs()) + list.append(::Utils::linphoneStringToQString(url->getValue())); + + return list; +} + +bool VcardModel::addUrl (const QString &url) { + shared_ptr belCard = m_vcard->getBelcard(); + shared_ptr value = belcard::BelCardGeneric::create(); + value->setValue(::Utils::qStringToLinphoneString(url)); + + qInfo() << QStringLiteral("Add new url: `%1`.").arg(url); + belCard->addURL(value); + + emit vcardUpdated(); + + return true; +} + +void VcardModel::removeUrl (const QString &url) { + shared_ptr belCard = m_vcard->getBelcard(); + shared_ptr value = findBelCardValue(belCard->getURLs(), url); + + if (!value) { + qWarning() << QStringLiteral("Unable to remove url: `%1`.").arg(url); + return; + } + + qInfo() << QStringLiteral("Remove url: `%1`.").arg(url); + belCard->removeURL(value); + + emit vcardUpdated(); +} + +bool VcardModel::updateUrl (const QString &old_url, const QString &url) { + if (old_url == url || !addUrl(url)) + return false; + + removeUrl(old_url); + + return true; +} diff --git a/tests/src/components/contact/VcardModel.hpp b/tests/src/components/contact/VcardModel.hpp new file mode 100644 index 000000000..f64ce17e6 --- /dev/null +++ b/tests/src/components/contact/VcardModel.hpp @@ -0,0 +1,67 @@ +#ifndef VCARD_MODEL_H_ +#define VCARD_MODEL_H_ + +#include +#include + +// ============================================================================= + +class VcardModel : public QObject { + Q_OBJECT; + + Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY vcardUpdated); + Q_PROPERTY(QString avatar READ getAvatar WRITE setAvatar NOTIFY vcardUpdated); + Q_PROPERTY(QVariantMap address READ getAddress WRITE setAddress NOTIFY vcardUpdated); + Q_PROPERTY(QVariantList sipAddresses READ getSipAddresses NOTIFY vcardUpdated); + Q_PROPERTY(QVariantList companies READ getCompanies NOTIFY vcardUpdated); + Q_PROPERTY(QVariantList emails READ getEmails NOTIFY vcardUpdated); + Q_PROPERTY(QVariantList urls READ getUrls NOTIFY vcardUpdated); + + friend class ContactsListProxyModel; + +public: + VcardModel (std::shared_ptr vcard) : m_vcard(vcard) {} + + ~VcardModel () = default; + +public slots: + bool addSipAddress (const QString &sip_address); + void removeSipAddress (const QString &sip_address); + bool updateSipAddress (const QString &old_sip_address, const QString &sip_address); + + bool addCompany (const QString &company); + void removeCompany (const QString &company); + bool updateCompany (const QString &old_company, const QString &company); + + bool addEmail (const QString &email); + void removeEmail (const QString &email); + bool updateEmail (const QString &old_email, const QString &email); + + bool addUrl (const QString &url); + void removeUrl (const QString &url); + bool updateUrl (const QString &old_url, const QString &url); + +signals: + void vcardUpdated (); + +private: + QString getUsername () const; + void setUsername (const QString &username); + + QString getAvatar () const; + void setAvatar (const QString &path); + + QVariantMap getAddress () const; + void setAddress (const QVariantMap &address); + + QVariantList getSipAddresses () const; + QVariantList getCompanies () const; + QVariantList getEmails () const; + QVariantList getUrls () const; + + std::shared_ptr m_vcard; +}; + +Q_DECLARE_METATYPE(VcardModel *); + +#endif // VCARD_MODEL_H_ diff --git a/tests/src/components/contacts/ContactModel.cpp b/tests/src/components/contacts/ContactModel.cpp deleted file mode 100644 index 7f0290355..000000000 --- a/tests/src/components/contacts/ContactModel.cpp +++ /dev/null @@ -1,428 +0,0 @@ -#include -#include -#include -#include - -#include - -#include "../../app/AvatarProvider.hpp" -#include "../../app/Database.hpp" -#include "../../utils.hpp" -#include "../core/CoreManager.hpp" - -#include "ContactModel.hpp" - -#define VCARD_SCHEME "linphone-desktop:/" - -using namespace std; - -// =================================================================== - -template -inline shared_ptr findBelCardValue ( - const list > &list, - const QString &value -) { - string match = Utils::qStringToLinphoneString(value); - - auto it = find_if( - list.cbegin(), list.cend(), - [&match](const shared_ptr &entry) { - return match == entry->getValue(); - } - ); - - return *it; -} - -// ------------------------------------------------------------------- - -ContactModel::ContactModel ( - shared_ptr linphone_friend, - bool is_detached -) { - linphone_friend->setData("contact-model", *this); - m_linphone_friend = linphone_friend; - m_is_detached = is_detached; -} - -// ------------------------------------------------------------------- - -void ContactModel::edit () { - if (!m_is_detached) - m_linphone_friend->edit(); -} - -void ContactModel::done () { - if (!m_is_detached) - m_linphone_friend->done(); -} - -// ------------------------------------------------------------------- - -QString ContactModel::getUsername () const { - return Utils::linphoneStringToQString( - m_linphone_friend->getName() - ); -} - -void ContactModel::setUsername (const QString &username) { - if (username.length() == 0 || username == getUsername()) - return; - - edit(); - - if (!m_linphone_friend->setName(Utils::qStringToLinphoneString(username))) - emit contactUpdated(); - - done(); -} - -// ------------------------------------------------------------------- - -QString ContactModel::getAvatar () const { - // Find desktop avatar. - list > photos = - m_linphone_friend->getVcard()->getBelcard()->getPhotos(); - auto it = find_if( - photos.cbegin(), photos.cend(), [](const shared_ptr &photo) { - return !photo->getValue().compare(0, sizeof(VCARD_SCHEME) - 1, VCARD_SCHEME); - } - ); - - // No path found. - if (it == photos.cend()) - return ""; - - // Returns right path. - return QStringLiteral("image://%1/%2") - .arg(AvatarProvider::PROVIDER_ID) - .arg(Utils::linphoneStringToQString( - (*it)->getValue().substr(sizeof(VCARD_SCHEME) - 1) - )); -} - -void ContactModel::setAvatar (const QString &path) { - // 1. Try to copy photo in avatars folder. - QFile file(path); - - if (!file.exists() || QImageReader::imageFormat(path).size() == 0) - return; - - QFileInfo info(file); - QString uuid = QUuid::createUuid().toString(); - QString file_id = QStringLiteral("%1.%2") - .arg(uuid.mid(1, uuid.length() - 2)) // Remove `{}`. - .arg(info.suffix()); - - QString dest = Utils::linphoneStringToQString(Database::getAvatarsPath()) + - file_id; - - if (!file.copy(dest)) - return; - - qInfo() << QStringLiteral("Update avatar of `%1`. (path=%2)") - .arg(getUsername()).arg(dest); - - // 2. Edit vcard. - edit(); - - shared_ptr belCard = m_linphone_friend->getVcard()->getBelcard(); - list > photos = belCard->getPhotos(); - - // 3. Remove oldest photo. - auto it = find_if( - photos.begin(), photos.end(), [](const shared_ptr &photo) { - return !photo->getValue().compare(0, sizeof(VCARD_SCHEME) - 1, VCARD_SCHEME); - } - ); - - if (it != photos.end()) { - QString image_path(Utils::linphoneStringToQString( - Database::getAvatarsPath() + (*it)->getValue().substr(sizeof(VCARD_SCHEME) - 1) - )); - if (!QFile::remove(image_path)) - qWarning() << QStringLiteral("Unable to remove `%1`.").arg(image_path); - belCard->removePhoto(*it); - } - - // 4. Update. - shared_ptr photo = - belcard::BelCardGeneric::create(); - photo->setValue(VCARD_SCHEME + Utils::qStringToLinphoneString(file_id)); - belCard->addPhoto(photo); - - done(); - - emit contactUpdated(); - - return; -} - -// ------------------------------------------------------------------- - -QVariantList ContactModel::getSipAddresses () const { - QVariantList list; - - for (const auto &address : m_linphone_friend->getAddresses()) - list.append(Utils::linphoneStringToQString(address->asString())); - - return list; -} - -bool ContactModel::addSipAddress (const QString &sip_address) { - shared_ptr address = - CoreManager::getInstance()->getCore()->createAddress( - Utils::qStringToLinphoneString(sip_address) - ); - - if (!address) { - qWarning() << QStringLiteral("Unable to add invalid sip address: `%1`.").arg(sip_address); - return false; - } - - qInfo() << QStringLiteral("Add new sip address: `%1`.").arg(sip_address); - - edit(); - m_linphone_friend->addAddress(address); - done(); - - emit contactUpdated(); - - return true; -} - -void ContactModel::removeSipAddress (const QString &sip_address) { - list > addresses = m_linphone_friend->getAddresses(); - string match = Utils::qStringToLinphoneString(sip_address); - - auto it = find_if( - addresses.cbegin(), addresses.cend(), - [&match](const shared_ptr &address) { - return match == address->asString(); - } - ); - - if (it == addresses.cend()) { - qWarning() << QStringLiteral("Unable to found sip address: `%1`.") - .arg(sip_address); - return; - } - - if (addresses.size() == 1) { - qWarning() << QStringLiteral("Unable to remove the only existing sip address: `%1`.") - .arg(sip_address); - return; - } - - qInfo() << QStringLiteral("Remove sip address: `%1`.").arg(sip_address); - - edit(); - m_linphone_friend->removeAddress(*it); - done(); - - emit contactUpdated(); - - return; -} - -bool ContactModel::updateSipAddress (const QString &old_sip_address, const QString &sip_address) { - if (old_sip_address == sip_address || !addSipAddress(sip_address)) - return false; - - removeSipAddress(old_sip_address); - - return true; -} - -// ------------------------------------------------------------------- - -QVariantList ContactModel::getCompanies () const { - QVariantList list; - - for (const auto &company : m_linphone_friend->getVcard()->getBelcard()->getRoles()) - list.append(Utils::linphoneStringToQString(company->getValue())); - - return list; -} - -void ContactModel::addCompany (const QString &company) { - shared_ptr belCard = m_linphone_friend->getVcard()->getBelcard(); - shared_ptr value = - belcard::BelCardGeneric::create(); - value->setValue(Utils::qStringToLinphoneString(company)); - - qInfo() << QStringLiteral("Add new company: `%1`.").arg(company); - - edit(); - belCard->addRole(value); - done(); - - emit contactUpdated(); -} - -void ContactModel::removeCompany (const QString &company) { - shared_ptr belCard = m_linphone_friend->getVcard()->getBelcard(); - shared_ptr value = findBelCardValue(belCard->getRoles(), company); - - if (!value) { - qWarning() << QStringLiteral("Unable to remove company: `%1`.").arg(company); - return; - } - - qInfo() << QStringLiteral("Remove company: `%1`.").arg(company); - - edit(); - belCard->removeRole(value); - done(); - - emit contactUpdated(); -} - -void ContactModel::updateCompany (const QString &old_company, const QString &company) { - if (old_company == company) - return; - - addCompany(company); - removeCompany(old_company); -} - -// ------------------------------------------------------------------- - -QVariantList ContactModel::getEmails () const { - QVariantList list; - - for (const auto &email : m_linphone_friend->getVcard()->getBelcard()->getEmails()) - list.append(Utils::linphoneStringToQString(email->getValue())); - - return list; -} - -bool ContactModel::addEmail (const QString &email) { - shared_ptr belCard = m_linphone_friend->getVcard()->getBelcard(); - shared_ptr value = - belcard::BelCardGeneric::create(); - value->setValue(Utils::qStringToLinphoneString(email)); - - qInfo() << QStringLiteral("Add new email: `%1`.").arg(email); - - edit(); - belCard->addEmail(value); - done(); - - emit contactUpdated(); - - // TODO: Check if email is valid. - return true; -} - -void ContactModel::removeEmail (const QString &email) { - shared_ptr belCard = m_linphone_friend->getVcard()->getBelcard(); - shared_ptr value = findBelCardValue(belCard->getEmails(), email); - - if (!value) { - qWarning() << QStringLiteral("Unable to remove email: `%1`.").arg(email); - return; - } - - qInfo() << QStringLiteral("Remove email: `%1`.").arg(email); - - edit(); - belCard->removeEmail(value); - done(); - - emit contactUpdated(); -} - -bool ContactModel::updateEmail (const QString &old_email, const QString &email) { - if (old_email == email || !addEmail(email)) - return false; - - removeEmail(old_email); - - return true; -} - -// ------------------------------------------------------------------- - -QVariantList ContactModel::getUrls () const { - QVariantList list; - - qDebug() << "card" << m_linphone_friend->getVcard().get(); - - for (const auto &url : m_linphone_friend->getVcard()->getBelcard()->getURLs()) - list.append(Utils::linphoneStringToQString(url->getValue())); - - return list; -} - -bool ContactModel::addUrl (const QString &url) { - shared_ptr belCard = m_linphone_friend->getVcard()->getBelcard(); - shared_ptr value = - belcard::BelCardGeneric::create(); - value->setValue(Utils::qStringToLinphoneString(url)); - - qInfo() << QStringLiteral("Add new url: `%1`.").arg(url); - - edit(); - belCard->addURL(value); - done(); - - emit contactUpdated(); - - // TODO: Check if url is valid. - return true; -} - -void ContactModel::removeUrl (const QString &url) { - shared_ptr belCard = m_linphone_friend->getVcard()->getBelcard(); - shared_ptr value = findBelCardValue(belCard->getURLs(), url); - - if (!value) { - qWarning() << QStringLiteral("Unable to remove url: `%1`.").arg(url); - return; - } - - qInfo() << QStringLiteral("Remove url: `%1`.").arg(url); - - edit(); - belCard->removeURL(value); - done(); - - emit contactUpdated(); -} - -bool ContactModel::updateUrl (const QString &old_url, const QString &url) { - if (old_url == url || !addUrl(url)) - return false; - - removeUrl(old_url); - - return true; -} - -// ------------------------------------------------------------------- - -QVariantMap ContactModel::getAddress () const { - -} - -void ContactModel::setAddress (const QVariantMap &address) { - - -} - -// ------------------------------------------------------------------- - -Presence::PresenceStatus ContactModel::getPresenceStatus () const { - return m_presence_status; -} - -Presence::PresenceLevel ContactModel::getPresenceLevel () const { - return Presence::getPresenceLevel(m_presence_status); -} -QString ContactModel::getSipAddress () const { - return Utils::linphoneStringToQString( - m_linphone_friend->getAddress()->asString() - ); -} diff --git a/tests/src/components/contacts/ContactModel.hpp b/tests/src/components/contacts/ContactModel.hpp deleted file mode 100644 index dda66574f..000000000 --- a/tests/src/components/contacts/ContactModel.hpp +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef CONTACT_MODEL_H_ -#define CONTACT_MODEL_H_ - -#include -#include - -#include "../presence/Presence.hpp" - -// =================================================================== - -class ContactModel : public QObject { - friend class ContactsListModel; - friend class ContactsListProxyModel; - - Q_OBJECT; - - Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY contactUpdated); - Q_PROPERTY(QString avatar READ getAvatar WRITE setAvatar NOTIFY contactUpdated); - Q_PROPERTY(QVariantList sipAddresses READ getSipAddresses NOTIFY contactUpdated); - Q_PROPERTY(QVariantList companies READ getCompanies NOTIFY contactUpdated); - Q_PROPERTY(QVariantList emails READ getEmails NOTIFY contactUpdated); - Q_PROPERTY(QVariantList urls READ getUrls NOTIFY contactUpdated); - Q_PROPERTY(QVariantMap address READ getAddress WRITE setAddress NOTIFY contactUpdated); - - Q_PROPERTY( - Presence::PresenceStatus presenceStatus - READ getPresenceStatus - NOTIFY contactUpdated - ); - - Q_PROPERTY( - Presence::PresenceLevel presenceLevel - READ getPresenceLevel - NOTIFY contactUpdated - ); - - Q_PROPERTY( - QString sipAddress - READ getSipAddress - NOTIFY contactUpdated - ); - -public: - ContactModel ( - std::shared_ptr linphone_friend, - bool is_detached = false - ); - -public slots: - - bool addSipAddress (const QString &sip_address); - void removeSipAddress (const QString &sip_address); - bool updateSipAddress (const QString &old_sip_address, const QString &sip_address); - - void addCompany (const QString &company); - void removeCompany (const QString &company); - void updateCompany (const QString &old_company, const QString &company); - - bool addEmail (const QString &email); - void removeEmail (const QString &email); - bool updateEmail (const QString &old_email, const QString &email); - - bool addUrl (const QString &url); - void removeUrl (const QString &url); - bool updateUrl (const QString &old_url, const QString &url); - -signals: - void contactUpdated (); - -private: - void edit (); - void done (); - - QString getUsername () const; - void setUsername (const QString &username); - - QString getAvatar () const; - void setAvatar (const QString &path); - - QVariantList getSipAddresses () const; - QVariantList getCompanies () const; - QVariantList getEmails () const; - QVariantList getUrls () const; - - QVariantMap getAddress () const; - void setAddress (const QVariantMap &address); - - Presence::PresenceStatus getPresenceStatus () const; - Presence::PresenceLevel getPresenceLevel () const; - - // TODO: Remove!!! - QString getSipAddress () const; - - bool m_is_detached; - - Presence::PresenceStatus m_presence_status = Presence::Offline; - - std::shared_ptr m_linphone_friend; -}; - -Q_DECLARE_METATYPE(ContactModel*); - -#endif // CONTACT_MODEL_H_ diff --git a/tests/src/components/contacts/ContactsListModel.cpp b/tests/src/components/contacts/ContactsListModel.cpp index a26588af4..aba27f5b5 100644 --- a/tests/src/components/contacts/ContactsListModel.cpp +++ b/tests/src/components/contacts/ContactsListModel.cpp @@ -8,9 +8,9 @@ using namespace std; -// =================================================================== +// ============================================================================= -ContactsListModel::ContactsListModel (QObject *parent): QAbstractListModel(parent) { +ContactsListModel::ContactsListModel (QObject *parent) : QAbstractListModel(parent) { m_linphone_friends = CoreManager::getInstance()->getCore()->getFriendsLists().front(); // Init contacts with linphone friends list. @@ -27,7 +27,7 @@ ContactsListModel::ContactsListModel (QObject *parent): QAbstractListModel(paren } } -int ContactsListModel::rowCount (const QModelIndex &) const { +int ContactsListModel::rowCount (const QModelIndex&) const { return m_list.count(); } @@ -49,7 +49,7 @@ QVariant ContactsListModel::data (const QModelIndex &index, int role) const { return QVariant(); } -bool ContactsListModel::removeRow (int row, const QModelIndex &) { +bool ContactsListModel::removeRow (int row, const QModelIndex&) { return removeRows(row, 1); } @@ -73,30 +73,20 @@ bool ContactsListModel::removeRows (int row, int count, const QModelIndex &paren return true; } -// ------------------------------------------------------------------- - -ContactModel *ContactsListModel::createDetachedContact () const { - return new ContactModel( - CoreManager::getInstance()->getCore()->createFriend(), - true - ); -} +// ----------------------------------------------------------------------------- ContactModel *ContactsListModel::mapSipAddressToContact (const QString &sipAddress) const { - // Maybe use a hashtable in future version to get a lower cost? - std::shared_ptr friend_ = m_linphone_friends->findFriendByUri( - Utils::qStringToLinphoneString(sipAddress) - ); + // TODO: Maybe use a hashtable in future version to get a lower cost? + shared_ptr friend_ = m_linphone_friends->findFriendByUri( + ::Utils::qStringToLinphoneString(sipAddress) + ); if (!friend_) { - qInfo() << "Map sip address to contact:" << sipAddress << "-> nullptr"; + qInfo() << QStringLiteral("Unable to map sip address: `%1`.").arg(sipAddress); return nullptr; } - ContactModel &contact = friend_->getData("contact-model"); - qInfo() << "Map sip address to contact:" << sipAddress << "->" << &contact; - - return &contact; + return &friend_->getData(ContactModel::NAME); } void ContactsListModel::removeContact (ContactModel *contact) { diff --git a/tests/src/components/contacts/ContactsListModel.hpp b/tests/src/components/contacts/ContactsListModel.hpp index 450b55b4e..3c2af153b 100644 --- a/tests/src/components/contacts/ContactsListModel.hpp +++ b/tests/src/components/contacts/ContactsListModel.hpp @@ -1,18 +1,18 @@ #ifndef CONTACTS_LIST_MODEL_H_ #define CONTACTS_LIST_MODEL_H_ -#include #include +#include -#include "ContactModel.hpp" +#include "../contact/ContactModel.hpp" -// =================================================================== +// ============================================================================= class ContactsListModel : public QAbstractListModel { - friend class ContactsListProxyModel; - Q_OBJECT; + friend class ContactsListProxyModel; + public: ContactsListModel (QObject *parent = Q_NULLPTR); @@ -25,10 +25,10 @@ public: bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; public slots: - ContactModel *createDetachedContact () const; ContactModel *mapSipAddressToContact (const QString &sipAddress) const; void removeContact (ContactModel *contact); + private: QList m_list; std::shared_ptr m_linphone_friends; diff --git a/tests/src/components/contacts/ContactsListProxyModel.cpp b/tests/src/components/contacts/ContactsListProxyModel.cpp index 9569070d9..d4286242f 100644 --- a/tests/src/components/contacts/ContactsListProxyModel.cpp +++ b/tests/src/components/contacts/ContactsListProxyModel.cpp @@ -1,23 +1,23 @@ #include #include "../../utils.hpp" -#include "ContactModel.hpp" +#include "../contact/ContactModel.hpp" #include "ContactsListModel.hpp" #include "ContactsListProxyModel.hpp" -#define USERNAME_WEIGHT 50.0f -#define MAIN_SIP_ADDRESS_WEIGHT 25.0f -#define OTHER_SIP_ADDRESSES_WEIGHT 25.0f +#define USERNAME_WEIGHT 50.f +#define SIP_ADDRESSES_WEIGHT 50.f -#define FACTOR_POS_1 0.90f -#define FACTOR_POS_2 0.80f -#define FACTOR_POS_3 0.70f -#define FACTOR_POS_OTHER 0.60f +#define FACTOR_POS_0 1.0f +#define FACTOR_POS_1 0.9f +#define FACTOR_POS_2 0.8f +#define FACTOR_POS_3 0.7f +#define FACTOR_POS_OTHER 0.6f using namespace std; -// =================================================================== +// ============================================================================= ContactsListModel *ContactsListProxyModel::m_list = nullptr; @@ -32,7 +32,7 @@ ContactsListModel *ContactsListProxyModel::m_list = nullptr; // - [_.-;@ ] is the main pattern (a separator). const QRegExp ContactsListProxyModel::m_search_separators("^[^_.-;@ ][_.-;@ ]"); -// ------------------------------------------------------------------- +// ----------------------------------------------------------------------------- ContactsListProxyModel::ContactsListProxyModel (QObject *parent) : QSortFilterProxyModel(parent) { if (m_list == nullptr) @@ -56,44 +56,35 @@ void ContactsListProxyModel::initContactsListModel (ContactsListModel *list) { } bool ContactsListProxyModel::filterAcceptsRow ( - int source_row, const QModelIndex &source_parent + int source_row, + const QModelIndex &source_parent ) const { QModelIndex index = sourceModel()->index(source_row, 0, source_parent); - const ContactModel *contact = qvariant_cast( - index.data() - ); + const ContactModel *contact = qvariant_cast(index.data()); - unsigned int weight = m_weights[contact] = static_cast( - computeContactWeight(*contact) - ); + m_weights[contact] = static_cast(computeContactWeight(*contact)); - return weight > 0 && ( + return m_weights[contact] > 0 && ( !m_use_connected_filter || contact->getPresenceLevel() != Presence::PresenceLevel::White ); } bool ContactsListProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const { - const ContactModel *contact_a = qvariant_cast( - sourceModel()->data(left) - ); - const ContactModel *contact_b = qvariant_cast( - sourceModel()->data(right) - ); + const ContactModel *contact_a = qvariant_cast(sourceModel()->data(left)); + const ContactModel *contact_b = qvariant_cast(sourceModel()->data(right)); unsigned int weight_a = m_weights[contact_a]; unsigned int weight_b = m_weights[contact_b]; // Sort by weight and name. - return ( - weight_a > weight_b || ( - weight_a == weight_b && - contact_a->m_linphone_friend->getName() <= contact_b->m_linphone_friend->getName() - ) + return weight_a > weight_b || ( + weight_a == weight_b && + contact_a->m_linphone_friend->getName() <= contact_b->m_linphone_friend->getName() ); } -// ------------------------------------------------------------------- +// ----------------------------------------------------------------------------- float ContactsListProxyModel::computeStringWeight (const QString &string, float percentage) const { int index = -1; @@ -105,8 +96,7 @@ float ContactsListProxyModel::computeStringWeight (const QString &string, float int tmp_offset = index - string.lastIndexOf(m_search_separators, index) - 1; if ((tmp_offset != -1 && tmp_offset < offset) || offset == -1) - if ((offset = tmp_offset) == 0) // Little optimization. - break; + if ((offset = tmp_offset) == 0) break; } // No weight. @@ -115,7 +105,7 @@ float ContactsListProxyModel::computeStringWeight (const QString &string, float // Weight & offset. switch (offset) { - case 0: return percentage; + case 0: return percentage * FACTOR_POS_0; case 1: return percentage * FACTOR_POS_1; case 2: return percentage * FACTOR_POS_2; case 3: return percentage * FACTOR_POS_3; @@ -126,27 +116,17 @@ float ContactsListProxyModel::computeStringWeight (const QString &string, float } float ContactsListProxyModel::computeContactWeight (const ContactModel &contact) const { - float weight = computeStringWeight(contact.getUsername(), USERNAME_WEIGHT); + float weight = computeStringWeight(contact.getVcardModel()->getUsername(), USERNAME_WEIGHT); // Get all contact's addresses. - const list > addresses = - contact.m_linphone_friend->getAddresses(); + const list > addresses = contact.m_linphone_friend->getAddresses(); - auto it = addresses.cbegin(); - - // It exists at least one sip address. - weight += computeStringWeight( - Utils::linphoneStringToQString((*it)->asString()), - MAIN_SIP_ADDRESS_WEIGHT - ); - - // Compute for other addresses. float size = static_cast(addresses.size()); - for (++it; it != addresses.cend(); ++it) + for (auto it = addresses.cbegin(); it != addresses.cend(); ++it) weight += computeStringWeight( - Utils::linphoneStringToQString((*it)->asString()), - OTHER_SIP_ADDRESSES_WEIGHT / size - ); + ::Utils::linphoneStringToQString((*it)->asString()), + SIP_ADDRESSES_WEIGHT / size + ); return weight; } diff --git a/tests/src/components/contacts/ContactsListProxyModel.hpp b/tests/src/components/contacts/ContactsListProxyModel.hpp index 7832359f6..81669931f 100644 --- a/tests/src/components/contacts/ContactsListProxyModel.hpp +++ b/tests/src/components/contacts/ContactsListProxyModel.hpp @@ -39,8 +39,9 @@ private: float computeContactWeight (const ContactModel &contact) const; bool isConnectedFilterUsed () const { - return m_use_connected_filter; + return m_use_connected_filter; } + void setConnectedFilter (bool use_connected_filter); static const QRegExp m_search_separators;