40 using namespace KCalCore;
47 class KCalCore::MemoryCalendar::Private
60 QString mIncidenceBeingUpdated;
66 QMap<IncidenceBase::IncidenceType, QMultiHash<QString, Incidence::Ptr> > mIncidences;
71 QHash<QString,KCalCore::Incidence::Ptr> mIncidencesByIdentifier;
77 QMap<IncidenceBase::IncidenceType, QMultiHash<QString, Incidence::Ptr> > mDeletedIncidences;
90 QMap<IncidenceBase::IncidenceType, QMultiHash<QString, IncidenceBase::Ptr> > mIncidencesForDate;
96 const KDateTime &recurrenceId = KDateTime())
const;
99 const KDateTime &recurrenceId,
135 d->mIncidencesByIdentifier.clear();
136 d->mDeletedIncidences.clear();
150 const QString uid = incidence->uid();
151 if (d->mIncidences[type].remove(uid, incidence)) {
152 d->mIncidencesByIdentifier.remove(incidence->instanceIdentifier());
156 d->mDeletedIncidences[type].insert(uid, incidence);
160 d->mIncidencesForDate[type].remove(dt.date().toString(),
incidence);
163 if (!incidence->hasRecurrenceId()) {
168 kWarning() << incidence->typeStr() <<
" not found.";
176 QList<Incidence::Ptr> values = d->mIncidences[type].values(incidence->uid());
177 QList<Incidence::Ptr>::const_iterator it;
178 for (it = values.constBegin(); it != values.constEnd(); ++it) {
180 if (i->hasRecurrenceId()) {
181 kDebug() <<
"deleting child"
182 <<
", type=" << int(type)
183 <<
", uid=" << i->uid()
184 <<
", start=" << i->dtStart()
196 QHashIterator<QString, Incidence::Ptr>i(mIncidences[incidenceType]);
197 while (i.hasNext()) {
199 q->notifyIncidenceDeleted(i.value());
200 i.value()->unRegisterObserver(q);
202 mIncidences[incidenceType].clear();
203 mIncidencesForDate[incidenceType].clear();
206 Incidence::Ptr MemoryCalendar::Private::incidence(
const QString &uid,
208 const KDateTime &recurrenceId)
const
210 QList<Incidence::Ptr> values = mIncidences[type].values(uid);
211 QList<Incidence::Ptr>::const_iterator it;
212 for (it = values.constBegin(); it != values.constEnd(); ++it) {
214 if (recurrenceId.isNull()) {
215 if (!i->hasRecurrenceId()) {
219 if (i->hasRecurrenceId() && i->recurrenceId() == recurrenceId) {
228 MemoryCalendar::Private::deletedIncidence(
const QString &uid,
229 const KDateTime &recurrenceId,
232 if (!q->deletionTracking()) {
236 QList<Incidence::Ptr> values = mDeletedIncidences[type].values(uid);
237 QList<Incidence::Ptr>::const_iterator it;
238 for (it = values.constBegin(); it != values.constEnd(); ++it) {
240 if (recurrenceId.isNull()) {
241 if (!i->hasRecurrenceId()) {
245 if (i->hasRecurrenceId() && i->recurrenceId() == recurrenceId) {
253 void MemoryCalendar::Private::insertIncidence(
const Incidence::Ptr &incidence)
255 const QString uid = incidence->uid();
257 if (!mIncidences[type].contains(uid, incidence)) {
258 mIncidences[type].insert(uid, incidence);
259 mIncidencesByIdentifier.insert(incidence->instanceIdentifier(), incidence);
262 mIncidencesForDate[type].insert(dt.date().toString(), incidence);
269 Q_ASSERT(mIncidences[type].value(uid) == incidence);
277 d->insertIncidence(incidence);
281 incidence->registerObserver(
this);
311 const KDateTime &recurrenceId)
const
342 const KDateTime &recurrenceId)
const
348 const KDateTime &recurrenceId)
const
358 while (i.hasNext()) {
360 todoList.append(i.value().staticCast<
Todo>());
374 while (i.hasNext()) {
376 todoList.append(i.value().staticCast<
Todo>());
388 QList<Incidence::Ptr>::const_iterator it;
389 for (it = values.constBegin(); it != values.constEnd(); ++it) {
391 if (t->hasRecurrenceId()) {
404 const QString dateStr = date.toString();
405 QMultiHash<QString, IncidenceBase::Ptr >::const_iterator it =
407 while (it != d->mIncidencesForDate[
Incidence::TypeTodo].constEnd() && it.key() == dateStr) {
408 t = it.value().staticCast<
Todo>();
415 while (i.hasNext()) {
417 t = i.value().staticCast<
Todo>();
419 if (t->recursOn(date, ts)) {
430 const KDateTime::Spec ×pec,
431 bool inclusive)
const
436 KDateTime::Spec ts = timespec.isValid() ? timespec :
timeSpec();
437 KDateTime st(start, ts);
438 KDateTime nd(end, ts);
443 while (i.hasNext()) {
445 todo = i.value().staticCast<
Todo>();
450 KDateTime rStart = todo->
hasDueDate() ? todo->dtDue() :
451 todo->hasStartDate() ? todo->dtStart() : KDateTime();
452 if (!rStart.isValid()) {
456 if (!todo->recurs()) {
457 if (nd.isValid() && nd < rStart) {
460 if (st.isValid() && rStart < st) {
464 switch (todo->recurrence()->duration()) {
469 KDateTime rEnd(todo->recurrence()->endDate(), ts);
470 if (!rEnd.isValid()) {
473 if (st.isValid() && rEnd < st) {
480 todoList.append(todo);
488 return alarms(KDateTime(QDate(1900, 1, 1)), to);
496 while (ie.hasNext()) {
498 e = ie.value().staticCast<
Event>();
508 while (it.hasNext()) {
510 t = it.value().staticCast<
Todo>();
512 if (!t->isCompleted()) {
530 if (!d->mIncidenceBeingUpdated.isEmpty()) {
531 kWarning() <<
"Incidence::update() called twice without an updated() call in between.";
535 d->mIncidenceBeingUpdated = inc->instanceIdentifier();
540 d->mIncidencesForDate[type].remove(dt.date().toString(), inc);
551 if (d->mIncidenceBeingUpdated.isEmpty()) {
552 kWarning() <<
"Incidence::updated() called twice without an update() call in between.";
553 }
else if (inc->instanceIdentifier() != d->mIncidenceBeingUpdated) {
555 d->mIncidencesByIdentifier.remove(d->mIncidenceBeingUpdated);
556 d->mIncidencesByIdentifier.insert(inc->instanceIdentifier(), inc);
559 d->mIncidenceBeingUpdated = QString();
561 inc->setLastModified(KDateTime::currentUtcDateTime());
569 d->mIncidencesForDate[type].insert(dt.date().toString(), inc);
579 const KDateTime::Spec ×pec,
585 if (!date.isValid()) {
593 const QString dateStr = date.toString();
594 QMultiHash<QString, IncidenceBase::Ptr >::const_iterator it =
597 KDateTime::Spec ts = timespec.isValid() ? timespec :
timeSpec();
598 KDateTime kdt(date, ts);
600 ev = it.value().staticCast<
Event>();
601 KDateTime end(ev->dtEnd().toTimeSpec(ev->dtStart()));
603 end.setDateOnly(
true);
605 end = end.addSecs(-1);
608 eventList.append(ev);
615 while (i.hasNext()) {
617 ev = i.value().staticCast<
Event>();
619 if (ev->isMultiDay()) {
620 int extraDays = ev->
dtStart().date().daysTo(ev->dtEnd().date());
621 for (
int i = 0; i <= extraDays; ++i) {
622 if (ev->recursOn(date.addDays(-i), ts)) {
623 eventList.append(ev);
628 if (ev->recursOn(date, ts)) {
629 eventList.append(ev);
633 if (ev->isMultiDay()) {
634 if (ev->dtStart().date() <= date && ev->dtEnd().date() >= date) {
635 eventList.append(ev);
646 const KDateTime::Spec ×pec,
647 bool inclusive)
const
650 KDateTime::Spec ts = timespec.isValid() ? timespec :
timeSpec();
651 KDateTime st(start, ts);
652 KDateTime nd(end, ts);
653 KDateTime yesterStart = st.addDays(-1);
658 while (i.hasNext()) {
660 event = i.value().staticCast<
Event>();
661 KDateTime rStart =
event->
dtStart();
665 if (inclusive && rStart < st) {
669 if (!event->recurs()) {
670 KDateTime rEnd =
event->dtEnd();
674 if (inclusive && nd < rEnd) {
678 switch (event->recurrence()->duration()) {
686 KDateTime rEnd(event->recurrence()->endDate(), ts);
687 if (!rEnd.isValid()) {
693 if (inclusive && nd < rEnd) {
700 eventList.append(event);
716 while (i.hasNext()) {
718 eventList.append(i.value().staticCast<
Event>());
732 while (i.hasNext()) {
734 eventList.append(i.value().staticCast<
Event>());
746 QList<Incidence::Ptr>::const_iterator it;
747 for (it = values.constBegin(); it != values.constEnd(); ++it) {
749 if (ev->hasRecurrenceId()) {
777 const KDateTime &recurrenceId)
const
783 const KDateTime &recurrenceId)
const
793 while (i.hasNext()) {
795 journalList.append(i.value().staticCast<
Journal>());
809 while (i.hasNext()) {
811 journalList.append(i.value().staticCast<
Journal>());
823 QList<Incidence::Ptr>::const_iterator it;
824 for (it = values.constBegin(); it != values.constEnd(); ++it) {
826 if (j->hasRecurrenceId()) {
838 QString dateStr = date.toString();
839 QMultiHash<QString, IncidenceBase::Ptr >::const_iterator it =
843 j = it.value().staticCast<
Journal>();
844 journalList.append(j);
852 return d->mIncidencesByIdentifier.value(identifier);