From 10d19014fe2c9c02f2bc3e19732cbe340e316076 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Tue, 10 Nov 2015 12:05:39 +0100 Subject: A result model The result model drives the data retrieval and provides the interace for consumers --- common/modelresult.h | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 common/modelresult.h (limited to 'common/modelresult.h') diff --git a/common/modelresult.h b/common/modelresult.h new file mode 100644 index 0000000..c23c41e --- /dev/null +++ b/common/modelresult.h @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2014 Christian Mollekopf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#pragma once + +#include +#include +#include +#include "query.h" +#include "clientapi.h" + +#include "resultprovider.h" + +template +class ModelResult : public QAbstractItemModel +{ +public: + + enum Roles { + DomainObjectRole = Qt::UserRole + 1 + }; + + ModelResult(const Akonadi2::Query &query, const QList &propertyColumns) + :QAbstractItemModel(), + mPropertyColumns(propertyColumns) + { + } + + static qint64 getIdentifier(const QModelIndex &idx) + { + if (!idx.isValid()) { + return 0; + } + return idx.internalId(); + } + + int rowCount(const QModelIndex &parent = QModelIndex()) const + { + return mTree[getIdentifier(parent)].size(); + } + + int columnCount(const QModelIndex &parent = QModelIndex()) const + { + return mPropertyColumns.size(); + } + + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const + { + if (role == DomainObjectRole) { + qWarning() << "trying to get entity " << index.internalId(); + Q_ASSERT(mEntities.contains(index.internalId())); + return QVariant::fromValue(mEntities.value(index.internalId())); + } + qDebug() << "Invalid role"; + return QVariant(); + } + + QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const + { + auto id = getIdentifier(parent); + auto childId = mTree.value(id).at(row); + return createIndex(row, column, childId); + } + + QModelIndex parent(const QModelIndex &index) const + { + auto id = getIdentifier(index); + auto parentId = mParents.value(id); + auto grandParentId = mParents.value(parentId, 0); + auto row = mTree.value(grandParentId).indexOf(parentId); + return createIndex(row, 0, parentId); + } + + bool canFetchMore(const QModelIndex &parent) const + { + return mEntityChildrenFetched.value(parent.internalId()); + } + + void fetchMore(const QModelIndex &parent) + { + fetchEntities(parent); + } + + void fetchEntities(const QModelIndex &parent) + { + qDebug() << "Fetching entities"; + const auto id = getIdentifier(parent); + // beginResetModel(); + // mEntities.remove(id); + mEntityChildrenFetched[id] = true; + auto query = mQuery; + if (!parent.isValid()) { + qDebug() << "no parent"; + query.propertyFilter.insert("parent", QByteArray()); + } else { + qDebug() << "parent is valid"; + auto object = parent.data(DomainObjectRole).template value(); + Q_ASSERT(object); + query.propertyFilter.insert("parent", object->identifier()); + } + auto emitter = Akonadi2::Store::load(query); + emitter->onAdded([this, id, parent](const typename T::Ptr &value) { + auto childId = qHash(value->identifier()); + qDebug() << "Added entity " << childId; + const auto keys = mTree[id]; + int index = 0; + for (; index < keys.size(); index++) { + if (childId < keys.at(index)) { + break; + } + } + beginInsertRows(parent, index, index); + mEntities.insert(childId, value); + mTree[id].insert(index, childId); + mParents.insert(childId, id); + endInsertRows(); + }); + emitter->onModified([this, id, parent](const typename T::Ptr &value) { + auto childId = qHash(value->identifier()); + qDebug() << "Modified entity" << childId; + auto i = mTree[id].indexOf(childId); + mEntities.remove(childId); + mEntities.insert(childId, value); + //TODO check for change of parents + auto idx = index(i, 0, parent); + emit dataChanged(idx, idx); + }); + emitter->onRemoved([this, id, parent](const typename T::Ptr &value) { + auto childId = qHash(value->identifier()); + qDebug() << "Removed entity" << childId; + auto index = mTree[id].indexOf(qHash(value->identifier())); + beginRemoveRows(parent, index, index); + mEntities.remove(childId); + mTree[id].removeAll(childId); + mParents.remove(childId); + //TODO remove children + endRemoveRows(); + }); + emitter->onInitialResultSetComplete([this]() { + }); + emitter->onComplete([this, id]() { + mEmitter[id].clear(); + }); + emitter->onClear([this]() { + // beginResetModel(); + // mEntities.clear(); + // endResetModel(); + }); + mEmitter.insert(id, emitter); + // endResetModel(); + } + +private: + QMap >> mEmitter; + //TODO we should be able to directly use T as index, with an appropriate hash function, and thus have a QMap and QList + QMap mEntities; + QMap /* child entity id*/> mTree; + QMap mParents; + QMap mEntityChildrenFetched; + QList mPropertyColumns; + Akonadi2::Query mQuery; +}; + -- cgit v1.2.3 From 09aafbd1373b5d1152ac7a453a140a7f76c2e90e Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 13 Nov 2015 19:34:47 +0100 Subject: It's starting to work --- common/modelresult.h | 139 ++++++++++++++++++++++++++++----------------------- 1 file changed, 76 insertions(+), 63 deletions(-) (limited to 'common/modelresult.h') diff --git a/common/modelresult.h b/common/modelresult.h index c23c41e..756f4d6 100644 --- a/common/modelresult.h +++ b/common/modelresult.h @@ -24,11 +24,10 @@ #include #include #include "query.h" -#include "clientapi.h" #include "resultprovider.h" -template +template class ModelResult : public QAbstractItemModel { public: @@ -79,13 +78,18 @@ public: return createIndex(row, column, childId); } + QModelIndex createIndexFromId(const qint64 &id) const + { + auto grandParentId = mParents.value(id, 0); + auto row = mTree.value(grandParentId).indexOf(id); + return createIndex(row, 0, id); + } + QModelIndex parent(const QModelIndex &index) const { auto id = getIdentifier(index); auto parentId = mParents.value(id); - auto grandParentId = mParents.value(parentId, 0); - auto row = mTree.value(grandParentId).indexOf(parentId); - return createIndex(row, 0, parentId); + return createIndexFromId(parentId); } bool canFetchMore(const QModelIndex &parent) const @@ -98,83 +102,92 @@ public: fetchEntities(parent); } + qint64 parentId(const Ptr &value) + { + return qHash(value->getProperty("parent").toByteArray()); + } + + void add(const Ptr &value) + { + auto childId = qHash(value->identifier()); + auto id = parentId(value); + auto parent = createIndexFromId(id); + qDebug() << "Added entity " << childId; + const auto keys = mTree[id]; + int index = 0; + for (; index < keys.size(); index++) { + if (childId < keys.at(index)) { + break; + } + } + beginInsertRows(parent, index, index); + mEntities.insert(childId, value); + mTree[id].insert(index, childId); + mParents.insert(childId, id); + endInsertRows(); + } + + void modify(const Ptr &value) + { + auto childId = qHash(value->identifier()); + auto id = parentId(value); + auto parent = createIndexFromId(id); + qDebug() << "Modified entity" << childId; + auto i = mTree[id].indexOf(childId); + mEntities.remove(childId); + mEntities.insert(childId, value); + //TODO check for change of parents + auto idx = index(i, 0, parent); + emit dataChanged(idx, idx); + } + + void remove(const Ptr &value) + { + auto childId = qHash(value->identifier()); + auto id = parentId(value); + auto parent = createIndexFromId(id); + qDebug() << "Removed entity" << childId; + auto index = mTree[id].indexOf(qHash(value->identifier())); + beginRemoveRows(parent, index, index); + mEntities.remove(childId); + mTree[id].removeAll(childId); + mParents.remove(childId); + //TODO remove children + endRemoveRows(); + } + void fetchEntities(const QModelIndex &parent) { qDebug() << "Fetching entities"; const auto id = getIdentifier(parent); - // beginResetModel(); - // mEntities.remove(id); mEntityChildrenFetched[id] = true; - auto query = mQuery; + QByteArray parentIdentifier; if (!parent.isValid()) { qDebug() << "no parent"; - query.propertyFilter.insert("parent", QByteArray()); } else { qDebug() << "parent is valid"; - auto object = parent.data(DomainObjectRole).template value(); + auto object = parent.data(DomainObjectRole).template value(); Q_ASSERT(object); - query.propertyFilter.insert("parent", object->identifier()); + parentIdentifier = object->identifier(); } - auto emitter = Akonadi2::Store::load(query); - emitter->onAdded([this, id, parent](const typename T::Ptr &value) { - auto childId = qHash(value->identifier()); - qDebug() << "Added entity " << childId; - const auto keys = mTree[id]; - int index = 0; - for (; index < keys.size(); index++) { - if (childId < keys.at(index)) { - break; - } - } - beginInsertRows(parent, index, index); - mEntities.insert(childId, value); - mTree[id].insert(index, childId); - mParents.insert(childId, id); - endInsertRows(); - }); - emitter->onModified([this, id, parent](const typename T::Ptr &value) { - auto childId = qHash(value->identifier()); - qDebug() << "Modified entity" << childId; - auto i = mTree[id].indexOf(childId); - mEntities.remove(childId); - mEntities.insert(childId, value); - //TODO check for change of parents - auto idx = index(i, 0, parent); - emit dataChanged(idx, idx); - }); - emitter->onRemoved([this, id, parent](const typename T::Ptr &value) { - auto childId = qHash(value->identifier()); - qDebug() << "Removed entity" << childId; - auto index = mTree[id].indexOf(qHash(value->identifier())); - beginRemoveRows(parent, index, index); - mEntities.remove(childId); - mTree[id].removeAll(childId); - mParents.remove(childId); - //TODO remove children - endRemoveRows(); - }); - emitter->onInitialResultSetComplete([this]() { - }); - emitter->onComplete([this, id]() { - mEmitter[id].clear(); - }); - emitter->onClear([this]() { - // beginResetModel(); - // mEntities.clear(); - // endResetModel(); - }); - mEmitter.insert(id, emitter); - // endResetModel(); + Trace() << "Loading entities"; + loadEntities(parentIdentifier); + } + + void setFetcher(const std::function &fetcher) + { + Trace() << "Setting fetcher"; + loadEntities = fetcher; } private: - QMap >> mEmitter; //TODO we should be able to directly use T as index, with an appropriate hash function, and thus have a QMap and QList - QMap mEntities; + QMap mEntities; QMap /* child entity id*/> mTree; QMap mParents; QMap mEntityChildrenFetched; QList mPropertyColumns; Akonadi2::Query mQuery; + std::function loadEntities; }; -- cgit v1.2.3 From 75c231f0758603120ec562af772b48b5f6ac0e24 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 13 Nov 2015 23:31:41 +0100 Subject: DummyResourceTest and QueryTest are passing sync has been removed from the query code and is now a separate step --- common/modelresult.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'common/modelresult.h') diff --git a/common/modelresult.h b/common/modelresult.h index 756f4d6..eabb868 100644 --- a/common/modelresult.h +++ b/common/modelresult.h @@ -111,6 +111,10 @@ public: { auto childId = qHash(value->identifier()); auto id = parentId(value); + //Ignore updates we get before the initial fetch is done + if (!mEntityChildrenFetched[id]) { + return; + } auto parent = createIndexFromId(id); qDebug() << "Added entity " << childId; const auto keys = mTree[id]; @@ -131,6 +135,10 @@ public: { auto childId = qHash(value->identifier()); auto id = parentId(value); + //Ignore updates we get before the initial fetch is done + if (!mEntityChildrenFetched[id]) { + return; + } auto parent = createIndexFromId(id); qDebug() << "Modified entity" << childId; auto i = mTree[id].indexOf(childId); -- cgit v1.2.3 From d4b10a3de396eebc6c815093e9e1725ece270e9e Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Sun, 15 Nov 2015 11:09:31 +0100 Subject: Working folder tree query --- common/modelresult.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'common/modelresult.h') diff --git a/common/modelresult.h b/common/modelresult.h index eabb868..8ca6daa 100644 --- a/common/modelresult.h +++ b/common/modelresult.h @@ -116,7 +116,7 @@ public: return; } auto parent = createIndexFromId(id); - qDebug() << "Added entity " << childId; + qDebug() << "Added entity " << childId << value->identifier(); const auto keys = mTree[id]; int index = 0; for (; index < keys.size(); index++) { @@ -166,7 +166,6 @@ public: void fetchEntities(const QModelIndex &parent) { - qDebug() << "Fetching entities"; const auto id = getIdentifier(parent); mEntityChildrenFetched[id] = true; QByteArray parentIdentifier; @@ -178,7 +177,7 @@ public: Q_ASSERT(object); parentIdentifier = object->identifier(); } - Trace() << "Loading entities"; + Trace() << "Loading child entities of: " << parentIdentifier; loadEntities(parentIdentifier); } -- cgit v1.2.3 From ef205affdb73bfdbef5830996e6336e583660fbc Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 19 Nov 2015 09:37:42 +0100 Subject: Use the new modelresult in the dummyclient --- common/modelresult.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'common/modelresult.h') diff --git a/common/modelresult.h b/common/modelresult.h index 8ca6daa..3b45955 100644 --- a/common/modelresult.h +++ b/common/modelresult.h @@ -63,11 +63,18 @@ public: virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const { if (role == DomainObjectRole) { - qWarning() << "trying to get entity " << index.internalId(); Q_ASSERT(mEntities.contains(index.internalId())); return QVariant::fromValue(mEntities.value(index.internalId())); } - qDebug() << "Invalid role"; + if (role == Qt::DisplayRole) { + if (index.column() < mPropertyColumns.size()) { + Q_ASSERT(mEntities.contains(index.internalId())); + auto entity = mEntities.value(index.internalId()); + return entity->getProperty(mPropertyColumns.at(index.column())).toString(); + } else { + return "No data available"; + } + } return QVariant(); } -- cgit v1.2.3 From 8d5684292ef92f32487ba32df716a00c4a0841b5 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 19 Nov 2015 17:37:39 +0100 Subject: Loading data with the new model for the test client --- common/modelresult.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'common/modelresult.h') diff --git a/common/modelresult.h b/common/modelresult.h index 3b45955..1675e60 100644 --- a/common/modelresult.h +++ b/common/modelresult.h @@ -131,7 +131,11 @@ public: break; } } - beginInsertRows(parent, index, index); + if (mEntities.contains(childId)) { + qWarning() << "Entity already in model " << value->identifier(); + return; + } + beginInsertRows(QModelIndex(), index, index); mEntities.insert(childId, value); mTree[id].insert(index, childId); mParents.insert(childId, id); -- cgit v1.2.3 From c4a6746e4420b580fe35cc89783de4dbc3205ac6 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 19 Nov 2015 18:14:09 +0100 Subject: The parent is always an object, so we might as well make that explicit --- common/modelresult.h | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'common/modelresult.h') diff --git a/common/modelresult.h b/common/modelresult.h index 1675e60..26f96d8 100644 --- a/common/modelresult.h +++ b/common/modelresult.h @@ -179,20 +179,11 @@ public: { const auto id = getIdentifier(parent); mEntityChildrenFetched[id] = true; - QByteArray parentIdentifier; - if (!parent.isValid()) { - qDebug() << "no parent"; - } else { - qDebug() << "parent is valid"; - auto object = parent.data(DomainObjectRole).template value(); - Q_ASSERT(object); - parentIdentifier = object->identifier(); - } - Trace() << "Loading child entities of: " << parentIdentifier; - loadEntities(parentIdentifier); + Trace() << "Loading child entities"; + loadEntities(parent.data(DomainObjectRole).template value()); } - void setFetcher(const std::function &fetcher) + void setFetcher(const std::function &fetcher) { Trace() << "Setting fetcher"; loadEntities = fetcher; @@ -206,6 +197,6 @@ private: QMap mEntityChildrenFetched; QList mPropertyColumns; Akonadi2::Query mQuery; - std::function loadEntities; + std::function loadEntities; }; -- cgit v1.2.3 From 94a2cd6ec21bf0466a9a50d6e4a0a956ed47bc82 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 19 Nov 2015 23:23:56 +0100 Subject: Move implementations to the cpp file. I finally figured out how to do that with cpp files. It requires instantiating the code with all expected classes, but that's not a big problem since we know all types. This will hopefully greatly reduce the compiletimes... --- common/modelresult.h | 167 ++++++--------------------------------------------- 1 file changed, 17 insertions(+), 150 deletions(-) (limited to 'common/modelresult.h') diff --git a/common/modelresult.h b/common/modelresult.h index 26f96d8..40a9d9d 100644 --- a/common/modelresult.h +++ b/common/modelresult.h @@ -23,10 +23,9 @@ #include #include #include +#include #include "query.h" -#include "resultprovider.h" - template class ModelResult : public QAbstractItemModel { @@ -36,160 +35,28 @@ public: DomainObjectRole = Qt::UserRole + 1 }; - ModelResult(const Akonadi2::Query &query, const QList &propertyColumns) - :QAbstractItemModel(), - mPropertyColumns(propertyColumns) - { - } - - static qint64 getIdentifier(const QModelIndex &idx) - { - if (!idx.isValid()) { - return 0; - } - return idx.internalId(); - } - - int rowCount(const QModelIndex &parent = QModelIndex()) const - { - return mTree[getIdentifier(parent)].size(); - } - - int columnCount(const QModelIndex &parent = QModelIndex()) const - { - return mPropertyColumns.size(); - } - - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const - { - if (role == DomainObjectRole) { - Q_ASSERT(mEntities.contains(index.internalId())); - return QVariant::fromValue(mEntities.value(index.internalId())); - } - if (role == Qt::DisplayRole) { - if (index.column() < mPropertyColumns.size()) { - Q_ASSERT(mEntities.contains(index.internalId())); - auto entity = mEntities.value(index.internalId()); - return entity->getProperty(mPropertyColumns.at(index.column())).toString(); - } else { - return "No data available"; - } - } - return QVariant(); - } - - QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const - { - auto id = getIdentifier(parent); - auto childId = mTree.value(id).at(row); - return createIndex(row, column, childId); - } - - QModelIndex createIndexFromId(const qint64 &id) const - { - auto grandParentId = mParents.value(id, 0); - auto row = mTree.value(grandParentId).indexOf(id); - return createIndex(row, 0, id); - } + ModelResult(const Akonadi2::Query &query, const QList &propertyColumns); - QModelIndex parent(const QModelIndex &index) const - { - auto id = getIdentifier(index); - auto parentId = mParents.value(id); - return createIndexFromId(parentId); - } + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; - bool canFetchMore(const QModelIndex &parent) const - { - return mEntityChildrenFetched.value(parent.internalId()); - } + bool canFetchMore(const QModelIndex &parent) const; + void fetchMore(const QModelIndex &parent); - void fetchMore(const QModelIndex &parent) - { - fetchEntities(parent); - } + void add(const Ptr &value); + void modify(const Ptr &value); + void remove(const Ptr &value); - qint64 parentId(const Ptr &value) - { - return qHash(value->getProperty("parent").toByteArray()); - } - - void add(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]) { - return; - } - auto parent = createIndexFromId(id); - qDebug() << "Added entity " << childId << value->identifier(); - const auto keys = mTree[id]; - int index = 0; - for (; index < keys.size(); index++) { - if (childId < keys.at(index)) { - break; - } - } - if (mEntities.contains(childId)) { - qWarning() << "Entity already in model " << value->identifier(); - return; - } - beginInsertRows(QModelIndex(), index, index); - mEntities.insert(childId, value); - mTree[id].insert(index, childId); - mParents.insert(childId, id); - endInsertRows(); - } - - void 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]) { - return; - } - auto parent = createIndexFromId(id); - qDebug() << "Modified entity" << childId; - auto i = mTree[id].indexOf(childId); - mEntities.remove(childId); - mEntities.insert(childId, value); - //TODO check for change of parents - auto idx = index(i, 0, parent); - emit dataChanged(idx, idx); - } - - void remove(const Ptr &value) - { - auto childId = qHash(value->identifier()); - auto id = parentId(value); - auto parent = createIndexFromId(id); - qDebug() << "Removed entity" << childId; - auto index = mTree[id].indexOf(qHash(value->identifier())); - beginRemoveRows(parent, index, index); - mEntities.remove(childId); - mTree[id].removeAll(childId); - mParents.remove(childId); - //TODO remove children - endRemoveRows(); - } - - void fetchEntities(const QModelIndex &parent) - { - const auto id = getIdentifier(parent); - mEntityChildrenFetched[id] = true; - Trace() << "Loading child entities"; - loadEntities(parent.data(DomainObjectRole).template value()); - } - - void setFetcher(const std::function &fetcher) - { - Trace() << "Setting fetcher"; - loadEntities = fetcher; - } + void setFetcher(const std::function &fetcher); private: + static qint64 parentId(const Ptr &value); + QModelIndex createIndexFromId(const qint64 &id) const; + void fetchEntities(const QModelIndex &parent); + //TODO we should be able to directly use T as index, with an appropriate hash function, and thus have a QMap and QList QMap mEntities; QMap /* child entity id*/> mTree; -- cgit v1.2.3 From a4acb7e251cba5ba6d66bf6235736202255c4eac Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Wed, 25 Nov 2015 09:37:59 +0100 Subject: Only use the parent index when it's available --- common/modelresult.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common/modelresult.h') diff --git a/common/modelresult.h b/common/modelresult.h index 40a9d9d..66dfce5 100644 --- a/common/modelresult.h +++ b/common/modelresult.h @@ -53,7 +53,7 @@ public: void setFetcher(const std::function &fetcher); private: - static qint64 parentId(const Ptr &value); + qint64 parentId(const Ptr &value); QModelIndex createIndexFromId(const qint64 &id) const; void fetchEntities(const QModelIndex &parent); -- cgit v1.2.3 From 5b41b26a349967acf2197f9f9228526193fd826e Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 27 Nov 2015 17:30:04 +0100 Subject: Introduced a QueryRunner object The QueryRunner object lives for the duration of the query (so just for the initial query for non-live queries, and for the lifetime of the result model for live queries). It's supposed to handle all the threading internally and decouple the lifetime of the facade. --- common/modelresult.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'common/modelresult.h') diff --git a/common/modelresult.h b/common/modelresult.h index 66dfce5..eb6c86b 100644 --- a/common/modelresult.h +++ b/common/modelresult.h @@ -23,20 +23,23 @@ #include #include #include +#include #include #include "query.h" +#include "resultprovider.h" template class ModelResult : public QAbstractItemModel { public: - enum Roles { DomainObjectRole = Qt::UserRole + 1 }; ModelResult(const Akonadi2::Query &query, const QList &propertyColumns); + void setEmitter(const typename Akonadi2::ResultEmitter::Ptr &); + int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; @@ -65,5 +68,6 @@ private: QList mPropertyColumns; Akonadi2::Query mQuery; std::function loadEntities; + typename Akonadi2::ResultEmitter::Ptr mEmitter; }; -- cgit v1.2.3 From 67d573d98da247d2cd16ce65fdd37457c5ee74ec Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 30 Nov 2015 10:30:31 +0100 Subject: ModelResult hasChildren, cleanup --- common/modelresult.h | 1 + 1 file changed, 1 insertion(+) (limited to 'common/modelresult.h') diff --git a/common/modelresult.h b/common/modelresult.h index eb6c86b..3ccf629 100644 --- a/common/modelresult.h +++ b/common/modelresult.h @@ -45,6 +45,7 @@ public: QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &index) const; + bool hasChildren(const QModelIndex &parent = QModelIndex()) const; bool canFetchMore(const QModelIndex &parent) const; void fetchMore(const QModelIndex &parent); -- cgit v1.2.3 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/modelresult.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'common/modelresult.h') 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; -- cgit v1.2.3