Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
PIM
KDE PIM Add-ons
Commits
3ac4586e
Commit
3ac4586e
authored
May 30, 2016
by
Daniel Vrátil
🤖
Browse files
Merge branch 'dev/plasmacalendarplugin'
parents
d8ce6626
6b0d0019
Changes
46
Hide whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
3ac4586e
...
...
@@ -54,6 +54,7 @@ find_package(KF5Config ${KF5_VERSION} CONFIG REQUIRED)
find_package
(
KF5DBusAddons
${
KF5_VERSION
}
CONFIG REQUIRED
)
find_package
(
KF5AkonadiNotes
${
AKONADINOTES_LIB_VERSION
}
CONFIG REQUIRED
)
find_package
(
KF5XmlGui
${
KF5_VERSION
}
CONFIG REQUIRED
)
find_package
(
KF5Declarative
${
KF5_VERSION
}
CONFIG REQUIRED
)
set
(
MAILCOMMN_LIB_VERSION
"5.2.40"
)
set
(
GRAVATAR_LIB_VERSION
"5.2.40"
)
...
...
@@ -69,6 +70,7 @@ set(GRAVATAR_LIB_VERSION "5.2.40")
set
(
INCIDENCEEDITOR_LIB_VERSION
"5.2.40"
)
set
(
KTNEF_LIB_VERSION
"5.2.40"
)
set
(
MESSAGELIB_LIB_VERSION
"5.2.62"
)
set
(
AKONADICALENDAR_LIB_VERSION
"5.2.40"
)
find_package
(
KF5WebEngineViewer
${
MESSAGELIB_LIB_VERSION
}
CONFIG REQUIRED
)
find_package
(
KF5MailCommon
${
MAILCOMMN_LIB_VERSION
}
CONFIG REQUIRED
)
...
...
@@ -85,6 +87,7 @@ find_package(KF5MessageList ${MESSAGELIB_LIB_VERSION} CONFIG REQUIRED)
find_package
(
KF5CalendarSupport
${
CALENDARSUPPORT_LIB_VERSION
}
CONFIG REQUIRED
)
find_package
(
KF5EventViews
${
EVENTVIEW_LIB_VERSION
}
CONFIG REQUIRED
)
find_package
(
KF5Akonadi
${
AKONADI_VERSION
}
CONFIG REQUIRED
)
find_package
(
KF5AkonadiCalendar
${
AKONADICALENDAR_LIB_VERSION
}
CONFIG REQUIRED
)
find_package
(
KF5Gravatar
${
GRAVATAR_LIB_VERSION
}
CONFIG REQUIRED
)
find_package
(
KF5Tnef
${
KTNEF_LIB_VERSION
}
CONFIG REQUIRED
)
...
...
kdepim-addons.categories
View file @
3ac4586e
...
...
@@ -16,3 +16,5 @@ log_externalscriptplugin kdepim-addons (External Script Plugin)
log_text_calendar kdepim-addons (messageviewer calendar plugins)
log_ms_tnef kdepim-addons (ms_tnef)
log_vcard kdepim-addons (vcard)
log_pimeventsplugin kdepim-addons (Plasma calendar plugin)
plugins/CMakeLists.txt
View file @
3ac4586e
...
...
@@ -3,5 +3,6 @@ add_subdirectory(messageviewerplugins)
add_subdirectory
(
messageviewerheaderplugins
)
add_subdirectory
(
storageservices
)
add_subdirectory
(
messageviewer
)
add_subdirectory
(
plasma
)
add_subdirectory
(
webengineurlinterceptor
)
plugins/plasma/CMakeLists.txt
0 → 100644
View file @
3ac4586e
add_subdirectory
(
pimeventsplugin
)
plugins/plasma/pimeventsplugin/CMakeLists.txt
0 → 100644
View file @
3ac4586e
if
(
BUILD_TESTING
)
add_subdirectory
(
autotests
)
endif
()
set
(
pimeventsplugin_SRCS
pimeventsplugin.cpp
akonadipimdatasource.cpp
eventdatavisitor.cpp
settingschangenotifier.cpp
)
ecm_qt_declare_logging_category
(
loggingcategory_SRCS
HEADER pimeventsplugin_debug.h
IDENTIFIER PIMEVENTSPLUGIN_LOG
CATEGORY_NAME log_pimeventsplugin
)
add_library
(
pimevents MODULE
${
pimeventsplugin_SRCS
}
${
loggingcategory_SRCS
}
)
target_link_libraries
(
pimevents
Qt5::Core
KF5::AkonadiCore
KF5::AkonadiCalendar
KF5::CalendarCore
KF5::CalendarEvents
KF5::EventViews
# for reading KOrganizer calendar colors
)
install
(
TARGETS pimevents
DESTINATION
${
PLUGIN_INSTALL_DIR
}
/plasmacalendarplugins
)
######################### NEXT TARGET #######################33
set
(
plasmapimcalendarsplugin_SRCS
pimcalendarsplugin.cpp
pimcalendarsmodel.cpp
settingschangenotifier.cpp
)
add_library
(
pimcalendarsplugin SHARED
${
plasmapimcalendarsplugin_SRCS
}
${
loggingcategory_SRCS
}
)
target_link_libraries
(
pimcalendarsplugin
Qt5::Core
Qt5::Qml
KF5::AkonadiCore
KF5::CalendarCore
)
install
(
TARGETS pimcalendarsplugin
DESTINATION
${
KDE_INSTALL_QMLDIR
}
/org/kde/plasma/PimCalendars
)
install
(
FILES qmldir
DESTINATION
${
KDE_INSTALL_QMLDIR
}
/org/kde/plasma/PimCalendars
)
install
(
FILES PimEventsConfig.qml
DESTINATION
${
PLUGIN_INSTALL_DIR
}
/plasmacalendarplugins/pimevents
)
plugins/plasma/pimeventsplugin/PimEventsConfig.qml
0 → 100644
View file @
3ac4586e
/*
* Copyright 2016 Daniel Vrátil <dvratil@kde.org>
*
* 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) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* 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, see <http://www.gnu.org/licenses/>
*/
import
QtQuick
2.0
import
QtQuick
.
Controls
1.4
// gives us TextSingleton
import
QtQuick
.
Controls
.
Private
1.0
import
QtQuick
.
Layouts
1.0
import
QtQuick
.
Dialogs
1.1
import
org
.
kde
.
plasma
.
core
2.0
import
org
.
kde
.
plasma
.
PimCalendars
1.0
Item
{
id
:
pimEventsConfig
width
:
parent
.
width
height
:
parent
.
height
signal
configurationChanged
function
saveConfig
()
{
calendarModel
.
saveConfig
();
}
PimCalendarsModel
{
id
:
calendarModel
}
// Invisible, used to measure implicitHeight of checkboxes so we can
// adjust row height in rowDelegate
CheckBox
{
id
:
checkboxSize
visible
:
false
}
TreeView
{
id
:
calendarTreeView
;
anchors.fill
:
parent
model
:
calendarModel
TableViewColumn
{
role
:
"
data
"
title
:
"
Select Calendars
"
;
delegate
:
Item
{
CheckBox
{
id
:
checkbox
visible
:
styleData
.
value
[
"
enabled
"
]
checked
:
styleData
.
value
[
"
checked
"
]
onCheckedChanged
:
{
if
(
checked
==
styleData
.
value
[
"
checked
"
])
{
return
;
}
calendarModel
.
setChecked
(
styleData
.
value
[
"
id
"
],
checked
);
pimEventsConfig
.
configurationChanged
();
}
width
:
24
height
:
24
}
IconItem
{
id
:
icon
anchors.left
:
checkbox
.
visible
?
checkbox
.
right
:
parent
.
left
visible
:
valid
source
:
styleData
.
value
[
"
iconName
"
]
height
:
20
width
:
20
}
Text
{
anchors.left
:
icon
.
visible
?
icon
.
right
:
checkbox
.
visible
?
checkbox
.
right
:
parent
.
left
text
:
styleData
.
value
[
"
name
"
]
horizontalAlignment
:
Qt
.
AlignLeft
verticalAlignment
:
Qt
.
AlignVCenter
color
:
styleData
.
textColor
height
:
24
}
}
}
// Based on Desktop.TableViewStyle
rowDelegate
:
BorderImage
{
visible
:
styleData
.
selected
||
styleData
.
alternate
source
:
"
image://__tablerow/
"
+
(
styleData
.
alternate
?
"
alternate_
"
:
""
)
+
(
styleData
.
selected
?
"
selected_
"
:
""
)
+
(
calendarTreeView
.
activeFocus
?
"
active
"
:
""
)
// Make sure the checkbox always fits, add 4 for some small margin
height
:
Math
.
min
(
checkboxSize
.
implicitHeight
,
Math
.
max
(
16
,
TextSingleton
.
implicitHeight
*
1.2
))
+
4
border
{
left
:
4
right
:
4
}
}
}
}
plugins/plasma/pimeventsplugin/akonadipimdatasource.cpp
0 → 100644
View file @
3ac4586e
/*
* Copyright (C) 2016 Daniel Vrátil <dvratil@kde.org>
*
* 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.
*
*/
#include
"akonadipimdatasource.h"
#include
"settingschangenotifier.h"
#include
"pimeventsplugin_debug.h"
#include
<AkonadiCore/ChangeRecorder>
#include
<AkonadiCore/ItemFetchScope>
#include
<AkonadiCore/EntityDisplayAttribute>
#include
<AkonadiCore/CollectionColorAttribute>
#include
<AkonadiCore/AttributeFactory>
#include
<Akonadi/Calendar/ETMCalendar>
#include
<KSharedConfig>
#include
<KConfigGroup>
#include
<KCoreConfigSkeleton>
#include
<EventViews/Prefs>
AkonadiPimDataSource
::
AkonadiPimDataSource
(
QObject
*
parent
)
:
QObject
(
parent
)
{
Akonadi
::
AttributeFactory
::
registerAttribute
<
Akonadi
::
CollectionColorAttribute
>
();
connect
(
SettingsChangeNotifier
::
self
(),
&
SettingsChangeNotifier
::
settingsChanged
,
this
,
&
AkonadiPimDataSource
::
onSettingsChanged
);
mMonitor
=
new
Akonadi
::
ChangeRecorder
(
this
);
mMonitor
->
setChangeRecordingEnabled
(
false
);
mMonitor
->
itemFetchScope
().
fetchFullPayload
(
true
);
mMonitor
->
itemFetchScope
().
fetchAttribute
<
Akonadi
::
EntityDisplayAttribute
>
();
mMonitor
->
itemFetchScope
().
fetchAttribute
<
Akonadi
::
CollectionColorAttribute
>
();
onSettingsChanged
();
mCalendar
=
new
Akonadi
::
ETMCalendar
(
mMonitor
,
this
);
// TOOD: Only retrieve PLD:HEAD once it's supported
mCalendar
->
setCollectionFilteringEnabled
(
false
);
// Would be nice to have a proper API to read KOrganizer calendar colors...
KSharedConfig
::
Ptr
config
=
KSharedConfig
::
openConfig
(
QStringLiteral
(
"korganizerrc"
));
KCoreConfigSkeleton
*
skel
=
new
KCoreConfigSkeleton
(
config
);
mEventViewsPrefs
=
EventViews
::
PrefsPtr
(
new
EventViews
::
Prefs
(
skel
));
mEventViewsPrefs
->
readConfig
();
}
AkonadiPimDataSource
::~
AkonadiPimDataSource
()
{
}
qint64
AkonadiPimDataSource
::
akonadiIdForIncidence
(
const
KCalCore
::
Incidence
::
Ptr
&
incidence
)
const
{
return
mCalendar
->
item
(
incidence
).
id
();
}
KCalCore
::
Calendar
*
AkonadiPimDataSource
::
calendar
()
const
{
return
mCalendar
;
}
QString
AkonadiPimDataSource
::
calendarColorForIncidence
(
const
KCalCore
::
Incidence
::
Ptr
&
incidence
)
const
{
const
auto
&
item
=
mCalendar
->
item
(
incidence
);
if
(
!
item
.
isValid
())
{
return
QString
();
}
const
auto
&
col
=
mCalendar
->
collection
(
item
.
parentCollection
().
id
());
if
(
!
col
.
isValid
())
{
return
QString
();
}
auto
it
=
mColorCache
.
find
(
col
.
id
());
if
(
it
==
mColorCache
.
end
())
{
if
(
col
.
hasAttribute
<
Akonadi
::
CollectionColorAttribute
>
())
{
const
auto
attr
=
col
.
attribute
<
Akonadi
::
CollectionColorAttribute
>
();
it
=
mColorCache
.
insert
(
col
.
id
(),
attr
->
color
().
name
());
}
else
{
QColor
color
=
mEventViewsPrefs
->
resourceColorKnown
(
QString
::
number
(
col
.
id
()));
if
(
color
.
isValid
())
{
it
=
mColorCache
.
insert
(
col
.
id
(),
color
.
name
());
}
else
{
it
=
mColorCache
.
insert
(
col
.
id
(),
QString
());
}
}
}
return
(
*
it
);
}
void
AkonadiPimDataSource
::
onSettingsChanged
()
{
QSet
<
Akonadi
::
Collection
>
currentCols
;
Q_FOREACH
(
const
Akonadi
::
Collection
&
col
,
mMonitor
->
collectionsMonitored
())
{
currentCols
.
insert
(
col
);
}
auto
config
=
KSharedConfig
::
openConfig
();
auto
group
=
config
->
group
(
"PIMEventsPlugin"
);
const
QList
<
qint64
>
calendars
=
group
.
readEntry
(
QStringLiteral
(
"calendars"
),
QList
<
qint64
>
());
QSet
<
Akonadi
::
Collection
>
configuredCols
;
Q_FOREACH
(
qint64
colId
,
calendars
)
{
configuredCols
.
insert
(
Akonadi
::
Collection
(
colId
));
}
Q_FOREACH
(
const
Akonadi
::
Collection
&
col
,
(
currentCols
-
configuredCols
))
{
mMonitor
->
setCollectionMonitored
(
col
,
false
);
}
Q_FOREACH
(
const
Akonadi
::
Collection
&
col
,
(
configuredCols
-
currentCols
))
{
mMonitor
->
setCollectionMonitored
(
col
,
true
);
}
const
bool
hasSelectedCols
=
mMonitor
->
collectionsMonitored
().
isEmpty
();
mMonitor
->
setMimeTypeMonitored
(
KCalCore
::
Event
::
eventMimeType
(),
hasSelectedCols
);
mMonitor
->
setMimeTypeMonitored
(
KCalCore
::
Todo
::
todoMimeType
(),
hasSelectedCols
);
}
plugins/plasma/pimeventsplugin/akonadipimdatasource.h
0 → 100644
View file @
3ac4586e
/*
* Copyright (C) 2016 Daniel Vrátil <dvratil@kde.org>
*
* 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.
*
*/
#ifndef AKONADIPIMDATASOURCE_H
#define AKONADIPIMDATASOURCE_H
#include
"pimdatasource.h"
#include
<QObject>
#include
<EventViews/Prefs>
namespace
Akonadi
{
class
ChangeRecorder
;
class
ETMCalendar
;
}
class
AkonadiPimDataSource
:
public
QObject
,
public
PimDataSource
{
Q_OBJECT
public:
explicit
AkonadiPimDataSource
(
QObject
*
parent
=
Q_NULLPTR
);
~
AkonadiPimDataSource
();
qint64
akonadiIdForIncidence
(
const
KCalCore
::
Incidence
::
Ptr
&
incidence
)
const
Q_DECL_OVERRIDE
;
KCalCore
::
Calendar
*
calendar
()
const
Q_DECL_OVERRIDE
;
QString
calendarColorForIncidence
(
const
KCalCore
::
Incidence
::
Ptr
&
incidence
)
const
Q_DECL_OVERRIDE
;
private
Q_SLOTS
:
void
onSettingsChanged
();
private:
Akonadi
::
ChangeRecorder
*
mMonitor
;
Akonadi
::
ETMCalendar
*
mCalendar
;
EventViews
::
PrefsPtr
mEventViewsPrefs
;
mutable
QHash
<
qint64
,
QString
>
mColorCache
;
};
#endif
plugins/plasma/pimeventsplugin/autotests/CMakeLists.txt
0 → 100644
View file @
3ac4586e
macro
(
add_plasma_pimeventsplugin_test _source _additional
)
set
(
_test
${
_source
}
${
_additional
}
testdataparser.cpp
fakepimdatasource.cpp
${
CMAKE_CURRENT_BINARY_DIR
}
/../pimeventsplugin_debug.cpp
)
get_filename_component
(
_name
${
_source
}
NAME_WE
)
add_executable
(
${
_name
}
${
_test
}
)
add_test
(
${
_name
}
${
_name
}
)
ecm_mark_as_test
(
plasma-pimeventsplugin-
${
_name
}
)
add_definitions
(
-DQT_TESTCASE_BUILDDIR=\"
${
CMAKE_CURRENT_SOURCE_DIR
}
\"
)
target_link_libraries
(
${
_name
}
Qt5::Core
Qt5::Test
KF5::AkonadiCore
KF5::AkonadiCalendar
KF5::CalendarCore
KF5::CalendarEvents
KF5::EventViews
)
include_directories
(
${
CMAKE_CURRENT_SOURCE_DIR
}
/..
${
CMAKE_CURRENT_BINARY_DIR
}
/..
)
endmacro
()
add_plasma_pimeventsplugin_test
(
eventdatavisitortest.cpp ../eventdatavisitor.cpp
)
add_plasma_pimeventsplugin_test
(
pimeventsplugintest.cpp
"../eventdatavisitor.cpp;../pimeventsplugin.cpp;../akonadipimdatasource.cpp;../settingschangenotifier.cpp"
)
plugins/plasma/pimeventsplugin/autotests/data/allday-multiday-event.ics
0 → 100644
View file @
3ac4586e
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTAMP:20160529T143409Z
CREATED:20160529T143351Z
UID:43f8fa38-6794-4862-a389-11e78d1ad584
LAST-MODIFIED:20160529T143409Z
DESCRIPTION:This is an all-day multi-day event
SUMMARY:Multi day all day event
DTSTART;VALUE=DATE:20160528
DTEND;VALUE=DATE:20160531
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
plugins/plasma/pimeventsplugin/autotests/data/allday-multiday-event.json
0 → 100644
View file @
3ac4586e
{
"rangeStart"
:
"2016-05-01"
,
"rangeEnd"
:
"2016-05-31"
,
"akonadiId"
:
1
,
"eventData"
:
[
{
"summary"
:
"Multi day all day event"
,
"description"
:
"This is an all-day multi-day event"
,
"type"
:
"Event"
,
"allDay"
:
true
,
"isMinor"
:
false
,
"startDateTime"
:
{
"date"
:
"2016-05-28"
,
"time"
:
""
},
"endDateTime"
:
{
"date"
:
"2016-05-30"
,
"time"
:
""
},
"uid"
:
"Akonadi-1"
}
]
}
plugins/plasma/pimeventsplugin/autotests/data/allday-oneday-event.ics
0 → 100644
View file @
3ac4586e
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTAMP:20160529T143104Z
CREATED:20160529T143019Z
UID:c843300a-856d-4567-8ecc-a29255b6f5f5
LAST-MODIFIED:20160529T143104Z
DESCRIPTION:This is an all-day one day non-recurring event.
SUMMARY:All day one day non-recurring event
DTSTART;VALUE=DATE:20160529
DTEND;VALUE=DATE:20160530
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
plugins/plasma/pimeventsplugin/autotests/data/allday-oneday-event.json
0 → 100644
View file @
3ac4586e
{
"rangeStart"
:
"2016-05-01"
,
"rangeEnd"
:
"2016-05-31"
,
"akonadiId"
:
2
,
"eventData"
:
[
{
"summary"
:
"All day one day non-recurring event"
,
"description"
:
"This is an all-day one day non-recurring event."
,
"type"
:
"Event"
,
"allDay"
:
true
,
"isMinor"
:
false
,
"startDateTime"
:
{
"date"
:
"2016-05-29"
,
"time"
:
""
},
"endDateTime"
:
{
"date"
:
"2016-05-29"
,
"time"
:
""
},
"uid"
:
"Akonadi-2"
}
]
}
plugins/plasma/pimeventsplugin/autotests/data/allday-recurring-multiday-event.ics
0 → 100644
View file @
3ac4586e
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTAMP:20160529T143448Z
CREATED:20160529T143412Z
UID:1fceddbc-d1b9-4e20-8fea-1d36e191a42d
LAST-MODIFIED:20160529T143448Z
DESCRIPTION:This is an all-day multi-day recurring event
SUMMARY:All day multi-day recurring event
RRULE:FREQ=WEEKLY;BYDAY=FR
DTSTART;VALUE=DATE:20160408
DTEND;VALUE=DATE:20160411
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
plugins/plasma/pimeventsplugin/autotests/data/allday-recurring-multiday-event.json
0 → 100644
View file @
3ac4586e
{
"rangeStart"
:
"2016-05-01"
,
"rangeEnd"
:
"2016-05-31"
,
"akonadiId"
:
3
,
"eventData"
:
[
{
"summary"
:
"All day multi-day recurring event"
,
"description"
:
"This is an all-day multi-day recurring event"
,
"type"
:
"Event"
,
"allDay"
:
true
,
"isMinor"
:
false
,
"startDateTime"
:
{
"date"
:
"2016-05-06"
,
"time"
:
""
},
"endDateTime"
:
{
"date"
:
"2016-05-08"
,
"time"
:
""
},
"uid"
:
"Akonadi-3-20160506T000000"
},
{
"summary"
:
"All day multi-day recurring event"
,
"description"
:
"This is an all-day multi-day recurring event"
,
"type"
:
"Event"
,
"allDay"
:
true
,
"isMinor"
:
false
,
"startDateTime"
:
{
"date"
:
"2016-05-13"
,
"time"
:
""
},
"endDateTime"
:
{
"date"
:
"2016-05-15"
,
"time"
:
""
},
"uid"
:
"Akonadi-3-20160513T000000"
},
{
"summary"
:
"All day multi-day recurring event"
,
"description"
:
"This is an all-day multi-day recurring event"
,
"type"
:
"Event"
,
"allDay"
:
true
,
"isMinor"
:
false
,
"startDateTime"
:
{
"date"
:
"2016-05-20"
,
"time"
:
""
},
"endDateTime"
:
{
"date"
:
"2016-05-22"
,
"time"
:
""
},
"uid"
:
"Akonadi-3-20160520T000000"
},
{
"summary"
:
"All day multi-day recurring event"
,
"description"
:
"This is an all-day multi-day recurring event"
,
"type"
:
"Event"
,
"allDay"
:
true
,
"isMinor"
:
false
,
"startDateTime"
:
{
"date"
:
"2016-05-27"
,
"time"
:
""
},
"endDateTime"
:
{
"date"
:
"2016-05-29"
,
"time"
:
""