summaryrefslogtreecommitdiffstats
path: root/common/modelresult.h
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2015-11-13 19:34:47 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2015-11-13 19:34:47 +0100
commit09aafbd1373b5d1152ac7a453a140a7f76c2e90e (patch)
tree10e33196c4dd0d69a223f7b047d1a4ef256e4705 /common/modelresult.h
parent10d19014fe2c9c02f2bc3e19732cbe340e316076 (diff)
downloadsink-09aafbd1373b5d1152ac7a453a140a7f76c2e90e.tar.gz
sink-09aafbd1373b5d1152ac7a453a140a7f76c2e90e.zip
It's starting to work
Diffstat (limited to 'common/modelresult.h')
-rw-r--r--common/modelresult.h139
1 files changed, 76 insertions, 63 deletions
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 @@
24#include <QModelIndex> 24#include <QModelIndex>
25#include <QDebug> 25#include <QDebug>
26#include "query.h" 26#include "query.h"
27#include "clientapi.h"
28 27
29#include "resultprovider.h" 28#include "resultprovider.h"
30 29
31template<class T> 30template<class T, class Ptr>
32class ModelResult : public QAbstractItemModel 31class ModelResult : public QAbstractItemModel
33{ 32{
34public: 33public:
@@ -79,13 +78,18 @@ public:
79 return createIndex(row, column, childId); 78 return createIndex(row, column, childId);
80 } 79 }
81 80
81 QModelIndex createIndexFromId(const qint64 &id) const
82 {
83 auto grandParentId = mParents.value(id, 0);
84 auto row = mTree.value(grandParentId).indexOf(id);
85 return createIndex(row, 0, id);
86 }
87
82 QModelIndex parent(const QModelIndex &index) const 88 QModelIndex parent(const QModelIndex &index) const
83 { 89 {
84 auto id = getIdentifier(index); 90 auto id = getIdentifier(index);
85 auto parentId = mParents.value(id); 91 auto parentId = mParents.value(id);
86 auto grandParentId = mParents.value(parentId, 0); 92 return createIndexFromId(parentId);
87 auto row = mTree.value(grandParentId).indexOf(parentId);
88 return createIndex(row, 0, parentId);
89 } 93 }
90 94
91 bool canFetchMore(const QModelIndex &parent) const 95 bool canFetchMore(const QModelIndex &parent) const
@@ -98,83 +102,92 @@ public:
98 fetchEntities(parent); 102 fetchEntities(parent);
99 } 103 }
100 104
105 qint64 parentId(const Ptr &value)
106 {
107 return qHash(value->getProperty("parent").toByteArray());
108 }
109
110 void add(const Ptr &value)
111 {
112 auto childId = qHash(value->identifier());
113 auto id = parentId(value);
114 auto parent = createIndexFromId(id);
115 qDebug() << "Added entity " << childId;
116 const auto keys = mTree[id];
117 int index = 0;
118 for (; index < keys.size(); index++) {
119 if (childId < keys.at(index)) {
120 break;
121 }
122 }
123 beginInsertRows(parent, index, index);
124 mEntities.insert(childId, value);
125 mTree[id].insert(index, childId);
126 mParents.insert(childId, id);
127 endInsertRows();
128 }
129
130 void modify(const Ptr &value)
131 {
132 auto childId = qHash(value->identifier());
133 auto id = parentId(value);
134 auto parent = createIndexFromId(id);
135 qDebug() << "Modified entity" << childId;
136 auto i = mTree[id].indexOf(childId);
137 mEntities.remove(childId);
138 mEntities.insert(childId, value);
139 //TODO check for change of parents
140 auto idx = index(i, 0, parent);
141 emit dataChanged(idx, idx);
142 }
143
144 void remove(const Ptr &value)
145 {
146 auto childId = qHash(value->identifier());
147 auto id = parentId(value);
148 auto parent = createIndexFromId(id);
149 qDebug() << "Removed entity" << childId;
150 auto index = mTree[id].indexOf(qHash(value->identifier()));
151 beginRemoveRows(parent, index, index);
152 mEntities.remove(childId);
153 mTree[id].removeAll(childId);
154 mParents.remove(childId);
155 //TODO remove children
156 endRemoveRows();
157 }
158
101 void fetchEntities(const QModelIndex &parent) 159 void fetchEntities(const QModelIndex &parent)
102 { 160 {
103 qDebug() << "Fetching entities"; 161 qDebug() << "Fetching entities";
104 const auto id = getIdentifier(parent); 162 const auto id = getIdentifier(parent);
105 // beginResetModel();
106 // mEntities.remove(id);
107 mEntityChildrenFetched[id] = true; 163 mEntityChildrenFetched[id] = true;
108 auto query = mQuery; 164 QByteArray parentIdentifier;
109 if (!parent.isValid()) { 165 if (!parent.isValid()) {
110 qDebug() << "no parent"; 166 qDebug() << "no parent";
111 query.propertyFilter.insert("parent", QByteArray());
112 } else { 167 } else {
113 qDebug() << "parent is valid"; 168 qDebug() << "parent is valid";
114 auto object = parent.data(DomainObjectRole).template value<typename T::Ptr>(); 169 auto object = parent.data(DomainObjectRole).template value<Ptr>();
115 Q_ASSERT(object); 170 Q_ASSERT(object);
116 query.propertyFilter.insert("parent", object->identifier()); 171 parentIdentifier = object->identifier();
117 } 172 }
118 auto emitter = Akonadi2::Store::load<T>(query); 173 Trace() << "Loading entities";
119 emitter->onAdded([this, id, parent](const typename T::Ptr &value) { 174 loadEntities(parentIdentifier);
120 auto childId = qHash(value->identifier()); 175 }
121 qDebug() << "Added entity " << childId; 176
122 const auto keys = mTree[id]; 177 void setFetcher(const std::function<void(const QByteArray &parent)> &fetcher)
123 int index = 0; 178 {
124 for (; index < keys.size(); index++) { 179 Trace() << "Setting fetcher";
125 if (childId < keys.at(index)) { 180 loadEntities = fetcher;
126 break;
127 }
128 }
129 beginInsertRows(parent, index, index);
130 mEntities.insert(childId, value);
131 mTree[id].insert(index, childId);
132 mParents.insert(childId, id);
133 endInsertRows();
134 });
135 emitter->onModified([this, id, parent](const typename T::Ptr &value) {
136 auto childId = qHash(value->identifier());
137 qDebug() << "Modified entity" << childId;
138 auto i = mTree[id].indexOf(childId);
139 mEntities.remove(childId);
140 mEntities.insert(childId, value);
141 //TODO check for change of parents
142 auto idx = index(i, 0, parent);
143 emit dataChanged(idx, idx);
144 });
145 emitter->onRemoved([this, id, parent](const typename T::Ptr &value) {
146 auto childId = qHash(value->identifier());
147 qDebug() << "Removed entity" << childId;
148 auto index = mTree[id].indexOf(qHash(value->identifier()));
149 beginRemoveRows(parent, index, index);
150 mEntities.remove(childId);
151 mTree[id].removeAll(childId);
152 mParents.remove(childId);
153 //TODO remove children
154 endRemoveRows();
155 });
156 emitter->onInitialResultSetComplete([this]() {
157 });
158 emitter->onComplete([this, id]() {
159 mEmitter[id].clear();
160 });
161 emitter->onClear([this]() {
162 // beginResetModel();
163 // mEntities.clear();
164 // endResetModel();
165 });
166 mEmitter.insert(id, emitter);
167 // endResetModel();
168 } 181 }
169 182
170private: 183private:
171 QMap<qint64 /* parent entity id */, QSharedPointer<Akonadi2::ResultEmitter<typename T::Ptr> >> mEmitter;
172 //TODO we should be able to directly use T as index, with an appropriate hash function, and thus have a QMap<T, T> and QList<T> 184 //TODO we should be able to directly use T as index, with an appropriate hash function, and thus have a QMap<T, T> and QList<T>
173 QMap<qint64 /* entity id */, typename T::Ptr> mEntities; 185 QMap<qint64 /* entity id */, Ptr> mEntities;
174 QMap<qint64 /* parent entity id */, QList<qint64> /* child entity id*/> mTree; 186 QMap<qint64 /* parent entity id */, QList<qint64> /* child entity id*/> mTree;
175 QMap<qint64 /* child entity id */, qint64 /* parent entity id*/> mParents; 187 QMap<qint64 /* child entity id */, qint64 /* parent entity id*/> mParents;
176 QMap<qint64 /* entity id */, bool> mEntityChildrenFetched; 188 QMap<qint64 /* entity id */, bool> mEntityChildrenFetched;
177 QList<QByteArray> mPropertyColumns; 189 QList<QByteArray> mPropertyColumns;
178 Akonadi2::Query mQuery; 190 Akonadi2::Query mQuery;
191 std::function<void(const QByteArray &)> loadEntities;
179}; 192};
180 193