Warning, /pim/kube/views/calendar/qml/MultiDayView.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  *  Copyright (C) 2018 Michael Bohlender, <bohlender@kolabsys.com>
0003  *  Copyright (C) 2018 Christian Mollekopf, <mollekopf@kolabsys.com>
0004  *
0005  *  This program is free software; you can redistribute it and/or modify
0006  *  it under the terms of the GNU General Public License as published by
0007  *  the Free Software Foundation; either version 2 of the License, or
0008  *  (at your option) any later version.
0009  *
0010  *  This program is distributed in the hope that it will be useful,
0011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0013  *  GNU General Public License for more details.
0014  *
0015  *  You should have received a copy of the GNU General Public License along
0016  *  with this program; if not, write to the Free Software Foundation, Inc.,
0017  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0018  */
0019 
0020 import QtQuick 2
0021 import QtQuick.Layouts 1
0022 import QtQuick.Controls 2
0023 
0024 import org.kube.framework 1.0 as Kube
0025 import "dateutils.js" as DateUtils
0026 
0027 Item {
0028     id: root
0029     property int daysToShow
0030     property int daysPerRow: daysToShow
0031     property double weekHeaderWidth: 0
0032     property double dayWidth: (width - weekHeaderWidth) / daysPerRow
0033     property date currentDate
0034     property date startDate
0035     property var calendarFilter
0036     property bool paintGrid: false
0037     property bool showDayIndicator: false
0038     property var filter
0039     property alias dayHeaderDelegate: dayLabels.delegate
0040     property Component weekHeaderDelegate
0041     property int month
0042 
0043     //Internal
0044     readonly property int verticalSpacing: 2
0045     property int horizontalSpacing: Kube.Units.smallSpacing
0046     readonly property int lineHeight: Kube.Units.gridUnit
0047     property int numberOfLinesShown: 0
0048     readonly property int numberOfRows: (daysToShow / daysPerRow)
0049     property var dayHeight: (height - dayLabels.height) / numberOfRows
0050 
0051     implicitHeight: (numberOfRows > 1 ? Kube.Units.gridUnit * 10 * numberOfRows: numberOfLinesShown * (Kube.Units.gridUnit + verticalSpacing)) + dayLabels.height + root.verticalSpacing
0052 
0053     height: implicitHeight
0054 
0055     ButtonGroup {
0056         id: expandButtonGroup
0057         exclusive: false
0058         //Like exclusive, but a checked button can be unchecked by clicking again.
0059         onClicked: {
0060             for (var i = 0; i < buttons.length; i++){
0061                 var btn = buttons[i];
0062                 if (button != btn) {
0063                     btn.checked = false;
0064                 }
0065             }
0066         }
0067     }
0068 
0069     ColumnLayout {
0070         anchors {
0071             fill: parent
0072         }
0073         spacing: 0
0074 
0075         DayLabels {
0076             id: dayLabels
0077             startDate: root.startDate
0078             dayWidth: root.dayWidth
0079             daysToShow: root.daysPerRow
0080         }
0081 
0082         //Weeks
0083         Repeater {
0084             model: Kube.MultiDayEventModel {
0085                 model: Kube.EventOccurrenceModel {
0086                     objectName: "eventOccurrenceModel"
0087                     start: root.startDate
0088                     length: root.daysToShow
0089                     calendarFilter: root.calendarFilter
0090                     filter: root.filter ? root.filter : ({})
0091                 }
0092                 // daysPerRow: root.daysPerRow //Hardcoded to 7
0093             }
0094             //One row => one week
0095             Item {
0096                 id: weekRow
0097                 Layout.fillHeight: true
0098                 Layout.minimumHeight: expanded ? calculatedHeight : Kube.Units.gridUnit + Kube.Units.smallSpacing
0099                 Layout.preferredHeight: root.dayHeight
0100                 implicitWidth: parent.width
0101                 property bool expanded: expandButton.checked
0102                 readonly property int calculatedHeight: Math.max(
0103                     root.dayHeight,
0104                     events.length * (root.lineHeight + root.verticalSpacing) + (root.showDayIndicator ? Kube.Units.gridUnit + root.verticalSpacing : root.verticalSpacing)
0105                 )
0106                 property bool overfilled: calculatedHeight > root.dayHeight
0107 
0108                 clip: true
0109                 Row {
0110                     width: parent.width
0111                     height: parent.height
0112                     Loader {
0113                         id: weekHeader
0114                         height: parent.height
0115                         sourceComponent: root.weekHeaderDelegate
0116                         property var startDate: weekStartDate
0117                         onStatusChanged: if (weekHeader.status == Loader.Ready) root.weekHeaderWidth = item.width
0118                     }
0119                     Item {
0120                         id: dayDelegate
0121                         height: parent.height
0122                         width: parent.width - weekHeader.width
0123                         property var startDate: weekStartDate
0124                         //Grid
0125                         Row {
0126                             height: parent.height
0127                             Repeater {
0128                                 id: gridRepeater
0129                                 model: root.daysPerRow
0130                                 Item {
0131                                     height: parent.height
0132                                     width: root.dayWidth
0133                                     property var date: DateUtils.addDaysToDate(dayDelegate.startDate, modelData)
0134                                     property bool isInPast: DateUtils.roundToDay(date) < DateUtils.roundToDay(root.currentDate)
0135                                     property bool isToday: DateUtils.sameDay(root.currentDate, date)
0136                                     property bool isCurrentMonth: date.getMonth() == root.month
0137 
0138                                     //Grid
0139                                     Rectangle {
0140                                         anchors.fill: parent
0141                                         visible: root.paintGrid
0142                                         color: Kube.Colors.viewBackgroundColor
0143                                         border.width: 1
0144                                         border.color: Kube.Colors.lightgrey
0145 
0146                                         //Dimm days in the past
0147                                         Rectangle {
0148                                             anchors.fill: parent
0149                                             anchors.margins: 1
0150                                             color: isToday && root.showDayIndicator ? Kube.Colors.activeBackgroundColor : Kube.Colors.buttonColor
0151                                             opacity: isToday && root.showDayIndicator ? 0.2 : 0.4
0152                                             visible: isInPast || (isToday && root.showDayIndicator)
0153                                         }
0154                                     }
0155 
0156                                     MouseArea {
0157                                         anchors.fill: parent
0158                                         onClicked: Kube.Fabric.postMessage(Kube.Messages.eventEditor, {"start": date, "allDay": true})
0159                                     }
0160 
0161                                     //Day number
0162                                     Label {
0163                                         visible: root.showDayIndicator
0164                                         anchors {
0165                                             top: parent.top
0166                                             left: parent.left
0167                                             topMargin: Kube.Units.smallSpacing
0168                                             leftMargin: Kube.Units.smallSpacing
0169                                         }
0170                                         //We add the month abbrevation to the first of each month
0171                                         text: date.toLocaleDateString(Qt.locale(), date.getDate() == 1 ? "d MMM" : "d")
0172                                         font.bold: true
0173                                         color: isToday ? Kube.Colors.highlightColor : (!isCurrentMonth ? Kube.Colors.disabledTextColor : Kube.Colors.textColor)
0174                                     }
0175                                 }
0176                             }
0177                         }
0178 
0179                         Column {
0180                             anchors {
0181                                 fill: parent
0182                                 //Offset for date
0183                                 topMargin: root.showDayIndicator ? Kube.Units.gridUnit + root.verticalSpacing : root.verticalSpacing
0184                             }
0185 
0186                             spacing: root.verticalSpacing
0187 
0188                             Repeater {
0189                                 id: linesRepeater
0190                                 model: events
0191                                 onCountChanged: {
0192                                     root.numberOfLinesShown = count
0193                                 }
0194                                 Item {
0195                                     id: line
0196                                     height: root.lineHeight
0197                                     width: parent.width
0198 
0199                                     //Events
0200                                     Repeater {
0201                                         id: eventsRepeater
0202                                         model: modelData
0203                                         Rectangle {
0204                                             x: root.dayWidth * modelData.starts + root.horizontalSpacing
0205                                             y: 0
0206                                             width: root.dayWidth * modelData.duration - (2 * root.horizontalSpacing)
0207                                             height: parent.height
0208 
0209                                             radius: 2
0210 
0211                                             Rectangle {
0212                                                 anchors.fill: parent
0213                                                 color: modelData.color
0214                                                 radius: parent.radius
0215                                                 border.width: 1
0216                                                 border.color: Kube.Colors.viewBackgroundColor
0217                                                 opacity: 0.6
0218                                             }
0219 
0220                                             Kube.Label {
0221                                                 anchors {
0222                                                     fill: parent
0223                                                     leftMargin: Kube.Units.smallSpacing
0224                                                     rightMargin: Kube.Units.smallSpacing
0225                                                 }
0226                                                 color: Kube.Colors.textColor
0227                                                 text: modelData.text
0228                                                 elide: Text.ElideRight
0229                                                 font.weight: Font.Medium
0230                                             }
0231 
0232                                             MouseArea {
0233                                                 id: mouseArea
0234                                                 anchors.fill: parent
0235                                                 hoverEnabled: true
0236                                                 onClicked: eventDetails.createObject(root, {}).open()
0237                                                 Component {
0238                                                     id: eventDetails
0239                                                     Kube.Popup {
0240                                                         id: popup
0241                                                         parent: ApplicationWindow.overlay
0242                                                         x: Math.round((parent.width - width) / 2)
0243                                                         y: Math.round((parent.height - height) / 2)
0244                                                         width: eventView.implicitWidth
0245                                                         height: eventView.implicitWidth
0246                                                         padding: 0
0247                                                         Rectangle {
0248                                                             anchors.fill: parent
0249                                                             color: Kube.Colors.paperWhite
0250                                                             EventEditor {
0251                                                                 id: eventView
0252                                                                 anchors.fill: parent
0253                                                                 editMode: true
0254                                                                 controller: Kube.EventController {
0255                                                                     eventOccurrence: model.modelData.eventOccurrence
0256                                                                 }
0257                                                                 onDone: popup.close()
0258                                                             }
0259                                                         }
0260                                                     }
0261                                                 }
0262                                             }
0263                                         }
0264                                     }
0265                                 }
0266                             }
0267                         }
0268                     }
0269                 }
0270                 Kube.IconButton {
0271                     id: expandButton
0272                     visible: weekRow.overfilled
0273                     anchors {
0274                         bottom: parent.bottom
0275                         horizontalCenter: parent.horizontalCenter
0276                     }
0277                     checkable: true
0278                     iconName: checked ? Kube.Icons.goUp : Kube.Icons.goDown
0279                     ButtonGroup.group: expandButtonGroup
0280                 }
0281             }
0282         }
0283     }
0284 }