MauiKit Calendar

infinitecalendarviewmodel.cpp
1// SPDX-FileCopyrightText: 2021 Claudio Cambra <claudio.cambra@gmail.com>
2// SPDX-License-Identifier: LGPL-2.1-or-later
3
4#include "incidenceoccurrencemodel.h"
5#include <Akonadi/EntityTreeModel>
6#include <QMetaEnum>
7#include <cmath>
8#include <models/infinitecalendarviewmodel.h>
9
10InfiniteCalendarViewModel::InfiniteCalendarViewModel(QObject *parent)
11 : QAbstractListModel(parent)
12{
13 setup();
14}
15
16void InfiniteCalendarViewModel::setup()
17{
19 QTime time;
20
21 if (!m_hourlyViewLocalisedHourLabels.length()) {
22 m_hourlyViewLocalisedHourLabels.clear();
23 for (int i = 1; i < 24; i++) {
24 time.setHMS(i, 0, 0);
25 m_hourlyViewLocalisedHourLabels.append(QLocale::system().toString(time, QLocale::NarrowFormat));
26 }
27 }
28
29 switch (m_scale) {
30 case DayScale: {
32 firstDay = firstDay.addDays(m_datesToAdd / 2);
33
34 addDayDates(true, firstDay);
35 break;
36 }
37 case ThreeDayScale: {
39 firstDay = firstDay.addDays((-m_datesToAdd * 3) / 2);
40
41 addDayDates(true, firstDay, 3);
42 break;
43 }
44 case WeekScale: {
45 QDate firstDay = today.addDays(-today.dayOfWeek() + m_locale.firstDayOfWeek());
46 // We create dates before and after where our view will start from (which is today)
47 firstDay = firstDay.addDays((-m_datesToAdd * 7) / 2);
48
49 addWeekDates(true, firstDay);
50 break;
51 }
52 case MonthScale: {
53 QDate firstDay(today.year(), today.month(), 1);
54 firstDay = firstDay.addMonths(-m_datesToAdd / 2);
55
56 addMonthDates(true, firstDay);
57 break;
58 }
59 case YearScale: {
60 QDate firstDay(today.year(), today.month(), 1);
61 firstDay = firstDay.addYears(-m_datesToAdd / 2);
62
63 addYearDates(true, firstDay);
64 break;
65 }
66 case DecadeScale: {
67 const int firstYear = ((floor(today.year() / 10)) * 10) - 1; // E.g. For 2020 have view start at 2019...
68 QDate firstDay(firstYear, today.month(), 1);
69 firstDay = firstDay.addYears(((-m_datesToAdd * 12) / 2) + 10); // 3 * 4 grid so 12 years, end at 2030, and align for mid index to be current decade
70
71 addDecadeDates(true, firstDay);
72 break;
73 }
74 }
75}
76
77QVariant InfiniteCalendarViewModel::data(const QModelIndex &idx, int role) const
78{
79 if (!hasIndex(idx.row(), idx.column())) {
80 return {};
81 }
82
83 const QDate startDate = m_startDates[idx.row()];
84
85 if (m_scale == MonthScale && role != StartDateRole) {
86 const QDate firstDay = m_firstDayOfMonthDates[idx.row()];
87
88 switch (role) {
89 case FirstDayOfMonthRole:
90 return firstDay.startOfDay();
91 case SelectedMonthRole:
92 return firstDay.month();
93 case SelectedYearRole:
94 return firstDay.year();
95 default:
96 qWarning() << "Unknown role for startdate:" << QMetaEnum::fromType<Roles>().valueToKey(role);
97 return {};
98 }
99 }
100
101 switch (role) {
102 case StartDateRole:
103 return startDate.startOfDay();
104 case SelectedMonthRole:
105 return startDate.month();
106 case SelectedYearRole:
107 return startDate.year();
108 default:
109 qWarning() << "Unknown role for startdate:" << QMetaEnum::fromType<Roles>().valueToKey(role);
110 return {};
111 }
112}
113
114int InfiniteCalendarViewModel::rowCount(const QModelIndex &parent) const
115{
117 return m_startDates.length();
118}
119
120QHash<int, QByteArray> InfiniteCalendarViewModel::roleNames() const
121{
122 return {
123 {StartDateRole, QByteArrayLiteral("startDate")},
124 {FirstDayOfMonthRole, QByteArrayLiteral("firstDay")},
125 {SelectedMonthRole, QByteArrayLiteral("selectedMonth")},
126 {SelectedYearRole, QByteArrayLiteral("selectedYear")},
127 };
128}
129
130void InfiniteCalendarViewModel::addDates(bool atEnd, const QDate startFrom)
131{
132 switch (m_scale) {
133 case DayScale:
134 addDayDates(atEnd, startFrom);
135 break;
136 case ThreeDayScale:
137 addDayDates(atEnd, startFrom, 3);
138 break;
139 case WeekScale:
140 addWeekDates(atEnd, startFrom);
141 break;
142 case MonthScale:
143 addMonthDates(atEnd, startFrom);
144 break;
145 case YearScale:
146 addYearDates(atEnd, startFrom);
147 break;
148 case DecadeScale:
149 addDecadeDates(atEnd, startFrom);
150 break;
151 }
152}
153
154void InfiniteCalendarViewModel::addDayDates(bool atEnd, const QDate &startFrom, int amount)
155{
156 const int newRow = atEnd ? rowCount() : 0;
157
158 beginInsertRows(QModelIndex(), newRow, newRow + m_datesToAdd - 1);
159
160 for (int i = 0; i < m_datesToAdd; i++) {
161 QDate startDate = startFrom.isValid() && i == 0 ? startFrom : atEnd ? m_startDates[rowCount() - 1].addDays(amount) : m_startDates[0].addDays(-amount);
162
163 if (atEnd) {
164 m_startDates.append(startDate);
165 } else {
166 m_startDates.insert(0, startDate);
167 }
168 }
169
171}
172
173void InfiniteCalendarViewModel::addWeekDates(bool atEnd, const QDate &startFrom)
174{
175 const int newRow = atEnd ? rowCount() : 0;
176
177 beginInsertRows(QModelIndex(), newRow, newRow + m_datesToAdd - 1);
178
179 for (int i = 0; i < m_datesToAdd; i++) {
180 QDate startDate = startFrom.isValid() && i == 0 ? startFrom : atEnd ? m_startDates[rowCount() - 1].addDays(7) : m_startDates[0].addDays(-7);
181
182 if (startDate.dayOfWeek() != m_locale.firstDayOfWeek()) {
183 startDate = startDate.addDays(-startDate.dayOfWeek() + m_locale.firstDayOfWeek());
184 }
185
186 if (atEnd) {
187 m_startDates.append(startDate);
188 } else {
189 m_startDates.insert(0, startDate);
190 }
191 }
192
194}
195
196void InfiniteCalendarViewModel::addMonthDates(bool atEnd, const QDate &startFrom)
197{
198 const int newRow = atEnd ? rowCount() : 0;
199
200 beginInsertRows(QModelIndex(), newRow, newRow + m_datesToAdd - 1);
201
202 for (int i = 0; i < m_datesToAdd; i++) {
203 const QDate firstDay = startFrom.isValid() && i == 0 ? startFrom
204 : atEnd ? m_firstDayOfMonthDates[rowCount() - 1].addMonths(1)
205 : m_firstDayOfMonthDates[0].addMonths(-1);
206 QDate startDate = firstDay;
207
208 startDate = startDate.addDays(-startDate.dayOfWeek() + m_locale.firstDayOfWeek());
209 if (startDate >= firstDay) {
210 startDate = startDate.addDays(-7);
211 }
212
213 if (atEnd) {
214 m_firstDayOfMonthDates.append(firstDay);
215 m_startDates.append(startDate);
216 } else {
217 m_firstDayOfMonthDates.insert(0, firstDay);
218 m_startDates.insert(0, startDate);
219 }
220 }
221
223}
224
225void InfiniteCalendarViewModel::addYearDates(bool atEnd, const QDate &startFrom)
226{
227 const int newRow = atEnd ? rowCount() : 0;
228
229 beginInsertRows(QModelIndex(), newRow, newRow + m_datesToAdd - 1);
230
231 for (int i = 0; i < m_datesToAdd; i++) {
232 QDate startDate = startFrom.isValid() && i == 0 ? startFrom : atEnd ? m_startDates[rowCount() - 1].addYears(1) : m_startDates[0].addYears(-1);
233
234 if (atEnd) {
235 m_startDates.append(startDate);
236 } else {
237 m_startDates.insert(0, startDate);
238 }
239 }
240
242}
243
244void InfiniteCalendarViewModel::addDecadeDates(bool atEnd, const QDate &startFrom)
245{
246 const int newRow = atEnd ? rowCount() : 0;
247
248 beginInsertRows(QModelIndex(), newRow, newRow + m_datesToAdd - 1);
249
250 for (int i = 0; i < m_datesToAdd; i++) {
251 QDate startDate = startFrom.isValid() && i == 0 ? startFrom : atEnd ? m_startDates[rowCount() - 1].addYears(10) : m_startDates[0].addYears(-10);
252
253 if (atEnd) {
254 m_startDates.append(startDate);
255 } else {
256 m_startDates.insert(0, startDate);
257 }
258 }
259
261}
262
263int InfiniteCalendarViewModel::datesToAdd() const
264{
265 return m_datesToAdd;
266}
267
268void InfiniteCalendarViewModel::setDatesToAdd(int datesToAdd)
269{
270 m_datesToAdd = datesToAdd;
271 Q_EMIT datesToAddChanged();
272}
273
274int InfiniteCalendarViewModel::scale() const
275{
276 return m_scale;
277}
278
279void InfiniteCalendarViewModel::setScale(int scale)
280{
282
283 m_startDates.clear();
284 m_firstDayOfMonthDates.clear();
285
286 m_scale = scale;
287 setup();
288 Q_EMIT scaleChanged();
289
291}
292
293#include "infinitecalendarviewmodel.moc"
294#include "moc_infinitecalendarviewmodel.cpp"
295
char * toString(const EngineQuery &query)
void beginInsertRows(const QModelIndex &parent, int first, int last)
bool hasIndex(int row, int column, const QModelIndex &parent) const const
QDate addDays(qint64 ndays) const const
QDate currentDate()
int dayOfWeek() const const
int month() const const
QDateTime startOfDay() const const
int year() const const
void append(QList< T > &&value)
void clear()
qsizetype length() const const
Qt::DayOfWeek firstDayOfWeek() const const
QLocale system()
Q_EMITQ_EMIT
QObject * parent() const const
T qobject_cast(QObject *object)
QTestData & newRow(const char *dataTag)
bool setHMS(int h, int m, int s, int ms)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:50:31 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.