Commit 7a882503 authored by mvogt's avatar mvogt

[libcontacts] Provide functionality for libcommhistory

Report changes to cached contacts, including on resolution of unknown
addressing details.
parent 0438ffa6
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
......
# 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
}
......@@ -37,7 +37,7 @@
#include "qcontactstatusflags_impl.h"
#include <QCoreApplication>
#ifdef USING_QTPIM
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#include <QStandardPaths>
#else
#include <QDesktopServices>
......@@ -67,7 +67,9 @@
#include <QtDebug>
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<ResolveData>::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<ContactIdType> &ids)
void SeasideCache::contactsRemoved(const QList<ContactIdType> &ids)
{
QList<ContactIdType> 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<ContactIdType> &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();
......
......@@ -65,11 +65,13 @@
#include <mgconfitem.h>
#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 @@ public:
{
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 @@ public:
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:
QList<QContactRelationship> m_relationshipsToSave;
QList<QContactRelationship> m_relationshipsToRemove;
QList<SeasideNameGroupChangeListener*> m_nameGroupChangeListeners;
QList<ChangeListener*> m_changeListeners;
QVector<ContactIdType> m_contacts[FilterTypesCount];
QList<ListModel *> m_models[FilterTypesCount];
QSet<QObject *> m_users;
......@@ -393,6 +409,7 @@ private:
bool m_contactsUpdated;
QList<ContactIdType> m_constituentIds;
QList<ContactIdType> m_candidateIds;
QSet<quint32> m_reportIds;
struct ResolveData {
QString first;
......
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