mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-23 22:58:15 +00:00
fix(ContactsListProxyModel): supports weight filter
This commit is contained in:
parent
cb598949e7
commit
8bf12ac561
6 changed files with 68 additions and 15 deletions
|
|
@ -6,6 +6,8 @@
|
|||
// ===================================================================
|
||||
|
||||
class ContactModel : public QObject {
|
||||
friend class ContactsListProxyModel;
|
||||
|
||||
Q_OBJECT;
|
||||
|
||||
Q_PROPERTY(
|
||||
|
|
@ -76,14 +78,14 @@ public:
|
|||
m_sip_addresses = sip_addresses;
|
||||
}
|
||||
|
||||
QString getUsername () const {
|
||||
return m_username;
|
||||
}
|
||||
|
||||
signals:
|
||||
void contactUpdated ();
|
||||
|
||||
private:
|
||||
QString getUsername () const {
|
||||
return m_username;
|
||||
}
|
||||
|
||||
void setUsername (const QString &username) {
|
||||
m_username = username;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
// ===================================================================
|
||||
|
||||
class ContactsListModel : public QAbstractListModel {
|
||||
friend class ContactsListProxyModel;
|
||||
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
#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;
|
||||
|
|
@ -9,6 +13,11 @@ ContactsListModel *ContactsListProxyModel::m_list = nullptr;
|
|||
ContactsListProxyModel::ContactsListProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
setSourceModel(m_list);
|
||||
setDynamicSortFilter(true);
|
||||
setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
|
||||
foreach (const ContactModel *contact, m_list->m_list)
|
||||
m_weights[contact] = 0;
|
||||
|
||||
sort(0);
|
||||
}
|
||||
|
||||
|
|
@ -16,7 +25,7 @@ void ContactsListProxyModel::initContactsListModel (ContactsListModel *list) {
|
|||
if (!m_list)
|
||||
m_list = list;
|
||||
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 {
|
||||
|
|
@ -25,17 +34,45 @@ bool ContactsListProxyModel::filterAcceptsRow (int source_row, const QModelIndex
|
|||
index.data(ContactsListModel::ContactRole)
|
||||
);
|
||||
|
||||
qDebug() << "A";
|
||||
|
||||
return contact->getUsername().contains(
|
||||
filterRegExp().pattern(),
|
||||
Qt::CaseInsensitive
|
||||
);
|
||||
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)
|
||||
);
|
||||
|
||||
qDebug() << "B";
|
||||
float weight_a = m_weights[contact_a];
|
||||
float weight_b = m_weights[contact_b];
|
||||
|
||||
return true;
|
||||
// Sort by weight and name.
|
||||
return (
|
||||
weight_a > weight_b ||
|
||||
(weight_a == weight_b && contact_a->m_username <= contact_b->m_username)
|
||||
);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if (size > 1)
|
||||
for (auto it = ++addresses.constBegin(); it != addresses.constEnd(); ++it)
|
||||
if (filterRegExp().indexIn(*it) != -1)
|
||||
weight += OTHER_SIP_ADDRESSES_WEIGHT / size;
|
||||
|
||||
return weight;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,18 @@ public:
|
|||
|
||||
protected:
|
||||
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:
|
||||
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;
|
||||
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include "app.hpp"
|
||||
#include "components/contacts/ContactsListProxyModel.hpp"
|
||||
|
||||
#include "components/contacts/ContactsListModel.hpp"
|
||||
#include "components/notification/Notification.hpp"
|
||||
|
||||
// ===================================================================
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@ ColumnLayout {
|
|||
}
|
||||
placeholderText: qsTr('searchContactPlaceholder')
|
||||
|
||||
onTextChanged: contacts.setFilterRegExp(text)
|
||||
onTextChanged: {
|
||||
contacts.setFilterFixedString(text)
|
||||
}
|
||||
}
|
||||
|
||||
ExclusiveButtons {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue