diff --git a/views/calendar/qml/EventEditor.qml b/views/calendar/qml/EventEditor.qml index 1f572d47..0f897a7b 100644 --- a/views/calendar/qml/EventEditor.qml +++ b/views/calendar/qml/EventEditor.qml @@ -1,228 +1,216 @@ /* * Copyright (C) 2018 Michael Bohlender, * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.4 import QtQuick.Layouts 1.1 import org.kube.framework 1.0 as Kube -Kube.Popup { +Item { id: root property var controller: Kube.EventController {} property bool editMode: false property date start: new Date() - width: contentLayout.implicitWidth + 2 * Kube.Units.largeSpacing - height: contentLayout.implicitHeight + 2 * Kube.Units.largeSpacing - - Item { - - states: [ - State { - name: "edit" - PropertyChanges { target: deleteButton; visible: true } - PropertyChanges { target: abortButton; visible: false } - PropertyChanges { target: saveButton; visible: true } - PropertyChanges { target: discardButton; visible: true } - PropertyChanges { target: createButton; visible: false } - PropertyChanges { target: calendarSelector; visible: false } - }, - State { - name: "new" - PropertyChanges { target: deleteButton; visible: false } - PropertyChanges { target: abortButton; visible: true } - PropertyChanges { target: saveButton; visible: false } - PropertyChanges { target: discardButton; visible: false } - PropertyChanges { target: createButton; visible: true } - PropertyChanges { target: calendarSelector; visible: true } - } - ] + signal done() + + implicitWidth: contentLayout.implicitWidth + 2 * Kube.Units.largeSpacing + implicitHeight: contentLayout.implicitHeight + buttons.implicitHeight + 2 * Kube.Units.largeSpacing + + states: [ + State { + name: "edit" + PropertyChanges { target: deleteButton; visible: true } + PropertyChanges { target: abortButton; visible: false } + PropertyChanges { target: saveButton; visible: true } + PropertyChanges { target: discardButton; visible: true } + PropertyChanges { target: createButton; visible: false } + PropertyChanges { target: calendarSelector; visible: false } + }, + State { + name: "new" + PropertyChanges { target: deleteButton; visible: false } + PropertyChanges { target: abortButton; visible: true } + PropertyChanges { target: saveButton; visible: false } + PropertyChanges { target: discardButton; visible: false } + PropertyChanges { target: createButton; visible: true } + PropertyChanges { target: calendarSelector; visible: true } + } + ] + + state: editMode ? "edit" : "new" - state: editMode ? "edit" : "new" + ColumnLayout { + id: contentLayout - anchors.fill: parent + anchors { + fill: parent + margins: Kube.Units.largeSpacing + } - Item { - id: eventEditor + spacing: Kube.Units.largeSpacing - anchors.fill: parent + ColumnLayout { - ColumnLayout { + spacing: Kube.Units.largeSpacing - anchors { - top: parent.top - left: parent.left - right: parent.right - bottom: buttons.top - bottomMargin: Kube.Units.largeSpacing - } + Kube.TextField { + id: titleEdit + Layout.fillWidth: true + placeholderText: qsTr("Event Title") + text: controller.summary + onTextChanged: controller.summary = text + } - spacing: Kube.Units.largeSpacing + ColumnLayout { + id: dateAndTimeChooser + spacing: Kube.Units.smallSpacing - Kube.TextField { - id: titleEdit + RowLayout { Layout.fillWidth: true - placeholderText: qsTr("Event Title") - text: controller.summary - onTextChanged: controller.summary = text + spacing: Kube.Units.largeSpacing + DateTimeChooser { + id: startDate + objectName: "startDate" + enableTime: !controller.allDay + initialValue: root.editMode ? controller.start : root.start + onDateTimeChanged: controller.start = dateTime + } + Kube.Label { + text: qsTr("until") + } + DateTimeChooser { + id: endDate + objectName: "endDate" + enableTime: !controller.allDay + notBefore: startDate.dateTime + initialValue: root.editMode ? controller.end : startDate.dateTime + onDateTimeChanged: controller.end = dateTime + } } - ColumnLayout { - id: dateAndTimeChooser - + RowLayout { spacing: Kube.Units.smallSpacing - - RowLayout { - Layout.fillWidth: true - spacing: Kube.Units.largeSpacing - DateTimeChooser { - id: startDate - objectName: "startDate" - enableTime: !controller.allDay - initialValue: root.editMode ? controller.start : root.start - onDateTimeChanged: controller.start = dateTime - } - Kube.Label { - text: qsTr("until") - } - DateTimeChooser { - id: endDate - objectName: "endDate" - enableTime: !controller.allDay - notBefore: startDate.dateTime - initialValue: root.editMode ? controller.end : startDate.dateTime - onDateTimeChanged: controller.end = dateTime - } - } - - RowLayout { - spacing: Kube.Units.smallSpacing - Kube.CheckBox { + Kube.CheckBox { + onClicked: { + checked: controller.allDay onClicked: { - checked: controller.allDay - onClicked: { - controller.allDay = !controller.allDay - } + controller.allDay = !controller.allDay } } - Kube.Label { - text: qsTr("All day") - } + } + Kube.Label { + text: qsTr("All day") } } + } - ColumnLayout { - spacing: Kube.Units.smallSpacing + ColumnLayout { + spacing: Kube.Units.smallSpacing + Layout.fillWidth: true + //FIXME location doesn't exist yet + // Kube.TextField { + // Layout.fillWidth: true + // placeholderText: qsTr("Location") + // text: controller.location + // onTextChanged: controller.location = text + // } + + Kube.TextEditor { Layout.fillWidth: true - //FIXME location doesn't exist yet - // Kube.TextField { - // Layout.fillWidth: true - // placeholderText: qsTr("Location") - // text: controller.location - // onTextChanged: controller.location = text - // } - - Kube.TextEditor { - Layout.fillWidth: true - Layout.fillHeight: true - //TODO placeholderText: "Description" - text: controller.description - onTextChanged: controller.description = text - } - - Kube.ComboBox { - id: calendarSelector - Layout.fillWidth: true + Layout.fillHeight: true + Layout.minimumHeight: Kube.Units.gridUnit * 4 - model: Kube.EntityModel { - id: calendarModel - type: "calendar" - roles: ["name"] - } - textRole: "name" - onActivated: { - controller.calendar = calendarModel.data(index).object - } - } + //TODO placeholderText: "Description" + text: controller.description + onTextChanged: controller.description = text } - } - RowLayout { - anchors { - bottom: parent.bottom - left: parent.left - } + Kube.ComboBox { + id: calendarSelector + Layout.fillWidth: true - Kube.Button { - id: deleteButton - text: qsTr("Delete") - onClicked: { - controller.remove() - root.close() + model: Kube.EntityModel { + id: calendarModel + type: "calendar" + roles: ["name"] } - } - Kube.Button { - id: abortButton - text: qsTr("Abort") - onClicked: { - root.close() + textRole: "name" + onActivated: { + controller.calendar = calendarModel.data(index).object } } } + } + + RowLayout { + id: buttons - RowLayout { - id: buttons + spacing: Kube.Units.smallSpacing - anchors { - bottom: parent.bottom - right: parent.right + Kube.Button { + id: deleteButton + text: qsTr("Delete") + onClicked: { + controller.remove() + root.done() } + } - spacing: Kube.Units.smallSpacing + Kube.Button { + id: abortButton + text: qsTr("Abort") + onClicked: { + root.done() + } + } - Kube.Button { - id: discardButton - text: qsTr("Discard Changes") - onClicked: { - root.close() - } + Item { + Layout.fillWidth: true + } + + Kube.Button { + id: discardButton + text: qsTr("Discard Changes") + onClicked: { + root.done() } + } - Kube.PositiveButton { - id: saveButton - text: qsTr("Save Changes") - onClicked: { - controller.saveAction.execute() - root.close() - } + Kube.PositiveButton { + id: saveButton + text: qsTr("Save Changes") + onClicked: { + controller.saveAction.execute() + root.done() } + } - Kube.PositiveButton { - id: createButton - text: qsTr("Create Event") - onClicked: { - controller.saveAction.execute() - root.close() - } + Kube.PositiveButton { + id: createButton + text: qsTr("Create Event") + onClicked: { + controller.saveAction.execute() + root.done() } } } } } diff --git a/views/calendar/qml/EventView.qml b/views/calendar/qml/EventView.qml index d28a1e51..d847225e 100644 --- a/views/calendar/qml/EventView.qml +++ b/views/calendar/qml/EventView.qml @@ -1,106 +1,111 @@ /* * Copyright (C) 2018 Michael Bohlender, * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.4 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.3 import org.kube.framework 1.0 as Kube FocusScope { id: root property var controller - width: contentLayout.implicitWidth + 2 * Kube.Units.largeSpacing - height: contentLayout.implicitHeight + 2 * Kube.Units.largeSpacing - - Rectangle { - anchors { - fill: parent - } - color: Kube.Colors.viewBackgroundColor - - ColumnLayout { - id: contentLayout - anchors { - centerIn: parent - } - - spacing: Kube.Units.smallSpacing + width: stackView.width + height: stackView.height + + signal done() + + StackView { + id: stackView + anchors.centerIn: parent + width: stackView.currentItem.implicitWidth + height: stackView.currentItem.implicitHeight + initialItem: eventDetails + clip: true + } - Kube.Heading { - width: parent.width - text: controller.summary - } + Component { + id: eventDetails + Rectangle { + implicitWidth: contentLayout.implicitWidth + 2 * Kube.Units.largeSpacing + implicitHeight: contentLayout.implicitHeight + 2 * Kube.Units.largeSpacing + color: Kube.Colors.viewBackgroundColor + + ColumnLayout { + id: contentLayout + anchors { + centerIn: parent + } - Kube.Label { - visible: controller.allDay - text: controller.start.toLocaleString(Qt.locale(), "dd. MMMM") + " - " + controller.end.toLocaleString(Qt.locale(), "dd. MMMM") - } - Kube.Label { - visible: !controller.allDay - text: controller.start.toLocaleString(Qt.locale(), "dd. MMMM hh:mm") + " - " + controller.end.toLocaleString(Qt.locale(), "dd. MMMM hh:mm") - } + spacing: Kube.Units.smallSpacing - Kube.Label { - text: controller.description - } + Kube.Heading { + width: parent.width + text: controller.summary + } - Item { - width: 1 - height: Kube.Units.largeSpacing - } + Kube.Label { + visible: controller.allDay + text: controller.start.toLocaleString(Qt.locale(), "dd. MMMM") + " - " + controller.end.toLocaleString(Qt.locale(), "dd. MMMM") + } + Kube.Label { + visible: !controller.allDay + text: controller.start.toLocaleString(Qt.locale(), "dd. MMMM hh:mm") + " - " + controller.end.toLocaleString(Qt.locale(), "dd. MMMM hh:mm") + } - RowLayout { - Kube.Button { - text: qsTr("Remove") - onClicked: { - root.controller.remove() - } + Kube.Label { + text: controller.description } + Item { - Layout.fillWidth: true + width: 1 + height: Kube.Units.largeSpacing } - Kube.Button { - text: qsTr("Edit") - onClicked: { - editor.createObject(root, {}).open() + + RowLayout { + Kube.Button { + text: qsTr("Remove") + onClicked: { + root.controller.remove() + } + } + Item { + Layout.fillWidth: true + } + Kube.Button { + text: qsTr("Edit") + onClicked: { + stackView.push(editor) + } } - } + } } } } Component { id: editor - EventEditor { - - width: 800 - height: 400 - - parent: ApplicationWindow.overlay - x: Math.round((parent.width - width) / 2) - y: Math.round((parent.height - height) / 2) - controller: root.controller editMode: true + onDone: root.done() } } } diff --git a/views/calendar/qml/MultiDayView.qml b/views/calendar/qml/MultiDayView.qml index 28f6463e..6f3e7410 100644 --- a/views/calendar/qml/MultiDayView.qml +++ b/views/calendar/qml/MultiDayView.qml @@ -1,232 +1,234 @@ /* * Copyright (C) 2018 Michael Bohlender, * Copyright (C) 2018 Christian Mollekopf, * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.4 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.2 import org.kube.framework 1.0 as Kube import "dateutils.js" as DateUtils Item { id: root property int daysToShow property int daysPerRow: daysToShow property double weekHeaderWidth: 0 property double dayWidth: (width - weekHeaderWidth) / daysPerRow property date currentDate property date startDate property var calendarFilter property bool paintGrid: false property bool showDayIndicator: false property var filter property alias dayHeaderDelegate: dayLabels.delegate property Component weekHeaderDelegate property int month //Internal property int numberOfLinesShown: 0 property int numberOfRows: (daysToShow / daysPerRow) property var dayHeight: (height - dayLabels.height) / numberOfRows implicitHeight: (numberOfRows > 1 ? Kube.Units.gridUnit * 10 * numberOfRows: numberOfLinesShown * Kube.Units.gridUnit) + dayLabels.height height: implicitHeight Column { anchors { fill: parent } DayLabels { id: dayLabels startDate: root.startDate dayWidth: root.dayWidth daysToShow: root.daysPerRow } //Weeks Repeater { model: Kube.MultiDayEventModel { model: Kube.EventModel { start: root.startDate length: root.daysToShow calendarFilter: root.calendarFilter filter: root.filter ? root.filter : {} } // daysPerRow: root.daysPerRow //Hardcoded to 7 } //One row => one week Item { width: parent.width height: root.dayHeight clip: true Row { width: parent.width height: parent.height Loader { id: weekHeader height: parent.height sourceComponent: root.weekHeaderDelegate property var startDate: weekStartDate onStatusChanged: if (weekHeader.status == Loader.Ready) root.weekHeaderWidth = item.width } Item { id: dayDelegate height: root.dayHeight width: parent.width - weekHeader.width property var startDate: weekStartDate //Grid Row { height: parent.height Repeater { id: gridRepeater model: root.daysPerRow Item { height: parent.height width: root.dayWidth property var date: DateUtils.addDaysToDate(dayDelegate.startDate, modelData) property bool isInPast: DateUtils.roundToDay(date) < DateUtils.roundToDay(root.currentDate) property bool isToday: DateUtils.sameDay(root.currentDate, date) property bool isCurrentMonth: date.getMonth() == root.month //Dimm days in the past Rectangle { anchors.fill: parent color: Kube.Colors.buttonColor opacity: 0.2 visible: isInPast } //Grid Rectangle { anchors.fill: parent visible: root.paintGrid color: "transparent" border.width: 1 border.color: Kube.Colors.lightgrey } //Day number Label { visible: root.showDayIndicator anchors { top: parent.top left: parent.left topMargin: Kube.Units.smallSpacing leftMargin: Kube.Units.smallSpacing } text: date.getDate() font.bold: true color: !isCurrentMonth ? Kube.Colors.disabledTextColor : Kube.Colors.textColor Rectangle { anchors { left: parent.left right: parent.right bottom: parent.bottom } width: Kube.Units.gridUnit height: 3 color: Kube.Colors.plasmaBlue opacity: 0.6 visible: isToday } } } } } Column { anchors { fill: parent //Offset for date topMargin: root.showDayIndicator ? Kube.Units.gridUnit + Kube.Units.smallSpacing : 0 } Repeater { id: linesRepeater model: events onCountChanged: { root.numberOfLinesShown = count } Item { id: line height: Kube.Units.gridUnit width: parent.width //Events Repeater { id: eventsRepeater model: modelData Rectangle { x: root.dayWidth * modelData.starts y: 0 width: root.dayWidth * modelData.duration height: parent.height color: modelData.color radius: 2 border.width: 1 border.color: Kube.Colors.viewBackgroundColor Kube.Label { anchors { fill: parent leftMargin: Kube.Units.smallSpacing rightMargin: Kube.Units.smallSpacing } color: Kube.Colors.highlightedTextColor text: modelData.text elide: Text.ElideRight } MouseArea { id: mouseArea anchors.fill: parent hoverEnabled: true onClicked: eventDetails.createObject(root, {}).open() Component { id: eventDetails Kube.Popup { + id: popup parent: ApplicationWindow.overlay x: Math.round((parent.width - width) / 2) y: Math.round((parent.height - height) / 2) width: eventView.width height: eventView.height padding: 0 EventView { id: eventView controller: Kube.EventController { event: modelData.event } + onDone: popup.close() } } } } } } } } } } } } } } } diff --git a/views/calendar/qml/View.qml b/views/calendar/qml/View.qml index 81bfe767..52721ea2 100644 --- a/views/calendar/qml/View.qml +++ b/views/calendar/qml/View.qml @@ -1,335 +1,340 @@ /* * Copyright (C) 2018 Michael Bohlender, * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.9 import QtQuick.Controls 2 import QtQuick.Layouts 1.2 import org.kube.framework 1.0 as Kube import "dateutils.js" as DateUtils Kube.View { id: root property date currentDate: new Date() property date selectedDate: getFirstDayOfWeek(currentDate) property bool autoUpdateDate: true Kube.CheckedEntities { id: calendarFilterCollector } onSelectedDateChanged: { console.log("Selected date changed", selectedDate) } onRefresh: { Kube.Fabric.postMessage(Kube.Messages.synchronize, {"type": "calendar"}) Kube.Fabric.postMessage(Kube.Messages.synchronize, {"type": "event"}) } function getFirstDayOfWeek(date) { var firstDay = Qt.locale().firstDayOfWeek var year = date.getFullYear() var month = date.getMonth() //Jup, getDate returns the day of the month var day = date.getDate() while (true) { if (date.getDay() === firstDay) { return date } day = day - 1 date = new Date(year, month, day) } return date } function getFirstDayOfMonth(date) { var d = date d.setDate(1) return d } RowLayout { Timer { running: autoUpdateDate interval: 2000; repeat: true onTriggered: root.currentDate = new Date() } Rectangle { Layout.fillHeight: true width: Kube.Units.gridUnit * 10 color: Kube.Colors.darkBackgroundColor Column { id: topLayout anchors { top: parent.top left: parent.left right: parent.right margins: Kube.Units.largeSpacing } spacing: Kube.Units.largeSpacing Kube.PositiveButton { id: newEventButton objectName: "newEventButton" anchors { left: parent.left right: parent.right } focus: true text: qsTr("New Event") onClicked: eventPopup.createObject(root, {}).open() } RowLayout { anchors { left: parent.left right: parent.right } spacing: Kube.Units.smallSpacing ButtonGroup { id: viewButtonGroup } Kube.TextButton { id: weekViewButton Layout.fillWidth: true text: qsTr("Week") textColor: Kube.Colors.highlightedTextColor checkable: true checked: true ButtonGroup.group: viewButtonGroup onCheckedChanged: { if (checked) { root.selectedDate = getFirstDayOfWeek(root.selectedDate) } } } Kube.TextButton { id: monthViewButton Layout.fillWidth: true text: qsTr("Month") textColor: Kube.Colors.highlightedTextColor checkable: true ButtonGroup.group: viewButtonGroup onCheckedChanged: { if (checked) { root.selectedDate = getFirstDayOfMonth(root.selectedDate) } } } } DateView { anchors { left: parent.left right: parent.right } date: root.currentDate MouseArea { anchors.fill: parent onClicked: root.selectedDate = root.currentDate } } DateSelector { id: dateSelector anchors { left: parent.left right: parent.right } selectedDate: root.selectedDate onSelected: { if (weekViewButton.checked) { root.selectedDate = getFirstDayOfWeek(date) } else { root.selectedDate = getFirstDayOfMonth(date) } } onNext: { if (weekViewButton.checked) { root.selectedDate = DateUtils.nextWeek(root.selectedDate) } else { root.selectedDate = DateUtils.nextMonth(root.selectedDate) } } onPrevious: { if (weekViewButton.checked) { root.selectedDate = DateUtils.previousWeek(root.selectedDate) } else { root.selectedDate = DateUtils.previousMonth(root.selectedDate) } } } } Kube.InlineAccountSwitcher { id: accountSwitcher //Grow from the button but don't go over topLayout anchors { bottom: statusBarContainer.top left: topLayout.left right: parent.right bottomMargin: Kube.Units.largeSpacing rightMargin: Kube.Units.largeSpacing } height: parent.height - (topLayout.y + topLayout.height) - Kube.Units.largeSpacing - anchors.bottomMargin - statusBarContainer.height delegate: Kube.ListView { id: listView spacing: Kube.Units.smallSpacing model: Kube.CheckableEntityModel { id: calendarModel type: "calendar" roles: ["name", "color", "enabled"] sortRole: "name" accountId: listView.parent.accountId checkedEntities: calendarFilterCollector } delegate: Kube.ListDelegate { id: delegate width: listView.availableWidth height: Kube.Units.gridUnit hoverEnabled: true background: Item {} RowLayout { anchors.fill: parent spacing: Kube.Units.smallSpacing Kube.CheckBox { id: checkBox opacity: 0.9 checked: model.checked || model.enabled onCheckedChanged: { model.checked = checked model.enabled = checked } indicator: Rectangle { width: Kube.Units.gridUnit * 0.8 height: Kube.Units.gridUnit * 0.8 color: model.color Rectangle { id: highlight anchors.fill: parent visible: checkBox.hovered || checkBox.visualFocus color: Kube.Colors.highlightColor opacity: 0.4 } Kube.Icon { anchors.centerIn: parent height: Kube.Units.gridUnit width: Kube.Units.gridUnit visible: checkBox.checked iconName: Kube.Icons.checkbox_inverted } } } Kube.Label { id: label Layout.fillWidth: true text: model.name color: Kube.Colors.highlightedTextColor elide: Text.ElideLeft clip: true } ToolTip { id: toolTipItem visible: delegate.hovered && label.truncated text: label.text } } } } } Item { id: statusBarContainer anchors { topMargin: Kube.Units.smallSpacing bottom: parent.bottom left: parent.left right: parent.right } height: childrenRect.height Rectangle { id: border visible: statusBar.visible anchors { right: parent.right left: parent.left margins: Kube.Units.smallSpacing } height: 1 color: Kube.Colors.viewBackgroundColor opacity: 0.3 } Kube.StatusBar { id: statusBar accountId: accountSwitcher.currentAccount height: Kube.Units.gridUnit * 2 anchors { top: border.bottom left: statusBarContainer.left right: statusBarContainer.right } } } } WeekView { visible: weekViewButton.checked Layout.fillHeight: true Layout.fillWidth: true currentDate: root.currentDate startDate: root.selectedDate calendarFilter: calendarFilterCollector.checkedEntities } MonthView { visible: monthViewButton.checked Layout.fillHeight: true Layout.fillWidth: true currentDate: root.currentDate startDate: getFirstDayOfWeek(getFirstDayOfMonth(root.selectedDate)) month: root.selectedDate.getMonth() calendarFilter: calendarFilterCollector.checkedEntities } } Component { id: eventPopup - EventEditor { + Kube.Popup { + id: popup x: root.width * 0.15 y: root.height * 0.15 width: root.width * 0.7 height: root.height * 0.7 - - start: root.selectedDate + padding: 0 + EventEditor { + anchors.fill: parent + start: root.selectedDate + onDone: popup.close() + } } } } diff --git a/views/calendar/qml/WeekView.qml b/views/calendar/qml/WeekView.qml index 8c5e1645..2b51396c 100644 --- a/views/calendar/qml/WeekView.qml +++ b/views/calendar/qml/WeekView.qml @@ -1,307 +1,309 @@ /* * Copyright (C) 2018 Michael Bohlender, * Copyright (C) 2018 Christian Mollekopf, * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.4 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.2 import org.kube.framework 1.0 as Kube import "dateutils.js" as DateUtils FocusScope { id: root property int daysToShow: 7 property var dayWidth: (root.width - Kube.Units.gridUnit - Kube.Units.largeSpacing * 2) / root.daysToShow property var hourHeight: Kube.Units.gridUnit * 2 property date currentDate property date startDate: currentDate property var calendarFilter Item { anchors { top: parent.top right: parent.right rightMargin: Kube.Units.largeSpacing } width: root.dayWidth * root.daysToShow + Kube.Units.gridUnit * 2 height: root.height Item { id: weekNumber anchors { top: parent.top left: parent.left } width: Kube.Units.gridUnit * 2 height: Kube.Units.gridUnit * 2 Label { anchors.centerIn: parent text: DateUtils.getWeek(startDate, Qt.locale().firstDayOfWeek) font.bold: true } } MultiDayView { id: daylong anchors { top: parent.top right: parent.right left: parent.left leftMargin: Kube.Units.gridUnit * 2 } dayWidth: root.dayWidth daysToShow: root.daysToShow currentDate: root.currentDate startDate: root.startDate calendarFilter: root.calendarFilter filter: {"allDay": true} paintGrid: true showDayIndicator: false dayHeaderDelegate: Item { height: Kube.Units.gridUnit + Kube.Units.smallSpacing * 3 Column { anchors.centerIn: parent Kube.Label { anchors.horizontalCenter: parent.horizontalCenter font.bold: true text: day.toLocaleString(Qt.locale(), "dddd") } Kube.Label { anchors.horizontalCenter: parent.horizontalCenter text: day.toLocaleString(Qt.locale(), "d") color: Kube.Colors.disabledTextColor font.pointSize: Kube.Units.tinyFontSize } } } } Flickable { id: mainWeekViewer anchors { top: daylong.bottom } Layout.fillWidth: true height: root.height - daylong.height - Kube.Units.largeSpacing width: root.dayWidth * root.daysToShow + Kube.Units.gridUnit * 2 contentHeight: root.hourHeight * 24 contentWidth: width clip: true boundsBehavior: Flickable.StopAtBounds ScrollBar.vertical: Kube.ScrollBar {} Kube.ScrollHelper { id: scrollHelper flickable: mainWeekViewer anchors.fill: parent } Row { height: root.hourHeight * 24 width: root.dayWidth * root.daysToShow + Kube.Units.gridUnit * 2 spacing: 0 //BEGIN time labels Column { anchors.bottom: parent.bottom Repeater { 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", "13:00","14:00","15:00","16:00","17:00","18:00","19:00","20:00","21:00","22:00","23:00","0:00"] delegate: Item { height: root.hourHeight width: Kube.Units.gridUnit * 2 Kube.Label { anchors { right: parent.right rightMargin: Kube.Units.smallSpacing bottom: parent.bottom } text: model.modelData } } } } //END time labels Repeater { model: Kube.PeriodDayEventModel { model: Kube.EventModel { start: root.startDate length: root.daysToShow calendarFilter: root.calendarFilter } } delegate: Rectangle { id: dayDelegate width: root.dayWidth height: root.hourHeight * 24 clip: true color: Kube.Colors.viewBackgroundColor property bool isInPast: DateUtils.roundToDay(root.currentDate) > DateUtils.roundToDay(date) property bool isToday: DateUtils.sameDay(root.currentDate, date) //Dimm days in the past Rectangle { anchors.fill: parent color: Kube.Colors.buttonColor opacity: 0.2 visible: isInPast } //Grid Column { anchors.fill: parent Repeater { model: 12 delegate: Rectangle { height: root.hourHeight * 2 width: parent.width color: "transparent" border.width: 1 border.color: Kube.Colors.lightgrey } } } Repeater { model: events delegate: Rectangle { id: eventDelegate states: [ State { name: "dnd" when: mouseArea.drag.active PropertyChanges {target: mouseArea; cursorShape: Qt.ClosedHandCursor} PropertyChanges {target: eventDelegate; x: x; y: y} PropertyChanges {target: eventDelegate; parent: root} PropertyChanges {target: eventDelegate; opacity: 0.7} PropertyChanges {target: eventDelegate; anchors.right: ""} PropertyChanges {target: eventDelegate; width: root.dayWidth - Kube.Units.smallSpacing * 2} } ] anchors { right: parent.right rightMargin: Kube.Units.smallSpacing } radius: 2 width: root.dayWidth - Kube.Units.smallSpacing * 2 - Kube.Units.gridUnit * model.modelData.indentation height: Math.max(root.hourHeight * 0.5, root.hourHeight * model.modelData.duration) y: root.hourHeight * model.modelData.starts x: Kube.Units.gridUnit * model.modelData.indentation color: model.modelData.color border.width: 1 border.color: Kube.Colors.viewBackgroundColor Kube.Label { anchors { fill: parent leftMargin: Kube.Units.smallSpacing rightMargin: Kube.Units.smallSpacing } text: model.modelData.text color: Kube.Colors.highlightedTextColor wrapMode: Text.Wrap elide: Text.ElideRight } Drag.active: mouseArea.drag.active Drag.hotSpot.x: mouseArea.mouseX Drag.hotSpot.y: mouseArea.mouseY Drag.source: eventDelegate MouseArea { id: mouseArea anchors.fill: parent hoverEnabled: true drag.target: parent onReleased: eventDelegate.Drag.drop() onClicked: eventDetails.createObject(root, {}).open() Component { id: eventDetails Kube.Popup { + id: popup parent: ApplicationWindow.overlay x: Math.round((parent.width - width) / 2) y: Math.round((parent.height - height) / 2) width: eventView.width height: eventView.height padding: 0 EventView { id: eventView controller: Kube.EventController { event: model.modelData.event } + onDone: popup.close() } } } } } } Rectangle { id: currentTimeLine anchors { right: parent.right left: parent.left } y: root.hourHeight * root.currentDate.getHours() + root.hourHeight / 60 * root.currentDate.getMinutes() height: 2 color: Kube.Colors.plasmaBlue visible: isToday opacity: 0.8 } DropArea { anchors.fill: parent onDropped: { console.log("DROP") drop.accept(Qt.MoveAction) //drop.source.visible = false console.log((drop.source.y - mainWeekViewer.y + mainWeekViewer.contentY) / hourHeight) } } } } } } } }