Commit d2a82eae authored by Damien Caliste's avatar Damien Caliste

Use the recurrenceId to delete the right occurrence.

parent 27f6d544
......@@ -404,3 +404,47 @@ void MemoryCalendarTest::testRawEvents()
cal->close();
}
void MemoryCalendarTest::testDeleteIncidence()
{
MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc()));
Event::Ptr event = Event::Ptr(new Event());
event->setDtStart(QDateTime(QDate(2021, 1, 4), QTime(10, 13),
QTimeZone("Europe/Paris")));
QVERIFY(cal->addEvent(event));
QVERIFY(cal->instance(event->instanceIdentifier()));
QVERIFY(cal->deleteIncidence(event));
QVERIFY(cal->instance(event->instanceIdentifier()).isNull());
event->recurrence()->setDaily(1);
event->recurrence()->setDuration(3);
QVERIFY(cal->addEvent(event));
QVERIFY(cal->instance(event->instanceIdentifier()));
Event::Ptr exception = Event::Ptr(event->clone());
exception->recurrence()->clear();
exception->setRecurrenceId(event->dtStart().addDays(1));
exception->setDtStart(event->dtStart().addDays(1).addSecs(3600));
QVERIFY(cal->addEvent(exception));
QVERIFY(cal->instance(exception->instanceIdentifier()));
Event::Ptr exception2 = Event::Ptr(event->clone());
exception2->recurrence()->clear();
exception2->setRecurrenceId(event->dtStart().addDays(2));
exception2->setDtStart(event->dtStart().addDays(2).addSecs(-3600));
QVERIFY(cal->addEvent(exception2));
QVERIFY(cal->instance(exception2->instanceIdentifier()));
QVERIFY(cal->deleteIncidence(exception));
QVERIFY(cal->incidence(event->uid(), exception->recurrenceId()).isNull());
QVERIFY(!cal->deleteIncidence(exception));
QVERIFY(cal->incidence(event->uid(), exception2->recurrenceId()));
QVERIFY(cal->incidence(event->uid()));
QVERIFY(cal->deleteIncidence(event));
QVERIFY(cal->incidence(event->uid(), exception2->recurrenceId()).isNull());
QVERIFY(cal->incidence(event->uid()).isNull());
}
......@@ -26,6 +26,7 @@ private Q_SLOTS:
void testRawEvents();
void testRawEventsForDate();
void testVisibility();
void testDeleteIncidence();
};
#endif
......@@ -89,6 +89,10 @@ public:
IncidenceBase::IncidenceType type,
const QDateTime &recurrenceId = {}) const;
bool deleteIncidence(const QString &uid,
IncidenceBase::IncidenceType type,
const QDateTime &recurrenceId = {});
Incidence::Ptr deletedIncidence(const QString &uid,
const QDateTime &recurrenceId,
IncidenceBase::IncidenceType type) const;
......@@ -209,54 +213,74 @@ bool MemoryCalendar::deleteIncidence(const Incidence::Ptr &incidence)
// relations is an Incidence's property, not a Todo's, so
// we remove relations in deleteIncidence, not in deleteTodo.
removeRelations(incidence);
// Notify while the incidence is still available,
// this is necessary so korganizer still has time to query for exceptions
notifyIncidenceAboutToBeDeleted(incidence);
const Incidence::IncidenceType type = incidence->type();
const QString uid = incidence->uid();
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].erase(incidenceIt);
d->mIncidencesByIdentifier.remove(incidence->instanceIdentifier());
const QString &uid = incidence->uid();
bool deleted = d->deleteIncidence(uid, type, incidence->recurrenceId());
if (deleted) {
setModified(true);
if (deletionTracking()) {
d->mDeletedIncidences[type].insert(uid, incidence);
}
const QDateTime dt = incidence->dateTime(Incidence::RoleCalendarHashing);
if (dt.isValid()) {
d->mIncidencesForDate[type].remove(dt.toTimeZone(timeZone()).date(), incidence);
}
// Delete child-incidences.
if (!incidence->hasRecurrenceId()) {
if (!incidence->hasRecurrenceId() && incidence->recurs()) {
deleteIncidenceInstances(incidence);
}
notifyIncidenceDeleted(incidence);
return true;
} else {
qCWarning(KCALCORE_LOG) << incidence->typeStr() << " not found. uid=" << uid;
return false;
}
notifyIncidenceDeleted(incidence);
return deleted;
}
bool MemoryCalendar::deleteIncidenceInstances(const Incidence::Ptr &incidence)
{
d->forIncidences<Incidence>(d->mIncidences[incidence->type()], incidence->uid(), [this](const Incidence::Ptr &incidence) {
if (incidence->hasRecurrenceId()) {
Incidence::List instances;
for (auto it = d->mIncidences[incidence->type()].constFind(incidence->uid()), end = d->mIncidences[incidence->type()].constEnd(); it != end && it.key() == incidence->uid(); ++it) {
if (it.value()->hasRecurrenceId()) {
qCDebug(KCALCORE_LOG) << "deleting child"
<< ", type=" << int(incidence->type())
<< ", uid=" << incidence->uid()
// << ", start=" << i->dtStart()
<< " from calendar";
deleteIncidence(incidence);
// Don't call deleteIncidence() now since it's modifying the
// mIncidences map we're iterating over.
instances.append(it.value());
}
});
}
for (Incidence::Ptr instance : instances) {
deleteIncidence(instance);
}
return true;
}
//@cond PRIVATE
bool MemoryCalendar::Private::deleteIncidence(const QString &uid,
IncidenceBase::IncidenceType type,
const QDateTime &recurrenceId)
{
for (auto it = mIncidences[type].find(uid), end = mIncidences[type].end(); it != end && it.key() == uid; ++it) {
Incidence::Ptr incidence = it.value();
if (recurrenceId.isNull() && incidence->hasRecurrenceId()) {
continue;
} else if (!recurrenceId.isNull() && (!incidence->hasRecurrenceId() || recurrenceId != incidence->recurrenceId())) {
continue;
}
mIncidences[type].erase(it);
mIncidencesByIdentifier.remove(incidence->instanceIdentifier());
const QDateTime dt = incidence->dateTime(Incidence::RoleCalendarHashing);
if (dt.isValid()) {
mIncidencesForDate[type].remove(dt.toTimeZone(q->timeZone()).date(), incidence);
}
return true;
}
return false;
}
void MemoryCalendar::Private::deleteAllIncidences(Incidence::IncidenceType incidenceType)
{
for (auto &incidence : mIncidences[incidenceType]) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment