summaryrefslogtreecommitdiffstats
path: root/framework/src/domain/perioddayeventmodel.cpp
diff options
context:
space:
mode:
authorRémi Nicole <nicole@kolabsystems.com>2018-04-17 14:30:27 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2018-04-17 14:32:29 +0200
commitb8d76329bced92d712185e5588dfd6061e8fe0f6 (patch)
treeaf37569d19c112549ab1e6ba0b94fe9c2d83c4fc /framework/src/domain/perioddayeventmodel.cpp
parentafaaeb6dc16315c78091653a2662be41781ddfd3 (diff)
downloadkube-b8d76329bced92d712185e5588dfd6061e8fe0f6.tar.gz
kube-b8d76329bced92d712185e5588dfd6061e8fe0f6.zip
Implement PeriodDayEventModel
Summary: Implements a model to load events. When finished, should fix T8225 TODO: - Use the parent / children model in qml, instead of relying on the ".events" attribute (using DelegateModel I think) Reviewers: cmollekopf Tags: #kube Maniphest Tasks: T8225 Differential Revision: https://phabricator.kde.org/D12089
Diffstat (limited to 'framework/src/domain/perioddayeventmodel.cpp')
-rw-r--r--framework/src/domain/perioddayeventmodel.cpp256
1 files changed, 256 insertions, 0 deletions
diff --git a/framework/src/domain/perioddayeventmodel.cpp b/framework/src/domain/perioddayeventmodel.cpp
new file mode 100644
index 00000000..637e5584
--- /dev/null
+++ b/framework/src/domain/perioddayeventmodel.cpp
@@ -0,0 +1,256 @@
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)
33 : QAbstractItemModel(parent), partitionedEvents(7)
34{
35 Sink::Query query;
36 query.setFlags(Sink::Query::LiveQuery);
37 query.request<Event::Summary>();
38 query.request<Event::Description>();
39 query.request<Event::StartTime>();
40 query.request<Event::EndTime>();
41
42 eventModel = Sink::Store::loadModel<Event>(query);
43
44 QObject::connect(eventModel.data(), &QAbstractItemModel::dataChanged, this, &PeriodDayEventModel::partitionData);
45 QObject::connect(eventModel.data(), &QAbstractItemModel::layoutChanged, this, &PeriodDayEventModel::partitionData);
46 QObject::connect(eventModel.data(), &QAbstractItemModel::modelReset, this, &PeriodDayEventModel::partitionData);
47 QObject::connect(eventModel.data(), &QAbstractItemModel::rowsInserted, this, &PeriodDayEventModel::partitionData);
48 QObject::connect(eventModel.data(), &QAbstractItemModel::rowsMoved, this, &PeriodDayEventModel::partitionData);
49 QObject::connect(eventModel.data(), &QAbstractItemModel::rowsRemoved, this, &PeriodDayEventModel::partitionData);
50
51 partitionData();
52}
53
54void PeriodDayEventModel::partitionData()
55{
56 SinkLog() << "Partitioning event data";
57
58 beginResetModel();
59
60 partitionedEvents = QVector<QList<QSharedPointer<Event>>>(mPeriodLength);
61
62 for (int i = 0; i < eventModel->rowCount(); ++i) {
63 auto event = eventModel->index(i, 0).data(Sink::Store::DomainObjectRole).value<Event::Ptr>();
64 QDate eventDate = event->getStartTime().date();
65
66 if (!eventDate.isValid()) {
67 SinkWarning() << "Invalid date in the eventModel, ignoring...";
68 continue;
69 }
70
71 int bucket = bucketOf(eventDate);
72
73 if (bucket >= 0) {
74 SinkTrace() << "Adding event:" << event->getSummary() << "in bucket #" << bucket;
75 partitionedEvents[bucket].append(event);
76 }
77 }
78
79 endResetModel();
80}
81
82int PeriodDayEventModel::bucketOf(const QDate &candidate) const
83{
84 int bucket = mPeriodStart.daysTo(candidate);
85 if (bucket >= mPeriodLength || bucket < 0) {
86 return -1;
87 }
88
89 return bucket;
90}
91
92QModelIndex PeriodDayEventModel::index(int row, int column, const QModelIndex &parent) const
93{
94 if (!hasIndex(row, column, parent)) {
95 return {};
96 }
97
98 if (!parent.isValid()) {
99 // Asking for a day
100
101 if (!(0 <= row && row < mPeriodLength)) {
102 return {};
103 }
104
105 return createIndex(row, column, DAY_ID);
106 }
107
108 // Asking for an Event
109 auto day = static_cast<int>(parent.row());
110
111 Q_ASSERT(0 <= day && day <= mPeriodLength);
112 if (row >= partitionedEvents[day].size()) {
113 return {};
114 }
115
116 return createIndex(row, column, day);
117}
118
119QModelIndex PeriodDayEventModel::parent(const QModelIndex &index) const
120{
121 if (!index.isValid()) {
122 return {};
123 }
124
125 if (index.internalId() == DAY_ID) {
126 return {};
127 }
128
129 auto day = index.internalId();
130
131 return this->index(day, 0);
132}
133
134int PeriodDayEventModel::rowCount(const QModelIndex &parent) const
135{
136 if (!parent.isValid()) {
137 return mPeriodLength;
138 }
139
140 auto day = parent.row();
141
142 return partitionedEvents[day].size();
143}
144
145int PeriodDayEventModel::columnCount(const QModelIndex &parent) const
146{
147 if (!parent.isValid()) {
148 return 1;
149 }
150
151 return eventModel->columnCount();
152}
153
154QVariant PeriodDayEventModel::data(const QModelIndex &id, int role) const
155{
156 if (id.internalId() == DAY_ID) {
157 auto day = id.row();
158
159 SinkTrace() << "Fetching data for day" << day << "with role"
160 << QMetaEnum::fromType<Roles>().valueToKey(role);
161
162 switch (role) {
163 case Qt::DisplayRole:
164 return mPeriodStart.addDays(day).toString();
165 case Events: {
166 auto result = QVariantList{};
167
168 for (int i = 0; i < partitionedEvents[day].size(); ++i) {
169 auto eventId = index(i, 0, id);
170 SinkTrace() << "Appending event:" << data(eventId, Summary);
171
172 auto startTime = data(eventId, StartTime).toDateTime().time();
173
174 result.append(QVariantMap{
175 {"text", data(eventId, Summary)},
176 {"description", data(eventId, Description)},
177 {"starts", startTime.hour() + startTime.minute() / 60.},
178 {"duration", data(eventId, Duration)},
179 {"color", "#134bab"},
180 {"indention", 0},
181 });
182 }
183
184 return result;
185 }
186 default:
187 SinkWarning() << "Unknown role for day:" << QMetaEnum::fromType<Roles>().valueToKey(role);
188 return {};
189 }
190 } else {
191 auto day = id.internalId();
192 SinkTrace() << "Fetching data for event on day" << day << "with role"
193 << QMetaEnum::fromType<Roles>().valueToKey(role);
194 auto event = partitionedEvents[day].at(id.row());
195
196 switch (role) {
197 case Summary:
198 return event->getSummary();
199 case Description:
200 return event->getDescription();
201 case StartTime:
202 return event->getStartTime();
203 case Duration: {
204 auto start = event->getStartTime();
205 auto end = event->getEndTime();
206 return start.secsTo(end) / 3600;
207 }
208 default:
209 SinkWarning() << "Unknown role for event:" << QMetaEnum::fromType<Roles>().valueToKey(role);
210 return {};
211 }
212 }
213}
214
215QHash<int, QByteArray> PeriodDayEventModel::roleNames() const
216{
217 return {
218 {Events, "events"},
219 {Summary, "summary"},
220 {Description, "description"},
221 {StartTime, "starts"},
222 {Duration, "duration"},
223 };
224}
225
226QDate PeriodDayEventModel::periodStart() const
227{
228 return mPeriodStart;
229}
230
231void PeriodDayEventModel::setPeriodStart(const QDate &start)
232{
233 if (!start.isValid()) {
234 SinkWarning() << "Passed an invalid starting date in setPeriodStart, ignoring...";
235 return;
236 }
237
238 mPeriodStart = start;
239 partitionData();
240}
241
242void PeriodDayEventModel::setPeriodStart(const QVariant &start)
243{
244 setPeriodStart(start.toDate());
245}
246
247int PeriodDayEventModel::periodLength() const
248{
249 return mPeriodLength;
250}
251
252void PeriodDayEventModel::setPeriodLength(int length)
253{
254 mPeriodLength = length;
255 partitionData();
256}