summaryrefslogtreecommitdiffstats
path: root/framework/src/domain/perioddayeventmodel.cpp
diff options
context:
space:
mode:
authorMinijackson <minijackson@riseup.net>2018-04-16 10:09:30 +0200
committerMinijackson <minijackson@riseup.net>2018-04-16 10:18:33 +0200
commit6a9ff4ac53f7c60902b851f4635ee4bf6ff2d024 (patch)
tree2619c6c3460e60929062d33d4e57099cf5e3182d /framework/src/domain/perioddayeventmodel.cpp
parentcabc867b3e7cbf56ac2d8f646c52deb59a3197f4 (diff)
downloadkube-6a9ff4ac53f7c60902b851f4635ee4bf6ff2d024.tar.gz
kube-6a9ff4ac53f7c60902b851f4635ee4bf6ff2d024.zip
Rename EventTreeModel -> PeriodDayEventModel + doc the model architecture
Diffstat (limited to 'framework/src/domain/perioddayeventmodel.cpp')
-rw-r--r--framework/src/domain/perioddayeventmodel.cpp257
1 files changed, 257 insertions, 0 deletions
diff --git a/framework/src/domain/perioddayeventmodel.cpp b/framework/src/domain/perioddayeventmodel.cpp
new file mode 100644
index 00000000..0b374d5c
--- /dev/null
+++ b/framework/src/domain/perioddayeventmodel.cpp
@@ -0,0 +1,257 @@
1/*
2 Copyright (c) 2018 Michael Bohlender <michael.bohlender@kdemail.net>
3 Copyright (c) 2018 Christian Mollekopf <mollekopf@kolabsys.com>
4 Copyright (c) 2018 Rémi Nicole <minijackson@riseup.net>
5
6 This library is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Library General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or (at your
9 option) any later version.
10
11 This library is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14 License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA.
20*/
21
22#include "perioddayeventmodel.h"
23
24#include <sink/log.h>
25#include <sink/query.h>
26#include <sink/store.h>
27
28#include <QJsonArray>
29#include <QJsonObject>
30#include <QMetaEnum>
31
32PeriodDayEventModel::PeriodDayEventModel(QObject *parent) : QAbstractItemModel(parent), partitionedEvents(7)
33{
34 Sink::Query query;
35 query.setFlags(Sink::Query::LiveQuery);
36 query.request<Event::Summary>();
37 query.request<Event::Description>();
38 query.request<Event::StartTime>();
39 query.request<Event::EndTime>();
40
41 eventModel = Sink::Store::loadModel<Event>(query);
42
43 QObject::connect(eventModel.data(), &QAbstractItemModel::dataChanged, this, &PeriodDayEventModel::partitionData);
44 QObject::connect(eventModel.data(), &QAbstractItemModel::layoutChanged, this, &PeriodDayEventModel::partitionData);
45 QObject::connect(eventModel.data(), &QAbstractItemModel::modelReset, this, &PeriodDayEventModel::partitionData);
46 QObject::connect(eventModel.data(), &QAbstractItemModel::rowsInserted, this, &PeriodDayEventModel::partitionData);
47 QObject::connect(eventModel.data(), &QAbstractItemModel::rowsMoved, this, &PeriodDayEventModel::partitionData);
48 QObject::connect(eventModel.data(), &QAbstractItemModel::rowsRemoved, this, &PeriodDayEventModel::partitionData);
49
50 partitionData();
51}
52
53void PeriodDayEventModel::partitionData()
54{
55 SinkLog() << "Partitioning event data";
56
57 beginResetModel();
58
59 partitionedEvents = QVector<QList<QSharedPointer<Event>>>(mViewLength);
60
61 for (int i = 0; i < eventModel->rowCount(); ++i) {
62 auto event = eventModel->index(i, 0).data(Sink::Store::DomainObjectRole).value<Event::Ptr>();
63 QDate eventDate = event->getStartTime().date();
64
65 if(!eventDate.isValid()) {
66 SinkWarning() << "Invalid date in the eventModel, ignoring...";
67 continue;
68 }
69
70 int bucket = bucketOf(eventDate);
71
72 if(bucket >= 0) {
73 SinkTrace() << "Adding event:" << event->getSummary() << "in bucket #" << bucket;
74 partitionedEvents[bucket].append(event);
75 }
76 }
77
78 endResetModel();
79}
80
81int PeriodDayEventModel::bucketOf(QDate const &candidate) const
82{
83 int bucket = mViewStart.daysTo(candidate);
84 if(bucket >= mViewLength || bucket < 0) {
85 return -1;
86 }
87
88 return bucket;
89}
90
91QModelIndex PeriodDayEventModel::index(int row, int column, const QModelIndex &parent) const
92{
93 if (!hasIndex(row, column, parent)) {
94 return {};
95 }
96
97 if (!parent.isValid()) {
98 // Asking for a day
99
100 if (!(0 <= row && row < mViewLength)) {
101 return {};
102 }
103
104 return createIndex(row, column, DAY_ID);
105 }
106
107 // Asking for an Event
108 auto day = static_cast<int>(parent.row());
109
110 Q_ASSERT(0 <= day && day <= mViewLength);
111 if (row >= partitionedEvents[day].size()) {
112 return {};
113 }
114
115 return createIndex(row, column, day);
116}
117
118QModelIndex PeriodDayEventModel::parent(const QModelIndex &index) const
119{
120 if (!index.isValid()) {
121 return {};
122 }
123
124 if (index.internalId() == DAY_ID) {
125 return {};
126 }
127
128 auto day = index.internalId();
129
130 return this->index(day, 0);
131}
132
133int PeriodDayEventModel::rowCount(const QModelIndex &parent) const
134{
135 if (!parent.isValid()) {
136 return mViewLength;
137 }
138
139 auto day = parent.row();
140
141 return partitionedEvents[day].size();
142}
143
144int PeriodDayEventModel::columnCount(const QModelIndex &parent) const
145{
146 if (!parent.isValid()) {
147 return 1;
148 }
149
150 return eventModel->columnCount();
151}
152
153QVariant PeriodDayEventModel::data(const QModelIndex &id, int role) const
154{
155 if (id.internalId() == DAY_ID) {
156 auto day = id.row();
157
158 SinkTrace() << "Fetching data for day" << day << "with role"
159 << QMetaEnum::fromType<Roles>().valueToKey(role);
160
161 switch (role) {
162 case Qt::DisplayRole:
163 return mViewStart.addDays(day).toString();
164 case Events: {
165 auto result = QVariantList{};
166
167 for (int i = 0; i < partitionedEvents[day].size(); ++i) {
168 auto eventId = index(i, 0, id);
169 SinkTrace() << "Appending event:" << data(eventId, Summary);
170
171 auto startTime = data(eventId, StartTime).toDateTime().time();
172
173 result.append(QVariantMap{
174 {"text", data(eventId, Summary)},
175 {"description", data(eventId, Description)},
176 {"starts", startTime.hour() + startTime.minute() / 60.},
177 {"duration", data(eventId, Duration)},
178 {"color", "#134bab"},
179 {"indention", 0},
180 });
181 }
182
183 return result;
184 }
185 default:
186 SinkWarning() << "Unknown role for day:" << QMetaEnum::fromType<Roles>().valueToKey(role);
187 return {};
188 }
189 } else {
190 auto day = id.internalId();
191 SinkTrace() << "Fetching data for event on day" << day << "with role"
192 << QMetaEnum::fromType<Roles>().valueToKey(role);
193 auto event = partitionedEvents[day].at(id.row());
194
195 switch (role) {
196 case Summary:
197 return event->getSummary();
198 case Description:
199 return event->getDescription();
200 case StartTime:
201 return event->getStartTime();
202 case Duration: {
203 auto start = event->getStartTime();
204 auto end = event->getEndTime();
205 return start.secsTo(end) / 3600;
206 }
207 default:
208 SinkWarning() << "Unknown role for event:" << QMetaEnum::fromType<Roles>().valueToKey(role);
209 return {};
210 }
211 }
212}
213
214QHash<int, QByteArray> PeriodDayEventModel::roleNames() const
215{
216 QHash<int, QByteArray> roles;
217
218 roles[Events] = "events";
219 roles[Summary] = "summary";
220 roles[Description] = "description";
221 roles[StartTime] = "starts";
222 roles[Duration] = "duration";
223
224 return roles;
225}
226
227QDate PeriodDayEventModel::viewStart() const
228{
229 return mViewStart;
230}
231
232void PeriodDayEventModel::setViewStart(QDate start)
233{
234 if (!start.isValid()) {
235 SinkWarning() << "Passed an invalid starting date in setViewStart, ignoring...";
236 return;
237 }
238
239 mViewStart = std::move(start);
240 partitionData();
241}
242
243void PeriodDayEventModel::setViewStart(QVariant start)
244{
245 setViewStart(start.toDate());
246}
247
248int PeriodDayEventModel::viewLength() const
249{
250 return mViewLength;
251}
252
253void PeriodDayEventModel::setViewLength(int length)
254{
255 mViewLength = std::move(length);
256 partitionData();
257}