Commit 54bdcb4b authored by Dimitris Kardarakos's avatar Dimitris Kardarakos

Event view and event editor added to calendar

parent af0686d0
/*
* Copyright 2018 Dimitris Kardarakos <dimkard@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 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 Library General Public License for more details
*
* You should have received a copy of the GNU Library 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.0
import QtQuick.Controls 2.4 as Controls2
import QtQuick.Layouts 1.11
import org.kde.kirigami 2.4 as Kirigami
import org.kde.phone.calindori 0.1 as Calindori
Kirigami.Page {
id: root
property date startdt
property string uid
property alias summary: summary.text
property alias description: description.text
property alias startHour: startTimeSelector.startHour
property alias startMinute: startTimeSelector.startMinutes
property alias allDay: allDaySelector.checked
property alias location: location.text
property var calendar
property var eventData
property alias timePicker: timePickerSheet
// property alias enddt: endDateSelector.endDate TODO
// property alias endHour: endTimeSelector.endHour TODO
// property alias endMinute: endTimeSelector.endMinutes TODO
signal editcompleted
title: qsTr("Event")
ColumnLayout {
anchors.centerIn: parent
Controls2.Label {
visible: root.startdt != undefined && !isNaN(root.startdt)
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
font.pointSize: Kirigami.Units.fontMetrics.font.pointSize * 1.2
text: eventData && !isNaN(eventData.dtstart) ? eventData.dtstart.toLocaleDateString(Qt.locale()) : (!isNaN(root.startdt) ? root.startdt.toLocaleDateString(Qt.locale()) : "")
}
Kirigami.FormLayout {
id: eventCard
enabled: !root.completed
Kirigami.Separator {
Kirigami.FormData.isSection: true
}
Controls2.Label {
id: calendarName
Kirigami.FormData.label: qsTr("Calendar:")
Layout.fillWidth: true
text: root.calendar.name
}
Kirigami.Separator {
Kirigami.FormData.isSection: true
}
Controls2.TextField {
id: summary
Layout.fillWidth: true
Kirigami.FormData.label: qsTr("Summary:")
text: eventData ? eventData.summary : ""
}
RowLayout {
Kirigami.FormData.label: qsTr("Start time:")
enabled: root.startdt != undefined && !isNaN(root.startdt)
Controls2.ToolButton {
id: startTimeSelector
property int startHour: timePickerSheet.hours + (timePickerSheet.pm ? 12 : 0)
property int startMinutes: timePickerSheet.minutes
property date startTime: root.startdt
text: !isNaN(startdt) ? (new Date(startdt.getFullYear(), startdt.getMonth() , startdt.getDate(), startHour, startMinutes)).toLocaleTimeString(Qt.locale(), "hh:mm"): "00:00"
enabled: !allDaySelector.checked
onClicked: timePickerSheet.open()
}
}
Controls2.CheckBox {
id: allDaySelector
enabled: !isNaN(root.startdt)
checked: eventData ? eventData.allday: false
text: qsTr("All day")
}
Kirigami.Separator {
Kirigami.FormData.isSection: true
}
Controls2.TextField {
id: location
Layout.fillWidth: true
Kirigami.FormData.label: qsTr("Location:")
text: eventData ? eventData.location : ""
}
}
Kirigami.Separator {
Layout.fillWidth: true
}
Controls2.TextArea {
id: description
Layout.fillWidth: true
Layout.minimumWidth: Kirigami.Units.gridUnit * 4
Layout.minimumHeight: Kirigami.Units.gridUnit * 4
wrapMode: Controls2.TextArea.WordWrap
text: eventData ? eventData.description : ""
placeholderText: qsTr("Description")
}
}
actions {
left: Kirigami.Action {
id: cancelAction
text: qsTr("Cancel")
icon.name : "dialog-cancel"
onTriggered: {
editcompleted();
}
}
main: Kirigami.Action {
id: info
text: qsTr("Info")
icon.name : "documentinfo"
onTriggered: {
showPassiveNotification("Please save or cancel this event");
}
}
right: Kirigami.Action {
id: saveAction
text: qsTr("Save")
icon.name : "dialog-ok"
onTriggered: {
if(summary.text) {
console.log("Saving event, root.startdt:" + startdt);
root.calendar.addEditEvent( { "uid" : root.uid, "startDate": root.startdt, "summary": root.summary, "description": root.description, "startHour": root.startHour, "startMinute": root.startMinute, "allDay": root.allDay, "location": root.location }) ;
editcompleted();
}
else {
showPassiveNotification("Summary should not be empty");
}
}
}
//TODO
// contextualActions: [
// Kirigami.Action {
// iconName:"editor"
// text: "Edit Start Date"
//
// onTriggered: showPassiveNotification("Edit start date")
//
// }
// ,
// Kirigami.Action { //TODO: Do we needed it?
// iconName:"delete"
// text: "Clear Start Date"
//
// onTriggered: {
// root.startdt = new Date("No Date");
// }
// }
// ]
}
Kirigami.OverlaySheet {
id: timePickerSheet
property int hours: eventData ? eventData.dtstart.toLocaleTimeString(Qt.locale(), "hh") % 12 : 0
property int minutes: eventData ? eventData.dtstart.toLocaleTimeString(Qt.locale(), "mm") : 0
property bool pm: (eventData && eventData.dtstart.toLocaleTimeString(Qt.locale(), "hh") > 12) ? true : false
rightPadding: 0
leftPadding: 0
contentItem: TimePicker {
id: timePicker
hours: timePickerSheet.hours
minutes: timePickerSheet.minutes
pm: timePickerSheet.pm
}
footer: RowLayout {
Item {
Layout.fillWidth: true
}
Controls2.ToolButton {
text: qsTr("OK")
onClicked: {
timePickerSheet.hours = timePicker.hours
timePickerSheet.minutes = timePicker.minutes
timePickerSheet.pm = timePicker.pm
timePickerSheet.close()
}
}
Controls2.ToolButton {
text: qsTr("Cancel")
onClicked: {
timePicker.hours = timePickerSheet.hours
timePicker.minutes = timePickerSheet.minutes
timePickerSheet.close()
}
}
}
}
}
/*
* Copyright 2018 Dimitris Kardarakos <dimkard@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 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 Library General Public License for more details
*
* You should have received a copy of the GNU Library 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.0
import QtQuick.Controls 2.4 as Controls2
import QtQuick.Layouts 1.11
import org.kde.kirigami 2.4 as Kirigami
import org.kde.phone.calindori 0.1 as Calindori
Kirigami.Page {
id: root
property date eventDt
property var calendar
signal editEvent(var modelData)
signal eventsUpdated
function reload()
{
cardsListview.model.loadEvents();
}
title: qsTr("Events")
actions.main: Kirigami.Action {
icon.name: "resource-calendar-insert"
text: qsTr("Add event")
onTriggered: pageStack.push(eventEditor, {startdt: eventStartDt})
}
Component {
id: eventEditor
EventEditor {
calendar: localCalendar
onEditcompleted: {
eventsUpdated();
pageStack.pop(eventEditor);
}
}
}
Kirigami.CardsListView {
id: cardsListview
anchors.fill: parent
model: Calindori.EventModel {
filterdt: root.eventStartDt
memorycalendar: root.calendar.memorycalendar
}
delegate: Kirigami.Card {
banner.title: model.summary
banner.titleLevel: 3
actions: [
Kirigami.Action {
text: qsTr("Delete")
icon.name: "delete"
onTriggered: {
root.calendar.deleteEvent(model.uid);
eventsUpdated();
}
},
Kirigami.Action {
text: qsTr("Edit")
icon.name: "editor"
onTriggered: root.editEvent(model)
}
]
contentItem: Column {
Controls2.Label {
wrapMode: Text.WordWrap
text: model.description
}
Controls2.Label {
visible: model.dtstart && !isNaN(model.dtstart) //&& model.dtstart.toLocaleTimeString(Qt.locale()) != ""
wrapMode: Text.WordWrap
text: (model.dtstart && !isNaN(model.dtstart)) ? model.dtstart.toLocaleDateString(Qt.locale()) : ""
}
Controls2.Label {
visible: model.dtstart && !isNaN(model.dtstart) //&& model.dtstart.toLocaleTimeString(Qt.locale()) != ""
wrapMode: Text.WordWrap
text: (model.dtstart && !isNaN(model.dtstart)) ? model.dtstart.toLocaleTimeString(Qt.locale(), Locale.ShortFormat) : ""
}
Controls2.Label {
visible: model.location != ""
wrapMode: Text.WordWrap
text: model.location
}
}
}
}
}
......@@ -172,6 +172,26 @@ Kirigami.ApplicationWindow {
text: "Add task"
onTriggered: root.pageStack.push(todoPage, { startdt: calendarMonthView.selectedDate} )
},
Kirigami.Action {
iconName: "view-calendar-events"
text: "Show events"
onTriggered: {
// if(localCalendar.eventsCount(calendarMonthView.selectedDate) > 0) { //TODO: Implement eventsCount
root.pageStack.push(eventsView, { eventDt: calendarMonthView.selectedDate });
// }
// else {
// showPassiveNotification (i18n("There is no event for the day selected"));
// }
}
},
Kirigami.Action {
iconName: "resource-calendar-insert"
text: "Add event"
onTriggered: root.pageStack.push(eventEditor, { startdt: calendarMonthView.selectedDate} )
}
]
}
......@@ -218,6 +238,24 @@ Kirigami.ApplicationWindow {
}
}
Component {
id: eventsView
EventsView {
calendar: localCalendar
onEditEvent: root.pageStack.push(eventEditor, { startdt: modelData.dtstart, uid: modelData.uid, eventData: modelData })
onEventsUpdated: root.refreshNeeded()
Connections {
target: root
onRefreshNeeded: reload()
}
}
}
Component {
id: todoPage
......@@ -230,6 +268,18 @@ Kirigami.ApplicationWindow {
}
}
Component {
id: eventEditor
EventEditor {
calendar: localCalendar
onEditcompleted: {
root.refreshNeeded();
root.pageStack.pop(eventEditor);
}
}
}
Component {
id: calendarInputPage
......
......@@ -83,8 +83,30 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
{
case Uid :
return m_events.at(index.row())->uid();
case DtStart:
return m_events.at(index.row())->dtStart();
case AllDay:
return m_events.at(index.row())->allDay();
case Description:
return m_events.at(index.row())->description();
case Summary:
return m_events.at(index.row())->summary();
case LastModified:
return m_events.at(index.row())->lastModified();
case Location:
return m_events.at(index.row())->location();
case Categories:
return m_events.at(index.row())->categories();
case Priority:
return m_events.at(index.row())->priority();
case Created:
return m_events.at(index.row())->created();
case Secrecy:
return m_events.at(index.row())->secrecy();
case EndDate:
return m_events.at(index.row())->dtEnd();
case Transparency:
return m_events.at(index.row())->transparency();
default:
return QVariant();
}
......
......@@ -169,3 +169,71 @@ QDateTime LocalCalendar::nulldate() const
{
return QDateTime();
}
void LocalCalendar::addEditEvent(const QVariantMap& eventObject)
{
if ( m_calendar == nullptr)
{
qDebug() << "Calendar not initialized, cannot add/edit events";
return;
}
qDebug() << "Creating event";
QDateTime now = QDateTime::currentDateTime();
Event::Ptr event;
QString uid = eventObject["uid"].value<QString>();
QString summary = eventObject["summary"].value<QString>();
if (uid == "") {
event = Event::Ptr(new Event());
event->setUid(summary.left(1) + now.toString("yyyyMMddhhmmsszzz"));
}
else {
event = m_calendar->event(uid);
event->setUid(uid);
}
QDate startDate = eventObject["startDate"].value<QDate>();
int startHour = eventObject["startHour"].value<int>();
int startMinute = eventObject["startMinute"].value<int>();
QDateTime startDateTime;
bool allDayFlg= eventObject["allDay"].value<bool>();
if(allDayFlg) {
startDateTime = QDateTime(startDate);
}
else {
startDateTime = QDateTime(startDate, QTime(startHour, startMinute, 0, 0), QTimeZone::systemTimeZone());
}
event->setDtStart(startDateTime);
event->setDescription(eventObject["description"].value<QString>());
event->setSummary(summary);
event->setAllDay(allDayFlg);
event->setLocation(eventObject["location"].value<QString>());
m_calendar->addEvent(event);
bool success = m_cal_storage->save();
qDebug() << "Saving event object: " << success;
}
void LocalCalendar::deleteEvent(QString uid) {
qDebug() << "Deleting event: " << uid;
Event::Ptr event = m_calendar->event(uid);
m_calendar->deleteEvent(event);
bool success = m_cal_storage->save();
qDebug() << "Event deleted? " << success;
}
int LocalCalendar::eventsCount(const QDate& date) const {
if(m_calendar == nullptr)
{
return 0;
}
Event::List eventList = m_calendar->rawEventsForDate(date);
return eventList.count();
}
......@@ -22,6 +22,7 @@
#include <QSharedPointer>
#include <KCalCore/MemoryCalendar>
#include <KCalCore/FileStorage>
#include <KCalCore/Event>
using namespace KCalCore;
......@@ -52,6 +53,9 @@ public Q_SLOTS:
int todosCount(const QDate &date) const;
void deleteCalendar();
void addEditEvent(const QVariantMap& eventObject);
void deleteEvent(QString uid);
int eventsCount(const QDate& date) const;
Q_SIGNALS:
void memorycalendarChanged();
void calendarstorageChanged();
......
......@@ -14,5 +14,7 @@
<file alias="Utils.js">contents/code/Utils.js</file>
<file alias="CalendarAction.qml">contents/ui/CalendarAction.qml</file>
<file alias="ConfirmationSheet.qml">contents/ui/ConfirmationSheet.qml</file>
<file alias="EventsView.qml">contents/ui/EventsView.qml</file>
<file alias="EventEditor.qml">contents/ui/EventEditor.qml</file>
</qresource>
</RCC>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment