Warning, /pim/kube/views/calendar/qml/WeekView.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.4
0021 import QtQuick.Layouts 1.1
0022 import QtQuick.Controls 2.2
0023 
0024 import org.kube.framework 1.0 as Kube
0025 import "dateutils.js" as DateUtils
0026 
0027 FocusScope {
0028     id: root
0029 
0030     property int daysToShow: 7
0031     property var dayWidth: (root.width - Kube.Units.gridUnit - Kube.Units.largeSpacing) / root.daysToShow
0032     property var hourHeight: Kube.Units.gridUnit * 2
0033     property date currentDate
0034     property date startDate: currentDate
0035     property var calendarFilter
0036 
0037     readonly property int horizontalSpacing: Kube.Units.smallSpacing
0038 
0039     Item {
0040         anchors {
0041             top: parent.top
0042             right: parent.right
0043         }
0044 
0045         width: root.dayWidth * root.daysToShow + Kube.Units.gridUnit * 2
0046         height: root.height
0047 
0048         Item {
0049             id: weekNumber
0050             anchors {
0051                 top: parent.top
0052                 left: parent.left
0053             }
0054             width: Kube.Units.gridUnit * 2
0055             height: Kube.Units.gridUnit * 2
0056             Label {
0057                 anchors.centerIn: parent
0058                 text: DateUtils.getWeek(startDate, Qt.locale().firstDayOfWeek)
0059                 font.bold: true
0060             }
0061         }
0062 
0063         MultiDayView {
0064             id: daylong
0065             objectName: "weekView"
0066             anchors {
0067                 top: parent.top
0068                 right: parent.right
0069                 left: parent.left
0070                 leftMargin: Kube.Units.gridUnit * 2
0071             }
0072             horizontalSpacing: root.horizontalSpacing
0073 
0074             dayWidth: root.dayWidth
0075             daysToShow: root.daysToShow
0076             currentDate: root.currentDate
0077             startDate: root.startDate
0078             calendarFilter: root.calendarFilter
0079             filter: {"allDay": true}
0080             paintGrid: true
0081             showDayIndicator: false
0082             dayHeaderDelegate: Item {
0083                 height: Kube.Units.gridUnit + Kube.Units.smallSpacing * 3
0084                 Column {
0085                     anchors.centerIn: parent
0086                     Kube.Label {
0087                         anchors.horizontalCenter: parent.horizontalCenter
0088                         font.bold: true
0089                         text: day.toLocaleString(Qt.locale(), "dddd")
0090                     }
0091                     Kube.Label {
0092                         anchors.horizontalCenter: parent.horizontalCenter
0093                         text: day.toLocaleString(Qt.locale(), "d")
0094                         color: Kube.Colors.disabledTextColor
0095                         font.pointSize: Kube.Units.tinyFontSize
0096                     }
0097                 }
0098             }
0099         }
0100 
0101         Flickable {
0102             id: mainWeekViewer
0103 
0104             anchors {
0105                 top: daylong.bottom
0106                 topMargin: 2
0107             }
0108 
0109             Layout.fillWidth: true
0110             height: root.height - daylong.height - Kube.Units.largeSpacing
0111             width: root.dayWidth * root.daysToShow + Kube.Units.gridUnit * 2
0112 
0113             contentHeight: root.hourHeight * 24
0114             contentWidth: width
0115 
0116             //Position the view starting at 8:00, but with the label visible
0117             contentY: root.hourHeight * 8 - 10
0118 
0119             clip: true
0120             boundsBehavior: Flickable.StopAtBounds
0121 
0122             ScrollBar.vertical: Kube.ScrollBar {}
0123 
0124             Kube.ScrollHelper {
0125                 id: scrollHelper
0126                 flickable: mainWeekViewer
0127                 anchors.fill: parent
0128             }
0129 
0130             Row {
0131                 height: root.hourHeight * 24
0132                 width: root.dayWidth * root.daysToShow + Kube.Units.gridUnit * 2
0133 
0134                 spacing: 0
0135 
0136                 //BEGIN time labels
0137                 Column {
0138                     anchors {
0139                         bottom: parent.bottom
0140                         //offset so the label is center aligned to the line
0141                         bottomMargin: root.hourHeight - Kube.Units.gridUnit / 2
0142                     }
0143                     Repeater {
0144                         model: ["1:00","2:00","3:00","4:00","5:00","6:00","7:00","8:00","9:00","10:00","11:00","12:00",
0145                         "13:00","14:00","15:00","16:00","17:00","18:00","19:00","20:00","21:00","22:00","23:00"]
0146                         delegate: Item {
0147                             height: root.hourHeight
0148                             width: Kube.Units.gridUnit * 2
0149 
0150                             Kube.Label {
0151                                 anchors {
0152                                     right: parent.right
0153                                     rightMargin: Kube.Units.smallSpacing
0154                                     bottom: parent.bottom
0155                                 }
0156                                 text: model.modelData
0157                             }
0158                         }
0159                     }
0160                 }
0161                 //END time labels
0162 
0163                 Repeater {
0164                     model: Kube.PeriodDayEventModel {
0165                         model: Kube.EventOccurrenceModel {
0166                             start: root.startDate
0167                             length: root.daysToShow
0168                             calendarFilter: root.calendarFilter
0169                         }
0170                     }
0171                     delegate: Rectangle {
0172                         id: dayDelegate
0173 
0174                         width: root.dayWidth
0175                         height: root.hourHeight * 24
0176 
0177 
0178                         color: Kube.Colors.viewBackgroundColor
0179 
0180                         property bool isInPast: DateUtils.roundToDay(root.currentDate) > DateUtils.roundToDay(date)
0181                         property bool isToday: DateUtils.sameDay(root.currentDate, date)
0182                         property var todaysDate: date
0183 
0184                         //Dimm days in the past
0185                         Rectangle {
0186                             anchors.fill: parent
0187                             color: Kube.Colors.buttonColor
0188                             opacity: 0.4
0189                             visible: isInPast
0190                         }
0191 
0192                         //Grid
0193                         Column {
0194                             anchors.fill: parent
0195                             Repeater {
0196                                 model: 12
0197                                 delegate: Rectangle {
0198                                     height: root.hourHeight * 2
0199                                     width: parent.width
0200                                     color: "transparent"
0201                                     border.width: 1
0202                                     border.color: Kube.Colors.lightgrey
0203                                     MouseArea {
0204                                         anchors.fill: parent
0205                                         onClicked: {
0206                                             var d = dayDelegate.todaysDate
0207                                             var hours = index * 2
0208                                             var minuteOffset = 120 / parent.height * mouse.y
0209                                             var minutes = minuteOffset % 60
0210                                             hours += (minuteOffset - minutes) / 60
0211                                             d.setHours(hours)
0212                                             d.setMinutes(minutes)
0213                                             Kube.Fabric.postMessage(Kube.Messages.eventEditor, {"start": d, "allDay": false})
0214                                         }
0215                                     }
0216                                 }
0217                             }
0218                         }
0219 
0220                         Repeater {
0221                             model: events
0222 
0223                             delegate: Rectangle {
0224                                 id: eventDelegate
0225 
0226                                 states: [
0227                                 State {
0228                                     name: "dnd"
0229                                     when: mouseArea.drag.active
0230 
0231                                     PropertyChanges {target: mouseArea; cursorShape: Qt.ClosedHandCursor}
0232                                     PropertyChanges {target: eventDelegate; x: x; y: y}
0233                                     PropertyChanges {target: eventDelegate; parent: root}
0234                                     PropertyChanges {target: eventDelegate; opacity: 0.7}
0235                                     PropertyChanges {target: eventDelegate; anchors.right: ""}
0236                                     PropertyChanges {target: eventDelegate; width: root.dayWidth - Kube.Units.smallSpacing * 2}
0237                                 }
0238                                 ]
0239 
0240                                 anchors {
0241                                     right: parent.right
0242                                     rightMargin: Kube.Units.smallSpacing
0243                                 }
0244                                 radius: 2
0245                                 width: root.dayWidth - root.horizontalSpacing * 2 - Kube.Units.gridUnit * model.modelData.indentation
0246                                 height: Math.max(root.hourHeight * 0.5, root.hourHeight * model.modelData.duration)
0247                                 y: root.hourHeight * model.modelData.starts
0248                                 x: Kube.Units.gridUnit * model.modelData.indentation
0249                                 z: model.modelData.indentation
0250 
0251                                 Rectangle {
0252                                     anchors.fill: parent
0253                                     color: model.modelData.color
0254                                     opacity: 0.6
0255                                     border.width: 1
0256                                     border.color: Kube.Colors.viewBackgroundColor
0257                                     radius: 2
0258                                 }
0259 
0260                                 Column {
0261                                     anchors {
0262                                         top: parent.top
0263                                         left: parent.left
0264                                         right: parent.right
0265                                         bottom: parent.bottom
0266                                         leftMargin: Kube.Units.smallSpacing
0267                                         rightMargin: Kube.Units.smallSpacing
0268                                     }
0269                                     Kube.Label {
0270                                         anchors {
0271                                             left: parent.left
0272                                             right: parent.right
0273                                         }
0274                                         text: model.modelData.text
0275                                         color: Kube.Colors.textColor
0276                                         font.weight: Font.Medium
0277                                         wrapMode: Text.Wrap
0278                                         elide: Text.ElideRight
0279                                         //Only show two lines if we have either space for three or there is no dateLabel
0280                                         maximumLineCount: model.modelData.duration >= (dateLabel.visible ? 2.0 : 1.0) ? 2 : 1
0281                                     }
0282                                     Kube.Label {
0283                                         id: dateLabel
0284                                         anchors {
0285                                             left: parent.left
0286                                             right: parent.right
0287                                         }
0288                                         visible: model.modelData.duration >= 1.0 && model.modelData.startDate
0289                                         text: model.modelData.startDate.toLocaleString(Qt.locale(), "hh:mm")
0290                                         font.pointSize: Kube.Units.smallFontSize
0291                                         color: Kube.Colors.textColor
0292                                         elide: Text.ElideRight
0293                                     }
0294                                 }
0295 
0296                                 Drag.active: mouseArea.drag.active
0297                                 Drag.hotSpot.x: mouseArea.mouseX
0298                                 Drag.hotSpot.y: mouseArea.mouseY
0299                                 Drag.source: eventDelegate
0300 
0301                                 MouseArea {
0302                                     id: mouseArea
0303                                     anchors.fill: parent
0304 
0305                                     hoverEnabled: true
0306                                     drag.target: parent
0307 
0308                                     onReleased: eventDelegate.Drag.drop()
0309                                     onClicked: eventDetails.createObject(root, {}).open()
0310 
0311                                     Component {
0312                                         id: eventDetails
0313                                         Kube.Popup {
0314                                             id: popup
0315                                             parent: ApplicationWindow.overlay
0316                                             x: Math.round((parent.width - width) / 2)
0317                                             y: Math.round((parent.height - height) / 2)
0318                                             width: Math.min(eventView.implicitWidth, parent.width - 2 * Kube.Units.gridUnit)
0319                                             height: Math.min(eventView.implicitHeight, parent.height - 2 * Kube.Units.gridUnit)
0320                                             padding: 0
0321                                             Rectangle {
0322                                                 anchors.fill: parent
0323                                                 color: Kube.Colors.paperWhite
0324                                                 EventEditor {
0325                                                     id: eventView
0326                                                     anchors.fill: parent
0327                                                     editMode: true
0328                                                     controller: Kube.EventController {
0329                                                         eventOccurrence: model.modelData.eventOccurrence
0330                                                     }
0331                                                     onDone: popup.close()
0332                                                 }
0333                                             }
0334                                         }
0335                                     }
0336                                 }
0337                             }
0338                         }
0339 
0340                         Rectangle {
0341                             id: currentTimeLine
0342                             anchors {
0343                                 right: parent.right
0344                                 left: parent.left
0345                             }
0346                             y: root.hourHeight * root.currentDate.getHours() + root.hourHeight / 60 * root.currentDate.getMinutes()
0347                             height: 2
0348                             color: Kube.Colors.plasmaBlue
0349                             visible: isToday
0350                             opacity: 0.8
0351                             Rectangle {
0352                                 anchors {
0353                                     verticalCenter: parent.verticalCenter
0354                                     left: parent.left
0355                                     leftMargin: -(width / 2)
0356                                 }
0357                                 width: Kube.Units.gridUnit / 2
0358                                 height: width
0359                                 radius: width / 2
0360                                 color: Kube.Colors.plasmaBlue
0361                                 opacity: 1
0362                             }
0363                         }
0364 
0365 
0366                         DropArea {
0367                             anchors.fill: parent
0368 
0369                             onDropped: {
0370                                 console.log("DROP")
0371                                 drop.accept(Qt.MoveAction)
0372                                 //drop.source.visible = false
0373                                 console.log((drop.source.y - mainWeekViewer.y + mainWeekViewer.contentY) / hourHeight)
0374                             }
0375                         }
0376                     }
0377                 }
0378             }
0379         }
0380     }
0381 }