Commit 8bf12ac5 authored by Ronan Abhamon's avatar Ronan Abhamon

fix(ContactsListProxyModel): supports weight filter

parent cb598949
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
// =================================================================== // ===================================================================
class ContactModel : public QObject { class ContactModel : public QObject {
friend class ContactsListProxyModel;
Q_OBJECT; Q_OBJECT;
Q_PROPERTY( Q_PROPERTY(
...@@ -76,14 +78,14 @@ public: ...@@ -76,14 +78,14 @@ public:
m_sip_addresses = sip_addresses; m_sip_addresses = sip_addresses;
} }
QString getUsername () const {
return m_username;
}
signals: signals:
void contactUpdated (); void contactUpdated ();
private: private:
QString getUsername () const {
return m_username;
}
void setUsername (const QString &username) { void setUsername (const QString &username) {
m_username = username; m_username = username;
} }
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
// =================================================================== // ===================================================================
class ContactsListModel : public QAbstractListModel { class ContactsListModel : public QAbstractListModel {
friend class ContactsListProxyModel;
Q_OBJECT; Q_OBJECT;
public: public:
......
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
#include "ContactsListProxyModel.hpp" #include "ContactsListProxyModel.hpp"
#define USERNAME_WEIGHT 0.5
#define MAIN_SIP_ADDRESS_WEIGHT 0.3
#define OTHER_SIP_ADDRESSES_WEIGHT 0.2
// =================================================================== // ===================================================================
ContactsListModel *ContactsListProxyModel::m_list = nullptr; ContactsListModel *ContactsListProxyModel::m_list = nullptr;
...@@ -9,6 +13,11 @@ ContactsListModel *ContactsListProxyModel::m_list = nullptr; ...@@ -9,6 +13,11 @@ ContactsListModel *ContactsListProxyModel::m_list = nullptr;
ContactsListProxyModel::ContactsListProxyModel (QObject *parent) : QSortFilterProxyModel(parent) { ContactsListProxyModel::ContactsListProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
setSourceModel(m_list); setSourceModel(m_list);
setDynamicSortFilter(true); setDynamicSortFilter(true);
setFilterCaseSensitivity(Qt::CaseInsensitive);
foreach (const ContactModel *contact, m_list->m_list)
m_weights[contact] = 0;
sort(0); sort(0);
} }
...@@ -16,7 +25,7 @@ void ContactsListProxyModel::initContactsListModel (ContactsListModel *list) { ...@@ -16,7 +25,7 @@ void ContactsListProxyModel::initContactsListModel (ContactsListModel *list) {
if (!m_list) if (!m_list)
m_list = list; m_list = list;
else else
qWarning() << "Contacts list model already defined."; qWarning() << "Contacts list model is already defined.";
} }
bool ContactsListProxyModel::filterAcceptsRow (int source_row, const QModelIndex &source_parent) const { bool ContactsListProxyModel::filterAcceptsRow (int source_row, const QModelIndex &source_parent) const {
...@@ -25,17 +34,45 @@ bool ContactsListProxyModel::filterAcceptsRow (int source_row, const QModelIndex ...@@ -25,17 +34,45 @@ bool ContactsListProxyModel::filterAcceptsRow (int source_row, const QModelIndex
index.data(ContactsListModel::ContactRole) index.data(ContactsListModel::ContactRole)
); );
qDebug() << "A"; int weight = m_weights[contact] = computeContactWeight(*contact);
return weight > 0;
}
bool ContactsListProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
const ContactModel *contact_a = qvariant_cast<ContactModel *>(
sourceModel()->data(left, ContactsListModel::ContactRole)
);
const ContactModel *contact_b = qvariant_cast<ContactModel *>(
sourceModel()->data(right, ContactsListModel::ContactRole)
);
float weight_a = m_weights[contact_a];
float weight_b = m_weights[contact_b];
return contact->getUsername().contains( // Sort by weight and name.
filterRegExp().pattern(), return (
Qt::CaseInsensitive weight_a > weight_b ||
(weight_a == weight_b && contact_a->m_username <= contact_b->m_username)
); );
} }
bool ContactsListProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const { float ContactsListProxyModel::computeContactWeight (const ContactModel &contact) const {
float weight = 0;
if (filterRegExp().indexIn(contact.m_username) != -1)
weight += USERNAME_WEIGHT;
const QStringList &addresses = contact.m_sip_addresses;
if (filterRegExp().indexIn(addresses[0]) != -1)
weight += MAIN_SIP_ADDRESS_WEIGHT;
int size = addresses.size();
qDebug() << "B"; if (size > 1)
for (auto it = ++addresses.constBegin(); it != addresses.constEnd(); ++it)
if (filterRegExp().indexIn(*it) != -1)
weight += OTHER_SIP_ADDRESSES_WEIGHT / size;
return true; return weight;
} }
...@@ -16,10 +16,18 @@ public: ...@@ -16,10 +16,18 @@ public:
protected: protected:
bool filterAcceptsRow (int source_row, const QModelIndex &source_parent) const; bool filterAcceptsRow (int source_row, const QModelIndex &source_parent) const;
bool lessThan(const QModelIndex &left, const QModelIndex &right) const; bool lessThan (const QModelIndex &left, const QModelIndex &right) const;
private: private:
float computeContactWeight (const ContactModel &contact) const;
// The contacts list is shared between `ContactsListProxyModel`
// it's necessary to initialize it with `initContactsListModel`.
static ContactsListModel *m_list; static ContactsListModel *m_list;
// It's just a cache to save values computed by `filterAcceptsRow`
// and reused by `lessThan`.
mutable QHash<const ContactModel *, float> m_weights;
}; };
#endif // CONTACTS_LIST_PROXY_MODEL_H #endif // CONTACTS_LIST_PROXY_MODEL_H
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include "app.hpp" #include "app.hpp"
#include "components/contacts/ContactsListProxyModel.hpp" #include "components/contacts/ContactsListProxyModel.hpp"
#include "components/contacts/ContactsListModel.hpp"
#include "components/notification/Notification.hpp" #include "components/notification/Notification.hpp"
// =================================================================== // ===================================================================
......
...@@ -32,7 +32,9 @@ ColumnLayout { ...@@ -32,7 +32,9 @@ ColumnLayout {
} }
placeholderText: qsTr('searchContactPlaceholder') placeholderText: qsTr('searchContactPlaceholder')
onTextChanged: contacts.setFilterRegExp(text) onTextChanged: {
contacts.setFilterFixedString(text)
}
} }
ExclusiveButtons { ExclusiveButtons {
......
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