summaryrefslogtreecommitdiffstats
path: root/common/modelresult.h
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2015-11-19 23:23:56 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2015-11-19 23:23:56 +0100
commit94a2cd6ec21bf0466a9a50d6e4a0a956ed47bc82 (patch)
tree8f05e8ed03691b006b1f2bf8f08bc21e582aad26 /common/modelresult.h
parentc4a6746e4420b580fe35cc89783de4dbc3205ac6 (diff)
downloadsink-94a2cd6ec21bf0466a9a50d6e4a0a956ed47bc82.tar.gz
sink-94a2cd6ec21bf0466a9a50d6e4a0a956ed47bc82.zip
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...
Diffstat (limited to 'common/modelresult.h')
-rw-r--r--common/modelresult.h167
1 files changed, 17 insertions, 150 deletions
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 @@
23#include <QAbstractItemModel> 23#include <QAbstractItemModel>
24#include <QModelIndex> 24#include <QModelIndex>
25#include <QDebug> 25#include <QDebug>
26#include <functional>
26#include "query.h" 27#include "query.h"
27 28
28#include "resultprovider.h"
29
30template<class T, class Ptr> 29template<class T, class Ptr>
31class ModelResult : public QAbstractItemModel 30class ModelResult : public QAbstractItemModel
32{ 31{
@@ -36,160 +35,28 @@ public:
36 DomainObjectRole = Qt::UserRole + 1 35 DomainObjectRole = Qt::UserRole + 1
37 }; 36 };
38 37
39 ModelResult(const Akonadi2::Query &query, const QList<QByteArray> &propertyColumns) 38 ModelResult(const Akonadi2::Query &query, const QList<QByteArray> &propertyColumns);
40 :QAbstractItemModel(),
41 mPropertyColumns(propertyColumns)
42 {
43 }
44
45 static qint64 getIdentifier(const QModelIndex &idx)
46 {
47 if (!idx.isValid()) {
48 return 0;
49 }
50 return idx.internalId();
51 }
52
53 int rowCount(const QModelIndex &parent = QModelIndex()) const
54 {
55 return mTree[getIdentifier(parent)].size();
56 }
57
58 int columnCount(const QModelIndex &parent = QModelIndex()) const
59 {
60 return mPropertyColumns.size();
61 }
62
63 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
64 {
65 if (role == DomainObjectRole) {
66 Q_ASSERT(mEntities.contains(index.internalId()));
67 return QVariant::fromValue(mEntities.value(index.internalId()));
68 }
69 if (role == Qt::DisplayRole) {
70 if (index.column() < mPropertyColumns.size()) {
71 Q_ASSERT(mEntities.contains(index.internalId()));
72 auto entity = mEntities.value(index.internalId());
73 return entity->getProperty(mPropertyColumns.at(index.column())).toString();
74 } else {
75 return "No data available";
76 }
77 }
78 return QVariant();
79 }
80
81 QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const
82 {
83 auto id = getIdentifier(parent);
84 auto childId = mTree.value(id).at(row);
85 return createIndex(row, column, childId);
86 }
87
88 QModelIndex createIndexFromId(const qint64 &id) const
89 {
90 auto grandParentId = mParents.value(id, 0);
91 auto row = mTree.value(grandParentId).indexOf(id);
92 return createIndex(row, 0, id);
93 }
94 39
95 QModelIndex parent(const QModelIndex &index) const 40 int rowCount(const QModelIndex &parent = QModelIndex()) const;
96 { 41 int columnCount(const QModelIndex &parent = QModelIndex()) const;
97 auto id = getIdentifier(index); 42 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
98 auto parentId = mParents.value(id); 43 QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
99 return createIndexFromId(parentId); 44 QModelIndex parent(const QModelIndex &index) const;
100 }
101 45
102 bool canFetchMore(const QModelIndex &parent) const 46 bool canFetchMore(const QModelIndex &parent) const;
103 { 47 void fetchMore(const QModelIndex &parent);
104 return mEntityChildrenFetched.value(parent.internalId());
105 }
106 48
107 void fetchMore(const QModelIndex &parent) 49 void add(const Ptr &value);
108 { 50 void modify(const Ptr &value);
109 fetchEntities(parent); 51 void remove(const Ptr &value);
110 }
111 52
112 qint64 parentId(const Ptr &value) 53 void setFetcher(const std::function<void(const Ptr &parent)> &fetcher);
113 {
114 return qHash(value->getProperty("parent").toByteArray());
115 }
116
117 void add(const Ptr &value)
118 {
119 auto childId = qHash(value->identifier());
120 auto id = parentId(value);
121 //Ignore updates we get before the initial fetch is done
122 if (!mEntityChildrenFetched[id]) {
123 return;
124 }
125 auto parent = createIndexFromId(id);
126 qDebug() << "Added entity " << childId << value->identifier();
127 const auto keys = mTree[id];
128 int index = 0;
129 for (; index < keys.size(); index++) {
130 if (childId < keys.at(index)) {
131 break;
132 }
133 }
134 if (mEntities.contains(childId)) {
135 qWarning() << "Entity already in model " << value->identifier();
136 return;
137 }
138 beginInsertRows(QModelIndex(), index, index);
139 mEntities.insert(childId, value);
140 mTree[id].insert(index, childId);
141 mParents.insert(childId, id);
142 endInsertRows();
143 }
144
145 void modify(const Ptr &value)
146 {
147 auto childId = qHash(value->identifier());
148 auto id = parentId(value);
149 //Ignore updates we get before the initial fetch is done
150 if (!mEntityChildrenFetched[id]) {
151 return;
152 }
153 auto parent = createIndexFromId(id);
154 qDebug() << "Modified entity" << childId;
155 auto i = mTree[id].indexOf(childId);
156 mEntities.remove(childId);
157 mEntities.insert(childId, value);
158 //TODO check for change of parents
159 auto idx = index(i, 0, parent);
160 emit dataChanged(idx, idx);
161 }
162
163 void remove(const Ptr &value)
164 {
165 auto childId = qHash(value->identifier());
166 auto id = parentId(value);
167 auto parent = createIndexFromId(id);
168 qDebug() << "Removed entity" << childId;
169 auto index = mTree[id].indexOf(qHash(value->identifier()));
170 beginRemoveRows(parent, index, index);
171 mEntities.remove(childId);
172 mTree[id].removeAll(childId);
173 mParents.remove(childId);
174 //TODO remove children
175 endRemoveRows();
176 }
177
178 void fetchEntities(const QModelIndex &parent)
179 {
180 const auto id = getIdentifier(parent);
181 mEntityChildrenFetched[id] = true;
182 Trace() << "Loading child entities";
183 loadEntities(parent.data(DomainObjectRole).template value<Ptr>());
184 }
185
186 void setFetcher(const std::function<void(const Ptr &parent)> &fetcher)
187 {
188 Trace() << "Setting fetcher";
189 loadEntities = fetcher;
190 }
191 54
192private: 55private:
56 static qint64 parentId(const Ptr &value);
57 QModelIndex createIndexFromId(const qint64 &id) const;
58 void fetchEntities(const QModelIndex &parent);
59
193 //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> 60 //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>
194 QMap<qint64 /* entity id */, Ptr> mEntities; 61 QMap<qint64 /* entity id */, Ptr> mEntities;
195 QMap<qint64 /* parent entity id */, QList<qint64> /* child entity id*/> mTree; 62 QMap<qint64 /* parent entity id */, QList<qint64> /* child entity id*/> mTree;