diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-11-19 23:23:56 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-11-19 23:23:56 +0100 |
commit | 94a2cd6ec21bf0466a9a50d6e4a0a956ed47bc82 (patch) | |
tree | 8f05e8ed03691b006b1f2bf8f08bc21e582aad26 /common/modelresult.h | |
parent | c4a6746e4420b580fe35cc89783de4dbc3205ac6 (diff) | |
download | sink-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.h | 167 |
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 | |||
30 | template<class T, class Ptr> | 29 | template<class T, class Ptr> |
31 | class ModelResult : public QAbstractItemModel | 30 | class 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 | ||
192 | private: | 55 | private: |
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; |