summaryrefslogtreecommitdiffstats
path: root/framework
diff options
context:
space:
mode:
authorMinijackson <minijackson@riseup.net>2018-04-10 16:19:58 +0200
committerMinijackson <minijackson@riseup.net>2018-04-10 16:19:58 +0200
commitb7fb9280032bde10ab942d0f2eeae50366a3dfda (patch)
tree0910d1bcabe6798e804a67accb553ef1bd3d820e /framework
parent004a1a2e91c72f9b1b7ca964fe20cd6a1a6e68a6 (diff)
downloadkube-help.tar.gz
kube-help.zip
Implement the EventTreeModel + move test data in that modelhelpcalendar
Diffstat (limited to 'framework')
-rw-r--r--framework/src/CMakeLists.txt2
-rw-r--r--framework/src/domain/eventtreemodel.cpp249
-rw-r--r--framework/src/domain/eventtreemodel.h95
-rw-r--r--framework/src/frameworkplugin.cpp2
4 files changed, 348 insertions, 0 deletions
diff --git a/framework/src/CMakeLists.txt b/framework/src/CMakeLists.txt
index 0059bd00..a4392b33 100644
--- a/framework/src/CMakeLists.txt
+++ b/framework/src/CMakeLists.txt
@@ -1,6 +1,7 @@
1 1
2find_package(Qt5 COMPONENTS REQUIRED Core Concurrent Quick Qml WebEngineWidgets Test WebEngine Gui) 2find_package(Qt5 COMPONENTS REQUIRED Core Concurrent Quick Qml WebEngineWidgets Test WebEngine Gui)
3find_package(KF5Mime 4.87.0 CONFIG REQUIRED) 3find_package(KF5Mime 4.87.0 CONFIG REQUIRED)
4find_package(KF5CalendarCore CONFIG REQUIRED)
4find_package(Sink 0.6.0 CONFIG REQUIRED) 5find_package(Sink 0.6.0 CONFIG REQUIRED)
5find_package(KAsync CONFIG REQUIRED) 6find_package(KAsync CONFIG REQUIRED)
6find_package(QGpgme CONFIG REQUIRED) 7find_package(QGpgme CONFIG REQUIRED)
@@ -16,6 +17,7 @@ add_library(kubeframework SHARED
16 settings/settings.cpp 17 settings/settings.cpp
17 domain/maillistmodel.cpp 18 domain/maillistmodel.cpp
18 domain/folderlistmodel.cpp 19 domain/folderlistmodel.cpp
20 domain/eventtreemodel.cpp
19 domain/composercontroller.cpp 21 domain/composercontroller.cpp
20 domain/modeltest.cpp 22 domain/modeltest.cpp
21 domain/retriever.cpp 23 domain/retriever.cpp
diff --git a/framework/src/domain/eventtreemodel.cpp b/framework/src/domain/eventtreemodel.cpp
new file mode 100644
index 00000000..784a40f9
--- /dev/null
+++ b/framework/src/domain/eventtreemodel.cpp
@@ -0,0 +1,249 @@
1/*
2 Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net>
3 Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com>
4
5 This library is free software; you can redistribute it and/or modify it
6 under the terms of the GNU Library General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or (at your
8 option) any later version.
9
10 This library is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 02110-1301, USA.
19*/
20
21#include "eventtreemodel.h"
22
23#include <sink/log.h>
24#include <sink/query.h>
25#include <sink/store.h>
26
27#include <QJsonArray>
28#include <QJsonObject>
29#include <QMetaEnum>
30
31EventTreeModel::EventTreeModel(QObject *parent) : QAbstractItemModel(parent), partitionedEvents(7)
32{
33 Sink::Query query;
34 query.request<Event::Summary>();
35 query.request<Event::Description>();
36 query.request<Event::StartTime>();
37 query.request<Event::EndTime>();
38
39 eventModel = Sink::Store::loadModel<Event>(query);
40
41 QObject::connect(eventModel.data(), &QAbstractItemModel::dataChanged, this, &EventTreeModel::partitionData);
42
43 Sink::Store::synchronize(Sink::Query());
44
45 partitionData();
46}
47
48void EventTreeModel::partitionData()
49{
50 SinkLog() << "Partitioning event data";
51
52 for (int i = 0; i < 7; ++i) {
53 SinkLog() << "Clearing #" << i;
54 partitionedEvents[i].clear();
55 }
56
57 for (int i = 0; i < eventModel->rowCount(); ++i) {
58 auto event = eventModel->index(i, 0).data(Sink::Store::DomainObjectRole).value<Event::Ptr>();
59 int dayOfWeek = event->getStartTime().date().dayOfWeek();
60
61 Q_ASSERT(dayOfWeek != 0);
62
63 SinkLog() << "Adding event in bucket #" << dayOfWeek;
64
65 partitionedEvents[dayOfWeek - 1].append(event);
66 }
67
68 // auto bottomRight = index(partitionedEvents[6].size(), eventModel->columnCount() - 1, index(6,
69 // 0));
70 emit dataChanged({}, {});
71}
72
73QModelIndex EventTreeModel::index(int row, int column, const QModelIndex &parent) const
74{
75 SinkLog() << "Calling EventTreeModel::index with" << row << column << parent.isValid();
76
77 if (!hasIndex(row, column, parent)) {
78 return {};
79 }
80
81 if (!parent.isValid()) {
82 // Asking for a LocalEventListModel
83
84 // TODO: Assuming week view
85 if (!(0 <= row && row <= 6)) {
86 return {};
87 }
88
89 return createIndex(row, column, DAY_ID);
90 }
91
92 // Asking for an Event
93 auto day = static_cast<int>(parent.internalId());
94
95 Q_ASSERT(0 <= day && day <= 6);
96 if (row >= partitionedEvents[day].size()) {
97 return {};
98 }
99
100 return createIndex(row, column, day);
101}
102
103QModelIndex EventTreeModel::parent(const QModelIndex &index) const
104{
105 SinkLog() << "Calling GlobalEventListModel::parent with index:" << index.row() << index.column();
106
107 if (!index.isValid()) {
108 return {};
109 }
110
111 if (index.internalId() == DAY_ID) {
112 return {};
113 }
114
115 auto day = index.internalId();
116
117 return this->index(day, 0);
118}
119
120int EventTreeModel::rowCount(const QModelIndex &parent) const
121{
122 if (!parent.isValid()) {
123 return 7;
124 }
125
126 auto day = parent.internalId();
127
128 return partitionedEvents[day].size();
129}
130
131int EventTreeModel::columnCount(const QModelIndex &parent) const
132{
133 if (!parent.isValid()) {
134 return 1;
135 }
136
137 return eventModel->columnCount();
138}
139
140bool EventTreeModel::hasChildren(const QModelIndex &parent) const
141{
142 return parent.internalId() == DAY_ID;
143}
144
145QVariant EventTreeModel::data(const QModelIndex &id, int role) const
146{
147 if (hasChildren(id)) {
148 auto day = id.row();
149
150 switch (role) {
151 case Qt::DisplayRole:
152 switch (day) {
153 case 0:
154 return "Monday";
155 case 1:
156 return "Tuesday";
157 case 2:
158 return "Wednesday";
159 case 3:
160 return "Thursday";
161 case 4:
162 return "Friday";
163 case 5:
164 return "Saturday";
165 case 6:
166 return "Sunday";
167 default:
168 SinkWarning() << "Unknown day";
169 return {};
170 }
171 case Events:
172 //{
173 // auto result = QVariantList{};
174
175 // for (int i = 0; i < partitionedEvents[day].size(); ++i) {
176 // auto eventId = index(i, 0, id);
177 // SinkLog() << "Appending event:" << data(eventId, Summary);
178 // result.append(QVariantMap{
179 // {"text", data(eventId, Summary)},
180 // {"description", data(eventId, Description)},
181 // {"starts", data(eventId, StartTime)},
182 // {"duration", data(eventId, Duration)},
183 // {"color", "#123"},
184 // {"indention", 0},
185 // });
186 // }
187
188 // return result;
189 //}
190 return QVariantList{
191 QVariantMap{
192 {"summary", "Hello, World!"},
193 {"text", "Hello, World!"},
194 {"description", "This is Hello, world!"},
195 {"starts", 4},
196 {"duration", 3},
197 {"color", "#123"},
198 {"indention", 0},
199 },
200 QVariantMap{
201 {"summary", "Hello, World!"},
202 {"text", "Hello, World!"},
203 {"description", "This is Hello, world!"},
204 {"starts", 8},
205 {"duration", 3},
206 {"color", "#456"},
207 {"indention", 1},
208 },
209 };
210 default:
211 SinkWarning() << "Unknown role for day:" << QMetaEnum::fromType<Roles>().valueToKey(role);
212 return {};
213 }
214 }
215
216 auto day = static_cast<int>(id.internalId());
217 SinkLog() << "Fetching data for day" << day;
218 auto event = partitionedEvents[day].at(id.row());
219
220 switch (role) {
221 case Summary:
222 return event->getSummary();
223 case Description:
224 return event->getDescription();
225 case StartTime:
226 return event->getStartTime();
227 case Duration: {
228 auto start = event->getStartTime();
229 auto end = event->getEndTime();
230 return start.secsTo(end) / 3600;
231 }
232 default:
233 SinkWarning() << "Unknown role for event:" << QMetaEnum::fromType<Roles>().valueToKey(role);
234 return {};
235 }
236}
237
238QHash<int, QByteArray> EventTreeModel::roleNames() const
239{
240 QHash<int, QByteArray> roles;
241
242 roles[Events] = "events";
243 roles[Summary] = "summary";
244 roles[Description] = "description";
245 roles[StartTime] = "starts";
246 roles[Duration] = "duration";
247
248 return roles;
249}
diff --git a/framework/src/domain/eventtreemodel.h b/framework/src/domain/eventtreemodel.h
new file mode 100644
index 00000000..ac126640
--- /dev/null
+++ b/framework/src/domain/eventtreemodel.h
@@ -0,0 +1,95 @@
1/*
2 Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net>
3 Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com>
4
5 This library is free software; you can redistribute it and/or modify it
6 under the terms of the GNU Library General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or (at your
8 option) any later version.
9
10 This library is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 02110-1301, USA.
19*/
20
21#pragma once
22
23#include <sink/applicationdomaintype.h>
24
25#include <QAbstractItemModel>
26#include <QList>
27#include <QSharedPointer>
28#include <QVector>
29
30// Implementation notes
31// ====================
32//
33// On the model side
34// -----------------
35//
36// Columns are never used.
37//
38// Top-level items just contains the ".events" attribute, and their rows
39// correspond to their day of week. In that case the internalId contains
40// DAY_ID.
41//
42// Direct children are events, and their rows corresponds to their index in
43// their partition. In that case no internalId / internalPointer is used.
44//
45// Internally:
46// -----------
47//
48// On construction and on dataChanged, all events are processed and partitioned
49// in partitionedEvents:
50//
51// QVector< QList<QSharedPointer<Event> >
52// ~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
53// | |
54// | '--- List of event pointers for that day
55// '--- Partition / day
56//
57class EventTreeModel : public QAbstractItemModel
58{
59 Q_OBJECT
60
61public:
62 using Event = Sink::ApplicationDomain::Event;
63
64 enum Roles
65 {
66 Events = Qt::UserRole + 1,
67 Summary,
68 Description,
69 StartTime,
70 Duration,
71 };
72 Q_ENUM(Roles);
73 EventTreeModel(QObject *parent = nullptr);
74 ~EventTreeModel() = default;
75
76 QModelIndex index(int row, int column, const QModelIndex &parent = {}) const override;
77 QModelIndex parent(const QModelIndex &index) const override;
78
79 int rowCount(const QModelIndex &parent) const override;
80 int columnCount(const QModelIndex &parent) const override;
81
82 bool hasChildren(const QModelIndex &parent) const override;
83
84 QVariant data(const QModelIndex &index, int role) const override;
85
86 QHash<int, QByteArray> roleNames() const override;
87
88private:
89 void partitionData();
90
91 QSharedPointer<QAbstractItemModel> eventModel;
92 QVector<QList<QSharedPointer<Event>>> partitionedEvents;
93
94 static const constexpr quintptr DAY_ID = 7;
95};
diff --git a/framework/src/frameworkplugin.cpp b/framework/src/frameworkplugin.cpp
index d512ce10..6dd1e985 100644
--- a/framework/src/frameworkplugin.cpp
+++ b/framework/src/frameworkplugin.cpp
@@ -21,6 +21,7 @@
21#include "frameworkplugin.h" 21#include "frameworkplugin.h"
22 22
23#include "domain/maillistmodel.h" 23#include "domain/maillistmodel.h"
24#include "domain/eventtreemodel.h"
24#include "domain/folderlistmodel.h" 25#include "domain/folderlistmodel.h"
25#include "domain/composercontroller.h" 26#include "domain/composercontroller.h"
26#include "domain/mime/messageparser.h" 27#include "domain/mime/messageparser.h"
@@ -120,6 +121,7 @@ void FrameworkPlugin::registerTypes (const char *uri)
120{ 121{
121 qmlRegisterType<FolderListModel>(uri, 1, 0, "FolderListModel"); 122 qmlRegisterType<FolderListModel>(uri, 1, 0, "FolderListModel");
122 qmlRegisterType<MailListModel>(uri, 1, 0, "MailListModel"); 123 qmlRegisterType<MailListModel>(uri, 1, 0, "MailListModel");
124 qmlRegisterType<EventTreeModel>(uri, 1, 0, "EventTreeModel");
123 qmlRegisterType<ComposerController>(uri, 1, 0, "ComposerController"); 125 qmlRegisterType<ComposerController>(uri, 1, 0, "ComposerController");
124 qmlRegisterType<Kube::ControllerAction>(uri, 1, 0, "ControllerAction"); 126 qmlRegisterType<Kube::ControllerAction>(uri, 1, 0, "ControllerAction");
125 qmlRegisterType<MessageParser>(uri, 1, 0, "MessageParser"); 127 qmlRegisterType<MessageParser>(uri, 1, 0, "MessageParser");