Commit 3236eec7 authored by Dimitris Kardarakos's avatar Dimitris Kardarakos

POC of selecting active calendar and showing all todos from Sink

parent 406dc730
/*
* Copyright 2018 Dimitris Kardarakos <dimkard@posteon.net>
* Copyright 2018 Dimitris Kardarakos <dimkard@posteo.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
......@@ -19,9 +19,9 @@
*/
/**
* Creates the list of actions of 'Calendars' action container
* Creates the list of actions of 'Local Calendars' action container
*/
function loadGlobalActions(calendars, calendarActions, calendarActionComp) {
function createLocalCalendarActions(calendars, calendarActions, calendarActionComp) {
var cfgCalendars = calendars.split(calendars.includes(";") ? ";" : null);
var currentChildren = calendarActions.children;
var newChildren = [];
......@@ -43,3 +43,30 @@ function loadGlobalActions(calendars, calendarActions, calendarActionComp) {
calendarActions.children = newChildren;
}
/**
* Creates the list of actions of 'Online Calendars' action container
*/
function createOnlineCalendarActions(calendars, calendarActions, calendarActionComp) {
var currentChildren = calendarActions.children;
var newChildren = [];
//Preserve non-dynamic actions
for(var i=0; i <currentChildren.length; ++i)
{
if(!(currentChildren[i].hasOwnProperty("isCalendar")))
{
newChildren.push(currentChildren[i]);
}
}
//Add calendars
for (var i=0; i < calendars.length; ++i)
{
console.log("calendars[" + i + "]: " + calendars[i].name + ", " + calendars[i].identifier);
newChildren.push(calendarActionComp.createObject(calendarActions, { text: calendars[i].name, identifier: calendars[i].identifier }));
}
calendarActions.children = newChildren;
}
......@@ -23,27 +23,32 @@ import org.kde.kirigami 2.4 as Kirigami
import org.kde.phone.calindori 0.1 as Calindori
Kirigami.Action {
id: root
property bool isCalendar: true
property bool isOnline: false
property var configuration
property string identifier
signal deleteCalendar
checked: (text == configuration.activeCalendar)
checked: (text == configuration.activeLocalCalendar) || (identifier == configuration.activeOnlineCalendar)
Kirigami.Action {
text: "Activate"
iconName: "dialog-ok"
onTriggered: {
configuration.activeCalendar = parent.text;
configuration.activeLocalCalendar = (root.isOnline) ? "" : parent.text;
configuration.activeOnlineCalendar = (root.isOnline) ? parent.identifier: "";
}
}
Kirigami.Action {
text: "Delete"
iconName: "delete"
visible: !isOnline
onTriggered: (configuration.activeCalendar == parent.text) ? showPassiveNotification("Active calendar cannot be deleted") : deleteCalendar()
onTriggered: (configuration.activeLocalCalendar == parent.text) ? showPassiveNotification("Active calendar cannot be deleted") : deleteCalendar()
}
}
......@@ -28,6 +28,7 @@ import org.kube.framework 1.0 as Kube
Kirigami.ApplicationWindow {
id: root
property alias localCalendar : local_calendar
/**
* To be emitted when data displayed should be refreshed
*/
......@@ -38,26 +39,33 @@ Kirigami.ApplicationWindow {
title: "Calindori"
actions: [
Kirigami.Action {
id: onlineCalendars
text: "Online Calendars"
onTriggered: root.pageStack.push(accountSwitcher);
},
Kirigami.Action {
id: calendarActions
text: "Calendars"
iconName: "view-calendar"
Kirigami.Action {
text: "Add calendar..."
iconName: "list-add"
onTriggered: root.pageStack.push(calendarInputPage);
id: onlineCalendarActions
text: "Online"
}
Kirigami.Action {
separator: true
id: localCalendarActions
text: "Local"
Kirigami.Action {
text: "Add calendar..."
iconName: "list-add"
onTriggered: root.pageStack.push(calendarInputPage);
}
Kirigami.Action {
separator: true
}
}
},
......@@ -77,17 +85,17 @@ Kirigami.ApplicationWindow {
}
Kirigami.Action {
text: "Tasks" + " (" + localCalendar.name + ")"
text: "Tasks"
iconName: "view-calendar-tasks"
onTriggered: {
pageStack.clear();
pageStack.push(todosView, { todoDt: localCalendar.nulldate });
pageStack.push(todosView, { todoDt: localCalendar.nulldate, onlineCalendarFilter: calendarFilter, isOnline: (calindoriConfig.activeOnlineCalendar != ""), calendar: root.localCalendar});
}
}
}
]
Component.onCompleted: Utils.loadGlobalActions(calindoriConfig.calendars, calendarActions, calendarAction)
Component.onCompleted: Utils.createLocalCalendarActions(calindoriConfig.calendars, localCalendarActions, calendarAction)
}
contextDrawer: Kirigami.ContextDrawer {
......@@ -100,14 +108,22 @@ Kirigami.ApplicationWindow {
Calindori.Config {
id: calindoriConfig
onActiveCalendarChanged: Utils.loadGlobalActions(calindoriConfig.calendars, calendarActions, calendarAction)
onCalendarsChanged: Utils.loadGlobalActions(calindoriConfig.calendars, calendarActions, calendarAction)
onActiveLocalCalendarChanged: {
Utils.createLocalCalendarActions(calindoriConfig.calendars, localCalendarActions, calendarAction);
calendarFilter.clearFilter();
}
onActiveOnlineCalendarChanged: {
calendarFilter.clearFilter();
calendarFilter.addFilter(activeOnlineCalendar);
}
onCalendarsChanged: Utils.createLocalCalendarActions(calindoriConfig.calendars, localCalendarActions, calendarAction)
}
Calindori.LocalCalendar {
id: localCalendar
id: local_calendar
name: calindoriConfig.activeCalendar
name: calindoriConfig.activeLocalCalendar
onNameChanged: {
root.refreshNeeded();
......@@ -134,6 +150,18 @@ Kirigami.ApplicationWindow {
}
}
/**
* Action that represents a calendar configuration entry
* It is added dynamically to the global drawer
*/
Component {
id: onlineCalendarAction
CalendarAction {
isOnline: true
configuration: calindoriConfig
}
}
Component {
id: calendarDashboardComponent
......@@ -166,12 +194,12 @@ Kirigami.ApplicationWindow {
text: "Show tasks"
onTriggered: {
if(localCalendar.todosCount(calendarMonthView.selectedDate) > 0) {
root.pageStack.push(todosView, { todoDt: calendarMonthView.selectedDate });
}
else {
showPassiveNotification (i18n("There is no task for the day selected"));
}
// if(localCalendar.todosCount(calendarMonthView.selectedDate) > 0) {
root.pageStack.push(todosView, { todoDt: calendarMonthView.selectedDate, onlineCalendarFilter: calendarFilter, isOnline: (calindoriConfig.activeOnlineCalendar != "") , calendar: root.localCalendar});
// }
// else {
// showPassiveNotification (i18n("There is no task for the day selected"));
// }
}
},
Kirigami.Action {
......@@ -214,7 +242,7 @@ Kirigami.ApplicationWindow {
calendar: localCalendar
onEditTask: root.pageStack.push(todoPage, { startdt: modelData.dtstart, uid: modelData.uid, todoData: modelData })
onEditTask: root.pageStack.push(todoPage, { startdt: modelData.startDate, uid: modelData.uid, todoData: modelData })
onTasksUpdated: root.refreshNeeded()
Connections {
......@@ -229,7 +257,7 @@ Kirigami.ApplicationWindow {
id: todoPage
TodoPage {
calendar: localCalendar
localCalendar: root.localCalendar
onTaskeditcompleted: {
root.refreshNeeded();
root.pageStack.pop(todoPage);
......@@ -267,41 +295,32 @@ Kirigami.ApplicationWindow {
}
}
Component {
id: accountSwitcher
Kirigami.Page {
Kirigami.CardsListView {
id: listView
anchors.fill: parent
model: Kube.EntityModel {
id: calendarModel
type: "calendar"
roles: ["name", "color"]
sortRole: "name"
filter: {"enabled": true}
onInitialItemsLoaded: {
if (currentIndex >= 0) {
root.selected(calendarModel.data(currentIndex).object)
}
}
}
delegate: Kirigami.Card {
contentItem: Controls2.Label {
wrapMode: Text.WordWrap
text: model.name
}
}
Kube.EntityModel {
id: calendarModel
type: "calendar"
roles: ["name", "identifier", "enabled"]
sortRole: "name"
filter: {"enabled": true}
onInitialItemsLoaded: {
var calendarList = [];
for(var i=0; i<calendarModel.rowCount(); ++i) {
calendarList.push(calendarModel.data(i));
}
Utils.createOnlineCalendarActions(calendarList, onlineCalendarActions, onlineCalendarAction)
}
}
Calindori.CalendarFilter {
id: calendarFilter
Component.onCompleted: { //TODO: if config is not loaded, this will not work. we need property binding
clearFilter();
addFilter(calindoriConfig.activeOnlineCalendar);
}
}
ConfirmationSheet {
id: deleteSheet
......
......@@ -34,9 +34,9 @@ Kirigami.Page {
property alias startHour: startTimeSelector.startHour
property alias startMinute: startTimeSelector.startMinutes
property alias allDay: allDaySelector.checked
property alias location: location.text
property string location: "" //location.text
property alias completed: completed.checked
property var calendar
property var localCalendar
property var todoData
property alias timePicker: timePickerSheet
......@@ -53,7 +53,7 @@ Kirigami.Page {
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
font.pointSize: Kirigami.Units.fontMetrics.font.pointSize * 1.2
text: todoData && !isNaN(todoData.dtstart) ? todoData.dtstart.toLocaleDateString(Qt.locale()) : (!isNaN(root.startdt) ? root.startdt.toLocaleDateString(Qt.locale()) : "")
text: todoData && !isNaN(todoData.startDate) ? todoData.startDate.toLocaleDateString(Qt.locale()) : (!isNaN(root.startdt) ? root.startdt.toLocaleDateString(Qt.locale()) : "")
}
Kirigami.FormLayout {
......@@ -66,11 +66,11 @@ Kirigami.Page {
}
Controls2.Label {
id: calendarName
id: localCalendarName
Kirigami.FormData.label: qsTr("Calendar:")
Layout.fillWidth: true
text: root.calendar.name
text: root.localCalendar.name
}
Kirigami.Separator {
......@@ -113,17 +113,17 @@ Kirigami.Page {
text: qsTr("All day")
}
Kirigami.Separator {
Kirigami.FormData.isSection: true
}
Controls2.TextField {
id: location
Layout.fillWidth: true
Kirigami.FormData.label: qsTr("Location:")
text: todoData ? todoData.location : ""
}
// Kirigami.Separator {
// Kirigami.FormData.isSection: true
// }
//
// Controls2.TextField {
// id: location
//
// Layout.fillWidth: true
// Kirigami.FormData.label: qsTr("Location:")
// text: todoData ? todoData.location : ""
// }
}
......@@ -152,7 +152,7 @@ Kirigami.Page {
id: completed
text: qsTr("Completed")
checked: todoData ? todoData.completed: false
checked: todoData ? todoData.complete: false
}
}
......@@ -190,7 +190,7 @@ Kirigami.Page {
onTriggered: {
if(summary.text) {
console.log("Saving task");
root.calendar.addEditTask(root.uid, root.startdt, root.summary, root.description, root.startHour, root.startMinute, root.allDay, root.location, root.completed); //TODO: Pass a Todo object
root.localCalendar.addEditTask(root.uid, root.startdt, root.summary, root.description, root.startHour, root.startMinute, root.allDay, root.location, root.completed); //TODO: Pass a Todo object
taskeditcompleted();
}
else {
......@@ -223,9 +223,9 @@ Kirigami.Page {
Kirigami.OverlaySheet {
id: timePickerSheet
property int hours: todoData ? todoData.dtstart.toLocaleTimeString(Qt.locale(), "hh") % 12 : 0
property int minutes: todoData ? todoData.dtstart.toLocaleTimeString(Qt.locale(), "mm") : 0
property bool pm: (todoData && todoData.dtstart.toLocaleTimeString(Qt.locale(), "hh") > 12) ? true : false
property int hours: todoData ? todoData.startDate.toLocaleTimeString(Qt.locale(), "hh") % 12 : 0
property int minutes: todoData ? todoData.startDate.toLocaleTimeString(Qt.locale(), "mm") : 0
property bool pm: (todoData && todoData.startDate.toLocaleTimeString(Qt.locale(), "hh") > 12) ? true : false
rightPadding: 0
leftPadding: 0
......
......@@ -29,6 +29,8 @@ Kirigami.Page {
property date todoDt
property var calendar
property var onlineCalendarFilter
property string isOnline
signal editTask(var modelData)
signal tasksUpdated
......@@ -50,30 +52,36 @@ Kirigami.Page {
Component {
id: todoPage
TodoPage {
calendar: localCalendar
localCalendar: root.calendar
onTaskeditcompleted: {
tasksUpdated();
pageStack.pop(todoPage);
}
}
}
Kube.CalendarSelector {
id: accountSwitcher
visible: false
}
Calindori.TodosModel {
id: localCalendarModel
filterdt: root.todoDt
memorycalendar: root.calendar.memorycalendar
}
Kube.TodoModel {
id: onlineCalendarModel
calendarFilter: root.onlineCalendarFilter.filter
filter: (root.isOnline =="true" && !isNaN(root.todoDt)) ? {"startDate" : root.todoDt} : {}
}
Kirigami.CardsListView {
id: cardsListview
anchors.fill: parent
// model: Calindori.TodosModel {
// filterdt: root.todoDt
// memorycalendar: root.calendar.memorycalendar
// }
model: Kube.TodoModel {
calendarFilter: accountSwitcher.enabledCalendars
}
model: (isOnline == "true") ? onlineCalendarModel : localCalendarModel
delegate: Kirigami.Card {
banner.title: model.summary
banner.titleLevel: 3
......@@ -99,7 +107,7 @@ Kirigami.Page {
contentItem: Column {
enabled: !model.completed
enabled: !model.complete
Controls2.Label {
wrapMode: Text.WordWrap
......@@ -107,22 +115,24 @@ Kirigami.Page {
}
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()) != ""
visible: model.startDate && !isNaN(model.startDate) //&& model.dtstart.toLocaleTimeString(Qt.locale()) != ""
wrapMode: Text.WordWrap
text: (model.dtstart && !isNaN(model.dtstart)) ? model.dtstart.toLocaleTimeString(Qt.locale(), Locale.ShortFormat) : ""
text: (model.startDate && !isNaN(model.startDate)) ? model.startDate.toLocaleDateString(Qt.locale()) : ""
}
Controls2.Label {
visible: model.location != ""
visible: model.startDate && !isNaN(model.startDate) //&& model.dtstart.toLocaleTimeString(Qt.locale()) != ""
wrapMode: Text.WordWrap
text: model.location
text: (model.startDate && !isNaN(model.startDate)) ? model.startDate.toLocaleTimeString(Qt.locale(), Locale.ShortFormat) : ""
}
//Not supported in Kube models
// Controls2.Label {
// visible: model.location != ""
// wrapMode: Text.WordWrap
// text: model.location
// }
}
}
}
......
......@@ -3,6 +3,7 @@ set(qmlplugin_SRCS
calindoriconfig.cpp
todosmodel.cpp
localcalendar.cpp
calendarfilter.cpp
)
add_library (calindoriqmlplugin SHARED ${qmlplugin_SRCS})
......
/*
* Copyright (C) 2019 Dimitris Kardarakos
*
* This library 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 3 of
* the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "calendarfilter.h"
#include <QDebug>
CalendarFilter::CalendarFilter(QObject* parent): QObject(parent)
{}
CalendarFilter::~CalendarFilter() = default;
QSet<QByteArray> CalendarFilter::filter() const
{
return m_filter;
}
void CalendarFilter::addFilter(const QVariant & calendarId )
{
m_filter.insert(calendarId.toByteArray());
emit filterChanged();
}
void CalendarFilter::clearFilter()
{
m_filter.clear();
emit filterChanged();
}
/*
* Copyright (C) 2019 Dimitris Kardarakos
*
* This library 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 3 of
* the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef CALENDARFILTER_H
#define CALENDARFILTER_H
#include <QObject>
#include <QSet>
#include <QByteArray>
class CalendarFilter : public QObject
{
Q_OBJECT
Q_PROPERTY(QSet<QByteArray> filter READ filter NOTIFY filterChanged)
public:
explicit CalendarFilter(QObject* parent = nullptr);
~CalendarFilter() override;
QSet<QByteArray> filter() const;
public Q_SLOTS:
void addFilter(const QVariant & calendarId) ;
void clearFilter();
Q_SIGNALS:
void filterChanged();
private:
QSet<QByteArray> m_filter;
};
#endif // CALENDARFILTER_H
......@@ -38,7 +38,7 @@ CalindoriConfig::CalindoriConfig(QObject* parent)
if(calendars.isEmpty()) {
qDebug() << "No calendar found, creating a default one";
addCalendar("personal");
setActiveCalendar("personal");
setActiveLocalCalendar("personal");
d->config.sync();
}
}
......@@ -53,17 +53,28 @@ QString CalindoriConfig::calendars() const
return d->config.group("general").readEntry("calendars", QString());
}
QString CalindoriConfig::activeCalendar() const
QString CalindoriConfig::activeLocalCalendar() const
{
return d->config.group("general").readEntry("activeCalendar", QString());
return d->config.group("general").readEntry("activeLocalCalendar", QString());
}
QString CalindoriConfig::activeOnlineCalendar() const
{
return d->config.group("general").readEntry("activeOnlineCalendar", QString());
}
void CalindoriConfig::setActiveLocalCalendar(const QString & calendar)
{
d->config.group("general").writeEntry("activeLocalCalendar", calendar);
d->config.sync();
emit activeLocalCalendarChanged();
}
void CalindoriConfig::setActiveCalendar(const QString & calendar)
void CalindoriConfig::setActiveOnlineCalendar(const QString & calendar)
{
d->config.group("general").writeEntry("activeCalendar", calendar);
d->config.group("general").writeEntry("activeOnlineCalendar", calendar);
d->config.sync();
emit activeCalendarChanged();
emit activeOnlineCalendarChanged();
}
QString CalindoriConfig::addCalendar(const QString & calendar)
......
......@@ -25,7 +25,8 @@ class CalindoriConfig : public QObject
{
Q_OBJECT
Q_PROPERTY(QString calendars READ calendars NOTIFY calendarsChanged)
Q_PROPERTY(QString activeCalendar READ activeCalendar WRITE setActiveCalendar NOTIFY activeCalendarChanged)
Q_PROPERTY(QString activeLocalCalendar READ activeLocalCalendar WRITE setActiveLocalCalendar NOTIFY activeLocalCalendarChanged)
Q_PROPERTY(QString activeOnlineCalendar READ activeOnlineCalendar WRITE setActiveOnlineCalendar NOTIFY activeOnlineCalendarChanged)
public:
explicit CalindoriConfig(QObject* parent = nullptr);
......@@ -34,9 +35,14 @@ public:
QString calendars() const;
Q_SIGNAL void calendarsChanged();
QString activeCalendar() const;
void setActiveCalendar(const QString& calendar);
Q_SIGNAL void activeCalendarChanged();
QString activeLocalCalendar() const;
void setActiveLocalCalendar(const QString& calendar);
Q_SIGNAL void activeLocalCalendarChanged();
QString activeOnlineCalendar() const;
void setActiveOnlineCalendar(const QString& calendar);
Q_SIGNAL void activeOnlineCalendarChanged();
public Q_SLOTS:
QString addCalendar(const QString& calendar);
......
......@@ -49,7 +49,7 @@ QString LocalCalendar::name() const
void LocalCalendar::setName(QString calendarName)
{
if (m_name != calendarName) {
if (m_name != calendarName && calendarName != "") {