From b5648af02ea7246b41d24e242c5f94e43e43980e Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 30 Nov 2015 11:09:31 +0100 Subject: Provide status information about children fetch state The fetch state is per parent. --- common/clientapi.h | 3 ++- common/modelresult.cpp | 30 ++++++++++++++++++++---------- common/modelresult.h | 8 ++++++-- common/queryrunner.cpp | 1 + common/resourcefacade.cpp | 2 +- common/resultprovider.h | 30 +++++++++++++++++++++--------- 6 files changed, 51 insertions(+), 23 deletions(-) (limited to 'common') diff --git a/common/clientapi.h b/common/clientapi.h index 04f1305..8f87562 100644 --- a/common/clientapi.h +++ b/common/clientapi.h @@ -44,7 +44,8 @@ public: static QByteArray resourceName(const QByteArray &instanceIdentifier); enum Roles { - DomainObjectRole = Qt::UserRole + 1 //Must be the same as in ModelResult + DomainObjectRole = Qt::UserRole + 1, //Must be the same as in ModelResult + ChildrenFetchedRole }; /** diff --git a/common/modelresult.cpp b/common/modelresult.cpp index 582f8ff..4def20f 100644 --- a/common/modelresult.cpp +++ b/common/modelresult.cpp @@ -74,6 +74,9 @@ QVariant ModelResult::data(const QModelIndex &index, int role) const Q_ASSERT(mEntities.contains(index.internalId())); return QVariant::fromValue(mEntities.value(index.internalId())); } + if (role == ChildrenFetchedRole) { + return childrenFetched(index); + } if (role == Qt::DisplayRole) { if (index.column() < mPropertyColumns.size()) { Q_ASSERT(mEntities.contains(index.internalId())); @@ -122,8 +125,8 @@ bool ModelResult::hasChildren(const QModelIndex &parent) const template bool ModelResult::canFetchMore(const QModelIndex &parent) const { - qDebug() << "Can fetch more: " << parent << mEntityChildrenFetched.value(parent.internalId()); - return !mEntityChildrenFetched.value(parent.internalId(), false); + qDebug() << "Can fetch more: " << parent << mEntityChildrenFetched.contains(parent.internalId()); + return !mEntityChildrenFetched.contains(parent.internalId()); } template @@ -139,7 +142,8 @@ void ModelResult::add(const Ptr &value) const auto childId = qHash(value->identifier()); const auto id = parentId(value); //Ignore updates we get before the initial fetch is done - if (!mEntityChildrenFetched[id]) { + if (!mEntityChildrenFetched.contains(id)) { + qDebug() << "Children not yet fetched"; return; } auto parent = createIndexFromId(id); @@ -185,7 +189,7 @@ template void ModelResult::fetchEntities(const QModelIndex &parent) { const auto id = getIdentifier(parent); - mEntityChildrenFetched[id] = true; + mEntityChildrenFetched.insert(id); Trace() << "Loading child entities"; loadEntities(parent.data(DomainObjectRole).template value()); } @@ -210,22 +214,28 @@ void ModelResult::setEmitter(const typename Akonadi2::ResultEmitter emitter->onRemoved([this](const Ptr &value) { this->remove(value); }); - emitter->onInitialResultSetComplete([this]() { - }); - emitter->onComplete([this]() { - }); - emitter->onClear([this]() { + emitter->onInitialResultSetComplete([this](const Ptr &parent) { + qint64 parentId = parent ? qHash(parent->identifier()) : 0; + const auto parentIndex = createIndexFromId(parentId); + mEntityChildrenFetchComplete.insert(parentId); + emit dataChanged(parentIndex, parentIndex, QVector() << ChildrenFetchedRole); }); mEmitter = emitter; } +template +bool ModelResult::childrenFetched(const QModelIndex &index) const +{ + return mEntityChildrenFetchComplete.contains(getIdentifier(index)); +} + template void ModelResult::modify(const Ptr &value) { auto childId = qHash(value->identifier()); auto id = parentId(value); //Ignore updates we get before the initial fetch is done - if (!mEntityChildrenFetched[id]) { + if (!mEntityChildrenFetched.contains(id)) { return; } auto parent = createIndexFromId(id); diff --git a/common/modelresult.h b/common/modelresult.h index 3ccf629..700064b 100644 --- a/common/modelresult.h +++ b/common/modelresult.h @@ -33,7 +33,8 @@ class ModelResult : public QAbstractItemModel { public: enum Roles { - DomainObjectRole = Qt::UserRole + 1 + DomainObjectRole = Qt::UserRole + 1, + ChildrenFetchedRole }; ModelResult(const Akonadi2::Query &query, const QList &propertyColumns); @@ -56,6 +57,8 @@ public: void setFetcher(const std::function &fetcher); + bool childrenFetched(const QModelIndex &) const; + private: qint64 parentId(const Ptr &value); QModelIndex createIndexFromId(const qint64 &id) const; @@ -65,7 +68,8 @@ private: QMap mEntities; QMap /* child entity id*/> mTree; QMap mParents; - QMap mEntityChildrenFetched; + QSet mEntityChildrenFetched; + QSet mEntityChildrenFetchComplete; QList mPropertyColumns; Akonadi2::Query mQuery; std::function loadEntities; diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp index bb1127c..e365cfc 100644 --- a/common/queryrunner.cpp +++ b/common/queryrunner.cpp @@ -303,6 +303,7 @@ qint64 QueryRunner::executeInitialQuery(const Akonadi2::Query &query return loadInitialResultSet(modifiedQuery, transaction, remainingFilters); }, resultProvider, true); Trace() << "Initial query took: " << time.elapsed() << " ms"; + resultProvider.initialResultSetComplete(parent); return revision; } diff --git a/common/resourcefacade.cpp b/common/resourcefacade.cpp index 3d207e4..6510c90 100644 --- a/common/resourcefacade.cpp +++ b/common/resourcefacade.cpp @@ -74,7 +74,7 @@ QPair, typename Akonadi2::ResultEmitterinitialResultSetComplete(); + resultProvider->initialResultSetComplete(Akonadi2::ApplicationDomain::AkonadiResource::Ptr()); resultProvider->complete(); }); return qMakePair(job, emitter); diff --git a/common/resultprovider.h b/common/resultprovider.h index 6d7867a..d50f3f6 100644 --- a/common/resultprovider.h +++ b/common/resultprovider.h @@ -50,7 +50,7 @@ public: virtual void add(const T &value) = 0; virtual void modify(const T &value) = 0; virtual void remove(const T &value) = 0; - virtual void initialResultSetComplete() = 0; + virtual void initialResultSetComplete(const T &parent) = 0; virtual void complete() = 0; virtual void clear() = 0; virtual void setFetcher(const std::function &fetcher) = 0; @@ -144,9 +144,15 @@ public: }); } - void initialResultSetComplete() + void initialResultSetComplete(const T &parent) { - callInMainThreadOnEmitter(&ResultEmitter::initialResultSetComplete); + //Because I don't know how to use bind + auto weakEmitter = mResultEmitter; + callInMainThreadOnEmitter([weakEmitter, parent](){ + if (auto strongRef = weakEmitter.toStrongRef()) { + strongRef->initialResultSetComplete(parent); + } + }); } //Called from worker thread @@ -244,7 +250,7 @@ public: removeHandler = handler; } - void onInitialResultSetComplete(const std::function &handler) + void onInitialResultSetComplete(const std::function &handler) { initialResultSetCompleteHandler = handler; } @@ -274,19 +280,25 @@ public: removeHandler(value); } - void initialResultSetComplete() + void initialResultSetComplete(const DomainType &parent) { - initialResultSetCompleteHandler(); + if (initialResultSetCompleteHandler) { + initialResultSetCompleteHandler(parent); + } } void complete() { - completeHandler(); + if (completeHandler) { + completeHandler(); + } } void clear() { - clearHandler(); + if (clearHandler) { + clearHandler(); + } } void setFetcher(const std::function &fetcher) @@ -302,7 +314,7 @@ private: std::function addHandler; std::function modifyHandler; std::function removeHandler; - std::function initialResultSetCompleteHandler; + std::function initialResultSetCompleteHandler; std::function completeHandler; std::function clearHandler; ThreadBoundary mThreadBoundary; -- cgit v1.2.3