summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2012-06-25 16:38:19 (GMT)
committerChristian Mollekopf <chrigi_1@fastmail.fm>2012-06-25 16:38:19 (GMT)
commitbf385f44f99d73263b1787daac7423599e69f024 (patch)
tree04b5ff03c18133cfc8facfec1f1e9b90ae35a9a9
downloadlibcalendaring-bf385f44f99d73263b1787daac7423599e69f024.tar.gz
commit b54a325116b194da090f900c9a538710759eb303
Copy of kcalcore from the frameworks branch Author: Stephen Kelly <steveire@gmail.com> Date: Sun May 6 20:44:53 2012 +0200 Revert "Port to const QRegExp API." This reverts commit 0ca0dfc7e0ca8095efd0b060d1d5e26ac9ceb379. The qtbase commit requiring this was reverted.
-rw-r--r--kcalcore/.krazy2
-rw-r--r--kcalcore/CMakeLists.txt148
-rw-r--r--kcalcore/COPYING487
-rw-r--r--kcalcore/ConfigureChecks.cmake7
-rw-r--r--kcalcore/Mainpage.dox40
-rw-r--r--kcalcore/Messages.sh6
-rw-r--r--kcalcore/alarm.cpp842
-rw-r--r--kcalcore/alarm.h677
-rw-r--r--kcalcore/attachment.cpp240
-rw-r--r--kcalcore/attachment.h274
-rw-r--r--kcalcore/attendee.cpp228
-rw-r--r--kcalcore/attendee.h293
-rw-r--r--kcalcore/calendar.cpp1502
-rw-r--r--kcalcore/calendar.h1446
-rw-r--r--kcalcore/calfilter.cpp273
-rw-r--r--kcalcore/calfilter.h226
-rw-r--r--kcalcore/calformat.cpp147
-rw-r--r--kcalcore/calformat.h199
-rw-r--r--kcalcore/calstorage.cpp64
-rw-r--r--kcalcore/calstorage.h101
-rw-r--r--kcalcore/compat.cpp280
-rw-r--r--kcalcore/compat.h285
-rw-r--r--kcalcore/config-kcalcore.h.cmake5
-rw-r--r--kcalcore/customproperties.cpp246
-rw-r--r--kcalcore/customproperties.h227
-rw-r--r--kcalcore/duration.cpp211
-rw-r--r--kcalcore/duration.h300
-rw-r--r--kcalcore/event.cpp335
-rw-r--r--kcalcore/event.h263
-rw-r--r--kcalcore/exceptions.cpp68
-rw-r--r--kcalcore/exceptions.h124
-rw-r--r--kcalcore/filestorage.cpp176
-rw-r--r--kcalcore/filestorage.h136
-rw-r--r--kcalcore/freebusy.cpp428
-rw-r--r--kcalcore/freebusy.h296
-rw-r--r--kcalcore/freebusycache.cpp42
-rw-r--r--kcalcore/freebusycache.h81
-rw-r--r--kcalcore/freebusyperiod.cpp129
-rw-r--r--kcalcore/freebusyperiod.h153
-rw-r--r--kcalcore/freebusyurlstore.cpp99
-rw-r--r--kcalcore/freebusyurlstore.h65
-rw-r--r--kcalcore/icalformat.cpp654
-rw-r--r--kcalcore/icalformat.h232
-rw-r--r--kcalcore/icalformat_p.cpp2883
-rw-r--r--kcalcore/icalformat_p.h255
-rw-r--r--kcalcore/icaltimezones.cpp1442
-rw-r--r--kcalcore/icaltimezones.h673
-rw-r--r--kcalcore/incidence.cpp1080
-rw-r--r--kcalcore/incidence.h849
-rw-r--r--kcalcore/incidencebase.cpp642
-rw-r--r--kcalcore/incidencebase.h716
-rw-r--r--kcalcore/journal.cpp126
-rw-r--r--kcalcore/journal.h165
-rw-r--r--kcalcore/kcalcore.kdev43
-rw-r--r--kcalcore/memorycalendar.cpp808
-rw-r--r--kcalcore/memorycalendar.h388
-rw-r--r--kcalcore/period.cpp179
-rw-r--r--kcalcore/period.h222
-rw-r--r--kcalcore/person.cpp397
-rw-r--r--kcalcore/person.h227
-rw-r--r--kcalcore/recurrence.cpp1390
-rw-r--r--kcalcore/recurrence.h651
-rw-r--r--kcalcore/recurrencerule.cpp2251
-rw-r--r--kcalcore/recurrencerule.h323
-rw-r--r--kcalcore/schedulemessage.cpp102
-rw-r--r--kcalcore/schedulemessage.h123
-rw-r--r--kcalcore/sortablelist.h303
-rw-r--r--kcalcore/sorting.cpp302
-rw-r--r--kcalcore/sorting.h119
-rw-r--r--kcalcore/supertrait.h56
-rw-r--r--kcalcore/tests/CMakeLists.txt124
-rw-r--r--kcalcore/tests/README15
-rw-r--r--kcalcore/tests/cal38
-rwxr-xr-xkcalcore/tests/createref.sh12
-rwxr-xr-xkcalcore/tests/createtestcases.pl82
-rw-r--r--kcalcore/tests/data/Compat/AppleICal_1.5.ics269
-rw-r--r--kcalcore/tests/data/Compat/Evolution_2.8.2_timezone_test.ics18
-rw-r--r--kcalcore/tests/data/Compat/Evolution_2.8.2_timezone_test.ics.ical.ref18
-rw-r--r--kcalcore/tests/data/Compat/KOrganizer_3.1.ics465
-rw-r--r--kcalcore/tests/data/Compat/KOrganizer_3.1.ics.ical.fixme1
-rw-r--r--kcalcore/tests/data/Compat/KOrganizer_3.1.ics.ical.ref254
-rw-r--r--kcalcore/tests/data/Compat/KOrganizer_3.1a.ics70
-rw-r--r--kcalcore/tests/data/Compat/KOrganizer_3.1a.ics.ical.ref41
-rw-r--r--kcalcore/tests/data/Compat/KOrganizer_3.2.ics87
-rw-r--r--kcalcore/tests/data/Compat/KOrganizer_3.2.ics.ical.ref81
-rw-r--r--kcalcore/tests/data/Compat/MSExchange.ics44
-rw-r--r--kcalcore/tests/data/Compat/MSExchange.ics.ical.fixme1
-rw-r--r--kcalcore/tests/data/Compat/MSExchange.ics.ical.ref40
-rw-r--r--kcalcore/tests/data/Compat/Mozilla_1.0.ics61
-rw-r--r--kcalcore/tests/data/Compat/Mozilla_1.0.ics.ical.ref85
-rw-r--r--kcalcore/tests/data/Compat/eGroupware.ics23
-rw-r--r--kcalcore/tests/data/Compat/eGroupware.ics.ical.ref22
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily-3.0.7.ics.saved123
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily1.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily1.ics.next.ref68
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily1.ics.prev.ref67
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily1.ics.recurson.ref68
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily10.ics30
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily10.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily10.ics.prev.ref8
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily10.ics.recurson.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily11.ics30
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily11.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily11.ics.prev.ref122
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily11.ics.recurson.ref329
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily1a.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily1a.ics.next.ref68
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily1a.ics.prev.ref67
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily1a.ics.recurson.ref67
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily2.ics30
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily2.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily2.ics.prev.ref161
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily2.ics.recurson.ref400
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily3.ics30
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily3.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily3.ics.prev.ref161
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily3.ics.recurson.ref400
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily4.ics30
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily4.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily4.ics.prev.ref175
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily4.ics.recurson.ref435
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily5.ics30
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily5.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily5.ics.prev.ref82
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily5.ics.recurson.ref200
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily6.ics30
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily6.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily6.ics.prev.ref81
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily6.ics.recurson.ref200
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily7.ics30
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily7.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily7.ics.prev.ref81
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily7.ics.recurson.ref200
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily8.ics30
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily8.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily8.ics.prev.ref81
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily8.ics.recurson.ref200
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily9.ics30
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily9.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily9.ics.prev.ref8
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/ConnectDaily9.ics.recurson.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/ConnectDaily/readme.txt1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase01.ics23
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase01.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase01.ics.prev.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase01.ics.recurson.ref501
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase02.ics23
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase02.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase02.ics.prev.ref293
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase02.ics.recurson.ref501
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase03.ics23
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase03.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase03.ics.prev.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase03.ics.recurson.ref501
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase04.ics24
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase04.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase04.ics.prev.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase04.ics.recurson.ref501
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase05.ics23
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase05.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase05.ics.prev.ref35
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase05.ics.recurson.ref94
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase06.ics30
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase06.ics.next.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase06.ics.prev.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase06.ics.recurson.ref1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase07.ics23
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase07.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase07.ics.prev.ref4
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase07.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase08.ics23
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase08.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase08.ics.prev.ref68
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase08.ics.recurson.ref187
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase09.ics24
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase09.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase09.ics.prev.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase09.ics.recurson.ref501
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase10.ics23
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase10.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase10.ics.prev.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCase10.ics.recurson.ref23
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/KAlarm_TestCases.ics.all214
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KAlarm_3.4/readme.txt10
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test01.ics20
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test01.ics.next.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test01.ics.next.ref28
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test01.ics.prev.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test01.ics.prev.ref28
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test01.ics.recurson.ref27
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test02.ics20
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test02.ics.next.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test02.ics.next.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test02.ics.prev.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test02.ics.prev.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test02.ics.recurson.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test03.ics20
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test03.ics.next.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test03.ics.next.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test03.ics.prev.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test03.ics.prev.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test03.ics.recurson.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test04.ics21
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test04.ics.next.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test04.ics.prev.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test04.ics.recurson.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test05.ics21
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test05.ics.next.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test05.ics.next.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test05.ics.prev.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test05.ics.prev.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test05.ics.recurson.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test06.ics20
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test06.ics.next.ref50
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test06.ics.prev.ref50
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test06.ics.recurson.ref50
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test07.ics21
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test07.ics.next.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test07.ics.next.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test07.ics.prev.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test07.ics.prev.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test07.ics.recurson.ref6
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test08.ics21
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test08.ics.next.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test08.ics.next.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test08.ics.prev.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test08.ics.prev.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test08.ics.recurson.ref6
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test09.ics20
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test09.ics.next.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test09.ics.next.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test09.ics.prev.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test09.ics.prev.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test09.ics.recurson.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test10.ics20
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test10.ics.next.ref13
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test10.ics.prev.ref13
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test10.ics.recurson.ref8
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test11.ics21
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test11.ics.next.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test11.ics.prev.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test11.ics.recurson.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test11.ics.recurson.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test12.ics20
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test12.ics.next.ref14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test12.ics.prev.ref14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test12.ics.recurson.ref14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test13.ics21
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test13.ics.next.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test13.ics.next.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test13.ics.prev.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test13.ics.prev.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Test13.ics.recurson.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/KOrganizer_Tests.ics.saved219
-rw-r--r--kcalcore/tests/data/RecurrenceRule/KOrganizer_3.4/readme.txt14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase01.ics12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase01.ics.next.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase01.ics.prev.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase01.ics.recurson.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase02.ics12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase02.ics.next.ref10
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase02.ics.prev.ref10
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase02.ics.recurson.ref8
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase03.ics12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase03.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase03.ics.prev.ref12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase03.ics.recurson.ref22
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase04.ics12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase04.ics.next.ref13
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase04.ics.prev.ref13
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase04.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase05.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase05.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase05.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase05.ics.recurson.ref20
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase06.ics12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase06.ics.next.ref13
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase06.ics.prev.ref13
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase06.ics.recurson.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase06.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase07.ics12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase07.ics.next.ref6
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase07.ics.prev.ref6
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase07.ics.recurson.ref4
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase08.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase08.ics.next.ref13
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase08.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase08.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase09.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase09.ics.next.ref10
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase09.ics.prev.ref10
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase09.ics.recurson.ref10
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase10.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase10.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase10.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase10.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase11.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase11.ics.next.ref6
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase11.ics.prev.ref6
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase11.ics.recurson.ref6
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase12.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase12.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase12.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase12.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase15.ics12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase15.ics.next.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase15.ics.prev.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase15.ics.recurson.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase16.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase16.ics.next.ref50
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase16.ics.prev.ref50
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase16.ics.recurson.ref51
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase17.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase17.ics.next.ref10
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase17.ics.prev.ref10
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase17.ics.recurson.ref10
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase18.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase18.ics.next.ref14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase18.ics.prev.ref14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase18.ics.recurson.ref15
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase19.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase19.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase19.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase19.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase20.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase20.ics.next.ref18
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase20.ics.prev.ref18
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase20.ics.recurson.ref18
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase21.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase21.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase21.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase21.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase23.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase23.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase23.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase23.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase24.ics12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase24.ics.next.ref25
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase24.ics.prev.ref25
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase24.ics.recurson.ref26
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase25.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase25.ics.next.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase25.ics.prev.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase25.ics.recurson.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase26.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase26.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase26.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase26.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase27.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase27.ics.next.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase27.ics.prev.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase27.ics.recurson.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase28.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase28.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase28.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase28.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase29.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase29.ics.next.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase29.ics.prev.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase29.ics.recurson.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase30.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase30.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase30.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase30.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase31.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase31.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase31.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase31.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase32.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase32.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase32.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase32.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase33.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase33.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase33.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase33.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase34.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase34.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase34.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase34.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase35.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase35.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase35.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase35.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase36.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase36.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase36.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase36.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase37.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase37.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase37.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase37.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase38.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase38.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase38.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase38.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase39.ics12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase39.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase39.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase39.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase40.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase40.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase40.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase40.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase41.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase41.ics.next.ref21
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase41.ics.prev.ref21
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase41.ics.recurson.ref21
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase42.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase42.ics.next.ref12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase42.ics.prev.ref12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase42.ics.recurson.ref12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase43.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase43.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase43.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase43.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase44.ics12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase44.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase44.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase44.ics.recurson.ref8
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase45.ics12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase45.ics.next.ref4
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase45.ics.prev.ref4
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase45.ics.recurson.ref4
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase46.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase46.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase46.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase46.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase48.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase48.ics.next.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase48.ics.prev.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase48.ics.recurson.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase49.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase49.ics.next.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase49.ics.prev.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase49.ics.recurson.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase50.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase50.ics.next.ref23
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase50.ics.prev.ref23
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase50.ics.recurson.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase51.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase51.ics.next.ref21
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase51.ics.prev.ref21
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase51.ics.recurson.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase54.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase54.ics.next.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase54.ics.prev.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase54.ics.recurson.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase55.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase55.ics.next.ref4
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase55.ics.prev.ref4
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase55.ics.recurson.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase56.ics12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase56.ics.next.ref3
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase56.ics.prev.ref3
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase56.ics.recurson.ref1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase57.ics14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase57.ics.next.ref24
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase57.ics.prev.ref24
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/LibICal_TestCase57.ics.recurson.ref24
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/readme.txt9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/LibICal/recur.ics.saved420
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/2445AllExamples.ics.saved367
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest01.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest01.ics.comp34.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest01.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest01.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest01.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest02.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest02.ics.comp34.ref115
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest02.ics.next.ref114
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest02.ics.prev.ref114
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest02.ics.recurson.ref114
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest03.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest03.ics.comp34.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest03.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest03.ics.prev.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest03.ics.recurson.ref501
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest04.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest04.ics.comp34.ref6
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest04.ics.next.ref6
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest04.ics.prev.ref6
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest04.ics.recurson.ref6
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest05.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest05.ics.comp34.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest05.ics.next.ref93
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest05.ics.prev.ref93
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest05.ics.recurson.ref93
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest06.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest06.ics.comp34.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest06.ics.next.ref93
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest06.ics.prev.ref93
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest06.ics.recurson.ref93
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest07.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest07.ics.comp34.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest07.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest07.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest07.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest08.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest08.ics.comp34.ref18
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest08.ics.next.ref18
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest08.ics.prev.ref18
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest08.ics.recurson.ref18
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest09.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest09.ics.comp34.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest09.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest09.ics.prev.ref349
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest09.ics.recurson.ref501
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest10.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest10.ics.comp34.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest10.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest10.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest10.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest11.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest11.ics.comp34.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest11.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest11.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest11.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest12.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest12.ics.comp34.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest12.ics.next.ref26
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest12.ics.prev.ref26
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest12.ics.recurson.ref26
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest13.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest13.ics.comp34.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest13.ics.next.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest13.ics.prev.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest13.ics.recurson.ref9
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest14.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest14.ics.comp34.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest14.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest14.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest14.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest15.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest15.ics.comp34.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest15.ics.next.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest15.ics.prev.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest15.ics.recurson.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest16.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest16.ics.comp34.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest16.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest16.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest16.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest17.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest17.ics.comp34.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest17.ics.next.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest17.ics.prev.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest17.ics.recurson.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest18.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest18.ics.comp34.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest18.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest18.ics.prev.ref161
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest18.ics.recurson.ref280
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest19.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest19.ics.comp34.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest19.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest19.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest19.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest20.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest20.ics.comp34.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest20.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest20.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest20.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest21.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest21.ics.comp34.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest21.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest21.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest21.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest22.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest22.ics.comp34.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest22.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest22.ics.prev.ref351
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest22.ics.recurson.ref501
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest23.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest23.ics.comp34.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest23.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest23.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest23.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest24.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest24.ics.comp34.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest24.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest24.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest24.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest25.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest25.ics.comp34.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest25.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest25.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest25.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest26.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest26.ics.comp34.ref1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest26.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest26.ics.prev.ref15
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest26.ics.recurson.ref24
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest27.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest27.ics.comp34.ref1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest27.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest27.ics.prev.ref15
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest27.ics.recurson.ref24
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest28.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest28.ics.comp34.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest28.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest28.ics.prev.ref61
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest28.ics.recurson.ref105
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest29.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest29.ics.comp34.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest29.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest29.ics.prev.ref185
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest29.ics.recurson.ref315
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest30.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest30.ics.comp34.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest30.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest30.ics.prev.ref23
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest30.ics.recurson.ref41
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest31.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest31.ics.comp34.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest31.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest31.ics.prev.ref161
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest31.ics.recurson.ref280
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest32.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest32.ics.comp34.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest32.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest32.ics.prev.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest32.ics.recurson.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest33.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest33.ics.comp34.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest33.ics.next.ref4
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest33.ics.prev.ref4
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest33.ics.recurson.ref4
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest34.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest34.ics.comp34.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest34.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest34.ics.prev.ref161
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest34.ics.recurson.ref280
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest35.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest35.ics.comp34.ref3
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest35.ics.next.ref3
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest35.ics.prev.ref3
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest35.ics.recurson.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest36.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest36.ics.comp34.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest36.ics.next.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest36.ics.prev.ref7
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest36.ics.recurson.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest36U.ics33
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest36U.ics.next.ref8
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest36U.ics.prev.ref8
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest36U.ics.recurson.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest37.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest37.ics.comp34.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest37.ics.next.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest37.ics.prev.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest37.ics.recurson.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest38.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest38.ics.comp34.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest38.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest38.ics.prev.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest38.ics.recurson.ref501
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest39.ics32
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest39.ics.comp34.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest39.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest39.ics.prev.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest39.ics.recurson.ref501
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest40.ics14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest40.ics.comp34.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest40.ics.next.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest40.ics.prev.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest40.ics.recurson.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest41.ics13
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest41.ics.comp34.ref3
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest41.ics.next.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest41.ics.prev.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/RFC2445_RRULETest41.ics.recurson.ref5
-rw-r--r--kcalcore/tests/data/RecurrenceRule/RFC2445/readme.txt2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase02.ics10
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase02.ics.next.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase02.ics.prev.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase02.ics.recurson.ref1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase03.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase03.ics.next.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase03.ics.prev.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase03.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase04.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase04.ics.next.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase04.ics.prev.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase04.ics.recurson.ref2
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase05.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase05.ics.next.ref93
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase05.ics.prev.ref93
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase05.ics.recurson.ref93
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase06.ics11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase06.ics.next.ref95
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase06.ics.prev.ref93
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/Until_TestCase06.ics.recurson.ref93
-rw-r--r--kcalcore/tests/data/RecurrenceRule/UntilInUTC/readme.txt25
-rw-r--r--kcalcore/tests/data/RecurrenceRule/readme.txt3
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/PayDay.ics31
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/PayDay.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/PayDay.ics.prev.ref84
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/PayDay.ics.recurson.ref203
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/anniversary_4.6.1.ics12
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/anniversary_4.6.1.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/anniversary_4.6.1.ics.prev.ref15
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/anniversary_4.6.1.ics.recurson.ref24
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/daily.ics15
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/daily.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/daily.ics.prev.ref30
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/daily.ics.recurson.ref81
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/exdate.ics23
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/exdate.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/exdate.ics.prev.ref293
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/exdate.ics.recurson.ref501
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/hourly.ics14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/hourly.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/hourly.ics.prev.fixme1
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/hourly.ics.prev.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/hourly.ics.recurson.ref501
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/lastworkday.ics14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/lastworkday.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/lastworkday.ics.prev.ref70
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/lastworkday.ics.recurson.ref189
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/monthly.ics14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/monthly.ics.comp34.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/monthly.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/monthly.ics.prev.ref138
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/monthly.ics.recurson.ref377
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/rdate.ics18
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/rdate.ics.next.ref14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/rdate.ics.prev.ref14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/rdate.ics.recurson.ref11
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/test1.ics14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/test1.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/test1.ics.prev.ref17
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/test1.ics.recurson.ref31
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/weekly.ics14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/weekly.ics.comp34.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/weekly.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/weekly.ics.prev.ref295
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/weekly.ics.recurson.ref501
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/yearly.ics14
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/yearly.ics.comp34.ref499
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/yearly.ics.next.ref500
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/yearly.ics.prev.ref4
-rw-r--r--kcalcore/tests/data/RecurrenceRule/unsorted/yearly.ics.recurson.ref8
-rw-r--r--kcalcore/tests/data/resource_test_config8
-rw-r--r--kcalcore/tests/data/test_relations.ics237
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_3.4.ics.all220
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_3.4.vcs.all201
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase01.ics22
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase01.ics.vcal.ref20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase01.vcs20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase01.vcs.ical.ref19
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase02.ics22
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase02.ics.vcal.ref20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase02.vcs20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase02.vcs.ical.ref19
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase03.ics22
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase03.ics.vcal.ref21
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase03.vcs20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase03.vcs.ical.ref19
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase04.ics23
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase04.ics.vcal.ref20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase04.vcs20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase04.vcs.ical.ref20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase05.ics23
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase05.ics.vcal.ref20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase05.vcs20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase05.vcs.ical.ref20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase06.ics22
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase06.ics.vcal.ref20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase06.vcs20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase06.vcs.ical.ref18
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase07.ics23
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase07.ics.vcal.ref19
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase07.vcs19
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase07.vcs.ical.ref19
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase08.ics23
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase08.ics.vcal.ref20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase08.vcs19
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase08.vcs.ical.ref19
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase09.ics22
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase09.ics.vcal.ref20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase09.vcs20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase09.vcs.ical.ref19
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase10.ics22
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase10.ics.vcal.ref21
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase10.vcs20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase10.vcs.ical.ref19
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase11.ics23
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase11.ics.vcal.ref20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase11.vcs20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase11.vcs.ical.ref20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase12.ics22
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase12.ics.vcal.ref20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase12.vcs20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase12.vcs.ical.ref19
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase13.ics23
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase13.ics.vcal.ref21
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase13.vcs20
-rw-r--r--kcalcore/tests/data/vCalendar/KOrganizer_vCalTestCase13.vcs.ical.ref20
-rw-r--r--kcalcore/tests/data/vCalendar/readme.txt5
-rw-r--r--kcalcore/tests/fbrecurring.cpp70
-rw-r--r--kcalcore/tests/incidencestest.cpp102
-rw-r--r--kcalcore/tests/loadcalendar.cpp67
-rw-r--r--kcalcore/tests/readandwrite.cpp86
-rwxr-xr-xkcalcore/tests/runsingletestcase.pl134
-rw-r--r--kcalcore/tests/testalarm.cpp58
-rw-r--r--kcalcore/tests/testalarm.h36
-rw-r--r--kcalcore/tests/testattachment.cpp71
-rw-r--r--kcalcore/tests/testattachment.h33
-rw-r--r--kcalcore/tests/testattendee.cpp150
-rw-r--r--kcalcore/tests/testattendee.h39
-rw-r--r--kcalcore/tests/testcalfilter.cpp52
-rw-r--r--kcalcore/tests/testcalfilter.h34
-rw-r--r--kcalcore/tests/testcustomproperties.cpp206
-rw-r--r--kcalcore/tests/testcustomproperties.h42
-rw-r--r--kcalcore/tests/testduration.cpp74
-rw-r--r--kcalcore/tests/testduration.h35
-rw-r--r--kcalcore/tests/testevent.cpp116
-rw-r--r--kcalcore/tests/testevent.h38
-rw-r--r--kcalcore/tests/testexception.cpp36
-rw-r--r--kcalcore/tests/testexception.h34
-rw-r--r--kcalcore/tests/testfb.cpp66
-rw-r--r--kcalcore/tests/testfilestorage.cpp168
-rw-r--r--kcalcore/tests/testfilestorage.h40
-rw-r--r--kcalcore/tests/testfreebusy.cpp130
-rw-r--r--kcalcore/tests/testfreebusy.h37
-rw-r--r--kcalcore/tests/testfreebusyperiod.cpp119
-rw-r--r--kcalcore/tests/testfreebusyperiod.h38
-rw-r--r--kcalcore/tests/testicalformat.cpp102
-rw-r--r--kcalcore/tests/testicalformat.h35
-rw-r--r--kcalcore/tests/testicaltimezones.cpp619
-rw-r--r--kcalcore/tests/testicaltimezones.h42
-rw-r--r--kcalcore/tests/testincidencegenerator.h53
-rw-r--r--kcalcore/tests/testincidencerelation.cpp62
-rw-r--r--kcalcore/tests/testincidencerelation.h34
-rw-r--r--kcalcore/tests/testjournal.cpp101
-rw-r--r--kcalcore/tests/testjournal.h38
-rw-r--r--kcalcore/tests/testmemorycalendar.cpp174
-rw-r--r--kcalcore/tests/testmemorycalendar.h37
-rw-r--r--kcalcore/tests/testperiod.cpp133
-rw-r--r--kcalcore/tests/testperiod.h37
-rw-r--r--kcalcore/tests/testperson.cpp114
-rw-r--r--kcalcore/tests/testperson.h38
-rw-r--r--kcalcore/tests/testrecurprevious.cpp164
-rw-r--r--kcalcore/tests/testrecurrence.cpp152
-rw-r--r--kcalcore/tests/testrecurrencetype.cpp151
-rw-r--r--kcalcore/tests/testrecurson.cpp118
-rw-r--r--kcalcore/tests/testrecurtodo.cpp93
-rw-r--r--kcalcore/tests/testrecurtodo.h35
-rw-r--r--kcalcore/tests/testsortablelist.cpp144
-rw-r--r--kcalcore/tests/testsortablelist.h34
-rw-r--r--kcalcore/tests/testtimesininterval.cpp85
-rw-r--r--kcalcore/tests/testtimesininterval.h35
-rw-r--r--kcalcore/tests/testtodo.cpp142
-rw-r--r--kcalcore/tests/testtodo.h39
-rw-r--r--kcalcore/tests/testtostring.cpp48
-rw-r--r--kcalcore/tests/testvcalexport.cpp86
-rw-r--r--kcalcore/todo.cpp590
-rw-r--r--kcalcore/todo.h367
-rw-r--r--kcalcore/vcalformat.cpp2676
-rw-r--r--kcalcore/vcalformat.h258
-rw-r--r--kcalcore/versit/port.h75
-rw-r--r--kcalcore/versit/readme.txt944
-rw-r--r--kcalcore/versit/vcc.c2885
-rw-r--r--kcalcore/versit/vcc.h76
-rw-r--r--kcalcore/versit/vcc.y1226
-rw-r--r--kcalcore/versit/vobject.c1448
-rw-r--r--kcalcore/versit/vobject.h392
-rw-r--r--kcalcore/visitor.cpp64
-rw-r--r--kcalcore/visitor.h87
870 files changed, 107046 insertions, 0 deletions
diff --git a/kcalcore/.krazy b/kcalcore/.krazy
new file mode 100644
index 0000000..44badf0
--- /dev/null
+++ b/kcalcore/.krazy
@@ -0,0 +1,2 @@
+SKIP /libical.*/\|/versit/\|/tests/
+EXTRA style,kdebug,tipsandthis,defines,qenums,null,camelcase
diff --git a/kcalcore/CMakeLists.txt b/kcalcore/CMakeLists.txt
new file mode 100644
index 0000000..2fb8bac
--- /dev/null
+++ b/kcalcore/CMakeLists.txt
@@ -0,0 +1,148 @@
+project(kcalcore)
+
+include(GenerateExportHeader)
+
+############### Build Options ###############
+
+# The following macros can be defined to alter how KCalCore is built.
+# For example, cmake -DKCALCORE_FOR_MEEGO=true
+
+# KCALCORE_FOR_MEEGO - builds KCalCore with some special features for the MeeGo platform.
+option(KCALCORE_FOR_MEEGO "Build KCalCore especially for the MeeGo." FALSE)
+
+# KCALCORE_FOR_SYMBIAN - builds KCalCore with some special features for the Symbian platform.
+option(KCALCORE_FOR_SYMBIAN "Build KCalCore especially for the Symbian." FALSE)
+
+# add C++ macro definitions for options passed to CMake
+if(KCALCORE_FOR_MEEGO)
+ add_definitions(-DKCALCORE_FOR_MEEGO)
+endif()
+if(KCALCORE_FOR_SYMBIAN)
+ add_definitions(-DKCALCORE_FOR_SYMBIAN)
+endif()
+
+############### Find packages ###############
+# FIXME KDE5PORT needed: kdatetime which belongs to kdecore
+find_package(kcoreaddons REQUIRED)
+include_directories(${kcoreaddons_INCLUDE_DIR} ${kcoreaddons_INCLUDE_DIR}/KDE)
+
+###########################################################
+
+add_definitions(-DKDE_DEFAULT_DEBUG_AREA=5810)
+
+include(ConfigureChecks.cmake)
+configure_file(config-kcalcore.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kcalcore.h)
+
+if(KDE4_BUILD_TESTS)
+ add_definitions(-DCOMPILING_TESTS)
+endif()
+
+include_directories(
+ ${LIBICAL_INCLUDE_DIRS}
+ ${LIBICAL_INCLUDE_DIRS}/libical
+ ${CMAKE_CURRENT_SOURCE_DIR}/versit
+ ${KDE4_INCLUDE_DIR}
+)
+
+########### next target ###############
+
+set(libversit_SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/versit/vcc.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/versit/vobject.c
+)
+
+set(kcalcore_LIB_SRCS ${libversit_SRCS}
+ alarm.cpp
+ attachment.cpp
+ attendee.cpp
+ calendar.cpp
+ calfilter.cpp
+ calformat.cpp
+ calstorage.cpp
+ compat.cpp
+ customproperties.cpp
+ duration.cpp
+ event.cpp
+ exceptions.cpp
+ filestorage.cpp
+ freebusy.cpp
+ freebusycache.cpp
+ freebusyurlstore.cpp
+ freebusyperiod.cpp
+ icalformat.cpp
+ icalformat_p.cpp
+ icaltimezones.cpp
+ incidence.cpp
+ incidencebase.cpp
+ journal.cpp
+ memorycalendar.cpp
+ period.cpp
+ person.cpp
+ recurrence.cpp
+ recurrencerule.cpp
+ schedulemessage.cpp
+ sorting.cpp
+ todo.cpp
+ vcalformat.cpp
+ visitor.cpp
+)
+
+add_library(kcalcore ${LIBRARY_TYPE} ${kcalcore_LIB_SRCS})
+generate_export_header(kcalcore)
+
+target_link_libraries(kcalcore ${KDE4_KDECORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${LIBICAL_LIBRARIES})
+
+if(HAVE_UUID_LIBRARY)
+ target_link_libraries(kcalcore uuid)
+endif()
+
+set_target_properties(kcalcore PROPERTIES
+ VERSION ${ECM_VERSION_STRING}
+ SOVERSION ${ECM_SOVERSION}
+)
+
+install(TARGETS kcalcore EXPORT kdepimlibsLibraryTargets ${ECM_TARGET_DEFAULT_ARGS})
+
+########### next target ###############
+
+#add_subdirectory(tests)
+
+########### install files ###############
+
+install(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/kcalcore_export.h
+ alarm.h
+ attachment.h
+ attendee.h
+ calendar.h
+ calfilter.h
+ calformat.h
+ calstorage.h
+ compat.h
+ customproperties.h
+ duration.h
+ event.h
+ exceptions.h
+ filestorage.h
+ freebusy.h
+ freebusycache.h
+ freebusyperiod.h
+ freebusyurlstore.h
+ icalformat.h
+ icaltimezones.h
+ incidence.h
+ incidencebase.h
+ journal.h
+ memorycalendar.h
+ period.h
+ person.h
+ recurrence.h
+ recurrencerule.h
+ schedulemessage.h
+ sortablelist.h
+ sorting.h
+ supertrait.h
+ todo.h
+ vcalformat.h
+ visitor.h
+ DESTINATION ${INCLUDE_INSTALL_DIR}/kcalcore COMPONENT Devel)
diff --git a/kcalcore/COPYING b/kcalcore/COPYING
new file mode 100644
index 0000000..b05ce71
--- /dev/null
+++ b/kcalcore/COPYING
@@ -0,0 +1,487 @@
+NOTE! The LGPL below is copyrighted by the Free Software Foundation, but
+the instance of code that it refers to are copyrighted
+by the authors who actually wrote it.
+
+---------------------------------------------------------------------------
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor
+ Boston, MA 02110-1301, USA.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 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 Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/kcalcore/ConfigureChecks.cmake b/kcalcore/ConfigureChecks.cmake
new file mode 100644
index 0000000..537e7cc
--- /dev/null
+++ b/kcalcore/ConfigureChecks.cmake
@@ -0,0 +1,7 @@
+include(CheckIncludeFiles)
+include(CheckLibraryExists)
+
+check_include_files(uuid/uuid.h HAVE_UUID_UUID_H)
+check_library_exists(uuid uuid_generate_random "" HAVE_UUID_LIBRARY)
+
+
diff --git a/kcalcore/Mainpage.dox b/kcalcore/Mainpage.dox
new file mode 100644
index 0000000..52ead22
--- /dev/null
+++ b/kcalcore/Mainpage.dox
@@ -0,0 +1,40 @@
+/*!
+ * @mainpage KCalCore - the KDE calendar access library.
+ *
+ * @section purpose Purpose
+ *
+ * This library provides access to and handling of calendar data.
+ * It supports the standard formats iCalendar and vCalendar and the
+ * group scheduling standard iTIP.
+ *
+ * @section desc Description
+ *
+ * A calendar contains information like incidences (events, to-dos, journals),
+ * alarms, time zones, and other useful information. This API provides
+ * access to that calendar information via well known calendar formats
+ * <a href="http://en.wikipedia.org/wiki/Icalendar">iCalendar (or iCal)</a>
+ * and the older <a href="http://en.wikipedia.org/wiki/VCalendar">vCalendar</a>.
+ *
+ * Credit goes to Eric Bossum \<eric@softwarestudio.org\> for his libical
+ * software that does most of the heavy-lifting of the iCalendar support
+ * that is abstracted by this API.
+ *
+ * @authors
+ * The major authors of this library are (in alphabetical order):\n
+ * Preston Brown \<pbrown@kde.org\>,
+ * Reinhold Kainhofer \<reinhold@kainhofer.com\>,
+ * Sergio Martins \<iamsergio@gmail.com\>,
+ * Cornelius Schumacher \<schumacher@kde.org\>,
+ * Allen Winter \<winter@kde.org\>
+ *
+ * @maintainers
+ * Allen Winter \<winter@kde.org\> and Sergio Martins \<iamsergio@gmail.com\>
+ *
+ * @licenses
+ * @lgpl
+ */
+
+// DOXYGEN_PROJECTNAME=KCalCore Library
+// DOXYGEN_EXCLUDE = libical
+// DOXYGEN_SET_EXCLUDE_PATTERNS += @topdir@/kcalcore/versit/*.h
+
diff --git a/kcalcore/Messages.sh b/kcalcore/Messages.sh
new file mode 100644
index 0000000..cd09465
--- /dev/null
+++ b/kcalcore/Messages.sh
@@ -0,0 +1,6 @@
+#! /bin/sh
+$XGETTEXT *.cpp -o $podir/libkcalcore.pot
+if ( test -e $podir/libkcalcore.pot )
+then
+ echo "Error: kdepimlibs/kcalcore library should NOT have i18n strings."
+fi
diff --git a/kcalcore/alarm.cpp b/kcalcore/alarm.cpp
new file mode 100644
index 0000000..8b1aeea
--- /dev/null
+++ b/kcalcore/alarm.cpp
@@ -0,0 +1,842 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 1998 Preston Brown <pbrown@kde.org>
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (c) 2003 David Jarvie <software@astrojar.org.uk>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Alarm class.
+
+ @brief
+ Represents an alarm notification.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+#include "alarm.h"
+#include "duration.h"
+#include "incidence.h"
+
+using namespace KCalCore;
+
+/**
+ Private class that helps to provide binary compatibility between releases.
+ @internal
+*/
+//@cond PRIVATE
+class KCalCore::Alarm::Private
+{
+ public:
+ Private()
+ : mParent( 0 ),
+ mType( Alarm::Invalid ),
+ mAlarmSnoozeTime( 5 ),
+ mAlarmRepeatCount( 0 ),
+ mEndOffset( false ),
+ mHasTime( false ),
+ mAlarmEnabled( false ),
+ mHasLocationRadius ( false ),
+ mLocationRadius ( 0 )
+ {}
+ Private( const Private &other )
+ : mParent( other.mParent ),
+ mType( other.mType ),
+ mDescription( other.mDescription ),
+ mFile( other.mFile ),
+ mMailSubject( other.mMailSubject ),
+ mMailAttachFiles( other.mMailAttachFiles ),
+ mMailAddresses( other.mMailAddresses ),
+ mAlarmTime( other.mAlarmTime ),
+ mAlarmSnoozeTime( other.mAlarmSnoozeTime ),
+ mAlarmRepeatCount( other.mAlarmRepeatCount ),
+ mOffset( other.mOffset ),
+ mEndOffset( other.mEndOffset ),
+ mHasTime( other.mHasTime ),
+ mAlarmEnabled( other.mAlarmEnabled ),
+ mHasLocationRadius( other.mHasLocationRadius ),
+ mLocationRadius( other.mLocationRadius )
+ {}
+
+ Incidence *mParent; // the incidence which this alarm belongs to
+
+ Type mType; // type of alarm
+ QString mDescription;// text to display/email body/procedure arguments
+ QString mFile; // program to run/optional audio file to play
+ QString mMailSubject;// subject of email
+ QStringList mMailAttachFiles; // filenames to attach to email
+ Person::List mMailAddresses; // who to mail for reminder
+
+ KDateTime mAlarmTime;// time at which to trigger the alarm
+ Duration mAlarmSnoozeTime; // how long after alarm to snooze before
+ // triggering again
+ int mAlarmRepeatCount;// number of times for alarm to repeat
+ // after the initial time
+
+ Duration mOffset; // time relative to incidence DTSTART
+ // to trigger the alarm
+ bool mEndOffset; // if true, mOffset relates to DTEND, not DTSTART
+ bool mHasTime; // use mAlarmTime, not mOffset
+ bool mAlarmEnabled;
+
+ bool mHasLocationRadius;
+ int mLocationRadius; // location radius for the alarm
+};
+//@endcond
+
+Alarm::Alarm( Incidence *parent ) : d( new KCalCore::Alarm::Private )
+{
+ d->mParent = parent;
+}
+
+Alarm::Alarm( const Alarm &other ) :
+ CustomProperties( other ), d( new KCalCore::Alarm::Private( *other.d ) )
+{
+}
+
+Alarm::~Alarm()
+{
+ delete d;
+}
+
+Alarm &Alarm::operator=( const Alarm &a )
+{
+ if ( &a != this ) {
+ d->mParent = a.d->mParent;
+ d->mType = a.d->mType;
+ d->mDescription = a.d->mDescription;
+ d->mFile = a.d->mFile;
+ d->mMailAttachFiles = a.d->mMailAttachFiles;
+ d->mMailAddresses = a.d->mMailAddresses;
+ d->mMailSubject = a.d->mMailSubject;
+ d->mAlarmSnoozeTime = a.d->mAlarmSnoozeTime;
+ d->mAlarmRepeatCount = a.d->mAlarmRepeatCount;
+ d->mAlarmTime = a.d->mAlarmTime;
+ d->mOffset = a.d->mOffset;
+ d->mEndOffset = a.d->mEndOffset;
+ d->mHasTime = a.d->mHasTime;
+ d->mAlarmEnabled = a.d->mAlarmEnabled;
+ }
+
+ return *this;
+}
+
+bool Alarm::operator==( const Alarm &rhs ) const
+{
+ if ( d->mType != rhs.d->mType ||
+ d->mAlarmSnoozeTime != rhs.d->mAlarmSnoozeTime ||
+ d->mAlarmRepeatCount != rhs.d->mAlarmRepeatCount ||
+ d->mAlarmEnabled != rhs.d->mAlarmEnabled ||
+ d->mHasTime != rhs.d->mHasTime ||
+ d->mHasLocationRadius != rhs.d->mHasLocationRadius ||
+ d->mLocationRadius != rhs.d->mLocationRadius ) {
+ return false;
+ }
+
+ if ( d->mHasTime ) {
+ if ( d->mAlarmTime != rhs.d->mAlarmTime ) {
+ return false;
+ }
+ } else {
+ if ( d->mOffset != rhs.d->mOffset || d->mEndOffset != rhs.d->mEndOffset ) {
+ return false;
+ }
+ }
+
+ switch ( d->mType ) {
+ case Display:
+ return d->mDescription == rhs.d->mDescription;
+
+ case Email:
+ return d->mDescription == rhs.d->mDescription &&
+ d->mMailAttachFiles == rhs.d->mMailAttachFiles &&
+ d->mMailAddresses == rhs.d->mMailAddresses &&
+ d->mMailSubject == rhs.d->mMailSubject;
+
+ case Procedure:
+ return d->mFile == rhs.d->mFile &&
+ d->mDescription == rhs.d->mDescription;
+
+ case Audio:
+ return d->mFile == rhs.d->mFile;
+
+ case Invalid:
+ break;
+ }
+ return false;
+}
+
+bool Alarm::operator!=( const Alarm &a ) const
+{
+ return !operator==( a );
+}
+
+void Alarm::setType( Alarm::Type type )
+{
+ if ( type == d->mType ) {
+ return;
+ }
+
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ switch ( type ) {
+ case Display:
+ d->mDescription = "";
+ break;
+ case Procedure:
+ d->mFile = d->mDescription = "";
+ break;
+ case Audio:
+ d->mFile = "";
+ break;
+ case Email:
+ d->mMailSubject = d->mDescription = "";
+ d->mMailAddresses.clear();
+ d->mMailAttachFiles.clear();
+ break;
+ case Invalid:
+ break;
+ default:
+ if ( d->mParent ) {
+ d->mParent->updated(); // not really
+ }
+ return;
+ }
+ d->mType = type;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+Alarm::Type Alarm::type() const
+{
+ return d->mType;
+}
+
+void Alarm::setAudioAlarm( const QString &audioFile )
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mType = Audio;
+ d->mFile = audioFile;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+void Alarm::setAudioFile( const QString &audioFile )
+{
+ if ( d->mType == Audio ) {
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mFile = audioFile;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+ }
+}
+
+QString Alarm::audioFile() const
+{
+ return ( d->mType == Audio ) ? d->mFile : QString();
+}
+
+void Alarm::setProcedureAlarm( const QString &programFile,
+ const QString &arguments )
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mType = Procedure;
+ d->mFile = programFile;
+ d->mDescription = arguments;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+void Alarm::setProgramFile( const QString &programFile )
+{
+ if ( d->mType == Procedure ) {
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mFile = programFile;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+ }
+}
+
+QString Alarm::programFile() const
+{
+ return ( d->mType == Procedure ) ? d->mFile : QString();
+}
+
+void Alarm::setProgramArguments( const QString &arguments )
+{
+ if ( d->mType == Procedure ) {
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mDescription = arguments;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+ }
+}
+
+QString Alarm::programArguments() const
+{
+ return ( d->mType == Procedure ) ? d->mDescription : QString();
+}
+
+void Alarm::setEmailAlarm( const QString &subject, const QString &text,
+ const Person::List &addressees,
+ const QStringList &attachments )
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mType = Email;
+ d->mMailSubject = subject;
+ d->mDescription = text;
+ d->mMailAddresses = addressees;
+ d->mMailAttachFiles = attachments;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+void Alarm::setMailAddress( const Person::Ptr &mailAddress )
+{
+ if ( d->mType == Email ) {
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mMailAddresses.clear();
+ d->mMailAddresses.append( mailAddress );
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+ }
+}
+
+void Alarm::setMailAddresses( const Person::List &mailAddresses )
+{
+ if ( d->mType == Email ) {
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mMailAddresses += mailAddresses;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+ }
+}
+
+void Alarm::addMailAddress( const Person::Ptr &mailAddress )
+{
+ if ( d->mType == Email ) {
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mMailAddresses.append( mailAddress );
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+ }
+}
+
+Person::List Alarm::mailAddresses() const
+{
+ return ( d->mType == Email ) ? d->mMailAddresses : Person::List();
+}
+
+void Alarm::setMailSubject( const QString &mailAlarmSubject )
+{
+ if ( d->mType == Email ) {
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mMailSubject = mailAlarmSubject;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+ }
+}
+
+QString Alarm::mailSubject() const
+{
+ return ( d->mType == Email ) ? d->mMailSubject : QString();
+}
+
+void Alarm::setMailAttachment( const QString &mailAttachFile )
+{
+ if ( d->mType == Email ) {
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mMailAttachFiles.clear();
+ d->mMailAttachFiles += mailAttachFile;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+ }
+}
+
+void Alarm::setMailAttachments( const QStringList &mailAttachFiles )
+{
+ if ( d->mType == Email ) {
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mMailAttachFiles = mailAttachFiles;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+ }
+}
+
+void Alarm::addMailAttachment( const QString &mailAttachFile )
+{
+ if ( d->mType == Email ) {
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mMailAttachFiles += mailAttachFile;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+ }
+}
+
+QStringList Alarm::mailAttachments() const
+{
+ return ( d->mType == Email ) ? d->mMailAttachFiles : QStringList();
+}
+
+void Alarm::setMailText( const QString &text )
+{
+ if ( d->mType == Email ) {
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mDescription = text;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+ }
+}
+
+QString Alarm::mailText() const
+{
+ return ( d->mType == Email ) ? d->mDescription : QString();
+}
+
+void Alarm::setDisplayAlarm( const QString &text )
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mType = Display;
+ if ( !text.isNull() ) {
+ d->mDescription = text;
+ }
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+void Alarm::setText( const QString &text )
+{
+ if ( d->mType == Display ) {
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mDescription = text;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+ }
+}
+
+QString Alarm::text() const
+{
+ return ( d->mType == Display ) ? d->mDescription : QString();
+}
+
+void Alarm::setTime( const KDateTime &alarmTime )
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mAlarmTime = alarmTime;
+ d->mHasTime = true;
+
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+KDateTime Alarm::time() const
+{
+ if ( hasTime() ) {
+ return d->mAlarmTime;
+ } else if ( d->mParent ) {
+ if ( d->mEndOffset ) {
+ KDateTime dt = d->mParent->dateTime( Incidence::RoleAlarmEndOffset );
+ return d->mOffset.end( dt );
+ } else {
+ KDateTime dt = d->mParent->dateTime( Incidence::RoleAlarmStartOffset );
+ return d->mOffset.end( dt );
+ }
+ } else {
+ return KDateTime();
+ }
+}
+
+KDateTime Alarm::nextTime( const KDateTime &preTime, bool ignoreRepetitions ) const
+{
+ if ( d->mParent && d->mParent->recurs() ) {
+ KDateTime dtEnd = d->mParent->dateTime( Incidence::RoleAlarmEndOffset );
+
+ KDateTime dtStart = d->mParent->dtStart();
+ // Find the incidence's earliest alarm
+ // Alarm time is defined by an offset from the event start or end time.
+ KDateTime alarmStart = d->mOffset.end( d->mEndOffset ? dtEnd : dtStart );
+ // Find the offset from the event start time, which is also used as the
+ // offset from the recurrence time.
+ Duration alarmOffset( dtStart, alarmStart );
+ /*
+ kDebug() << "dtStart " << dtStart;
+ kDebug() << "dtEnd " << dtEnd;
+ kDebug() << "alarmStart " << alarmStart;
+ kDebug() << "alarmOffset " << alarmOffset.value();
+ kDebug() << "preTime " << preTime;
+ */
+ if ( alarmStart > preTime ) {
+ // No need to go further.
+ return alarmStart;
+ }
+ if ( d->mAlarmRepeatCount && !ignoreRepetitions ) {
+ // The alarm has repetitions, so check whether repetitions of previous
+ // recurrences happen after given time.
+ KDateTime prevRecurrence = d->mParent->recurrence()->getPreviousDateTime( preTime );
+ if ( prevRecurrence.isValid() ) {
+ KDateTime prevLastRepeat = alarmOffset.end( duration().end( prevRecurrence ) );
+ // kDebug() << "prevRecurrence" << prevRecurrence;
+ // kDebug() << "prevLastRepeat" << prevLastRepeat;
+ if ( prevLastRepeat > preTime ) {
+ // Yes they did, return alarm offset to previous recurrence.
+ KDateTime prevAlarm = alarmOffset.end( prevRecurrence );
+ // kDebug() << "prevAlarm " << prevAlarm;
+ return prevAlarm;
+ }
+ }
+ }
+ // Check the next recurrence now.
+ KDateTime nextRecurrence = d->mParent->recurrence()->getNextDateTime( preTime );
+ if ( nextRecurrence.isValid() ) {
+ KDateTime nextAlarm = alarmOffset.end( nextRecurrence );
+ /*
+ kDebug() << "nextRecurrence" << nextRecurrence;
+ kDebug() << "nextAlarm " << nextAlarm;
+ */
+ if ( nextAlarm > preTime ) {
+ // It's first alarm takes place after given time.
+ return nextAlarm;
+ }
+ }
+ } else {
+ // Not recurring.
+ KDateTime alarmTime = time();
+ if ( alarmTime > preTime ) {
+ return alarmTime;
+ }
+ }
+ return KDateTime();
+}
+
+bool Alarm::hasTime() const
+{
+ return d->mHasTime;
+}
+
+void Alarm::shiftTimes( const KDateTime::Spec &oldSpec,
+ const KDateTime::Spec &newSpec )
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mAlarmTime = d->mAlarmTime.toTimeSpec( oldSpec );
+ d->mAlarmTime.setTimeSpec( newSpec );
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+void Alarm::setSnoozeTime( const Duration &alarmSnoozeTime )
+{
+ if ( alarmSnoozeTime.value() > 0 ) {
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mAlarmSnoozeTime = alarmSnoozeTime;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+ }
+}
+
+Duration Alarm::snoozeTime() const
+{
+ return d->mAlarmSnoozeTime;
+}
+
+void Alarm::setRepeatCount( int alarmRepeatCount )
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mAlarmRepeatCount = alarmRepeatCount;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+int Alarm::repeatCount() const
+{
+ return d->mAlarmRepeatCount;
+}
+
+Duration Alarm::duration() const
+{
+ return Duration( d->mAlarmSnoozeTime.value() * d->mAlarmRepeatCount,
+ d->mAlarmSnoozeTime.type() );
+}
+
+KDateTime Alarm::nextRepetition( const KDateTime &preTime ) const
+{
+ KDateTime at = nextTime( preTime );
+ if ( at > preTime ) {
+ return at;
+ }
+ if ( !d->mAlarmRepeatCount ) {
+ // there isn't an occurrence after the specified time
+ return KDateTime();
+ }
+ qint64 repetition;
+ int interval = d->mAlarmSnoozeTime.value();
+ bool daily = d->mAlarmSnoozeTime.isDaily();
+ if ( daily ) {
+ int daysTo = at.daysTo( preTime );
+ if ( !preTime.isDateOnly() && preTime.time() <= at.time() ) {
+ --daysTo;
+ }
+ repetition = daysTo / interval + 1;
+ } else {
+ repetition = at.secsTo_long( preTime ) / interval + 1;
+ }
+ if ( repetition > d->mAlarmRepeatCount ) {
+ // all repetitions have finished before the specified time
+ return KDateTime();
+ }
+ return daily ? at.addDays( int( repetition * interval ) )
+ : at.addSecs( repetition * interval );
+}
+
+KDateTime Alarm::previousRepetition( const KDateTime &afterTime ) const
+{
+ KDateTime at = time();
+ if ( at >= afterTime ) {
+ // alarm's first/only time is at/after the specified time
+ return KDateTime();
+ }
+ if ( !d->mAlarmRepeatCount ) {
+ return at;
+ }
+ qint64 repetition;
+ int interval = d->mAlarmSnoozeTime.value();
+ bool daily = d->mAlarmSnoozeTime.isDaily();
+ if ( daily ) {
+ int daysTo = at.daysTo( afterTime );
+ if ( afterTime.isDateOnly() || afterTime.time() <= at.time() ) {
+ --daysTo;
+ }
+ repetition = daysTo / interval;
+ } else {
+ repetition = ( at.secsTo_long( afterTime ) - 1 ) / interval;
+ }
+ if ( repetition > d->mAlarmRepeatCount ) {
+ repetition = d->mAlarmRepeatCount;
+ }
+ return daily ? at.addDays( int( repetition * interval ) )
+ : at.addSecs( repetition * interval );
+}
+
+KDateTime Alarm::endTime() const
+{
+ if ( !d->mAlarmRepeatCount ) {
+ return time();
+ }
+ if ( d->mAlarmSnoozeTime.isDaily() ) {
+ return time().addDays( d->mAlarmRepeatCount * d->mAlarmSnoozeTime.asDays() );
+ } else {
+ return time().addSecs( d->mAlarmRepeatCount * d->mAlarmSnoozeTime.asSeconds() );
+ }
+}
+
+void Alarm::toggleAlarm()
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mAlarmEnabled = !d->mAlarmEnabled;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+void Alarm::setEnabled( bool enable )
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mAlarmEnabled = enable;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+bool Alarm::enabled() const
+{
+ return d->mAlarmEnabled;
+}
+
+void Alarm::setStartOffset( const Duration &offset )
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mOffset = offset;
+ d->mEndOffset = false;
+ d->mHasTime = false;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+Duration Alarm::startOffset() const
+{
+ return ( d->mHasTime || d->mEndOffset ) ? Duration( 0 ) : d->mOffset;
+}
+
+bool Alarm::hasStartOffset() const
+{
+ return !d->mHasTime && !d->mEndOffset;
+}
+
+bool Alarm::hasEndOffset() const
+{
+ return !d->mHasTime && d->mEndOffset;
+}
+
+void Alarm::setEndOffset( const Duration &offset )
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mOffset = offset;
+ d->mEndOffset = true;
+ d->mHasTime = false;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+Duration Alarm::endOffset() const
+{
+ return ( d->mHasTime || !d->mEndOffset ) ? Duration( 0 ) : d->mOffset;
+}
+
+void Alarm::setParent( Incidence *parent )
+{
+ d->mParent = parent;
+}
+
+QString Alarm::parentUid() const
+{
+ return d->mParent ? d->mParent->uid() : QString();
+}
+
+void Alarm::customPropertyUpdated()
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ d->mParent->updated();
+ }
+}
+
+void Alarm::setHasLocationRadius( bool hasLocationRadius )
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mHasLocationRadius = hasLocationRadius;
+ if ( hasLocationRadius ) {
+ setNonKDECustomProperty( "X-LOCATION-RADIUS", QString::number( d->mLocationRadius ) );
+ } else {
+ removeNonKDECustomProperty( "X-LOCATION-RADIUS" );
+ }
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+bool Alarm::hasLocationRadius() const
+{
+ return d->mHasLocationRadius;
+}
+
+void Alarm::setLocationRadius( int locationRadius )
+{
+ if ( d->mParent ) {
+ d->mParent->update();
+ }
+ d->mLocationRadius = locationRadius;
+ if ( d->mParent ) {
+ d->mParent->updated();
+ }
+}
+
+int Alarm::locationRadius() const
+{
+ return d->mLocationRadius;
+}
+
+void Alarm::virtual_hook( int id, void *data )
+{
+ Q_UNUSED( id );
+ Q_UNUSED( data );
+ Q_ASSERT( false );
+}
diff --git a/kcalcore/alarm.h b/kcalcore/alarm.h
new file mode 100644
index 0000000..6edf02d
--- /dev/null
+++ b/kcalcore/alarm.h
@@ -0,0 +1,677 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001-2003 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (c) 2003 David Jarvie <software@astrojar.org.uk>
+ Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Alarm class.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#ifndef KCALCORE_ALARM_H
+#define KCALCORE_ALARM_H
+
+#include "kcalcore_export.h"
+#include "customproperties.h"
+#include "duration.h"
+#include "person.h"
+
+#include <KDE/KDateTime>
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVector>
+
+namespace KCalCore {
+
+class Incidence;
+
+/**
+ @brief
+ Represents an alarm notification.
+
+ Alarms are user notifications that occur at specified times.
+ Notifications can be on-screen pop-up dialogs, email messages,
+ the playing of audio files, or the running of another program.
+
+ Alarms always belong to a parent Incidence.
+*/
+class KCALCORE_EXPORT Alarm : public CustomProperties
+{
+ public:
+ /**
+ The different types of alarms.
+ */
+ enum Type {
+ Invalid, /**< Invalid, or no alarm */
+ Display, /**< Display a dialog box */
+ Procedure, /**< Call a script */
+ Email, /**< Send email */
+ Audio /**< Play an audio file */
+ };
+
+ /**
+ A shared pointer to an Alarm object.
+ */
+ typedef QSharedPointer<Alarm> Ptr;
+
+ /**
+ List of alarms.
+ */
+ typedef QVector<Ptr> List;
+
+ /**
+ Constructs an alarm belonging to the @p parent Incidence.
+
+ @param parent is the Incidence this alarm will belong to.
+ */
+ // Can't find a way to use a shared pointer here.
+ // Inside incidence.cpp, it does alarm->setParent( this )
+ explicit Alarm( Incidence *parent );
+
+ /**
+ Copy constructor.
+ @param other is the alarm to copy.
+ */
+ Alarm( const Alarm &other );
+
+ /**
+ Destroys the alarm.
+ */
+ virtual ~Alarm();
+
+ /**
+ Copy operator.
+ */
+ Alarm &operator=( const Alarm & );
+
+ /**
+ Compares two alarms for equality.
+ @param a is the comparison alarm.
+ */
+ bool operator==( const Alarm &a ) const;
+
+ /**
+ Compares two alarms for inequality.
+
+ @param a is the comparison alarm.
+ */
+ bool operator!=( const Alarm &a ) const;
+
+ /**
+ Sets the @p parent Incidence of the alarm.
+
+ @param parent is alarm parent Incidence to set.
+
+ @see parentUid()
+ */
+ // Is there a way to use QSharedPointer here?
+ // although it's safe, Incidence's dtor calls setParent( 0 )
+ // se we don't dereference a deleted pointer here.
+ // Also, I renamed "Incidence *parent()" to "QString parentUid()"
+ // So we don't return raw pointers
+ void setParent( Incidence *parent );
+
+ /**
+ Returns the parent's incidence UID of the alarm.
+
+ @see setParent()
+ */
+ // We don't have a share pointer to return, so return the UID.
+ QString parentUid() const;
+
+ /**
+ Sets the #Type for this alarm to @p type.
+ If the specified type is different from the current type of the alarm,
+ then the alarm's type-specific properties are re-initialized.
+
+ @param type is the alarm #Type to set.
+
+ @see type()
+ */
+ void setType( Type type );
+
+ /**
+ Returns the #Type of the alarm.
+
+ @see setType()
+ */
+ Type type() const;
+
+ /**
+ Sets the #Display type for this alarm.
+ If @p text is specified non-empty, then it is used as the description
+ text to display when the alarm is triggered.
+
+ @param text is the description to display when the alarm is triggered.
+
+ @see setText(), text()
+ */
+ void setDisplayAlarm( const QString &text = QString() );
+
+ /**
+ Sets the description @p text to be displayed when the alarm is triggered.
+ Ignored if the alarm is not a display alarm.
+
+ @param text is the description to display when the alarm is triggered.
+
+ @see setDisplayAlarm(), text()
+ */
+ void setText( const QString &text );
+
+ /**
+ Returns the display text string for a #Display alarm type.
+ Returns an empty string if the alarm is not a #Display type.
+
+ @see setDisplayAlarm(), setText()
+ */
+ QString text() const;
+
+ /**
+ Sets the #Audio type for this alarm and the name of the audio file
+ to play when the alarm is triggered.
+
+ @param audioFile is the name of the audio file to play when the alarm
+ is triggered.
+
+ @see setAudioFile(), audioFile()
+ */
+ void setAudioAlarm( const QString &audioFile = QString() );
+
+ /**
+ Sets the name of the audio file to play when the audio alarm is triggered.
+ Ignored if the alarm is not an #Audio type.
+
+ @param audioFile is the name of the audio file to play when the alarm
+ is triggered.
+
+ @see setAudioAlarm(), audioFile()
+ */
+ void setAudioFile( const QString &audioFile );
+
+ /**
+ Returns the audio file name for an #Audio alarm type.
+ Returns an empty string if the alarm is not an #Audio type.
+
+ @see setAudioAlarm(), setAudioFile()
+ */
+ QString audioFile() const;
+
+ /**
+ Sets the #Procedure type for this alarm and the program (with arguments)
+ to execute when the alarm is triggered.
+
+ @param programFile is the name of the program file to execute when
+ the alarm is triggered.
+ @param arguments is a string of arguments to supply to @p programFile.
+
+ @see setProgramFile(), programFile(),
+ setProgramArguments(), programArguments()
+ */
+ void setProcedureAlarm( const QString &programFile,
+ const QString &arguments = QString() );
+
+ /**
+ Sets the program file to execute when the alarm is triggered.
+ Ignored if the alarm is not a #Procedure type.
+
+ @param programFile is the name of the program file to execute when
+ the alarm is triggered.
+
+ @see setProcedureAlarm(), programFile(),
+ setProgramArguments(), programArguments()
+ */
+ void setProgramFile( const QString &programFile );
+
+ /**
+ Returns the program file name for a #Procedure alarm type.
+ Returns an empty string if the alarm is not a #Procedure type.
+
+ @see setProcedureAlarm(), setProgramFile(),
+ setProgramArguments(), programArguments()
+ */
+ QString programFile() const;
+
+ /**
+ Sets the program arguments string when the alarm is triggered.
+ Ignored if the alarm is not a #Procedure type.
+
+ @param arguments is a string of arguments to supply to the program.
+
+ @see setProcedureAlarm(), setProgramFile(), programFile(),
+ programArguments()
+ */
+ void setProgramArguments( const QString &arguments );
+
+ /**
+ Returns the program arguments string for a #Procedure alarm type.
+ Returns an empty string if the alarm is not a #Procedure type.
+
+ @see setProcedureAlarm(), setProgramFile(), programFile(),
+ setProgramArguments()
+ */
+ QString programArguments() const;
+
+ /**
+ Sets the #Email type for this alarm and the email @p subject, @p text,
+ @p addresses, and @p attachments that make up an email message to be
+ sent when the alarm is triggered.
+
+ @param subject is the email subject.
+ @param text is a string containing the body of the email message.
+ @param addressees is Person list of email addresses.
+ @param attachments is a a QStringList of optional file names
+ of email attachments.
+
+ @see setMailSubject(), setMailText(), setMailAddresses(),
+ setMailAttachments()
+ */
+ void setEmailAlarm( const QString &subject, const QString &text,
+ const Person::List &addressees,
+ const QStringList &attachments = QStringList() );
+
+ /**
+ Sets the email address of an #Email type alarm.
+ Ignored if the alarm is not an #Email type.
+
+ @param mailAlarmAddress is a Person to receive a mail message when
+ an #Email type alarm is triggered.
+
+ @see setMailSubject(), setMailText(), setMailAddresses(),
+ setMailAttachment(), setMailAttachments(), mailAddresses()
+ */
+ void setMailAddress( const Person::Ptr &mailAlarmAddress );
+
+ /**
+ Sets a list of email addresses of an #Email type alarm.
+ Ignored if the alarm is not an #Email type.
+
+ @param mailAlarmAddresses is a Person list to receive a mail message
+ when an #Email type alarm is triggered.
+
+ @see setMailSubject(), setMailText(), setMailAddress(),
+ setMailAttachments(), setMailAttachment(), mailAddresses()
+ */
+ void setMailAddresses( const Person::List &mailAlarmAddresses );
+
+ /**
+ Adds an address to the list of email addresses to send mail to when the
+ alarm is triggered.
+ Ignored if the alarm is not an #Email type.
+
+ @param mailAlarmAddress is a Person to add to the list of addresses to
+ receive a mail message when an #Email type alarm is triggered.
+
+ @see setMailAddress(), setMailAddresses(), mailAddresses()
+ */
+ void addMailAddress( const Person::Ptr &mailAlarmAddress );
+
+ /**
+ Returns the list of addresses for an #Email alarm type.
+ Returns an empty list if the alarm is not an #Email type.
+
+ @see addMailAddress(), setMailAddress(), setMailAddresses()
+ */
+ Person::List mailAddresses() const;
+
+ /**
+ Sets the subject line of a mail message for an #Email alarm type.
+ Ignored if the alarm is not an #Email type.
+
+ @param mailAlarmSubject is a string to be used as a subject line
+ of an email message to send when the #Email type alarm is triggered.
+
+ @see setMailText(), setMailAddress(), setMailAddresses(),
+ setMailAttachment(), setMailAttachments(), mailSubject()
+ */
+ void setMailSubject( const QString &mailAlarmSubject );
+
+ /**
+ Returns the subject line string for an #Email alarm type.
+ Returns an empty string if the alarm is not an #Email type.
+
+ @see setMailSubject()
+ */
+ QString mailSubject() const;
+
+ /**
+ Sets the filename to attach to a mail message for an #Email alarm type.
+ Ignored if the alarm is not an #Email type.
+
+ @param mailAttachFile is a string containing a filename to be attached
+ to an email message to send when the #Email type alarm is triggered.
+
+ @see setMailSubject(), setMailText(), setMailAddress(),
+ setMailAddresses(), setMailAttachments(), mailAttachments()
+ */
+ void setMailAttachment( const QString &mailAttachFile );
+
+ /**
+ Sets a list of filenames to attach to a mail message for an #Email
+ alarm type. Ignored if the alarm is not an #Email type.
+
+ @param mailAttachFiles is a QString list of filenames to attach to
+ a mail message when an #Email type alarm is triggered.
+
+ @see setMailSubject(), setMailText(), setMailAttachment(),
+ setMailAddress(), setMailAddresses()
+ */
+ void setMailAttachments( const QStringList &mailAttachFiles );
+
+ /**
+ Adds a filename to the list of files to attach to a mail message for
+ an #Email alarm type. Ignored if the alarm is not an #Email type.
+
+ @param mailAttachFile is a string containing a filename to be attached
+ to an email message to send when the #Email type alarm is triggered.
+
+ @see setMailAttachment(), setMailAttachments(), mailAttachments()
+ */
+ void addMailAttachment( const QString &mailAttachFile );
+
+ /**
+ Returns the list of attachment filenames for an #Email alarm type.
+ Returns an empty list if the alarm is not an #Email type.
+
+ @see addMailAttachment(), setMailAttachment(), setMailAttachments()
+ */
+ QStringList mailAttachments() const;
+
+ /**
+ Sets the body text for an #Email alarm type.
+ Ignored if the alarm is not an #Email type.
+
+ @param text is a string containing the body text of a mail message
+ when an #Email type alarm is triggered.
+
+ @see setMailSubject(), setMailAddress(), setMailAddresses(),
+ setMailAttachment(), setMailAttachments()
+ */
+ void setMailText( const QString &text );
+
+ /**
+ Returns the body text for an #Email alarm type.
+ Returns an empty string if the alarm is not an #Email type.
+
+ @see setMailText()
+ */
+ QString mailText() const;
+
+ /**
+ Sets the trigger time of the alarm.
+
+ @param alarmTime is the KDateTime alarm trigger.
+
+ @see time()
+ */
+ void setTime( const KDateTime &alarmTime );
+
+ /**
+ Returns the alarm trigger date/time.
+
+ @see setTime()
+ */
+ KDateTime time() const;
+
+ /**
+ Returns the next alarm trigger date/time after given date/time.
+ Takes recurrent incidences into account.
+
+ @param preTime date/time from where to start
+ @param ignoreRepetitions don't take repetitions into account
+ @see nextRepetition()
+ */
+ KDateTime nextTime( const KDateTime &preTime, bool ignoreRepetitions = false ) const;
+
+ /**
+ Returns the date/time when the last repetition of the alarm goes off.
+ If the alarm does not repeat this is equivalent to calling time().
+
+ @see setTime()
+ */
+ KDateTime endTime() const;
+
+ /**
+ Returns true if the alarm has a trigger date/time.
+ */
+ bool hasTime() const;
+
+ /**
+ Sets the alarm offset relative to the start of the parent Incidence.
+
+ @param offset is a Duration to be used as a time relative to the
+ start of the parent Incidence to be used as the alarm trigger.
+
+ @see setEndOffset(), startOffset(), endOffset()
+ */
+ void setStartOffset( const Duration &offset );
+
+ /**
+ Returns offset of alarm in time relative to the start of the parent
+ Incidence. If the alarm's time is not defined in terms of an offset
+ relative to the start of the event, returns zero.
+
+ @see setStartOffset(), hasStartOffset()
+ */
+ Duration startOffset() const;
+
+ /**
+ Returns whether the alarm is defined in terms of an offset relative
+ to the start of the parent Incidence.
+
+ @see startOffset(), setStartOffset()
+ */
+ bool hasStartOffset() const;
+
+ /**
+ Sets the alarm offset relative to the end of the parent Incidence.
+
+ @param offset is a Duration to be used as a time relative to the
+ end of the parent Incidence to be used as the alarm trigger.
+
+ @see setStartOffset(), startOffset(), endOffset()
+ */
+ void setEndOffset( const Duration &offset );
+
+ /**
+ Returns offset of alarm in time relative to the end of the event.
+ If the alarm's time is not defined in terms of an offset relative
+ to the end of the event, returns zero.
+
+ @see setEndOffset(), hasEndOffset()
+ */
+ Duration endOffset() const;
+
+ /**
+ Returns whether the alarm is defined in terms of an offset relative
+ to the end of the event.
+
+ @see endOffset(), setEndOffset()
+ */
+ bool hasEndOffset() const;
+
+ /**
+ Shift the times of the alarm so that they appear at the same clock
+ time as before but in a new time zone. The shift is done from a viewing
+ time zone rather than from the actual alarm time zone.
+
+ For example, shifting an alarm whose start time is 09:00 America/New York,
+ using an old viewing time zone (@p oldSpec) of Europe/London, to a new
+ time zone (@p newSpec) of Europe/Paris, will result in the time being
+ shifted from 14:00 (which is the London time of the alarm start) to
+ 14:00 Paris time.
+
+ @param oldSpec the time specification which provides the clock times
+ @param newSpec the new time specification
+ */
+ void shiftTimes( const KDateTime::Spec &oldSpec,
+ const KDateTime::Spec &newSpec );
+
+ /**
+ Sets the snooze time interval for the alarm.
+
+ @param alarmSnoozeTime the time between snoozes.
+
+ @see snoozeTime()
+ */
+ void setSnoozeTime( const Duration &alarmSnoozeTime );
+
+ /**
+ Returns the snooze time interval.
+
+ @see setSnoozeTime()
+ */
+ Duration snoozeTime() const;
+
+ /**
+ Sets how many times an alarm is to repeat itself after its initial
+ occurrence (w/snoozes).
+
+ @param alarmRepeatCount is the number of times an alarm may repeat,
+ excluding the initial occurrence.
+
+ @see repeatCount()
+ */
+ void setRepeatCount( int alarmRepeatCount );
+
+ /**
+ Returns how many times an alarm may repeats after its initial occurrence.
+
+ @see setRepeatCount()
+ */
+ int repeatCount() const;
+
+ /**
+ Returns the date/time of the alarm's initial occurrence or its next
+ repetition after a given time.
+
+ @param preTime the date/time after which to find the next repetition.
+
+ @return the date/time of the next repetition, or an invalid date/time
+ if the specified time is at or after the alarm's last repetition.
+
+ @see previousRepetition()
+ */
+ KDateTime nextRepetition( const KDateTime &preTime ) const;
+
+ /**
+ Returns the date/time of the alarm's latest repetition or, if none,
+ its initial occurrence before a given time.
+
+ @param afterTime is the date/time before which to find the latest
+ repetition.
+
+ @return the date and time of the latest repetition, or an invalid
+ date/time if the specified time is at or before the alarm's initial
+ occurrence.
+
+ @see nextRepetition()
+ */
+ KDateTime previousRepetition( const KDateTime &afterTime ) const;
+
+ /**
+ Returns the interval between the alarm's initial occurrence and
+ its final repetition.
+ */
+ Duration duration() const;
+
+ /**
+ Toggles the alarm status, i.e, an enable alarm becomes disabled
+ and a disabled alarm becomes enabled.
+
+ @see enabled(), setEnabled()
+ */
+ void toggleAlarm();
+
+ /**
+ Sets the enabled status of the alarm.
+ @param enable if true, then enable the alarm; else disable the alarm.
+
+ @see enabled(), toggleAlarm()
+ */
+ void setEnabled( bool enable );
+
+ /**
+ Returns the alarm enabled status: true (enabled) or false (disabled).
+
+ @see setEnabled(), toggleAlarm()
+ */
+ bool enabled() const;
+
+ /**
+ Set if the location radius for the alarm has been defined.
+ @param hasLocationRadius if true, then this alarm has a location radius.
+
+ @see setLocationRadius()
+ */
+ void setHasLocationRadius( bool hasLocationRadius );
+
+ /**
+ Returns true if alarm has location radius defined.
+
+ @see setLocationRadius()
+ */
+ bool hasLocationRadius() const;
+
+ /**
+ Set location radius for the alarm. This means that alarm will be
+ triggered when user approaches the location. Given value will be
+ stored into custom properties as X-LOCATION-RADIUS.
+
+ @param locationRadius radius in meters
+ @see locationRadius()
+ */
+ void setLocationRadius( int locationRadius );
+
+ /**
+ Returns the location radius in meters.
+
+ @see setLocationRadius()
+ */
+ int locationRadius() const;
+
+ protected:
+ /**
+ @copydoc
+ CustomProperties::customPropertyUpdated()
+ */
+ virtual void customPropertyUpdated();
+
+ /**
+ @copydoc
+ IncidenceBase::virtual_hook()
+ */
+ virtual void virtual_hook( int id, void *data );
+
+ private:
+ //@cond PRIVATE
+ class Private;
+ Private *const d;
+ //@endcond
+};
+
+}
+
+Q_DECLARE_TYPEINFO( KCalCore::Alarm::Ptr, Q_MOVABLE_TYPE );
+
+#endif
diff --git a/kcalcore/attachment.cpp b/kcalcore/attachment.cpp
new file mode 100644
index 0000000..b80ec11
--- /dev/null
+++ b/kcalcore/attachment.cpp
@@ -0,0 +1,240 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2002 Michael Brade <brade@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Attachment class.
+
+ @brief
+ Represents information related to an attachment for a Calendar Incidence.
+
+ @author Michael Brade \<brade@kde.org\>
+*/
+
+#include "attachment.h"
+
+using namespace KCalCore;
+
+/**
+ Private class that helps to provide binary compatibility between releases.
+ @internal
+*/
+//@cond PRIVATE
+class KCalCore::Attachment::Private
+{
+ public:
+ Private( const QString &mime, bool binary )
+ : mSize( 0 ),
+ mMimeType( mime ),
+ mBinary( binary ),
+ mLocal( false ),
+ mShowInline( false )
+ {}
+ Private( const Private &other )
+ : mSize( other.mSize ),
+ mMimeType( other.mMimeType ),
+ mUri( other.mUri ),
+ mEncodedData( other.mEncodedData ),
+ mLabel( other.mLabel ),
+ mBinary( other.mBinary ),
+ mLocal( other.mLocal ),
+ mShowInline( other.mShowInline )
+ {}
+
+ ~Private()
+ {
+ }
+
+ QByteArray mDecodedDataCache;
+ uint mSize;
+ QString mMimeType;
+ QString mUri;
+ QByteArray mEncodedData;
+ QString mLabel;
+ bool mBinary;
+ bool mLocal;
+ bool mShowInline;
+};
+//@endcond
+
+Attachment::Attachment( const Attachment &attachment )
+ : d( new Attachment::Private( *attachment.d ) )
+{
+}
+
+Attachment::Attachment( const QString &uri, const QString &mime )
+ : d( new Attachment::Private( mime, false ) )
+{
+ d->mUri = uri;
+}
+
+Attachment::Attachment( const QByteArray &base64, const QString &mime )
+ : d( new Attachment::Private( mime, true ) )
+{
+ d->mEncodedData = base64;
+}
+
+Attachment::~Attachment()
+{
+ delete d;
+}
+
+bool Attachment::isUri() const
+{
+ return !d->mBinary;
+}
+
+QString Attachment::uri() const
+{
+ if ( !d->mBinary ) {
+ return d->mUri;
+ } else {
+ return QString();
+ }
+}
+
+void Attachment::setUri( const QString &uri )
+{
+ d->mUri = uri;
+ d->mBinary = false;
+}
+
+bool Attachment::isBinary() const
+{
+ return d->mBinary;
+}
+
+QByteArray Attachment::data() const
+{
+ if ( d->mBinary ) {
+ return d->mEncodedData;
+ } else {
+ return QByteArray();
+ }
+}
+
+QByteArray Attachment::decodedData() const
+{
+ if ( d->mDecodedDataCache.isNull() ) {
+ d->mDecodedDataCache = QByteArray::fromBase64( d->mEncodedData );
+ }
+
+ return d->mDecodedDataCache;
+}
+
+void Attachment::setDecodedData( const QByteArray &data )
+{
+ setData( data.toBase64() );
+ d->mDecodedDataCache = data;
+ d->mSize = d->mDecodedDataCache.size();
+}
+
+void Attachment::setData( const QByteArray &base64 )
+{
+ d->mEncodedData = base64;
+ d->mBinary = true;
+ d->mDecodedDataCache = QByteArray();
+ d->mSize = 0;
+}
+
+uint Attachment::size() const
+{
+ if ( isUri() ) {
+ return 0;
+ }
+ if ( !d->mSize ) {
+ d->mSize = decodedData().size();
+ }
+
+ return d->mSize;
+}
+
+QString Attachment::mimeType() const
+{
+ return d->mMimeType;
+}
+
+void Attachment::setMimeType( const QString &mime )
+{
+ d->mMimeType = mime;
+}
+
+bool Attachment::showInline() const
+{
+ return d->mShowInline;
+}
+
+void Attachment::setShowInline( bool showinline )
+{
+ d->mShowInline = showinline;
+}
+
+QString Attachment::label() const
+{
+ return d->mLabel;
+}
+
+void Attachment::setLabel( const QString &label )
+{
+ d->mLabel = label;
+}
+
+bool Attachment::isLocal() const
+{
+ return d->mLocal;
+}
+
+void Attachment::setLocal( bool local )
+{
+ d->mLocal = local;
+}
+
+Attachment &Attachment::operator=( const Attachment &other )
+{
+ if ( this != &other ) {
+ d->mSize = other.d->mSize;
+ d->mMimeType = other.d->mMimeType;
+ d->mUri = other.d->mUri;
+ d->mEncodedData = other.d->mEncodedData;
+ d->mLabel = other.d->mLabel;
+ d->mBinary = other.d->mBinary;
+ d->mLocal = other.d->mLocal;
+ d->mShowInline = other.d->mShowInline;
+ }
+
+ return *this;
+}
+
+bool Attachment::operator==( const Attachment &a2 ) const
+{
+ return uri() == a2.uri() &&
+ d->mLabel == a2.label() &&
+ d->mLocal == a2.isLocal() &&
+ d->mBinary == a2.isBinary() &&
+ d->mShowInline == a2.showInline() &&
+ size() == a2.size() &&
+ decodedData() == a2.decodedData();
+}
+
+bool Attachment::operator!=( const Attachment &a2 ) const
+{
+ return !( *this == a2 );
+}
diff --git a/kcalcore/attachment.h b/kcalcore/attachment.h
new file mode 100644
index 0000000..e614103
--- /dev/null
+++ b/kcalcore/attachment.h
@@ -0,0 +1,274 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2002 Michael Brade <brade@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Attachment class.
+
+ @author Michael Brade \<brade@kde.org\>
+*/
+
+#ifndef KCALCORE_ATTACHMENT_H
+#define KCALCORE_ATTACHMENT_H
+
+#include "kcalcore_export.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QString>
+#include <QtCore/QSharedPointer>
+
+namespace KCalCore {
+
+/**
+ @brief
+ Represents information related to an attachment for a Calendar Incidence.
+
+ This is not an email message attachment.
+
+ Calendar Incidence attachments consist of:
+ - A <a href="http://en.wikipedia.org/wiki/Uniform_Resource_Identifier">
+ Uniform Resource Identifier (URI)</a>
+ or a
+ <a href="http://en.wikipedia.org/wiki/Base64#MIME">base64 encoded</a>
+ binary blob.
+ - A <a href="http://en.wikipedia.org/wiki/MIME">
+ Multipurpose Internet Mail Extensions (MIME)</a> type.
+
+ This class is used to associate files (local or remote) or other resources
+ with a Calendar Incidence.
+*/
+class KCALCORE_EXPORT Attachment
+{
+ public:
+ /**
+ A shared pointer to an Attachment object.
+ */
+ typedef QSharedPointer<Attachment> Ptr;
+
+ /**
+ List of attachments.
+ */
+ typedef QVector<Ptr> List;
+
+ /**
+ Constructs an attachment consisting of a @p uri and a @p mime type.
+
+ @param uri is the @acronym URI referred to by this attachment.
+ @param mime is the (optional) @acronym MIME type of the @p uri
+ */
+ explicit Attachment( const QString &uri, const QString &mime = QString() );
+
+ /**
+ Constructs an attachment consisting of a binary blob of data
+ and a @p mime type.
+
+ @param base64 is the binary data in base64 format for the attachment.
+ @param mime is the (optional) @acronym MIME type of the attachment
+ */
+ explicit Attachment( const QByteArray &base64,
+ const QString &mime = QString() );
+
+ /**
+ Constructs an attachment by copying another attachment.
+
+ @param attachment is the attachment to be copied.
+ */
+ Attachment( const Attachment &attachment );
+
+ /**
+ Destroys the attachment.
+ */
+ ~Attachment();
+
+ /**
+ Sets the @acronym URI for this attachment to @p uri.
+
+ @param uri is the @acronym URI to use for the attachment.
+
+ @see uri(), isUri()
+ */
+ void setUri( const QString &uri );
+
+ /**
+ Returns the @acronym URI of the attachment.
+
+ @see setUri(), isUri()
+ */
+ QString uri() const;
+
+ /**
+ Returns true if the attachment has a @acronym URI; false otherwise.
+
+ @see uri(), setUri(I), isBinary()
+ */
+ bool isUri() const;
+
+ /**
+ Returns true if the attachment has a binary blob; false otherwise.
+
+ @see isUri()
+ */
+ bool isBinary() const;
+
+ /**
+ Sets the base64 encoded binary blob data of the attachment.
+
+ @param base64 contains the base64 encoded binary data.
+
+ @see data(), decodedData()
+ */
+ void setData( const QByteArray &base64 );
+
+ /**
+ Returns a pointer to a QByteArray containing the base64 encoded
+ binary data of the attachment.
+
+ @see setData(), setDecodedData()
+ */
+ QByteArray data() const;
+
+ /**
+ Sets the decoded attachment data.
+
+ @param data is the decoded base64 binary data.
+
+ @see decodedData(), data()
+ */
+ void setDecodedData( const QByteArray &data );
+
+ /**
+ Returns a QByteArray containing the decoded base64 binary data of the
+ attachment.
+
+ @see setDecodedData(), setData()
+ */
+ QByteArray decodedData() const;
+
+ /**
+ Returns the size of the attachment, in bytes.
+ If the attachment is binary (i.e, there is no @acronym URI associated
+ with the attachment) then a value of 0 is returned.
+ */
+ uint size() const;
+
+ /**
+ Sets the @acronym MIME-type of the attachment to @p mime.
+
+ @param mime is the string to use for the attachment @acronym MIME-type.
+
+ @see mimeType()
+ */
+ void setMimeType( const QString &mime );
+
+ /**
+ Returns the @acronym MIME-type of the attachment.
+
+ @see setMimeType()
+ */
+ QString mimeType() const;
+
+ /**
+ Sets the attachment "show in-line" option, which is derived from
+ the Calendar Incidence @b X-CONTENT-DISPOSITION parameter.
+
+ @param showinline is the flag to set (true) or unset (false)
+ for the attachment "show in-line" option.
+
+ @see showInline()
+ */
+ void setShowInline( bool showinline );
+
+ /**
+ Returns the attachment "show in-line" flag.
+
+ @see setShowInline()
+ */
+ bool showInline() const;
+
+ /**
+ Sets the attachment label to @p label, which is derived from
+ the Calendar Incidence @b X-LABEL parameter.
+
+ @param label is the string to use for the attachment label.
+
+ @see label()
+ */
+ void setLabel( const QString &label );
+
+ /**
+ Returns the attachment label string.
+ */
+ QString label() const;
+
+ /**
+ Sets the attachment "local" option, which is derived from the
+ Calendar Incidence @b X-KONTACT-TYPE parameter.
+
+ @param local is the flag to set (true) or unset (false) for the
+ attachment "local" option.
+
+ @see local()
+ */
+ void setLocal( bool local );
+
+ /**
+ Returns the attachment "local" flag.
+ */
+ bool isLocal() const;
+
+ /**
+ Assignment operator.
+ */
+ Attachment &operator=( const Attachment &attachment );
+
+ /**
+ Compare this with @p attachment for equality.
+ @param attachment is the attachment to compare.
+ @return true if the attachments are equal; false otherwise.
+ */
+ bool operator==( const Attachment &attachment ) const;
+
+ /**
+ Compare this with @p attachment for inequality.
+ @param attachment is the attachment to compare.
+ @return true if the attachments are /not/ equal; false otherwise.
+ */
+ bool operator!=( const Attachment &attachment ) const;
+
+ private:
+ //@cond PRIVATE
+ class Private;
+ Private *const d;
+ //@endcond
+};
+
+}
+
+Q_DECLARE_TYPEINFO( KCalCore::Attachment::Ptr, Q_MOVABLE_TYPE );
+
+//@cond PRIVATE
+inline uint qHash( const QSharedPointer<KCalCore::Attachment> &key )
+{
+ return qHash<KCalCore::Attachment>( key.data() );
+}
+//@endcond
+
+#endif
diff --git a/kcalcore/attendee.cpp b/kcalcore/attendee.cpp
new file mode 100644
index 0000000..900c7ec
--- /dev/null
+++ b/kcalcore/attendee.cpp
@@ -0,0 +1,228 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (C) 2010 Casey Link <unnamedrambler@gmail.com>
+ Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Attendee class.
+
+ @brief
+ Represents information related to an attendee of an Calendar Incidence.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#include "attendee.h"
+using namespace KCalCore;
+
+/**
+ Private class that helps to provide binary compatibility between releases.
+ @internal
+*/
+//@cond PRIVATE
+class KCalCore::Attendee::Private
+{
+ public:
+ bool mRSVP;
+ Role mRole;
+ PartStat mStatus;
+ QString mUid;
+ QString mDelegate;
+ QString mDelegator;
+ CustomProperties mCustomProperties;
+};
+//@endcond
+
+Attendee::Attendee( const QString &name, const QString &email, bool rsvp,
+ Attendee::PartStat status, Attendee::Role role, const QString &uid )
+ : d( new Attendee::Private )
+{
+ setName( name );
+ setEmail( email );
+ d->mRSVP = rsvp;
+ d->mStatus = status;
+ d->mRole = role;
+ d->mUid = uid;
+}
+
+Attendee::Attendee( const Attendee &attendee )
+ : Person( attendee ),
+ d( new Attendee::Private( *attendee.d ) )
+{
+}
+
+Attendee::~Attendee()
+{
+ delete d;
+}
+
+bool KCalCore::Attendee::operator==( const Attendee &attendee ) const
+{
+ return
+ ( Person & )*this == ( const Person & )attendee &&
+ d->mRSVP == attendee.d->mRSVP &&
+ d->mRole == attendee.d->mRole &&
+ d->mStatus == attendee.d->mStatus &&
+ d->mUid == attendee.d->mUid &&
+ d->mDelegate == attendee.d->mDelegate &&
+ d->mDelegator == attendee.d->mDelegator;
+}
+
+bool KCalCore::Attendee::operator!=( const Attendee &attendee ) const
+{
+ return !operator==( attendee );
+}
+
+Attendee &KCalCore::Attendee::operator=( const Attendee &attendee )
+{
+ // check for self assignment
+ if ( &attendee == this ) {
+ return *this;
+ }
+
+ *d = *attendee.d;
+ setName( attendee.name() );
+ setEmail( attendee.email() );
+ return *this;
+}
+
+void Attendee::setRSVP( bool r )
+{
+ d->mRSVP = r;
+}
+
+bool Attendee::RSVP() const
+{
+ return d->mRSVP;
+}
+
+void Attendee::setStatus( Attendee::PartStat status )
+{
+ d->mStatus = status;
+}
+
+Attendee::PartStat Attendee::status() const
+{
+ return d->mStatus;
+}
+
+void Attendee::setRole( Attendee::Role role )
+{
+ d->mRole = role;
+}
+
+Attendee::Role Attendee::role() const
+{
+ return d->mRole;
+}
+
+void Attendee::setUid( const QString &uid )
+{
+ d->mUid = uid;
+}
+
+QString Attendee::uid() const
+{
+ return d->mUid;
+}
+
+void Attendee::setDelegate( const QString &delegate )
+{
+ d->mDelegate = delegate;
+}
+
+QString Attendee::delegate() const
+{
+ return d->mDelegate;
+}
+
+void Attendee::setDelegator( const QString &delegator )
+{
+ d->mDelegator = delegator;
+}
+
+QString Attendee::delegator() const
+{
+ return d->mDelegator;
+}
+
+void Attendee::setCustomProperty( const QByteArray &xname, const QString &xvalue )
+{
+ d->mCustomProperties.setNonKDECustomProperty( xname, xvalue );
+}
+
+CustomProperties &Attendee::customProperties()
+{
+ return d->mCustomProperties;
+}
+
+const CustomProperties &Attendee::customProperties() const
+{
+ return d->mCustomProperties;
+}
+
+QDataStream &KCalCore::operator<<( QDataStream &stream, const KCalCore::Attendee::Ptr &attendee )
+{
+ KCalCore::Person::Ptr p( new KCalCore::Person( *( (Person *)attendee.data() ) ) );
+ stream << p;
+ return stream << attendee->d->mRSVP
+ << int( attendee->d->mRole )
+ << int( attendee->d->mStatus )
+ << attendee->d->mUid
+ << attendee->d->mDelegate
+ << attendee->d->mDelegator
+ << attendee->d->mCustomProperties;
+}
+
+QDataStream &KCalCore::operator>>( QDataStream &stream, KCalCore::Attendee::Ptr &attendee )
+{
+ bool RSVP;
+ Attendee::Role role;
+ Attendee::PartStat status;
+ QString uid;
+ QString delegate;
+ QString delegator;
+ CustomProperties customProperties;
+ uint role_int;
+ uint status_int;
+
+ KCalCore::Person::Ptr person( new Person() );
+ stream >> person;
+ stream >> RSVP
+ >> role_int
+ >> status_int
+ >> uid
+ >> delegate
+ >> delegator
+ >> customProperties;
+
+ role = Attendee::Role( role_int );
+ status = Attendee::PartStat( status_int );
+
+ Attendee::Ptr att_temp( new KCalCore::Attendee( person->name(), person->email(),
+ RSVP, status, role, uid ) );
+ att_temp->setDelegate( delegate );
+ att_temp->setDelegator( delegator );
+ att_temp->d->mCustomProperties = customProperties;
+ attendee.swap( att_temp );
+ return stream;
+}
diff --git a/kcalcore/attendee.h b/kcalcore/attendee.h
new file mode 100644
index 0000000..6319cb2
--- /dev/null
+++ b/kcalcore/attendee.h
@@ -0,0 +1,293 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001-2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Attendee class.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#ifndef KCALCORE_ATTENDEE_H
+#define KCALCORE_ATTENDEE_H
+
+#include <QtCore/QMetaType>
+
+#include "kcalcore_export.h"
+#include "customproperties.h"
+#include "person.h"
+
+namespace KCalCore {
+
+/**
+ @brief
+ Represents information related to an attendee of an Calendar Incidence,
+ typically a meeting or task (to-do).
+
+ Attendees are people with a name and (optional) email address who are
+ invited to participate in some way in a meeting or task. This class
+ also tracks that status of the invitation: accepted; tentatively accepted;
+ declined; delegated to another person; in-progress; completed.
+
+ Attendees may optionally be asked to @acronym RSVP ("Respond Please") to
+ the invitation.
+
+ Note that each attendee be can optionally associated with a @acronym UID
+ (unique identifier) derived from a Calendar Incidence, Email Message,
+ or any other thing you want.
+*/
+class KCALCORE_EXPORT Attendee : private Person
+{
+ public:
+ using Person::setEmail;
+ using Person::email;
+ using Person::setName;
+ using Person::name;
+ using Person::fullName;
+
+ /**
+ The different types of participant status.
+ The meaning is specific to the incidence type in context.
+ */
+ enum PartStat {
+ NeedsAction, /**< Event, to-do or journal needs action (default) */
+ Accepted, /**< Event, to-do or journal accepted */
+ Declined, /**< Event, to-do or journal declined */
+ Tentative, /**< Event or to-do tentatively accepted */
+ Delegated, /**< Event or to-do delegated */
+ Completed, /**< To-do completed */
+ InProcess, /**< To-do in process of being completed */
+ None
+ };
+
+ /**
+ The different types of participation roles.
+ */
+ enum Role {
+ ReqParticipant, /**< Participation is required (default) */
+ OptParticipant, /**< Participation is optional */
+ NonParticipant, /**< Non-Participant; copied for information purposes */
+ Chair /**< Chairperson */
+ };
+
+ /**
+ A shared pointer to an Attendee object.
+ */
+ typedef QSharedPointer<Attendee> Ptr;
+
+ /**
+ List of attendees.
+ */
+ typedef QVector<Ptr> List;
+
+ /**
+ Constructs an attendee consisting of a Person name (@p name) and
+ email address (@p email); invitation status and #Role;
+ an optional @acronym RSVP flag and @acronym UID.
+
+ @param name is person name of the attendee.
+ @param email is person email address of the attendee.
+ @param rsvp if true, the attendee is requested to reply to invitations.
+ @param status is the #PartStat status of the attendee.
+ @param role is the #Role of the attendee.
+ @param uid is the @acronym UID of the attendee.
+ */
+ Attendee( const QString &name, const QString &email,
+ bool rsvp = false, PartStat status = None,
+ Role role = ReqParticipant, const QString &uid = QString() );
+
+ /**
+ Constructs an attendee by copying another attendee.
+
+ @param attendee is the attendee to be copied.
+ */
+ Attendee( const Attendee &attendee );
+
+ /**
+ Destroys the attendee.
+ */
+ ~Attendee();
+
+ /**
+ Sets the Role of the attendee to @p role.
+
+ @param role is the Role to use for the attendee.
+
+ @see role()
+ */
+ void setRole( Role role );
+
+ /**
+ Returns the Role of the attendee.
+
+ @see setRole()
+ */
+ Role role() const;
+
+ /**
+ Sets the @acronym UID of the attendee to @p uid.
+
+ @param uid is the @acronym UID to use for the attendee.
+
+ @see uid()
+ */
+ void setUid ( const QString &uid );
+
+ /**
+ Returns the @acronym UID of the attendee.
+
+ @see setUid()
+ */
+ QString uid() const;
+
+ /**
+ Sets the #PartStat of the attendee to @p status.
+
+ @param status is the #PartStat to use for the attendee.
+
+ @see status()
+ */
+ void setStatus( PartStat status );
+
+ /**
+ Returns the #PartStat of the attendee.
+
+ @see setStatus()
+ */
+ PartStat status() const;
+
+ /**
+ Sets the @acronym RSVP flag of the attendee to @p rsvp.
+
+ @param rsvp if set (true), the attendee is requested to reply to
+ invitations.
+
+ @see RSVP()
+ */
+ void setRSVP( bool rsvp );
+
+ /**
+ Returns the attendee @acronym RSVP flag.
+
+ @see setRSVP()
+ */
+ bool RSVP() const;
+
+ /**
+ Compares this with @p attendee for equality.
+
+ @param attendee the attendee to compare.
+ */
+ bool operator==( const Attendee &attendee ) const;
+
+ /**
+ Compares this with @p attendee for inequality.
+
+ @param attendee the attendee to compare.
+ */
+ bool operator!=( const Attendee &attendee ) const;
+
+ /**
+ Sets the delegate.
+ @param delegate is a string containing a MAILTO URI of those delegated
+ to attend the meeting.
+ @see delegate(), setDelegator().
+ */
+ void setDelegate( const QString &delegate );
+
+ /**
+ Returns the delegate.
+ @see setDelegate().
+ */
+ QString delegate() const;
+
+ /**
+ Sets the delegator.
+ @param delegator is a string containing a MAILTO URI of those who
+ have delegated their meeting attendance.
+ @see delegator(), setDelegate().
+ */
+ void setDelegator( const QString &delegator );
+
+ /**
+ Returns the delegator.
+ @see setDelegator().
+ */
+ QString delegator() const;
+
+ /**
+ Adds a custom property. If the property already exists it will be overwritten.
+ @param xname is the name of the property.
+ @param xvalue is its value.
+ */
+ void setCustomProperty( const QByteArray &xname, const QString &xvalue );
+
+ /**
+ Returns a reference to the CustomProperties object
+ */
+ CustomProperties &customProperties();
+
+ /**
+ Returns a const reference to the CustomProperties object
+ */
+ const CustomProperties &customProperties() const;
+
+ /**
+ Sets this attendee equal to @p attendee.
+
+ @param attendee is the attendee to copy.
+ */
+ Attendee &operator=( const Attendee &attendee );
+
+ private:
+ //@cond PRIVATE
+ class Private;
+ Private *const d;
+ //@endcond
+
+ friend KCALCORE_EXPORT QDataStream &operator<<( QDataStream &s,
+ const KCalCore::Attendee::Ptr &attendee );
+ friend KCALCORE_EXPORT QDataStream &operator>>( QDataStream &s,
+ KCalCore::Attendee::Ptr &attendee );
+};
+
+/**
+ Serializes an Attendee object into a data stream.
+ @param stream is a QDataStream.
+ @param attendee is a pointer to a Attendee object to be serialized.
+*/
+KCALCORE_EXPORT QDataStream &operator<<( QDataStream &stream,
+ const KCalCore::Attendee::Ptr &attendee );
+
+/**
+ Initializes an Attendee object from a data stream.
+ @param stream is a QDataStream.
+ @param attendee is a pointer to a Attendee object to be initialized.
+*/
+KCALCORE_EXPORT QDataStream &operator>>( QDataStream &stream, KCalCore::Attendee::Ptr &attendee );
+}
+
+//@cond PRIVATE
+Q_DECLARE_TYPEINFO( KCalCore::Attendee::Ptr, Q_MOVABLE_TYPE );
+Q_DECLARE_METATYPE( KCalCore::Attendee::Ptr )
+//@endcond
+
+#endif
diff --git a/kcalcore/calendar.cpp b/kcalcore/calendar.cpp
new file mode 100644
index 0000000..676d2f3
--- /dev/null
+++ b/kcalcore/calendar.cpp
@@ -0,0 +1,1502 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 1998 Preston Brown <pbrown@kde.org>
+ Copyright (c) 2000-2004 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+ Copyright (c) 2006 David Jarvie <software@astrojar.org.uk>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Calendar class.
+
+ @brief
+ Represents the main calendar class.
+
+ @author Preston Brown \<pbrown@kde.org\>
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+ @author Reinhold Kainhofer \<reinhold@kainhofer.com\>
+ @author David Jarvie \<software@astrojar.org.uk\>
+*/
+#include "calendar.h"
+#include "calfilter.h"
+#include "icaltimezones.h"
+#include "sorting.h"
+#include "visitor.h"
+
+#include <KDebug>
+
+extern "C" {
+ #include <icaltimezone.h>
+}
+
+#include <algorithm> // for std::remove()
+
+using namespace KCalCore;
+
+/**
+ Private class that helps to provide binary compatibility between releases.
+ @internal
+*/
+//@cond PRIVATE
+class KCalCore::Calendar::Private
+{
+ public:
+ Private()
+ : mTimeZones( new ICalTimeZones ),
+ mModified( false ),
+ mNewObserver( false ),
+ mObserversEnabled( true ),
+ mDefaultFilter( new CalFilter ),
+ batchAddingInProgress( false )
+ {
+ // Setup default filter, which does nothing
+ mFilter = mDefaultFilter;
+ mFilter->setEnabled( false );
+
+ mOwner = Person::Ptr( new Person() );
+ mOwner->setName( "Unknown Name" );
+ mOwner->setEmail( "unknown@nowhere" );
+ }
+
+ ~Private()
+ {
+ delete mTimeZones;
+ mTimeZones = 0;
+ if ( mFilter != mDefaultFilter ) {
+ delete mFilter;
+ }
+ delete mDefaultFilter;
+ }
+ KDateTime::Spec timeZoneIdSpec( const QString &timeZoneId, bool view );
+
+ QString mProductId;
+ Person::Ptr mOwner;
+ ICalTimeZones *mTimeZones; // collection of time zones used in this calendar
+ ICalTimeZone mBuiltInTimeZone; // cached time zone lookup
+ ICalTimeZone mBuiltInViewTimeZone; // cached viewing time zone lookup
+ KDateTime::Spec mTimeSpec;
+ mutable KDateTime::Spec mViewTimeSpec;
+ bool mModified;
+ bool mNewObserver;
+ bool mObserversEnabled;
+ QList<CalendarObserver*> mObservers;
+
+ CalFilter *mDefaultFilter;
+ CalFilter *mFilter;
+
+ // These lists are used to put together related To-dos
+ QMultiHash<QString, Incidence::Ptr> mOrphans;
+ QMultiHash<QString, Incidence::Ptr> mOrphanUids;
+
+ // Lists for associating incidences to notebooks
+ QMultiHash<QString, Incidence::Ptr >mNotebookIncidences;
+ QHash<QString, QString>mUidToNotebook;
+ QHash<QString, bool>mNotebooks; // name to visibility
+ QHash<Incidence::Ptr, bool>mIncidenceVisibility; // incidence -> visibility
+ QString mDefaultNotebook; // uid of default notebook
+ QMap<QString, Incidence::List > mIncidenceRelations;
+ bool batchAddingInProgress;
+
+};
+
+/**
+ Make a QHash::value that returns a QVector.
+*/
+template <typename K, typename V>
+QVector<V> values( const QMultiHash<K,V> &c )
+{
+ QVector<V> v;
+ v.reserve( c.size() );
+ for ( typename QMultiHash<K,V>::const_iterator it = c.begin(), end = c.end(); it != end; ++it ) {
+ v.push_back( it.value() );
+ }
+ return v;
+}
+
+template <typename K, typename V>
+QVector<V> values( const QMultiHash<K,V> &c, const K &x )
+{
+ QVector<V> v;
+ typename QMultiHash<K,V>::const_iterator it = c.find( x );
+ while ( it != c.end() && it.key() == x ) {
+ v.push_back( it.value() );
+ ++it;
+ }
+ return v;
+}
+
+/**
+ Template for a class that implements a visitor for adding an Incidence
+ to a resource supporting addEvent(), addTodo() and addJournal() calls.
+*/
+template<class T>
+class AddVisitor : public Visitor
+{
+ public:
+ AddVisitor( T *r ) : mResource( r ) {}
+
+ bool visit( Event::Ptr e )
+ {
+ return mResource->addEvent( e );
+ }
+ bool visit( Todo::Ptr t )
+ {
+ return mResource->addTodo( t );
+ }
+ bool visit( Journal::Ptr j )
+ {
+ return mResource->addJournal( j );
+ }
+ bool visit( FreeBusy::Ptr )
+ {
+ return false;
+ }
+
+ private:
+ T *mResource;
+};
+
+/**
+ Template for a class that implements a visitor for deleting an Incidence
+ from a resource supporting deleteEvent(), deleteTodo() and deleteJournal()
+ calls.
+*/
+template<class T>
+class DeleteVisitor : public Visitor
+{
+ public:
+ DeleteVisitor( T *r ) : mResource( r ) {}
+
+ bool visit( Event::Ptr e )
+ {
+ mResource->deleteEvent( e );
+ return true;
+ }
+ bool visit( Todo::Ptr t )
+ {
+ mResource->deleteTodo( t );
+ return true;
+ }
+ bool visit( Journal::Ptr j )
+ {
+ mResource->deleteJournal( j );
+ return true;
+ }
+ bool visit( FreeBusy::Ptr )
+ {
+ return false;
+ }
+
+ private:
+ T *mResource;
+};
+//@endcond
+
+Calendar::Calendar( const KDateTime::Spec &timeSpec )
+ : d( new KCalCore::Calendar::Private )
+{
+ d->mTimeSpec = timeSpec;
+ d->mViewTimeSpec = timeSpec;
+}
+
+Calendar::Calendar( const QString &timeZoneId )
+ : d( new KCalCore::Calendar::Private )
+{
+ setTimeZoneId( timeZoneId );
+}
+
+Calendar::~Calendar()
+{
+ delete d;
+}
+
+Person::Ptr Calendar::owner() const
+{
+ return d->mOwner;
+}
+
+void Calendar::setOwner( const Person::Ptr &owner )
+{
+ Q_ASSERT( owner );
+ d->mOwner = owner;
+ setModified( true );
+}
+
+void Calendar::setTimeSpec( const KDateTime::Spec &timeSpec )
+{
+ d->mTimeSpec = timeSpec;
+ d->mBuiltInTimeZone = ICalTimeZone();
+ setViewTimeSpec( timeSpec );
+
+ doSetTimeSpec( d->mTimeSpec );
+}
+
+KDateTime::Spec Calendar::timeSpec() const
+{
+ return d->mTimeSpec;
+}
+
+void Calendar::setTimeZoneId( const QString &timeZoneId )
+{
+ d->mTimeSpec = d->timeZoneIdSpec( timeZoneId, false );
+ d->mViewTimeSpec = d->mTimeSpec;
+ d->mBuiltInViewTimeZone = d->mBuiltInTimeZone;
+
+ doSetTimeSpec( d->mTimeSpec );
+}
+
+//@cond PRIVATE
+KDateTime::Spec Calendar::Private::timeZoneIdSpec( const QString &timeZoneId,
+ bool view )
+{
+ if ( view ) {
+ mBuiltInViewTimeZone = ICalTimeZone();
+ } else {
+ mBuiltInTimeZone = ICalTimeZone();
+ }
+ if ( timeZoneId == QLatin1String( "UTC" ) ) {
+ return KDateTime::UTC;
+ }
+ ICalTimeZone tz = mTimeZones->zone( timeZoneId );
+ if ( !tz.isValid() ) {
+ ICalTimeZoneSource tzsrc;
+ tz = tzsrc.parse( icaltimezone_get_builtin_timezone( timeZoneId.toLatin1() ) );
+ if ( view ) {
+ mBuiltInViewTimeZone = tz;
+ } else {
+ mBuiltInTimeZone = tz;
+ }
+ }
+ if ( tz.isValid() ) {
+ return tz;
+ } else {
+ return KDateTime::ClockTime;
+ }
+}
+//@endcond
+
+QString Calendar::timeZoneId() const
+{
+ KTimeZone tz = d->mTimeSpec.timeZone();
+ return tz.isValid() ? tz.name() : QString();
+}
+
+void Calendar::setViewTimeSpec( const KDateTime::Spec &timeSpec ) const
+{
+ d->mViewTimeSpec = timeSpec;
+ d->mBuiltInViewTimeZone = ICalTimeZone();
+}
+
+void Calendar::setViewTimeZoneId( const QString &timeZoneId ) const
+{
+ d->mViewTimeSpec = d->timeZoneIdSpec( timeZoneId, true );
+}
+
+KDateTime::Spec Calendar::viewTimeSpec() const
+{
+ return d->mViewTimeSpec;
+}
+
+QString Calendar::viewTimeZoneId() const
+{
+ KTimeZone tz = d->mViewTimeSpec.timeZone();
+ return tz.isValid() ? tz.name() : QString();
+}
+
+ICalTimeZones *Calendar::timeZones() const
+{
+ return d->mTimeZones;
+}
+
+void Calendar::setTimeZones( ICalTimeZones *zones )
+{
+ if ( !zones ) {
+ return;
+ }
+
+ if ( d->mTimeZones && ( d->mTimeZones != zones ) ) {
+ delete d->mTimeZones;
+ d->mTimeZones = 0;
+ }
+ d->mTimeZones = zones;
+}
+
+void Calendar::shiftTimes( const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec )
+{
+ setTimeSpec( newSpec );
+
+ int i, end;
+ Event::List ev = events();
+ for ( i = 0, end = ev.count(); i < end; ++i ) {
+ ev[i]->shiftTimes( oldSpec, newSpec );
+ }
+
+ Todo::List to = todos();
+ for ( i = 0, end = to.count(); i < end; ++i ) {
+ to[i]->shiftTimes( oldSpec, newSpec );
+ }
+
+ Journal::List jo = journals();
+ for ( i = 0, end = jo.count(); i < end; ++i ) {
+ jo[i]->shiftTimes( oldSpec, newSpec );
+ }
+}
+
+void Calendar::setFilter( CalFilter *filter )
+{
+ if ( filter ) {
+ d->mFilter = filter;
+ } else {
+ d->mFilter = d->mDefaultFilter;
+ }
+}
+
+CalFilter *Calendar::filter() const
+{
+ return d->mFilter;
+}
+
+QStringList Calendar::categories() const
+{
+ Incidence::List rawInc( rawIncidences() );
+ QStringList cats, thisCats;
+ // @TODO: For now just iterate over all incidences. In the future,
+ // the list of categories should be built when reading the file.
+ for ( Incidence::List::ConstIterator i = rawInc.constBegin();
+ i != rawInc.constEnd(); ++i ) {
+ thisCats = (*i)->categories();
+ for ( QStringList::ConstIterator si = thisCats.constBegin();
+ si != thisCats.constEnd(); ++si ) {
+ if ( !cats.contains( *si ) ) {
+ cats.append( *si );
+ }
+ }
+ }
+ return cats;
+}
+
+Incidence::List Calendar::incidences( const QDate &date ) const
+{
+ return mergeIncidenceList( events( date ), todos( date ), journals( date ) );
+}
+
+Incidence::List Calendar::incidences() const
+{
+ return mergeIncidenceList( events(), todos(), journals() );
+}
+
+Incidence::List Calendar::rawIncidences() const
+{
+ return mergeIncidenceList( rawEvents(), rawTodos(), rawJournals() );
+}
+
+Incidence::List Calendar::instances( const Incidence::Ptr &incidence ) const
+{
+ if ( incidence ) {
+ Event::List elist;
+ Todo::List tlist;
+ Journal::List jlist;
+
+ if ( incidence->type() == Incidence::TypeEvent ) {
+ elist = eventInstances( incidence );
+ } else if ( incidence->type() == Incidence::TypeTodo ) {
+ tlist = todoInstances( incidence );
+ } else if ( incidence->type() == Incidence::TypeJournal ) {
+ jlist = journalInstances( incidence );
+ }
+ return mergeIncidenceList( elist, tlist, jlist );
+ } else {
+ return Incidence::List();
+ }
+}
+
+Incidence::List Calendar::duplicates( const Incidence::Ptr &incidence )
+{
+ if ( incidence ) {
+ Incidence::List list;
+ Incidence::List vals = values( d->mNotebookIncidences );
+ Incidence::List::const_iterator it;
+ for ( it = vals.constBegin(); it != vals.constEnd(); ++it ) {
+ if ( ( ( incidence->dtStart() == (*it)->dtStart() ) ||
+ ( !incidence->dtStart().isValid() && !(*it)->dtStart().isValid() ) ) &&
+ ( incidence->summary() == (*it)->summary() ) ) {
+ list.append( *it );
+ }
+ }
+ return list;
+ } else {
+ return Incidence::List();
+ }
+}
+
+bool Calendar::addNotebook( const QString &notebook, bool isVisible )
+{
+ if ( d->mNotebooks.contains( notebook ) ) {
+ return false;
+ } else {
+ d->mNotebooks.insert( notebook, isVisible );
+ return true;
+ }
+}
+
+bool Calendar::updateNotebook( const QString &notebook, bool isVisible )
+{
+ if ( !d->mNotebooks.contains( notebook ) ) {
+ return false;
+ } else {
+ d->mNotebooks.insert( notebook, isVisible );
+ return true;
+ }
+}
+
+bool Calendar::deleteNotebook( const QString &notebook )
+{
+ if ( !d->mNotebooks.contains( notebook ) ) {
+ return false;
+ } else {
+ return d->mNotebooks.remove( notebook );
+ }
+}
+
+bool Calendar::setDefaultNotebook( const QString &notebook )
+{
+ if ( !d->mNotebooks.contains( notebook ) ) {
+ return false;
+ } else {
+ d->mDefaultNotebook = notebook;
+ return true;
+ }
+}
+
+QString Calendar::defaultNotebook() const
+{
+ return d->mDefaultNotebook;
+}
+
+bool Calendar::hasValidNotebook( const QString &notebook ) const
+{
+ return d->mNotebooks.contains( notebook );
+}
+
+bool Calendar::isVisible( const Incidence::Ptr &incidence ) const
+{
+ if ( d->mIncidenceVisibility.contains( incidence ) ) {
+ return d->mIncidenceVisibility[incidence];
+ }
+ const QString nuid = notebook( incidence );
+ bool rv;
+ if ( d->mNotebooks.contains( nuid ) ) {
+ rv = d->mNotebooks.value( nuid );
+ } else {
+ // NOTE returns true also for nonexisting notebooks for compatibility
+ rv = true;
+ }
+ d->mIncidenceVisibility[incidence] = rv;
+ return rv;
+}
+
+void Calendar::clearNotebookAssociations()
+{
+ d->mNotebookIncidences.clear();
+ d->mUidToNotebook.clear();
+ d->mIncidenceVisibility.clear();
+}
+
+bool Calendar::setNotebook( const Incidence::Ptr &inc, const QString &notebook )
+{
+ if ( !inc ) {
+ return false;
+ }
+
+ if ( !notebook.isEmpty() &&
+ !incidence( inc->uid(), inc->recurrenceId() ) ) {
+ kWarning() << "cannot set notebook until incidence has been added";
+ return false;
+ }
+
+ if ( d->mUidToNotebook.contains( inc->uid() ) ) {
+ QString old = d->mUidToNotebook.value( inc->uid() );
+ if ( !old.isEmpty() && notebook != old ) {
+ if ( inc->hasRecurrenceId() ) {
+ kWarning() << "cannot set notebook for child incidences";
+ return false;
+ }
+ // Move all possible children also.
+ Incidence::List list = instances( inc );
+ Incidence::List::Iterator it;
+ for ( it = list.begin(); it != list.end(); ++it ) {
+ d->mNotebookIncidences.remove( old, *it );
+ d->mNotebookIncidences.insert( notebook, *it );
+ }
+ notifyIncidenceChanged( inc ); // for removing from old notebook
+ // don not remove from mUidToNotebook to keep deleted incidences
+ d->mNotebookIncidences.remove( old, inc );
+ }
+ }
+ if ( !notebook.isEmpty() ) {
+ d->mUidToNotebook.insert( inc->uid(), notebook );
+ d->mNotebookIncidences.insert( notebook, inc );
+ kDebug() << "setting notebook" << notebook << "for" << inc->uid();
+ notifyIncidenceChanged( inc ); // for inserting into new notebook
+ }
+
+ return true;
+}
+
+QString Calendar::notebook( const Incidence::Ptr &incidence ) const
+{
+ if ( incidence ) {
+ return d->mUidToNotebook.value( incidence->uid() );
+ } else {
+ return QString();
+ }
+}
+
+QString Calendar::notebook( const QString &uid ) const
+{
+ return d->mUidToNotebook.value( uid );
+}
+
+QStringList Calendar::notebooks() const
+{
+ return d->mNotebookIncidences.uniqueKeys();
+}
+
+Incidence::List Calendar::incidences( const QString &notebook ) const
+{
+ if ( notebook.isEmpty() ) {
+ return values( d->mNotebookIncidences );
+ } else {
+ return values( d->mNotebookIncidences, notebook );
+ }
+}
+
+/** static */
+Event::List Calendar::sortEvents( const Event::List &eventList,
+ EventSortField sortField,
+ SortDirection sortDirection )
+{
+
+ if ( eventList.isEmpty() ) {
+ return Event::List();
+ }
+
+ Event::List eventListSorted;
+
+ // Notice we alphabetically presort Summaries first.
+ // We do this so comparison "ties" stay in a nice order.
+ eventListSorted = eventList;
+ switch( sortField ) {
+ case EventSortUnsorted:
+ break;
+
+ case EventSortStartDate:
+ if ( sortDirection == SortDirectionAscending ) {
+ qSort( eventListSorted.begin(), eventListSorted.end(), Events::startDateLessThan );
+ } else {
+ qSort( eventListSorted.begin(), eventListSorted.end(), Events::startDateMoreThan );
+ }
+ break;
+
+ case EventSortEndDate:
+ if ( sortDirection == SortDirectionAscending ) {
+ qSort( eventListSorted.begin(), eventListSorted.end(), Events::endDateLessThan );
+ } else {
+ qSort( eventListSorted.begin(), eventListSorted.end(), Events::endDateMoreThan );
+ }
+ break;
+
+ case EventSortSummary:
+ if ( sortDirection == SortDirectionAscending ) {
+ qSort( eventListSorted.begin(), eventListSorted.end(), Events::summaryLessThan );
+ } else {
+ qSort( eventListSorted.begin(), eventListSorted.end(), Events::summaryMoreThan );
+ }
+ break;
+ }
+
+ return eventListSorted;
+
+}
+
+Event::List Calendar::events( const QDate &date,
+ const KDateTime::Spec &timeSpec,
+ EventSortField sortField,
+ SortDirection sortDirection ) const
+{
+ Event::List el = rawEventsForDate( date, timeSpec, sortField, sortDirection );
+ d->mFilter->apply( &el );
+ return el;
+}
+
+Event::List Calendar::events( const KDateTime &dt ) const
+{
+ Event::List el = rawEventsForDate( dt );
+ d->mFilter->apply( &el );
+ return el;
+}
+
+Event::List Calendar::events( const QDate &start, const QDate &end,
+ const KDateTime::Spec &timeSpec,
+ bool inclusive ) const
+{
+ Event::List el = rawEvents( start, end, timeSpec, inclusive );
+ d->mFilter->apply( &el );
+ return el;
+}
+
+Event::List Calendar::events( EventSortField sortField,
+ SortDirection sortDirection ) const
+{
+ Event::List el = rawEvents( sortField, sortDirection );
+ d->mFilter->apply( &el );
+ return el;
+}
+
+bool Calendar::addIncidence( const Incidence::Ptr &incidence )
+{
+ if ( !incidence ) {
+ return false;
+ }
+
+ AddVisitor<Calendar> v( this );
+ return incidence->accept( v, incidence );
+}
+
+bool Calendar::deleteIncidence( const Incidence::Ptr &incidence )
+{
+ if ( !incidence ) {
+ return false;
+ }
+
+ if ( beginChange( incidence ) ) {
+ DeleteVisitor<Calendar> v( this );
+ const bool result = incidence->accept( v, incidence );
+ endChange( incidence );
+ return result;
+ } else {
+ return false;
+ }
+}
+
+// Dissociate a single occurrence or all future occurrences from a recurring
+// sequence. The new incidence is returned, but not automatically inserted
+// into the calendar, which is left to the calling application.
+Incidence::Ptr Calendar::dissociateOccurrence( const Incidence::Ptr &incidence,
+ const QDate &date,
+ const KDateTime::Spec &spec,
+ bool single )
+{
+ if ( !incidence || !incidence->recurs() ) {
+ return Incidence::Ptr();
+ }
+
+ Incidence::Ptr newInc( incidence->clone() );
+ newInc->recreate();
+ // Do not call setRelatedTo() when dissociating recurring to-dos, otherwise the new to-do
+ // will appear as a child. Originally, we planned to set a relation with reltype SIBLING
+ // when dissociating to-dos, but currently kcalcore only supports reltype PARENT.
+ // We can uncomment the following line when we support the PARENT reltype.
+ //newInc->setRelatedTo( incidence );
+ Recurrence *recur = newInc->recurrence();
+ if ( single ) {
+ recur->clear();
+ } else {
+ // Adjust the recurrence for the future incidences. In particular adjust
+ // the "end after n occurrences" rules! "No end date" and "end by ..."
+ // don't need to be modified.
+ int duration = recur->duration();
+ if ( duration > 0 ) {
+ int doneduration = recur->durationTo( date.addDays( -1 ) );
+ if ( doneduration >= duration ) {
+ kDebug() << "The dissociated event already occurred more often"
+ << "than it was supposed to ever occur. ERROR!";
+ recur->clear();
+ } else {
+ recur->setDuration( duration - doneduration );
+ }
+ }
+ }
+ // Adjust the date of the incidence
+ if ( incidence->type() == Incidence::TypeEvent ) {
+ Event::Ptr ev = newInc.staticCast<Event>();
+ KDateTime start( ev->dtStart() );
+ int daysTo = start.toTimeSpec( spec ).date().daysTo( date );
+ ev->setDtStart( start.addDays( daysTo ) );
+ ev->setDtEnd( ev->dtEnd().addDays( daysTo ) );
+ } else if ( incidence->type() == Incidence::TypeTodo ) {
+ Todo::Ptr td = newInc.staticCast<Todo>();
+ bool haveOffset = false;
+ int daysTo = 0;
+ if ( td->hasDueDate() ) {
+ KDateTime due( td->dtDue() );
+ daysTo = due.toTimeSpec( spec ).date().daysTo( date );
+ td->setDtDue( due.addDays( daysTo ), true );
+ haveOffset = true;
+ }
+ if ( td->hasStartDate() ) {
+ KDateTime start( td->dtStart() );
+ if ( !haveOffset ) {
+ daysTo = start.toTimeSpec( spec ).date().daysTo( date );
+ }
+ td->setDtStart( start.addDays( daysTo ) );
+ haveOffset = true;
+ }
+ }
+ recur = incidence->recurrence();
+ if ( recur ) {
+ if ( single ) {
+ recur->addExDate( date );
+ } else {
+ // Make sure the recurrence of the past events ends
+ // at the corresponding day
+ recur->setEndDate( date.addDays(-1) );
+ }
+ }
+ return newInc;
+}
+
+Incidence::Ptr Calendar::incidence( const QString &uid,
+ const KDateTime &recurrenceId ) const
+{
+ Incidence::Ptr i = event( uid, recurrenceId );
+ if ( i ) {
+ return i;
+ }
+
+ i = todo( uid, recurrenceId );
+ if ( i ) {
+ return i;
+ }
+
+ i = journal( uid, recurrenceId );
+ return i;
+}
+
+Incidence::Ptr Calendar::deleted( const QString &uid, const KDateTime &recurrenceId ) const
+{
+ Incidence::Ptr i = deletedEvent( uid, recurrenceId );
+ if ( i ) {
+ return i;
+ }
+
+ i = deletedTodo( uid, recurrenceId );
+ if ( i ) {
+ return i;
+ }
+
+ i = deletedJournal( uid, recurrenceId );
+ return i;
+}
+
+Incidence::List Calendar::incidencesFromSchedulingID( const QString &sid ) const
+{
+ Incidence::List result;
+ const Incidence::List incidences = rawIncidences();
+ Incidence::List::const_iterator it = incidences.begin();
+ for ( ; it != incidences.end(); ++it ) {
+ if ( (*it)->schedulingID() == sid ) {
+ result.append( *it );
+ }
+ }
+ return result;
+}
+
+Incidence::Ptr Calendar::incidenceFromSchedulingID( const QString &uid ) const
+{
+ const Incidence::List incidences = rawIncidences();
+ Incidence::List::const_iterator it = incidences.begin();
+ for ( ; it != incidences.end(); ++it ) {
+ if ( (*it)->schedulingID() == uid ) {
+ // Touchdown, and the crowd goes wild
+ return *it;
+ }
+ }
+ // Not found
+ return Incidence::Ptr();
+}
+
+/** static */
+Todo::List Calendar::sortTodos( const Todo::List &todoList,
+ TodoSortField sortField,
+ SortDirection sortDirection )
+{
+ if ( todoList.isEmpty() ) {
+ return Todo::List();
+ }
+
+ Todo::List todoListSorted;
+
+ // Notice we alphabetically presort Summaries first.
+ // We do this so comparison "ties" stay in a nice order.
+
+ // Note that To-dos may not have Start DateTimes nor due DateTimes.
+
+ todoListSorted = todoList;
+ switch( sortField ) {
+ case TodoSortUnsorted:
+ break;
+
+ case TodoSortStartDate:
+ if ( sortDirection == SortDirectionAscending ) {
+ qSort( todoListSorted.begin(), todoListSorted.end(), Todos::startDateLessThan );
+ } else {
+ qSort( todoListSorted.begin(), todoListSorted.end(), Todos::startDateMoreThan );
+ }
+ break;
+
+ case TodoSortDueDate:
+ if ( sortDirection == SortDirectionAscending ) {
+ qSort( todoListSorted.begin(), todoListSorted.end(), Todos::dueDateLessThan );
+ } else {
+ qSort( todoListSorted.begin(), todoListSorted.end(), Todos::dueDateMoreThan );
+ }
+ break;
+
+ case TodoSortPriority:
+ if ( sortDirection == SortDirectionAscending ) {
+ qSort( todoListSorted.begin(), todoListSorted.end(), Todos::priorityLessThan );
+ } else {
+ qSort( todoListSorted.begin(), todoListSorted.end(), Todos::priorityMoreThan );
+ }
+ break;
+
+ case TodoSortPercentComplete:
+ if ( sortDirection == SortDirectionAscending ) {
+ qSort( todoListSorted.begin(), todoListSorted.end(), Todos::percentLessThan );
+ } else {
+ qSort( todoListSorted.begin(), todoListSorted.end(), Todos::percentMoreThan );
+ }
+ break;
+
+ case TodoSortSummary:
+ if ( sortDirection == SortDirectionAscending ) {
+ qSort( todoListSorted.begin(), todoListSorted.end(), Todos::summaryLessThan );
+ } else {
+ qSort( todoListSorted.begin(), todoListSorted.end(), Todos::summaryMoreThan );
+ }
+ break;
+
+ case TodoSortCreated:
+ if ( sortDirection == SortDirectionAscending ) {
+ qSort( todoListSorted.begin(), todoListSorted.end(), Todos::createdLessThan );
+ } else {
+ qSort( todoListSorted.begin(), todoListSorted.end(), Todos::createdMoreThan );
+ }
+ break;
+ }
+
+ return todoListSorted;
+}
+
+Todo::List Calendar::todos( TodoSortField sortField,
+ SortDirection sortDirection ) const
+{
+ Todo::List tl = rawTodos( sortField, sortDirection );
+ d->mFilter->apply( &tl );
+ return tl;
+}
+
+Todo::List Calendar::todos( const QDate &date ) const
+{
+ Todo::List el = rawTodosForDate( date );
+ d->mFilter->apply( &el );
+ return el;
+}
+
+Todo::List Calendar::todos( const QDate &start, const QDate &end,
+ const KDateTime::Spec &timespec, bool inclusive ) const
+{
+ Todo::List tl = rawTodos( start, end, timespec, inclusive );
+ d->mFilter->apply( &tl );
+ return tl;
+}
+
+/** static */
+Journal::List Calendar::sortJournals( const Journal::List &journalList,
+ JournalSortField sortField,
+ SortDirection sortDirection )
+{
+ if ( journalList.isEmpty() ) {
+ return Journal::List();
+ }
+
+ Journal::List journalListSorted = journalList;
+
+ switch( sortField ) {
+ case JournalSortUnsorted:
+ break;
+
+ case JournalSortDate:
+ if ( sortDirection == SortDirectionAscending ) {
+ qSort( journalListSorted.begin(), journalListSorted.end(), Journals::dateLessThan );
+ } else {
+ qSort( journalListSorted.begin(), journalListSorted.end(), Journals::dateMoreThan );
+ }
+ break;
+
+ case JournalSortSummary:
+ if ( sortDirection == SortDirectionAscending ) {
+ qSort( journalListSorted.begin(), journalListSorted.end(), Journals::summaryLessThan );
+ } else {
+ qSort( journalListSorted.begin(), journalListSorted.end(), Journals::summaryMoreThan );
+ }
+ break;
+ }
+
+ return journalListSorted;
+}
+
+Journal::List Calendar::journals( JournalSortField sortField,
+ SortDirection sortDirection ) const
+{
+ Journal::List jl = rawJournals( sortField, sortDirection );
+ d->mFilter->apply( &jl );
+ return jl;
+}
+
+Journal::List Calendar::journals( const QDate &date ) const
+{
+ Journal::List el = rawJournalsForDate( date );
+ d->mFilter->apply( &el );
+ return el;
+}
+
+// When this is called, the to-dos have already been added to the calendar.
+// This method is only about linking related to-dos.
+void Calendar::setupRelations( const Incidence::Ptr &forincidence )
+{
+ if ( !forincidence ) {
+ return;
+ }
+
+ const QString uid = forincidence->uid();
+
+ // First, go over the list of orphans and see if this is their parent
+ Incidence::List l = values( d->mOrphans, uid );
+ d->mOrphans.remove( uid );
+ for ( int i = 0, end = l.count(); i < end; ++i ) {
+ d->mIncidenceRelations[uid].append( l[i] );
+ d->mOrphanUids.remove( l[i]->uid() );
+ }
+
+ // Now see about this incidences parent
+ if ( forincidence->relatedTo().isEmpty() && !forincidence->relatedTo().isEmpty() ) {
+ // Incidence has a uid it is related to but is not registered to it yet.
+ // Try to find it
+ Incidence::Ptr parent = incidence( forincidence->relatedTo() );
+ if ( parent ) {
+ // Found it
+
+ // look for hierarchy loops
+ if ( isAncestorOf( forincidence, parent ) ) {
+ forincidence->setRelatedTo( QString() );
+ kWarning() << "hierarchy loop beetween " << forincidence->uid() << " and " << parent->uid();
+ } else {
+ d->mIncidenceRelations[parent->uid()].append( forincidence );
+ }
+ } else {
+ // Not found, put this in the mOrphans list
+ // Note that the mOrphans dict might contain multiple entries with the
+ // same key! which are multiple children that wait for the parent
+ // incidence to be inserted.
+ d->mOrphans.insert( forincidence->relatedTo(), forincidence );
+ d->mOrphanUids.insert( forincidence->uid(), forincidence );
+ }
+ }
+}
+
+// If a to-do with sub-to-dos is deleted, move it's sub-to-dos to the orphan list
+void Calendar::removeRelations( const Incidence::Ptr &incidence )
+{
+ if ( !incidence ) {
+ kDebug() << "Warning: incidence is 0";
+ return;
+ }
+
+ const QString uid = incidence->uid();
+
+ foreach ( Incidence::Ptr i, d->mIncidenceRelations[uid] ) {
+ if ( !d->mOrphanUids.contains( i->uid() ) ) {
+ d->mOrphans.insert( uid, i );
+ d->mOrphanUids.insert( i->uid(), i );
+ i->setRelatedTo( uid );
+ }
+ }
+
+ const QString parentUid = incidence->relatedTo();
+
+ // If this incidence is related to something else, tell that about it
+ if ( !parentUid.isEmpty() ) {
+ d->mIncidenceRelations[parentUid].erase(
+ std::remove( d->mIncidenceRelations[parentUid].begin(),
+ d->mIncidenceRelations[parentUid].end(), incidence ),
+ d->mIncidenceRelations[parentUid].end() );
+ }
+
+ // Remove this one from the orphans list
+ if ( d->mOrphanUids.remove( uid ) ) {
+ // This incidence is located in the orphans list - it should be removed
+ // Since the mOrphans dict might contain the same key (with different
+ // child incidence pointers!) multiple times, take care that we remove
+ // the correct one. So we need to remove all items with the given
+ // parent UID, and readd those that are not for this item. Also, there
+ // might be other entries with differnet UID that point to this
+ // incidence (this might happen when the relatedTo of the item is
+ // changed before its parent is inserted. This might happen with
+ // groupware servers....). Remove them, too
+ QStringList relatedToUids;
+
+ // First, create a list of all keys in the mOrphans list which point
+ // to the removed item
+ relatedToUids << incidence->relatedTo();
+ for ( QMultiHash<QString, Incidence::Ptr>::Iterator it = d->mOrphans.begin();
+ it != d->mOrphans.end(); ++it ) {
+ if ( it.value()->uid() == uid ) {
+ relatedToUids << it.key();
+ }
+ }
+
+ // now go through all uids that have one entry that point to the incidence
+ for ( QStringList::const_iterator uidit = relatedToUids.constBegin();
+ uidit != relatedToUids.constEnd(); ++uidit ) {
+ Incidence::List tempList;
+ // Remove all to get access to the remaining entries
+ QList<Incidence::Ptr> l = d->mOrphans.values( *uidit );
+ d->mOrphans.remove( *uidit );
+ foreach ( Incidence::Ptr i, l ) {
+ if ( i != incidence ) {
+ tempList.append( i );
+ }
+ }
+ // Readd those that point to a different orphan incidence
+ for ( Incidence::List::Iterator incit = tempList.begin();
+ incit != tempList.end(); ++incit ) {
+ d->mOrphans.insert( *uidit, *incit );
+ }
+ }
+ }
+
+ // Make sure the deleted incidence doesn't relate to a non-deleted incidence,
+ // since that would cause trouble in MemoryCalendar::close(), as the deleted
+ // incidences are destroyed after the non-deleted incidences. The destructor
+ // of the deleted incidences would then try to access the already destroyed
+ // non-deleted incidence, which would segfault.
+ //
+ // So in short: Make sure dead incidences don't point to alive incidences
+ // via the relation.
+ //
+ // This crash is tested in MemoryCalendarTest::testRelationsCrash().
+// incidence->setRelatedTo( Incidence::Ptr() );
+}
+
+bool Calendar::isAncestorOf( const Incidence::Ptr &ancestor,
+ const Incidence::Ptr &incidence ) const
+{
+ if ( !incidence || incidence->relatedTo().isEmpty() ) {
+ return false;
+ } else if ( incidence->relatedTo() == ancestor->uid() ) {
+ return true;
+ } else {
+ return isAncestorOf( ancestor, this->incidence( incidence->relatedTo() ) );
+ }
+}
+
+Incidence::List Calendar::relations( const QString &uid ) const
+{
+ return d->mIncidenceRelations[uid];
+}
+
+Calendar::CalendarObserver::~CalendarObserver()
+{
+}
+
+void Calendar::CalendarObserver::calendarModified( bool modified, Calendar *calendar )
+{
+ Q_UNUSED( modified );
+ Q_UNUSED( calendar );
+}
+
+void Calendar::CalendarObserver::calendarIncidenceAdded( const Incidence::Ptr &incidence )
+{
+ Q_UNUSED( incidence );
+}
+
+void Calendar::CalendarObserver::calendarIncidenceChanged( const Incidence::Ptr &incidence )
+{
+ Q_UNUSED( incidence );
+}
+
+void Calendar::CalendarObserver::calendarIncidenceDeleted( const Incidence::Ptr &incidence )
+{
+ Q_UNUSED( incidence );
+}
+
+void
+Calendar::CalendarObserver::calendarIncidenceAdditionCanceled( const Incidence::Ptr &incidence )
+{
+ Q_UNUSED( incidence );
+}
+
+void Calendar::registerObserver( CalendarObserver *observer )
+{
+ if ( !observer ) {
+ return;
+ }
+
+ if ( !d->mObservers.contains( observer ) ) {
+ d->mObservers.append( observer );
+ } else {
+ d->mNewObserver = true;
+ }
+}
+
+void Calendar::unregisterObserver( CalendarObserver *observer )
+{
+ if ( !observer ) {
+ return;
+ } else {
+ d->mObservers.removeAll( observer );
+ }
+}
+
+bool Calendar::isSaving() const
+{
+ return false;
+}
+
+void Calendar::setModified( bool modified )
+{
+ if ( modified != d->mModified || d->mNewObserver ) {
+ d->mNewObserver = false;
+ foreach ( CalendarObserver *observer, d->mObservers ) {
+ observer->calendarModified( modified, this );
+ }
+ d->mModified = modified;
+ }
+}
+
+bool Calendar::isModified() const
+{
+ return d->mModified;
+}
+
+bool Calendar::save()
+{
+ return true;
+}
+
+bool Calendar::reload()
+{
+ return true;
+}
+
+void Calendar::incidenceUpdated( const QString &uid, const KDateTime &recurrenceId )
+{
+
+ Incidence::Ptr inc = incidence( uid, recurrenceId );
+
+ if ( !inc ) {
+ return;
+ }
+
+ inc->setLastModified( KDateTime::currentUtcDateTime() );
+ // we should probably update the revision number here,
+ // or internally in the Event itself when certain things change.
+ // need to verify with ical documentation.
+
+ notifyIncidenceChanged( inc );
+
+ setModified( true );
+}
+
+void Calendar::doSetTimeSpec( const KDateTime::Spec &timeSpec )
+{
+ Q_UNUSED( timeSpec );
+}
+
+void Calendar::notifyIncidenceAdded( const Incidence::Ptr &incidence )
+{
+ if ( !incidence ) {
+ return;
+ }
+
+ if ( !d->mObserversEnabled ) {
+ return;
+ }
+
+ foreach ( CalendarObserver *observer, d->mObservers ) {
+ observer->calendarIncidenceAdded( incidence );
+ }
+}
+
+void Calendar::notifyIncidenceChanged( const Incidence::Ptr &incidence )
+{
+ if ( !incidence ) {
+ return;
+ }
+
+ if ( !d->mObserversEnabled ) {
+ return;
+ }
+
+ foreach ( CalendarObserver *observer, d->mObservers ) {
+ observer->calendarIncidenceChanged( incidence );
+ }
+}
+
+void Calendar::notifyIncidenceDeleted( const Incidence::Ptr &incidence )
+{
+ if ( !incidence ) {
+ return;
+ }
+
+ if ( !d->mObserversEnabled ) {
+ return;
+ }
+
+ foreach ( CalendarObserver *observer, d->mObservers ) {
+ observer->calendarIncidenceDeleted( incidence );
+ }
+}
+
+void Calendar::notifyIncidenceAdditionCanceled( const Incidence::Ptr &incidence )
+{
+ if ( !incidence ) {
+ return;
+ }
+
+ if ( !d->mObserversEnabled ) {
+ return;
+ }
+
+ foreach ( CalendarObserver *observer, d->mObservers ) {
+ observer->calendarIncidenceAdditionCanceled( incidence );
+ }
+}
+
+void Calendar::customPropertyUpdated()
+{
+ setModified( true );
+}
+
+void Calendar::setProductId( const QString &id )
+{
+ d->mProductId = id;
+}
+
+QString Calendar::productId() const
+{
+ return d->mProductId;
+}
+
+/** static */
+Incidence::List Calendar::mergeIncidenceList( const Event::List &events,
+ const Todo::List &todos,
+ const Journal::List &journals )
+{
+ Incidence::List incidences;
+
+ int i, end;
+ for ( i = 0, end = events.count(); i < end; ++i ) {
+ incidences.append( events[i] );
+ }
+
+ for ( i = 0, end = todos.count(); i < end; ++i ) {
+ incidences.append( todos[i] );
+ }
+
+ for ( i = 0, end = journals.count(); i < end; ++i ) {
+ incidences.append( journals[i] );
+ }
+
+ return incidences;
+}
+
+bool Calendar::beginChange( const Incidence::Ptr &incidence )
+{
+ Q_UNUSED( incidence );
+ return true;
+}
+
+bool Calendar::endChange( const Incidence::Ptr &incidence )
+{
+ Q_UNUSED( incidence );
+ return true;
+}
+
+void Calendar::setObserversEnabled( bool enabled )
+{
+ d->mObserversEnabled = enabled;
+}
+
+void Calendar::appendAlarms( Alarm::List &alarms, const Incidence::Ptr &incidence,
+ const KDateTime &from, const KDateTime &to ) const
+{
+ KDateTime preTime = from.addSecs(-1);
+
+ Alarm::List alarmlist = incidence->alarms();
+ for ( int i = 0, iend = alarmlist.count(); i < iend; ++i ) {
+ if ( alarmlist[i]->enabled() ) {
+ KDateTime dt = alarmlist[i]->nextRepetition( preTime );
+ if ( dt.isValid() && dt <= to ) {
+ kDebug() << incidence->summary() << "':" << dt.toString();
+ alarms.append( alarmlist[i] );
+ }
+ }
+ }
+}
+
+void Calendar::appendRecurringAlarms( Alarm::List &alarms,
+ const Incidence::Ptr &incidence,
+ const KDateTime &from,
+ const KDateTime &to ) const
+{
+ KDateTime dt;
+ bool endOffsetValid = false;
+ Duration endOffset( 0 );
+ Duration period( from, to );
+
+ Alarm::List alarmlist = incidence->alarms();
+ for ( int i = 0, iend = alarmlist.count(); i < iend; ++i ) {
+ Alarm::Ptr a = alarmlist[i];
+ if ( a->enabled() ) {
+ if ( a->hasTime() ) {
+ // The alarm time is defined as an absolute date/time
+ dt = a->nextRepetition( from.addSecs(-1) );
+ if ( !dt.isValid() || dt > to ) {
+ continue;
+ }
+ } else {
+ // Alarm time is defined by an offset from the event start or end time.
+ // Find the offset from the event start time, which is also used as the
+ // offset from the recurrence time.
+ Duration offset( 0 );
+ if ( a->hasStartOffset() ) {
+ offset = a->startOffset();
+ } else if ( a->hasEndOffset() ) {
+ offset = a->endOffset();
+ if ( !endOffsetValid ) {
+ endOffset = Duration( incidence->dtStart(),
+ incidence->dateTime( Incidence::RoleAlarmEndOffset ) );
+ endOffsetValid = true;
+ }
+ }
+
+ // Find the incidence's earliest alarm
+ KDateTime alarmStart =
+ offset.end( a->hasEndOffset() ? incidence->dateTime( Incidence::RoleAlarmEndOffset ) :
+ incidence->dtStart() );
+// KDateTime alarmStart = incidence->dtStart().addSecs( offset );
+ if ( alarmStart > to ) {
+ continue;
+ }
+ KDateTime baseStart = incidence->dtStart();
+ if ( from > alarmStart ) {
+ alarmStart = from; // don't look earlier than the earliest alarm
+ baseStart = (-offset).end( (-endOffset).end( alarmStart ) );
+ }
+
+ // Adjust the 'alarmStart' date/time and find the next recurrence at or after it.
+ // Treate the two offsets separately in case one is daily and the other not.
+ dt = incidence->recurrence()->getNextDateTime( baseStart.addSecs(-1) );
+ if ( !dt.isValid() ||
+ ( dt = endOffset.end( offset.end( dt ) ) ) > to ) // adjust 'dt' to get the alarm time
+ {
+ // The next recurrence is too late.
+ if ( !a->repeatCount() ) {
+ continue;
+ }
+
+ // The alarm has repetitions, so check whether repetitions of previous
+ // recurrences fall within the time period.
+ bool found = false;
+ Duration alarmDuration = a->duration();
+ for ( KDateTime base = baseStart;
+ ( dt = incidence->recurrence()->getPreviousDateTime( base ) ).isValid();
+ base = dt ) {
+ if ( a->duration().end( dt ) < base ) {
+ break; // this recurrence's last repetition is too early, so give up
+ }
+
+ // The last repetition of this recurrence is at or after 'alarmStart' time.
+ // Check if a repetition occurs between 'alarmStart' and 'to'.
+ int snooze = a->snoozeTime().value(); // in seconds or days
+ if ( a->snoozeTime().isDaily() ) {
+ Duration toFromDuration( dt, base );
+ int toFrom = toFromDuration.asDays();
+ if ( a->snoozeTime().end( from ) <= to ||
+ ( toFromDuration.isDaily() && toFrom % snooze == 0 ) ||
+ ( toFrom / snooze + 1 ) * snooze <= toFrom + period.asDays() ) {
+ found = true;
+#ifndef NDEBUG
+ // for debug output
+ dt = offset.end( dt ).addDays( ( ( toFrom - 1 ) / snooze + 1 ) * snooze );
+#endif
+ break;
+ }
+ } else {
+ int toFrom = dt.secsTo( base );
+ if ( period.asSeconds() >= snooze ||
+ toFrom % snooze == 0 ||
+ ( toFrom / snooze + 1 ) * snooze <= toFrom + period.asSeconds() )
+ {
+ found = true;
+#ifndef NDEBUG
+ // for debug output
+ dt = offset.end( dt ).addSecs( ( ( toFrom - 1 ) / snooze + 1 ) * snooze );
+#endif
+ break;
+ }
+ }
+ }
+ if ( !found ) {
+ continue;
+ }
+ }
+ }
+ kDebug() << incidence->summary() << "':" << dt.toString();
+ alarms.append( a );
+ }
+ }
+}
+
+void Calendar::startBatchAdding()
+{
+ d->batchAddingInProgress = true;
+}
+
+void Calendar::endBatchAdding()
+{
+ d->batchAddingInProgress = false;
+}
+
+bool Calendar::batchAdding() const
+{
+ return d->batchAddingInProgress;
+}
+
+void Calendar::virtual_hook( int id, void *data )
+{
+ Q_UNUSED( id );
+ Q_UNUSED( data );
+ Q_ASSERT( false );
+}
+
diff --git a/kcalcore/calendar.h b/kcalcore/calendar.h
new file mode 100644
index 0000000..d1dcc39
--- /dev/null
+++ b/kcalcore/calendar.h
@@ -0,0 +1,1446 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 1998 Preston Brown <pbrown@kde.org>
+ Copyright (c) 2001,2003,2004 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+ Copyright (c) 2006 David Jarvie <software@astrojar.org.uk>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Calendar class.
+
+ @author Preston Brown \<pbrown@kde.org\>
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+ @author Reinhold Kainhofer \<reinhold@kainhofer.com\>
+ @author David Jarvie \<software@astrojar.org.uk\>
+ */
+
+/**
+
+TODO: KDE5:
+
+This API needs serious cleaning up:
+- Most (all) methods aren't async ( deleteIncidence(), addIncidence(), load(), save(), ... )
+ so it's not very easy to make a derived class that loads from akonadi.
+
+- It has too many methods. Why do we need fooEvent()/fooJournal()/fooTodo() when fooIncidence()
+ should be enough.
+
+*/
+
+#ifndef KCALCORE_CALENDAR_H
+#define KCALCORE_CALENDAR_H
+
+#include "kcalcore_export.h"
+#include "event.h"
+#include "customproperties.h"
+#include "incidence.h"
+#include "journal.h"
+#include "todo.h"
+
+#include <QtCore/QObject>
+
+namespace KCalCore {
+
+class CalFilter;
+class Person;
+class ICalTimeZones;
+
+/**
+ Calendar Incidence sort directions.
+*/
+enum SortDirection {
+ SortDirectionAscending, /**< Sort in ascending order (first to last) */
+ SortDirectionDescending /**< Sort in descending order (last to first) */
+};
+
+/**
+ Calendar Event sort keys.
+*/
+enum EventSortField {
+ EventSortUnsorted, /**< Do not sort Events */
+ EventSortStartDate, /**< Sort Events chronologically, by start date */
+ EventSortEndDate, /**< Sort Events chronologically, by end date */
+ EventSortSummary /**< Sort Events alphabetically, by summary */
+};
+
+/**
+ Calendar Todo sort keys.
+*/
+enum TodoSortField {
+ TodoSortUnsorted, /**< Do not sort Todos */
+ TodoSortStartDate, /**< Sort Todos chronologically, by start date */
+ TodoSortDueDate, /**< Sort Todos chronologically, by due date */
+ TodoSortPriority, /**< Sort Todos by priority */
+ TodoSortPercentComplete, /**< Sort Todos by percentage completed */
+ TodoSortSummary, /**< Sort Todos alphabetically, by summary */
+ TodoSortCreated /**< Sort Todos chronologically, by creation date */
+};
+
+/**
+ Calendar Journal sort keys.
+*/
+enum JournalSortField {
+ JournalSortUnsorted, /**< Do not sort Journals */
+ JournalSortDate, /**< Sort Journals chronologically by date */
+ JournalSortSummary /**< Sort Journals alphabetically, by summary */
+};
+
+/**
+ @brief
+ Represents the main calendar class.
+
+ A calendar contains information like incidences (events, to-dos, journals),
+ alarms, time zones, and other useful information.
+
+ This is an abstract base class defining the interface to a calendar.
+ It is implemented by subclasses like MemoryCalendar, which use different
+ methods to store and access the data.
+
+ <b>Ownership of Incidences</b>:
+
+ Incidence ownership is handled by the following policy: as soon as an
+ incidence (or any other subclass of IncidenceBase) is added to the
+ Calendar by an add...() method it is owned by the Calendar object.
+ The Calendar takes care of deleting the incidence using the delete...()
+ methods. All Incidences returned by the query functions are returned
+ as pointers so that changes to the returned Incidences are immediately
+ visible in the Calendar. Do <em>Not</em> attempt to 'delete' any Incidence
+ object you get from Calendar -- use the delete...() methods.
+*/
+class KCALCORE_EXPORT Calendar : public QObject, public CustomProperties,
+ public IncidenceBase::IncidenceObserver
+{
+ Q_OBJECT
+
+ public:
+
+ /**
+ A shared pointer to a Calendar
+ */
+ typedef QSharedPointer<Calendar> Ptr;
+
+ /**
+ Constructs a calendar with a specified time zone @p timeZoneid.
+ The time specification is used as the default for creating or
+ modifying incidences in the Calendar. The time specification does
+ not alter existing incidences.
+
+ The constructor also calls setViewTimeSpec(@p timeSpec).
+
+ @param timeSpec time specification
+ */
+ explicit Calendar( const KDateTime::Spec &timeSpec );
+
+ /**
+ Construct Calendar object using a time zone ID.
+ The time zone ID is used as the default for creating or modifying
+ incidences in the Calendar. The time zone does not alter existing
+ incidences.
+
+ The constructor also calls setViewTimeZoneId(@p timeZoneId).
+
+ @param timeZoneId is a string containing a time zone ID, which is
+ assumed to be valid. If no time zone is found, the viewing time
+ specification is set to local clock time.
+ @e Example: "Europe/Berlin"
+ */
+ explicit Calendar( const QString &timeZoneId );
+
+ /**
+ Destroys the calendar.
+ */
+ virtual ~Calendar();
+
+ /**
+ Sets the calendar Product ID to @p id.
+
+ @param id is a string containing the Product ID.
+
+ @see productId() const
+ */
+ void setProductId( const QString &id );
+
+ /**
+ Returns the calendar's Product ID.
+
+ @see setProductId()
+ */
+ QString productId() const;
+
+ /**
+ Sets the owner of the calendar to @p owner.
+
+ @param owner is a Person object. Must be a non-null pointer.
+
+ @see owner()
+ */
+ void setOwner( const Person::Ptr &owner );
+
+ /**
+ Returns the owner of the calendar.
+
+ @return the owner Person object.
+
+ @see setOwner()
+ */
+ Person::Ptr owner() const;
+
+ /**
+ Sets the default time specification (time zone, etc.) used for creating
+ or modifying incidences in the Calendar.
+
+ The method also calls setViewTimeSpec(@p timeSpec).
+
+ @param timeSpec time specification
+ */
+ void setTimeSpec( const KDateTime::Spec &timeSpec );
+
+ /**
+ Get the time specification (time zone etc.) used for creating or
+ modifying incidences in the Calendar.
+
+ @return time specification
+ */
+ KDateTime::Spec timeSpec() const;
+
+ /**
+ Sets the time zone ID used for creating or modifying incidences in the
+ Calendar. This method has no effect on existing incidences.
+
+ The method also calls setViewTimeZoneId(@p timeZoneId).
+
+ @param timeZoneId is a string containing a time zone ID, which is
+ assumed to be valid. The time zone ID is used to set the time zone
+ for viewing Incidence date/times. If no time zone is found, the
+ viewing time specification is set to local clock time.
+ @e Example: "Europe/Berlin"
+ @see setTimeSpec()
+ */
+ void setTimeZoneId( const QString &timeZoneId );
+
+ /**
+ Returns the time zone ID used for creating or modifying incidences in
+ the calendar.
+
+ @return the string containing the time zone ID, or empty string if the
+ creation/modification time specification is not a time zone.
+ */
+ QString timeZoneId() const;
+
+ /**
+ Notes the time specification which the client application intends to
+ use for viewing the incidences in this calendar. This is simply a
+ convenience method which makes a note of the new time zone so that
+ it can be read back by viewTimeSpec(). The client application must
+ convert date/time values to the desired time zone itself.
+
+ The time specification is not used in any way by the Calendar or its
+ incidences; it is solely for use by the client application.
+
+ @param timeSpec time specification
+
+ @see viewTimeSpec()
+ */
+ void setViewTimeSpec( const KDateTime::Spec &timeSpec ) const;
+
+ /**
+ Notes the time zone Id which the client application intends to use for
+ viewing the incidences in this calendar. This is simply a convenience
+ method which makes a note of the new time zone so that it can be read
+ back by viewTimeId(). The client application must convert date/time
+ values to the desired time zone itself.
+
+ The Id is not used in any way by the Calendar or its incidences.
+ It is solely for use by the client application.
+
+ @param timeZoneId is a string containing a time zone ID, which is
+ assumed to be valid. The time zone ID is used to set the time zone
+ for viewing Incidence date/times. If no time zone is found, the
+ viewing time specification is set to local clock time.
+ @e Example: "Europe/Berlin"
+
+ @see viewTimeZoneId()
+ */
+ void setViewTimeZoneId( const QString &timeZoneId ) const;
+
+ /**
+ Returns the time specification used for viewing the incidences in
+ this calendar. This simply returns the time specification last
+ set by setViewTimeSpec().
+ @see setViewTimeSpec().
+ */
+ KDateTime::Spec viewTimeSpec() const;
+
+ /**
+ Returns the time zone Id used for viewing the incidences in this
+ calendar. This simply returns the time specification last set by
+ setViewTimeSpec().
+ @see setViewTimeZoneId().
+ */
+ QString viewTimeZoneId() const;
+
+ /**
+ Shifts the times of all incidences so that they appear at the same clock
+ time as before but in a new time zone. The shift is done from a viewing
+ time zone rather than from the actual incidence time zone.
+
+ For example, shifting an incidence whose start time is 09:00 America/New York,
+ using an old viewing time zone (@p oldSpec) of Europe/London, to a new time
+ zone (@p newSpec) of Europe/Paris, will result in the time being shifted
+ from 14:00 (which is the London time of the incidence start) to 14:00 Paris
+ time.
+
+ @param oldSpec the time specification which provides the clock times
+ @param newSpec the new time specification
+
+ @see isLocalTime()
+ */
+ void shiftTimes( const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec );
+
+ /**
+ Returns the time zone collection used by the calendar.
+
+ @return the time zones collection.
+
+ @see setLocalTime()
+ */
+ ICalTimeZones *timeZones() const;
+
+ /**
+ Set the time zone collection used by the calendar.
+
+ @param zones time zones collection. Important: all time zones references
+ in the calendar must be included in the collection.
+ */
+ void setTimeZones( ICalTimeZones *zones );
+
+ /**
+ Sets if the calendar has been modified.
+
+ @param modified is true if the calendar has been modified since open
+ or last save.
+
+ @see isModified()
+ */
+ void setModified( bool modified );
+
+ /**
+ Determine the calendar's modification status.
+
+ @return true if the calendar has been modified since open or last save.
+
+ @see setModified()
+ */
+ bool isModified() const;
+
+ /**
+ Clears out the current calendar, freeing all used memory etc.
+ */
+ virtual void close() = 0;
+
+ /**
+ Syncs changes in memory to persistent storage.
+
+ @return true if the save was successful; false otherwise.
+ Base implementation returns true.
+ */
+ virtual bool save();
+
+ /**
+ Loads the calendar contents from storage. This requires that the
+ calendar has been previously loaded (initialized).
+
+ @return true if the reload was successful; otherwise false.
+ Base implementation returns true.
+ */
+ virtual bool reload();
+
+ /**
+ Determine if the calendar is currently being saved.
+
+ @return true if the calendar is currently being saved; false otherwise.
+ */
+ virtual bool isSaving() const;
+
+ /**
+ Returns a list of all categories used by Incidences in this Calendar.
+
+ @return a QStringList containing all the categories.
+ */
+ QStringList categories() const;
+
+ // Incidence Specific Methods //
+
+ /**
+ Call this to tell the calendar that you're adding a batch of incidences.
+ So it doesn't, for example, ask the destination for each incidence.
+
+ @see endBatchAdding()
+ */
+ virtual void startBatchAdding();
+
+ /**
+ Tells the Calendar that you stoped adding a batch of incidences.
+
+ @see startBatchAdding()
+ */
+ virtual void endBatchAdding();
+
+ /**
+ @return true if batch adding is in progress
+ */
+ bool batchAdding() const;
+
+ /**
+ Inserts an Incidence into the calendar.
+
+ @param incidence is a pointer to the Incidence to insert.
+
+ @return true if the Incidence was successfully inserted; false otherwise.
+
+ @see deleteIncidence()
+ */
+ virtual bool addIncidence( const Incidence::Ptr &incidence );
+
+ /**
+ Removes an Incidence from the calendar.
+
+ @param incidence is a pointer to the Incidence to remove.
+
+ @return true if the Incidence was successfully removed; false otherwise.
+
+ @see addIncidence()
+ */
+ virtual bool deleteIncidence( const Incidence::Ptr &incidence );
+
+ /**
+ Returns a filtered list of all Incidences for this Calendar.
+
+ @return the list of all filtered Incidences.
+ */
+ virtual Incidence::List incidences() const;
+
+ /**
+ Returns a filtered list of all Incidences which occur on the given date.
+
+ @param date request filtered Incidence list for this QDate only.
+
+ @return the list of filtered Incidences occurring on the specified date.
+ */
+ virtual Incidence::List incidences( const QDate &date ) const;
+
+ /**
+ Returns an unfiltered list of all Incidences for this Calendar.
+
+ @return the list of all unfiltered Incidences.
+ */
+ virtual Incidence::List rawIncidences() const;
+
+ /**
+ Returns an unfiltered list of all possible instances for this recurring Incidence.
+
+ @param incidence incidence to check
+
+ @return the list of all unfiltered Incidences.
+ */
+ virtual Incidence::List instances( const Incidence::Ptr &incidence ) const;
+
+ // Notebook Specific Methods //
+
+ /**
+ Clears notebook associations from hash-tables for incidences.
+ Called when in-memory content of the calendar is cleared.
+ */
+ virtual void clearNotebookAssociations();
+
+ /**
+ Associate notebook for an incidence.
+
+ @param incidence incidence
+ @param notebook notebook uid
+
+ @return true if the operation was successful; false otherwise.
+ */
+ virtual bool setNotebook( const Incidence::Ptr &incidence, const QString &notebook );
+
+ /**
+ Get incidence's notebook.
+
+ @param incidence incidence
+
+ @return notebook uid
+ */
+ virtual QString notebook( const Incidence::Ptr &incidence ) const;
+
+ /**
+ Get incidence's notebook.
+
+ @param uid is a unique identifier string
+
+ @return notebook uid
+ */
+ virtual QString notebook( const QString &uid ) const;
+
+ /**
+ List all uids of notebooks currently in the memory.
+
+ @return list of uids of notebooks
+ */
+ virtual QStringList notebooks() const;
+
+ /**
+ Check if calendar knows about the given notebook.
+ This means that it will be saved by one of the attached storages.
+
+ @param notebook notebook uid
+ @return true if calendar has valid notebook
+ */
+ bool hasValidNotebook( const QString &notebook ) const;
+
+ /**
+ Add notebook information into calendar.
+ Is usually called by storages only.
+
+ @param notebook notebook uid
+ @param isVisible notebook visibility
+ @return true if operation succeeded
+ @see isVisible()
+ */
+ bool addNotebook( const QString &notebook, bool isVisible );
+
+ /**
+ Update notebook information in calendar.
+ Is usually called by storages only.
+
+ @param notebook notebook uid
+ @param isVisible notebook visibility
+ @return true if operation succeeded
+ @see isVisible()
+ */
+ bool updateNotebook( const QString &notebook, bool isVisible );
+
+ /**
+ Delete notebook information from calendar.
+ Is usually called by storages only.
+
+ @param notebook notebook uid
+ @return true if operation succeeded
+ @see isVisible()
+ */
+ bool deleteNotebook( const QString &notebook );
+
+ /**
+ set DefaultNotebook information to calendar.
+
+ @param notebook notebook uid
+ @return true if operation was successful; false otherwise.
+ */
+ bool setDefaultNotebook( const QString &notebook );
+
+ /**
+ Get uid of default notebook.
+
+ @return notebook uid
+ */
+ QString defaultNotebook() const;
+
+ /**
+ Check if incidence is visible.
+ @param incidence is a pointer to the Incidence to check for visibility.
+ @return true if incidence is visible, false otherwise
+ */
+ bool isVisible( const Incidence::Ptr &incidence ) const;
+
+ /**
+ List all notebook incidences in the memory.
+
+ @param notebook is the notebook uid.
+ @return a list of incidences for the notebook.
+ */
+ virtual Incidence::List incidences( const QString &notebook ) const;
+
+ /**
+ List all possible duplicate incidences.
+
+ @param incidence is the incidence to check.
+ @return a list of duplicate incidences.
+ */
+ virtual Incidence::List duplicates( const Incidence::Ptr &incidence );
+
+ /**
+ Returns the Incidence associated with the given unique identifier.
+
+ @param uid is a unique identifier string.
+ @param recurrenceId is possible recurrenceid of incidence, default is null
+
+ @return a pointer to the Incidence.
+ A null pointer is returned if no such Incidence exists.
+ */
+ Incidence::Ptr incidence( const QString &uid,
+ const KDateTime &recurrenceId = KDateTime() ) const;
+
+ /**
+ Returns the deleted Incidence associated with the given unique identifier.
+
+ @param uid is a unique identifier string.
+ @param recurrenceId is possible recurrenceid of incidence, default is null
+
+ @return a pointer to the Incidence.
+ A null pointer is returned if no such Incidence exists.
+ */
+ Incidence::Ptr deleted( const QString &uid, const KDateTime &recurrenceId = KDateTime() ) const;
+
+ /**
+ Delete all incidences that are instances of recurring incidence @p incidence.
+
+ @param incidence is a pointer to a deleted Incidence
+ @return true if delete was successful; false otherwise
+ */
+ virtual bool deleteIncidenceInstances( const Incidence::Ptr &incidence ) = 0;
+
+ /**
+ Returns the Incidence associated with the given scheduling identifier.
+
+ @param sid is a unique scheduling identifier string.
+
+ @return a pointer to the Incidence.
+ A null pointer is returned if no such Incidence exists.
+ */
+ virtual Incidence::Ptr incidenceFromSchedulingID( const QString &sid ) const;
+
+ /**
+ Searches all events and todos for an incidence with this
+ scheduling identifier. Returns a list of matching results.
+
+ @param sid is a unique scheduling identifier string.
+ */
+ virtual Incidence::List incidencesFromSchedulingID( const QString &sid ) const;
+
+ /**
+ Create a merged list of Events, Todos, and Journals.
+
+ @param events is an Event list to merge.
+ @param todos is a Todo list to merge.
+ @param journals is a Journal list to merge.
+
+ @return a list of merged Incidences.
+ */
+ static Incidence::List mergeIncidenceList( const Event::List &events,
+ const Todo::List &todos,
+ const Journal::List &journals );
+
+ /**
+ Flag that a change to a Calendar Incidence is starting.
+ @param incidence is a pointer to the Incidence that will be changing.
+ */
+ virtual bool beginChange( const Incidence::Ptr &incidence );
+
+ /**
+ Flag that a change to a Calendar Incidence has completed.
+ @param incidence is a pointer to the Incidence that was changed.
+ */
+ virtual bool endChange( const Incidence::Ptr &incidence );
+
+ /**
+ Dissociate an Incidence from a recurring Incidence.
+ By default, only one single Incidence for the specified @a date
+ will be dissociated and returned. If @a single is false, then
+ the recurrence will be split at @a date, the old Incidence will
+ have its recurrence ending at @a date and the new Incidence
+ will have all recurrences past the @a date.
+
+ @param incidence is a pointer to a recurring Incidence.
+ @param date is the QDate within the recurring Incidence on which
+ the dissociation will be performed.
+ @param spec is the spec in which the @a date is formulated.
+ @param single is a flag meaning that a new Incidence should be created
+ from the recurring Incidences after @a date.
+
+ @return a pointer to a new recurring Incidence if @a single is false.
+ */
+ Incidence::Ptr dissociateOccurrence( const Incidence::Ptr &incidence, const QDate &date,
+ const KDateTime::Spec &spec,
+ bool single = true );
+
+ // Event Specific Methods //
+
+ /**
+ Inserts an Event into the calendar.
+
+ @param event is a pointer to the Event to insert.
+
+ @return true if the Event was successfully inserted; false otherwise.
+
+ @see deleteEvent()
+ */
+ virtual bool addEvent( const Event::Ptr &event ) = 0;
+
+ /**
+ Removes an Event from the calendar.
+
+ @param event is a pointer to the Event to remove.
+
+ @return true if the Event was successfully remove; false otherwise.
+
+ @see addEvent(), deleteAllEvents()
+ */
+ virtual bool deleteEvent( const Event::Ptr &event ) = 0;
+
+ /**
+ Delete all events that are instances of recurring event @p event.
+
+ @param event is a pointer to a deleted Event
+ @return true if delete was successful; false otherwise
+ */
+ virtual bool deleteEventInstances( const Event::Ptr &event ) = 0;
+
+ /**
+ Removes all Events from the calendar.
+ @see deleteEvent()
+ */
+ virtual void deleteAllEvents() = 0;
+
+ /**
+ Sort a list of Events.
+
+ @param eventList is a pointer to a list of Events.
+ @param sortField specifies the EventSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return a list of Events sorted as specified.
+ */
+ static Event::List sortEvents( const Event::List &eventList,
+ EventSortField sortField,
+ SortDirection sortDirection );
+ /**
+ Returns a sorted, filtered list of all Events for this Calendar.
+
+ @param sortField specifies the EventSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return the list of all filtered Events sorted as specified.
+ */
+ virtual Event::List events( EventSortField sortField = EventSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const;
+
+ /**
+ Returns a filtered list of all Events which occur on the given timestamp.
+
+ @param dt request filtered Event list for this KDateTime only.
+
+ @return the list of filtered Events occurring on the specified timestamp.
+ */
+ Event::List events( const KDateTime &dt ) const;
+
+ /**
+ Returns a filtered list of all Events occurring within a date range.
+
+ @param start is the starting date.
+ @param end is the ending date.
+ @param timeSpec time zone etc. to interpret @p start and @p end,
+ or the calendar's default time spec if none is specified
+ @param inclusive if true only Events which are completely included
+ within the date range are returned.
+
+ @return the list of filtered Events occurring within the specified
+ date range.
+ */
+ Event::List events( const QDate &start, const QDate &end,
+ const KDateTime::Spec &timeSpec = KDateTime::Spec(),
+ bool inclusive = false ) const;
+
+ /**
+ Returns a sorted, filtered list of all Events which occur on the given
+ date. The Events are sorted according to @a sortField and
+ @a sortDirection.
+
+ @param date request filtered Event list for this QDate only.
+ @param timeSpec time zone etc. to interpret @p start and @p end,
+ or the calendar's default time spec if none is specified
+ @param sortField specifies the EventSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return the list of sorted, filtered Events occurring on @a date.
+ */
+ Event::List events( const QDate &date,
+ const KDateTime::Spec &timeSpec = KDateTime::Spec(),
+ EventSortField sortField = EventSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const;
+
+ /**
+ Returns a sorted, unfiltered list of all Events for this Calendar.
+
+ @param sortField specifies the EventSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return the list of all unfiltered Events sorted as specified.
+ */
+ virtual Event::List rawEvents(
+ EventSortField sortField = EventSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const = 0;
+
+ /**
+ Returns an unfiltered list of all Events which occur on the given
+ timestamp.
+
+ @param dt request unfiltered Event list for this KDateTime only.
+
+ @return the list of unfiltered Events occurring on the specified
+ timestamp.
+ */
+ virtual Event::List rawEventsForDate( const KDateTime &dt ) const = 0;
+
+ /**
+ Returns an unfiltered list of all Events occurring within a date range.
+
+ @param start is the starting date
+ @param end is the ending date
+ @param timeSpec time zone etc. to interpret @p start and @p end,
+ or the calendar's default time spec if none is specified
+ @param inclusive if true only Events which are completely included
+ within the date range are returned.
+
+ @return the list of unfiltered Events occurring within the specified
+ date range.
+ */
+ virtual Event::List rawEvents( const QDate &start, const QDate &end,
+ const KDateTime::Spec &timeSpec = KDateTime::Spec(),
+ bool inclusive = false ) const = 0;
+
+ /**
+ Returns a sorted, unfiltered list of all Events which occur on the given
+ date. The Events are sorted according to @a sortField and
+ @a sortDirection.
+
+ @param date request unfiltered Event list for this QDate only
+ @param timeSpec time zone etc. to interpret @p date,
+ or the calendar's default time spec if none is specified
+ @param sortField specifies the EventSortField
+ @param sortDirection specifies the SortDirection
+
+ @return the list of sorted, unfiltered Events occurring on @p date
+ */
+ virtual Event::List rawEventsForDate(
+ const QDate &date,
+ const KDateTime::Spec &timeSpec = KDateTime::Spec(),
+ EventSortField sortField = EventSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const = 0;
+
+ /**
+ Returns the Event associated with the given unique identifier.
+
+ @param uid is a unique identifier string.
+ @param recurrenceId is possible recurrenceId of event, default is null
+
+ @return a pointer to the Event.
+ A null pointer is returned if no such Event exists.
+ */
+ virtual Event::Ptr event( const QString &uid,
+ const KDateTime &recurrenceId = KDateTime() ) const = 0;
+
+ /**
+ Returns the deleted Event associated with the given unique identifier.
+
+ @param uid is a unique identifier string.
+ @param recurrenceId is possible recurrenceId of event, default is null
+
+ @return a pointer to the deleted Event.
+ A null pointer is returned if no such deleted Event exists.
+ */
+ virtual Event::Ptr deletedEvent( const QString &uid,
+ const KDateTime &recurrenceId = KDateTime() ) const = 0;
+
+ /**
+ Returns a sorted, unfiltered list of all deleted Events for this Calendar.
+
+ @param sortField specifies the EventSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return the list of all unfiltered deleted Events sorted as specified.
+ */
+ virtual Event::List deletedEvents(
+ EventSortField sortField = EventSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const = 0;
+
+ /**
+ Returns a sorted, unfiltered list of all possible instances for this recurring Event.
+
+ @param event event to check for. Caller guarantees it's of type Event.
+ @param sortField specifies the EventSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return the list of all unfiltered event instances sorted as specified.
+ */
+ virtual Event::List eventInstances(
+ const Incidence::Ptr &event,
+ EventSortField sortField = EventSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const = 0;
+
+ // Todo Specific Methods //
+
+ /**
+ Inserts a Todo into the calendar.
+
+ @param todo is a pointer to the Todo to insert.
+
+ @return true if the Todo was successfully inserted; false otherwise.
+
+ @see deleteTodo()
+ */
+ virtual bool addTodo( const Todo::Ptr &todo ) = 0;
+
+ /**
+ Removes a Todo from the calendar.
+
+ @param todo is a pointer to the Todo to remove.
+
+ @return true if the Todo was successfully removed; false otherwise.
+
+ @see addTodo(), deleteAllTodos()
+ */
+ virtual bool deleteTodo( const Todo::Ptr &todo ) = 0;
+
+ /**
+ Delete all to-dos that are instances of recurring to-do @p todo.
+ @param todo is a pointer to a deleted Todo
+ @return true if delete was successful; false otherwise
+ */
+ virtual bool deleteTodoInstances( const Todo::Ptr &todo ) = 0;
+
+ /**
+ Removes all To-dos from the calendar.
+ @see deleteTodo()
+ */
+ virtual void deleteAllTodos() = 0;
+
+ /**
+ Sort a list of Todos.
+
+ @param todoList is a pointer to a list of Todos.
+ @param sortField specifies the TodoSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return a list of Todos sorted as specified.
+ */
+ static Todo::List sortTodos( const Todo::List &todoList,
+ TodoSortField sortField,
+ SortDirection sortDirection );
+
+ /**
+ Returns a sorted, filtered list of all Todos for this Calendar.
+
+ @param sortField specifies the TodoSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return the list of all filtered Todos sorted as specified.
+ */
+ virtual Todo::List todos( TodoSortField sortField = TodoSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const;
+
+ /**
+ Returns a filtered list of all Todos which are due on the specified date.
+
+ @param date request filtered Todos due on this QDate.
+
+ @return the list of filtered Todos due on the specified date.
+ */
+ virtual Todo::List todos( const QDate &date ) const;
+
+ /**
+ Returns a filtered list of all Todos occurring within a date range.
+
+ @param start is the starting date
+ @param end is the ending date
+ @param timespec time zone etc. to interpret @p start and @p end,
+ or the calendar's default time spec if none is specified
+ @param inclusive if true only Todos which are completely included
+ within the date range are returned.
+
+ @return the list of filtered Todos occurring within the specified
+ date range.
+ */
+ virtual Todo::List todos( const QDate &start, const QDate &end,
+ const KDateTime::Spec &timespec = KDateTime::Spec(),
+ bool inclusive = false ) const;
+
+ /**
+ Returns a sorted, unfiltered list of all Todos for this Calendar.
+
+ @param sortField specifies the TodoSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return the list of all unfiltered Todos sorted as specified.
+ */
+ virtual Todo::List rawTodos(
+ TodoSortField sortField = TodoSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const = 0;
+
+ /**
+ Returns an unfiltered list of all Todos which due on the specified date.
+
+ @param date request unfiltered Todos due on this QDate.
+
+ @return the list of unfiltered Todos due on the specified date.
+ */
+ virtual Todo::List rawTodosForDate( const QDate &date ) const = 0;
+
+ /**
+ Returns an unfiltered list of all Todos occurring within a date range.
+
+ @param start is the starting date
+ @param end is the ending date
+ @param timespec time zone etc. to interpret @p start and @p end,
+ or the calendar's default time spec if none is specified
+ @param inclusive if true only Todos which are completely included
+ within the date range are returned.
+
+ @return the list of unfiltered Todos occurring within the specified
+ date range.
+ */
+ virtual Todo::List rawTodos( const QDate &start, const QDate &end,
+ const KDateTime::Spec &timespec = KDateTime::Spec(),
+ bool inclusive = false ) const = 0;
+
+ /**
+ Returns the Todo associated with the given unique identifier.
+
+ @param uid is a unique identifier string.
+ @param recurrenceId is possible recurrenceId of todo, default is null
+
+ @return a pointer to the Todo.
+ A null pointer is returned if no such Todo exists.
+ */
+ virtual Todo::Ptr todo( const QString &uid,
+ const KDateTime &recurrenceId = KDateTime() ) const = 0;
+
+ /**
+ Returns the deleted Todo associated with the given unique identifier.
+
+ @param uid is a unique identifier string.
+ @param recurrenceId is possible recurrenceId of todo, default is null
+
+ @return a pointer to the deleted Todo.
+ A null pointer is returned if no such deletef Todo exists.
+ */
+ virtual Todo::Ptr deletedTodo( const QString &uid,
+ const KDateTime &recurrenceId = KDateTime() ) const = 0;
+
+ /**
+ Returns a sorted, unfiltered list of all deleted Todos for this Calendar.
+
+ @param sortField specifies the TodoSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return the list of all unfiltered deleted Todos sorted as specified.
+ */
+ virtual Todo::List deletedTodos(
+ TodoSortField sortField = TodoSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const = 0;
+
+ /**
+ Returns a sorted, unfiltered list of all possible instances for this recurring Todo.
+
+ @param todo todo to check for. Caller guarantees it's of type Todo.
+ @param sortField specifies the TodoSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return the list of all unfiltered todo instances sorted as specified.
+ */
+ virtual Todo::List todoInstances(
+ const Incidence::Ptr &todo,
+ TodoSortField sortField = TodoSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const = 0;
+
+ // Journal Specific Methods //
+
+ /**
+ Inserts a Journal into the calendar.
+
+ @param journal is a pointer to the Journal to insert.
+
+ @return true if the Journal was successfully inserted; false otherwise.
+
+ @see deleteJournal()
+ */
+ virtual bool addJournal( const Journal::Ptr &journal ) = 0;
+
+ /**
+ Removes a Journal from the calendar.
+
+ @param journal is a pointer to the Journal to remove.
+
+ @return true if the Journal was successfully removed; false otherwise.
+
+ @see addJournal(), deleteAllJournals()
+ */
+ virtual bool deleteJournal( const Journal::Ptr &journal ) = 0;
+
+ /**
+ Delete all journals that are instances of recurring journal @p journal.
+
+ @param journal is a pointer to a deleted Journal
+ @return true if delete was successful; false otherwise
+ */
+ virtual bool deleteJournalInstances( const Journal::Ptr &journal ) = 0;
+
+ /**
+ Removes all Journals from the calendar.
+ @see deleteJournal()
+ */
+ virtual void deleteAllJournals() = 0;
+
+ /**
+ Sort a list of Journals.
+
+ @param journalList is a pointer to a list of Journals.
+ @param sortField specifies the JournalSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return a list of Journals sorted as specified.
+ */
+ static Journal::List sortJournals( const Journal::List &journalList,
+ JournalSortField sortField,
+ SortDirection sortDirection );
+ /**
+ Returns a sorted, filtered list of all Journals for this Calendar.
+
+ @param sortField specifies the JournalSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return the list of all filtered Journals sorted as specified.
+ */
+ virtual Journal::List journals(
+ JournalSortField sortField = JournalSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const;
+
+ /**
+ Returns a filtered list of all Journals for on the specified date.
+
+ @param date request filtered Journals for this QDate only.
+
+ @return the list of filtered Journals for the specified date.
+ */
+ virtual Journal::List journals( const QDate &date ) const;
+
+ /**
+ Returns a sorted, unfiltered list of all Journals for this Calendar.
+
+ @param sortField specifies the JournalSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return the list of all unfiltered Journals sorted as specified.
+ */
+ virtual Journal::List rawJournals(
+ JournalSortField sortField = JournalSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const = 0;
+
+ /**
+ Returns an unfiltered list of all Journals for on the specified date.
+
+ @param date request unfiltered Journals for this QDate only.
+
+ @return the list of unfiltered Journals for the specified date.
+ */
+ virtual Journal::List rawJournalsForDate( const QDate &date ) const = 0;
+
+ /**
+ Returns the Journal associated with the given unique identifier.
+
+ @param uid is a unique identifier string.
+ @param recurrenceId is possible recurrenceId of journal, default is null
+
+ @return a pointer to the Journal.
+ A null pointer is returned if no such Journal exists.
+ */
+ virtual Journal::Ptr journal( const QString &uid,
+ const KDateTime &recurrenceId = KDateTime() ) const = 0;
+
+ /**
+ Returns the deleted Journal associated with the given unique identifier.
+
+ @param uid is a unique identifier string.
+ @param recurrenceId is possible recurrenceId of journal, default is null
+
+ @return a pointer to the deleted Journal.
+ A null pointer is returned if no such deleted Journal exists.
+ */
+ virtual Journal::Ptr deletedJournal( const QString &uid,
+ const KDateTime &recurrenceId = KDateTime() ) const = 0;
+
+ /**
+ Returns a sorted, unfiltered list of all deleted Journals for this Calendar.
+
+ @param sortField specifies the JournalSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return the list of all unfiltered deleted Journals sorted as specified.
+ */
+ virtual Journal::List deletedJournals(
+ JournalSortField sortField = JournalSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const = 0;
+
+ /**
+ Returns a sorted, unfiltered list of all instances for this recurring Journal.
+
+ @param journal journal to check for. Caller guarantees it's of type Journal.
+ @param sortField specifies the JournalSortField.
+ @param sortDirection specifies the SortDirection.
+
+ @return the list of all unfiltered journal instances sorted as specified.
+ */
+ virtual Journal::List journalInstances(
+ const Incidence::Ptr &journal,
+ JournalSortField sortField = JournalSortUnsorted,
+ SortDirection sortDirection = SortDirectionAscending ) const = 0;
+
+ // Relations Specific Methods //
+
+ /**
+ Setup Relations for an Incidence.
+ @param incidence is a pointer to the Incidence to have a Relation setup.
+ */
+ virtual void setupRelations( const Incidence::Ptr &incidence );
+
+ /**
+ Removes all Relations from an Incidence.
+
+ @param incidence is a pointer to the Incidence to have a Relation removed.
+ */
+ virtual void removeRelations( const Incidence::Ptr &incidence );
+
+ /**
+ Checks if @p ancestor is an ancestor of @p incidence
+
+ @param ancestor is the incidence we are testing to be an ancestor.
+ @param incidence is the incidence we are testing to be descended from @p ancestor.
+ */
+ bool isAncestorOf( const Incidence::Ptr &ancestor,
+ const Incidence::Ptr &incidence ) const;
+
+ /**
+ Returns a list of incidences that have a relation of RELTYPE parent
+ to incidence @p uid.
+
+ @param uid The parent identifier whos children we want to obtain.
+ */
+ Incidence::List relations( const QString &uid ) const;
+
+ // Filter Specific Methods //
+
+ /**
+ Sets the calendar filter.
+
+ @param filter a pointer to a CalFilter object which will be
+ used to filter Calendar Incidences. The Calendar takes
+ ownership of @p filter.
+
+ @see filter()
+ */
+ void setFilter( CalFilter *filter );
+
+ /**
+ Returns the calendar filter.
+
+ @return a pointer to the calendar CalFilter.
+ A null pointer is returned if no such CalFilter exists.
+
+ @see setFilter()
+ */
+ CalFilter *filter() const;
+
+ // Alarm Specific Methods //
+
+ /**
+ Returns a list of Alarms within a time range for this Calendar.
+
+ @param from is the starting timestamp.
+ @param to is the ending timestamp.
+
+ @return the list of Alarms for the for the specified time range.
+ */
+ virtual Alarm::List alarms( const KDateTime &from, const KDateTime &to ) const = 0;
+
+ // Observer Specific Methods //
+
+ /**
+ @class CalendarObserver
+
+ The CalendarObserver class.
+ */
+ class KCALCORE_EXPORT CalendarObserver //krazy:exclude=dpointer
+ {
+ public:
+ /**
+ Destructor.
+ */
+ virtual ~CalendarObserver();
+
+ /**
+ Notify the Observer that a Calendar has been modified.
+
+ @param modified set if the calendar has been modified.
+ @param calendar is a pointer to the Calendar object that
+ is being observed.
+ */
+ virtual void calendarModified( bool modified, Calendar *calendar );
+
+ /**
+ Notify the Observer that an Incidence has been inserted.
+ @param incidence is a pointer to the Incidence that was inserted.
+ */
+ virtual void calendarIncidenceAdded( const Incidence::Ptr &incidence );
+
+ /**
+ Notify the Observer that an Incidence has been modified.
+ @param incidence is a pointer to the Incidence that was modified.
+ */
+ virtual void calendarIncidenceChanged( const Incidence::Ptr &incidence );
+
+ /**
+ Notify the Observer that an Incidence has been removed.
+ @param incidence is a pointer to the Incidence that was removed.
+ */
+ virtual void calendarIncidenceDeleted( const Incidence::Ptr &incidence );
+
+ /**
+ Notify the Observer that an addition of Incidence has been canceled.
+ @param incidence is a pointer to the Incidence that was removed.
+ */
+ virtual void calendarIncidenceAdditionCanceled( const Incidence::Ptr &incidence );
+ };
+
+ /**
+ Registers an Observer for this Calendar.
+
+ @param observer is a pointer to an Observer object that will be
+ watching this Calendar.
+
+ @see unregisterObserver()
+ */
+ void registerObserver( CalendarObserver *observer );
+
+ /**
+ Unregisters an Observer for this Calendar.
+
+ @param observer is a pointer to an Observer object that has been
+ watching this Calendar.
+
+ @see registerObserver()
+ */
+ void unregisterObserver( CalendarObserver *observer );
+
+ using QObject::event; // prevent warning about hidden virtual method
+
+ protected:
+ /**
+ The Observer interface. So far not implemented.
+ @param uid is the UID for the Incidence that has been updated.
+ @param recurrenceId is possible recurrenceid of incidence.
+ */
+ void incidenceUpdated( const QString &uid, const KDateTime &recurrenceId );
+
+ /**
+ Let Calendar subclasses set the time specification.
+ @param timeSpec is the time specification (time zone, etc.) for
+ viewing Incidence dates.\n
+ */
+ virtual void doSetTimeSpec( const KDateTime::Spec &timeSpec );
+
+ /**
+ Let Calendar subclasses notify that they inserted an Incidence.
+ @param incidence is a pointer to the Incidence object that was inserted.
+ */
+ void notifyIncidenceAdded( const Incidence::Ptr &incidence );
+
+ /**
+ Let Calendar subclasses notify that they modified an Incidence.
+ @param incidence is a pointer to the Incidence object that was modified.
+ */
+ void notifyIncidenceChanged( const Incidence::Ptr &incidence );
+
+ /**
+ Let Calendar subclasses notify that they removed an Incidence.
+ @param incidence is a pointer to the Incidence object that was removed.
+ */
+ void notifyIncidenceDeleted( const Incidence::Ptr &incidence );
+
+ /**
+ Let Calendar subclasses notify that they canceled addition of an Incidence.
+ @param incidence is a pointer to the Incidence object that addition as canceled.
+ */
+ void notifyIncidenceAdditionCanceled( const Incidence::Ptr &incidence );
+
+ /**
+ @copydoc
+ CustomProperties::customPropertyUpdated()
+ */
+ virtual void customPropertyUpdated();
+
+ /**
+ Let Calendar subclasses notify that they enabled an Observer.
+
+ @param enabled if true tells the calendar that a subclass has
+ enabled an Observer.
+ */
+ void setObserversEnabled( bool enabled );
+
+ /**
+ Appends alarms of incidence in interval to list of alarms.
+
+ @param alarms is a List of Alarms to be appended onto.
+ @param incidence is a pointer to an Incidence containing the Alarm
+ to be appended.
+ @param from is the lower range of the next Alarm repitition.
+ @param to is the upper range of the next Alarm repitition.
+ */
+ void appendAlarms( Alarm::List &alarms, const Incidence::Ptr &incidence,
+ const KDateTime &from, const KDateTime &to ) const;
+
+ /**
+ Appends alarms of recurring events in interval to list of alarms.
+
+ @param alarms is a List of Alarms to be appended onto.
+ @param incidence is a pointer to an Incidence containing the Alarm
+ to be appended.
+ @param from is the lower range of the next Alarm repitition.
+ @param to is the upper range of the next Alarm repitition.
+ */
+ void appendRecurringAlarms( Alarm::List &alarms, const Incidence::Ptr &incidence,
+ const KDateTime &from, const KDateTime &to ) const;
+
+ /**
+ @copydoc
+ IncidenceBase::virtual_hook()
+ */
+ virtual void virtual_hook( int id, void *data );
+
+ private:
+ //@cond PRIVATE
+ class Private;
+ Private *const d;
+ //@endcond
+
+ Q_DISABLE_COPY( Calendar )
+};
+
+}
+
+#endif
diff --git a/kcalcore/calfilter.cpp b/kcalcore/calfilter.cpp
new file mode 100644
index 0000000..5c39e41
--- /dev/null
+++ b/kcalcore/calfilter.cpp
@@ -0,0 +1,273 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+ Copyright (C) 2004 Bram Schoenmakers <bramschoenmakers@kde.nl>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the CalFilter class.
+
+ @brief
+ Provides a filter for calendars.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+ @author Reinhold Kainhofer \<reinhold@kainhofer.com\>
+ @author Bram Schoenmakers \<bramschoenmakers@kde.nl\>
+*/
+
+#include "calfilter.h"
+
+using namespace KCalCore;
+
+/**
+ Private class that helps to provide binary compatibility between releases.
+ @internal
+*/
+//@cond PRIVATE
+class KCalCore::CalFilter::Private
+{
+ public:
+ Private()
+ : mCriteria( 0 ),
+ mCompletedTimeSpan( 0 ),
+ mEnabled( true )
+ {}
+ QString mName; // filter name
+ QStringList mCategoryList;
+ QStringList mEmailList;
+ int mCriteria;
+ int mCompletedTimeSpan;
+ bool mEnabled;
+
+};
+//@endcond
+
+CalFilter::CalFilter() : d( new KCalCore::CalFilter::Private )
+{
+}
+
+CalFilter::CalFilter( const QString &name )
+ : d( new KCalCore::CalFilter::Private )
+{
+ d->mName = name;
+}
+
+CalFilter::~CalFilter()
+{
+ delete d;
+}
+
+bool KCalCore::CalFilter::operator==( const CalFilter &filter ) const
+{
+ return d->mName == filter.d->mName &&
+ d->mCriteria == filter.d->mCriteria &&
+ d->mCategoryList == filter.d->mCategoryList &&
+ d->mEmailList == filter.d->mEmailList &&
+ d->mCompletedTimeSpan == filter.d->mCompletedTimeSpan;
+}
+
+void CalFilter::apply( Event::List *eventList ) const
+{
+ if ( !d->mEnabled ) {
+ return;
+ }
+
+ Event::List::Iterator it = eventList->begin();
+ while ( it != eventList->end() ) {
+ if ( !filterIncidence( *it ) ) {
+ it = eventList->erase( it );
+ } else {
+ ++it;
+ }
+ }
+}
+
+// TODO: avoid duplicating apply() code
+void CalFilter::apply( Todo::List *todoList ) const
+{
+ if ( !d->mEnabled ) {
+ return;
+ }
+
+ Todo::List::Iterator it = todoList->begin();
+ while ( it != todoList->end() ) {
+ if ( !filterIncidence( *it ) ) {
+ it = todoList->erase( it );
+ } else {
+ ++it;
+ }
+ }
+}
+
+void CalFilter::apply( Journal::List *journalList ) const
+{
+ if ( !d->mEnabled ) {
+ return;
+ }
+
+ Journal::List::Iterator it = journalList->begin();
+ while ( it != journalList->end() ) {
+ if ( !filterIncidence( *it ) ) {
+ it = journalList->erase( it );
+ } else {
+ ++it;
+ }
+ }
+}
+
+bool CalFilter::filterIncidence( Incidence::Ptr incidence ) const
+{
+ if ( !d->mEnabled ) {
+ return true;
+ }
+
+ Todo::Ptr todo = incidence.dynamicCast<Todo>();
+ if ( todo ) {
+ if ( ( d->mCriteria & HideCompletedTodos ) && todo->isCompleted() ) {
+ // Check if completion date is suffently long ago:
+ if ( todo->completed().addDays( d->mCompletedTimeSpan ) <
+ KDateTime::currentUtcDateTime() ) {
+ return false;
+ }
+ }
+
+ if ( ( d->mCriteria & HideInactiveTodos ) &&
+ ( ( todo->hasStartDate() &&
+ KDateTime::currentUtcDateTime() < todo->dtStart() ) ||
+ todo->isCompleted() ) ) {
+ return false;
+ }
+
+ if ( d->mCriteria & HideNoMatchingAttendeeTodos ) {
+ bool iAmOneOfTheAttendees = false;
+ const Attendee::List &attendees = todo->attendees();
+ if ( !todo->attendees().isEmpty() ) {
+ Attendee::List::ConstIterator it;
+ for ( it = attendees.begin(); it != attendees.end(); ++it ) {
+ if ( d->mEmailList.contains( (*it)->email() ) ) {
+ iAmOneOfTheAttendees = true;
+ break;
+ }
+ }
+ } else {
+ // no attendees, must be me only
+ iAmOneOfTheAttendees = true;
+ }
+ if ( !iAmOneOfTheAttendees ) {
+ return false;
+ }
+ }
+ }
+
+ if ( d->mCriteria & HideRecurring ) {
+ if ( incidence->recurs() ) {
+ return false;
+ }
+ }
+
+ if ( d->mCriteria & ShowCategories ) {
+ for ( QStringList::ConstIterator it = d->mCategoryList.constBegin();
+ it != d->mCategoryList.constEnd(); ++it ) {
+ QStringList incidenceCategories = incidence->categories();
+ for ( QStringList::ConstIterator it2 = incidenceCategories.constBegin();
+ it2 != incidenceCategories.constEnd(); ++it2 ) {
+ if ( (*it) == (*it2) ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ } else {
+ for ( QStringList::ConstIterator it = d->mCategoryList.constBegin();
+ it != d->mCategoryList.constEnd(); ++it ) {
+ QStringList incidenceCategories = incidence->categories();
+ for ( QStringList::ConstIterator it2 = incidenceCategories.constBegin();
+ it2 != incidenceCategories.constEnd(); ++it2 ) {
+ if ( (*it) == (*it2) ) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ return true;
+}
+
+void CalFilter::setName( const QString &name )
+{
+ d->mName = name;
+}
+
+QString CalFilter::name() const
+{
+ return d->mName;
+}
+
+void CalFilter::setEnabled( bool enabled )
+{
+ d->mEnabled = enabled;
+}
+
+bool CalFilter::isEnabled() const
+{
+ return d->mEnabled;
+}
+
+void CalFilter::setCriteria( int criteria )
+{
+ d->mCriteria = criteria;
+}
+
+int CalFilter::criteria() const
+{
+ return d->mCriteria;
+}
+
+void CalFilter::setCategoryList( const QStringList &categoryList )
+{
+ d->mCategoryList = categoryList;
+}
+
+QStringList CalFilter::categoryList() const
+{
+ return d->mCategoryList;
+}
+
+void CalFilter::setEmailList( const QStringList &emailList )
+{
+ d->mEmailList = emailList;
+}
+
+QStringList CalFilter::emailList() const
+{
+ return d->mEmailList;
+}
+
+void CalFilter::setCompletedTimeSpan( int timespan )
+{
+ d->mCompletedTimeSpan = timespan;
+}
+
+int CalFilter::completedTimeSpan() const
+{
+ return d->mCompletedTimeSpan;
+}
diff --git a/kcalcore/calfilter.h b/kcalcore/calfilter.h
new file mode 100644
index 0000000..80b8610
--- /dev/null
+++ b/kcalcore/calfilter.h
@@ -0,0 +1,226 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001,2003,2004 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the CalFilter class.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+ @author Reinhold Kainhofer \<reinhold@kainhofer.com\>
+*/
+
+#ifndef KCALCORE_CALFILTER_H
+#define KCALCORE_CALFILTER_H
+
+#include "kcalcore_export.h"
+#include "event.h"
+#include "journal.h"
+#include "todo.h"
+
+namespace KCalCore {
+
+/**
+ @brief
+ Provides a filter for calendars.
+
+ This class provides a means for filtering calendar incidences by
+ a list of email addresses, a list of categories, or other #Criteria.
+
+ The following #Criteria are available:
+ - remove recurring Incidences
+ - keep Incidences with a matching category (see setCategoryList())
+ - remove completed To-dos (see setCompletedTimeSpan())
+ - remove inactive To-dos
+ - remove To-dos without a matching attendee (see setEmailList())
+*/
+class KCALCORE_EXPORT CalFilter
+{
+ public:
+ /**
+ Filtering Criteria.
+ */
+ enum Criteria {
+ HideRecurring = 1, /**< Remove incidences that recur */
+ HideCompletedTodos = 2,/**< Remove completed to-dos */
+ ShowCategories = 4, /**< Show incidences with at least one matching category */
+ HideInactiveTodos = 8, /**< Remove to-dos that haven't started yet */
+ HideNoMatchingAttendeeTodos = 16 /**< Remove to-dos without a matching attendee */
+ };
+
+ /**
+ Constructs an empty filter -- a filter without a name or criteria.
+ */
+ CalFilter();
+
+ /**
+ Constructs a filter with @p name.
+
+ @param name is the name of this filter.
+ */
+ explicit CalFilter( const QString &name );
+
+ /**
+ Destroys this filter.
+ */
+ ~CalFilter();
+
+ /**
+ Sets the filter name.
+
+ @param name is the name of this filter.
+ @see name().
+ */
+ void setName( const QString &name );
+
+ /**
+ Returns the filter name.
+ @see setName().
+ */
+ QString name() const;
+
+ /**
+ Sets the criteria which must be fulfilled for an Incidence to pass
+ the filter.
+
+ @param criteria is a combination of #Criteria.
+ @see criteria().
+ */
+ void setCriteria( int criteria );
+
+ /**
+ Returns the inclusive filter criteria.
+ @see setCriteria().
+ */
+ int criteria() const;
+
+ /**
+ Applies the filter to a list of Events. All events not matching the
+ filter criteria are removed from the list.
+
+ @param eventList is a list of Events to filter.
+ */
+ void apply( Event::List *eventList ) const;
+
+ /**
+ Applies the filter to a list of To-dos. All to-dos not matching the
+ filter criterias are removed from the list.
+
+ @param todoList is a list of To-dos to filter.
+ */
+ void apply( Todo::List *todoList ) const;
+
+ /**
+ Applies the filter to a list of Journals. All journals not matching the
+ filter criterias are removed from the list.
+
+ @param journalList is a list of Journals to filter.
+ */
+ void apply( Journal::List *journalList ) const;
+
+ /**
+ Applies the filter criteria to the specified Incidence.
+
+ @param incidence is the Incidence to filter.
+ @return true if the Incidence passes the criteria; false otherwise.
+ */
+ bool filterIncidence( Incidence::Ptr incidence ) const;
+
+ /**
+ Enables or disables the filter.
+
+ @param enabled is true if the filter is to be enabled; false otherwise.
+ @see isEnabled().
+ */
+ void setEnabled( bool enabled );
+
+ /**
+ Returns whether the filter is enabled or not.
+ @see setEnabled().
+ */
+ bool isEnabled() const;
+
+ /**
+ Sets the list of categories to be considered when filtering incidences
+ according to the #ShowCategories criteria.
+
+ @param categoryList is a QStringList of categories.
+ @see categoryList().
+ */
+ void setCategoryList( const QStringList &categoryList );
+
+ /**
+ Returns the category list for this filter.
+ @see setCategoryList().
+ */
+ QStringList categoryList() const;
+
+ /**
+ Sets the list of email addresses to be considered when filtering
+ incidences according ot the #HideNoMatchingAttendeeTodos criteria.
+
+ @param emailList is a QStringList of email addresses.
+ @see emailList().
+ */
+ void setEmailList( const QStringList &emailList );
+
+ /**
+ Returns the email list for this filter.
+ @see setEmailList().
+ */
+ QStringList emailList() const;
+
+ /**
+ Sets the number of days for the #HideCompletedTodos criteria.
+ If a to-do has been completed within the recent @p timespan days,
+ then that to-do will be removed during filtering. If a time span is
+ not specified in the filter, then all completed to-dos will be removed
+ if the #HideCompletedTodos criteria is set.
+
+ @param timespan is an integer representing a time span in days.
+ @see completedTimeSpan().
+ */
+ void setCompletedTimeSpan( int timespan );
+
+ /**
+ Returns the completed time span for this filter.
+ @see setCompletedTimeSpan()
+ */
+ int completedTimeSpan() const;
+
+ /**
+ Compares this with @p filter for equality.
+
+ @param filter the CalFilter to compare.
+ */
+ bool operator==( const CalFilter &filter ) const;
+
+ private:
+ //@cond PRIVATE
+ Q_DISABLE_COPY( CalFilter )
+ class Private;
+ Private *const d;
+ //@endcond
+};
+
+}
+
+#endif
diff --git a/kcalcore/calformat.cpp b/kcalcore/calformat.cpp
new file mode 100644
index 0000000..ad9ae83
--- /dev/null
+++ b/kcalcore/calformat.cpp
@@ -0,0 +1,147 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the CalFormat base class.
+
+ @brief
+ Base class providing an interface to various calendar formats.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#include <config-kcalcore.h>
+#include "calformat.h"
+#include "exceptions.h"
+
+#if defined(HAVE_UUID_UUID_H)
+#include <uuid/uuid.h>
+#else
+#include <KRandom>
+#include <QtCore/QDateTime>
+#endif
+
+using namespace KCalCore;
+
+/**
+ Private class that helps to provide binary compatibility between releases.
+ @internal
+*/
+//@cond PRIVATE
+class KCalCore::CalFormat::Private
+{
+ public:
+ Private() : mException( 0 ) {}
+ ~Private() { delete mException; }
+ static QString mApplication; // Name of application, for creating unique ID strings
+ static QString mProductId; // PRODID string to write to calendar files
+ QString mLoadedProductId; // PRODID string loaded from calendar file
+ Exception *mException;
+};
+
+QString CalFormat::Private::mApplication = QLatin1String( "libkcal" );
+QString CalFormat::Private::mProductId =
+ QLatin1String( "-//K Desktop Environment//NONSGML libkcal 4.3//EN" );
+//@endcond
+
+CalFormat::CalFormat()
+ : d( new KCalCore::CalFormat::Private )
+{
+}
+
+CalFormat::~CalFormat()
+{
+ clearException();
+ delete d;
+}
+
+void CalFormat::clearException()
+{
+ delete d->mException;
+ d->mException = 0;
+}
+
+void CalFormat::setException( Exception *exception )
+{
+ delete d->mException;
+ d->mException = exception;
+}
+
+Exception *CalFormat::exception() const
+{
+ return d->mException;
+}
+
+void CalFormat::setApplication( const QString &application,
+ const QString &productID )
+{
+ Private::mApplication = application;
+ Private::mProductId = productID;
+}
+
+const QString &CalFormat::application()
+{
+ return Private::mApplication;
+}
+
+const QString &CalFormat::productId()
+{
+ return Private::mProductId;
+}
+
+QString CalFormat::loadedProductId()
+{
+ return d->mLoadedProductId;
+}
+
+void CalFormat::setLoadedProductId( const QString &id )
+{
+ d->mLoadedProductId = id;
+}
+
+QString CalFormat::createUniqueId()
+{
+#if defined(HAVE_UUID_UUID_H)
+ uuid_t uuid;
+ char suuid[64];
+
+ uuid_generate_random( uuid );
+ uuid_unparse( uuid, suuid );
+ return QString( suuid );
+#else
+ int hashTime = QTime::currentTime().hour() +
+ QTime::currentTime().minute() + QTime::currentTime().second() +
+ QTime::currentTime().msec();
+ QString uidStr = QString( "%1-%2.%3" ).
+ arg( Private::mApplication ).
+ arg( KRandom::random() ).
+ arg( hashTime );
+ return uidStr;
+#endif
+}
+
+void CalFormat::virtual_hook( int id, void *data )
+{
+ Q_UNUSED( id );
+ Q_UNUSED( data );
+ Q_ASSERT( false );
+}
diff --git a/kcalcore/calformat.h b/kcalcore/calformat.h
new file mode 100644
index 0000000..ad1f505
--- /dev/null
+++ b/kcalcore/calformat.h
@@ -0,0 +1,199 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001-2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the CalFormat abstract base class.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#ifndef KCALCORE_CALFORMAT_H
+#define KCALCORE_CALFORMAT_H
+
+#include "kcalcore_export.h"
+#include "calendar.h"
+
+#include <QtCore/QString>
+
+namespace KCalCore {
+
+class Exception;
+
+/**
+ @brief
+ An abstract base class that provides an interface to various calendar formats.
+
+ This is the base class for calendar formats. It provides an interface for the
+ generation/interpretation of a textual representation of a calendar.
+*/
+class KCALCORE_EXPORT CalFormat
+{
+ public:
+ /**
+ Constructs a new Calendar Format object.
+ */
+ CalFormat();
+
+ /**
+ Destructor.
+ */
+ virtual ~CalFormat();
+
+ /**
+ Loads a calendar on disk into the calendar associated with this format.
+
+ @param calendar is the Calendar to be loaded.
+ @param fileName is the name of the disk file containing the Calendar data.
+
+ @return true if successful; false otherwise.
+ */
+ virtual bool load( const Calendar::Ptr &calendar, const QString &fileName ) = 0;
+
+ /**
+ Writes the calendar to disk.
+
+ @param calendar is the Calendar containing the data to be saved.
+ @param fileName is the name of the file to write the calendar data.
+
+ @return true if successful; false otherwise.
+ */
+ virtual bool save( const Calendar::Ptr &calendar, const QString &fileName ) = 0;
+
+ /**
+ Loads a calendar from a string
+
+ @param calendar is the Calendar to be loaded.
+ @param string is the QString containing the Calendar data.
+ @param deleted use deleted incidences
+ @param notebook notebook uid
+
+ @return true if successful; false otherwise.
+ @see fromRawString(), toString().
+ */
+ virtual bool fromString( const Calendar::Ptr &calendar, const QString &string,
+ bool deleted = false, const QString &notebook = QString() ) = 0;
+
+ /**
+ Parses a utf8 encoded string, returning the first iCal component
+ encountered in that string. This is an overload used for efficient
+ reading to avoid utf8 conversions, which are expensive when reading
+ from disk.
+
+ @param calendar is the Calendar to be loaded.
+ @param string is the QByteArray containing the Calendar data.
+ @param deleted use deleted incidences
+ @param notebook notebook uid
+
+ @return true if successful; false otherwise.
+ @see fromString(), toString().
+ */
+ virtual bool fromRawString( const Calendar::Ptr &calendar, const QByteArray &string,
+ bool deleted = false, const QString &notebook = QString() ) = 0;
+
+ /**
+ Returns the calendar as a string.
+ @param calendar is the Calendar containing the data to be saved.
+ @param notebook uid use only incidences with given notebook
+ @param deleted use deleted incidences
+
+ @return a QString containing the Calendar data if successful;
+ an empty string otherwise.
+ @see fromString(), fromRawString().
+ */
+ virtual QString toString( const Calendar::Ptr &calendar,
+ const QString &notebook = QString(), bool deleted = false ) = 0;
+
+ /**
+ Clears the exception status.
+ */
+ void clearException();
+
+ /**
+ Returns an exception, if there is any, containing information about the
+ last error that occurred.
+ */
+ Exception *exception() const;
+
+ /**
+ Sets the application name for use in unique IDs and error messages,
+ and product ID for incidence PRODID property
+
+ @param application is a string containing the application name.
+ @param productID is a string containing the product identifier.
+ */
+ static void setApplication( const QString &application,
+ const QString &productID );
+
+ /**
+ Returns the application name used in unique IDs and error messages.
+ */
+ static const QString &application(); //krazy:exclude=constref
+
+ /**
+ Returns the our library's PRODID string to write into calendar files.
+ */
+ static const QString &productId(); //krazy:exclude=constref
+
+ /**
+ Returns the PRODID string loaded from calendar file.
+ @see setLoadedProductId()
+ */
+ QString loadedProductId();
+
+ /**
+ Creates a unique id string.
+ */
+ static QString createUniqueId();
+
+ /**
+ Sets an exception that is to be used by the functions of this class
+ to report errors.
+
+ @param error is a pointer to an Exception which contains the exception.
+ */
+ void setException( Exception *error );
+
+ protected:
+ /**
+ Sets the the PRODID string loaded from calendar file.
+ @param id is a pruduct Id string to set for the calendar file.
+ @see loadedProductId()
+ */
+ void setLoadedProductId( const QString &id );
+
+ /**
+ @copydoc
+ IncidenceBase::virtual_hook()
+ */
+ virtual void virtual_hook( int id, void *data );
+
+ private:
+ //@cond PRIVATE
+ Q_DISABLE_COPY( CalFormat )
+ class Private;
+ Private *const d;
+ //@endcond
+};
+
+}
+
+#endif
diff --git a/kcalcore/calstorage.cpp b/kcalcore/calstorage.cpp
new file mode 100644
index 0000000..af96d43
--- /dev/null
+++ b/kcalcore/calstorage.cpp
@@ -0,0 +1,64 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2002,2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the CalStorage abstract base class.
+
+ @brief
+ An abstract base class that provides a calendar storage interface.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#include "calstorage.h"
+
+using namespace KCalCore;
+
+/**
+ Private class that helps to provide binary compatibility between releases.
+ @internal
+*/
+//@cond PRIVATE
+class KCalCore::CalStorage::Private
+{
+ public:
+ Private( const Calendar::Ptr &cal )
+ : mCalendar( cal )
+ {}
+ Calendar::Ptr mCalendar;
+};
+//@endcond
+
+CalStorage::CalStorage( const Calendar::Ptr &calendar )
+ : d( new KCalCore::CalStorage::Private ( calendar ) )
+{
+}
+
+CalStorage::~CalStorage()
+{
+ delete d;
+}
+
+Calendar::Ptr CalStorage::calendar() const
+{
+ return d->mCalendar;
+}
diff --git a/kcalcore/calstorage.h b/kcalcore/calstorage.h
new file mode 100644
index 0000000..cad5593
--- /dev/null
+++ b/kcalcore/calstorage.h
@@ -0,0 +1,101 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2002,2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the CalStorage abstract base class.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#ifndef KCALCORE_CALSTORAGE_H
+#define KCALCORE_CALSTORAGE_H
+
+#include "kcalcore_export.h"
+#include "calendar.h"
+
+#include <QtCore/QObject>
+
+namespace KCalCore {
+
+/**
+ @brief
+ An abstract base class that provides a calendar storage interface.
+
+ This is the base class for calendar storage. It provides an interface for the
+ loading and saving of calendars.
+*/
+class KCALCORE_EXPORT CalStorage : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ Construcst a new storage object for a calendar.
+ @param calendar is a pointer to a valid Calendar object.
+ */
+ explicit CalStorage( const Calendar::Ptr &calendar );
+
+ /**
+ Destuctor.
+ */
+ virtual ~CalStorage();
+
+ /**
+ Returns a pointer to the calendar whose storage is being managed.
+ */
+ Calendar::Ptr calendar() const;
+
+ /**
+ Opens the calendar for storage.
+ @return true if the open was successful; false otherwise.
+ */
+ virtual bool open() = 0;
+
+ /**
+ Loads the calendar into memory.
+ @return true if the load was successful; false otherwise.
+ */
+ virtual bool load() = 0;
+
+ /**
+ Saves the calendar.
+ @return true if the save was successful; false otherwise.
+ */
+ virtual bool save() = 0;
+
+ /**
+ Closes the calendar storage.
+ @return true if the close was successful; false otherwise.
+ */
+ virtual bool close() = 0;
+
+ private:
+ //@cond PRIVATE
+ Q_DISABLE_COPY( CalStorage )
+ class Private;
+ Private *const d;
+ //@endcond
+};
+
+}
+
+#endif
diff --git a/kcalcore/compat.cpp b/kcalcore/compat.cpp
new file mode 100644
index 0000000..9447fff
--- /dev/null
+++ b/kcalcore/compat.cpp
@@ -0,0 +1,280 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and defines
+ classes for managing compatibility between different calendar formats.
+
+ @brief
+ Classes that provide compatibility to older or "broken" calendar formats.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+ @author Reinhold Kainhofer \<reinhold@kainhofer.com\>
+*/
+
+#include "compat.h"
+#include "incidence.h"
+
+#include <KDebug>
+
+#include <QtCore/QRegExp>
+#include <QtCore/QString>
+
+using namespace KCalCore;
+
+Compat *CompatFactory::createCompat( const QString &productId )
+{
+ Compat *compat = 0;
+
+ int korg = productId.indexOf( "KOrganizer" );
+ int outl9 = productId.indexOf( "Outlook 9.0" );
+
+ // TODO: Use the version of LibKCal to determine the compat class...
+ if ( korg >= 0 ) {
+ int versionStart = productId.indexOf( " ", korg );
+ if ( versionStart >= 0 ) {
+ int versionStop = productId.indexOf( QRegExp( "[ /]" ), versionStart + 1 );
+ if ( versionStop >= 0 ) {
+ QString version = productId.mid( versionStart + 1,
+ versionStop - versionStart - 1 );
+
+ int versionNum = version.section( '.', 0, 0 ).toInt() * 10000 +
+ version.section( '.', 1, 1 ).toInt() * 100 +
+ version.section( '.', 2, 2 ).toInt();
+ int releaseStop = productId.indexOf( "/", versionStop );
+ QString release;
+ if ( releaseStop > versionStop ) {
+ release = productId.mid( versionStop+1, releaseStop-versionStop-1 );
+ }
+ if ( versionNum < 30100 ) {
+ compat = new CompatPre31;
+ } else if ( versionNum < 30200 ) {
+ compat = new CompatPre32;
+ } else if ( versionNum == 30200 && release == "pre" ) {
+ kDebug() << "Generating compat for KOrganizer 3.2 pre";
+ compat = new Compat32PrereleaseVersions;
+ } else if ( versionNum < 30400 ) {
+ compat = new CompatPre34;
+ } else if ( versionNum < 30500 ) {
+ compat = new CompatPre35;
+ }
+ }
+ }
+ } else if ( outl9 >= 0 ) {
+ kDebug() << "Generating compat for Outlook < 2000 (Outlook 9.0)";
+ compat = new CompatOutlook9;
+ }
+
+ if ( !compat ) {
+ compat = new Compat;
+ }
+
+ return compat;
+}
+
+Compat::Compat()
+{
+}
+
+Compat::~Compat()
+{
+}
+
+void Compat::fixEmptySummary( const Incidence::Ptr &incidence )
+{
+ // some stupid vCal exporters ignore the standard and use Description
+ // instead of Summary for the default field. Correct for this: Copy the
+ // first line of the description to the summary (if summary is just one
+ // line, move it)
+ if ( incidence->summary().isEmpty() && !( incidence->description().isEmpty() ) ) {
+ QString oldDescription = incidence->description().trimmed();
+ QString newSummary( oldDescription );
+ newSummary.remove( QRegExp( "\n.*" ) );
+ incidence->setSummary( newSummary );
+ if ( oldDescription == newSummary ) {
+ incidence->setDescription( "" );
+ }
+ }
+}
+
+void Compat::fixAlarms( const Incidence::Ptr &incidence )
+{
+ Q_UNUSED( incidence );
+}
+
+void Compat::fixFloatingEnd( QDate &date )
+{
+ Q_UNUSED( date );
+}
+
+void Compat::fixRecurrence( const Incidence::Ptr &incidence )
+{
+ Q_UNUSED( incidence );
+ // Prevent use of compatibility mode during subsequent changes by the application
+ // incidence->recurrence()->setCompatVersion();
+}
+
+int Compat::fixPriority( int priority )
+{
+ return priority;
+}
+
+bool Compat::useTimeZoneShift()
+{
+ return true;
+}
+
+void CompatPre35::fixRecurrence( const Incidence::Ptr &incidence )
+{
+ Recurrence *recurrence = incidence->recurrence();
+ if ( recurrence ) {
+ KDateTime start( incidence->dtStart() );
+ // kde < 3.5 only had one rrule, so no need to loop over all RRULEs.
+ RecurrenceRule *r = recurrence->defaultRRule();
+ if ( r && !r->dateMatchesRules( start ) ) {
+ recurrence->addExDateTime( start );
+ }
+ }
+
+ // Call base class method now that everything else is done
+ Compat::fixRecurrence( incidence );
+}
+
+int CompatPre34::fixPriority( int priority )
+{
+ if ( 0 < priority && priority < 6 ) {
+ // adjust 1->1, 2->3, 3->5, 4->7, 5->9
+ return 2 * priority - 1;
+ } else {
+ return priority;
+ }
+}
+
+void CompatPre32::fixRecurrence( const Incidence::Ptr &incidence )
+{
+ Recurrence *recurrence = incidence->recurrence();
+ if ( recurrence->recurs() && recurrence->duration() > 0 ) {
+ recurrence->setDuration( recurrence->duration() + incidence->recurrence()->exDates().count() );
+ }
+ // Call base class method now that everything else is done
+ CompatPre35::fixRecurrence( incidence );
+}
+
+void CompatPre31::fixFloatingEnd( QDate &endDate )
+{
+ endDate = endDate.addDays( 1 );
+}
+
+void CompatPre31::fixRecurrence( const Incidence::Ptr &incidence )
+{
+ CompatPre32::fixRecurrence( incidence );
+
+ Recurrence *recur = incidence->recurrence();
+ RecurrenceRule *r = 0;
+ if ( recur ) {
+ r = recur->defaultRRule();
+ }
+ if ( recur && r ) {
+ int duration = r->duration();
+ if ( duration > 0 ) {
+ // Backwards compatibility for KDE < 3.1.
+ // rDuration was set to the number of time periods to recur,
+ // with week start always on a Monday.
+ // Convert this to the number of occurrences.
+ r->setDuration( -1 );
+ QDate end( r->startDt().date() );
+ bool doNothing = false;
+ // # of periods:
+ int tmp = ( duration - 1 ) * r->frequency();
+ switch ( r->recurrenceType() ) {
+ case RecurrenceRule::rWeekly:
+ {
+ end = end.addDays( tmp * 7 + 7 - end.dayOfWeek() );
+ break;
+ }
+ case RecurrenceRule::rMonthly:
+ {
+ int month = end.month() - 1 + tmp;
+ end.setYMD( end.year() + month / 12, month % 12 + 1, 31 );
+ break;
+ }
+ case RecurrenceRule::rYearly:
+ {
+ end.setYMD( end.year() + tmp, 12, 31 );
+ break;
+ }
+ default:
+ doNothing = true;
+ break;
+ }
+ if ( !doNothing ) {
+ duration = r->durationTo(
+ KDateTime( end, QTime( 0, 0, 0 ), incidence->dtStart().timeSpec() ) );
+ r->setDuration( duration );
+ }
+ }
+
+ /* addYearlyNum */
+ // Dates were stored as day numbers, with a fiddle to take account of
+ // leap years. Convert the day number to a month.
+ QList<int> days = r->byYearDays();
+ if ( !days.isEmpty() ) {
+ QList<int> months = r->byMonths();
+ for ( int i = 0; i < months.size(); ++i ) {
+ int newmonth =
+ QDate( r->startDt().date().year(), 1, 1 ).addDays( months.at( i ) - 1 ).month();
+ if ( !months.contains( newmonth ) ) {
+ months.append( newmonth );
+ }
+ }
+
+ r->setByMonths( months );
+ days.clear();
+ r->setByYearDays( days );
+ }
+ }
+}
+
+void CompatOutlook9::fixAlarms( const Incidence::Ptr &incidence )
+{
+ if ( !incidence ) {
+ return;
+ }
+ Alarm::List alarms = incidence->alarms();
+ Alarm::List::Iterator it;
+ for ( it = alarms.begin(); it != alarms.end(); ++it ) {
+ Alarm::Ptr al = *it;
+ if ( al && al->hasStartOffset() ) {
+ Duration offsetDuration = al->startOffset();
+ int offs = offsetDuration.asSeconds();
+ if ( offs > 0 ) {
+ offsetDuration = Duration( -offs );
+ }
+ al->setStartOffset( offsetDuration );
+ }
+ }
+}
+
+bool Compat32PrereleaseVersions::useTimeZoneShift()
+{
+ return false;
+}
diff --git a/kcalcore/compat.h b/kcalcore/compat.h
new file mode 100644
index 0000000..c74aa9d
--- /dev/null
+++ b/kcalcore/compat.h
@@ -0,0 +1,285 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and defines
+ classes for managing compatibility between different calendar formats.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+ @author Reinhold Kainhofer \<reinhold@kainhofer.com\>
+*/
+
+#ifndef KCALCORE_COMPAT_P_H
+#define KCALCORE_COMPAT_P_H
+
+#include "incidence.h"
+
+#include <QtCore/QtGlobal> // for Q_DISABLE_COPY()
+
+class QDate;
+class QString;
+
+namespace KCalCore {
+
+class Compat;
+
+/**
+ @brief
+ Factory for creating the right Compat object.
+
+ @internal
+*/
+class CompatFactory
+{
+ public:
+ /**
+ Creates the appropriate Compat class as determined by the Product ID.
+
+ @param productId is a string containing a valid Product ID from
+ a supported calendar format.
+ @return A pointer to a Compat object which is owned by the caller.
+ */
+ static Compat *createCompat( const QString &productId );
+};
+
+/**
+ @brief
+ This class provides compatibility to older or broken calendar files.
+
+ @internal
+*/
+class Compat
+{
+ public:
+ /**
+ Constructor.
+ */
+ Compat();
+
+ /**
+ Destructor.
+ */
+ virtual ~Compat();
+
+ /**
+ Fixes the recurrence rule for an incidence.
+ @param incidence is a pointer to an Incidence object that may
+ need its recurrence rule fixed.
+ */
+ virtual void fixRecurrence( const Incidence::Ptr &incidence );
+
+ /**
+ Fixes an empty summary for an incidence.
+ @param incidence is a pointer to an Incidence object that may need
+ its summary fixed.
+ */
+ virtual void fixEmptySummary( const Incidence::Ptr &incidence );
+
+ /**
+ Fixes the alarms list an incidence.
+ @param incidence is a pointer to an Incidence object that may need
+ its alarms fixed.
+ */
+ virtual void fixAlarms( const Incidence::Ptr &incidence );
+
+ /**
+ Fixes the end date for floating events.
+ @param date is the end date to fix.
+ */
+ virtual void fixFloatingEnd( QDate &date );
+
+ /**
+ Fixes the priority.
+ @param priority is the priority value to fix.
+ @return an integer representing a valid priority value.
+ */
+ virtual int fixPriority( int priority );
+
+ /**
+ Returns true if a timezone shift should be used; false otherwise.
+ */
+ virtual bool useTimeZoneShift();
+
+ private:
+ //@cond PRIVATE
+ Q_DISABLE_COPY( Compat )
+ class Private;
+ Private *d;
+ //@endcond
+};
+
+/**
+ @brief
+ Compatibility class for KOrganizer pre-3.5 calendar files.
+
+ Before kde 3.5, the start date was not automatically a recurring date.
+ So, if the start date doesn't match the recurrence rule, we need to add
+ an ex-date for the date start. If a duration was given, the DTSTART was
+ only counted if it matched, so by accident this was already the correct
+ behavior, so we don't need to adjust the duration.
+*/
+class CompatPre35 : public Compat
+{
+ public:
+ /**
+ @copydoc
+ Compat::fixRecurrence()
+ */
+ virtual void fixRecurrence( const Incidence::Ptr &incidence );
+
+ private:
+ //@cond PRIVATE
+ class Private;
+ Private *d;
+ //@endcond
+};
+
+/**
+ @brief
+ Compatibility class for KOrganizer pre-3.4 calendar files.
+*/
+class CompatPre34 : public CompatPre35
+{
+ public:
+ /**
+ @copydoc
+ Compat::fixPriority()
+ */
+ virtual int fixPriority( int priority );
+
+ private:
+ //@cond PRIVATE
+ class Private;
+ Private *d;
+ //@endcond
+};
+
+/**
+ @brief
+ Compatibility class for KOrganizer pre-3.2 calendar files.
+
+ The recurrence has a specified number of repetitions.
+ Pre-3.2, this was extended by the number of exception dates.
+ This is also rfc 2445-compliant. The duration of an RRULE also counts
+ events that are later excluded via EXDATE or EXRULE.
+*/
+class CompatPre32 : public CompatPre34
+{
+ public:
+ /**
+ @copydoc
+ Compat::fixRecurrence()
+ */
+ virtual void fixRecurrence( const Incidence::Ptr &incidence );
+
+ private:
+ //@cond PRIVATE
+
+ class Private;
+ Private *d;
+ //@endcond
+};
+
+/**
+ @brief
+ Compatibility class for KOrganizer pre-3.1 calendar files.
+
+ Before kde 3.1, floating events (events without a date) had 0:00 of their
+ last day as the end date. E.g. 28.5.2005 0:00 until 28.5.2005 0:00 for an
+ event that lasted the whole day on May 28, 2005. According to RFC 2445, the
+ end date for such an event needs to be 29.5.2005 0:00.
+
+ Update: We misunderstood rfc 2445 in this regard. For all-day events, the
+ DTEND is the last day of the event. See a mail from the Author or rfc 2445:
+ http://www.imc.org/ietf-calendar/archive1/msg03648.html
+ However, as all other applications also got this wrong, we'll just leave it
+ as it is and use the wrong interpretation (was also discussed on ietf-calsify)
+*/
+class CompatPre31 : public CompatPre32
+{
+ public:
+ /**
+ @copydoc
+ Compat::fixFloatingEnd()
+ */
+ virtual void fixFloatingEnd( QDate &date );
+
+ /**
+ @copydoc
+ Compat::fixRecurrence()
+ */
+ virtual void fixRecurrence( const Incidence::Ptr &incidence );
+
+ private:
+ //@cond PRIVATE
+ class Private;
+ Private *d;
+ //@endcond
+};
+
+/**
+ @brief
+ Compatibility class for KOrganizer prerelease 3.2 calendar files.
+*/
+class Compat32PrereleaseVersions : public Compat
+{
+ public:
+ /**
+ @copydoc
+ Compat::useTimeZoneShift()
+ */
+ virtual bool useTimeZoneShift();
+
+ private:
+ //@cond PRIVATE
+ class Private;
+ Private *d;
+ //@endcond
+};
+
+/**
+ @brief
+ Compatibility class for Outlook 9 calendar files.
+
+ In Outlook 9, alarms have the wrong sign. I.e. RFC 2445 says that negative
+ values for the trigger are before the event's start. Outlook/exchange,
+ however used positive values.
+*/
+class CompatOutlook9 : public Compat
+{
+ public:
+ /**
+ @copydoc
+ Compat::fixAlarms()
+ */
+ virtual void fixAlarms( const Incidence::Ptr &incidence );
+
+ private:
+ //@cond PRIVATE
+ class Private;
+ Private *d;
+ //@endcond
+};
+
+}
+
+#endif
diff --git a/kcalcore/config-kcalcore.h.cmake b/kcalcore/config-kcalcore.h.cmake
new file mode 100644
index 0000000..4a6f35c
--- /dev/null
+++ b/kcalcore/config-kcalcore.h.cmake
@@ -0,0 +1,5 @@
+/* Define to 1 if you have the <uuid/uuid.h> header file. */
+#cmakedefine HAVE_UUID_UUID_H
+
+/* Define to 1 if the libical version is equal or greater than 0.46 */
+#cmakedefine USE_ICAL_0_46
diff --git a/kcalcore/customproperties.cpp b/kcalcore/customproperties.cpp
new file mode 100644
index 0000000..8c42851
--- /dev/null
+++ b/kcalcore/customproperties.cpp
@@ -0,0 +1,246 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2002,2006,2010 David Jarvie <djarvie@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the CustomProperties class.
+
+ @brief
+ A class to manage custom calendar properties.
+
+ @author David Jarvie \<djarvie@kde.org\>
+*/
+
+#include "customproperties.h"
+
+#include <QDataStream>
+
+using namespace KCalCore;
+
+//@cond PRIVATE
+static bool checkName( const QByteArray &name );
+
+class CustomProperties::Private
+{
+ public:
+ bool operator==( const Private &other ) const;
+ QMap<QByteArray, QString> mProperties; // custom calendar properties
+ QMap<QByteArray, QString> mPropertyParameters;
+};
+
+bool CustomProperties::Private::operator==( const CustomProperties::Private &other ) const
+{
+ if ( mProperties.count() != other.mProperties.count() ) {
+ return false;
+ }
+ for ( QMap<QByteArray, QString>::ConstIterator it = mProperties.begin();
+ it != mProperties.end(); ++it ) {
+ QMap<QByteArray, QString>::ConstIterator itOther =
+ other.mProperties.find( it.key() );
+ if ( itOther == other.mProperties.end() || itOther.value() != it.value() ) {
+ return false;
+ }
+ }
+ for ( QMap<QByteArray, QString>::ConstIterator it = mPropertyParameters.begin();
+ it != mPropertyParameters.end(); ++it ) {
+ QMap<QByteArray, QString>::ConstIterator itOther =
+ other.mPropertyParameters.find( it.key() );
+ if ( itOther == other.mPropertyParameters.end() || itOther.value() != it.value() ) {
+ return false;
+ }
+ }
+ return true;
+}
+//@endcond
+
+CustomProperties::CustomProperties()
+ : d( new Private )
+{
+}
+
+CustomProperties::CustomProperties( const CustomProperties &cp )
+ : d( new Private( *cp.d ) )
+{
+}
+
+CustomProperties &CustomProperties::operator=( const CustomProperties &other )
+{
+ // check for self assignment
+ if ( &other == this ) {
+ return *this;
+ }
+
+ *d = *other.d;
+ return *this;
+}
+
+CustomProperties::~CustomProperties()
+{
+ delete d;
+}
+
+bool CustomProperties::operator==( const CustomProperties &other ) const
+{
+ return *d == *other.d;
+}
+
+void CustomProperties::setCustomProperty( const QByteArray &app, const QByteArray &key,
+ const QString &value )
+{
+ if ( value.isNull() || key.isEmpty() || app.isEmpty() ) {
+ return;
+ }
+ QByteArray property = "X-KDE-" + app + '-' + key;
+ if ( !checkName( property ) ) {
+ return;
+ }
+ customPropertyUpdate();
+ d->mProperties[property] = value;
+ customPropertyUpdated();
+}
+
+void CustomProperties::removeCustomProperty( const QByteArray &app, const QByteArray &key )
+{
+ removeNonKDECustomProperty( QByteArray( "X-KDE-" + app + '-' + key ) );
+}
+
+QString CustomProperties::customProperty( const QByteArray &app, const QByteArray &key ) const
+{
+ return nonKDECustomProperty( QByteArray( "X-KDE-" + app + '-' + key ) );
+}
+
+QByteArray CustomProperties::customPropertyName( const QByteArray &app, const QByteArray &key )
+{
+ QByteArray property( "X-KDE-" + app + '-' + key );
+ if ( !checkName( property ) ) {
+ return QByteArray();
+ }
+ return property;
+}
+
+void CustomProperties::setNonKDECustomProperty( const QByteArray &name, const QString &value,
+ const QString &parameters )
+{
+ if ( value.isNull() || !checkName( name ) ) {
+ return;
+ }
+ customPropertyUpdate();
+ d->mProperties[name] = value;
+ d->mPropertyParameters[name] = parameters;
+ customPropertyUpdated();
+}
+void CustomProperties::removeNonKDECustomProperty( const QByteArray &name )
+{
+ if ( d->mProperties.contains( name ) ) {
+ customPropertyUpdate();
+ d->mProperties.remove( name );
+ d->mPropertyParameters.remove( name );
+ customPropertyUpdated();
+ }
+}
+
+QString CustomProperties::nonKDECustomProperty( const QByteArray &name ) const
+{
+ return d->mProperties.value( name );
+}
+
+QString CustomProperties::nonKDECustomPropertyParameters( const QByteArray &name ) const
+{
+ return d->mPropertyParameters.value( name );
+}
+
+void CustomProperties::setCustomProperties( const QMap<QByteArray, QString> &properties )
+{
+ bool changed = false;
+ for ( QMap<QByteArray, QString>::ConstIterator it = properties.begin();
+ it != properties.end(); ++it ) {
+ // Validate the property name and convert any null string to empty string
+ if ( checkName( it.key() ) ) {
+ d->mProperties[it.key()] = it.value().isNull() ? QString( "" ) : it.value();
+ if ( !changed ) {
+ customPropertyUpdate();
+ }
+ changed = true;
+ }
+ }
+ if ( changed ) {
+ customPropertyUpdated();
+ }
+}
+
+QMap<QByteArray, QString> CustomProperties::customProperties() const
+{
+ return d->mProperties;
+}
+
+void CustomProperties::customPropertyUpdate()
+{
+}
+
+void CustomProperties::customPropertyUpdated()
+{
+}
+
+void CustomProperties::virtual_hook( int id, void *data )
+{
+ Q_UNUSED( id );
+ Q_UNUSED( data );
+ Q_ASSERT( false );
+}
+
+//@cond PRIVATE
+bool checkName( const QByteArray &name )
+{
+ // Check that the property name starts with 'X-' and contains
+ // only the permitted characters
+ const char *n = name;
+ int len = name.length();
+ if ( len < 2 || n[0] != 'X' || n[1] != '-' ) {
+ return false;
+ }
+ for ( int i = 2; i < len; ++i ) {
+ char ch = n[i];
+ if ( ( ch >= 'A' && ch <= 'Z' ) ||
+ ( ch >= 'a' && ch <= 'z' ) ||
+ ( ch >= '0' && ch <= '9' ) ||
+ ch == '-' ) {
+ continue;
+ }
+ return false; // invalid character found
+ }
+ return true;
+}
+//@endcond
+
+QDataStream &KCalCore::operator<<( QDataStream &stream,
+ const KCalCore::CustomProperties &properties )
+{
+ return stream << properties.d->mProperties
+ << properties.d->mPropertyParameters;
+}
+
+QDataStream &KCalCore::operator>>( QDataStream &stream,
+ KCalCore::CustomProperties &properties )
+{
+ return stream >> properties.d->mProperties
+ >> properties.d->mPropertyParameters;
+}
+
diff --git a/kcalcore/customproperties.h b/kcalcore/customproperties.h
new file mode 100644
index 0000000..1c093a1
--- /dev/null
+++ b/kcalcore/customproperties.h
@@ -0,0 +1,227 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2002,2006,2010 David Jarvie <djarvie@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the CustomProperties class.
+
+ @author David Jarvie \<djarvie@kde.org\>
+*/
+
+#ifndef KCALCORE_CUSTOMPROPERTIES_H
+#define KCALCORE_CUSTOMPROPERTIES_H
+
+#include "kcalcore_export.h"
+
+#include <QtCore/QMap>
+#include <QtCore/QString>
+
+namespace KCalCore {
+
+/**
+ @brief
+ A class to manage custom calendar properties.
+
+ This class represents custom calendar properties.
+ It is used as a base class for classes which represent calendar components.
+ A custom property name written by the kcalcore library has the form X-KDE-APP-KEY
+ where APP represents the application name, and KEY distinguishes individual
+ properties for the application.
+ In keeping with RFC2445, property names must be composed only of the
+ characters A-Z, a-z, 0-9 and '-'.
+*/
+class KCALCORE_EXPORT CustomProperties
+{
+ friend KCALCORE_EXPORT QDataStream &operator<<( QDataStream &s,
+ const KCalCore::CustomProperties &properties );
+ friend KCALCORE_EXPORT QDataStream &operator>>( QDataStream &s,
+ KCalCore::CustomProperties &properties );
+ public:
+ /**
+ Constructs an empty custom properties instance.
+ */
+ CustomProperties();
+
+ /**
+ Copy constructor.
+ @param other is the one to copy.
+ */
+ CustomProperties( const CustomProperties &other );
+
+ /**
+ Destructor.
+ */
+ virtual ~CustomProperties();
+
+ /**
+ Compare this with @p properties for equality.
+ @param properties is the one to compare.
+ @warning The comparison is not polymorphic.
+ */
+ bool operator==( const CustomProperties &properties ) const;
+
+ /**
+ Create or modify a custom calendar property.
+
+ @param app Application name as it appears in the custom property name.
+ @param key Property identifier specific to the application.
+ @param value The property's value. A call with a value of QString()
+ will be ignored.
+ @see removeCustomProperty().
+ */
+ void setCustomProperty( const QByteArray &app, const QByteArray &key,
+ const QString &value );
+
+ /**
+ Delete a custom calendar property.
+
+ @param app Application name as it appears in the custom property name.
+ @param key Property identifier specific to the application.
+ @see setCustomProperty().
+ */
+ void removeCustomProperty( const QByteArray &app, const QByteArray &key );
+
+ /**
+ Return the value of a custom calendar property.
+
+ @param app Application name as it appears in the custom property name.
+ @param key Property identifier specific to the application.
+ @return Property value, or QString() if (and only if) the property
+ does not exist.
+ */
+ QString customProperty( const QByteArray &app, const QByteArray &key ) const;
+
+ /**
+ Validate and return the full name of a custom calendar property.
+
+ @param app Application name as it appears in the custom property name.
+ @param key Property identifier specific to the application.
+ @return Full property name, or empty string if it would contain invalid
+ characters
+ */
+ static QByteArray customPropertyName( const QByteArray &app, const QByteArray &key );
+
+ /**
+ Create or modify a non-KDE or non-standard custom calendar property.
+
+ @param name Full property name
+ @param value The property's value. A call with a value of QString()
+ will be ignored.
+ @param parameters The formatted list of parameters for the
+ property. They should be formatted as RFC specifies, that is,
+ KEY=VALUE;KEY2=VALUE2. We're mostly concerned about passing them
+ through as-is albeit they can be of course parsed if need be.
+ @see removeNonKDECustomProperty().
+ */
+ void setNonKDECustomProperty( const QByteArray &name, const QString &value,
+ const QString &parameters = QString() );
+
+ /**
+ Delete a non-KDE or non-standard custom calendar property.
+
+ @param name Full property name
+ @see setNonKDECustomProperty().
+ */
+ void removeNonKDECustomProperty( const QByteArray &name );
+
+ /**
+ Return the value of a non-KDE or non-standard custom calendar property.
+
+ @param name Full property name
+ @return Property value, or QString() if (and only if) the property
+ does not exist.
+ */
+ QString nonKDECustomProperty( const QByteArray &name ) const;
+
+ /**
+ Return the parameters of a non-KDE or non-standard custom
+ calendar property.
+
+ @param name Full property name
+ @return The parameters for the given property. Empty string is
+ returned if none are set.
+ */
+ QString nonKDECustomPropertyParameters( const QByteArray &name ) const;
+
+ /**
+ Initialise the alarm's custom calendar properties to the specified
+ key/value pairs.
+ @param properties is a QMap of property key/value pairs.
+ @see customProperties().
+ */
+ void setCustomProperties( const QMap<QByteArray, QString> &properties );
+
+ /**
+ Returns all custom calendar property key/value pairs.
+ @see setCustomProperties().
+ */
+ QMap<QByteArray, QString> customProperties() const;
+
+ /**
+ Assignment operator.
+ @warning The assignment is not polymorphic.
+ @param other is the CustomProperty to assign.
+ */
+ CustomProperties &operator=( const CustomProperties &other );
+
+ protected:
+ /**
+ Called before a custom property will be changed.
+ The default implementation does nothing: override in derived classes
+ to perform change processing.
+ */
+ virtual void customPropertyUpdate();
+
+ /**
+ Called when a custom property has been changed.
+ The default implementation does nothing: override in derived classes
+ to perform change processing.
+ */
+ virtual void customPropertyUpdated();
+
+ /**
+ @copydoc
+ IncidenceBase::virtual_hook()
+ */
+ virtual void virtual_hook( int id, void *data );
+
+ private:
+ //@cond PRIVATE
+ class Private;
+ Private *const d;
+ //@endcond
+};
+
+/**
+ Serializes the @p properties object into the @p stream.
+*/
+KCALCORE_EXPORT QDataStream &operator<<( QDataStream &stream,
+ const KCalCore::CustomProperties &properties );
+
+/**
+ Initializes the @p properties object from the @p stream.
+*/
+KCALCORE_EXPORT QDataStream &operator>>( QDataStream &stream,
+ KCalCore::CustomProperties &properties );
+
+}
+
+#endif
diff --git a/kcalcore/duration.cpp b/kcalcore/duration.cpp
new file mode 100644
index 0000000..c08e440
--- /dev/null
+++ b/kcalcore/duration.cpp
@@ -0,0 +1,211 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (c) 2007 David Jarvie <djarvie@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Duration class.
+
+ @brief
+ Represents a span of time measured in seconds.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+ @author David Jarvie \<software@astrojar.org.uk\>
+*/
+#include "duration.h"
+#include <KDateTime>
+
+using namespace KCalCore;
+
+/**
+ Private class that helps to provide binary compatibility between releases.
+ @internal
+*/
+//@cond PRIVATE
+class KCalCore::Duration::Private
+{
+ public:
+ int seconds() const {
+ return mDaily ? mDuration * 86400 : mDuration;
+ }
+ int mDuration; // number of seconds or days in the duration
+ bool mDaily; // specified in terms of days rather than seconds
+};
+//@endcond
+
+Duration::Duration()
+ : d( new KCalCore::Duration::Private() )
+{
+}
+
+Duration::Duration( const KDateTime &start, const KDateTime &end )
+ : d( new KCalCore::Duration::Private() )
+{
+ if ( start.time() == end.time() && start.timeSpec() == end.timeSpec() ) {
+ d->mDuration = start.daysTo( end );
+ d->mDaily = true;
+ } else {
+ d->mDuration = start.secsTo( end );
+ d->mDaily = false;
+ }
+}
+
+Duration::Duration( const KDateTime &start, const KDateTime &end, Type type )
+ : d( new KCalCore::Duration::Private() )
+{
+ if ( type == Days ) {
+ KDateTime endSt( end.toTimeSpec( start ) );
+ d->mDuration = start.daysTo( endSt );
+ if ( d->mDuration ) {
+ // Round down to whole number of days if necessary
+ if ( start < endSt ) {
+ if ( endSt.time() < start.time() ) {
+ --d->mDuration;
+ }
+ } else {
+ if ( endSt.time() > start.time() ) {
+ ++d->mDuration;
+ }
+ }
+ }
+ d->mDaily = true;
+ } else {
+ d->mDuration = start.secsTo( end );
+ d->mDaily = false;
+ }
+}
+
+Duration::Duration( int duration, Type type )
+ : d( new KCalCore::Duration::Private() )
+{
+ d->mDuration = duration;
+ d->mDaily = ( type == Days );
+}
+
+Duration::Duration( const Duration &duration )
+ : d( new KCalCore::Duration::Private( *duration.d ) )
+{
+}
+
+Duration::~Duration()
+{
+ delete d;
+}
+
+Duration &Duration::operator=( const Duration &duration )
+{
+ // check for self assignment
+ if ( &duration == this ) {
+ return *this;
+ }
+
+ *d = *duration.d;
+ return *this;
+}
+
+Duration::operator bool() const
+{
+ return d->mDuration;
+}
+
+bool Duration::operator<( const Duration &other ) const
+{
+ if ( d->mDaily == other.d->mDaily ) {
+ // guard against integer overflow for two daily durations
+ return d->mDuration < other.d->mDuration;
+ }
+ return d->seconds() < other.d->seconds();
+}
+
+bool Duration::operator==( const Duration &other ) const
+{
+ // Note: daily and non-daily durations are always unequal, since a day's
+ // duration may differ from 24 hours if it happens to span a daylight saving
+ // time change.
+ return d->mDuration == other.d->mDuration &&
+ d->mDaily == other.d->mDaily;
+}
+
+Duration &Duration::operator+=( const Duration &other )
+{
+ if ( d->mDaily == other.d->mDaily ) {
+ d->mDuration += other.d->mDuration;
+ } else if ( d->mDaily ) {
+ d->mDuration = d->mDuration * 86400 + other.d->mDuration;
+ d->mDaily = false;
+ } else {
+ d->mDuration += other.d->mDuration + 86400;
+ }
+ return *this;
+}
+
+Duration Duration::operator-() const
+{
+ return Duration( -d->mDuration, ( d->mDaily ? Days : Seconds ) );
+}
+
+Duration &Duration::operator-=( const Duration &duration )
+{
+ return operator+=( -duration );
+}
+
+Duration &Duration::operator*=( int value )
+{
+ d->mDuration *= value;
+ return *this;
+}
+
+Duration &Duration::operator/=( int value )
+{
+ d->mDuration /= value;
+ return *this;
+}
+
+KDateTime Duration::end( const KDateTime &start ) const
+{
+ return d->mDaily ? start.addDays( d->mDuration )
+ : start.addSecs( d->mDuration );
+}
+
+Duration::Type Duration::type() const
+{
+ return d->mDaily ? Days : Seconds;
+}
+
+bool Duration::isDaily() const
+{
+ return d->mDaily;
+}
+
+int Duration::asSeconds() const
+{
+ return d->seconds();
+}
+
+int Duration::asDays() const
+{
+ return d->mDaily ? d->mDuration : d->mDuration / 86400;
+}
+
+int Duration::value() const
+{
+ return d->mDuration;
+}
diff --git a/kcalcore/duration.h b/kcalcore/duration.h
new file mode 100644
index 0000000..e7aec11
--- /dev/null
+++ b/kcalcore/duration.h
@@ -0,0 +1,300 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001-2003 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (c) 2007 David Jarvie <djarvie@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Duration class.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+ @author David Jarvie \<software@astrojar.org.uk\>
+*/
+
+#ifndef KCALCORE_DURATION_H
+#define KCALCORE_DURATION_H
+
+#include "kcalcore_export.h"
+
+class KDateTime;
+
+namespace KCalCore {
+
+/**
+ @brief
+ Represents a span of time measured in seconds or days.
+
+ A duration is a span of time measured in seconds or days. Construction can
+ be done by specifying a stop and end time, or simply by specifying the number
+ of seconds or days.
+
+ Much of the time, it does not matter whether a duration is specified in
+ seconds or in days. But it does make a difference when a duration is used to
+ define a time period encompassing a daylight saving time change.
+*/
+class KCALCORE_EXPORT Duration
+{
+ public:
+ /**
+ The unit of time used to define the duration.
+ */
+ enum Type {
+ Seconds, /**< duration is a number of seconds */
+ Days /**< duration is a number of days */
+ };
+
+ /**
+ Constructs a duration of 0 seconds.
+ */
+ Duration();
+
+ /**
+ Constructs a duration from @p start to @p end.
+
+ If the time of day in @p start and @p end is equal, and their time
+ specifications (i.e. time zone etc.) are the same, the duration will be
+ set in terms of days. Otherwise, the duration will be set in terms of
+ seconds.
+
+ @param start is the time the duration begins.
+ @param end is the time the duration ends.
+ */
+ Duration( const KDateTime &start, const KDateTime &end );
+
+ /**
+ Constructs a duration from @p start to @p end.
+
+ If @p type is Days, and the time of day in @p start's time zone differs
+ between @p start and @p end, the duration will be rounded down to the
+ nearest whole number of days.
+
+ @param start is the time the duration begins.
+ @param end is the time the duration ends.
+ @param type the unit of time to use (seconds or days)
+ */
+ Duration( const KDateTime &start, const KDateTime &end, Type type );
+
+ /**
+ Constructs a duration with a number of seconds or days.
+
+ @param duration the number of seconds or days in the duration
+ @param type the unit of time to use (seconds or days)
+ */
+ // Keep the following implicit since instances are often used in integer evaluations.
+ Duration( int duration, Type type = Seconds ); //krazy:exclude=explicit
+
+ /**
+ Constructs a duration by copying another duration object.
+
+ @param duration is the duration to copy.
+ */
+ Duration( const Duration &duration );
+
+ /**
+ Destroys a duration.
+ */
+ ~Duration();
+
+ /**
+ Sets this duration equal to @p duration.
+
+ @param duration is the duration to copy.
+ */
+ Duration &operator=( const Duration &duration );
+
+ /**
+ Returns true if this duration is non-zero.
+ */
+ operator bool() const;
+
+ /**
+ Returns true if this duration is zero.
+ */
+ bool operator!() const { return !operator bool(); }
+
+ /**
+ Returns true if this duration is smaller than the @p other.
+ @param other is the other duration to compare.
+ */
+ bool operator<( const Duration &other ) const;
+
+ /**
+ Returns true if this duration is smaller than or equal to the @p other.
+ @param other is the other duration to compare.
+ */
+ bool operator<=( const Duration &other ) const
+ { return !other.operator<( *this ); }
+
+ /**
+ Returns true if this duration is greater than the @p other.
+ @param other is the other duration to compare.
+ */
+ bool operator>( const Duration &other ) const
+ { return other.operator<( *this ); }
+
+ /**
+ Returns true if this duration is greater than or equal to the @p other.
+ @param other is the other duration to compare.
+ */
+ bool operator>=( const Duration &other ) const
+ { return !operator<( other ); }
+
+ /**
+ Returns true if this duration is equal to the @p other.
+ Daily and non-daily durations are always considered unequal, since a
+ day's duration may differ from 24 hours if it happens to span a daylight
+ saving time change.
+ @param other the other duration to compare
+ */
+ bool operator==( const Duration &other ) const;
+
+ /**
+ Returns true if this duration is not equal to the @p other.
+ Daily and non-daily durations are always considered unequal, since a
+ day's duration may differ from 24 hours if it happens to span a daylight
+ saving time change.
+ @param other is the other duration to compare.
+ */
+ bool operator!=( const Duration &other ) const
+ { return !operator==( other ); }
+
+ /**
+ Adds another duration to this one.
+ If one is in terms of days and the other in terms of seconds,
+ the result is in terms of seconds.
+ @param other the other duration to add
+ */
+ Duration &operator+=( const Duration &other );
+
+ /**
+ Adds two durations.
+ If one is in terms of days and the other in terms of seconds,
+ the result is in terms of seconds.
+
+ @param other the other duration to add
+ @return combined duration
+ */
+ Duration operator+( const Duration &other ) const
+ { return Duration( *this ) += other; }
+
+ /**
+ Returns the negative of this duration.
+ */
+ Duration operator-() const;
+
+ /**
+ Subtracts another duration from this one.
+ If one is in terms of days and the other in terms of seconds,
+ the result is in terms of seconds.
+
+ @param other the other duration to subtract
+ */
+ Duration &operator-=( const Duration &other );
+
+ /**
+ Returns the difference between another duration and this.
+ If one is in terms of days and the other in terms of seconds,
+ the result is in terms of seconds.
+
+ @param other the other duration to subtract
+ @return difference in durations
+ */
+ Duration operator-( const Duration &other ) const
+ { return Duration( *this ) += other; }
+
+ /**
+ Multiplies this duration by a value.
+ @param value value to multiply by
+ */
+ Duration &operator*=( int value );
+
+ /**
+ Multiplies a duration by a value.
+
+ @param value value to multiply by
+ @return resultant duration
+ */
+ Duration operator*( int value ) const
+ { return Duration( *this ) *= value; }
+
+ /**
+ Divides this duration by a value.
+ @param value value to divide by
+ */
+ Duration &operator/=( int value );
+
+ /**
+ Divides a duration by a value.
+
+ @param value value to divide by
+ @return resultant duration
+ */
+ Duration operator/( int value ) const
+ { return Duration( *this ) /= value; }
+
+ /**
+ Computes a duration end time by adding the number of seconds or
+ days in the duration to the specified @p start time.
+
+ @param start is the start time.
+ @return end time.
+ */
+ KDateTime end( const KDateTime &start ) const;
+
+ /**
+ Returns the time units (seconds or days) used to specify the duration.
+ */
+ Type type() const;
+
+ /**
+ Returns whether the duration is specified in terms of days rather
+ than seconds.
+ */
+ bool isDaily() const;
+
+ /**
+ Returns the length of the duration in seconds.
+ */
+ int asSeconds() const;
+
+ /**
+ Returns the length of the duration in days. If the duration is
+ not an exact number of days, it is rounded down to return the
+ number of whole days.
+ */
+ int asDays() const;
+
+ /**
+ Returns the length of the duration in seconds or days.
+
+ @return if isDaily(), duration in days, else duration in seconds
+ */
+ int value() const;
+
+ private:
+ //@cond PRIVATE
+ class Private;
+ Private *const d;
+ //@endcond
+};
+
+}
+
+#endif
diff --git a/kcalcore/event.cpp b/kcalcore/event.cpp
new file mode 100644
index 0000000..f0900f6
--- /dev/null
+++ b/kcalcore/event.cpp
@@ -0,0 +1,335 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Event class.
+
+ @brief
+ This class provides an Event in the sense of RFC2445.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#include "event.h"
+#include "visitor.h"
+
+#include <KDebug>
+
+using namespace KCalCore;
+
+/**
+ Private class that helps to provide binary compatibility between releases.
+ @internal
+*/
+//@cond PRIVATE
+class KCalCore::Event::Private
+{
+ public:
+ Private()
+ : mHasEndDate( false ),
+ mTransparency( Opaque ),
+ mMultiDayValid( false ),
+ mMultiDay( false )
+ {}
+ Private( const KCalCore::Event::Private &other )
+ : mDtEnd( other.mDtEnd ),
+ mHasEndDate( other.mHasEndDate ),
+ mTransparency( other.mTransparency ),
+ mMultiDayValid( false ),
+ mMultiDay( false )
+ {}
+
+ KDateTime mDtEnd;
+ bool mHasEndDate;
+ Transparency mTransparency;
+ bool mMultiDayValid;
+ bool mMultiDay;
+};
+//@endcond
+
+Event::Event()
+ : d( new KCalCore::Event::Private )
+{
+}
+
+Event::Event( const Event &other )
+ : Incidence( other ), d( new KCalCore::Event::Private( *other.d ) )
+{
+}
+
+Event::~Event()
+{
+ delete d;
+}
+
+Event *Event::clone() const
+{
+ return new Event( *this );
+}
+
+IncidenceBase &Event::assign( const IncidenceBase &other )
+{
+ if ( &other != this ) {
+ Incidence::assign( other );
+ const Event *e = static_cast<const Event*>( &other );
+ *d = *( e->d );
+ }
+ return *this;
+}
+
+bool Event::equals( const IncidenceBase &event ) const
+{
+ if ( !Incidence::equals( event ) ) {
+ return false;
+ } else {
+ // If they weren't the same type IncidenceBase::equals would had returned false already
+ const Event *e = static_cast<const Event*>( &event );
+ return
+ ( ( dtEnd() == e->dtEnd() ) ||
+ ( !dtEnd().isValid() && !e->dtEnd().isValid() ) ) &&
+ hasEndDate() == e->hasEndDate() &&
+ transparency() == e->transparency();
+ }
+}
+
+Incidence::IncidenceType Event::type() const
+{
+ return TypeEvent;
+}
+
+QByteArray Event::typeStr() const
+{
+ return "Event";
+}
+
+void Event::setDtStart( const KDateTime &dt )
+{
+ d->mMultiDayValid = false;
+ Incidence::setDtStart( dt );
+}
+
+void Event::setDtEnd( const KDateTime &dtEnd )
+{
+ if ( mReadOnly ) {
+ return;
+ }
+
+ update();
+
+ d->mDtEnd = dtEnd;
+ d->mMultiDayValid = false;
+ setHasEndDate( true );
+ setHasDuration( false );
+ setFieldDirty( FieldDtEnd );
+ updated();
+}
+
+KDateTime Event::dtEnd() const
+{
+ if ( hasEndDate() ) {
+ return d->mDtEnd;
+ }
+
+ if ( hasDuration() ) {
+ if ( allDay() ) {
+ // For all day events, dtEnd is always inclusive
+ KDateTime end = duration().end( dtStart() ).addDays( -1 );
+ return end >= dtStart() ? end : dtStart();
+ } else {
+ return duration().end( dtStart() );
+ }
+ }
+
+ // It is valid for a VEVENT to be without a DTEND. See RFC2445, Sect4.6.1.
+ // Be careful to use Event::dateEnd() as appropriate due to this possibility.
+ return dtStart();
+}
+
+QDate Event::dateEnd() const
+{
+ KDateTime end = dtEnd().toTimeSpec( dtStart() );
+ if ( allDay() ) {
+ return end.date();
+ } else {
+ return end.addSecs(-1).date();
+ }
+}
+
+void Event::setHasEndDate( bool b )
+{
+ d->mHasEndDate = b;
+ setFieldDirty( FieldDtEnd );
+}
+
+bool Event::hasEndDate() const
+{
+ return d->mHasEndDate;
+}
+
+bool Event::isMultiDay( const KDateTime::Spec &spec ) const
+{
+ // First off, if spec's not valid, we can check for cache
+ if ( ( !spec.isValid() ) && d->mMultiDayValid ) {
+ return d->mMultiDay;
+ }
+
+ // Not in cache -> do it the hard way
+ KDateTime start, end;
+
+ if ( !spec.isValid() ) {
+ start = dtStart();
+ end = dtEnd();
+ } else {
+ start = dtStart().toTimeSpec( spec );
+ end = dtEnd().toTimeSpec( spec );
+ }
+
+ // End date is non inclusive, so subtract 1 second... except if we
+ // got the event from some braindead implementation which gave us
+ // start == end one (those do happen)
+ if ( start != end ) {
+ end = end.addSecs( -1 );
+ }
+
+ const bool multi = ( start.date() != end.date() && start <= end );
+
+ // Update the cache
+ if ( spec.isValid() ) {
+ d->mMultiDayValid = true;
+ d->mMultiDay = multi;
+ }
+ return multi;
+}
+
+void Event::shiftTimes( const KDateTime::Spec &oldSpec,
+ const KDateTime::Spec &newSpec )
+{
+ Incidence::shiftTimes( oldSpec, newSpec );
+ if ( hasEndDate() ) {
+ d->mDtEnd = d->mDtEnd.toTimeSpec( oldSpec );
+ d->mDtEnd.setTimeSpec( newSpec );
+ }
+}
+
+void Event::setTransparency( Event::Transparency transparency )
+{
+ if ( mReadOnly ) {
+ return;
+ }
+ update();
+ d->mTransparency = transparency;
+ setFieldDirty( FieldTransparency );
+ updated();
+}
+
+Event::Transparency Event::transparency() const
+{
+ return d->mTransparency;
+}
+
+void Event::setDuration( const Duration &duration )
+{
+ setHasEndDate( false );
+ Incidence::setDuration( duration );
+}
+
+void Event::setAllDay( bool allday )
+{
+ if ( allday != allDay() && !mReadOnly ) {
+ setFieldDirty( FieldDtEnd );
+ Incidence::setAllDay( allday );
+ }
+}
+
+bool Event::accept( Visitor &v, IncidenceBase::Ptr incidence )
+{
+ return v.visit( incidence.staticCast<Event>() );
+}
+
+KDateTime Event::dateTime( DateTimeRole role ) const
+{
+ switch ( role ) {
+ case RoleRecurrenceStart:
+ case RoleAlarmStartOffset:
+ case RoleStartTimeZone:
+ case RoleSort:
+ return dtStart();
+ case RoleCalendarHashing:
+ return !recurs() && !isMultiDay() ? dtStart() :
+ KDateTime();
+ case RoleAlarmEndOffset:
+ case RoleEndTimeZone:
+ case RoleEndRecurrenceBase:
+ case RoleEnd:
+ case RoleDisplayEnd:
+ return dtEnd();
+ case RoleDisplayStart:
+ return dtStart();
+ case RoleAlarm:
+ if ( alarms().isEmpty() ) {
+ return KDateTime();
+ } else {
+ Alarm::Ptr alarm = alarms().first();
+ return alarm->hasStartOffset() ? dtStart() : dtEnd();
+ }
+ break;
+ default:
+ return KDateTime();
+ }
+}
+
+void Event::setDateTime( const KDateTime &dateTime, DateTimeRole role )
+{
+ switch ( role ) {
+ case RoleDnD:
+ {
+ const int duration = dtStart().secsTo( dtEnd() );
+ setDtStart( dateTime );
+ setDtEnd( dateTime.addSecs( duration ) );
+ break;
+ }
+ default:
+ kDebug() << "Unhandled role" << role;
+ }
+}
+
+void Event::virtual_hook( int id, void *data )
+{
+ Q_UNUSED( id );
+ Q_UNUSED( data );
+ Q_ASSERT( false );
+}
+
+QLatin1String KCalCore::Event::mimeType() const
+{
+ return Event::eventMimeType();
+}
+
+QLatin1String Event::eventMimeType()
+{
+ return QLatin1String( "application/x-vnd.akonadi.calendar.event" );
+}
+
+QLatin1String Event::iconName( const KDateTime & ) const
+{
+ return QLatin1String( "view-calendar-day" );
+}
diff --git a/kcalcore/event.h b/kcalcore/event.h
new file mode 100644
index 0000000..3521a38
--- /dev/null
+++ b/kcalcore/event.h
@@ -0,0 +1,263 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001-2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Event class.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+#ifndef KCALCORE_EVENT_H
+#define KCALCORE_EVENT_H
+
+#include "kcalcore_export.h"
+#include "incidence.h"
+#include "supertrait.h"
+
+namespace KCalCore {
+
+/**
+ @brief
+ This class provides an Event in the sense of RFC2445.
+*/
+class KCALCORE_EXPORT Event : public Incidence
+{
+ public:
+ /**
+ The different Event transparency types.
+ */
+ enum Transparency {
+ Opaque, /**< Event appears in free/busy time */
+ Transparent /**< Event does @b not appear in free/busy time */
+ };
+
+ /**
+ A shared pointer to an Event object.
+ */
+ typedef QSharedPointer<Event> Ptr;
+
+ /**
+ List of events.
+ */
+ typedef QVector<Ptr> List;
+
+ /**
+ Constructs an event.
+ */
+ Event();
+
+ /**
+ Copy constructor.
+ @param other is the event to copy.
+ */
+ Event( const Event &other );
+
+ /**
+ Destroys the event.
+ */
+ ~Event();
+
+ /**
+ @copydoc
+ IncidenceBase::type()
+ */
+ IncidenceType type() const;
+
+ /**
+ @copydoc
+ IncidenceBase::typeStr()
+ */
+ QByteArray typeStr() const;
+
+ /**
+ Returns an exact copy of this Event. The caller owns the returned object.
+ */
+ Event *clone() const;
+
+ /**
+ Sets the incidence starting date/time.
+
+ @param dt is the starting date/time.
+ @see IncidenceBase::dtStart().
+ */
+ virtual void setDtStart( const KDateTime &dt );
+
+ /**
+ Sets the event end date and time.
+ Important note for all day events: the end date is inclusive,
+ the event will still occur during dtEnd(). When serializing to iCalendar
+ DTEND will be dtEnd()+1, because the RFC states that DTEND is exclusive.
+ @param dtEnd is a KDateTime specifying when the event ends.
+ @see dtEnd(), dateEnd().
+ */
+ void setDtEnd( const KDateTime &dtEnd );
+
+ /**
+ Returns the event end date and time.
+ Important note for all day events: the returned end date is inclusive,
+ the event will still occur during dtEnd(). When serializing to iCalendar
+ DTEND will be dtEnd()+1, because the RFC states that DTEND is exclusive.
+ @see setDtEnd().
+ */
+ virtual KDateTime dtEnd() const;
+
+ /**
+ Returns the date when the event ends. This might be different from
+ dtEnd().date, since the end date/time is non-inclusive. So timed events
+ ending at 0:00 have their end date on the day before.
+ */
+ QDate dateEnd() const;
+
+ /**
+ Sets whether the event has an end date/time.
+ @param b If set, indicates the event has an end date.
+ */
+ void setHasEndDate( bool b );
+
+ /**
+ Returns whether the event has an end date/time.
+ */
+ bool hasEndDate() const;
+
+ /**
+ Returns true if the event spans multiple days, otherwise return false.
+
+ For recurring events, it returns true if the first occurrence spans multiple days,
+ otherwise returns false. Other occurrences might have a different span due to day light
+ savings changes.
+
+ @param spec If set, looks if the event is multiday for the given spec.
+ If not set, looks if event this multiday for its spec.
+ */
+ bool isMultiDay( const KDateTime::Spec &spec = KDateTime::Spec() ) const;
+
+ /**
+ @copydoc
+ IncidenceBase::shiftTimes()
+ */
+ virtual void shiftTimes( const KDateTime::Spec &oldSpec,
+ const KDateTime::Spec &newSpec );
+
+ /**
+ Sets the event's time transparency level.
+ @param transparency is the event Transparency level.
+ */
+ void setTransparency( Transparency transparency );
+
+ /**
+ Returns the event's time transparency level.
+ */
+ Transparency transparency() const;
+
+ /**
+ Sets the duration of this event.
+ @param duration is the event Duration.
+ */
+ void setDuration( const Duration &duration );
+
+ /**
+ @copydoc
+ IncidenceBase::setAllDay().
+ */
+ void setAllDay( bool allDay );
+
+ /**
+ @copydoc
+ IncidenceBase::dateTime()
+ */
+ KDateTime dateTime( DateTimeRole role ) const;
+
+ /**
+ @copydoc
+ IncidenceBase::setDateTime()
+ */
+ void setDateTime( const KDateTime &dateTime, DateTimeRole role );
+
+ /**
+ @copydoc
+ IncidenceBase::mimeType()
+ */
+ QLatin1String mimeType() const;
+
+ /**
+ @copydoc
+ IncidenceBase::iconName()
+ */
+ QLatin1String iconName( const KDateTime &recurrenceId = KDateTime() ) const;
+
+ /**
+ Returns the Akonadi specific sub MIME type of a KCalCore::Event.
+ */
+ static QLatin1String eventMimeType();
+
+ protected:
+ /**
+ Compares two events for equality.
+ @param event is the event to compare.
+ */
+ virtual bool equals( const IncidenceBase &event ) const;
+
+ /**
+ @copydoc
+ IncidenceBase::assign()
+ */
+ virtual IncidenceBase &assign( const IncidenceBase &other );
+
+ /**
+ @copydoc
+ IncidenceBase::virtual_hook()
+ */
+ virtual void virtual_hook( int id, void *data );
+
+ private:
+ /**
+ @copydoc
+ IncidenceBase::accept()
+ */
+ bool accept( Visitor &v, IncidenceBase::Ptr incidence );
+
+ /**
+ Disabled, otherwise could be dangerous if you subclass Event.
+ Use IncidenceBase::operator= which is safe because it calls
+ virtual function assign().
+ @param other is another Event object to assign to this one.
+ */
+ Event &operator=( const Event &other );
+
+ //@cond PRIVATE
+ class Private;
+ Private *const d;
+ //@endcond
+};
+
+} // namespace KCalCore
+
+Q_DECLARE_TYPEINFO( KCalCore::Event::Ptr, Q_MOVABLE_TYPE );
+
+//@cond PRIVATE
+namespace KPIMUtils
+{
+ // super class trait specialization
+ template <> struct SuperClass<KCalCore::Event> : public SuperClassTrait<KCalCore::Incidence>{};
+}
+//@endcond
+
+#endif
diff --git a/kcalcore/exceptions.cpp b/kcalcore/exceptions.cpp
new file mode 100644
index 0000000..357fbfa
--- /dev/null
+++ b/kcalcore/exceptions.cpp
@@ -0,0 +1,68 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Exception class.
+
+ We don't use actual C++ exceptions right now. These classes are currently
+ returned by an error function; but we can build upon them, if/when we start
+ to use C++ exceptions.
+
+ @brief
+ Exception base class.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#include "exceptions.h"
+#include "calformat.h"
+
+using namespace KCalCore;
+
+Exception::Exception( const ErrorCode code, const QStringList &arguments )
+ : mCode( code ), mArguments( arguments ), d( 0 )
+{
+}
+
+Exception::~Exception()
+{
+}
+
+Exception::ErrorCode Exception::code() const
+{
+ return mCode;
+}
+
+QStringList Exception::arguments() const
+{
+ return mArguments;
+}
+
+/**
+ Private class that helps to provide binary compatibility between releases.
+ @internal
+*/
+//@cond PRIVATE
+class KCalCore::Exception::Private
+{
+};
+//@endcond
diff --git a/kcalcore/exceptions.h b/kcalcore/exceptions.h
new file mode 100644
index 0000000..2275d49
--- /dev/null
+++ b/kcalcore/exceptions.h
@@ -0,0 +1,124 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001-2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Exception class.
+
+ We don't use actual C++ exceptions right now. These classes are currently
+ returned by an error function; but we can build upon them, if/when we start
+ to use C++ exceptions.
+
+ @brief
+ Exception base class.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#ifndef KCALCORE_EXCEPTIONS_H
+#define KCALCORE_EXCEPTIONS_H
+
+#include "kcalcore_export.h"
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+namespace KCalCore {
+
+/**
+ Exception base class, currently used as a fancy kind of error code
+ and not as an C++ exception.
+*/
+class Exception
+{
+ public:
+
+ /**
+ The different types of error codes
+ */
+ //KDAB_TODO: give decent names here
+ enum ErrorCode {
+ LoadError, /**< Load error */
+ SaveError, /**< Save error */
+ ParseErrorIcal, /**< Parse error in libical */
+ ParseErrorKcal, /**< Parse error in libkcal */
+ NoCalendar, /**< No calendar component found */
+ CalVersion1, /**< vCalendar v1.0 detected */
+ CalVersion2, /**< iCalendar v2.0 detected */
+ CalVersionUnknown, /**< Unknown calendar format detected */
+ Restriction, /**< Restriction violation */
+ UserCancel, /**< User canceled the operation */
+ NoWritableFound, /**< No writable resource is available */
+ SaveErrorOpenFile,
+ SaveErrorSaveFile,
+ LibICalError,
+ VersionPropertyMissing,
+ ExpectedCalVersion2,
+ ExpectedCalVersion2Unknown,
+ ParseErrorNotIncidence,
+ ParseErrorEmptyMessage,
+ ParseErrorUnableToParse,
+ ParseErrorMethodProperty
+ };
+
+ /**
+ Construct an exception.
+ @param code is the error code.
+ @param arguments is a list of arguments that can be passed
+ to an i18n engine to help build a descriptive message for the user, a common
+ argument is for example the filename where the error occurred.
+ */
+ explicit Exception( const ErrorCode code,
+ const QStringList &arguments = QStringList() );
+
+ /**
+ Destructor.
+ */
+ virtual ~Exception();
+
+ /**
+ Returns the error code
+ */
+ virtual ErrorCode code() const;
+
+ /**
+ Returns the arguments.
+ */
+ virtual QStringList arguments() const;
+
+ protected:
+ /** The current exception code. */
+ ErrorCode mCode;
+
+ /** Arguments to pass to i18n(). */
+ QStringList mArguments;
+
+ private:
+ //@cond PRIVATE
+ Q_DISABLE_COPY( Exception )
+ class Private;
+ Private *const d;
+ //@endcond
+};
+
+} // namespace
+
+#endif
diff --git a/kcalcore/filestorage.cpp b/kcalcore/filestorage.cpp
new file mode 100644
index 0000000..13b7c6e
--- /dev/null
+++ b/kcalcore/filestorage.cpp
@@ -0,0 +1,176 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the FileStorage class.
+
+ @brief
+ This class provides a calendar storage as a local file.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+#include "filestorage.h"
+#include "exceptions.h"
+#include "icalformat.h"
+#include "memorycalendar.h"
+#include "vcalformat.h"
+
+#include <KDebug>
+
+using namespace KCalCore;
+
+/*
+ Private class that helps to provide binary compatibility between releases.
+*/
+//@cond PRIVATE
+class KCalCore::FileStorage::Private
+{
+ public:
+ Private( const QString &fileName, CalFormat *format )
+ : mFileName( fileName ),
+ mSaveFormat( format )
+ {}
+ ~Private() { delete mSaveFormat; }
+
+ QString mFileName;
+ CalFormat *mSaveFormat;
+};
+//@endcond
+
+FileStorage::FileStorage( const Calendar::Ptr &cal, const QString &fileName,
+ CalFormat *format )
+ : CalStorage( cal ),
+ d( new Private( fileName, format ) )
+{
+}
+
+FileStorage::~FileStorage()
+{
+ delete d;
+}
+
+void FileStorage::setFileName( const QString &fileName )
+{
+ d->mFileName = fileName;
+}
+
+QString FileStorage::fileName() const
+{
+ return d->mFileName;
+}
+
+void FileStorage::setSaveFormat( CalFormat *format )
+{
+ delete d->mSaveFormat;
+ d->mSaveFormat = format;
+}
+
+CalFormat *FileStorage::saveFormat() const
+{
+ return d->mSaveFormat;
+}
+
+bool FileStorage::open()
+{
+ return true;
+}
+
+bool FileStorage::load()
+{
+ // do we want to silently accept this, or make some noise? Dunno...
+ // it is a semantical thing vs. a practical thing.
+ if ( d->mFileName.isEmpty() ) {
+ return false;
+ }
+
+ // Always try to load with iCalendar. It will detect, if it is actually a
+ // vCalendar file.
+ bool success;
+ QString productId;
+ // First try the supplied format. Otherwise fall through to iCalendar, then
+ // to vCalendar
+ success = saveFormat() && saveFormat()->load( calendar(), d->mFileName );
+ if ( success ) {
+ productId = saveFormat()->loadedProductId();
+ } else {
+ ICalFormat iCal;
+
+ success = iCal.load( calendar(), d->mFileName );
+
+ if ( success ) {
+ productId = iCal.loadedProductId();
+ } else {
+ if ( iCal.exception() ) {
+ if ( iCal.exception()->code() == Exception::CalVersion1 ) {
+ // Expected non vCalendar file, but detected vCalendar
+ kDebug() << "Fallback to VCalFormat";
+ VCalFormat vCal;
+ success = vCal.load( calendar(), d->mFileName );
+ productId = vCal.loadedProductId();
+ } else {
+ return false;
+ }
+ } else {
+ kDebug() << "Warning! There should be an exception set.";
+ return false;
+ }
+ }
+ }
+
+ calendar()->setProductId( productId );
+ calendar()->setModified( false );
+
+ return true;
+}
+
+bool FileStorage::save()
+{
+ kDebug();
+ if ( d->mFileName.isEmpty() ) {
+ return false;
+ }
+
+ CalFormat *format = d->mSaveFormat ? d->mSaveFormat : new ICalFormat;
+
+ bool success = format->save( calendar(), d->mFileName );
+
+ if ( success ) {
+ calendar()->setModified( false );
+ } else {
+ if ( !format->exception() ) {
+ kDebug() << "Error. There should be an expection set.";
+ } else {
+ kDebug() << int( format->exception()->code() );
+ }
+ }
+
+ if ( !d->mSaveFormat ) {
+ delete format;
+ }
+
+ return success;
+}
+
+bool FileStorage::close()
+{
+ return true;
+}
diff --git a/kcalcore/filestorage.h b/kcalcore/filestorage.h
new file mode 100644
index 0000000..47c8556
--- /dev/null
+++ b/kcalcore/filestorage.h
@@ -0,0 +1,136 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2002,2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the FileStorage class.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#ifndef KCALCORE_FILESTORAGE_H
+#define KCALCORE_FILESTORAGE_H
+
+#include "kcalcore_export.h"
+#include "calstorage.h"
+
+namespace KCalCore {
+
+class CalFormat;
+class Calendar;
+
+/**
+ @brief
+ This class provides a calendar storage as a local file.
+*/
+class KCALCORE_EXPORT FileStorage : public CalStorage
+{
+ public:
+
+ /**
+ A shared pointer to a FileStorage.
+ */
+ typedef QSharedPointer<FileStorage> Ptr;
+
+ /**
+ Constructs a new FileStorage object for Calendar @p calendar with format
+ @p format, and storage to file @p fileName.
+
+ @param calendar is a pointer to a valid Calendar object.
+ @param fileName is the name of the disk file containing the calendar data.
+ @param format is a pointer to a valid CalFormat object that specifies
+ the calendar format to be used. FileStorage takes ownership; i.e., the
+ memory for @p format is deleted by this destructor. If no format is
+ specified, then iCalendar format is assumed.
+ */
+ explicit FileStorage( const Calendar::Ptr &calendar,
+ const QString &fileName = QString(),
+ KCalCore::CalFormat *format = 0 );
+
+ /**
+ Destructor.
+ */
+ virtual ~FileStorage();
+
+ /**
+ Sets the name of the file that contains the calendar data.
+
+ @param fileName is the name of the disk file containing the calendar data.
+ @see fileName().
+ */
+ void setFileName( const QString &fileName );
+
+ /**
+ Returns a string containing the name of the calendar file.
+ @see setFileName().
+ */
+ QString fileName() const;
+
+ /**
+ Sets the CalFormat object to use for this storage.
+
+ @param format is a pointer to a valid CalFormat object that specifies
+ the calendar format to be used. FileStorage takes ownership.
+ @see saveFormat().
+ */
+ void setSaveFormat( KCalCore::CalFormat *format );
+
+ /**
+ Returns a pointer to the CalFormat object used by this storage.
+ @see setSaveFormat().
+ */
+ CalFormat *saveFormat() const;
+
+ /**
+ @copydoc
+ CalStorage::open()
+ */
+ bool open();
+
+ /**
+ @copydoc
+ CalStorage::load()
+ */
+ bool load();
+
+ /**
+ @copydoc
+ CalStorage::save()
+ */
+ bool save();
+
+ /**
+ @copydoc
+ CalStorage::close()
+ */
+ bool close();
+
+ private:
+ //@cond PRIVATE
+ Q_DISABLE_COPY( FileStorage )
+ class Private;
+ Private *const d;
+ //@endcond
+};
+
+}
+
+#endif
diff --git a/kcalcore/freebusy.cpp b/kcalcore/freebusy.cpp
new file mode 100644
index 0000000..9e37773
--- /dev/null
+++ b/kcalcore/freebusy.cpp
@@ -0,0 +1,428 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the FreeBusy class.
+
+ @brief
+ Provides information about the free/busy time of a calendar user.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+ @author Reinhold Kainhofer \<reinhold@kainhofer.com\>
+*/
+#include "freebusy.h"
+#include "visitor.h"
+
+#include "icalformat.h"
+
+#include <KDebug>
+
+using namespace KCalCore;
+
+//@cond PRIVATE
+class KCalCore::FreeBusy::Private
+{
+ private:
+ FreeBusy *q;
+ public:
+ Private( FreeBusy *qq ) : q( qq )
+ {}
+
+ Private( const KCalCore::FreeBusy::Private &other, FreeBusy *qq ) : q( qq )
+ {
+ init( other );
+ }
+
+ Private( const FreeBusyPeriod::List &busyPeriods, FreeBusy *qq )
+ : q( qq ), mBusyPeriods( busyPeriods )
+ {}
+
+ void init( const KCalCore::FreeBusy::Private &other );
+ void init( const Event::List &events, const KDateTime &start, const KDateTime &end );
+
+ KDateTime mDtEnd; // end datetime
+ FreeBusyPeriod::List mBusyPeriods; // list of periods
+
+ // This is used for creating a freebusy object for the current user
+ bool addLocalPeriod( FreeBusy *fb, const KDateTime &start, const KDateTime &end );
+};
+
+void KCalCore::FreeBusy::Private::init( const KCalCore::FreeBusy::Private &other )
+{
+ mDtEnd = other.mDtEnd;
+ mBusyPeriods = other.mBusyPeriods;
+}
+//@endcond
+
+FreeBusy::FreeBusy()
+ : d( new KCalCore::FreeBusy::Private( this ) )
+{
+}
+
+FreeBusy::FreeBusy( const FreeBusy &other )
+ : IncidenceBase( other ),
+ d( new KCalCore::FreeBusy::Private( *other.d, this ) )
+{
+}
+
+FreeBusy::FreeBusy( const KDateTime &start, const KDateTime &end )
+ : d( new KCalCore::FreeBusy::Private( this ) )
+{
+ setDtStart( start );
+ setDtEnd( end );
+}
+
+FreeBusy::FreeBusy( const Event::List &events, const KDateTime &start, const KDateTime &end )
+ : d( new KCalCore::FreeBusy::Private( this ) )
+{
+ setDtStart( start );
+ setDtEnd( end );
+
+ d->init( events, start, end );
+}
+
+//@cond PRIVATE
+void FreeBusy::Private::init( const Event::List &eventList,
+ const KDateTime &start, const KDateTime &end )
+{
+ int extraDays, i, x, duration;
+ duration = start.daysTo( end );
+ QDate day;
+ KDateTime tmpStart;
+ KDateTime tmpEnd;
+
+ // Loops through every event in the calendar
+ Event::List::ConstIterator it;
+ for ( it = eventList.constBegin(); it != eventList.constEnd(); ++it ) {
+ Event::Ptr event = *it;
+
+ // If this event is transparent it shouldn't be in the freebusy list.
+ if ( event->transparency() == Event::Transparent ) {
+ continue;
+ }
+
+ // The code below can not handle all-day events. Fixing this resulted
+ // in a lot of duplicated code. Instead, make a copy of the event and
+ // set the period to the full day(s). This trick works for recurring,
+ // multiday, and single day all-day events.
+ Event::Ptr allDayEvent;
+ if ( event->allDay() ) {
+ // addDay event. Do the hack
+ kDebug() << "All-day event";
+ allDayEvent = Event::Ptr( new Event( *event ) );
+
+ // Set the start and end times to be on midnight
+ KDateTime st = allDayEvent->dtStart();
+ st.setTime( QTime( 0, 0 ) );
+ KDateTime nd = allDayEvent->dtEnd();
+ nd.setTime( QTime( 23, 59, 59, 999 ) );
+ allDayEvent->setAllDay( false );
+ allDayEvent->setDtStart( st );
+ allDayEvent->setDtEnd( nd );
+
+ kDebug() << "Use:" << st.toString() << "to" << nd.toString();
+ // Finally, use this event for the setting below
+ event = allDayEvent;
+ }
+
+ // This whole for loop is for recurring events, it loops through
+ // each of the days of the freebusy request
+
+ for ( i = 0; i <= duration; ++i ) {
+ day = start.addDays(i).date();
+ tmpStart.setDate( day );
+ tmpEnd.setDate( day );
+
+ if ( event->recurs() ) {
+ if ( event->isMultiDay() ) {
+ // FIXME: This doesn't work for sub-daily recurrences or recurrences with
+ // a different time than the original event.
+ extraDays = event->dtStart().daysTo( event->dtEnd() );
+ for ( x = 0; x <= extraDays; ++x ) {
+ if ( event->recursOn( day.addDays(-x), start.timeSpec() ) ) {
+ tmpStart.setDate( day.addDays(-x) );
+ tmpStart.setTime( event->dtStart().time() );
+ tmpEnd = event->duration().end( tmpStart );
+
+ addLocalPeriod( q, tmpStart, tmpEnd );
+ break;
+ }
+ }
+ } else {
+ if ( event->recursOn( day, start.timeSpec() ) ) {
+ tmpStart.setTime( event->dtStart().time() );
+ tmpEnd.setTime( event->dtEnd().time() );
+
+ addLocalPeriod ( q, tmpStart, tmpEnd );
+ }
+ }
+ }
+
+ }
+ // Non-recurring events
+ addLocalPeriod( q, event->dtStart(), event->dtEnd() );
+ }
+
+ q->sortList();
+}
+//@endcond
+
+FreeBusy::FreeBusy( const Period::List &busyPeriods )
+ : d( new KCalCore::FreeBusy::Private( this ) )
+{
+ addPeriods(busyPeriods);
+}
+
+FreeBusy::FreeBusy( const FreeBusyPeriod::List &busyPeriods )
+ : d( new KCalCore::FreeBusy::Private( busyPeriods, this ) )
+{
+}
+
+FreeBusy::~FreeBusy()
+{
+ delete d;
+}
+
+IncidenceBase::IncidenceType FreeBusy::type() const
+{
+ return TypeFreeBusy;
+}
+
+QByteArray FreeBusy::typeStr() const
+{
+ return "FreeBusy";
+}
+
+void FreeBusy::setDtStart( const KDateTime &start )
+{
+ IncidenceBase::setDtStart( start.toUtc() );
+ updated();
+}
+
+void FreeBusy::setDtEnd( const KDateTime &end )
+{
+ d->mDtEnd = end;
+}
+
+KDateTime FreeBusy::dtEnd() const
+{
+ return d->mDtEnd;
+}
+
+Period::List FreeBusy::busyPeriods() const
+{
+ Period::List res;
+
+ foreach ( const FreeBusyPeriod &p, d->mBusyPeriods ) {
+ res << p;
+ }
+
+ return res;
+}
+
+FreeBusyPeriod::List FreeBusy::fullBusyPeriods() const
+{
+ return d->mBusyPeriods;
+}
+
+void FreeBusy::sortList()
+{
+ qSort( d->mBusyPeriods );
+ return;
+}
+
+void FreeBusy::addPeriods( const Period::List &list )
+{
+ foreach ( const Period &p, list ) {
+ d->mBusyPeriods << FreeBusyPeriod( p );
+ }
+ sortList();
+}
+
+void FreeBusy::addPeriods( const FreeBusyPeriod::List &list )
+{
+ d->mBusyPeriods += list;
+ sortList();
+}
+
+void FreeBusy::addPeriod( const KDateTime &start, const KDateTime &end )
+{
+ d->mBusyPeriods.append( FreeBusyPeriod( start, end ) );
+ sortList();
+}
+
+void FreeBusy::addPeriod( const KDateTime &start, const Duration &duration )
+{
+ d->mBusyPeriods.append( FreeBusyPeriod( start, duration ) );
+ sortList();
+}
+
+void FreeBusy::merge( FreeBusy::Ptr freeBusy )
+{
+ if ( freeBusy->dtStart() < dtStart() ) {
+ setDtStart( freeBusy->dtStart() );
+ }
+
+ if ( freeBusy->dtEnd() > dtEnd() ) {
+ setDtEnd( freeBusy->dtEnd() );
+ }
+
+ Period::List periods = freeBusy->busyPeriods();
+ Period::List::ConstIterator it;
+ for ( it = periods.constBegin(); it != periods.constEnd(); ++it ) {
+ d->mBusyPeriods.append( FreeBusyPeriod( (*it).start(), (*it).end() ) );
+ }
+ sortList();
+}
+
+void FreeBusy::shiftTimes( const KDateTime::Spec &oldSpec,
+ const KDateTime::Spec &newSpec )
+{
+ if ( oldSpec.isValid() && newSpec.isValid() && oldSpec != newSpec ) {
+ IncidenceBase::shiftTimes( oldSpec, newSpec );
+ d->mDtEnd = d->mDtEnd.toTimeSpec( oldSpec );
+ d->mDtEnd.setTimeSpec( newSpec );
+ foreach ( FreeBusyPeriod p, d->mBusyPeriods ) { //krazy:exclude=foreach
+ p.shiftTimes( oldSpec, newSpec );
+ }
+ }
+}
+
+IncidenceBase &FreeBusy::assign( const IncidenceBase &other )
+{
+ if ( &other != this ) {
+ IncidenceBase::assign( other );
+ const FreeBusy *f = static_cast<const FreeBusy*>( &other );
+ d->init( *( f->d ) );
+ }
+ return *this;
+}
+
+bool FreeBusy::equals( const IncidenceBase &freeBusy ) const
+{
+ if ( !IncidenceBase::equals( freeBusy ) ) {
+ return false;
+ } else {
+ // If they weren't the same type IncidenceBase::equals would had returned false already
+ const FreeBusy *fb = static_cast<const FreeBusy*>( &freeBusy );
+ return
+ dtEnd() == fb->dtEnd() &&
+ d->mBusyPeriods == fb->d->mBusyPeriods;
+ }
+}
+
+bool FreeBusy::accept( Visitor &v, IncidenceBase::Ptr incidence )
+{
+ return v.visit( incidence.staticCast<FreeBusy>() );
+}
+
+KDateTime FreeBusy::dateTime( DateTimeRole role ) const
+{
+ Q_UNUSED( role );
+ // No roles affecting freeBusy yet
+ return KDateTime();
+}
+
+void FreeBusy::setDateTime( const KDateTime &dateTime, DateTimeRole role )
+{
+ Q_UNUSED( dateTime );
+ Q_UNUSED( role );
+}
+
+void FreeBusy::virtual_hook( int id, void *data )
+{
+ Q_UNUSED( id );
+ Q_UNUSED( data );
+ Q_ASSERT( false );
+}
+
+//@cond PRIVATE
+bool FreeBusy::Private::addLocalPeriod( FreeBusy *fb,
+ const KDateTime &eventStart,
+ const KDateTime &eventEnd )
+{
+ KDateTime tmpStart;
+ KDateTime tmpEnd;
+
+ //Check to see if the start *or* end of the event is
+ //between the start and end of the freebusy dates.
+ KDateTime start = fb->dtStart();
+ if ( !( ( ( start.secsTo( eventStart ) >= 0 ) &&
+ ( eventStart.secsTo( mDtEnd ) >= 0 ) ) ||
+ ( ( start.secsTo( eventEnd ) >= 0 ) &&
+ ( eventEnd.secsTo( mDtEnd ) >= 0 ) ) ) ) {
+ return false;
+ }
+
+ if ( eventStart.secsTo( start ) >= 0 ) {
+ tmpStart = start;
+ } else {
+ tmpStart = eventStart;
+ }
+
+ if ( eventEnd.secsTo( mDtEnd ) <= 0 ) {
+ tmpEnd = mDtEnd;
+ } else {
+ tmpEnd = eventEnd;
+ }
+
+ FreeBusyPeriod p( tmpStart, tmpEnd );
+ mBusyPeriods.append( p );
+
+ return true;
+}
+//@endcond
+
+QLatin1String FreeBusy::mimeType() const
+{
+ return FreeBusy::freeBusyMimeType();
+}
+
+QLatin1String KCalCore::FreeBusy::freeBusyMimeType()
+{
+ return QLatin1String( "application/x-vnd.akonadi.calendar.freebusy" );
+}
+
+QDataStream &KCalCore::operator<<( QDataStream &stream, const KCalCore::FreeBusy::Ptr &freebusy )
+{
+ KCalCore::ICalFormat format;
+ QString data = format.createScheduleMessage( freebusy, iTIPPublish );
+ return stream << data;
+}
+
+QDataStream &KCalCore::operator>>( QDataStream &stream, KCalCore::FreeBusy::Ptr &freebusy )
+{
+ QString freeBusyVCal;
+ stream >> freeBusyVCal;
+
+ KCalCore::ICalFormat format;
+ freebusy = format.parseFreeBusy( freeBusyVCal );
+
+ if ( !freebusy ) {
+ kDebug() << "Error parsing free/busy";
+ kDebug() << freeBusyVCal;
+ }
+
+ return stream;
+}
+
diff --git a/kcalcore/freebusy.h b/kcalcore/freebusy.h
new file mode 100644
index 0000000..83f397b
--- /dev/null
+++ b/kcalcore/freebusy.h
@@ -0,0 +1,296 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001-2003 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the FreeBusy class.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+ @author Reinhold Kainhofer \<reinhold@kainhofer.com\>
+*/
+
+#ifndef KCALCORE_FREEBUSY_H
+#define KCALCORE_FREEBUSY_H
+
+#include "kcalcore_export.h"
+#include "event.h"
+#include "freebusyperiod.h"
+#include "incidencebase.h"
+#include "period.h"
+
+#include <QtCore/QMetaType>
+
+namespace KCalCore {
+
+class FreeBusy;
+
+/**
+ @brief
+ Provides information about the free/busy time of a calendar.
+
+ A free/busy is a collection of Periods (@see Period).
+*/
+class KCALCORE_EXPORT FreeBusy : public IncidenceBase
+{
+ friend KCALCORE_EXPORT QDataStream &operator<<( QDataStream &s,
+ const KCalCore::FreeBusy::Ptr &freebusy );
+ friend KCALCORE_EXPORT QDataStream &operator>>( QDataStream &s,
+ KCalCore::FreeBusy::Ptr &freebusy );
+
+ public:
+
+ /**
+ A shared pointer to a FreeBusy object.
+ */
+ typedef QSharedPointer<FreeBusy> Ptr;
+
+ /**
+ List of FreeBusy objects.
+ */
+ typedef QVector<Ptr> List;
+
+ /**
+ Constructs an free/busy without any periods.
+ */
+ FreeBusy();
+
+ /**
+ Copy constructor.
+ @param other is the free/busy to copy.
+ */
+ FreeBusy( const FreeBusy &other );
+
+ /**
+ Constructs a free/busy from a list of periods.
+ @param busyPeriods is a list of periods.
+ */
+ explicit FreeBusy( const Period::List &busyPeriods );
+
+ /**
+ Constructs a free/busy from a list of periods.
+ @param busyPeriods is a list of periods.
+ */
+ explicit FreeBusy( const FreeBusyPeriod::List &busyPeriods );
+
+ /**
+ Constructs a free/busy from a single period.
+
+ @param start is the start datetime of the period.
+ @param end is the end datetime of the period.
+ */
+ FreeBusy( const KDateTime &start, const KDateTime &end );
+
+ /**
+ Constructs a freebusy for a specified list of events given a single period.
+
+ @param events list of events.
+ @param start is the start datetime of the period.
+ @param end is the end datetime of the period.
+ */
+ FreeBusy( const Event::List &events, const KDateTime &start, const KDateTime &end );
+
+ /**
+ Destroys a free/busy.
+ */
+ ~FreeBusy();
+
+ /**
+ @copydoc
+ IncidenceBase::type()
+ */
+ IncidenceType type() const;
+
+ /**
+ @copydoc
+ IncidenceBase::typeStr()
+ */
+ QByteArray typeStr() const;
+
+ /**
+ Sets the start datetime for the free/busy. Note that this datetime
+ may be later or earlier than all periods within the free/busy.
+
+ @param start is a KDateTime specifying an start datetime.
+ @see IncidenceBase::dtStart(), setDtEnd().
+ */
+ virtual void setDtStart( const KDateTime &start );
+
+ /**
+ Sets the end datetime for the free/busy. Note that this datetime
+ may be later or earlier than all periods within the free/busy.
+
+ @param end is a KDateTime specifying an end datetime.
+ @see dtEnd(), setDtStart().
+ */
+ void setDtEnd( const KDateTime &end );
+
+ /**
+ Returns the end datetime for the free/busy.
+ FIXME: calling addPeriod() does not change mDtEnd. Is that incorrect?
+ @see setDtEnd().
+ */
+ virtual KDateTime dtEnd() const;
+
+ /**
+ @copydoc
+ IncidenceBase::shiftTimes()
+ */
+ virtual void shiftTimes( const KDateTime::Spec &oldSpec,
+ const KDateTime::Spec &newSpec );
+
+ /**
+ Returns the list of all periods within the free/busy.
+ */
+ Period::List busyPeriods() const;
+
+ /**
+ Returns the list of all periods within the free/busy.
+ */
+ FreeBusyPeriod::List fullBusyPeriods() const;
+
+ /**
+ Adds a period to the freebusy list and sorts the list.
+
+ @param start is the start datetime of the period.
+ @param end is the end datetime of the period.
+ */
+ void addPeriod( const KDateTime &start, const KDateTime &end );
+
+ /**
+ Adds a period to the freebusy list and sorts the list.
+
+ @param start is the start datetime of the period.
+ @param duration is the Duration of the period.
+ */
+ void addPeriod( const KDateTime &start, const Duration &duration );
+
+ /**
+ Adds a list of periods to the freebusy object and then sorts that list.
+ Use this if you are adding many items, instead of the addPeriod method,
+ to avoid sorting repeatedly.
+
+ @param list is a list of Period objects.
+ */
+ void addPeriods( const Period::List &list );
+
+ /**
+ Adds a list of periods to the freebusy object and then sorts that list.
+ Use this if you are adding many items, instead of the addPeriod method,
+ to avoid sorting repeatedly.
+
+ @param list is a list of FreeBusyPeriod objects.
+ */
+ void addPeriods( const FreeBusyPeriod::List &list );
+
+ /**
+ Sorts the list of free/busy periods into ascending order.
+ */
+ void sortList();
+
+ /**
+ Merges another free/busy into this free/busy.
+
+ @param freebusy is a pointer to a valid FreeBusy object.
+ */
+ void merge( FreeBusy::Ptr freebusy );
+
+ /**
+ @copydoc
+ IncidenceBase::dateTime()
+ */
+ KDateTime dateTime( DateTimeRole role ) const;
+
+ /**
+ @copydoc
+ IncidenceBase::setDateTime()
+ */
+ void setDateTime( const KDateTime &dateTime, DateTimeRole role );
+
+ /**
+ @copydoc
+ IncidenceBase::mimeType()
+ */
+ QLatin1String mimeType() const;
+
+ /**
+ Returns the Akonadi specific sub MIME type of a KCalCore::FreeBusy.
+ */
+ static QLatin1String freeBusyMimeType();
+
+ protected:
+ /**
+ Compare this with @p freebusy for equality.
+ @param freebusy is the FreeBusy to compare.
+ */
+ virtual bool equals( const IncidenceBase &freebusy ) const;
+
+ /**
+ @copydoc
+ IncidenceBase::assign()
+ */
+ virtual IncidenceBase &assign( const IncidenceBase &other );
+
+ /**
+ @copydoc
+ IncidenceBase::virtual_hook()
+ */
+ virtual void virtual_hook( int id, void *data );
+
+ private:
+ /**
+ @copydoc
+ IncidenceBase::accept()
+ */
+ bool accept( Visitor &v, IncidenceBase::Ptr incidence );
+
+ /**
+ Disabled, otherwise could be dangerous if you subclass FreeBusy.
+ Use IncidenceBase::operator= which is safe because it calls
+ virtual function assign().
+ @param other is another FreeBusy object to assign to this one.
+ */
+ FreeBusy &operator=( const FreeBusy &other );
+
+ //@cond PRIVATE
+ class Private;
+ Private *const d;
+ //@endcond
+};
+
+/**
+ Serializes the @p fb object into the @p stream.
+*/
+KCALCORE_EXPORT QDataStream &operator<<( QDataStream &stream,
+ const KCalCore::FreeBusy::Ptr &freebusy );
+/**
+ Initializes the @p fb object from the @p stream.
+*/
+KCALCORE_EXPORT QDataStream &operator>>( QDataStream &stream,
+ KCalCore::FreeBusy::Ptr &freebusy );
+}
+
+//@cond PRIVATE
+Q_DECLARE_TYPEINFO( KCalCore::FreeBusy::Ptr, Q_MOVABLE_TYPE );
+Q_DECLARE_METATYPE( KCalCore::FreeBusy::Ptr )
+//@endcond
+
+#endif
diff --git a/kcalcore/freebusycache.cpp b/kcalcore/freebusycache.cpp
new file mode 100644
index 0000000..08a66a0
--- /dev/null
+++ b/kcalcore/freebusycache.cpp
@@ -0,0 +1,42 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the FreeBusyCache abstract base class.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#include "freebusycache.h"
+
+using namespace KCalCore;
+
+FreeBusyCache::~FreeBusyCache()
+{
+}
+
+void FreeBusyCache::virtual_hook( int id, void *data )
+{
+ Q_UNUSED( id );
+ Q_UNUSED( data );
+ Q_ASSERT( false );
+}
diff --git a/kcalcore/freebusycache.h b/kcalcore/freebusycache.h
new file mode 100644
index 0000000..51712a9
--- /dev/null
+++ b/kcalcore/freebusycache.h
@@ -0,0 +1,81 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the FreeBusyCache abstract base class.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#ifndef KCALCORE_FREEBUSYCACHE_H
+#define KCALCORE_FREEBUSYCACHE_H
+
+#include "kcalcore_export.h"
+
+#include "freebusy.h"
+
+class QString;
+
+namespace KCalCore {
+
+class Person;
+
+/**
+ @brief
+ An abstract base class to allow different implementations of storing
+ free busy information, e.g. local storage or storage on a Kolab server.
+*/
+class KCALCORE_EXPORT FreeBusyCache
+{
+ public:
+ /**
+ Destructor.
+ */
+ virtual ~FreeBusyCache();
+
+ /**
+ Save freebusy information belonging to an email.
+
+ @param freebusy is a pointer to a valid FreeBusy instance.
+ @param person is a valid Person instance.
+ */
+ virtual bool saveFreeBusy( const FreeBusy::Ptr &freebusy, const Person::Ptr &person ) = 0;
+
+ /**
+ Load freebusy information belonging to an email.
+
+ @param email is a QString containing a email string in the
+ "FirstName LastName <emailaddress>" format.
+ */
+ virtual FreeBusy::Ptr loadFreeBusy( const QString &email ) = 0;
+
+ protected:
+ /**
+ @copydoc
+ IncidenceBase::virtual_hook()
+ */
+ virtual void virtual_hook( int id, void *data );
+};
+
+}
+
+#endif
diff --git a/kcalcore/freebusyperiod.cpp b/kcalcore/freebusyperiod.cpp
new file mode 100644
index 0000000..a4cf2f2
--- /dev/null
+++ b/kcalcore/freebusyperiod.cpp
@@ -0,0 +1,129 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (c) 2007 David Jarvie <software@astrojar.org.uk>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the FreeBusyPeriod class.
+
+ @brief
+ Represents a period of time.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#include "freebusyperiod.h"
+
+using namespace KCalCore;
+
+//@cond PRIVATE
+class KCalCore::FreeBusyPeriod::Private
+{
+ public:
+ Private() {}
+
+ QString mSummary;
+ QString mLocation;
+};
+//@endcond
+
+FreeBusyPeriod::FreeBusyPeriod() : Period(), d( new KCalCore::FreeBusyPeriod::Private() )
+{
+}
+
+FreeBusyPeriod::FreeBusyPeriod( const KDateTime &start, const KDateTime &end )
+ : Period( start, end ), d( new KCalCore::FreeBusyPeriod::Private() )
+{
+}
+
+FreeBusyPeriod::FreeBusyPeriod( const KDateTime &start, const Duration &duration )
+ : Period( start, duration ), d( new KCalCore::FreeBusyPeriod::Private() )
+{
+}
+
+FreeBusyPeriod::FreeBusyPeriod( const FreeBusyPeriod &period )
+ : Period( period ), d( new KCalCore::FreeBusyPeriod::Private( *period.d ) )
+{
+}
+
+FreeBusyPeriod::FreeBusyPeriod( const Period &period )
+ : Period( period ), d( new KCalCore::FreeBusyPeriod::Private() )
+{
+}
+
+FreeBusyPeriod::~FreeBusyPeriod()
+{
+ delete d;
+}
+
+FreeBusyPeriod &FreeBusyPeriod::operator=( const FreeBusyPeriod &other )
+{
+ // check for self assignment
+ if ( &other == this ) {
+ return *this;
+ }
+
+ Period::operator=(other);
+ *d = *other.d;
+ return *this;
+}
+
+QString FreeBusyPeriod::summary() const
+{
+ return d->mSummary;
+}
+
+void FreeBusyPeriod::setSummary( const QString &summary )
+{
+ d->mSummary = summary;
+}
+
+QString FreeBusyPeriod::location() const
+{
+ return d->mLocation;
+}
+
+void FreeBusyPeriod::setLocation( const QString &location )
+{
+ d->mLocation = location;
+}
+
+QDataStream &KCalCore::operator<<( QDataStream &stream, const KCalCore::FreeBusyPeriod &period )
+{
+ KCalCore::Period periodParent = static_cast<KCalCore::Period>( period );
+ stream << periodParent;
+ stream << period.summary() << period.location();
+ return stream;
+}
+
+QDataStream &KCalCore::operator>>( QDataStream &stream, FreeBusyPeriod &period )
+{
+ KCalCore::Period periodParent;
+ QString summary, location;
+
+ stream >> periodParent >> summary >> location;
+
+ period = periodParent;
+ period.setLocation( location );
+ period.setSummary( summary );
+ return stream;
+}
+
diff --git a/kcalcore/freebusyperiod.h b/kcalcore/freebusyperiod.h
new file mode 100644
index 0000000..5e8f7f3
--- /dev/null
+++ b/kcalcore/freebusyperiod.h
@@ -0,0 +1,153 @@
+/*
+ This file is part of the kcalcore library.
+
+ Copyright (c) 2001-2003 Cornelius Schumacher <schumacher@kde.org>
+
+ This library 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 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+/**
+ @file
+ This file is part of the API for handling calendar data and
+ defines the Period class.
+
+ @brief
+ Represents a period of time.
+
+ @author Cornelius Schumacher \<schumacher@kde.org\>
+*/
+
+#ifndef KCALCORE_FREEBUSYPERIOD_H
+#define KCALCORE_FREEBUSYPERIOD_H
+
+#include "kcalcore_export.h"
+#include "period.h"
+
+#include <QtCore/QMetaType>
+
+namespace KCalCore {
+
+/**
+ The period can be defined by either a start time and an end time or
+ by a start time and a duration.
+*/
+class KCALCORE_EXPORT FreeBusyPeriod : public Period
+{
+ public:
+ /**
+ List of periods.
+ */
+ typedef QVector<FreeBusyPeriod> List;
+
+ /**
+ Constructs a period without a duration.
+ */
+ FreeBusyPeriod();
+
+ /**
+ Constructs a period from @p start to @p end.
+
+ @param start the time the period begins.
+ @param end the time the period ends.
+ */
+ FreeBusyPeriod( const KDateTime &start, const KDateTime &end );
+
+ /**
+ Constructs a period from @p start and lasting @p duration.
+
+ @param start the time when the period starts.
+ @param duration how long the period lasts.
+ */
+ FreeBusyPeriod( const KDateTime &start, const Duration &duration );
+
+ /**
+ Constructs a period by copying another period object
+
+ @param period the period to copy
+ */
+
+ FreeBusyPeriod( const FreeBusyPeriod &period );
+
+ /**
+ Constructs a period by copying another period object
+
+ @param period the period to copy
+ */
+
+ FreeBusyPeriod( const Period &period );
+
+ /**
+ Destroys a period.
+ */
+ ~FreeBusyPeriod();
+
+ /**
+ Sets this period equal to the @p other one.
+
+ @param other is the other period to compare.
+ */
+ FreeBusyPeriod &operator=( const FreeBusyPeriod &other );
+
+ /**
+ Sets the period summary.
+ @param summary is the period summary string.
+ @see summary().
+ */
+ void setSummary( const QString &summary );
+
+ /**
+ Returns the period summary.
+ @see setSummary()
+ */
+ QString summary() const;
+
+ /**
+ Sets the period location.
+ @param location is the period location string.
+ @see location().
+ */
+ void setLocation( const QString &location );
+
+ /**