Warning, /maui/mauikit-calendar/src/controls.6/MonthView.qml is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2023 Camilo Higuita, <milo.h@kaol.com>
0002 // Copyright (C) 2018 Michael Bohlender, <bohlender@kolabsys.com>
0003 // Copyright (C) 2018 Christian Mollekopf, <mollekopf@kolabsys.com>
0004 // SPDX-FileCopyrightText: 2021 Claudio Cambra <claudio.cambra@gmail.com>
0005 // SPDX-License-Identifier: GPL-2.0-or-later
0006 
0007 import QtQuick
0008 import QtQuick.Layouts
0009 import QtQuick.Controls 
0010 
0011 import org.mauikit.controls 1.3 as Maui
0012 import org.mauikit.calendar 1.0 as Kalendar
0013 
0014 import "dateutils.js" as DateUtils
0015 
0016 /**
0017  * @inherit QtQuick.Controls.Pane
0018  * @brief A view for browsing the calendar months and its days.
0019  * 
0020  * @image html monthview_sizes.png "MonthView control with different sizes"
0021  * 
0022  * 
0023  * @code
0024  * Maui.Page
0025  * {
0026  *    anchors.fill: parent
0027  *    Maui.Controls.showCSD: true
0028  * 
0029  *    title: _monthsView.title
0030  * 
0031  *    headBar.rightContent: Maui.ToolActions
0032  *    {
0033  *        checkable: false
0034  *        Action
0035  *        {
0036  *            icon.name: "go-previous"
0037  *            onTriggered: _monthsView.previousDate()
0038  *        }
0039  * 
0040  *        Action
0041  *        {
0042  *            icon.name: "go-next"
0043  *            onTriggered: _monthsView.nextDate()
0044  * 
0045  *        }
0046  *    }
0047  * 
0048  *    MC.MonthView
0049  *    {
0050  *        id: _monthsView
0051  *        anchors.fill: parent
0052  *    }
0053  * }
0054  * @endcode
0055  */
0056 Pane
0057 {
0058     id: control
0059     
0060     padding : 0
0061     
0062     /**
0063      * @brief
0064      */
0065     readonly property date currentDate: new Date()
0066     
0067     /**
0068      * @brief
0069      */
0070     readonly property string title: Qt.formatDate(pathView.currentItem.firstDayOfMonth, "MMM yyyy")
0071     
0072     /**
0073      * @brief
0074      */
0075     property var openOccurrence: ({})
0076     
0077     /**
0078      * @brief
0079      */
0080     property var filter: {
0081         "collectionId": -1,
0082         "tags": [],
0083         "name": ""
0084     }
0085     
0086     /**
0087      * @brief
0088      */
0089     readonly property alias model :  _monthViewModel
0090     
0091     /**
0092      * @brief
0093      */
0094     property date startDate
0095     
0096     /**
0097      * @brief
0098      */
0099     property date firstDayOfMonth
0100     
0101     /**
0102      * @brief
0103      */
0104     property int month
0105     
0106     /**
0107      * @brief
0108      */
0109     property int year
0110     
0111     /**
0112      * @brief
0113      */
0114     property bool initialMonth: true
0115     
0116     /**
0117      * @brief
0118      */
0119     readonly property bool isLarge: width > Maui.Style.units.gridUnit * 40
0120     
0121     /**
0122      * @brief
0123      */
0124     readonly property bool isTiny: width < Maui.Style.units.gridUnit * 18
0125     
0126     /**
0127      * @brief
0128      */
0129     property date selectedDate : currentDate
0130     
0131     /**
0132      * @brief
0133      */
0134     property bool dragDropEnabled: true
0135     
0136     /**
0137      * @brief
0138      */
0139     property alias interactive : pathView.interactive
0140     
0141     /**
0142      * @brief
0143      */
0144     signal dateClicked(var date)
0145     
0146     /**
0147      * @brief
0148      */
0149     signal dateRightClicked(var date)
0150     
0151     /**
0152      * @brief
0153      */
0154     signal dateDoubleClicked(var date)
0155     
0156     background: Rectangle
0157     {
0158         color: Maui.Theme.backgroundColor
0159     }
0160     
0161     Kalendar.InfiniteCalendarViewModel
0162     {
0163         id: _monthViewModel
0164         scale: Kalendar.InfiniteCalendarViewModel.MonthScale
0165     }
0166     
0167     contentItem: PathView
0168     {
0169         id: pathView
0170         
0171         flickDeceleration: Maui.Style.units.longDuration
0172         interactive: Maui.Handy.isMobile
0173         
0174         preferredHighlightBegin: 0.5
0175         preferredHighlightEnd: 0.5
0176         
0177         //                   highlightRangeMode: ListView.StrictlyEnforceRange
0178         highlightMoveDuration: 0
0179         //        spacing: 10
0180         snapMode: PathView.SnapToItem
0181         focus: true
0182         //        interactive: Kirigami.Settings.tabletMode
0183         
0184         path: Path {
0185             startX: - pathView.width * pathView.count / 2 + pathView.width / 2
0186             startY: pathView.height / 2
0187             PathLine {
0188                 x: pathView.width * pathView.count / 2 + pathView.width / 2
0189                 y: pathView.height / 2
0190             }
0191         }
0192         
0193         model: control.model
0194         
0195         property int startIndex
0196         
0197         Component.onCompleted:
0198         {
0199             startIndex = count / 2;
0200             currentIndex = startIndex;
0201         }
0202         
0203         onCurrentIndexChanged:
0204         {
0205             control.startDate = currentItem.startDate;
0206             control.firstDayOfMonth = currentItem.firstDayOfMonth;
0207             control.month = currentItem.month;
0208             control.year = currentItem.year;
0209             
0210             if(currentIndex >= count - 2) {
0211                 model.addDates(true);
0212             } else if (currentIndex <= 1) {
0213                 model.addDates(false);
0214                 startIndex += model.datesToAdd;
0215             }
0216         }
0217         
0218         delegate: Loader
0219         {
0220             id: viewLoader
0221             
0222             property date startDate: model.startDate
0223             property date firstDayOfMonth: model.firstDay
0224             property int month: model.selectedMonth - 1 // Convert QDateTime month to JS month
0225             property int year: model.selectedYear
0226             
0227             property bool isNextOrCurrentItem: index >= pathView.currentIndex -1 && index <= pathView.currentIndex + 1
0228             property bool isCurrentItem: PathView.isCurrentItem
0229             
0230             active: isNextOrCurrentItem
0231             asynchronous: !isCurrentItem
0232             visible: status === Loader.Ready
0233             
0234             sourceComponent: Kalendar.DayGridView
0235             {
0236                 id: dayView
0237                 objectName: "monthView"
0238                 
0239                 width: pathView.width
0240                 height: pathView.height
0241                 
0242                 //                model: monthViewModel // from control model
0243                 isCurrentView: viewLoader.isCurrentItem
0244                 dragDropEnabled: control.dragDropEnabled
0245                 
0246                 startDate: viewLoader.startDate
0247                 currentDate: control.currentDate
0248                 month: viewLoader.month
0249                 
0250                 
0251                 
0252                 onDateClicked: 
0253                 {
0254                     
0255                     control.selectedDate = date
0256                     control.dateClicked(control.selectedDate)
0257                 }
0258                 
0259                 onDateDoubleClicked:
0260                 {
0261                     control.selectedDate = date
0262                     control.dateDoubleClicked(control.selectedDate)
0263                 }
0264                 
0265                 dayHeaderDelegate: ItemDelegate
0266                 {
0267                     leftPadding: Maui.Style.units.smallSpacing
0268                     rightPadding: Maui.Style.units.smallSpacing
0269                     
0270                     contentItem: Label
0271                     {
0272                         text:
0273                         {
0274                             let longText = day.toLocaleString(Qt.locale(), "dddd");
0275                             let midText = day.toLocaleString(Qt.locale(), "ddd");
0276                             let shortText = midText.slice(0,1);
0277                             
0278                             
0279                             return control.isTiny ? shortText : midText;
0280                         }
0281                         
0282                         
0283                         horizontalAlignment: Text.AlignLeft
0284                         font.bold: true
0285                         font.weight: Font.Bold
0286                         font.pointSize: Maui.Style.fontSizes.big
0287                         
0288                         
0289                     }                   
0290                     
0291                     
0292                 }
0293                 
0294                 weekHeaderDelegate: Maui.LabelDelegate
0295                 {
0296                     padding: Maui.Style.units.smallSpacing
0297                     //                                        verticalAlignment: Qt.AlignTop
0298                     label.horizontalAlignment: Qt.AlignHCenter
0299                     text: DateUtils.getWeek(startDate, Qt.locale().firstDayOfWeek)
0300                     //                    background: Rectangle {
0301                     //                        Kirigami.Theme.inherit: false
0302                     //                        Kirigami.Theme.colorSet: Kirigami.Theme.View
0303                     //                        color: Kirigami.Theme.backgroundColor
0304                     //                    }
0305                 }
0306                 
0307                 openOccurrence: control.openOccurrence
0308             }
0309         }
0310     }
0311     
0312     /**
0313      * @brief
0314      */
0315     function resetDate()
0316     {
0317         setToDate(new Date())
0318     }
0319     
0320     /**
0321      * @brief
0322      */
0323     function nextDate()
0324     {
0325         setToDate(DateUtils.addMonthsToDate(pathView.currentItem.firstDayOfMonth, 1))
0326     }
0327     
0328     /**
0329      * @brief
0330      */
0331     function previousDate()
0332     {
0333         setToDate(DateUtils.addMonthsToDate(pathView.currentItem.firstDayOfMonth, -1))
0334     }
0335     
0336     /**
0337      * @brief
0338      */
0339     function addMonthsToDate(date, days)
0340     {
0341         return DateUtils.addMonthsToDate(date, days)
0342     }
0343     
0344     /**
0345      * @brief
0346      */
0347     function setToDate(date, isInitialMonth = true)
0348     {
0349         control.initialMonth = isInitialMonth;
0350         let monthDiff = date.getMonth() - pathView.currentItem.firstDayOfMonth.getMonth() + (12 * (date.getFullYear() - pathView.currentItem.firstDayOfMonth.getFullYear()))
0351         let newIndex = pathView.currentIndex + monthDiff;
0352         
0353         let firstItemDate = pathView.model.data(pathView.model.index(1,0), Kalendar.InfiniteCalendarViewModel.FirstDayOfMonthRole);
0354         let lastItemDate = pathView.model.data(pathView.model.index(pathView.model.rowCount() - 1,0), Kalendar.InfiniteCalendarViewModel.FirstDayOfMonthRole);
0355         
0356         while(firstItemDate >= date) {
0357             pathView.model.addDates(false)
0358             firstItemDate = pathView.model.data(pathView.model.index(1,0), Kalendar.InfiniteCalendarViewModel.FirstDayOfMonthRole);
0359             newIndex = 0;
0360         }
0361         if(firstItemDate < date && newIndex === 0) {
0362             newIndex = date.getMonth() - firstItemDate.getMonth() + (12 * (date.getFullYear() - firstItemDate.getFullYear())) + 1;
0363         }
0364         
0365         while(lastItemDate <= date) {
0366             pathView.model.addDates(true)
0367             lastItemDate = pathView.model.data(pathView.model.index(pathView.model.rowCount() - 1,0), Kalendar.InfiniteCalendarViewModel.FirstDayOfMonthRole);
0368         }
0369         pathView.currentIndex = newIndex;
0370     }
0371 }
0372