Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package kcalendarcore for openSUSE:Factory checked in at 2021-10-18 21:58:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kcalendarcore (Old) and /work/SRC/openSUSE:Factory/.kcalendarcore.new.1890 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kcalendarcore" Mon Oct 18 21:58:26 2021 rev:25 rq:924415 version:5.87.0 Changes: -------- --- /work/SRC/openSUSE:Factory/kcalendarcore/kcalendarcore.changes 2021-09-16 23:14:55.323813874 +0200 +++ /work/SRC/openSUSE:Factory/.kcalendarcore.new.1890/kcalendarcore.changes 2021-10-18 22:00:00.429998733 +0200 @@ -1,0 +2,16 @@ +Sun Oct 3 20:33:35 UTC 2021 - Christophe Giboudeaux <[email protected]> + +- Update to 5.87.0 + * New feature release + * For more details please see: + * https://kde.org/announcements/frameworks/5/5.87.0 +- Changes since 5.86.0: + * Add Gitlab CI configuration + * Set the correct last modified time when creating an exception for a recurring event. + * icalformat_p.cpp - support ATTACH parameter FILENAME (kde#436161) + * Add Qt5Gui as dependency in pkgconfig file. + * autotests/testicaltimezones.cpp - fix unused variable warning + * Read floating date time as LocalTime + * Implement PERIOD support in RDATE + +------------------------------------------------------------------- Old: ---- kcalendarcore-5.86.0.tar.xz kcalendarcore-5.86.0.tar.xz.sig New: ---- kcalendarcore-5.87.0.tar.xz kcalendarcore-5.87.0.tar.xz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kcalendarcore.spec ++++++ --- /var/tmp/diff_new_pack.ZlmnwM/_old 2021-10-18 22:00:00.901999074 +0200 +++ /var/tmp/diff_new_pack.ZlmnwM/_new 2021-10-18 22:00:00.901999074 +0200 @@ -16,14 +16,14 @@ # -%define _tar_path 5.86 +%define _tar_path 5.87 # Full KF5 version (e.g. 5.33.0) %{!?_kf5_version: %global _kf5_version %{version}} # Last major and minor KF5 version (e.g. 5.33) %{!?_kf5_bugfix_version: %define _kf5_bugfix_version %(echo %{_kf5_version} | awk -F. '{print $1"."$2}')} %bcond_without lang Name: kcalendarcore -Version: 5.86.0 +Version: 5.87.0 Release: 0 Summary: Library to access and handle calendar data License: LGPL-2.0-or-later ++++++ kcalendarcore-5.86.0.tar.xz -> kcalendarcore-5.87.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/.gitlab-ci.yml new/kcalendarcore-5.87.0/.gitlab-ci.yml --- old/kcalendarcore-5.86.0/.gitlab-ci.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/kcalendarcore-5.87.0/.gitlab-ci.yml 2021-10-02 14:14:52.000000000 +0200 @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2020 Volker Krause <[email protected]> +# SPDX-License-Identifier: CC0-1.0 + +include: + - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/.kde-ci.yml new/kcalendarcore-5.87.0/.kde-ci.yml --- old/kcalendarcore-5.86.0/.kde-ci.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/kcalendarcore-5.87.0/.kde-ci.yml 2021-10-02 14:14:52.000000000 +0200 @@ -0,0 +1,7 @@ +Dependencies: +- 'on': ['@all'] + 'require': + 'frameworks/extra-cmake-modules': '@same' + +Options: + test-before-installing: True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/CMakeLists.txt new/kcalendarcore-5.87.0/CMakeLists.txt --- old/kcalendarcore-5.86.0/CMakeLists.txt 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/CMakeLists.txt 2021-10-02 14:14:52.000000000 +0200 @@ -1,11 +1,11 @@ cmake_minimum_required(VERSION 3.16) -set(KF_VERSION "5.86.0") # handled by release scripts +set(KF_VERSION "5.87.0") # handled by release scripts project(KCalendarCore VERSION ${KF_VERSION}) # ECM setup include(FeatureSummary) -find_package(ECM 5.86.0 NO_MODULE) +find_package(ECM 5.87.0 NO_MODULE) set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://commits.kde.org/extra-cmake-modules") feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) @@ -120,7 +120,7 @@ if (NOT WIN32) ecm_generate_pkgconfig_file(BASE_NAME KF5CalendarCore INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/KCalendarCore/ - DEPS Qt5Core + DEPS "Qt5Core Qt5Gui" INSTALL) endif() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/autotests/data/Compat/Evolution_2.8.2_timezone_test.ics.ical.ref new/kcalendarcore-5.87.0/autotests/data/Compat/Evolution_2.8.2_timezone_test.ics.ical.ref --- old/kcalendarcore-5.86.0/autotests/data/Compat/Evolution_2.8.2_timezone_test.ics.ical.ref 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/autotests/data/Compat/Evolution_2.8.2_timezone_test.ics.ical.ref 2021-10-02 14:14:52.000000000 +0200 @@ -3,9 +3,6 @@ VERSION:2.0 X-KDE-ICAL-IMPLEMENTATION-VERSION:1.0 X-LibKCal-Testsuite-OutTZ:Europe/London -BEGIN:VTIMEZONE -TZID:GMT -END:VTIMEZONE BEGIN:VEVENT DTSTAMP:20070127T211005Z CREATED:20070127T211013 @@ -13,8 +10,8 @@ SEQUENCE:2 LAST-MODIFIED:20070127T211124 SUMMARY:Nominal is 1200 to 1230 _GMT_ on 27 Jan 2007 -DTSTART;TZID=GMT:20070127T120000 -DTEND;TZID=GMT:20070127T123000 +DTSTART:20070127T120000 +DTEND:20070127T123000 TRANSP:OPAQUE END:VEVENT END:VCALENDAR diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/autotests/data/Compat/Mozilla_1.0.ics.ical.ref new/kcalendarcore-5.87.0/autotests/data/Compat/Mozilla_1.0.ics.ical.ref --- old/kcalendarcore-5.86.0/autotests/data/Compat/Mozilla_1.0.ics.ical.ref 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/autotests/data/Compat/Mozilla_1.0.ics.ical.ref 2021-10-02 14:14:52.000000000 +0200 @@ -2,9 +2,6 @@ PRODID:-//K Desktop Environment//NONSGML libkcal 4.3//EN VERSION:2.0 X-KDE-ICAL-IMPLEMENTATION-VERSION:1.0 -BEGIN:VTIMEZONE -TZID:GMT -END:VTIMEZONE BEGIN:VTODO DTSTAMP:20171006T143852Z CREATED:20171006T143852Z @@ -13,8 +10,8 @@ SUMMARY:Call Beacon to transfer funds STATUS:NEEDS-ACTION CLASS:PRIVATE -DUE;TZID=GMT:20040505T111500 -DTSTART;TZID=GMT:20040505T101500 +DUE:20040505T111500 +DTSTART:20040505T101500 PERCENT-COMPLETE:0 END:VTODO BEGIN:VEVENT @@ -53,8 +50,8 @@ SUMMARY:Dental Exam STATUS:CONFIRMED CLASS:PRIVATE -DTSTART;TZID=GMT:20040510T090000 -DTEND;TZID=GMT:20040510T110000 +DTSTART:20040510T090000 +DTEND:20040510T110000 TRANSP:OPAQUE END:VEVENT BEGIN:VEVENT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/autotests/testicalformat.cpp new/kcalendarcore-5.87.0/autotests/testicalformat.cpp --- old/kcalendarcore-5.86.0/autotests/testicalformat.cpp 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/autotests/testicalformat.cpp 2021-10-02 14:14:52.000000000 +0200 @@ -11,6 +11,7 @@ #include "event.h" #include "icalformat.h" #include "memorycalendar.h" +#include "occurrenceiterator.h" #include <QTest> #include <QTimeZone> @@ -252,3 +253,100 @@ } } } + +void ICalFormatTest::testRDate() +{ + ICalFormat format; + + const QString serializedCalendar = QLatin1String( + "BEGIN:VCALENDAR\n" + "VERSION:2.0\n" + "PRODID:-//Lotus Development Corporation//NONSGML Notes 9.0.1//EN_C\n" + "METHOD:PUBLISH\n" + "BEGIN:VEVENT\n" + "DTSTART:20210630T100000Z\n" + "DTEND:20210630T110000Z\n" + "TRANSP:OPAQUE\n" + "RDATE;VALUE=PERIOD:20210630T100000Z/20210630T110000Z\n" + " ,20210825T100000Z/20210825T110000Z,20211027T100000Z/20211027T110000Z\n" + " ,20211215T110000Z/PT2H\n" + "LAST-MODIFIED:20210601T094627Z\n" + "DTSTAMP:20210601T092939Z\n" + "UID:5FC21473F5CC80CCC12586E70033ED9C-Lotus_Notes_Generated\n" + "END:VEVENT\n" + "END:VCALENDAR\n"); + MemoryCalendar::Ptr calendar(new MemoryCalendar(QTimeZone::utc())); + QVERIFY(format.fromString(calendar, serializedCalendar)); + const QString uid = QString::fromLatin1("5FC21473F5CC80CCC12586E70033ED9C-Lotus_Notes_Generated"); + Incidence::Ptr event = calendar->incidence(uid); + QVERIFY(event); + QVERIFY(event->recurs()); + + const QDateTime ev1(QDate(2021, 6, 30), QTime(10, 0), Qt::UTC); + const QDateTime ev2(QDate(2021, 8, 25), QTime(10, 0), Qt::UTC); + const QDateTime ev3(QDate(2021, 10, 27), QTime(10, 0), Qt::UTC); + const QDateTime ev4(QDate(2021, 12, 15), QTime(11, 0), Qt::UTC); + QCOMPARE(event->recurrence()->rDateTimes(), + QList<QDateTime>() << ev1 << ev2 << ev3 << ev4); + + OccurrenceIterator it(*calendar, QDateTime(QDate(2021, 6, 1), QTime(0, 0)), + QDateTime(QDate(2021, 12, 31), QTime(0, 0))); + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.occurrenceStartDate(), ev1); + QCOMPARE(it.occurrenceEndDate(), ev1.addSecs(3600)); + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.occurrenceStartDate(), ev2); + QCOMPARE(it.occurrenceEndDate(), ev2.addSecs(3600)); + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.occurrenceStartDate(), ev3); + QCOMPARE(it.occurrenceEndDate(), ev3.addSecs(3600)); + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.occurrenceStartDate(), ev4); + QCOMPARE(it.occurrenceEndDate(), ev4.addSecs(7200)); + + const QStringList output = format.toString(calendar, QString()).split(QString::fromLatin1("\r\n")); + QVERIFY(output.contains(QString::fromLatin1("RDATE;VALUE=PERIOD:20210630T100000Z/20210630T110000Z"))); + QVERIFY(output.contains(QString::fromLatin1("RDATE;VALUE=PERIOD:20210825T100000Z/20210825T110000Z"))); + QVERIFY(output.contains(QString::fromLatin1("RDATE;VALUE=PERIOD:20211027T100000Z/20211027T110000Z"))); + QVERIFY(output.contains(QString::fromLatin1("RDATE;VALUE=PERIOD:20211215T110000Z/PT2H"))); +} + +void ICalFormatTest::testDateTime_data() +{ + QTest::addColumn<QByteArray>("dtStartData"); + QTest::addColumn<QDateTime>("dtStart"); + + QTest::newRow("clock time") + << QByteArray("DTSTART:20191113T130000") + << QDateTime(QDate(2019, 11, 13), QTime(13, 00), Qt::LocalTime); + QTest::newRow("date") + << QByteArray("DTSTART;VALUE=DATE:20191113") + << QDate(2019, 11, 13).startOfDay(); + QTest::newRow("UTC time") + << QByteArray("DTSTART:20191113T130000Z") + << QDateTime(QDate(2019, 11, 13), QTime(13, 00), Qt::UTC); + QTest::newRow("time zone time") + << QByteArray("DTSTART;TZID=Europe/Paris:20191113T130000") + << QDateTime(QDate(2019, 11, 13), QTime(13, 00), QTimeZone("Europe/Paris")); +} + +void ICalFormatTest::testDateTime() +{ + QFETCH(QByteArray, dtStartData); + QFETCH(QDateTime, dtStart); + + // test fromString(QString) + const QByteArray serializedCalendar + = "BEGIN:VCALENDAR\nPRODID:-//K Desktop Environment//NONSGML libkcal 3.2//EN\nVERSION:2.0\nBEGIN:VEVENT\nUID:12345\n" + + dtStartData + + "\nEND:VEVENT\nEND:VCALENDAR"; + + ICalFormat format; + Incidence::Ptr event = format.fromString(QString::fromUtf8(serializedCalendar)); + QVERIFY(event); + QCOMPARE(dtStart, event->dtStart()); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/autotests/testicalformat.h new/kcalendarcore-5.87.0/autotests/testicalformat.h --- old/kcalendarcore-5.86.0/autotests/testicalformat.h 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/autotests/testicalformat.h 2021-10-02 14:14:52.000000000 +0200 @@ -23,6 +23,9 @@ void testAlarm(); void testDateTimeSerialization_data(); void testDateTimeSerialization(); + void testRDate(); + void testDateTime_data(); + void testDateTime(); }; #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/autotests/testicaltimezones.cpp new/kcalendarcore-5.87.0/autotests/testicaltimezones.cpp --- old/kcalendarcore-5.86.0/autotests/testicaltimezones.cpp 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/autotests/testicaltimezones.cpp 2021-10-02 14:14:52.000000000 +0200 @@ -132,6 +132,7 @@ // When there's an extra transition from +0000 to +0100 // in 1978 (FreeBSD and old Debian), we get one more // transition and slightly different RRULEs +#ifdef Q_OS_FREEBSD static const char *VTZ_PragueExtra = "BEGIN:VTIMEZONE\r\n" "TZID:Europe/Prague\r\n" @@ -173,6 +174,7 @@ "RDATE:19950924T030000\r\n" "END:STANDARD\r\n" "END:VTIMEZONE\r\n"; +#endif // CALENDAR component header and footer static const char *calendarHeader = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/autotests/testoccurrenceiterator.cpp new/kcalendarcore-5.87.0/autotests/testoccurrenceiterator.cpp --- old/kcalendarcore-5.86.0/autotests/testoccurrenceiterator.cpp 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/autotests/testoccurrenceiterator.cpp 2021-10-02 14:14:52.000000000 +0200 @@ -273,3 +273,51 @@ KCalendarCore::OccurrenceIterator rIt2(calendar, tomorrow, tomorrow.addDays(1)); QVERIFY(!rIt2.hasNext()); } + +void TestOccurrenceIterator::testEndDate() +{ + const QDateTime start(QDate(2021, 8, 30), QTime(10, 0, 0)); + const QDateTime end(QDate(2021, 8, 30), QTime(11, 0, 0)); + + const QDateTime start2(QDate(2021, 8, 30), QTime(15, 0, 0)); + const QDateTime end2(QDate(2021, 8, 30), QTime(18, 0, 0)); + + KCalendarCore::MemoryCalendar calendar(QTimeZone::utc()); + + KCalendarCore::Event::Ptr event(new KCalendarCore::Event); + event->setUid(QStringLiteral("event")); + event->setSummary(QStringLiteral("event")); + event->setDtStart(start); + event->setDtEnd(end); + event->recurrence()->setDaily(1); + event->recurrence()->addRDateTimePeriod(KCalendarCore::Period(start2, end2)); + calendar.addEvent(event); + + KCalendarCore::Journal::Ptr journal(new KCalendarCore::Journal); + journal->setUid(QStringLiteral("journal")); + journal->setDtStart(start); + calendar.addJournal(journal); + + KCalendarCore::OccurrenceIterator rIt(calendar, start, start.addDays(1)); + // The base event. + QVERIFY(rIt.hasNext()); + rIt.next(); + QCOMPARE(rIt.occurrenceStartDate(), start); + QCOMPARE(rIt.occurrenceEndDate(), end); + // The additional occurrence with a longer duration. + QVERIFY(rIt.hasNext()); + rIt.next(); + QCOMPARE(rIt.occurrenceStartDate(), start2); + QCOMPARE(rIt.occurrenceEndDate(), end2); + // The recurring occurrence with the base duration. + QVERIFY(rIt.hasNext()); + rIt.next(); + QCOMPARE(rIt.occurrenceStartDate(), start.addDays(1)); + QCOMPARE(rIt.occurrenceEndDate(), end.addDays(1)); + // The journal. + QVERIFY(rIt.hasNext()); + rIt.next(); + QCOMPARE(rIt.occurrenceStartDate(), start); + QVERIFY(!rIt.occurrenceEndDate().isValid()); + QVERIFY(!rIt.hasNext()); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/autotests/testoccurrenceiterator.h new/kcalendarcore-5.87.0/autotests/testoccurrenceiterator.h --- old/kcalendarcore-5.86.0/autotests/testoccurrenceiterator.h 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/autotests/testoccurrenceiterator.h 2021-10-02 14:14:52.000000000 +0200 @@ -19,6 +19,7 @@ void testWithExceptionThisAndFuture(); void testSubDailyRecurrences(); void testJournals(); + void testEndDate(); }; #endif // TESTOCCURRENCEITERATOR_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/autotests/testrecurrenceexception.cpp new/kcalendarcore-5.87.0/autotests/testrecurrenceexception.cpp --- old/kcalendarcore-5.86.0/autotests/testrecurrenceexception.cpp 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/autotests/testrecurrenceexception.cpp 2021-10-02 14:14:52.000000000 +0200 @@ -22,10 +22,14 @@ todo->setDtDue(dtdue); todo->recurrence()->setDaily(1); todo->recurrence()->setDuration(3); + todo->setCreated(dtstart); + todo->setLastModified(dtstart); const KCalendarCore::Todo::Ptr exception = KCalendarCore::MemoryCalendar::createException(todo, recurrenceId, false).staticCast<KCalendarCore::Todo>(); QCOMPARE(exception->dtStart(), recurrenceId); QCOMPARE(exception->dtDue(), QDateTime(dtdue).addDays(1)); + QVERIFY(exception->created() >= todo->created()); + QVERIFY(exception->lastModified() >= exception->created()); // FIXME should be done on clearing the recurrence, but we can't due to BC. // Probably not that important as long as dtRecurrence is ignored if the todo is not recurring // QCOMPARE(exception->dtRecurrence(), QDateTime()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/autotests/testtimesininterval.cpp new/kcalendarcore-5.87.0/autotests/testtimesininterval.cpp --- old/kcalendarcore-5.86.0/autotests/testtimesininterval.cpp 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/autotests/testtimesininterval.cpp 2021-10-02 14:14:52.000000000 +0200 @@ -276,3 +276,31 @@ QCOMPARE(expectedEventOccurrences.size(), 0); } + +void TimesInIntervalTest::testRDatePeriod() +{ + const QDateTime start(QDate(2021, 8, 30), QTime(11, 14)); + const QDateTime end(QDate(2021, 8, 30), QTime(11, 42)); + const QDateTime other(QDate(2021, 8, 30), QTime(12, 00)); + const QDateTime later(QDate(2021, 8, 30), QTime(15, 00)); + Recurrence recur; + + QVERIFY(!recur.recurs()); + QVERIFY(!recur.rDateTimePeriod(start).isValid()); + + recur.addRDateTimePeriod(Period(start, end)); + QVERIFY(recur.recurs()); + QCOMPARE(recur.rDateTimePeriod(start), Period(start, end)); + + const QList<QDateTime> timesInInterval = recur.timesInInterval(start.addDays(-1), + start.addDays(+1)); + QCOMPARE(timesInInterval, QList<QDateTime>() << start); + + recur.addRDateTime(other); + QCOMPARE(recur.rDateTimes(), QList<QDateTime>() << start << other); + QCOMPARE(recur.rDateTimePeriod(start), Period(start, end)); + + recur.setRDateTimes(QList<QDateTime>() << other << later); + QCOMPARE(recur.rDateTimes(), QList<QDateTime>() << other << later); + QVERIFY(!recur.rDateTimePeriod(start).isValid()); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/autotests/testtimesininterval.h new/kcalendarcore-5.87.0/autotests/testtimesininterval.h --- old/kcalendarcore-5.86.0/autotests/testtimesininterval.h 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/autotests/testtimesininterval.h 2021-10-02 14:14:52.000000000 +0200 @@ -23,6 +23,7 @@ void testLocalTimeHandlingNonAllDay(); void testLocalTimeHandlingAllDay(); void testByDayRecurrence(); + void testRDatePeriod(); }; #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/src/calendar.cpp new/kcalendarcore-5.87.0/src/calendar.cpp --- old/kcalendarcore-5.86.0/src/calendar.cpp 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/src/calendar.cpp 2021-10-02 14:14:52.000000000 +0200 @@ -5,6 +5,7 @@ SPDX-FileCopyrightText: 2000-2004 Cornelius Schumacher <[email protected]> SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <[email protected]> SPDX-FileCopyrightText: 2006 David Jarvie <[email protected]> + SPDX-FileCopyrightText: 2021 Boris Shmarin <[email protected]> SPDX-License-Identifier: LGPL-2.0-or-later */ @@ -583,7 +584,9 @@ } Incidence::Ptr newInc(incidence->clone()); - newInc->setCreated(QDateTime::currentDateTimeUtc()); + const QDateTime current = QDateTime::currentDateTimeUtc(); + newInc->setCreated(current); + newInc->setLastModified(current); newInc->setRevision(0); // Recurring exceptions are not support for now newInc->clearRecurrence(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/src/calfilter.cpp new/kcalendarcore-5.87.0/src/calfilter.cpp --- old/kcalendarcore-5.86.0/src/calfilter.cpp 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/src/calfilter.cpp 2021-10-02 14:14:52.000000000 +0200 @@ -72,14 +72,10 @@ return; } - Event::List::Iterator it = eventList->begin(); - while (it != eventList->end()) { - if (!filterIncidence(*it)) { - it = eventList->erase(it); - } else { - ++it; - } - } + auto it = std::remove_if(eventList->begin(), eventList->end(), [=](const Incidence::Ptr &incidence) { + return !filterIncidence(incidence); + }); + eventList->erase(it, eventList->end()); } // TODO: avoid duplicating apply() code @@ -89,14 +85,10 @@ return; } - Todo::List::Iterator it = todoList->begin(); - while (it != todoList->end()) { - if (!filterIncidence(*it)) { - it = todoList->erase(it); - } else { - ++it; - } - } + auto it = std::remove_if(todoList->begin(), todoList->end(), [=](const Incidence::Ptr &incidence) { + return !filterIncidence(incidence); + }); + todoList->erase(it, todoList->end()); } void CalFilter::apply(Journal::List *journalList) const @@ -105,14 +97,10 @@ return; } - Journal::List::Iterator it = journalList->begin(); - while (it != journalList->end()) { - if (!filterIncidence(*it)) { - it = journalList->erase(it); - } else { - ++it; - } - } + auto it = std::remove_if(journalList->begin(), journalList->end(), [=](const Incidence::Ptr &incidence) { + return !filterIncidence(incidence); + }); + journalList->erase(it, journalList->end()); } bool CalFilter::filterIncidence(const Incidence::Ptr &incidence) const diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/src/icalformat_p.cpp new/kcalendarcore-5.87.0/src/icalformat_p.cpp --- old/kcalendarcore-5.86.0/src/icalformat_p.cpp 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/src/icalformat_p.cpp 2021-10-02 14:14:52.000000000 +0200 @@ -567,7 +567,21 @@ } dateTimeList = incidence->recurrence()->rDateTimes(); for (auto rdtIt = dateTimeList.constBegin(); rdtIt != dateTimeList.constEnd(); ++rdtIt) { - icalcomponent_add_property(parent, writeICalDateTimeProperty(ICAL_RDATE_PROPERTY, *rdtIt, tzUsedList)); + Period period = incidence->recurrence()->rDateTimePeriod(*rdtIt); + if (period.isValid()) { + icaldatetimeperiodtype tp; + tp.time = icaltime_null_time(); + tp.period = icalperiodtype_null_period(); + tp.period.start = writeICalDateTime(period.start()); + if (period.hasDuration()) { + tp.period.duration = writeICalDuration(period.duration()); + } else { + tp.period.end = writeICalDateTime(period.end()); + } + icalcomponent_add_property(parent, icalproperty_new_rdate(tp)); + } else { + icalcomponent_add_property(parent, writeICalDateTimeProperty(ICAL_RDATE_PROPERTY, *rdtIt, tzUsedList)); + } } // attachments @@ -1545,6 +1559,12 @@ attachment.setMimeType(QLatin1String(icalparameter_get_fmttype(p))); } + /* Support FILENAME property (Caldav). see https://datatracker.ietf.org/doc/html/rfc8607 */ + p = icalproperty_get_first_parameter(attach, ICAL_FILENAME_PARAMETER); + if (p) { + attachment.setLabel(QString::fromUtf8(icalparameter_get_xvalue(p))); + } + p = icalproperty_get_first_parameter(attach, ICAL_X_PARAMETER); while (p) { QString xname = QString::fromLatin1(icalparameter_get_xname(p)).toUpper(); @@ -1773,7 +1793,15 @@ incidence->recurrence()->addRDateTime(kdt); } } else { - // TODO: RDates as period are not yet implemented! + icaldatetimeperiodtype tp = icalproperty_get_rdate(p); + const QDateTime start = readICalDateTime(p, tp.period.start, tzlist, false); + if (icaltime_is_null_time(tp.period.end)) { + Period period(start, readICalDuration(tp.period.duration)); + incidence->recurrence()->addRDateTimePeriod(period); + } else { + Period period(start, readICalDateTime(p, tp.period.end, tzlist, false)); + incidence->recurrence()->addRDateTimePeriod(period); + } } break; } @@ -2363,7 +2391,7 @@ } QTimeZone qtz; - if (!icaltime_is_utc(t)) { + if (!icaltime_is_utc(t) && dt.timeSpec() == Qt::TimeZone) { qtz = dt.timeZone(); } @@ -2404,20 +2432,21 @@ // First try to get the timezone from cache timeZone = tzCache->tzForTime(QDateTime({t.year, t.month, t.day}, {}), tzid); } - if (!timeZone.isValid()) { + if (!timeZone.isValid() && !tzid.isEmpty()) { // Fallback to trying to match against Qt timezone timeZone = QTimeZone(tzid); } - if (!timeZone.isValid()) { - // Finally, give up and assume local timezone - timeZone = QTimeZone::systemTimeZone(); - } + // If Time zone is still invalid, we will use LocalTime as TimeSpec. + } + QTime resultTime; + if (!t.is_date) { + resultTime = QTime(t.hour, t.minute, t.second); } QDateTime result; - if (t.is_date) { - result = QDateTime(QDate(t.year, t.month, t.day), {}, timeZone); + if (timeZone.isValid()) { + result = QDateTime(QDate(t.year, t.month, t.day), resultTime, timeZone); } else { - result = QDateTime(QDate(t.year, t.month, t.day), QTime(t.hour, t.minute, t.second), timeZone); + result = QDateTime(QDate(t.year, t.month, t.day), resultTime); } return utc ? result.toUTC() : result; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/src/icaltimezones.cpp new/kcalendarcore-5.87.0/src/icaltimezones.cpp --- old/kcalendarcore-5.86.0/src/icaltimezones.cpp 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/src/icaltimezones.cpp 2021-10-02 14:14:52.000000000 +0200 @@ -118,7 +118,7 @@ const ICalTimeZone tz = mCache.value(tzid); if (!tz.qZone.isValid()) { - return QTimeZone::systemTimeZone(); + return QTimeZone(); } // If the matched timezone is one of the UTC offset timezones, we need to make diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/src/occurrenceiterator.cpp new/kcalendarcore-5.87.0/src/occurrenceiterator.cpp --- old/kcalendarcore-5.86.0/src/occurrenceiterator.cpp 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/src/occurrenceiterator.cpp 2021-10-02 14:14:52.000000000 +0200 @@ -47,16 +47,19 @@ { } - Occurrence(const Incidence::Ptr &i, const QDateTime &recurrenceId, const QDateTime &startDate) + Occurrence(const Incidence::Ptr &i, const QDateTime &recurrenceId, + const QDateTime &startDate, const QDateTime &endDate) : incidence(i) , recurrenceId(recurrenceId) , startDate(startDate) + , endDate(endDate) { } Incidence::Ptr incidence; QDateTime recurrenceId; QDateTime startDate; + QDateTime endDate; }; QList<Occurrence> occurrenceList; QListIterator<Occurrence> occurrenceIt; @@ -85,6 +88,20 @@ return false; } + QDateTime occurrenceEnd(const Incidence::Ptr &inc, const QDateTime &start) + { + if (inc->hasDuration()) { + return inc->duration().end(start); + } else { + const QDateTime end = inc->dateTime(Incidence::RoleEnd); + if (end.isValid()) { + const Duration elapsed(inc->dtStart(), end, Duration::Seconds); + return elapsed.end(start); + } + } + return QDateTime(); + } + void setupIterator(const Calendar &calendar, const Incidence::List &incidences) { for (const Incidence::Ptr &inc : qAsConst(incidences)) { @@ -131,7 +148,12 @@ } if (!occurrenceIsHidden(calendar, incidence, occurrenceStartDate)) { - occurrenceList << Private::Occurrence(incidence, recurrenceId, occurrenceStartDate); + const Period period = inc->recurrence()->rDateTimePeriod(occurrenceStartDate); + if (period.isValid()) { + occurrenceList << Private::Occurrence(incidence, recurrenceId, occurrenceStartDate, period.end()); + } else { + occurrenceList << Private::Occurrence(incidence, recurrenceId, occurrenceStartDate, occurrenceEnd(incidence, occurrenceStartDate)); + } } if (resetIncidence) { @@ -140,7 +162,8 @@ } } } else { - occurrenceList << Private::Occurrence(inc, {}, inc->dtStart()); + occurrenceList << Private::Occurrence(inc, {}, inc->dtStart(), + inc->dateTime(Incidence::RoleEnd)); } } occurrenceIt = QListIterator<Private::Occurrence>(occurrenceList); @@ -225,6 +248,11 @@ return d->current.startDate; } +QDateTime OccurrenceIterator::occurrenceEndDate() const +{ + return d->current.endDate; +} + QDateTime OccurrenceIterator::recurrenceId() const { return d->current.recurrenceId; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/src/occurrenceiterator.h new/kcalendarcore-5.87.0/src/occurrenceiterator.h --- old/kcalendarcore-5.86.0/src/occurrenceiterator.h 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/src/occurrenceiterator.h 2021-10-02 14:14:52.000000000 +0200 @@ -69,6 +69,17 @@ QDateTime occurrenceStartDate() const; /** + * Returns the end date of the occurrence + * + * For incidence that supports end date (events and due date for todos), + * this is computed from the duration or directly the end date of + * the occurrence or an exception overriding that occurrence. For incidences + * without end date, an invalid date is returned. + * @since 5.87 + */ + QDateTime occurrenceEndDate() const; + + /** * Returns the recurrence Id. * * This is the date where the occurrence starts without exceptions, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/src/period.cpp new/kcalendarcore-5.87.0/src/period.cpp --- old/kcalendarcore-5.86.0/src/period.cpp 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/src/period.cpp 2021-10-02 14:14:52.000000000 +0200 @@ -96,6 +96,11 @@ return *this; } +bool Period::isValid() const +{ + return d->mStart.isValid(); +} + QDateTime Period::start() const { return d->mStart; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/src/period.h new/kcalendarcore-5.87.0/src/period.h --- old/kcalendarcore-5.86.0/src/period.h 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/src/period.h 2021-10-02 14:14:52.000000000 +0200 @@ -124,6 +124,12 @@ Period &operator=(const Period &other); /** + Returns true if the Period is not empty. + @since 5.87 + */ + Q_REQUIRED_RESULT bool isValid() const; + + /** Returns when this period starts. */ Q_REQUIRED_RESULT QDateTime start() const; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/src/recurrence.cpp new/kcalendarcore-5.87.0/src/recurrence.cpp --- old/kcalendarcore-5.86.0/src/recurrence.cpp 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/src/recurrence.cpp 2021-10-02 14:14:52.000000000 +0200 @@ -18,6 +18,7 @@ #include <QDataStream> #include <QTime> #include <QTimeZone> +#include <QHash> using namespace KCalendarCore; @@ -34,6 +35,7 @@ Private(const Private &p) : mRDateTimes(p.mRDateTimes) + , mRDateTimePeriods(p.mRDateTimePeriods) , mRDates(p.mRDates) , mExDateTimes(p.mExDateTimes) , mExDates(p.mExDates) @@ -49,6 +51,7 @@ RecurrenceRule::List mExRules; RecurrenceRule::List mRRules; QList<QDateTime> mRDateTimes; + QHash<QDateTime, Period> mRDateTimePeriods; // Map RDate starts with periods if any DateList mRDates; QList<QDateTime> mExDateTimes; DateList mExDates; @@ -67,7 +70,7 @@ // qCDebug(KCALCORE_LOG) << mStartDateTime << p.mStartDateTime; if ((mStartDateTime != p.mStartDateTime && (mStartDateTime.isValid() || p.mStartDateTime.isValid())) || mAllDay != p.mAllDay || mRecurReadOnly != p.mRecurReadOnly || mExDates != p.mExDates || mExDateTimes != p.mExDateTimes || mRDates != p.mRDates - || mRDateTimes != p.mRDateTimes) { + || mRDateTimes != p.mRDateTimes || mRDateTimePeriods != p.mRDateTimePeriods) { return false; } @@ -522,11 +525,15 @@ d->mStartDateTime = d->mStartDateTime.toTimeZone(oldTz); d->mStartDateTime.setTimeZone(newTz); + QHash<QDateTime, Period> oldPeriods = d->mRDateTimePeriods; int i; int end; for (i = 0, end = d->mRDateTimes.count(); i < end; ++i) { + QHash<QDateTime, Period>::Iterator period = oldPeriods.find(d->mRDateTimes[i]); + period->shiftTimes(oldTz, newTz); d->mRDateTimes[i] = d->mRDateTimes[i].toTimeZone(oldTz); d->mRDateTimes[i].setTimeZone(newTz); + d->mRDateTimePeriods.insert(d->mRDateTimes[i], *period); } for (i = 0, end = d->mExDateTimes.count(); i < end; ++i) { d->mExDateTimes[i] = d->mExDateTimes[i].toTimeZone(oldTz); @@ -561,6 +568,7 @@ d->mExRules.clear(); d->mRDates.clear(); d->mRDateTimes.clear(); + d->mRDateTimePeriods.clear(); d->mExDates.clear(); d->mExDateTimes.clear(); d->mCachedType = rMax; @@ -1337,6 +1345,7 @@ d->mRDateTimes = rdates; sortAndRemoveDuplicates(d->mRDateTimes); + d->mRDateTimePeriods.clear(); updated(); } @@ -1350,6 +1359,22 @@ updated(); } +void Recurrence::addRDateTimePeriod(const Period &period) +{ + if (d->mRecurReadOnly) { + return; + } + + setInsert(d->mRDateTimes, period.start()); + d->mRDateTimePeriods.insert(period.start(), period); + updated(); +} + +Period Recurrence::rDateTimePeriod(const QDateTime &rdate) const +{ + return d->mRDateTimePeriods.value(rdate); +} + DateList Recurrence::rDates() const { return d->mRDates; @@ -1487,6 +1512,11 @@ } serializeQDateTimeList(out, r->d->mRDateTimes); + out << r->d->mRDateTimePeriods.size(); + for (QHash<QDateTime, Period>::ConstIterator it = r->d->mRDateTimePeriods.constBegin(); + it != r->d->mRDateTimePeriods.constEnd(); ++it) { + out << it.key() << it.value(); + } serializeQDateTimeList(out, r->d->mExDateTimes); out << r->d->mRDates; serializeQDateTimeAsKDateTime(out, r->d->mStartDateTime); @@ -1511,8 +1541,19 @@ int rruleCount; int exruleCount; + int size; deserializeQDateTimeList(in, r->d->mRDateTimes); + in >> size; + r->d->mRDateTimePeriods.clear(); + r->d->mRDateTimePeriods.reserve(size); + for (int i = 0; i < size; ++i) { + QDateTime start; + Period period; + in >> start >> period; + r->d->mRDateTimes << start; + r->d->mRDateTimePeriods.insert(start, period); + } deserializeQDateTimeList(in, r->d->mExDateTimes); in >> r->d->mRDates; deserializeKDateTimeAsQDateTime(in, r->d->mStartDateTime); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.86.0/src/recurrence.h new/kcalendarcore-5.87.0/src/recurrence.h --- old/kcalendarcore-5.86.0/src/recurrence.h 2021-09-04 17:41:34.000000000 +0200 +++ new/kcalendarcore-5.87.0/src/recurrence.h 2021-10-02 14:14:52.000000000 +0200 @@ -13,6 +13,7 @@ #include "kcalendarcore_export.h" #include "recurrencerule.h" +#include "period.h" class QBitArray; class QTimeZone; @@ -612,10 +613,26 @@ // RDATE Q_REQUIRED_RESULT QList<QDateTime> rDateTimes() const; Q_REQUIRED_RESULT DateList rDates() const; + /** + Inquire if the given RDATE is associated to a PERIOD. + @param rdate a given RDATE in date time format. + @return a Period, invalid if there is no period associated to @param rdate. + @since 5.87 + */ + Q_REQUIRED_RESULT Period rDateTimePeriod(const QDateTime &rdate) const; void setRDateTimes(const QList<QDateTime> &rdates); void setRDates(const DateList &rdates); void addRDateTime(const QDateTime &rdate); void addRDate(const QDate &rdate); + /** + Add a RDATE defined as a PERIOD. The start date-time of the period is added + to the recurring date time list, and will be listed by a call to + rDateTimes(). Use then rDateTimePeriod() to fetch the associated + period defintion. + @param period a given RDATE in period defintion. + @since 5.87 + */ + void addRDateTimePeriod(const Period &period); // ExDATE Q_REQUIRED_RESULT QList<QDateTime> exDateTimes() const;
