Hello community, here is the log from the commit of package kcalendarcore for openSUSE:Factory checked in at 2019-12-18 14:40:06 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kcalendarcore (Old) and /work/SRC/openSUSE:Factory/.kcalendarcore.new.4691 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kcalendarcore" Wed Dec 18 14:40:06 2019 rev:3 rq:757013 version:5.65.0 Changes: -------- --- /work/SRC/openSUSE:Factory/kcalendarcore/kcalendarcore.changes 2019-11-12 11:43:34.494609691 +0100 +++ /work/SRC/openSUSE:Factory/.kcalendarcore.new.4691/kcalendarcore.changes 2019-12-18 14:42:01.805766042 +0100 @@ -1,0 +2,15 @@ +Sun Dec 8 11:18:21 UTC 2019 - Christophe Giboudeaux <[email protected]> + +- Update to 5.65.0 + * New feature release + * For more details please see: + * https://www.kde.org/announcements/kde-frameworks-5.65.0.php +- Changes since 5.64.0: + * autotests: Find perl executable on all platforms + * Add some test to ensure local time handling in recurrences. + * Fallback to system time zone on calendar creation with an invalid one. + * Memory Calendar: avoid code duplication + * Use QDate as key in mIncidencesForDate in MemoryCalendar + * Handle incidences in different time zones in MemoryCalendar. + +------------------------------------------------------------------- Old: ---- kcalendarcore-5.64.0.tar.xz kcalendarcore-5.64.0.tar.xz.sig New: ---- kcalendarcore-5.65.0.tar.xz kcalendarcore-5.65.0.tar.xz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kcalendarcore.spec ++++++ --- /var/tmp/diff_new_pack.um4mS3/_old 2019-12-18 14:42:03.117766642 +0100 +++ /var/tmp/diff_new_pack.um4mS3/_new 2019-12-18 14:42:03.117766642 +0100 @@ -1,7 +1,7 @@ # # spec file for package kcalendarcore # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,14 +16,14 @@ # -%define _tar_path 5.64 +%define _tar_path 5.65 # 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.64.0 +Version: 5.65.0 Release: 0 Summary: Library to access and handle calendar data License: LGPL-2.0-or-later ++++++ kcalendarcore-5.64.0.tar.xz -> kcalendarcore-5.65.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.64.0/CMakeLists.txt new/kcalendarcore-5.65.0/CMakeLists.txt --- old/kcalendarcore-5.64.0/CMakeLists.txt 2019-11-02 12:42:22.000000000 +0100 +++ new/kcalendarcore-5.65.0/CMakeLists.txt 2019-12-07 20:41:23.000000000 +0100 @@ -1,11 +1,11 @@ cmake_minimum_required(VERSION 3.5) -set(KF5_VERSION "5.64.0") # handled by release scripts +set(KF5_VERSION "5.65.0") # handled by release scripts project(KCalendarCore VERSION ${KF5_VERSION}) # ECM setup include(FeatureSummary) -find_package(ECM 5.64.0 NO_MODULE) +find_package(ECM 5.65.0 NO_MODULE) set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://projects.kde.org/projects/kdesupport/extra-cmake-modules") feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) @@ -70,7 +70,6 @@ add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050d00) -add_definitions(-DQT_DEPRECATED_WARNINGS_SINCE=0x060000) add_definitions(-DQT_NO_FOREACH) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.64.0/autotests/testmemorycalendar.cpp new/kcalendarcore-5.65.0/autotests/testmemorycalendar.cpp --- old/kcalendarcore-5.64.0/autotests/testmemorycalendar.cpp 2019-11-02 12:42:22.000000000 +0100 +++ new/kcalendarcore-5.65.0/autotests/testmemorycalendar.cpp 2019-12-07 20:41:23.000000000 +0100 @@ -41,6 +41,13 @@ cal->close(); } +void MemoryCalendarTest::testInvalidTimeZone() +{ + MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone())); + // On invalid time zone, fallback to system time zone. + QVERIFY(cal->timeZone() == QTimeZone::systemTimeZone()); +} + void MemoryCalendarTest::testEvents() { MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); @@ -272,3 +279,44 @@ QVERIFY(exception->summary() == QLatin1String("exception")); QVERIFY(main->summary() == event1->summary()); } + +void MemoryCalendarTest::testRawEventsForDate() +{ + // We're checking that events at a date in a given time zone + // are properly returned for the day after / before if + // the calendar is for another time zone. + MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); + + Event::Ptr event = Event::Ptr(new Event()); + event->setDtStart(QDateTime(QDate(2019, 10, 29), QTime(1, 30), + QTimeZone("Asia/Ho_Chi_Minh"))); + + QVERIFY(cal->addEvent(event)); + + QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 28)).count(), 1); + QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 29), + QTimeZone("Asia/Ho_Chi_Minh")).count(), 1); + + cal->setTimeZoneId("Asia/Ho_Chi_Minh"); + QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 29)).count(), 1); + QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 28), + QTimeZone::utc()).count(), 1); + + event->setDtStart(QDateTime(QDate(2019, 10, 30), QTime(23, 00), + QTimeZone::utc())); + QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 31)).count(), 1); + QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 30), + QTimeZone::utc()).count(), 1); + + QVERIFY(cal->deleteIncidence(event)); + QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 31)).count(), 0); + + // Multi-days events are treated differently. + event->setDtEnd(QDateTime(QDate(2019, 10, 31), QTime(23, 00), + QTimeZone::utc())); + QVERIFY(cal->addEvent(event)); + QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 31)).count(), 1); + QCOMPARE(cal->rawEventsForDate(QDate(2019, 11, 1)).count(), 1); + + cal->close(); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.64.0/autotests/testmemorycalendar.h new/kcalendarcore-5.65.0/autotests/testmemorycalendar.h --- old/kcalendarcore-5.64.0/autotests/testmemorycalendar.h 2019-11-02 12:42:22.000000000 +0100 +++ new/kcalendarcore-5.65.0/autotests/testmemorycalendar.h 2019-12-07 20:41:23.000000000 +0100 @@ -29,11 +29,13 @@ Q_OBJECT private Q_SLOTS: void testValidity(); + void testInvalidTimeZone(); void testEvents(); void testIncidences(); void testRelationsCrash(); void testRecurrenceExceptions(); void testChangeRecurId(); + void testRawEventsForDate(); }; #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.64.0/src/calendar.cpp new/kcalendarcore-5.65.0/src/calendar.cpp --- old/kcalendarcore-5.64.0/src/calendar.cpp 2019-11-02 12:42:22.000000000 +0100 +++ new/kcalendarcore-5.65.0/src/calendar.cpp 2019-12-07 20:41:23.000000000 +0100 @@ -141,7 +141,11 @@ Calendar::Calendar(const QTimeZone &timeZone) : d(new KCalendarCore::Calendar::Private) { - d->mTimeZone = timeZone; + if (timeZone.isValid()) { + d->mTimeZone = timeZone; + } else { + d->mTimeZone = QTimeZone::systemTimeZone(); + } } Calendar::Calendar(const QByteArray &timeZoneId) @@ -168,7 +172,11 @@ void Calendar::setTimeZone(const QTimeZone &timeZone) { - d->mTimeZone = timeZone; + if (timeZone.isValid()) { + d->mTimeZone = timeZone; + } else { + d->mTimeZone = QTimeZone::systemTimeZone(); + } doSetTimeZone(d->mTimeZone); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.64.0/src/memorycalendar.cpp new/kcalendarcore-5.65.0/src/memorycalendar.cpp --- old/kcalendarcore-5.64.0/src/memorycalendar.cpp 2019-11-02 12:42:22.000000000 +0100 +++ new/kcalendarcore-5.65.0/src/memorycalendar.cpp 2019-12-07 20:41:23.000000000 +0100 @@ -38,28 +38,7 @@ #include <QDate> -template <typename K, typename V> -static 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> -static 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; -} +#include <functional> using namespace KCalendarCore; @@ -70,6 +49,9 @@ //@cond PRIVATE class Q_DECL_HIDDEN KCalendarCore::MemoryCalendar::Private { +private: + static constexpr int incidenceTypeCount = 4; + public: Private(MemoryCalendar *qq) : q(qq), mFormat(nullptr) @@ -83,11 +65,12 @@ CalFormat *mFormat; // calendar format QString mIncidenceBeingUpdated; // Instance identifier of Incidence currently being updated + /** * List of all incidences. * First indexed by incidence->type(), then by incidence->uid(); */ - QMap<IncidenceBase::IncidenceType, QMultiHash<QString, Incidence::Ptr> > mIncidences; + QMultiHash<QString, Incidence::Ptr> mIncidences[incidenceTypeCount]; /** * Has all incidences, indexed by identifier. @@ -98,20 +81,20 @@ * List of all deleted incidences. * First indexed by incidence->type(), then by incidence->uid(); */ - QMap<IncidenceBase::IncidenceType, QMultiHash<QString, Incidence::Ptr> > mDeletedIncidences; + QMultiHash<QString, Incidence::Ptr> mDeletedIncidences[incidenceTypeCount]; /** * Contains incidences ( to-dos; non-recurring, non-multiday events; journals; ) * indexed by start/due date. * * The QMap key is the incidence->type(). - * The QMultiHash key is the dtStart/dtDue().toString() + * The QMultiHash key is the dtStart/dtDue() converted to calendar's timezone * * Note: We had 3 variables, mJournalsForDate, mTodosForDate and mEventsForDate * but i merged them into one (indexed by type) because it simplifies code using * it. No need to if else based on type. */ - QMap<IncidenceBase::IncidenceType, QMultiHash<QString, IncidenceBase::Ptr> > mIncidencesForDate; + QMultiHash<QDate, Incidence::Ptr> mIncidencesForDate[incidenceTypeCount]; void insertIncidence(const Incidence::Ptr &incidence); @@ -125,6 +108,54 @@ void deleteAllIncidences(IncidenceBase::IncidenceType type); + template<typename IncidenceType, typename Key> + void forIncidences(const QMultiHash<Key, Incidence::Ptr> &incidences, const Key &key, + std::function<void(const typename IncidenceType::Ptr &)> &&op) const { + for (auto it = incidences.constFind(key), end = incidences.cend(); it != end && it.key() == key; ++it) { + op(it.value().template staticCast<IncidenceType>()); + } + } + + template<typename IncidenceType, typename Key> + void forIncidences(const QMultiHash<Key, Incidence::Ptr> &incidences, + std::function<void(const typename IncidenceType::Ptr &)> &&op) const { + for (const auto &incidence : incidences) { + op(incidence.template staticCast<IncidenceType>()); + } + } + + template<typename IncidenceType> + typename IncidenceType::List castIncidenceList(const QMultiHash<QString, Incidence::Ptr> &incidences) const { + typename IncidenceType::List list; + list.reserve(incidences.size()); + std::transform(incidences.cbegin(), incidences.cend(), std::back_inserter(list), + [](const Incidence::Ptr &inc) { return inc.staticCast<IncidenceType>(); }); + return list; + } + + template<typename IncidenceType> + typename IncidenceType::List incidenceInstances(IncidenceBase::IncidenceType type, const Incidence::Ptr &incidence) const { + typename IncidenceType::List list; + forIncidences<IncidenceType, QString>(mIncidences[type], incidence->uid(), [&list](const typename IncidenceType::Ptr &incidence) { + if (incidence->hasRecurrenceId()) { + list.push_back(incidence); + } + }); + return list; + } + + Incidence::Ptr findIncidence(const QMultiHash<QString, Incidence::Ptr> &incidences, const QString &uid, const QDateTime &recurrenceId) const { + for (auto it = incidences.constFind(uid), end = incidences.cend(); it != end && it.key() == uid; ++it) { + const auto &incidence = it.value(); + if (recurrenceId.isNull() && !incidence->hasRecurrenceId()) { + return incidence; + } else if (!recurrenceId.isNull() && incidence->hasRecurrenceId() && recurrenceId == incidence->recurrenceId()) { + return incidence; + } + } + return {}; + } + }; //@endcond @@ -146,6 +177,23 @@ delete d; } +void MemoryCalendar::doSetTimeZone(const QTimeZone &timeZone) +{ + // Reset date based hashes before storing for the new zone. + for (auto &table : d->mIncidencesForDate) { + table.clear(); + } + + for (auto &table : d->mIncidences) { + for (const auto &incidence : table) { + const QDateTime dt = incidence->dateTime(Incidence::RoleCalendarHashing); + if (dt.isValid()) { + d->mIncidencesForDate[incidence->type()].insert(dt.toTimeZone(timeZone).date(), incidence); + } + } + } +} + void MemoryCalendar::close() { setObserversEnabled(false); @@ -157,7 +205,9 @@ d->deleteAllIncidences(Incidence::TypeJournal); d->mIncidencesByIdentifier.clear(); - d->mDeletedIncidences.clear(); + for (auto &table : d->mDeletedIncidences) { + table.clear(); + } setModified(false); @@ -172,12 +222,13 @@ removeRelations(incidence); const Incidence::IncidenceType type = incidence->type(); const QString uid = incidence->uid(); - if (d->mIncidences[type].contains(uid, incidence)) { + auto incidenceIt = d->mIncidences[type].constFind(uid); + if (incidenceIt != d->mIncidences[type].cend()) { // Notify while the incidence is still available, // this is necessary so korganizer still has time to query for exceptions notifyIncidenceAboutToBeDeleted(incidence); - d->mIncidences[type].remove(uid, incidence); + d->mIncidences[type].erase(incidenceIt); d->mIncidencesByIdentifier.remove(incidence->instanceIdentifier()); setModified(true); if (deletionTracking()) { @@ -186,7 +237,7 @@ const QDateTime dt = incidence->dateTime(Incidence::RoleCalendarHashing); if (dt.isValid()) { - d->mIncidencesForDate[type].remove(dt.date().toString(), incidence); + d->mIncidencesForDate[type].remove(dt.toTimeZone(timeZone()).date(), incidence); } // Delete child-incidences. if (!incidence->hasRecurrenceId()) { @@ -202,19 +253,16 @@ bool MemoryCalendar::deleteIncidenceInstances(const Incidence::Ptr &incidence) { - const Incidence::IncidenceType type = incidence->type(); - Incidence::List values = ::values(d->mIncidences[type], incidence->uid()); - for (auto it = values.constBegin(); it != values.constEnd(); ++it) { - Incidence::Ptr i = *it; - if (i->hasRecurrenceId()) { + d->forIncidences<Incidence>(d->mIncidences[incidence->type()], incidence->uid(), [this](const Incidence::Ptr &incidence) { + if (incidence->hasRecurrenceId()) { qCDebug(KCALCORE_LOG) << "deleting child" - << ", type=" << int(type) - << ", uid=" << i->uid() + << ", type=" << int(incidence->type()) + << ", uid=" << incidence->uid() // << ", start=" << i->dtStart() << " from calendar"; - deleteIncidence(i); + deleteIncidence(incidence); } - } + }); return true; } @@ -222,11 +270,9 @@ //@cond PRIVATE void MemoryCalendar::Private::deleteAllIncidences(Incidence::IncidenceType incidenceType) { - QHashIterator<QString, Incidence::Ptr>i(mIncidences[incidenceType]); - while (i.hasNext()) { - i.next(); - q->notifyIncidenceAboutToBeDeleted(i.value()); - i.value()->unRegisterObserver(q); + for (auto &incidence : mIncidences[incidenceType]) { + q->notifyIncidenceAboutToBeDeleted(incidence); + incidence->unRegisterObserver(q); } mIncidences[incidenceType].clear(); mIncidencesForDate[incidenceType].clear(); @@ -236,20 +282,7 @@ Incidence::IncidenceType type, const QDateTime &recurrenceId) const { - Incidence::List values = ::values(mIncidences[type], uid); - for (auto it = values.constBegin(); it != values.constEnd(); ++it) { - Incidence::Ptr i = *it; - if (recurrenceId.isNull()) { - if (!i->hasRecurrenceId()) { - return i; - } - } else { - if (i->hasRecurrenceId() && i->recurrenceId() == recurrenceId) { - return i; - } - } - } - return Incidence::Ptr(); + return findIncidence(mIncidences[type], uid, recurrenceId); } Incidence::Ptr @@ -261,20 +294,7 @@ return Incidence::Ptr(); } - Incidence::List values = ::values(mDeletedIncidences[type], uid); - for (auto it = values.constBegin(); it != values.constEnd(); ++it) { - Incidence::Ptr i = *it; - if (recurrenceId.isNull()) { - if (!i->hasRecurrenceId()) { - return i; - } - } else { - if (i->hasRecurrenceId() && i->recurrenceId() == recurrenceId) { - return i; - } - } - } - return Incidence::Ptr(); + return findIncidence(mDeletedIncidences[type], uid, recurrenceId); } void MemoryCalendar::Private::insertIncidence(const Incidence::Ptr &incidence) @@ -286,7 +306,7 @@ mIncidencesByIdentifier.insert(incidence->instanceIdentifier(), incidence); const QDateTime dt = incidence->dateTime(Incidence::RoleCalendarHashing); if (dt.isValid()) { - mIncidencesForDate[type].insert(dt.date().toString(), incidence); + mIncidencesForDate[type].insert(dt.toTimeZone(q->timeZone()).date(), incidence); } } else { @@ -370,14 +390,7 @@ Todo::List MemoryCalendar::rawTodos(TodoSortField sortField, SortDirection sortDirection) const { - Todo::List todoList; - todoList.reserve(d->mIncidences[Incidence::TypeTodo].count()); - QHashIterator<QString, Incidence::Ptr>i(d->mIncidences[Incidence::TypeTodo]); - while (i.hasNext()) { - i.next(); - todoList.append(i.value().staticCast<Todo>()); - } - return Calendar::sortTodos(todoList, sortField, sortDirection); + return Calendar::sortTodos(d->castIncidenceList<Todo>(d->mIncidences[Incidence::TypeTodo]), sortField, sortDirection); } Todo::List MemoryCalendar::deletedTodos(TodoSortField sortField, @@ -387,57 +400,30 @@ return Todo::List(); } - Todo::List todoList; - todoList.reserve(d->mDeletedIncidences[Incidence::TypeTodo].count()); - QHashIterator<QString, Incidence::Ptr >i(d->mDeletedIncidences[Incidence::TypeTodo]); - while (i.hasNext()) { - i.next(); - todoList.append(i.value().staticCast<Todo>()); - } - return Calendar::sortTodos(todoList, sortField, sortDirection); + return Calendar::sortTodos(d->castIncidenceList<Todo>(d->mDeletedIncidences[Incidence::TypeTodo]), sortField, sortDirection); } Todo::List MemoryCalendar::todoInstances(const Incidence::Ptr &todo, TodoSortField sortField, SortDirection sortDirection) const { - Todo::List list; - - Incidence::List values = ::values(d->mIncidences[Incidence::TypeTodo], todo->uid()); - for (auto it = values.constBegin(); it != values.constEnd(); ++it) { - Todo::Ptr t = (*it).staticCast<Todo>(); - if (t->hasRecurrenceId()) { - list.append(t); - } - } - return Calendar::sortTodos(list, sortField, sortDirection); + return Calendar::sortTodos(d->incidenceInstances<Todo>(Incidence::TypeTodo, todo), sortField, sortDirection); } Todo::List MemoryCalendar::rawTodosForDate(const QDate &date) const { Todo::List todoList; - Todo::Ptr t; - const QString dateStr = date.toString(); - QMultiHash<QString, IncidenceBase::Ptr >::const_iterator it = - d->mIncidencesForDate[Incidence::TypeTodo].constFind(dateStr); - while (it != d->mIncidencesForDate[Incidence::TypeTodo].constEnd() && it.key() == dateStr) { - t = it.value().staticCast<Todo>(); - todoList.append(t); - ++it; - } + d->forIncidences<Todo>(d->mIncidencesForDate[Incidence::TypeTodo], date, [&todoList](const Todo::Ptr &todo) { + todoList.append(todo); + }); // Iterate over all todos. Look for recurring todoss that occur on this date - QHashIterator<QString, Incidence::Ptr >i(d->mIncidences[Incidence::TypeTodo]); - while (i.hasNext()) { - i.next(); - t = i.value().staticCast<Todo>(); - if (t->recurs()) { - if (t->recursOn(date, timeZone())) { - todoList.append(t); - } + d->forIncidences<Todo>(d->mIncidences[Incidence::TypeTodo], [this, &todoList, &date](const Todo::Ptr &todo) { + if (todo->recurs() && todo->recursOn(date, timeZone())) { + todoList.append(todo); } - } + }); return todoList; } @@ -455,11 +441,8 @@ QDateTime nd(end, QTime(23, 59, 59, 999), ts); // Get todos - QHashIterator<QString, Incidence::Ptr >i(d->mIncidences[Incidence::TypeTodo]); - Todo::Ptr todo; - while (i.hasNext()) { - i.next(); - todo = i.value().staticCast<Todo>(); + for (const auto &incidence : d->mIncidences[Incidence::TypeTodo]) { + const auto todo = incidence.staticCast<Todo>(); if (!isVisible(todo)) { continue; } @@ -509,24 +492,16 @@ { Q_UNUSED(excludeBlockedAlarms); Alarm::List alarmList; - QHashIterator<QString, Incidence::Ptr>ie(d->mIncidences[Incidence::TypeEvent]); - Event::Ptr e; - while (ie.hasNext()) { - ie.next(); - e = ie.value().staticCast<Event>(); + + d->forIncidences<Event>(d->mIncidences[Incidence::TypeEvent], [this, &alarmList, &from, &to](const Event::Ptr &e) { if (e->recurs()) { appendRecurringAlarms(alarmList, e, from, to); } else { appendAlarms(alarmList, e, from, to); } - } - - QHashIterator<QString, Incidence::Ptr>it(d->mIncidences[Incidence::TypeTodo]); - Todo::Ptr t; - while (it.hasNext()) { - it.next(); - t = it.value().staticCast<Todo>(); + }); + d->forIncidences<Todo>(d->mIncidences[IncidenceBase::TypeTodo], [this, &alarmList, &from, &to](const Todo::Ptr &t) { if (!t->isCompleted()) { appendAlarms(alarmList, t, from, to); if (t->recurs()) { @@ -535,7 +510,7 @@ appendAlarms(alarmList, t, from, to); } } - } + }); return alarmList; } @@ -554,8 +529,7 @@ const QDateTime dt = inc->dateTime(Incidence::RoleCalendarHashing); if (dt.isValid()) { - const Incidence::IncidenceType type = inc->type(); - d->mIncidencesForDate[type].remove(dt.date().toString(), inc); + d->mIncidencesForDate[inc->type()].remove(dt.toTimeZone(timeZone()).date(), inc); } } } @@ -583,8 +557,7 @@ const QDateTime dt = inc->dateTime(Incidence::RoleCalendarHashing); if (dt.isValid()) { - const Incidence::IncidenceType type = inc->type(); - d->mIncidencesForDate[type].insert(dt.date().toString(), inc); + d->mIncidencesForDate[inc->type()].insert(dt.toTimeZone(timeZone()).date(), inc); } notifyIncidenceChanged(inc); @@ -605,33 +578,21 @@ return eventList; } - Event::Ptr ev; + if (timeZone.isValid() && timeZone != this->timeZone()) { + // We cannot use the hash table on date, since time zone is different. + eventList = rawEvents(date, date, timeZone, false); + return Calendar::sortEvents(eventList, sortField, sortDirection); + } - // Find the hash for the specified date - const QString dateStr = date.toString(); - QMultiHash<QString, IncidenceBase::Ptr >::const_iterator it = - d->mIncidencesForDate[Incidence::TypeEvent].constFind(dateStr); // Iterate over all non-recurring, single-day events that start on this date - const auto ts = timeZone.isValid() ? timeZone : this->timeZone(); - while (it != d->mIncidencesForDate[Incidence::TypeEvent].constEnd() && it.key() == dateStr) { - ev = it.value().staticCast<Event>(); - QDateTime end(ev->dtEnd().toTimeZone(ev->dtStart().timeZone())); - if (ev->allDay()) { - end.setTime(QTime()); - } else { - end = end.addSecs(-1); - } - if (end.date() >= date) { - eventList.append(ev); - } - ++it; - } + d->forIncidences<Event>(d->mIncidencesForDate[Incidence::TypeEvent], date, [&eventList](const Event::Ptr &event) { + eventList.append(event); + }); // Iterate over all events. Look for recurring events that occur on this date - QHashIterator<QString, Incidence::Ptr>i(d->mIncidences[Incidence::TypeEvent]); - while (i.hasNext()) { - i.next(); - ev = i.value().staticCast<Event>(); + const auto ts = timeZone.isValid() ? timeZone : this->timeZone(); + for (const auto &event : d->mIncidences[Incidence::TypeEvent]) { + const auto ev = event.staticCast<Event>(); if (ev->recurs()) { if (ev->isMultiDay()) { int extraDays = ev->dtStart().date().daysTo(ev->dtEnd().date()); @@ -648,7 +609,7 @@ } } else { if (ev->isMultiDay()) { - if (ev->dtStart().date() <= date && ev->dtEnd().date() >= date) { + if (ev->dtStart().toTimeZone(ts).date() <= date && ev->dtEnd().toTimeZone(ts).date() >= date) { eventList.append(ev); } } @@ -669,11 +630,8 @@ QDateTime nd(end, QTime(23, 59, 59, 999), ts); // Get non-recurring events - QHashIterator<QString, Incidence::Ptr>i(d->mIncidences[Incidence::TypeEvent]); - Event::Ptr event; - while (i.hasNext()) { - i.next(); - event = i.value().staticCast<Event>(); + for (const auto &e: d->mIncidences[Incidence::TypeEvent]) { + const auto event = e.staticCast<Event>(); QDateTime rStart = event->dtStart(); if (nd < rStart) { continue; @@ -727,14 +685,7 @@ Event::List MemoryCalendar::rawEvents(EventSortField sortField, SortDirection sortDirection) const { - Event::List eventList; - eventList.reserve(d->mIncidences[Incidence::TypeEvent].count()); - QHashIterator<QString, Incidence::Ptr> i(d->mIncidences[Incidence::TypeEvent]); - while (i.hasNext()) { - i.next(); - eventList.append(i.value().staticCast<Event>()); - } - return Calendar::sortEvents(eventList, sortField, sortDirection); + return Calendar::sortEvents(d->castIncidenceList<Event>(d->mIncidences[Incidence::TypeEvent]), sortField, sortDirection); } Event::List MemoryCalendar::deletedEvents(EventSortField sortField, @@ -744,30 +695,14 @@ return Event::List(); } - Event::List eventList; - eventList.reserve(d->mDeletedIncidences[Incidence::TypeEvent].count()); - QHashIterator<QString, Incidence::Ptr>i(d->mDeletedIncidences[Incidence::TypeEvent]); - while (i.hasNext()) { - i.next(); - eventList.append(i.value().staticCast<Event>()); - } - return Calendar::sortEvents(eventList, sortField, sortDirection); + return Calendar::sortEvents(d->castIncidenceList<Event>(d->mDeletedIncidences[Incidence::TypeEvent]), sortField, sortDirection); } Event::List MemoryCalendar::eventInstances(const Incidence::Ptr &event, EventSortField sortField, SortDirection sortDirection) const { - Event::List list; - - Incidence::List values = ::values(d->mIncidences[Incidence::TypeEvent], event->uid()); - for (auto it = values.constBegin(); it != values.constEnd(); ++it) { - Event::Ptr ev = (*it).staticCast<Event>(); - if (ev->hasRecurrenceId()) { - list.append(ev); - } - } - return Calendar::sortEvents(list, sortField, sortDirection); + return Calendar::sortEvents(d->incidenceInstances<Event>(Incidence::TypeEvent, event), sortField, sortDirection); } bool MemoryCalendar::addJournal(const Journal::Ptr &journal) @@ -799,13 +734,7 @@ Journal::List MemoryCalendar::rawJournals(JournalSortField sortField, SortDirection sortDirection) const { - Journal::List journalList; - QHashIterator<QString, Incidence::Ptr>i(d->mIncidences[Incidence::TypeJournal]); - while (i.hasNext()) { - i.next(); - journalList.append(i.value().staticCast<Journal>()); - } - return Calendar::sortJournals(journalList, sortField, sortDirection); + return Calendar::sortJournals(d->castIncidenceList<Journal>(d->mIncidences[Incidence::TypeJournal]), sortField, sortDirection); } Journal::List MemoryCalendar::deletedJournals(JournalSortField sortField, @@ -815,46 +744,24 @@ return Journal::List(); } - Journal::List journalList; - journalList.reserve(d->mDeletedIncidences[Incidence::TypeJournal].count()); - QHashIterator<QString, Incidence::Ptr>i(d->mDeletedIncidences[Incidence::TypeJournal]); - while (i.hasNext()) { - i.next(); - journalList.append(i.value().staticCast<Journal>()); - } - return Calendar::sortJournals(journalList, sortField, sortDirection); + return Calendar::sortJournals(d->castIncidenceList<Journal>(d->mDeletedIncidences[Incidence::TypeJournal]), sortField, sortDirection); } Journal::List MemoryCalendar::journalInstances(const Incidence::Ptr &journal, JournalSortField sortField, SortDirection sortDirection) const { - Journal::List list; - - Incidence::List values = ::values(d->mIncidences[Incidence::TypeJournal], journal->uid()); - for (auto it = values.constBegin(); it != values.constEnd(); ++it) { - Journal::Ptr j = (*it).staticCast<Journal>(); - if (j->hasRecurrenceId()) { - list.append(j); - } - } - return Calendar::sortJournals(list, sortField, sortDirection); + return Calendar::sortJournals(d->incidenceInstances<Journal>(Incidence::TypeJournal, journal), sortField, sortDirection); } Journal::List MemoryCalendar::rawJournalsForDate(const QDate &date) const { Journal::List journalList; - Journal::Ptr j; - QString dateStr = date.toString(); - QMultiHash<QString, IncidenceBase::Ptr >::const_iterator it = - d->mIncidencesForDate[Incidence::TypeJournal].constFind(dateStr); - - while (it != d->mIncidencesForDate[Incidence::TypeJournal].constEnd() && it.key() == dateStr) { - j = it.value().staticCast<Journal>(); - journalList.append(j); - ++it; - } + d->forIncidences<Journal>(d->mIncidencesForDate[Incidence::TypeJournal], date, [&journalList](const Journal::Ptr &journal) { + journalList.append(journal); + }); + return journalList; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcalendarcore-5.64.0/src/memorycalendar.h new/kcalendarcore-5.65.0/src/memorycalendar.h --- old/kcalendarcore-5.64.0/src/memorycalendar.h 2019-11-02 12:42:22.000000000 +0100 +++ new/kcalendarcore-5.65.0/src/memorycalendar.h 2019-12-07 20:41:23.000000000 +0100 @@ -72,6 +72,11 @@ void close() override; /** + @copydoc Calendar::doSetTimeZone() + */ + void doSetTimeZone(const QTimeZone &timeZone) override; + + /** @copydoc Calendar::deleteIncidence() */ bool deleteIncidence(const Incidence::Ptr &incidence) override;
