Sophie

Sophie

distrib > Mageia > 5 > i586 > by-pkgid > ddfeee3bedf84e44f20049fdcc070a8a > files > 48

kdepimlibs4-4.14.10-2.2.mga5.src.rpm

From d3b66dea473ab84fee48fb901318879328c77fc7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Vr=C3=A1til?= <daniel.vratil@kdab.com>
Date: Thu, 19 Jan 2017 11:28:19 +0100
Subject: [PATCH 47/47] Improve handling of identical events from multiple
 calendars

This addresses some issues introduced in commit 5e7ae1a7c that
caused events to disappear from Agenda view in KOrganizer after
editing and broke removing of events ther as well.

The main issue in both cases was that KCalCore::Calendar assumes
that UID is always unique (as it should be), so if we have multiple
incidences with the same UID in the calendar, we have no guarantee
that KCalCore::Calendar::incidence gives us the one that we actually
want, so we need to workaround that and provide some additional
metadata that the higher-level subclases (ETMCalendar and CalendarBase)
understand and handle notifications ourselves.
---
 akonadi/calendar/calendarbase.cpp |  5 ++++-
 akonadi/calendar/etmcalendar.cpp  | 19 ++++++++++++++++---
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/akonadi/calendar/calendarbase.cpp b/akonadi/calendar/calendarbase.cpp
index 9ca58009f..97bb5285c 100644
--- a/akonadi/calendar/calendarbase.cpp
+++ b/akonadi/calendar/calendarbase.cpp
@@ -149,8 +149,11 @@ void CalendarBasePrivate::internalRemove(const Akonadi::Item &item)
         return;
     }
 
+    tmp->setCustomProperty("VOLATILE", "AKONADI-ID", QString::number(item.id()));
+    tmp->setCustomProperty("VOLATILE", "COLLECTION-ID", QString::number(item.storageCollectionId()));
     // We want the one stored in the calendar
-    Incidence::Ptr incidence = q->incidence(tmp->uid(), tmp->recurrenceId());
+    const Akonadi::Item storedItem = q->item(tmp);
+    const Incidence::Ptr incidence = CalendarUtils::incidence(storedItem);
 
     // Null incidence means it was deleted via CalendarBase::deleteIncidence(), but then
     // the ETMCalendar received the monitor notification and tried to delete it again.
diff --git a/akonadi/calendar/etmcalendar.cpp b/akonadi/calendar/etmcalendar.cpp
index f0003e4e4..56341667e 100644
--- a/akonadi/calendar/etmcalendar.cpp
+++ b/akonadi/calendar/etmcalendar.cpp
@@ -407,7 +407,13 @@ void ETMCalendarPrivate::updateItem(const Akonadi::Item &item)
     Q_ASSERT(newIncidence);
     Q_ASSERT(!newIncidence->uid().isEmpty());
     newIncidence->setCustomProperty("VOLATILE", "AKONADI-ID", QString::number(item.id()));
-    IncidenceBase::Ptr existingIncidence = q->incidence(newIncidence->uid(), newIncidence->recurrenceId());
+    newIncidence->setCustomProperty("VOLATILE", "COLLECTION-ID", QString::number(item.storageCollectionId()));
+
+    const Akonadi::Item existingItem = q->item(newIncidence);
+    IncidenceBase::Ptr existingIncidence;
+    if (existingItem.isValid()) {
+        existingIncidence = CalendarUtils::incidence(existingItem);
+    }
 
     if (!existingIncidence && !mItemById.contains(item.id())) {
         // We don't know about this one because it was discarded, for example because of not having DTSTART
@@ -415,7 +421,6 @@ void ETMCalendarPrivate::updateItem(const Akonadi::Item &item)
     }
 
     mItemsByCollection.insert(item.storageCollectionId(), item);
-    Akonadi::Item oldItem = mItemById.value(item.id());
 
     if (existingIncidence) {
         // We set the payload so that the internal incidence pointer and the one in mItemById stay the same
@@ -425,11 +430,19 @@ void ETMCalendarPrivate::updateItem(const Akonadi::Item &item)
 
         // Check if RELATED-TO changed, updating parenting information
         handleParentChanged(newIncidence);
+        // KCalCore::IncidenceBase::operator=() triggers notification to all observers.
+        // However since KCalCore does not support multiple incidences with the same UID,
+        // the change notification delivered by KCalCore can have a wrong incidence.
+        // To workaround that we emit the notification ourselves and with the correct
+        // incidence.
+        q->setObserversEnabled(false);
         *(existingIncidence.data()) = *(newIncidence.data());
+        q->setObserversEnabled(true);
+        q->notifyIncidenceChanged(existingIncidence.staticCast<KCalCore::Incidence>());
     } else {
         mItemById.insert(item.id(), item);   // The item needs updating too, revision changed.
         // The item changed it's UID, update our maps, the Google resource changes the UID when we create incidences.
-        handleUidChange(oldItem, item, newIncidence->instanceIdentifier());
+        handleUidChange(existingItem, item, newIncidence->instanceIdentifier());
     }
 }
 
-- 
2.14.1