diff --git a/akonadi/calendar/calendarbase.cpp b/akonadi/calendar/calendarbase.cpp index e544b4e47..753cf3ca9 100644 --- a/akonadi/calendar/calendarbase.cpp +++ b/akonadi/calendar/calendarbase.cpp @@ -1,702 +1,702 @@ /* 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 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(); } 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 { 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; } const QString calendar = QString::number(item.storageCollectionId()); const QString uniqueInstanceIdentifier = calendar + incidence->instanceIdentifier(); if (mItemIdByUniqueInstanceIdentifier.contains(uniqueInstanceIdentifier) && mItemIdByUniqueInstanceIdentifier[uniqueInstanceIdentifier] != 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]; 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(); if (collection.isValid()) { // Some items don't have collection set if (item.storageCollectionId() != collection.id() && item.storageCollectionId() > -1) { if (mCollections.contains(item.storageCollectionId())) { collection = mCollections.value(item.storageCollectionId()); incidence->setReadOnly(!(collection.rights() & Akonadi::Collection::CanChangeItem)); } else if (!mCollectionJobs.key(item.storageCollectionId())) { collection = Akonadi::Collection(item.storageCollectionId()); Akonadi::CollectionFetchJob *job = new Akonadi::CollectionFetchJob(collection, Akonadi::CollectionFetchJob::Base, this); connect(job, SIGNAL(result(KJob*)), this, SLOT(collectionFetchResult(KJob*))); mCollectionJobs.insert(job, collection.id()); } } else { mCollections.insert(collection.id(), collection); incidence->setReadOnly(!(collection.rights() & Akonadi::Collection::CanChangeItem)); } } mItemById.insert(item.id(), item); mItemIdByUniqueInstanceIdentifier.insert(uniqueInstanceIdentifier, item.id()); mItemsByCollection.insert(item.storageCollectionId(), item); incidence->setCustomProperty("VOLATILE", "AKONADI-ID", QString::number(item.id())); // 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::collectionFetchResult(KJob* job) { Akonadi::Collection::Id colid = mCollectionJobs.take(job); if ( job->error() ) { qDebug() << "Error occurred"; return; } Akonadi::CollectionFetchJob *fetchJob = qobject_cast( job ); const Akonadi::Collection collection = fetchJob->collections().first(); if (collection.id() != colid) { kError() << "Fetched the wrong collection, should fetch: " << colid << "fetched: " << collection.id(); } bool isReadOnly = !(collection.rights() & Akonadi::Collection::CanChangeItem); foreach (const Akonadi::Item &item, mItemsByCollection.values(collection.id())) { KCalCore::Incidence::Ptr incidence = CalendarUtils::incidence(item); incidence->setReadOnly(isReadOnly); } mCollections.insert(collection.id(), collection); if (mCollectionJobs.count() == 0) { emit fetchFinished(); } } 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); const QString 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) { mItemById.remove(item.id()); // kDebug() << "Deleting incidence from calendar .id=" << item.id() << "uid=" << incidence->uid(); mItemIdByUniqueInstanceIdentifier.remove(uniqueInstanceIdentifier); mItemsByCollection.remove(item.storageCollectionId(), item); // Must be the last one due to re-entrancy // 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); } } 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.storageCollectionId()); // 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.storageCollectionId()); 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) << "; 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.id()); // 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"; Q_ASSERT(false); 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.storageCollectionId()); 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)) { const Akonadi::Item::Id id = mItemIdByUniqueInstanceIdentifier.value(uniqueInstanceIdentifier); if (!mItemById.contains(id)) { kError() << "Item with id " << id << "(uid=" << uniqueInstanceIdentifier << ") not found, but in uid map"; Q_ASSERT_X(false, "CalendarBase::item", "not in mItemById"); } i = mItemById[id]; } 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)) { const Akonadi::Item item = d->mItemById.value(parentId); Q_ASSERT(item.isValid()); KCalCore::Incidence::Ptr parent = CalendarUtils::incidence(item); const QString calendar = QString::number(item.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); Q_ASSERT(item.isValid()); const QString calendar = QString::number(item.storageCollectionId()); Akonadi::Item::List children; KCalCore::Incidence::List incidences = childIncidences(parentId); Q_FOREACH (const KCalCore::Incidence::Ptr &inc, incidences) { children << d->mItemById.value(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) { - Q_ASSERT(false); - return false; + //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 item_ = item(incidence); return -1 != d->mIncidenceChanger->deleteIncidence(item_); } 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"