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

refactoring unstable

parent a314d1fd
......@@ -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");
......
#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_
#ifndef CONTACT_MODEL_H_
#define CONTACT_MODEL_H_
#ifndef VCARD_MODEL_H_
#define VCARD_MODEL_H_
#include <QObject>
#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_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
);
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:
ContactModel (
std::shared_ptr<linphone::Friend> linphone_friend,
bool is_detached = false
);
VcardModel (std::shared_ptr<linphone::Vcard> vcard) : m_vcard(vcard) {}
public slots:
~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);
void addCompany (const QString &company);
bool addCompany (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);
void removeEmail (const QString &email);
......@@ -65,39 +42,26 @@ public slots:
bool updateUrl (const QString &old_url, const QString &url);
signals:
void contactUpdated ();
void vcardUpdated ();
private:
void edit ();
void done ();
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;
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;
std::shared_ptr<linphone::Vcard> m_vcard;
};
Q_DECLARE_METATYPE(ContactModel*);
Q_DECLARE_METATYPE(VcardModel *);
#endif // CONTACT_MODEL_H_
#endif // VCARD_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) {
......
#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;
......
#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();
auto it = addresses.cbegin();
// It exists at least one sip address.
weight += computeStringWeight(
Utils::linphoneStringToQString((*it)->asString()),
MAIN_SIP_ADDRESS_WEIGHT
);
const list<shared_ptr<linphone::Address> > addresses = contact.m_linphone_friend->getAddresses();
// 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;
......
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