1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
/*
Copyright (c) 2018 Michael Bohlender <michael.bohlender@kdemail.net>
Copyright (c) 2018 Christian Mollekopf <mollekopf@kolabsys.com>
Copyright (c) 2018 Rémi Nicole <minijackson@riseup.net>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#pragma once
#include "kube_export.h"
#include <sink/applicationdomaintype.h>
#include <QAbstractItemModel>
#include <QList>
#include <QSharedPointer>
#include <QVector>
#include <limits>
// Facility used to get a restricted period into a Sink model comprised of
// events, partitioned according to the day the events take place.
//
// Day-long events are filtered out.
//
// Model Format
// ============
//
// Day 0
// |--- Event 0 starting at `periodStart + 0d`
// |--- Event 1 starting at `periodStart + 0d`
// '--- Event 2 starting at `periodStart + 0d`
// Day 1
// '--- Event 0 starting at `periodStart + 1d`
// Day 2
// Day 3
// |--- Event 0 starting at `periodStart + 3d`
// '--- Event 1 starting at `periodStart + 3d`
// Day 4
// ⋮
//
// Implementation notes
// ====================
//
// On the model side
// -----------------
//
// Columns are never used.
//
// Top-level items just contains the ".events" attribute, and their rows
// correspond to their offset compared to the start of the period (in number of
// days). In that case the internalId contains DAY_ID.
//
// Direct children are events, and their rows corresponds to their index in
// their partition. In that case no internalId / internalPointer is used.
//
// Internally:
// -----------
//
// On construction and on dataChanged, all events are processed and partitioned
// in partitionedEvents:
//
// QVector< QList<QSharedPointer<Event> >
// ~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
// | |
// | '--- List of event pointers for that day
// '--- Partition / day
//
class KUBE_EXPORT PeriodDayEventModel : public QAbstractItemModel
{
Q_OBJECT
Q_PROPERTY(QVariant start READ periodStart WRITE setPeriodStart)
Q_PROPERTY(int length READ periodLength WRITE setPeriodLength)
public:
using Event = Sink::ApplicationDomain::Event;
enum Roles
{
Events = Qt::UserRole + 1,
Summary,
Description,
StartTime,
Duration,
};
Q_ENUM(Roles);
PeriodDayEventModel(QObject *parent = nullptr);
~PeriodDayEventModel() = default;
QModelIndex index(int row, int column, const QModelIndex &parent = {}) const override;
QModelIndex parent(const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
QDate periodStart() const;
void setPeriodStart(const QDate &);
void setPeriodStart(const QVariant &);
int periodLength() const;
void setPeriodLength(int);
private:
void partitionData();
int bucketOf(const QDate &candidate) const;
QDate mPeriodStart;
int mPeriodLength = 7;
QSharedPointer<QAbstractItemModel> eventModel;
QVector<QList<QSharedPointer<Event>>> partitionedEvents;
static const constexpr quintptr DAY_ID = std::numeric_limits<quintptr>::max();
};
|