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;


Reply via email to