diff --git a/src/akonadi/akonadiserializer.cpp b/src/akonadi/akonadiserializer.cpp --- a/src/akonadi/akonadiserializer.cpp +++ b/src/akonadi/akonadiserializer.cpp @@ -30,9 +30,12 @@ #include #include #include +#include #include #include +#if KCALCORE_VERSION < QT_VERSION_CHECK(5, 6, 80) #include +#endif #include @@ -194,9 +197,21 @@ task->setTitle(todo->summary()); task->setText(todo->description()); task->setDone(todo->isCompleted()); +#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 6, 80) + if (todo->allDay()) { + task->setDoneDate(QDateTime(todo->completed().date(), QTime(), Qt::UTC)); + task->setStartDate(QDateTime(todo->dtStart().date(), QTime(), Qt::UTC)); + task->setDueDate(QDateTime(todo->dtDue().date(), QTime(), Qt::UTC)); + } else { + task->setDoneDate(todo->completed().toUTC()); + task->setStartDate(todo->dtStart().toUTC()); + task->setDueDate(todo->dtDue().toUTC()); + } +#else task->setDoneDate(todo->completed().dateTime().toUTC()); task->setStartDate(todo->dtStart().dateTime().toUTC()); task->setDueDate(todo->dtDue().dateTime().toUTC()); +#endif task->setProperty("itemId", item.id()); task->setProperty("parentCollectionId", item.parentCollection().id()); task->setProperty("todoUid", todo->uid()); @@ -261,15 +276,30 @@ return false; } +#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 6, 80) +#define KDateTime QDateTime +#endif + + Akonadi::Item Serializer::createItemFromTask(Domain::Task::Ptr task) { auto todo = KCalCore::Todo::Ptr::create(); todo->setSummary(task->title()); todo->setDescription(task->text()); + // We only support all-day todos, so ignore timezone information and possible effect from timezone on dates + // KCalCore reads "DUE;VALUE=DATE:20171130" as QDateTime(QDate(2017, 11, 30), QTime(), Qt::LocalTime), for lack of timezone information + // so we should never call toUtc() on that, it would mess up the date. Instead we force UTC while preserving the date. + // If one day we want to support time information, we need to add a task->isAllDay()/setAllDay(). +#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 6, 80) + todo->setDtStart(QDateTime(task->startDate().date(), QTime(), Qt::UTC)); + todo->setDtDue(QDateTime(task->dueDate().date(), QTime(), Qt::UTC)); + todo->setAllDay(true); +#else todo->setDtStart(KDateTime(task->startDate(), KDateTime::UTC)); todo->setDtDue(KDateTime(task->dueDate(), KDateTime::UTC)); +#endif if (task->property("todoUid").isValid()) { todo->setUid(task->property("todoUid").toString()); diff --git a/tests/benchmarks/serializerTest.cpp b/tests/benchmarks/serializerTest.cpp --- a/tests/benchmarks/serializerTest.cpp +++ b/tests/benchmarks/serializerTest.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "domain/task.h" #include "akonadi/akonadiserializer.h" @@ -39,6 +40,10 @@ void checkPayload(); }; +#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 6, 80) +#define KDateTime QDateTime +#endif + Akonadi::Item SerializerBenchmark::createTestItem() { KCalCore::Todo::Ptr todo(new KCalCore::Todo); diff --git a/tests/testlib/akonadistoragetestbase.cpp b/tests/testlib/akonadistoragetestbase.cpp --- a/tests/testlib/akonadistoragetestbase.cpp +++ b/tests/testlib/akonadistoragetestbase.cpp @@ -29,10 +29,12 @@ #include #include -#include #include #include #include +#if KCALCORE_VERSION < QT_VERSION_CHECK(5, 6, 80) +#include +#endif #include "utils/mem_fn.h" @@ -49,6 +51,10 @@ #include "akonadi/akonaditagfetchjobinterface.h" #include "akonadi/akonaditimestampattribute.h" +#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 6, 80) +#define KDateTime QDateTime +#endif + using namespace Testlib; AkonadiStorageTestBase::AkonadiStorageTestBase(QObject *parent) diff --git a/tests/testlib/gentodo.cpp b/tests/testlib/gentodo.cpp --- a/tests/testlib/gentodo.cpp +++ b/tests/testlib/gentodo.cpp @@ -25,7 +25,10 @@ #include #include +#include +#if KCALCORE_VERSION < QT_VERSION_CHECK(5, 6, 80) #include +#endif using namespace Testlib; @@ -106,6 +109,17 @@ return *this; } +#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 6, 80) + +template +static QDateTime KDateTime(const T& input) { + QDateTime dt(input); + dt.setTimeSpec(Qt::UTC); + return dt; +} + +#endif + GenTodo &GenTodo::withDoneDate(const QString &date) { m_item.payload()->setCompleted(KDateTime(QDate::fromString(date, Qt::ISODate))); diff --git a/tests/units/akonadi/akonadiserializertest.cpp b/tests/units/akonadi/akonadiserializertest.cpp --- a/tests/units/akonadi/akonadiserializertest.cpp +++ b/tests/units/akonadi/akonadiserializertest.cpp @@ -34,10 +34,26 @@ #include #include #include +#include #include Q_DECLARE_METATYPE(Akonadi::Item*) +#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 6, 80) +#define KDateTime QDateTime +#endif + + +static void setTodoDates(KCalCore::Todo::Ptr todo, const QDateTime &start, const QDateTime &due) { +#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 6, 80) + todo->setDtStart(start); + todo->setDtDue(due); +#else + todo->setDtStart(KDateTime(start, KDateTime::UTC)); + todo->setDtDue(KDateTime(due, KDateTime::UTC)); +#endif +} + class AkonadiSerializerTest : public QObject { Q_OBJECT @@ -551,8 +567,7 @@ else todo->setCompleted(isDone); - todo->setDtStart(KDateTime(startDate, KDateTime::UTC)); - todo->setDtDue(KDateTime(dueDate, KDateTime::UTC)); + setTodoDates(todo, startDate, dueDate); todo->setRelatedTo(QStringLiteral("my-uid")); if (!delegateName.isEmpty() || !delegateEmail.isEmpty()) { KCalCore::Attendee::Ptr attendee(new KCalCore::Attendee(delegateName, @@ -678,8 +693,8 @@ originalTodo->setSummary(QStringLiteral("summary")); originalTodo->setDescription(QStringLiteral("content")); originalTodo->setCompleted(false); - originalTodo->setDtStart(KDateTime(QDate(2013, 11, 24), KDateTime::UTC)); - originalTodo->setDtDue(KDateTime(QDate(2014, 03, 01), KDateTime::UTC)); + setTodoDates(originalTodo, QDateTime(QDate(2013, 11, 24)), QDateTime(QDate(2014, 03, 01))); + originalTodo->setRelatedTo(QStringLiteral("my-uid")); KCalCore::Attendee::Ptr originalAttendee(new KCalCore::Attendee(QStringLiteral("John Doe"), QStringLiteral("j@d.com"), @@ -736,8 +751,7 @@ else updatedTodo->setCompleted(updatedDone); - updatedTodo->setDtStart(KDateTime(updatedStartDate, KDateTime::UTC)); - updatedTodo->setDtDue(KDateTime(updatedDueDate, KDateTime::UTC)); + setTodoDates(updatedTodo, updatedStartDate, updatedDueDate); updatedTodo->setRelatedTo(updatedRelated); if (updatedRecurs) @@ -905,7 +919,11 @@ // ... stored in a todo... KCalCore::Todo::Ptr todo(new KCalCore::Todo); todo->setSummary(QStringLiteral("summary")); +#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 6, 80) + todo->setDtStart(startDate); +#else todo->setDtStart(KDateTime(startDate, KDateTime::UTC)); +#endif todo->recurrence()->setMonthly(1); // ... as payload of an item... @@ -957,9 +975,7 @@ originalTodo->setCompleted(KDateTime(doneDate)); else originalTodo->setCompleted(isDone); - - originalTodo->setDtStart(KDateTime(startDate, KDateTime::UTC)); - originalTodo->setDtDue(KDateTime(dueDate, KDateTime::UTC)); + setTodoDates(originalTodo, startDate, dueDate); // ... as payload of an item... Akonadi::Item originalItem; @@ -1016,9 +1032,7 @@ originalTodo->setCompleted(KDateTime(doneDate)); else originalTodo->setCompleted(isDone); - - originalTodo->setDtStart(KDateTime(startDate, KDateTime::UTC)); - originalTodo->setDtDue(KDateTime(dueDate, KDateTime::UTC)); + setTodoDates(originalTodo, startDate, dueDate); // ... as payload of an item... Akonadi::Item originalItem; @@ -1136,13 +1150,15 @@ << Domain::Task::Attachments() << Domain::Task::Delegate() << false; - QTest::newRow("nominal_with_time_info_noid") << "summary" << "content" << true << QDateTime(QDate(2015, 3, 1), QTime(1, 2, 3), Qt::UTC) +#if 0 // if we ever need time info, then we need a Task::setAllDay(bool) just like KCalCore::Todo has. + QTest::newRow("nominal_with_time_info_noid") << "summary" << "content" << true << QDateTime(QDate(2015, 3, 1), QTime(1, 2, 3), Qt::UTC) << QDateTime(QDate(2013, 11, 24), QTime(0, 1, 2), Qt::UTC) << QDateTime(QDate(2016, 3, 1), QTime(4, 5, 6), Qt::UTC) << qint64(-1) << qint64(-1) << QString() << Domain::Task::NoRecurrence << Domain::Task::Attachments() << Domain::Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("j@d.com")) << false; +#endif QTest::newRow("nominal case (with id)") << "summary" << "content" << false << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) @@ -1243,14 +1259,24 @@ QCOMPARE(todo->summary(), summary); QCOMPARE(todo->description(), content); QCOMPARE(todo->isCompleted(), isDone); +#if KCALCORE_VERSION >= QT_VERSION_CHECK(5, 6, 80) + QCOMPARE(todo->completed().toUTC(), doneDate); + QCOMPARE(todo->dtStart().toUTC(), startDate); + QCOMPARE(todo->dtDue().toUTC(), dueDate); + if (todo->dtStart().isValid()) { + QCOMPARE(int(todo->dtStart().timeSpec()), int(Qt::UTC)); + } + QVERIFY(todo->allDay()); // this is always true currently... +#else QCOMPARE(todo->completed().dateTime().toUTC(), doneDate); QCOMPARE(todo->dtStart().dateTime().toUTC(), startDate); QCOMPARE(todo->dtDue().dateTime().toUTC(), dueDate); if (todo->dtStart().isValid()) { QCOMPARE(int(todo->dtStart().timeType()), int(KDateTime::UTC)); } QCOMPARE(todo->dtStart().isDateOnly(), todo->allDay()); +#endif const ushort expectedRecurrence = recurrence == Domain::Task::NoRecurrence ? KCalCore::Recurrence::rNone : recurrence == Domain::Task::RecursDaily ? KCalCore::Recurrence::rDaily : recurrence == Domain::Task::RecursWeekly ? KCalCore::Recurrence::rWeekly @@ -1319,8 +1345,7 @@ else childTodo->setCompleted(isDone); - childTodo->setDtStart(KDateTime(startDate, KDateTime::UTC)); - childTodo->setDtDue(KDateTime(dueDate, KDateTime::UTC)); + setTodoDates(childTodo, startDate, dueDate); Akonadi::Item childItem; childItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); @@ -1337,9 +1362,7 @@ childTodo2->setCompleted(KDateTime(doneDate)); else childTodo2->setCompleted(isDone); - - childTodo2->setDtStart(KDateTime(startDate, KDateTime::UTC)); - childTodo2->setDtDue(KDateTime(dueDate, KDateTime::UTC)); + setTodoDates(childTodo2, startDate, dueDate); childTodo2->setRelatedTo(QStringLiteral("1")); Akonadi::Item childItem2; @@ -2665,10 +2688,12 @@ QVERIFY(atMidnight.time().isValid()); QVERIFY(!atMidnight.time().isNull()); +#if 0 // GIVEN a KDateTime without time information KDateTime kdOnly(QDate(2016, 6, 12)); // THEN we can detect that there was no time information, i.e. all day event QVERIFY(kdOnly.isDateOnly()); +#endif } };