Skip to content
This repository has been archived by the owner on Sep 4, 2021. It is now read-only.

Commit

Permalink
[libcontacts] Update name groups correctly
Browse files Browse the repository at this point in the history
Contacts do not change name groups when contact ordering changes, only
if their details change or the dislay label ordering changes.

Also add a function for attached models to handle the completion of
list synchronization.
  • Loading branch information
matthewvogt committed Aug 16, 2013
1 parent b155c07 commit 75e172b
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 43 deletions.
103 changes: 65 additions & 38 deletions src/seasidecache.cpp
Expand Up @@ -535,19 +535,25 @@ void SeasideCache::setNameGrouper(SeasideNameGrouper *grouper)
}
}

QChar SeasideCache::nameGroupForCacheItem(CacheItem *cacheItem)
QChar SeasideCache::nameGroup(const CacheItem *cacheItem)
{
if (!cacheItem)
return QChar();

if (!instancePtr)
new SeasideCache;
return cacheItem->nameGroup;
}

QChar SeasideCache::determineNameGroup(const CacheItem *cacheItem)
{
if (!cacheItem)
return QChar();

if (!instancePtr->m_nameGrouper.isNull()) {
SeasideNameGrouper::DisplayLabelOrder order = (SeasideNameGrouper::DisplayLabelOrder)(int)SeasideCache::displayLabelOrder();
QChar group = instancePtr->m_nameGrouper->nameGroupForContact(cacheItem->contact, order);
if (!group.isNull())
if (!group.isNull()) {
return group;
}
}

QChar group;
Expand Down Expand Up @@ -829,10 +835,12 @@ void SeasideCache::removeContactData(
m_contacts[filter].remove(row);

if (filter == FilterAll) {
QList<QChar> modifiedNameGroups;
const QChar nameGroup = nameGroupForCacheItem(existingItem(contactId));
removeFromContactNameGroup(internalId(contactId), nameGroup, &modifiedNameGroups);
notifyNameGroupsChanged(modifiedNameGroups);
const QChar group(nameGroup(existingItem(contactId)));
if (!group.isNull()) {
QSet<QChar> modifiedNameGroups;
removeFromContactNameGroup(internalId(contactId), group, &modifiedNameGroups);
notifyNameGroupsChanged(modifiedNameGroups);
}
}

for (int i = 0; i < models.count(); ++i)
Expand Down Expand Up @@ -1403,6 +1411,9 @@ void SeasideCache::updateCache(CacheItem *item, const QContact &contact, bool pa
} else {
item->contact = contact;
}

// Check if the name group has changed
item->nameGroup = determineNameGroup(item);
}

bool SeasideCache::updateContactIndexing(const QContact &oldContact, const QContact &contact, quint32 iid, const QSet<DetailTypeId> &queryDetailTypes)
Expand Down Expand Up @@ -1499,7 +1510,7 @@ void SeasideCache::contactsAvailable()
appendContacts(contacts, type, partialFetch);
} else {
// An update.
QList<QChar> modifiedGroups;
QSet<QChar> modifiedGroups;

for (int i = m_resultsRead; i < contacts.count(); ++i) {
QContact contact = contacts.at(i);
Expand All @@ -1519,7 +1530,7 @@ void SeasideCache::contactsAvailable()
QContactName oldName;

if (preexisting) {
oldNameGroup = nameGroupForCacheItem(item);
oldNameGroup = item->nameGroup;
oldName = item->contact.detail<QContactName>();

if (partialFetch) {
Expand Down Expand Up @@ -1557,10 +1568,9 @@ void SeasideCache::contactsAvailable()
updateCache(item, contact, partialFetch);

// do this even if !roleDataChanged as name groups are affected by other display label changes
QChar newNameGroup = nameGroupForCacheItem(item);
if (newNameGroup != oldNameGroup) {
addToContactNameGroup(item->iid, newNameGroup, &modifiedGroups);
if (preexisting) {
if (item->nameGroup != oldNameGroup) {
addToContactNameGroup(item->iid, item->nameGroup, &modifiedGroups);
if (!oldNameGroup.isNull()) {
removeFromContactNameGroup(item->iid, oldNameGroup, &modifiedGroups);
}
}
Expand All @@ -1583,25 +1593,32 @@ void SeasideCache::contactsAvailable()
}
}

void SeasideCache::addToContactNameGroup(quint32 iid, const QChar &group, QList<QChar> *modifiedGroups)
void SeasideCache::addToContactNameGroup(quint32 iid, const QChar &group, QSet<QChar> *modifiedGroups)
{
if (!group.isNull()) {
m_contactNameGroups[group].insert(iid);
if (modifiedGroups && !m_nameGroupChangeListeners.isEmpty())
modifiedGroups->append(group);
QSet<quint32> &set(m_contactNameGroups[group]);
if (!set.contains(iid)) {
set.insert(iid);
if (modifiedGroups && !m_nameGroupChangeListeners.isEmpty()) {
modifiedGroups->insert(group);
}
}
}
}

void SeasideCache::removeFromContactNameGroup(quint32 iid, const QChar &group, QList<QChar> *modifiedGroups)
void SeasideCache::removeFromContactNameGroup(quint32 iid, const QChar &group, QSet<QChar> *modifiedGroups)
{
if (!group.isNull() && m_contactNameGroups.contains(group)) {
m_contactNameGroups[group].remove(iid);
if (modifiedGroups && !m_nameGroupChangeListeners.isEmpty())
modifiedGroups->append(group);
if (!group.isNull()) {
QSet<quint32> &set(m_contactNameGroups[group]);
if (set.remove(iid)) {
if (modifiedGroups && !m_nameGroupChangeListeners.isEmpty()) {
modifiedGroups->insert(group);
}
}
}
}

void SeasideCache::notifyNameGroupsChanged(const QList<QChar> &groups)
void SeasideCache::notifyNameGroupsChanged(const QSet<QChar> &groups)
{
if (groups.isEmpty() || m_nameGroupChangeListeners.isEmpty())
return;
Expand Down Expand Up @@ -1648,7 +1665,6 @@ void SeasideCache::removeRange(
{
QVector<ContactIdType> &cacheIds = m_contacts[filter];
QList<ListModel *> &models = m_models[filter];
QList<QChar> modifiedNameGroups;

for (int i = 0; i < models.count(); ++i)
models[i]->sourceAboutToRemoveItems(index, index + count - 1);
Expand All @@ -1657,18 +1673,13 @@ void SeasideCache::removeRange(
if (filter == FilterAll) {
const ContactIdType apiId = cacheIds.at(index);
m_expiredContacts[apiId] -= 1;

const QChar nameGroup = nameGroupForCacheItem(existingItem(apiId));
removeFromContactNameGroup(internalId(apiId), nameGroup, &modifiedNameGroups);
}

cacheIds.remove(index);
}

for (int i = 0; i < models.count(); ++i)
models[i]->sourceItemsRemoved();

notifyNameGroupsChanged(modifiedNameGroups);
}

int SeasideCache::insertRange(
Expand All @@ -1680,7 +1691,6 @@ int SeasideCache::insertRange(
{
QVector<ContactIdType> &cacheIds = m_contacts[filter];
QList<ListModel *> &models = m_models[filter];
QList<QChar> modifiedNameGroups;

const ContactIdType selfId = m_manager.selfContactId();

Expand All @@ -1695,9 +1705,6 @@ int SeasideCache::insertRange(
if (filter == FilterAll) {
const ContactIdType apiId = queryIds.at(queryIndex + i);
m_expiredContacts[apiId] += 1;

const QChar nameGroup = nameGroupForCacheItem(existingItem(apiId));
addToContactNameGroup(internalId(apiId), nameGroup, &modifiedNameGroups);
}

cacheIds.insert(index + i, queryIds.at(queryIndex + i));
Expand All @@ -1706,8 +1713,6 @@ int SeasideCache::insertRange(
for (int i = 0; i < models.count(); ++i)
models[i]->sourceItemsInserted(index, end);

notifyNameGroupsChanged(modifiedNameGroups);

return end - index + 1;
}

Expand All @@ -1723,6 +1728,8 @@ void SeasideCache::appendContacts(const QList<QContact> &contacts, FilterType fi
int end = cacheIds.count() + contacts.count() - m_appendIndex - 1;

if (begin <= end) {
QSet<QChar> modifiedGroups;

for (int i = 0; i < models.count(); ++i)
models.at(i)->sourceAboutToInsertItems(begin, end);

Expand All @@ -1743,14 +1750,14 @@ void SeasideCache::appendContacts(const QList<QContact> &contacts, FilterType fi
}

if (filterType == FilterAll) {
addToContactNameGroup(iid, nameGroupForCacheItem(&cacheItem), 0);
addToContactNameGroup(iid, nameGroup(&cacheItem), &modifiedGroups);
}
}

for (int i = 0; i < models.count(); ++i)
models.at(i)->sourceItemsInserted(begin, end);

notifyNameGroupsChanged(m_contactNameGroups.keys());
notifyNameGroupsChanged(modifiedGroups);
}
}
}
Expand Down Expand Up @@ -1830,6 +1837,11 @@ void SeasideCache::requestStateChanged(QContactAbstractRequest::State state)
// We have completed fetching this filter set
completeSynchronizeList(this, m_contacts[m_syncFilter], m_cacheIndex, m_contactIdRequest.ids(), m_queryIndex);

// Notify models of completed updates
QList<ListModel *> &models = m_models[m_syncFilter];
for (int i = 0; i < models.count(); ++i)
models.at(i)->sourceItemsChanged();

if (m_syncFilter == FilterFavorites) {
// Next, query for all contacts (including favorites)
m_syncFilter = FilterAll;
Expand Down Expand Up @@ -1977,6 +1989,8 @@ void SeasideCache::displayLabelOrderChanged()

setSortOrder(m_displayLabelOrder);

QSet<QChar> modifiedGroups;

typedef QHash<quint32, CacheItem>::iterator iterator;
for (iterator it = m_people.begin(); it != m_people.end(); ++it) {
if (it->itemData) {
Expand All @@ -1990,8 +2004,21 @@ void SeasideCache::displayLabelOrderChanged()
#endif
it->contact.saveDetail(&name);
}

// Update the nameGroup for this contact
const QChar group(determineNameGroup(&*it));
if (group != it->nameGroup) {
if (!it->nameGroup.isNull()) {
removeFromContactNameGroup(it->iid, it->nameGroup, &modifiedGroups);
}

it->nameGroup = group;
addToContactNameGroup(it->iid, it->nameGroup, &modifiedGroups);
}
}

notifyNameGroupsChanged(modifiedGroups);

for (int i = 0; i < FilterTypesCount; ++i) {
for (int j = 0; j < m_models[i].count(); ++j)
m_models[i].at(j)->updateDisplayLabelOrder();
Expand Down
13 changes: 9 additions & 4 deletions src/seasidecache.h
Expand Up @@ -207,6 +207,7 @@ class CONTACTCACHE_EXPORT SeasideCache : public QObject
quint64 statusFlags;
ContactState contactState;
ItemListener *listeners;
QChar nameGroup;
};

struct ContactLinkRequest
Expand All @@ -232,6 +233,8 @@ class CONTACTCACHE_EXPORT SeasideCache : public QObject

virtual void sourceDataChanged(int begin, int end) = 0;

virtual void sourceItemsChanged() = 0;

virtual void makePopulated() = 0;
virtual void updateDisplayLabelOrder() = 0;
};
Expand Down Expand Up @@ -300,7 +303,9 @@ class CONTACTCACHE_EXPORT SeasideCache : public QObject

static void ensureCompletion(CacheItem *cacheItem);

static QChar nameGroupForCacheItem(CacheItem *cacheItem);
static QChar nameGroup(const CacheItem *cacheItem);
static QChar determineNameGroup(const CacheItem *cacheItem);

static QList<QChar> allNameGroups();
static QHash<QChar, QSet<quint32> > nameGroupMembers();

Expand Down Expand Up @@ -397,9 +402,9 @@ private slots:
void removeContactData(const ContactIdType &contactId, FilterType filter);
void makePopulated(FilterType filter);

void addToContactNameGroup(quint32 iid, const QChar &group, QList<QChar> *modifiedGroups = 0);
void removeFromContactNameGroup(quint32 iid, const QChar &group, QList<QChar> *modifiedGroups = 0);
void notifyNameGroupsChanged(const QList<QChar> &groups);
void addToContactNameGroup(quint32 iid, const QChar &group, QSet<QChar> *modifiedGroups = 0);
void removeFromContactNameGroup(quint32 iid, const QChar &group, QSet<QChar> *modifiedGroups = 0);
void notifyNameGroupsChanged(const QSet<QChar> &groups);

void updateConstituentAggregations(const ContactIdType &contactId);
void completeContactAggregation(const ContactIdType &contact1Id, const ContactIdType &contact2Id);
Expand Down
2 changes: 1 addition & 1 deletion src/src.pro
Expand Up @@ -10,7 +10,7 @@ target.path = $$PREFIX/lib
INSTALLS += target

# set version for generated pkgconfig files
VERSION=0.0.11
VERSION=0.0.12
QMAKE_PKGCONFIG_INCDIR = $$PREFIX/include/$${PACKAGENAME}
QMAKE_PKGCONFIG_LIBDIR = $$PREFIX/lib
QMAKE_PKGCONFIG_DESTDIR = pkgconfig
Expand Down

0 comments on commit 75e172b

Please sign in to comment.