MauiKit Calendar

MonthView.qml
1// Copyright (C) 2023 Camilo Higuita, <milo.h@kaol.com>
2// Copyright (C) 2018 Michael Bohlender, <bohlender@kolabsys.com>
3// Copyright (C) 2018 Christian Mollekopf, <mollekopf@kolabsys.com>
4// SPDX-FileCopyrightText: 2021 Claudio Cambra <claudio.cambra@gmail.com>
5// SPDX-License-Identifier: GPL-2.0-or-later
6
7import QtQuick
8import QtQuick.Layouts
9import QtQuick.Controls
10
11import org.mauikit.controls as Maui
12import org.mauikit.calendar as Kalendar
13
14import "dateutils.js" as DateUtils
15
16/**
17 * @inherit QtQuick.Controls.Pane
18 * @brief A view for browsing the calendar months and its days.
19 *
20 * @image html monthview_sizes.png "MonthView control with different sizes"
21 *
22 *
23 * @code
24 * Maui.Page
25 * {
26 * anchors.fill: parent
27 * Maui.Controls.showCSD: true
28 *
29 * title: _monthsView.title
30 *
31 * headBar.rightContent: Maui.ToolActions
32 * {
33 * checkable: false
34 * Action
35 * {
36 * icon.name: "go-previous"
37 * onTriggered: _monthsView.previousDate()
38 * }
39 *
40 * Action
41 * {
42 * icon.name: "go-next"
43 * onTriggered: _monthsView.nextDate()
44 *
45 * }
46 * }
47 *
48 * MC.MonthView
49 * {
50 * id: _monthsView
51 * anchors.fill: parent
52 * }
53 * }
54 * @endcode
55 */
56Pane
57{
58 id: control
59
60 padding : 0
61
62 /**
63 * @brief
64 */
65 readonly property date currentDate: new Date()
66
67 /**
68 * @brief
69 */
70 readonly property string title: Qt.formatDate(pathView.currentItem.firstDayOfMonth, "MMM yyyy")
71
72 /**
73 * @brief
74 */
75 property var openOccurrence: ({})
77 /**
78 * @brief
79 */
80 property var filter: {
81 "collectionId": -1,
82 "tags": [],
83 "name": ""
84 }
85
86 /**
87 * @brief
88 */
89 readonly property alias model : _monthViewModel
90
91 /**
92 * @brief
93 */
94 property date startDate
95
96 /**
97 * @brief
98 */
99 property date firstDayOfMonth
100
101 /**
102 * @brief
103 */
104 property int month
105
106 /**
107 * @brief
108 */
109 property int year
110
111 /**
112 * @brief
113 */
114 property bool initialMonth: true
115
116 /**
117 * @brief
118 */
119 readonly property bool isLarge: width > Maui.Style.units.gridUnit * 40
120
121 /**
122 * @brief
123 */
124 readonly property bool isTiny: width < Maui.Style.units.gridUnit * 18
125
126 /**
127 * @brief
128 */
129 property date selectedDate : currentDate
130
131 /**
132 * @brief
133 */
134 property bool dragDropEnabled: true
135
136 /**
137 * @brief
138 */
139 property alias interactive : pathView.interactive
140
141 /**
142 * @brief
143 */
144 signal dateClicked(var date)
145
146 /**
147 * @brief
148 */
149 signal dateRightClicked(var date)
150
151 /**
152 * @brief
153 */
154 signal dateDoubleClicked(var date)
155
156 background: Rectangle
157 {
158 color: Maui.Theme.backgroundColor
159 }
160
161 Kalendar.InfiniteCalendarViewModel
162 {
163 id: _monthViewModel
164 scale: Kalendar.InfiniteCalendarViewModel.MonthScale
165 }
166
167 contentItem: PathView
168 {
169 id: pathView
170
171 flickDeceleration: Maui.Style.units.longDuration
172 interactive: Maui.Handy.isMobile
173
174 preferredHighlightBegin: 0.5
175 preferredHighlightEnd: 0.5
176
177 // highlightRangeMode: ListView.StrictlyEnforceRange
178 highlightMoveDuration: 0
179 // spacing: 10
180 snapMode: PathView.SnapToItem
181 focus: true
182 // interactive: Kirigami.Settings.tabletMode
183
184 path: Path {
185 startX: - pathView.width * pathView.count / 2 + pathView.width / 2
186 startY: pathView.height / 2
187 PathLine {
188 x: pathView.width * pathView.count / 2 + pathView.width / 2
189 y: pathView.height / 2
190 }
191 }
192
193 model: control.model
194
195 property int startIndex
196
197 Component.onCompleted:
198 {
199 startIndex = count / 2;
200 currentIndex = startIndex;
201 }
202
203 onCurrentIndexChanged:
204 {
205 control.startDate = currentItem.startDate;
206 control.firstDayOfMonth = currentItem.firstDayOfMonth;
207 control.month = currentItem.month;
208 control.year = currentItem.year;
209
210 if(currentIndex >= count - 2) {
211 model.addDates(true);
212 } else if (currentIndex <= 1) {
213 model.addDates(false);
214 startIndex += model.datesToAdd;
215 }
216 }
217
218 delegate: Loader
219 {
220 id: viewLoader
221
222 property date startDate: model.startDate
223 property date firstDayOfMonth: model.firstDay
224 property int month: model.selectedMonth - 1 // Convert QDateTime month to JS month
225 property int year: model.selectedYear
226
227 property bool isNextOrCurrentItem: index >= pathView.currentIndex -1 && index <= pathView.currentIndex + 1
228 property bool isCurrentItem: PathView.isCurrentItem
229
230 active: isNextOrCurrentItem
231 asynchronous: !isCurrentItem
232 visible: status === Loader.Ready
233
234 sourceComponent: Kalendar.DayGridView
235 {
236 id: dayView
237 objectName: "monthView"
238
239 width: pathView.width
240 height: pathView.height
241
242 // model: monthViewModel // from control model
243 isCurrentView: viewLoader.isCurrentItem
244 dragDropEnabled: control.dragDropEnabled
245
246 startDate: viewLoader.startDate
247 currentDate: control.currentDate
248 month: viewLoader.month
249
250
251
252 onDateClicked:
253 {
254
255 control.selectedDate = date
256 control.dateClicked(control.selectedDate)
257 }
258
259 onDateDoubleClicked:
260 {
261 control.selectedDate = date
262 control.dateDoubleClicked(control.selectedDate)
263 }
264
265 dayHeaderDelegate: ItemDelegate
266 {
267 leftPadding: Maui.Style.units.smallSpacing
268 rightPadding: Maui.Style.units.smallSpacing
269
270 contentItem: Label
271 {
272 text:
273 {
274 let longText = day.toLocaleString(Qt.locale(), "dddd");
275 let midText = day.toLocaleString(Qt.locale(), "ddd");
276 let shortText = midText.slice(0,1);
277
278
279 return control.isTiny ? shortText : midText;
280 }
281
282
283 horizontalAlignment: Text.AlignLeft
284 font.bold: true
285 font.weight: Font.Bold
286 font.pointSize: Maui.Style.fontSizes.big
287
288
289 }
290
291
292 }
293
294 weekHeaderDelegate: Maui.LabelDelegate
295 {
296 padding: Maui.Style.units.smallSpacing
297 // verticalAlignment: Qt.AlignTop
298 label.horizontalAlignment: Qt.AlignHCenter
299 text: DateUtils.getWeek(startDate, Qt.locale().firstDayOfWeek)
300 // background: Rectangle {
301 // Kirigami.Theme.inherit: false
302 // Kirigami.Theme.colorSet: Kirigami.Theme.View
303 // color: Kirigami.Theme.backgroundColor
304 // }
305 }
306
307 openOccurrence: control.openOccurrence
308 }
309 }
310 }
311
312 /**
313 * @brief
314 */
315 function resetDate()
316 {
317 setToDate(new Date())
318 }
319
320 /**
321 * @brief
322 */
323 function nextDate()
324 {
325 setToDate(DateUtils.addMonthsToDate(pathView.currentItem.firstDayOfMonth, 1))
326 }
327
328 /**
329 * @brief
330 */
331 function previousDate()
332 {
333 setToDate(DateUtils.addMonthsToDate(pathView.currentItem.firstDayOfMonth, -1))
334 }
335
336 /**
337 * @brief
338 */
339 function addMonthsToDate(date, days)
340 {
341 return DateUtils.addMonthsToDate(date, days)
342 }
343
344 /**
345 * @brief
346 */
347 function setToDate(date, isInitialMonth = true)
348 {
349 control.initialMonth = isInitialMonth;
350 let monthDiff = date.getMonth() - pathView.currentItem.firstDayOfMonth.getMonth() + (12 * (date.getFullYear() - pathView.currentItem.firstDayOfMonth.getFullYear()))
351 let newIndex = pathView.currentIndex + monthDiff;
352
353 let firstItemDate = pathView.model.data(pathView.model.index(1,0), Kalendar.InfiniteCalendarViewModel.FirstDayOfMonthRole);
354 let lastItemDate = pathView.model.data(pathView.model.index(pathView.model.rowCount() - 1,0), Kalendar.InfiniteCalendarViewModel.FirstDayOfMonthRole);
355
356 while(firstItemDate >= date) {
357 pathView.model.addDates(false)
358 firstItemDate = pathView.model.data(pathView.model.index(1,0), Kalendar.InfiniteCalendarViewModel.FirstDayOfMonthRole);
359 newIndex = 0;
360 }
361 if(firstItemDate < date && newIndex === 0) {
362 newIndex = date.getMonth() - firstItemDate.getMonth() + (12 * (date.getFullYear() - firstItemDate.getFullYear())) + 1;
363 }
364
365 while(lastItemDate <= date) {
366 pathView.model.addDates(true)
367 lastItemDate = pathView.model.data(pathView.model.index(pathView.model.rowCount() - 1,0), Kalendar.InfiniteCalendarViewModel.FirstDayOfMonthRole);
368 }
369 pathView.currentIndex = newIndex;
370 }
371}
372
Q_SCRIPTABLE CaptureState status()
QString path(const QString &relativePath)
QString label(StandardShortcut id)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 4 2024 11:53:16 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.