From 7a882503cdfdbcc3f87652a587bf9fbd7c0d80ba Mon Sep 17 00:00:00 2001 From: Matt Vogt Date: Tue, 6 Aug 2013 13:44:52 +1000 Subject: [PATCH] [libcontacts] Provide functionality for libcommhistory Report changes to cached contacts, including on resolution of unknown addressing details. --- config.pri | 2 +- contacts-namespace.pri | 18 -------- src/seasidecache.cpp | 93 +++++++++++++++++++++++++++++++++++------- src/seasidecache.h | 23 +++++++++-- 4 files changed, 99 insertions(+), 37 deletions(-) delete mode 100644 contacts-namespace.pri diff --git a/config.pri b/config.pri index 9ebb839..efd6c79 100644 --- a/config.pri +++ b/config.pri @@ -1,5 +1,4 @@ include(package.pri) -include(contacts-namespace.pri) CONFIG += qt link_pkgconfig QT -= gui @@ -11,6 +10,7 @@ equals(QT_MAJOR_VERSION, 4) { } equals(QT_MAJOR_VERSION, 5) { PKGCONFIG += Qt5Contacts Qt5Versit qtcontacts-sqlite-qt5-extensions + DEFINES *= USING_QTPIM # Needed for qt4 moc, which can't handle numeric tests DEFINES *= QT_VERSION_5 diff --git a/contacts-namespace.pri b/contacts-namespace.pri deleted file mode 100644 index 0a325b0..0000000 --- a/contacts-namespace.pri +++ /dev/null @@ -1,18 +0,0 @@ -# We need different macros depending on which Contacts we're using -equals(QT_MAJOR_VERSION, 4) { - DEFINES *= BEGIN_CONTACTS_NAMESPACE=QTM_BEGIN_NAMESPACE - DEFINES *= END_CONTACTS_NAMESPACE=QTM_END_NAMESPACE - DEFINES *= USE_CONTACTS_NAMESPACE=QTM_USE_NAMESPACE - DEFINES *= BEGIN_VERSIT_NAMESPACE= - DEFINES *= END_VERSIT_NAMESPACE= - DEFINES *= USE_VERSIT_NAMESPACE= -} -equals(QT_MAJOR_VERSION, 5) { - DEFINES *= USING_QTPIM - DEFINES *= BEGIN_CONTACTS_NAMESPACE=QT_BEGIN_NAMESPACE_CONTACTS - DEFINES *= END_CONTACTS_NAMESPACE=QT_END_NAMESPACE_CONTACTS - DEFINES *= USE_CONTACTS_NAMESPACE=QTCONTACTS_USE_NAMESPACE - DEFINES *= BEGIN_VERSIT_NAMESPACE=QT_BEGIN_NAMESPACE_VERSIT - DEFINES *= END_VERSIT_NAMESPACE=QT_END_NAMESPACE_VERSIT - DEFINES *= USE_VERSIT_NAMESPACE=QTVERSIT_USE_NAMESPACE -} diff --git a/src/seasidecache.cpp b/src/seasidecache.cpp index 324c709..2ba4b72 100644 --- a/src/seasidecache.cpp +++ b/src/seasidecache.cpp @@ -37,7 +37,7 @@ #include "qcontactstatusflags_impl.h" #include -#ifdef USING_QTPIM +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #include #else #include @@ -67,7 +67,9 @@ #include -USE_VERSIT_NAMESPACE +#ifdef USING_QTPIM +QTVERSIT_USE_NAMESPACE +#endif namespace { @@ -485,6 +487,40 @@ void SeasideCache::unregisterNameGroupChangeListener(SeasideNameGroupChangeListe instancePtr->m_nameGroupChangeListeners.removeAll(listener); } +void SeasideCache::registerChangeListener(ChangeListener *listener) +{ + if (!instancePtr) + new SeasideCache; + instancePtr->m_changeListeners.append(listener); +} + +void SeasideCache::unregisterChangeListener(ChangeListener *listener) +{ + if (!instancePtr) + return; + instancePtr->m_changeListeners.removeAll(listener); +} + +void SeasideCache::unregisterResolveListener(ResolveListener *listener) +{ + if (!instancePtr) + return; + + // We might have outstanding resolve requests for this listener + if (instancePtr->m_activeResolve && (instancePtr->m_activeResolve->listener == listener)) { + instancePtr->m_activeResolve = 0; + } + + QList::iterator it = instancePtr->m_resolveAddresses.begin(); + for ( ; it != instancePtr->m_resolveAddresses.end(); ) { + if (it->listener == listener) { + it = instancePtr->m_resolveAddresses.erase(it); + } else { + ++it; + } + } +} + QChar SeasideCache::nameGroupForCacheItem(CacheItem *cacheItem) { if (!cacheItem) @@ -666,6 +702,8 @@ SeasideCache::CacheItem *SeasideCache::resolvePhoneNumber(ResolveListener *liste CacheItem *item = itemByPhoneNumber(number, requireComplete); if (!item) { instancePtr->resolveAddress(listener, QString(), number, requireComplete); + } else if (requireComplete) { + ensureCompletion(item); } return item; @@ -676,6 +714,8 @@ SeasideCache::CacheItem *SeasideCache::resolveEmailAddress(ResolveListener *list CacheItem *item = itemByEmailAddress(address, requireComplete); if (!item) { instancePtr->resolveAddress(listener, address, QString(), requireComplete); + } else if (requireComplete) { + ensureCompletion(item); } return item; } @@ -685,6 +725,8 @@ SeasideCache::CacheItem *SeasideCache::resolveOnlineAccount(ResolveListener *lis CacheItem *item = itemByOnlineAccount(localUid, remoteUid, requireComplete); if (!item) { instancePtr->resolveAddress(listener, localUid, remoteUid, requireComplete); + } else if (requireComplete) { + ensureCompletion(item); } return item; } @@ -1131,7 +1173,7 @@ bool SeasideCache::event(QEvent *event) remoteFilter.setMatchFlags(QContactFilter::MatchExactly | QContactFilter::MatchFixedString); // allow case insensitive remoteFilter.setValue(resolve.second); - m_fetchRequest.setFilter(localFilter | remoteFilter); + m_fetchRequest.setFilter(localFilter & remoteFilter); } // If completion is not required, we need to at least retrieve as much detail @@ -1207,22 +1249,30 @@ void SeasideCache::contactsChanged(const QList &ids) void SeasideCache::contactsRemoved(const QList &ids) { + QList presentIds; + + foreach (const ContactIdType &id, ids) { + if (CacheItem *item = existingItem(id)) { + // Report this item is about to be removed + foreach (ChangeListener *listener, m_changeListeners) { + listener->itemAboutToBeRemoved(item); + } + if (!m_keepPopulated) { + presentIds.append(id); + } + } + } + if (m_keepPopulated) { m_refreshRequired = true; - requestUpdate(); } else { - // Remove these contacts if they're already in the cache - bool present = false; - foreach (const ContactIdType &id, ids) { - if (existingItem(id)) { - present = true; - m_expiredContacts[id] += -1; - } - } - if (present) { - requestUpdate(); + // Remove these contacts if they're already in the cache; they won't be removed by syncing + foreach (const ContactIdType &id, presentIds) { + m_expiredContacts[id] += -1; } } + + requestUpdate(); } void SeasideCache::updateContacts() @@ -1273,6 +1323,10 @@ void SeasideCache::updateContacts(const QList &contactIds) m_contactsUpdated = true; m_changedContacts.append(contactIds); + foreach (const ContactIdType &id, contactIds) { + m_reportIds.insert(internalId(id)); + } + if (m_fetchPostponed.isValid()) { // We are waiting to accumulate further changes int remainder = MaxPostponementMs - m_fetchPostponed.elapsed(); @@ -1471,6 +1525,15 @@ void SeasideCache::contactsAvailable() if (roleDataChanged) { instancePtr->contactDataChanged(apiId); } + + if (m_reportIds.contains(item->iid)) { + m_reportIds.remove(item->iid); + + // Report the change to this contact + foreach (ChangeListener *listener, m_changeListeners) { + listener->itemUpdated(item); + } + } } m_resultsRead = contacts.count(); notifyNameGroupsChanged(modifiedGroups); @@ -1837,7 +1900,7 @@ void SeasideCache::requestStateChanged(QContactAbstractRequest::State state) if (!m_fetchRequest.contacts().isEmpty()) { item = itemById(apiId(m_fetchRequest.contacts().first()), false); } - m_activeResolve->listener->addressResolved(item); + m_activeResolve->listener->addressResolved(m_activeResolve->first, m_activeResolve->second, item); m_activeResolve = 0; m_resolveAddresses.takeFirst(); diff --git a/src/seasidecache.h b/src/seasidecache.h index 900dc30..55aef3c 100644 --- a/src/seasidecache.h +++ b/src/seasidecache.h @@ -65,11 +65,13 @@ #include #endif -USE_CONTACTS_NAMESPACE - #ifdef USING_QTPIM +QTCONTACTS_USE_NAMESPACE + typedef QContactDetail::DetailType DetailTypeId; #else +QTM_USE_NAMESPACE + typedef QString DetailTypeId; #endif @@ -186,7 +188,15 @@ class CONTACTCACHE_EXPORT SeasideCache : public QObject { virtual ~ResolveListener() {} - virtual void addressResolved(CacheItem *item) = 0; + virtual void addressResolved(const QString &first, const QString &second, CacheItem *item) = 0; + }; + + struct ChangeListener + { + virtual ~ChangeListener() {} + + virtual void itemUpdated(CacheItem *item) = 0; + virtual void itemAboutToBeRemoved(CacheItem *item) = 0; }; static SeasideCache *instance(); @@ -214,6 +224,11 @@ class CONTACTCACHE_EXPORT SeasideCache : public QObject static void registerNameGroupChangeListener(SeasideNameGroupChangeListener *listener); static void unregisterNameGroupChangeListener(SeasideNameGroupChangeListener *listener); + static void registerChangeListener(ChangeListener *listener); + static void unregisterChangeListener(ChangeListener *listener); + + static void unregisterResolveListener(ResolveListener *listener); + static DisplayLabelOrder displayLabelOrder(); static int contactId(const QContact &contact); @@ -357,6 +372,7 @@ private slots: QList m_relationshipsToSave; QList m_relationshipsToRemove; QList m_nameGroupChangeListeners; + QList m_changeListeners; QVector m_contacts[FilterTypesCount]; QList m_models[FilterTypesCount]; QSet m_users; @@ -393,6 +409,7 @@ private slots: bool m_contactsUpdated; QList m_constituentIds; QList m_candidateIds; + QSet m_reportIds; struct ResolveData { QString first;