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 onDateClicked: (date) =>
251 {
252 control.selectedDate = date
253 control.dateClicked(control.selectedDate)
254 }
255
256 onDateDoubleClicked: (date) =>
257 {
258 control.selectedDate = date
259 control.dateDoubleClicked(control.selectedDate)
260 }
261
262 dayHeaderDelegate: ItemDelegate
263 {
264 leftPadding: Maui.Style.units.smallSpacing
265 rightPadding: Maui.Style.units.smallSpacing
266
267 contentItem: Label
268 {
269 text:
270 {
271 let longText = day.toLocaleString(Qt.locale(), "dddd");
272 let midText = day.toLocaleString(Qt.locale(), "ddd");
273 let shortText = midText.slice(0,1);
274
275
276 return control.isTiny ? shortText : midText;
277 }
278
279
280 horizontalAlignment: Text.AlignLeft
281 font.bold: true
282 font.weight: Font.Bold
283 font.pointSize: Maui.Style.fontSizes.big
284
285 }
286 }
287
288 weekHeaderDelegate: Maui.LabelDelegate
289 {
290 padding: Maui.Style.units.smallSpacing
291 // verticalAlignment: Qt.AlignTop
292 label.horizontalAlignment: Qt.AlignHCenter
293 text: DateUtils.getWeek(startDate, Qt.locale().firstDayOfWeek)
294 // background: Rectangle {
295 // Kirigami.Theme.inherit: false
296 // Kirigami.Theme.colorSet: Kirigami.Theme.View
297 // color: Kirigami.Theme.backgroundColor
298 // }
299 }
300
301 openOccurrence: control.openOccurrence
302 }
303 }
304 }
305
306 /**
307 * @brief
308 */
309 function resetDate()
310 {
311 setToDate(new Date())
312 }
313
314 /**
315 * @brief
316 */
317 function nextDate()
318 {
319 setToDate(DateUtils.addMonthsToDate(pathView.currentItem.firstDayOfMonth, 1))
320 }
321
322 /**
323 * @brief
324 */
325 function previousDate()
326 {
327 setToDate(DateUtils.addMonthsToDate(pathView.currentItem.firstDayOfMonth, -1))
328 }
329
330 /**
331 * @brief
332 */
333 function addMonthsToDate(date, days)
334 {
335 return DateUtils.addMonthsToDate(date, days)
336 }
337
338 /**
339 * @brief
340 */
341 function setToDate(date, isInitialMonth = true)
342 {
343 control.initialMonth = isInitialMonth;
344 let monthDiff = date.getMonth() - pathView.currentItem.firstDayOfMonth.getMonth() + (12 * (date.getFullYear() - pathView.currentItem.firstDayOfMonth.getFullYear()))
345 let newIndex = pathView.currentIndex + monthDiff;
346
347 let firstItemDate = pathView.model.data(pathView.model.index(1,0), Kalendar.InfiniteCalendarViewModel.FirstDayOfMonthRole);
348 let lastItemDate = pathView.model.data(pathView.model.index(pathView.model.rowCount() - 1,0), Kalendar.InfiniteCalendarViewModel.FirstDayOfMonthRole);
349
350 while(firstItemDate >= date) {
351 pathView.model.addDates(false)
352 firstItemDate = pathView.model.data(pathView.model.index(1,0), Kalendar.InfiniteCalendarViewModel.FirstDayOfMonthRole);
353 newIndex = 0;
354 }
355 if(firstItemDate < date && newIndex === 0) {
356 newIndex = date.getMonth() - firstItemDate.getMonth() + (12 * (date.getFullYear() - firstItemDate.getFullYear())) + 1;
357 }
358
359 while(lastItemDate <= date) {
360 pathView.model.addDates(true)
361 lastItemDate = pathView.model.data(pathView.model.index(pathView.model.rowCount() - 1,0), Kalendar.InfiniteCalendarViewModel.FirstDayOfMonthRole);
362 }
363 pathView.currentIndex = newIndex;
364 }
365}
366
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 Sat Dec 21 2024 17:02:37 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.