diff --git a/akonadi/calendar/calendarbase.cpp b/akonadi/calendar/calendarbase.cpp index 4df5c21f9..05a124288 100644 --- a/akonadi/calendar/calendarbase.cpp +++ b/akonadi/calendar/calendarbase.cpp @@ -1,735 +1,732 @@ /* Copyright (C) 2011 Sérgio Martins Copyright (C) 2012 Sérgio Martins This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "calendarbase.h" #include "calendarbase_p.h" #include "incidencechanger.h" #include "utils_p.h" #include #include #include #include #include #include #include using namespace Akonadi; using namespace KCalCore; MultiCalendar::MultiCalendar(const KTimeZone &tz) : KCalCore::MemoryCalendar(tz) { } void MultiCalendar::addParentInformation(const KCalCore::Incidence::Ptr &inc, const KCalCore::Incidence::Ptr &parentIncidence) { mChildrenByIncidence[parentIncidence].append(inc); mParentByIncidence.insert(inc, parentIncidence); } void MultiCalendar::cleanupParentInformation(const KCalCore::Incidence::Ptr &inc) { if (KCalCore::Incidence::Ptr parentIncidence = mParentByIncidence.value(inc)) { mChildrenByIncidence[parentIncidence].remove(mChildrenByIncidence[parentIncidence].indexOf(inc)); mParentByIncidence.remove(inc); } } void MultiCalendar::incidenceUpdated(KCalCore::IncidenceBase *ptr) { Incidence::Ptr inc = KCalCore::MemoryCalendar::incidence(ptr); if (inc) { if (!inc->relatedTo().isEmpty()) { //Check if current parent still corresponds to relatedTo KCalCore::Incidence::Ptr parentIncidence = mParentByIncidence.value(inc); if (parentIncidence && parentIncidence->uid() != inc->relatedTo()) { cleanupParentInformation(inc); addParentInformation(inc, incidence(calendar(inc), inc->relatedTo())); } } } MemoryCalendar::incidenceUpdated(ptr); } bool MultiCalendar::addIncidenceToCalendar(const QString &calendar, const KCalCore::Incidence::Ptr &inc) { if (!mIncidenceByCalendar.values(calendar).contains(inc)) { mIncidenceByCalendar.insert(calendar, inc); mCalendarByIncidence.insert(inc, calendar); if (!inc->relatedTo().isEmpty()) { KCalCore::Incidence::Ptr parentIncidence = incidence(calendar, inc->relatedTo()); if (parentIncidence) { addParentInformation(inc, parentIncidence); } } MemoryCalendar::addIncidence(inc); } return true; } bool MultiCalendar::deleteIncidenceFromCalendar(const QString &calendar, const KCalCore::Incidence::Ptr &inc) { MemoryCalendar::deleteIncidence(inc); mIncidenceByCalendar.remove(calendar, inc); mCalendarByIncidence.remove(inc); cleanupParentInformation(inc); return true; } QString MultiCalendar::realUid(const KCalCore::Incidence::Ptr &incidence) const { return calendar(incidence) + incidence->uid(); } QString MultiCalendar::realIdentifier(const KCalCore::Incidence::Ptr &incidence) const { return calendar(incidence) + incidence->instanceIdentifier(); } KCalCore::Incidence::List MultiCalendar::incidencesFromCalendar(const QString &calendar) const { return mIncidenceByCalendar.values(calendar).toVector(); } KCalCore::Incidence::Ptr MultiCalendar::incidence(const QString &calendar, const QString &uid, const KDateTime &recurrenceId) const { Q_FOREACH (const KCalCore::Incidence::Ptr &inc, mIncidenceByCalendar.values(calendar)) { if (inc->uid() == uid && ((recurrenceId.isNull() && !inc->recurrenceId().isValid()) || recurrenceId == inc->recurrenceId())) { return inc; } } return KCalCore::Incidence::Ptr(); } KCalCore::Incidence::List MultiCalendar::incidenceExceptions(const KCalCore::Incidence::Ptr &incidence) const { KCalCore::Incidence::List instances; Q_FOREACH (const KCalCore::Incidence::Ptr &inc, mIncidenceByCalendar.values(calendar(incidence))) { if (inc->uid() == incidence->uid() && inc->recurrenceId().isValid()) { instances << inc; } } return instances; } QStringList MultiCalendar::calendars(const QString &uid, const KDateTime &recurrenceId) const { QStringList calendars; Q_FOREACH (const QString &cal, mIncidenceByCalendar.uniqueKeys()) { if (incidence(cal, uid, recurrenceId)) { calendars << cal; } } return calendars; } QString MultiCalendar::calendar(const KCalCore::Incidence::Ptr &incidence) const { if (!mCalendarByIncidence.contains(incidence)) { kWarning() << "The incidence is no longer in this calenar: " << incidence->instanceIdentifier() << incidence; kWarning() << mCalendarByIncidence; } Q_ASSERT(mCalendarByIncidence.contains(incidence)); return mCalendarByIncidence.value(incidence); } QString MultiCalendar::uniqueInstanceIdentifier(const KCalCore::Incidence::Ptr &incidence) const { return calendar(incidence) + incidence->instanceIdentifier(); } KCalCore::Incidence::List MultiCalendar::childIncidences(const KCalCore::Incidence::Ptr &incidence) const { // Q_ASSERT(mChildrenByIncidence.contains(incidence)); return mChildrenByIncidence.value(incidence); } static QString itemToString(const Akonadi::Item &item) { const KCalCore::Incidence::Ptr &incidence = CalendarUtils::incidence(item); QString str; QTextStream stream(&str); stream << item.id() << "; summary=" << incidence->summary() << "; uid=" << incidence->uid() << "; type=" << incidence->type() << "; recurs=" << incidence->recurs() << "; recurrenceId=" << incidence->recurrenceId().toString() << "; dtStart=" << incidence->dtStart().toString() << "; dtEnd=" << incidence->dateTime(Incidence::RoleEnd).toString() << "; parentCollection=" << item.storageCollectionId() << item.parentCollection().displayName(); return str; } CalendarBasePrivate::CalendarBasePrivate(CalendarBase *qq) : QObject() , mIncidenceChanger(new IncidenceChanger()) , mBatchInsertionCancelled(false) , mListensForNewItems(false) , mLastCreationCancelled(false) , q(qq) { connect(mIncidenceChanger, SIGNAL(createFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)), SLOT(slotCreateFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString))); connect(mIncidenceChanger, SIGNAL(deleteFinished(int,QVector,Akonadi::IncidenceChanger::ResultCode,QString)), SLOT(slotDeleteFinished(int,QVector,Akonadi::IncidenceChanger::ResultCode,QString))); connect(mIncidenceChanger, SIGNAL(modifyFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)), SLOT(slotModifyFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString))); mIncidenceChanger->setDestinationPolicy(IncidenceChanger::DestinationPolicyAsk); mIncidenceChanger->setGroupwareCommunication(false); mIncidenceChanger->setHistoryEnabled(false); } CalendarBasePrivate::~CalendarBasePrivate() { delete mIncidenceChanger; mIncidenceChanger = 0; } void CalendarBasePrivate::internalInsert(const Akonadi::Item &item) { Q_ASSERT(item.isValid()); Q_ASSERT(item.hasPayload()); KCalCore::Incidence::Ptr incidence = CalendarUtils::incidence(item); Q_ASSERT(item.storageCollectionId() > 0); if (!incidence) { kError() << "Incidence is null. id=" << item.id() << "; hasPayload()=" << item.hasPayload() << "; has incidence=" << item.hasPayload() << "; mime type=" << item.mimeType(); Q_ASSERT(false); return; } //kDebug() << "Inserting incidence in calendar. id=" << item.id() << "uid=" << incidence->uid(); if (incidence->uid().isEmpty()) { // This code path should never happen kError() << "Incidence has empty UID. id=" << item.id() << "; summary=" << incidence->summary() << "Please fix it. Ignoring this incidence."; return; } //If the parentCollection is invalid the model will be inconsistent Q_ASSERT(item.parentCollection().isValid()); if (!item.parentCollection().isValid()) { // This code path should never happen kError() << "Incidence has an invalid parentCollection. id=" << item.id() << "; uid=" << incidence->uid() << "; summary=" << incidence->summary() << "Please fix it. Ignoring this incidence."; return; } - const QString calendar = QString::number(item.parentCollection().id()); + QString calendar = QString::number(item.parentCollection().id()); + + // With virtual collections, it can happen, that we have exceptions in other calendars that the mainevent. + // For displaying all exceptions, we have to save them also in storage collection to have a unified way to get all exceptions. + if ((item.parentCollection().id() != item.storageCollectionId()) && (incidence->hasRecurrenceId() || incidence->recurs())) { + calendar = QString::number(item.storageCollectionId()); + } Q_ASSERT(!calendar.isEmpty()); + const QString uniqueInstanceIdentifier = calendar + incidence->instanceIdentifier(); if (mItemIdByUniqueInstanceIdentifier.contains(uniqueInstanceIdentifier) && mItemIdByUniqueInstanceIdentifier[uniqueInstanceIdentifier].id() != item.id()) { // We only allow duplicate UIDs if they have the same item id, for example // when using virtual folders. kWarning() << "Discarding duplicate incidence with instanceIdentifier=" << uniqueInstanceIdentifier << "and summary " << incidence->summary() << "; recurrenceId() =" << incidence->recurrenceId() << "; new id=" << item.id() << "; existing id=" << mItemIdByUniqueInstanceIdentifier[uniqueInstanceIdentifier].id(); return; } if (incidence->type() == KCalCore::Incidence::TypeEvent && !incidence->dtStart().isValid()) { // TODO: make the parser discard them would also be a good idea kWarning() << "Discarding event with invalid DTSTART. identifier=" << incidence->instanceIdentifier() << "; summary=" << incidence->summary(); return; } Akonadi::Collection collection = item.parentCollection(); Q_ASSERT(collection.isValid()); if (item.storageCollectionId() != collection.id() && item.storageCollectionId() > -1) { mItemsByCollection.insert(item.storageCollectionId(), item); } mItemById.insert(item.id(), item); mItemIdByUniqueInstanceIdentifier.insert(uniqueInstanceIdentifier, item); mItemsByCollection.insert(item.parentCollection().id(), item); incidence->interceptUpdates(); incidence->setCustomProperty("VOLATILE", "AKONADI-ID", QString::number(item.id())); incidence->cancelUpdates(); - // With virtual collections, it can happen, that we have exceptions in other calendars that the mainevent. - // For displaying all exceptions, we have to save them also in storage collection to have a unified way to get all exceptions. - if ((item.parentCollection().id() != item.storageCollectionId()) && (incidence->hasRecurrenceId() || incidence->recurs())) { - const bool result = q->MultiCalendar::addIncidenceToCalendar(QString::number(item.storageCollectionId()), incidence); - if (!result) { - kError() << "Error adding incidence " << itemToString(item); - Q_ASSERT(false); - } - } else { - // Must be the last one due to re-entrancy - const bool result = q->MultiCalendar::addIncidenceToCalendar(calendar, incidence); - if (!result) { - kError() << "Error adding incidence " << itemToString(item); - Q_ASSERT(false); - } + // Must be the last one due to re-entrancy + const bool result = q->MultiCalendar::addIncidenceToCalendar(calendar, incidence); + if (!result) { + kError() << "Error adding incidence " << itemToString(item); + Q_ASSERT(false); } } void CalendarBasePrivate::internalRemove(const Akonadi::Item &item) { Q_ASSERT(item.isValid()); Incidence::Ptr tmp = CalendarUtils::incidence(item); if (!tmp) { kError() << "CalendarBase::internalRemove1: incidence is null, item.id=" << item.id(); return; } Q_ASSERT(item.storageCollectionId() > 0); QString calendar = QString::number(item.parentCollection().id()); if ((item.parentCollection().id() != item.storageCollectionId()) && (tmp->hasRecurrenceId() || tmp->recurs())) { calendar = QString::number(item.storageCollectionId()); } const QString uniqueInstanceIdentifier = calendar + tmp->instanceIdentifier(); // We want the one stored in the calendar Incidence::Ptr incidence = q->incidence(calendar, tmp->uid(), tmp->recurrenceId()); // Null incidence means it was deleted via CalendarBase::deleteIncidence(), but then // the ETMCalendar received the monitor notification and tried to delete it again. if (incidence) { // kDebug() << "Deleting incidence from calendar .id=" << item.id() << "uid=" << incidence->instanceIdentifier(); // This will trigger the removal of all exceptions via deleteIncidence const bool result = q->MultiCalendar::deleteIncidenceFromCalendar(calendar, incidence); if (!result) { kError() << "Error removing incidence " << itemToString(item); Q_ASSERT(false); } mItemIdByUniqueInstanceIdentifier.remove(uniqueInstanceIdentifier); mItemsByCollection.remove(item.parentCollection().id(), item); if (item.storageCollectionId() != item.parentCollection().id()) { mItemsByCollection.remove(item.storageCollectionId(), item); } // only remove ItemById entry if all incidences are deleted // we need item in storageCollection, to find exceptions if (mItemIdByUniqueInstanceIdentifier.key(item, QString()).isEmpty()) { mItemById.remove(item.id()); } } else { kWarning() << "CalendarBase::internalRemove2: incidence is null, item.id=" << itemToString(item); } } void CalendarBasePrivate::deleteAllIncidencesOfType(const QString &mimeType) { kWarning() << "Refusing to delete your Incidences."; Q_UNUSED(mimeType); /* QHash::iterator i; Item::List incidences; for ( i = mItemById.begin(); i != mItemById.end(); ++i ) { if ( i.value().payload()->mimeType() == mimeType ) incidences.append( i.value() ); } mIncidenceChanger->deleteIncidences( incidences ); */ } void CalendarBasePrivate::slotDeleteFinished(int changeId, const QVector &itemIds, IncidenceChanger::ResultCode resultCode, const QString &errorMessage) { Q_UNUSED(changeId); if (resultCode == IncidenceChanger::ResultCodeSuccess) { foreach(const Akonadi::Item::Id &id, itemIds) { if (mItemById.contains(id)) internalRemove(mItemById.value(id)); } } emit q->deleteFinished(resultCode == IncidenceChanger::ResultCodeSuccess, errorMessage); } void CalendarBasePrivate::slotCreateFinished(int changeId, const Akonadi::Item &item, IncidenceChanger::ResultCode resultCode, const QString &errorMessage) { Q_UNUSED(changeId); Q_UNUSED(item); if (resultCode == IncidenceChanger::ResultCodeSuccess && !mListensForNewItems) { Q_ASSERT(item.isValid()); Q_ASSERT(item.hasPayload()); //FIXME fetch, otherwise we don't have the storageCollectionId internalInsert(item); } mLastCreationCancelled = (resultCode == IncidenceChanger::ResultCodeUserCanceled); emit q->createFinished(resultCode == IncidenceChanger::ResultCodeSuccess, errorMessage); } void CalendarBasePrivate::slotModifyFinished(int changeId, const Akonadi::Item &item, IncidenceChanger::ResultCode resultCode, const QString &errorMessage) { Q_UNUSED(changeId); Q_UNUSED(item); QString message = errorMessage; if (resultCode == IncidenceChanger::ResultCodeSuccess) { KCalCore::Incidence::Ptr incidence = CalendarUtils::incidence(item); Q_ASSERT(incidence); Q_ASSERT(item.storageCollectionId() > 0); const QString calendar = QString::number(item.parentCollection().id()); // We want the one stored in the calendar KCalCore::Incidence::Ptr localIncidence = q->incidence(calendar, incidence->uid(), incidence->recurrenceId()); if (localIncidence) { //update our local one *(static_cast(localIncidence.data())) = *(incidence.data()); } else { // This shouldn't happen, unless the incidence gets deleted between event loops kWarning() << "CalendarBasePrivate::slotModifyFinished() Incidence was deleted already probably? id=" << item.id(); message = i18n("Could not find incidence to update, it probably was deleted recently."); resultCode = IncidenceChanger::ResultCodeAlreadyDeleted; } } emit q->modifyFinished(resultCode == IncidenceChanger::ResultCodeSuccess, message); } void CalendarBasePrivate::handleUidChange(const Akonadi::Item &oldItem, const Akonadi::Item &newItem) { Q_ASSERT(oldItem.isValid()); Incidence::Ptr newIncidence = CalendarUtils::incidence(newItem); Q_ASSERT(newIncidence); Incidence::Ptr oldIncidence = CalendarUtils::incidence(oldItem); Q_ASSERT(oldIncidence); const QString calendar = QString::number(newItem.parentCollection().id()); const QString uniqueInstanceIdentifier = calendar + newIncidence->instanceIdentifier(); if (mItemIdByUniqueInstanceIdentifier.contains(uniqueInstanceIdentifier)) { Incidence::Ptr oldIncidence = CalendarUtils::incidence(oldItem); kWarning() << "New uid shouldn't be known: " << uniqueInstanceIdentifier << "; id=" << newItem.id() << "; oldItem.id=" << mItemIdByUniqueInstanceIdentifier.value(uniqueInstanceIdentifier).id() << "; new summary= " << newIncidence->summary() << "; new recurrenceId=" << newIncidence->recurrenceId() << "; oldIncidence" << oldIncidence; if (oldIncidence) { kWarning() << "; oldIncidence uid=" << oldIncidence->uid() << "; oldIncidence recurrenceId = " << oldIncidence->recurrenceId() << "; oldIncidence summary = " << oldIncidence->summary(); } Q_ASSERT(false); return; } mItemIdByUniqueInstanceIdentifier.insert(uniqueInstanceIdentifier, newItem); // Get the real pointer oldIncidence = q->MultiCalendar::incidence(calendar, oldIncidence->uid(), oldIncidence->recurrenceId()); if (!oldIncidence) { // How can this happen ? kWarning() << "Couldn't find old incidence"; return; } if (q->realIdentifier(newIncidence) == q->realIdentifier(oldIncidence)) { kWarning() << "New uid=" << newIncidence->uid() << "; old uid=" << oldIncidence->uid() << "; new recurrenceId=" << newIncidence->recurrenceId() << "; old recurrenceId=" << oldIncidence->recurrenceId() << "; new summary = " << newIncidence->summary() << "; old summary = " << oldIncidence->summary() << "; id = " << newItem.id(); Q_ASSERT(false); // The reason we're here in the first place return; } const QString oldCalendar = QString::number(oldItem.parentCollection().id()); const QString oldUniqueInstanceIdentifier = oldCalendar + oldIncidence->instanceIdentifier(); mItemIdByUniqueInstanceIdentifier.remove(oldUniqueInstanceIdentifier); const QString oldUid = oldIncidence->uid(); // Update internal maps of the base class, MemoryCalendar q->setObserversEnabled(false); q->MultiCalendar::deleteIncidenceFromCalendar(calendar, oldIncidence); q->MultiCalendar::addIncidenceToCalendar(calendar, newIncidence); const QString newUid = newIncidence->uid(); newIncidence->setUid(oldUid); // We set and unset just to notify observers of a change. q->setObserversEnabled(true); newIncidence->setUid(newUid); } CalendarBase::CalendarBase(QObject *parent) : MultiCalendar(KSystemTimeZones::local()) , d_ptr(new CalendarBasePrivate(this)) { setParent(parent); setDeletionTracking(false); } CalendarBase::CalendarBase(CalendarBasePrivate *const dd, QObject *parent) : MultiCalendar(KSystemTimeZones::local()) , d_ptr(dd) { setParent(parent); setDeletionTracking(false); } CalendarBase::~CalendarBase() { } Akonadi::Item CalendarBase::item(Akonadi::Item::Id id) const { Q_D(const CalendarBase); Akonadi::Item i; if (d->mItemById.contains(id)) { i = d->mItemById[id]; } else { kDebug() << "Can't find any item with id " << id; } return i; } Akonadi::Item CalendarBasePrivate::item(const QString &uniqueInstanceIdentifier) const { Akonadi::Item i; if (uniqueInstanceIdentifier.isEmpty()) return i; if (mItemIdByUniqueInstanceIdentifier.contains(uniqueInstanceIdentifier)) { i = mItemIdByUniqueInstanceIdentifier.value(uniqueInstanceIdentifier); } else { kDebug() << "Can't find any incidence with uid " << uniqueInstanceIdentifier; } return i; } Item CalendarBase::item(const Incidence::Ptr &incidence) const { Q_D(const CalendarBase); const QString cal = calendar(incidence); Q_ASSERT(!cal.isEmpty()); return incidence ? d->item(cal + incidence->instanceIdentifier()) : Item(); } Akonadi::Item::List CalendarBase::items() const { Q_D(const CalendarBase); return d->mItemById.values(); } Akonadi::Item::List CalendarBase::items(Akonadi::Collection::Id id) const { Q_D(const CalendarBase); return d->mItemsByCollection.values(id); } Akonadi::Item::List CalendarBase::itemList(const KCalCore::Incidence::List &incidences) const { Akonadi::Item::List items; foreach(const KCalCore::Incidence::Ptr &incidence, incidences) { if (incidence) { items << item(incidence); } else { items << Akonadi::Item(); } } return items; } KCalCore::Incidence::List CalendarBase::childIncidences(const Akonadi::Item::Id &parentId) const { Q_D(const CalendarBase); KCalCore::Incidence::List childs; if (d->mItemById.contains(parentId)) { return childIncidences(d->mItemById.value(parentId)); } return childs; } KCalCore::Incidence::List CalendarBase::childIncidences(const Akonadi::Item &parentItem) const { Q_D(const CalendarBase); KCalCore::Incidence::List childs; KCalCore::Incidence::Ptr parent = CalendarUtils::incidence(parentItem); const QString calendar = QString::number(parentItem.storageCollectionId()); if (parent) { childs = MultiCalendar::childIncidences(incidence(calendar, parent->uid(), parent->recurrenceId())); } else { Q_ASSERT(false); } return childs; } Akonadi::Item::List CalendarBase::childItems(const Akonadi::Item::Id &parentId) const { Q_D(const CalendarBase); if (!d->mItemById.contains(parentId)) { kWarning() << "invalid parent " << parentId; Q_ASSERT(false); return Akonadi::Item::List(); } const Akonadi::Item item = d->mItemById.value(parentId); return childItems(item); } Akonadi::Item::List CalendarBase::childItems(const Akonadi::Item &parent) const { Q_D(const CalendarBase); Q_ASSERT(parent.isValid()); const QString calendar = QString::number(parent.storageCollectionId()); Akonadi::Item::List children; KCalCore::Incidence::List incidences = childIncidences(parent); Q_FOREACH (const KCalCore::Incidence::Ptr &inc, incidences) { children << d->mItemIdByUniqueInstanceIdentifier.value(calendar + inc->instanceIdentifier()); } return children; } Akonadi::Item::List CalendarBase::childItems(const Incidence::Ptr &incidence) const { Q_D(const CalendarBase); return childItems(d->mItemIdByUniqueInstanceIdentifier.value(calendar(incidence) + incidence->instanceIdentifier())); } bool CalendarBase::addIncidence(const KCalCore::Incidence::Ptr &incidence) { //Let the incidencechanger decide what collection to use return addIncidence("-1", incidence); } bool CalendarBase::addIncidence(const QString &calendar, const KCalCore::Incidence::Ptr &incidence) { //TODO: Parent for dialogs Q_D(CalendarBase); // User canceled on the collection selection dialog if (batchAdding() && d->mBatchInsertionCancelled) { return false; } d->mLastCreationCancelled = false; Akonadi::Collection collection = Akonadi::Collection(calendar.toLongLong()); const int changeId = d->mIncidenceChanger->createIncidence(incidence, collection); if (batchAdding()) { const Akonadi::Collection lastCollection = d->mIncidenceChanger->lastCollectionUsed(); if (changeId != -1 && !lastCollection.isValid()) { d->mBatchInsertionCancelled = true; } } return changeId != -1; } bool CalendarBase::deleteIncidence(const KCalCore::Incidence::Ptr &incidence) { Q_D(CalendarBase); Q_ASSERT(incidence); Akonadi::Item::List items; items << item(incidence); foreach (const KCalCore::Incidence::Ptr &exception, incidenceExceptions(incidence)) { items << item(exception); } return -1 != d->mIncidenceChanger->deleteIncidences(items); } bool CalendarBase::deleteIncidenceInstances(const KCalCore::Incidence::Ptr &incidence) { //We have to avoid that we actually delete the incidences and make sure only the MemoryCalendar implementation is called foreach (const KCalCore::Incidence::Ptr &exception, incidenceExceptions(incidence)) { MemoryCalendar::deleteIncidence(exception); } return true; } bool CalendarBase::modifyIncidence(const KCalCore::Incidence::Ptr &oldIncidence, const KCalCore::Incidence::Ptr &newIncidence) { Q_D(CalendarBase); Q_ASSERT(oldIncidence); Q_ASSERT(newIncidence); Akonadi::Item item_ = item(oldIncidence); item_.setPayload(newIncidence); return -1 != d->mIncidenceChanger->modifyIncidence(item_); } void CalendarBase::setWeakPointer(const QWeakPointer &pointer) { Q_D(CalendarBase); d->mWeakPointer = pointer; } QWeakPointer CalendarBase::weakPointer() const { Q_D(const CalendarBase); return d->mWeakPointer; } IncidenceChanger* CalendarBase::incidenceChanger() const { Q_D(const CalendarBase); return d->mIncidenceChanger; } void CalendarBase::startBatchAdding() { KCalCore::MemoryCalendar::startBatchAdding(); } void CalendarBase::endBatchAdding() { Q_D(CalendarBase); d->mBatchInsertionCancelled = false; KCalCore::MemoryCalendar::endBatchAdding(); } #include "moc_calendarbase.cpp" #include "moc_calendarbase_p.cpp"