Commit 76def6d0 authored by Ronan Abhamon's avatar Ronan Abhamon

refactoring unstable

parent a314d1fd
...@@ -58,7 +58,8 @@ set(SOURCES ...@@ -58,7 +58,8 @@ set(SOURCES
src/components/camera/Camera.cpp src/components/camera/Camera.cpp
src/components/chat/ChatModel.cpp src/components/chat/ChatModel.cpp
src/components/chat/ChatProxyModel.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/ContactsListModel.cpp
src/components/contacts/ContactsListProxyModel.cpp src/components/contacts/ContactsListProxyModel.cpp
src/components/core/CoreManager.cpp src/components/core/CoreManager.cpp
...@@ -80,7 +81,8 @@ set(HEADERS ...@@ -80,7 +81,8 @@ set(HEADERS
src/components/camera/Camera.hpp src/components/camera/Camera.hpp
src/components/chat/ChatModel.hpp src/components/chat/ChatModel.hpp
src/components/chat/ChatProxyModel.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/ContactsListModel.hpp
src/components/contacts/ContactsListProxyModel.hpp src/components/contacts/ContactsListProxyModel.hpp
src/components/core/CoreManager.hpp src/components/core/CoreManager.hpp
......
...@@ -109,6 +109,10 @@ void App::registerTypes () { ...@@ -109,6 +109,10 @@ void App::registerTypes () {
"Linphone", 1, 0, "ContactModel", "ContactModel is uncreatable" "Linphone", 1, 0, "ContactModel", "ContactModel is uncreatable"
); );
qmlRegisterUncreatableType<VcardModel>(
"Linphone", 1, 0, "VcardModel", "VcardModel is uncreatable"
);
ContactsListProxyModel::initContactsListModel(new ContactsListModel()); ContactsListProxyModel::initContactsListModel(new ContactsListModel());
qmlRegisterType<ContactsListProxyModel>("Linphone", 1, 0, "ContactsListProxyModel"); qmlRegisterType<ContactsListProxyModel>("Linphone", 1, 0, "ContactsListProxyModel");
......
#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());
}
#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_
#include <belcard/belcard.hpp>
#include <QFileInfo> #include <QFileInfo>
#include <QImageReader> #include <QImageReader>
#include <QUuid>
#include <QtDebug> #include <QtDebug>
#include <QUuid>
#include <belcard/belcard.hpp>
#include "../../app/AvatarProvider.hpp" #include "../../app/AvatarProvider.hpp"
#include "../../app/Database.hpp" #include "../../app/Database.hpp"
#include "../../utils.hpp" #include "../../utils.hpp"
#include "../core/CoreManager.hpp" #include "../core/CoreManager.hpp"
#include "ContactModel.hpp" #include "VcardModel.hpp"
#define VCARD_SCHEME "linphone-desktop:/" #define VCARD_SCHEME "linphone-desktop:/"
using namespace std; using namespace std;
// =================================================================== // =============================================================================
template<class T> template<class T>
inline shared_ptr<T> findBelCardValue ( inline shared_ptr<T> findBelCardValue (const list<shared_ptr<T> > &list, const QString &value) {
const list<shared_ptr<T> > &list, string match = ::Utils::qStringToLinphoneString(value);
const QString &value
) {
string match = Utils::qStringToLinphoneString(value);
auto it = find_if( auto it = find_if(
list.cbegin(), list.cend(), list.cbegin(), list.cend(), [&match](const shared_ptr<T> &entry) {
[&match](const shared_ptr<T> &entry) { return match == entry->getValue();
return match == entry->getValue(); }
} );
);
return *it; return *it;
} }
// ------------------------------------------------------------------- // -----------------------------------------------------------------------------
ContactModel::ContactModel ( QString VcardModel::getUsername () const {
shared_ptr<linphone::Friend> linphone_friend, return ::Utils::linphoneStringToQString(m_vcard->getFullName());
bool is_detached
) {
linphone_friend->setData("contact-model", *this);
m_linphone_friend = linphone_friend;
m_is_detached = is_detached;
} }
// ------------------------------------------------------------------- void VcardModel::setUsername (const QString &username) {
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()) if (username.length() == 0 || username == getUsername())
return; return;
edit(); m_vcard->setFullName(::Utils::qStringToLinphoneString(username));
emit vcardUpdated();
if (!m_linphone_friend->setName(Utils::qStringToLinphoneString(username)))
emit contactUpdated();
done();
} }
// ------------------------------------------------------------------- // -----------------------------------------------------------------------------
QString ContactModel::getAvatar () const { QString VcardModel::getAvatar () const {
// Find desktop avatar. // Find desktop avatar.
list<shared_ptr<belcard::BelCardPhoto> > photos = list<shared_ptr<belcard::BelCardPhoto> > photos = m_vcard->getBelcard()->getPhotos();
m_linphone_friend->getVcard()->getBelcard()->getPhotos();
auto it = find_if( auto it = find_if(
photos.cbegin(), photos.cend(), [](const shared_ptr<belcard::BelCardPhoto> &photo) { photos.cbegin(), photos.cend(), [](const shared_ptr<belcard::BelCardPhoto> &photo) {
return !photo->getValue().compare(0, sizeof(VCARD_SCHEME) - 1, VCARD_SCHEME); return !photo->getValue().compare(0, sizeof(VCARD_SCHEME) - 1, VCARD_SCHEME);
} }
); );
// No path found. // No path found.
if (it == photos.cend()) if (it == photos.cend())
return ""; return "";
// Returns right path. // Returns right path.
return QStringLiteral("image://%1/%2") return QStringLiteral("image://%1/%2").arg(AvatarProvider::PROVIDER_ID).arg(
.arg(AvatarProvider::PROVIDER_ID) ::Utils::linphoneStringToQString((*it)->getValue().substr(sizeof(VCARD_SCHEME) - 1))
.arg(Utils::linphoneStringToQString( );
(*it)->getValue().substr(sizeof(VCARD_SCHEME) - 1)
));
} }
void ContactModel::setAvatar (const QString &path) { void VcardModel::setAvatar (const QString &path) {
// 1. Try to copy photo in avatars folder. // 1. Try to copy photo in avatars folder.
QFile file(path); QFile file(path);
...@@ -115,32 +78,31 @@ void ContactModel::setAvatar (const QString &path) { ...@@ -115,32 +78,31 @@ void ContactModel::setAvatar (const QString &path) {
.arg(uuid.mid(1, uuid.length() - 2)) // Remove `{}`. .arg(uuid.mid(1, uuid.length() - 2)) // Remove `{}`.
.arg(info.suffix()); .arg(info.suffix());
QString dest = Utils::linphoneStringToQString(Database::getAvatarsPath()) + QString dest = ::Utils::linphoneStringToQString(Database::getAvatarsPath()) + file_id;
file_id;
if (!file.copy(dest)) if (!file.copy(dest))
return; return;
qInfo() << QStringLiteral("Update avatar of `%1`. (path=%2)") qInfo() << QStringLiteral("Update avatar of `%1`. (path=%2)").arg(getUsername()).arg(dest);
.arg(getUsername()).arg(dest);
// 2. Edit vcard. // 2. Edit vcard.
edit(); shared_ptr<belcard::BelCard> belCard = m_vcard->getBelcard();
shared_ptr<belcard::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard();
list<shared_ptr<belcard::BelCardPhoto> > photos = belCard->getPhotos(); list<shared_ptr<belcard::BelCardPhoto> > photos = belCard->getPhotos();
// 3. Remove oldest photo. // 3. Remove oldest photo.
auto it = find_if( auto it = find_if(
photos.begin(), photos.end(), [](const shared_ptr<belcard::BelCardPhoto> &photo) { photos.begin(), photos.end(), [](const shared_ptr<belcard::BelCardPhoto> &photo) {
return !photo->getValue().compare(0, sizeof(VCARD_SCHEME) - 1, VCARD_SCHEME); return !photo->getValue().compare(0, sizeof(VCARD_SCHEME) - 1, VCARD_SCHEME);
} }
); );
if (it != photos.end()) { if (it != photos.end()) {
QString image_path(Utils::linphoneStringToQString( QString image_path(
Database::getAvatarsPath() + (*it)->getValue().substr(sizeof(VCARD_SCHEME) - 1) ::Utils::linphoneStringToQString(
)); Database::getAvatarsPath() + (*it)->getValue().substr(sizeof(VCARD_SCHEME) - 1)
)
);
if (!QFile::remove(image_path)) if (!QFile::remove(image_path))
qWarning() << QStringLiteral("Unable to remove `%1`.").arg(image_path); qWarning() << QStringLiteral("Unable to remove `%1`.").arg(image_path);
belCard->removePhoto(*it); belCard->removePhoto(*it);
...@@ -149,59 +111,49 @@ void ContactModel::setAvatar (const QString &path) { ...@@ -149,59 +111,49 @@ void ContactModel::setAvatar (const QString &path) {
// 4. Update. // 4. Update.
shared_ptr<belcard::BelCardPhoto> photo = shared_ptr<belcard::BelCardPhoto> photo =
belcard::BelCardGeneric::create<belcard::BelCardPhoto>(); belcard::BelCardGeneric::create<belcard::BelCardPhoto>();
photo->setValue(VCARD_SCHEME + Utils::qStringToLinphoneString(file_id)); photo->setValue(VCARD_SCHEME + ::Utils::qStringToLinphoneString(file_id));
belCard->addPhoto(photo); belCard->addPhoto(photo);
done(); emit vcardUpdated();
}
emit contactUpdated(); // -----------------------------------------------------------------------------
return; QVariantMap VcardModel::getAddress () const {
// TODO
} }
// ------------------------------------------------------------------- void VcardModel::setAddress (const QVariantMap &address) {
// TODO
}
QVariantList ContactModel::getSipAddresses () const { QVariantList VcardModel::getSipAddresses () const {
QVariantList list; QVariantList list;
for (const auto &address : m_linphone_friend->getAddresses()) for (const auto &address : m_vcard->getSipAddresses())
list.append(Utils::linphoneStringToQString(address->asString())); list.append(::Utils::linphoneStringToQString(address->asString()));
return list; return list;
} }
bool ContactModel::addSipAddress (const QString &sip_address) { bool VcardModel::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); qInfo() << QStringLiteral("Add new sip address: `%1`.").arg(sip_address);
m_vcard->addSipAddress(::Utils::qStringToLinphoneString(sip_address));
edit(); emit vcardUpdated();
m_linphone_friend->addAddress(address);
done();
emit contactUpdated();
return true; return true;
} }
void ContactModel::removeSipAddress (const QString &sip_address) { void VcardModel::removeSipAddress (const QString &sip_address) {
list<shared_ptr<linphone::Address> > addresses = m_linphone_friend->getAddresses(); list<shared_ptr<linphone::Address> > addresses = m_vcard->getSipAddresses();
string match = Utils::qStringToLinphoneString(sip_address); string match = ::Utils::qStringToLinphoneString(sip_address);
auto it = find_if( auto it = find_if(
addresses.cbegin(), addresses.cend(), addresses.cbegin(), addresses.cend(), [&match](const shared_ptr<linphone::Address> &address) {
[&match](const shared_ptr<linphone::Address> &address) { return match == address->asString();
return match == address->asString(); }
} );
);
if (it == addresses.cend()) { if (it == addresses.cend()) {
qWarning() << QStringLiteral("Unable to found sip address: `%1`.") qWarning() << QStringLiteral("Unable to found sip address: `%1`.")
...@@ -216,17 +168,12 @@ void ContactModel::removeSipAddress (const QString &sip_address) { ...@@ -216,17 +168,12 @@ void ContactModel::removeSipAddress (const QString &sip_address) {
} }
qInfo() << QStringLiteral("Remove sip address: `%1`.").arg(sip_address); qInfo() << QStringLiteral("Remove sip address: `%1`.").arg(sip_address);
m_vcard->removeSipAddress((*it)->asStringUriOnly());
edit(); emit vcardUpdated();
m_linphone_friend->removeAddress(*it);
done();
emit contactUpdated();
return;
} }
bool ContactModel::updateSipAddress (const QString &old_sip_address, const QString &sip_address) { bool VcardModel::updateSipAddress (const QString &old_sip_address, const QString &sip_address) {
if (old_sip_address == sip_address || !addSipAddress(sip_address)) if (old_sip_address == sip_address || !addSipAddress(sip_address))
return false; return false;
...@@ -235,34 +182,32 @@ bool ContactModel::updateSipAddress (const QString &old_sip_address, const QStri ...@@ -235,34 +182,32 @@ bool ContactModel::updateSipAddress (const QString &old_sip_address, const QStri
return true; return true;
} }
// ------------------------------------------------------------------- // -----------------------------------------------------------------------------
QVariantList ContactModel::getCompanies () const { QVariantList VcardModel::getCompanies () const {
QVariantList list; QVariantList list;
for (const auto &company : m_linphone_friend->getVcard()->getBelcard()->getRoles()) for (const auto &company : m_vcard->getBelcard()->getRoles())
list.append(Utils::linphoneStringToQString(company->getValue())); list.append(::Utils::linphoneStringToQString(company->getValue()));
return list; return list;
} }
void ContactModel::addCompany (const QString &company) { bool VcardModel::addCompany (const QString &company) {
shared_ptr<belcard::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard(); shared_ptr<belcard::BelCard> belCard = m_vcard->getBelcard();
shared_ptr<belcard::BelCardRole> value = shared_ptr<belcard::BelCardRole> value = belcard::BelCardGeneric::create<belcard::BelCardRole>();
belcard::BelCardGeneric::create<belcard::BelCardRole>(); value->setValue(::Utils::qStringToLinphoneString(company));
value->setValue(Utils::qStringToLinphoneString(company));
qInfo() << QStringLiteral("Add new company: `%1`.").arg(company); qInfo() << QStringLiteral("Add new company: `%1`.").arg(company);
edit();
belCard->addRole(value); belCard->addRole(value);
done();
emit contactUpdated(); emit vcardUpdated();
return true;
} }
void ContactModel::removeCompany (const QString &company) { void VcardModel::removeCompany (const QString &company) {
shared_ptr<belcard::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard(); shared_ptr<belcard::BelCard> belCard = m_vcard->getBelcard();
shared_ptr<belcard::BelCardRole> value = findBelCardValue(belCard->getRoles(), company); shared_ptr<belcard::BelCardRole> value = findBelCardValue(belCard->getRoles(), company);
if (!value) { if (!value) {
...@@ -271,53 +216,47 @@ void ContactModel::removeCompany (const QString &company) { ...@@ -271,53 +216,47 @@ void ContactModel::removeCompany (const QString &company) {
} }
qInfo() << QStringLiteral("Remove company: `%1`.").arg(company); qInfo() << QStringLiteral("Remove company: `%1`.").arg(company);
edit();
belCard->removeRole(value); belCard->removeRole(value);
done();
emit contactUpdated(); emit vcardUpdated();
} }
void ContactModel::updateCompany (const QString &old_company, const QString &company) { bool VcardModel::updateCompany (const QString &old_company, const QString &company) {
if (old_company == company) if (old_company == company || !addCompany(company))
return; return false;
addCompany(company);
removeCompany(old_company); removeCompany(old_company);
return true;
} }
// ------------------------------------------------------------------- // -----------------------------------------------------------------------------
QVariantList ContactModel::getEmails () const { QVariantList VcardModel::getEmails () const {
QVariantList list; QVariantList list;
for (const auto &email : m_linphone_friend->getVcard()->getBelcard()->getEmails()) for (const auto &email : m_vcard->getBelcard()->getEmails())
list.append(Utils::linphoneStringToQString(email->getValue())); list.append(::Utils::linphoneStringToQString(email->getValue()));
return list; return list;
} }
bool ContactModel::addEmail (const QString &email) { bool VcardModel::addEmail (const QString &email) {
shared_ptr<belcard::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard(); shared_ptr<belcard::BelCard> belCard = m_vcard->getBelcard();
shared_ptr<belcard::BelCardEmail> value = shared_ptr<belcard::BelCardEmail> value =
belcard::BelCardGeneric::create<belcard::BelCardEmail>(); belcard::BelCardGeneric::create<belcard::BelCardEmail>();
value->setValue(Utils::qStringToLinphoneString(email)); value->setValue(::Utils::qStringToLinphoneString(email));
qInfo() << QStringLiteral("Add new email: `%1`.").arg(email); qInfo() << QStringLiteral("Add new email: `%1`.").arg(email);
edit();
belCard->addEmail(value); belCard->addEmail(value);
done();
emit contactUpdated(); emit vcardUpdated();
// TODO: Check if email is valid.
return true; return true;
} }
void ContactModel::removeEmail (const QString &email) { void VcardModel::removeEmail (const QString &email) {
shared_ptr<belcard::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard(); shared_ptr<belcard::BelCard> belCard = m_vcard->getBelcard();
shared_ptr<belcard::BelCardEmail> value = findBelCardValue(belCard->getEmails(), email); shared_ptr<belcard::BelCardEmail> value = findBelCardValue(belCard->getEmails(), email);
if (!value) { if (!value) {
...@@ -326,15 +265,12 @@ void ContactModel::removeEmail (const QString &email) { ...@@ -326,15 +265,12 @@ void ContactModel::removeEmail (const QString &email) {
} }
qInfo() << QStringLiteral("Remove email: `%1`.").arg(email); qInfo() << QStringLiteral("Remove email: `%1`.").arg(email);
edit();
belCard->removeEmail(value); belCard->removeEmail(value);
done();
emit contactUpdated(); emit vcardUpdated();
} }
bool ContactModel::updateEmail (const QString &old_email, const QString &email) { bool VcardModel::updateEmail (const QString &old_email, const QString &email) {
if (old_email == email || !addEmail(email)) if (old_email == email || !addEmail(email))
return false; return false;
...@@ -343,39 +279,32 @@ bool ContactModel::updateEmail (const QString &old_email, const QString &email) ...@@ -343,39 +279,32 @@ bool ContactModel::updateEmail (const QString &old_email, const QString &email)
return true; return true;
} }
// ------------------------------------------------------------------- // -----------------------------------------------------------------------------
QVariantList ContactModel::getUrls () const { QVariantList VcardModel::getUrls () const {
QVariantList list; QVariantList list;
qDebug() << "card" << m_linphone_friend->getVcard().get(); for (const auto &url : m_vcard->getBelcard()->getURLs())
list.append(::Utils::linphoneStringToQString(url->getValue()));
for (const auto &url : m_linphone_friend->getVcard()->getBelcard()->getURLs())
list.append(Utils::linphoneStringToQString(url->getValue()));
return list; return list;
} }
bool ContactModel::addUrl (const QString &url) { bool VcardModel::addUrl (const QString &url) {
shared_ptr<belcard::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard(); shared_ptr<belcard::BelCard> belCard = m_vcard->getBelcard();
shared_ptr<belcard::BelCardURL> value = shared_ptr<belcard::BelCardURL> value = belcard::BelCardGeneric::create<belcard::BelCardURL>();
belcard::BelCardGeneric::create<belcard::BelCardURL>(); value->setValue(::Utils::qStringToLinphoneString(url));
value->setValue(Utils::qStringToLinphoneString(url));
qInfo() << QStringLiteral("Add new url: `%1`.").arg(url); qInfo() << QStringLiteral("Add new url: `%1`.").arg(url);
edit();
belCard->addURL(value); belCard->addURL(value);
done();
emit contactUpdated(); emit vcardUpdated();
// TODO: Check if url is valid.
return true; return true;
} }
void ContactModel::removeUrl (const QString &url) { void VcardModel::removeUrl (const QString &url) {
shared_ptr<belcard::BelCard> belCard = m_linphone_friend->getVcard()->getBelcard(); shared_ptr<belcard::BelCard> belCard = m_vcard->getBelcard();
shared_ptr<belcard::BelCardURL> value = findBelCardValue(belCard->getURLs(), url); shared_ptr<belcard::BelCardURL> value = findBelCardValue(belCard->getURLs(), url);
if (!value) { if (!value) {
...@@ -384,15 +313,12 @@ void ContactModel::removeUrl (const QString &url) { ...@@ -384,15 +313,12 @@ void ContactModel::removeUrl (const QString &url) {
} }
qInfo() << QStringLiteral("Remove url: `%1`.").arg(url); qInfo() << QStringLiteral("Remove url: `%1`.").arg(url);
edit();
belCard->removeURL(value); belCard->removeURL(value);
done();
emit contactUpdated(); emit vcardUpdated();
} }
bool ContactModel::updateUrl (const QString &old_url, const QString &url) { bool VcardModel::updateUrl (const QString &old_url, const QString &url) {
if (old_url == url || !addUrl(url)) if (old_url == url || !addUrl(url))
return false; return false;
...@@ -400,29 +326,3 @@ bool ContactModel::updateUrl (const QString &old_url, const QString &url) { ...@@ -400,29 +326,3 @@ bool ContactModel::updateUrl (const QString &old_url, const QString &url) {
return true; 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()
);
}
#ifndef CONTACT_MODEL_H_ #ifndef VCARD_MODEL_H_
#define CONTACT_MODEL_H_ #define VCARD_MODEL_H_
#include <QObject>
#include <linphone++/linphone.hh> #include <linphone++/linphone.hh>
#include <QObject>
#include "../presence/Presence.hpp" // =============================================================================
// ===================================================================
class ContactModel : public QObject {
friend class ContactsListModel;
friend class ContactsListProxyModel;
class VcardModel : public QObject {
Q_OBJECT; Q_OBJECT;
Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY contactUpdated); Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY vcardUpdated);
Q_PROPERTY(QString avatar READ getAvatar WRITE setAvatar NOTIFY contactUpdated); Q_PROPERTY(QString avatar READ getAvatar WRITE setAvatar NOTIFY vcardUpdated);
Q_PROPERTY(QVariantList sipAddresses READ getSipAddresses NOTIFY contactUpdated); Q_PROPERTY(QVariantMap address READ getAddress WRITE setAddress NOTIFY vcardUpdated);
Q_PROPERTY(QVariantList companies READ getCompanies NOTIFY contactUpdated); Q_PROPERTY(QVariantList sipAddresses READ getSipAddresses NOTIFY vcardUpdated);
Q_PROPERTY(QVariantList emails READ getEmails NOTIFY contactUpdated); Q_PROPERTY(QVariantList companies READ getCompanies NOTIFY vcardUpdated);
Q_PROPERTY(QVariantList urls READ getUrls NOTIFY contactUpdated); Q_PROPERTY(QVariantList emails READ getEmails NOTIFY vcardUpdated);
Q_PROPERTY(QVariantMap address READ getAddress WRITE setAddress NOTIFY contactUpdated); Q_PROPERTY(QVariantList urls READ getUrls NOTIFY vcardUpdated);
Q_PROPERTY( friend class ContactsListProxyModel;
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: public:
ContactModel ( VcardModel (std::shared_ptr<linphone::Vcard> vcard) : m_vcard(vcard) {}
std::shared_ptr<linphone::Friend> linphone_friend,
bool is_detached = false
);
public slots: ~VcardModel () = default;
public slots:
bool addSipAddress (const QString &sip_address); bool addSipAddress (const QString &sip_address);
void removeSipAddress (const QString &sip_address); void removeSipAddress (const QString &sip_address);
bool updateSipAddress (const QString &old_sip_address, const QString &sip_address); bool updateSipAddress (const QString &old_sip_address, const QString &sip_address);
void addCompany (const QString &company); bool addCompany (const QString &company);
void removeCompany (const QString &company); void removeCompany (const QString &company);
void updateCompany (const QString &old_company, const QString &company); bool updateCompany (const QString &old_company, const QString &company);
bool addEmail (const QString &email); bool addEmail (const QString &email);
void removeEmail (const QString &email); void removeEmail (const QString &email);
...@@ -65,39 +42,26 @@ public slots: ...@@ -65,39 +42,26 @@ public slots:
bool updateUrl (const QString &old_url, const QString &url); bool updateUrl (const QString &old_url, const QString &url);
signals: signals:
void contactUpdated (); void vcardUpdated ();
private: private:
void edit ();
void done ();
QString getUsername () const; QString getUsername () const;
void setUsername (const QString &username); void setUsername (const QString &username);
QString getAvatar () const; QString getAvatar () const;
void setAvatar (const QString &path); void setAvatar (const QString &path);
QVariantMap getAddress () const;
void setAddress (const QVariantMap &address);
QVariantList getSipAddresses () const; QVariantList getSipAddresses () const;
QVariantList getCompanies () const; QVariantList getCompanies () const;
QVariantList getEmails () const; QVariantList getEmails () const;
QVariantList getUrls () const; QVariantList getUrls () const;
QVariantMap getAddress () const; std::shared_ptr<linphone::Vcard> m_vcard;
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*); Q_DECLARE_METATYPE(VcardModel *);
#endif // CONTACT_MODEL_H_ #endif // VCARD_MODEL_H_
...@@ -8,9 +8,9 @@ ...@@ -8,9 +8,9 @@
using namespace std; using namespace std;
// =================================================================== // =============================================================================
ContactsListModel::ContactsListModel (QObject *parent): QAbstractListModel(parent) { ContactsListModel::ContactsListModel (QObject *parent) : QAbstractListModel(parent) {
m_linphone_friends = CoreManager::getInstance()->getCore()->getFriendsLists().front(); m_linphone_friends = CoreManager::getInstance()->getCore()->getFriendsLists().front();
// Init contacts with linphone friends list. // Init contacts with linphone friends list.
...@@ -27,7 +27,7 @@ ContactsListModel::ContactsListModel (QObject *parent): QAbstractListModel(paren ...@@ -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(); return m_list.count();
} }
...@@ -49,7 +49,7 @@ QVariant ContactsListModel::data (const QModelIndex &index, int role) const { ...@@ -49,7 +49,7 @@ QVariant ContactsListModel::data (const QModelIndex &index, int role) const {
return QVariant(); return QVariant();
} }
bool ContactsListModel::removeRow (int row, const QModelIndex &) { bool ContactsListModel::removeRow (int row, const QModelIndex&) {
return removeRows(row, 1); return removeRows(row, 1);
} }
...@@ -73,30 +73,20 @@ bool ContactsListModel::removeRows (int row, int count, const QModelIndex &paren ...@@ -73,30 +73,20 @@ bool ContactsListModel::removeRows (int row, int count, const QModelIndex &paren
return true; return true;
} }
// ------------------------------------------------------------------- // -----------------------------------------------------------------------------
ContactModel *ContactsListModel::createDetachedContact () const {
return new ContactModel(
CoreManager::getInstance()->getCore()->createFriend(),
true
);
}
ContactModel *ContactsListModel::mapSipAddressToContact (const QString &sipAddress) const { ContactModel *ContactsListModel::mapSipAddressToContact (const QString &sipAddress) const {
// Maybe use a hashtable in future version to get a lower cost? // TODO: Maybe use a hashtable in future version to get a lower cost?
std::shared_ptr<linphone::Friend> friend_ = m_linphone_friends->findFriendByUri( shared_ptr<linphone::Friend> friend_ = m_linphone_friends->findFriendByUri(
Utils::qStringToLinphoneString(sipAddress) ::Utils::qStringToLinphoneString(sipAddress)
); );
if (!friend_) { if (!friend_) {
qInfo() << "Map sip address to contact:" << sipAddress << "-> nullptr"; qInfo() << QStringLiteral("Unable to map sip address: `%1`.").arg(sipAddress);
return nullptr; return nullptr;
} }
ContactModel &contact = friend_->getData<ContactModel>("contact-model"); return &friend_->getData<ContactModel>(ContactModel::NAME);
qInfo() << "Map sip address to contact:" << sipAddress << "->" << &contact;
return &contact;
} }
void ContactsListModel::removeContact (ContactModel *contact) { void ContactsListModel::removeContact (ContactModel *contact) {
......
#ifndef CONTACTS_LIST_MODEL_H_ #ifndef CONTACTS_LIST_MODEL_H_
#define CONTACTS_LIST_MODEL_H_ #define CONTACTS_LIST_MODEL_H_
#include <QAbstractListModel>
#include <linphone++/linphone.hh> #include <linphone++/linphone.hh>
#include <QAbstractListModel>
#include "ContactModel.hpp" #include "../contact/ContactModel.hpp"
// =================================================================== // =============================================================================
class ContactsListModel : public QAbstractListModel { class ContactsListModel : public QAbstractListModel {
friend class ContactsListProxyModel;
Q_OBJECT; Q_OBJECT;
friend class ContactsListProxyModel;
public: public:
ContactsListModel (QObject *parent = Q_NULLPTR); ContactsListModel (QObject *parent = Q_NULLPTR);
...@@ -25,10 +25,10 @@ public: ...@@ -25,10 +25,10 @@ public:
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override; bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
public slots: public slots:
ContactModel *createDetachedContact () const;
ContactModel *mapSipAddressToContact (const QString &sipAddress) const; ContactModel *mapSipAddressToContact (const QString &sipAddress) const;
void removeContact (ContactModel *contact); void removeContact (ContactModel *contact);
private: private:
QList<ContactModel *> m_list; QList<ContactModel *> m_list;
std::shared_ptr<linphone::FriendList> m_linphone_friends; std::shared_ptr<linphone::FriendList> m_linphone_friends;
......
#include <QDebug> #include <QDebug>
#include "../../utils.hpp" #include "../../utils.hpp"
#include "ContactModel.hpp" #include "../contact/ContactModel.hpp"
#include "ContactsListModel.hpp" #include "ContactsListModel.hpp"
#include "ContactsListProxyModel.hpp" #include "ContactsListProxyModel.hpp"
#define USERNAME_WEIGHT 50.0f #define USERNAME_WEIGHT 50.f
#define MAIN_SIP_ADDRESS_WEIGHT 25.0f #define SIP_ADDRESSES_WEIGHT 50.f
#define OTHER_SIP_ADDRESSES_WEIGHT 25.0f
#define FACTOR_POS_1 0.90f #define FACTOR_POS_0 1.0f
#define FACTOR_POS_2 0.80f #define FACTOR_POS_1 0.9f
#define FACTOR_POS_3 0.70f #define FACTOR_POS_2 0.8f
#define FACTOR_POS_OTHER 0.60f #define FACTOR_POS_3 0.7f
#define FACTOR_POS_OTHER 0.6f
using namespace std; using namespace std;
// =================================================================== // =============================================================================
ContactsListModel *ContactsListProxyModel::m_list = nullptr; ContactsListModel *ContactsListProxyModel::m_list = nullptr;
...@@ -32,7 +32,7 @@ ContactsListModel *ContactsListProxyModel::m_list = nullptr; ...@@ -32,7 +32,7 @@ ContactsListModel *ContactsListProxyModel::m_list = nullptr;
// - [_.-;@ ] is the main pattern (a separator). // - [_.-;@ ] is the main pattern (a separator).
const QRegExp ContactsListProxyModel::m_search_separators("^[^_.-;@ ][_.-;@ ]"); const QRegExp ContactsListProxyModel::m_search_separators("^[^_.-;@ ][_.-;@ ]");
// ------------------------------------------------------------------- // -----------------------------------------------------------------------------
ContactsListProxyModel::ContactsListProxyModel (QObject *parent) : QSortFilterProxyModel(parent) { ContactsListProxyModel::ContactsListProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
if (m_list == nullptr) if (m_list == nullptr)
...@@ -56,44 +56,35 @@ void ContactsListProxyModel::initContactsListModel (ContactsListModel *list) { ...@@ -56,44 +56,35 @@ void ContactsListProxyModel::initContactsListModel (ContactsListModel *list) {
} }
bool ContactsListProxyModel::filterAcceptsRow ( bool ContactsListProxyModel::filterAcceptsRow (
int source_row, const QModelIndex &source_parent int source_row,
const QModelIndex &source_parent
) const { ) const {
QModelIndex index = sourceModel()->index(source_row, 0, source_parent); QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
const ContactModel *contact = qvariant_cast<ContactModel *>( const ContactModel *contact = qvariant_cast<ContactModel *>(index.data());
index.data()
);
unsigned int weight = m_weights[contact] = static_cast<unsigned int>( m_weights[contact] = static_cast<unsigned int>(computeContactWeight(*contact));
computeContactWeight(*contact)
);
return weight > 0 && ( return m_weights[contact] > 0 && (
!m_use_connected_filter || !m_use_connected_filter ||
contact->getPresenceLevel() != Presence::PresenceLevel::White contact->getPresenceLevel() != Presence::PresenceLevel::White
); );
} }
bool ContactsListProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const { bool ContactsListProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
const ContactModel *contact_a = qvariant_cast<ContactModel *>( const ContactModel *contact_a = qvariant_cast<ContactModel *>(sourceModel()->data(left));
sourceModel()->data(left) const ContactModel *contact_b = qvariant_cast<ContactModel *>(sourceModel()->data(right));
);
const ContactModel *contact_b = qvariant_cast<ContactModel *>(
sourceModel()->data(right)
);
unsigned int weight_a = m_weights[contact_a]; unsigned int weight_a = m_weights[contact_a];
unsigned int weight_b = m_weights[contact_b]; unsigned int weight_b = m_weights[contact_b];
// Sort by weight and name. // Sort by weight and name.
return ( return weight_a > weight_b || (
weight_a > weight_b || ( weight_a == weight_b &&
weight_a == weight_b && contact_a->m_linphone_friend->getName() <= contact_b->m_linphone_friend->getName()
contact_a->m_linphone_friend->getName() <= contact_b->m_linphone_friend->getName()
)
); );
} }
// ------------------------------------------------------------------- // -----------------------------------------------------------------------------
float ContactsListProxyModel::computeStringWeight (const QString &string, float percentage) const { float ContactsListProxyModel::computeStringWeight (const QString &string, float percentage) const {
int index = -1; int index = -1;
...@@ -105,8 +96,7 @@ float ContactsListProxyModel::computeStringWeight (const QString &string, float ...@@ -105,8 +96,7 @@ float ContactsListProxyModel::computeStringWeight (const QString &string, float
int tmp_offset = index - string.lastIndexOf(m_search_separators, index) - 1; int tmp_offset = index - string.lastIndexOf(m_search_separators, index) - 1;
if ((tmp_offset != -1 && tmp_offset < offset) || offset == -1) if ((tmp_offset != -1 && tmp_offset < offset) || offset == -1)
if ((offset = tmp_offset) == 0) // Little optimization. if ((offset = tmp_offset) == 0) break;
break;
} }
// No weight. // No weight.
...@@ -115,7 +105,7 @@ float ContactsListProxyModel::computeStringWeight (const QString &string, float ...@@ -115,7 +105,7 @@ float ContactsListProxyModel::computeStringWeight (const QString &string, float
// Weight & offset. // Weight & offset.
switch (offset) { switch (offset) {
case 0: return percentage; case 0: return percentage * FACTOR_POS_0;
case 1: return percentage * FACTOR_POS_1; case 1: return percentage * FACTOR_POS_1;
case 2: return percentage * FACTOR_POS_2; case 2: return percentage * FACTOR_POS_2;
case 3: return percentage * FACTOR_POS_3; case 3: return percentage * FACTOR_POS_3;
...@@ -126,27 +116,17 @@ float ContactsListProxyModel::computeStringWeight (const QString &string, float ...@@ -126,27 +116,17 @@ float ContactsListProxyModel::computeStringWeight (const QString &string, float
} }
float ContactsListProxyModel::computeContactWeight (const ContactModel &contact) const { 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. // Get all contact's addresses.
const list<shared_ptr<linphone::Address> > addresses = const list<shared_ptr<linphone::Address> > addresses = contact.m_linphone_friend->getAddresses();
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()); float size = static_cast<float>(addresses.size());
for (++it; it != addresses.cend(); ++it) for (auto it = addresses.cbegin(); it != addresses.cend(); ++it)
weight += computeStringWeight( weight += computeStringWeight(
Utils::linphoneStringToQString((*it)->asString()), ::Utils::linphoneStringToQString((*it)->asString()),
OTHER_SIP_ADDRESSES_WEIGHT / size SIP_ADDRESSES_WEIGHT / size
); );
return weight; return weight;
} }
......
...@@ -39,8 +39,9 @@ private: ...@@ -39,8 +39,9 @@ private:
float computeContactWeight (const ContactModel &contact) const; float computeContactWeight (const ContactModel &contact) const;
bool isConnectedFilterUsed () const { bool isConnectedFilterUsed () const {
return m_use_connected_filter; return m_use_connected_filter;
} }
void setConnectedFilter (bool use_connected_filter); void setConnectedFilter (bool use_connected_filter);
static const QRegExp m_search_separators; static const QRegExp m_search_separators;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment