From c9279bd7201ff1a14deda314a4be432181f58757 Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Mon, 27 May 2019 16:19:06 +1000 Subject: [PATCH] [libcontacts] Emit saveContactComplete() when appropriate. Contributes to JB#45633 When a new contact is created via a save operation, the backend will create that local constituent and also an aggregate for it. The UI often wants to know that newly created aggregate's ID, e.g. to show the contact card. --- src/seasidecache.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/seasidecache.h | 4 ++++ 2 files changed, 46 insertions(+) diff --git a/src/seasidecache.cpp b/src/seasidecache.cpp index 8524eab..2a3d13d 100644 --- a/src/seasidecache.cpp +++ b/src/seasidecache.cpp @@ -2660,6 +2660,17 @@ void SeasideCache::appendContacts(const QList &contacts, FilterType fi } } +void SeasideCache::notifySaveContactComplete(int constituentId, int aggregateId) +{ + for (int i = 0; i < FilterTypesCount; ++i) { + const QList &models = m_models[i]; + for (int j = 0; j < models.count(); ++j) { + ListModel *model = models.at(j); + model->saveContactComplete(constituentId, aggregateId); + } + } +} + void SeasideCache::requestStateChanged(QContactAbstractRequest::State state) { if (state != QContactAbstractRequest::FinishedState) @@ -2800,6 +2811,37 @@ void SeasideCache::requestStateChanged(QContactAbstractRequest::State state) } m_populating = false; } + } else if (request == &m_saveRequest) { + for (int i = 0; i < m_saveRequest.contacts().size(); ++i) { + const QContact c = m_saveRequest.contacts().at(i); + if (m_saveRequest.errorMap().value(i) != QContactManager::NoError) { + notifySaveContactComplete(-1, -1); + } else if (c.detail().syncTarget() == QStringLiteral("aggregate")) { + // In case an aggregate is saved rather than a local constituent, + // no need to look up the aggregate via a relationship fetch request. + notifySaveContactComplete(-1, internalId(c)); + } else { + // Get the aggregate associated with this contact. + QContactRelationshipFetchRequest *rfr = new QContactRelationshipFetchRequest(this); + rfr->setManager(m_saveRequest.manager()); + rfr->setRelationshipType(QContactRelationship::Aggregates()); + rfr->setSecond(c); + connect(rfr, &QContactAbstractRequest::stateChanged, this, [this, c, rfr] { + if (rfr->state() == QContactAbstractRequest::FinishedState) { + rfr->deleteLater(); + if (rfr->relationships().size()) { + const quint32 constituentId = internalId(apiId(rfr->relationships().at(0).second())); + const quint32 aggregateId = internalId(apiId(rfr->relationships().at(0).first())); + this->notifySaveContactComplete(constituentId, aggregateId); + } else { + // error: cannot retrieve aggregate for newly created constituent. + this->notifySaveContactComplete(internalId(c), -1); + } + } + }); + rfr->start(); + } + } } // See if there are any more requests to dispatch diff --git a/src/seasidecache.h b/src/seasidecache.h index 5c366d9..4eb8d37 100644 --- a/src/seasidecache.h +++ b/src/seasidecache.h @@ -234,6 +234,8 @@ class CONTACTCACHE_EXPORT SeasideCache : public QObject virtual void updateGroupProperty() = 0; virtual void updateSectionBucketIndexCache() = 0; + + virtual void saveContactComplete(int localId, int aggregateId) = 0; }; struct ResolveListener @@ -407,6 +409,8 @@ private slots: int contactIndex(quint32 iid, FilterType filter); + void notifySaveContactComplete(int constituentId, int aggregateId); + static QContactRelationship makeRelationship(const QString &type, const QContactId &id1, const QContactId &id2); static QContactRelationship makeRelationship(const QString &type, const QContact &contact1, const QContact &contact2);