mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-28 01:09:19 +00:00
refactoring unstable
This commit is contained in:
parent
a314d1fded
commit
76def6d0f7
12 changed files with 539 additions and 610 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -109,6 +109,10 @@ void App::registerTypes () {
|
|||
"Linphone", 1, 0, "ContactModel", "ContactModel is uncreatable"
|
||||
);
|
||||
|
||||
qmlRegisterUncreatableType<VcardModel>(
|
||||
"Linphone", 1, 0, "VcardModel", "VcardModel is uncreatable"
|
||||
);
|
||||
|
||||
ContactsListProxyModel::initContactsListModel(new ContactsListModel());
|
||||
qmlRegisterType<ContactsListProxyModel>("Linphone", 1, 0, "ContactsListProxyModel");
|
||||
|
||||
|
|
|
|||
25
tests/src/components/contact/ContactModel.cpp
Normal file
25
tests/src/components/contact/ContactModel.cpp
Normal file
|
|
@ -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) {
|
||||
linphone_friend->setData(NAME, *this);
|
||||
m_linphone_friend = linphone_friend;
|
||||
m_vcard = make_shared<VcardModel>(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());
|
||||
}
|
||||
63
tests/src/components/contact/ContactModel.hpp
Normal file
63
tests/src/components/contact/ContactModel.hpp
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef CONTACT_MODEL_H_
|
||||
#define CONTACT_MODEL_H_
|
||||
|
||||
#include <linphone++/linphone.hh>
|
||||
#include <QObject>
|
||||
|
||||
#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> 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<VcardModel> getVcardModel () const {
|
||||
return m_vcard;
|
||||
}
|
||||
|
||||
VcardModel *getVcardModelPtr () const {
|
||||
return m_vcard.get();
|
||||
}
|
||||
|
||||
std::shared_ptr<VcardModel> m_vcard;
|
||||
std::shared_ptr<linphone::Friend> m_linphone_friend;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(ContactModel *);
|
||||
|
||||
#endif // CONTACT_MODEL_H_
|
||||
328
tests/src/components/contact/VcardModel.cpp
Normal file
328
tests/src/components/contact/VcardModel.cpp
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
#include <belcard/belcard.hpp>
|
||||
#include <QFileInfo>
|
||||
#include <QImageReader>
|
||||
#include <QtDebug>
|
||||
#include <QUuid>
|
||||
|
||||
#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<class T>
|
||||
inline shared_ptr<T> findBelCardValue (const list<shared_ptr<T> > &list, const QString &value) {
|
||||
string match = ::Utils::qStringToLinphoneString(value);
|
||||
|
||||
auto it = find_if(
|
||||
list.cbegin(), list.cend(), [&match](const shared_ptr<T> &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<shared_ptr<belcard::BelCardPhoto> > photos = m_vcard->getBelcard()->getPhotos();
|
||||
auto it = find_if(
|
||||
photos.cbegin(), photos.cend(), [](const shared_ptr<belcard::BelCardPhoto> &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::BelCard> belCard = m_vcard->getBelcard();
|
||||
list<shared_ptr<belcard::BelCardPhoto> > photos = belCard->getPhotos();
|
||||
|
||||
// 3. Remove oldest photo.
|
||||
auto it = find_if(
|
||||
photos.begin(), photos.end(), [](const shared_ptr<belcard::BelCardPhoto> &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<belcard::BelCardPhoto> photo =
|
||||
belcard::BelCardGeneric::create<belcard::BelCardPhoto>();
|
||||
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<shared_ptr<linphone::Address> > addresses = m_vcard->getSipAddresses();
|
||||
string match = ::Utils::qStringToLinphoneString(sip_address);
|
||||
|
||||
auto it = find_if(
|
||||
addresses.cbegin(), addresses.cend(), [&match](const shared_ptr<linphone::Address> &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::BelCard> belCard = m_vcard->getBelcard();
|
||||
shared_ptr<belcard::BelCardRole> value = belcard::BelCardGeneric::create<belcard::BelCardRole>();
|
||||
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::BelCard> belCard = m_vcard->getBelcard();
|
||||
shared_ptr<belcard::BelCardRole> 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::BelCard> belCard = m_vcard->getBelcard();
|
||||
shared_ptr<belcard::BelCardEmail> value =
|
||||
belcard::BelCardGeneric::create<belcard::BelCardEmail>();
|
||||
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::BelCard> belCard = m_vcard->getBelcard();
|
||||
shared_ptr<belcard::BelCardEmail> 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::BelCard> belCard = m_vcard->getBelcard();
|
||||
shared_ptr<belcard::BelCardURL> value = belcard::BelCardGeneric::create<belcard::BelCardURL>();
|
||||
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::BelCard> belCard = m_vcard->getBelcard();
|
||||
shared_ptr<belcard::BelCardURL> 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;
|
||||
}
|
||||
67
tests/src/components/contact/VcardModel.hpp
Normal file
67
tests/src/components/contact/VcardModel.hpp
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#ifndef VCARD_MODEL_H_
|
||||
#define VCARD_MODEL_H_
|
||||
|
||||
#include <linphone++/linphone.hh>
|
||||
#include <QObject>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
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<linphone::Vcard> 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<linphone::Vcard> m_vcard;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(VcardModel *);
|
||||
|
||||
#endif // VCARD_MODEL_H_
|
||||
|
|
@ -1,428 +0,0 @@
|
|||
#include <QFileInfo>
|
||||
#include <QImageReader>
|
||||
#include <QUuid>
|
||||
#include <QtDebug>
|
||||
|
||||
#include <belcard/belcard.hpp>
|
||||
|
||||
#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<class T>
|
||||
inline shared_ptr<T> findBelCardValue (
|
||||
const list<shared_ptr<T> > &list,
|
||||
const QString &value
|
||||
) {
|
||||
string match = Utils::qStringToLinphoneString(value);
|
||||
|
||||
auto it = find_if(
|
||||
list.cbegin(), list.cend(),
|
||||
[&match](const shared_ptr<T> &entry) {
|
||||
return match == entry->getValue();
|
||||
}
|
||||
);
|
||||
|
||||
return *it;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
ContactModel::ContactModel (
|
||||
shared_ptr<linphone::Friend> 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<shared_ptr<belcard::BelCardPhoto> > photos =
|
||||
m_linphone_friend->getVcard()->getBelcard()->getPhotos();
|
||||
auto it = find_if(
|
||||
photos.cbegin(), photos.cend(), [](const shared_ptr<belcard::BelCardPhoto> &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::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard();
|
||||
list<shared_ptr<belcard::BelCardPhoto> > photos = belCard->getPhotos();
|
||||
|
||||
// 3. Remove oldest photo.
|
||||
auto it = find_if(
|
||||
photos.begin(), photos.end(), [](const shared_ptr<belcard::BelCardPhoto> &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<belcard::BelCardPhoto> photo =
|
||||
belcard::BelCardGeneric::create<belcard::BelCardPhoto>();
|
||||
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<linphone::Address> 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<shared_ptr<linphone::Address> > addresses = m_linphone_friend->getAddresses();
|
||||
string match = Utils::qStringToLinphoneString(sip_address);
|
||||
|
||||
auto it = find_if(
|
||||
addresses.cbegin(), addresses.cend(),
|
||||
[&match](const shared_ptr<linphone::Address> &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::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard();
|
||||
shared_ptr<belcard::BelCardRole> value =
|
||||
belcard::BelCardGeneric::create<belcard::BelCardRole>();
|
||||
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::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard();
|
||||
shared_ptr<belcard::BelCardRole> 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::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard();
|
||||
shared_ptr<belcard::BelCardEmail> value =
|
||||
belcard::BelCardGeneric::create<belcard::BelCardEmail>();
|
||||
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::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard();
|
||||
shared_ptr<belcard::BelCardEmail> 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::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard();
|
||||
shared_ptr<belcard::BelCardURL> value =
|
||||
belcard::BelCardGeneric::create<belcard::BelCardURL>();
|
||||
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::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard();
|
||||
shared_ptr<belcard::BelCardURL> 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()
|
||||
);
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
#ifndef CONTACT_MODEL_H_
|
||||
#define CONTACT_MODEL_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
#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> 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<linphone::Friend> m_linphone_friend;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(ContactModel*);
|
||||
|
||||
#endif // CONTACT_MODEL_H_
|
||||
|
|
@ -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<linphone::Friend> friend_ = m_linphone_friends->findFriendByUri(
|
||||
Utils::qStringToLinphoneString(sipAddress)
|
||||
);
|
||||
// TODO: Maybe use a hashtable in future version to get a lower cost?
|
||||
shared_ptr<linphone::Friend> 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<ContactModel>("contact-model");
|
||||
qInfo() << "Map sip address to contact:" << sipAddress << "->" << &contact;
|
||||
|
||||
return &contact;
|
||||
return &friend_->getData<ContactModel>(ContactModel::NAME);
|
||||
}
|
||||
|
||||
void ContactsListModel::removeContact (ContactModel *contact) {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
#ifndef CONTACTS_LIST_MODEL_H_
|
||||
#define CONTACTS_LIST_MODEL_H_
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <linphone++/linphone.hh>
|
||||
#include <QAbstractListModel>
|
||||
|
||||
#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<ContactModel *> m_list;
|
||||
std::shared_ptr<linphone::FriendList> m_linphone_friends;
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
#include <QDebug>
|
||||
|
||||
#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<ContactModel *>(
|
||||
index.data()
|
||||
);
|
||||
const ContactModel *contact = qvariant_cast<ContactModel *>(index.data());
|
||||
|
||||
unsigned int weight = m_weights[contact] = static_cast<unsigned int>(
|
||||
computeContactWeight(*contact)
|
||||
);
|
||||
m_weights[contact] = static_cast<unsigned int>(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<ContactModel *>(
|
||||
sourceModel()->data(left)
|
||||
);
|
||||
const ContactModel *contact_b = qvariant_cast<ContactModel *>(
|
||||
sourceModel()->data(right)
|
||||
);
|
||||
const ContactModel *contact_a = qvariant_cast<ContactModel *>(sourceModel()->data(left));
|
||||
const ContactModel *contact_b = qvariant_cast<ContactModel *>(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<shared_ptr<linphone::Address> > addresses =
|
||||
contact.m_linphone_friend->getAddresses();
|
||||
const list<shared_ptr<linphone::Address> > 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<float>(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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue