KCalendarCore

memorycalendar.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the kcalcore library.
3 
4  SPDX-FileCopyrightText: 1998 Preston Brown <[email protected]>
5  SPDX-FileCopyrightText: 2001, 2003, 2004 Cornelius Schumacher <[email protected]>
6  SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <[email protected]>
7 
8  SPDX-License-Identifier: LGPL-2.0-or-later
9 */
10 /**
11  @file
12  This file is part of the API for handling calendar data and
13  defines the MemoryCalendar class.
14 
15  @brief
16  This class provides a calendar stored as a local file.
17 
18  @author Preston Brown <[email protected]>
19  @author Cornelius Schumacher <[email protected]>
20  */
21 
22 #include "memorycalendar.h"
23 #include "calformat.h"
24 #include "kcalendarcore_debug.h"
25 
26 #include <QDate>
27 
28 #include <functional>
29 
30 using namespace KCalendarCore;
31 
32 /**
33  Private class that helps to provide binary compatibility between releases.
34  @internal
35 */
36 //@cond PRIVATE
37 class Q_DECL_HIDDEN KCalendarCore::MemoryCalendar::Private
38 {
39 private:
40  static constexpr int incidenceTypeCount = 4;
41 
42 public:
43  Private(MemoryCalendar *qq)
44  : q(qq)
45  , mFormat(nullptr)
46  , mUpdateLastModified(true)
47  {
48  }
49  ~Private()
50  {
51  }
52 
53  MemoryCalendar *q;
54  CalFormat *mFormat; // calendar format
55  QString mIncidenceBeingUpdated; // Instance identifier of Incidence currently being updated
56  bool mUpdateLastModified; // Call setLastModified() on incidence modific ations
57 
58  /**
59  * List of all incidences.
60  * First indexed by incidence->type(), then by incidence->uid();
61  */
62  QMultiHash<QString, Incidence::Ptr> mIncidences[incidenceTypeCount];
63 
64  /**
65  * Has all incidences, indexed by identifier.
66  */
67  QHash<QString, KCalendarCore::Incidence::Ptr> mIncidencesByIdentifier;
68 
69  /**
70  * List of all deleted incidences.
71  * First indexed by incidence->type(), then by incidence->uid();
72  */
73  QMultiHash<QString, Incidence::Ptr> mDeletedIncidences[incidenceTypeCount];
74 
75  /**
76  * Contains incidences ( to-dos; non-recurring, non-multiday events; journals; )
77  * indexed by start/due date.
78  *
79  * The QMap key is the incidence->type().
80  * The QMultiHash key is the dtStart/dtDue() converted to calendar's timezone
81  *
82  * Note: We had 3 variables, mJournalsForDate, mTodosForDate and mEventsForDate
83  * but i merged them into one (indexed by type) because it simplifies code using
84  * it. No need to if else based on type.
85  */
86  QMultiHash<QDate, Incidence::Ptr> mIncidencesForDate[incidenceTypeCount];
87 
88  void insertIncidence(const Incidence::Ptr &incidence);
89 
90  Incidence::Ptr incidence(const QString &uid, IncidenceBase::IncidenceType type, const QDateTime &recurrenceId = {}) const;
91 
92  bool deleteIncidence(const QString &uid, IncidenceBase::IncidenceType type, const QDateTime &recurrenceId = {});
93 
94  Incidence::Ptr deletedIncidence(const QString &uid, const QDateTime &recurrenceId, IncidenceBase::IncidenceType type) const;
95 
96  void deleteAllIncidences(IncidenceBase::IncidenceType type);
97 
98  template<typename IncidenceType, typename Key>
99  void forIncidences(const QMultiHash<Key, Incidence::Ptr> &incidences, const Key &key, std::function<void(const typename IncidenceType::Ptr &)> &&op) const
100  {
101  for (auto it = incidences.constFind(key), end = incidences.cend(); it != end && it.key() == key; ++it) {
102  op(it.value().template staticCast<IncidenceType>());
103  }
104  }
105 
106  template<typename IncidenceType, typename Key>
107  void forIncidences(const QMultiHash<Key, Incidence::Ptr> &incidences, std::function<void(const typename IncidenceType::Ptr &)> &&op) const
108  {
109  for (const auto &incidence : incidences) {
110  op(incidence.template staticCast<IncidenceType>());
111  }
112  }
113 
114  template<typename IncidenceType>
115  typename IncidenceType::List castIncidenceList(const QMultiHash<QString, Incidence::Ptr> &incidences) const
116  {
117  typename IncidenceType::List list;
118  list.reserve(incidences.size());
119  std::transform(incidences.cbegin(), incidences.cend(), std::back_inserter(list), [](const Incidence::Ptr &inc) {
120  return inc.staticCast<IncidenceType>();
121  });
122  return list;
123  }
124 
125  template<typename IncidenceType>
126  typename IncidenceType::List incidenceInstances(IncidenceBase::IncidenceType type, const Incidence::Ptr &incidence) const
127  {
128  typename IncidenceType::List list;
129  forIncidences<IncidenceType, QString>(mIncidences[type], incidence->uid(), [&list](const typename IncidenceType::Ptr &incidence) {
130  if (incidence->hasRecurrenceId()) {
131  list.push_back(incidence);
132  }
133  });
134  return list;
135  }
136 
137  Incidence::Ptr findIncidence(const QMultiHash<QString, Incidence::Ptr> &incidences, const QString &uid, const QDateTime &recurrenceId) const
138  {
139  for (auto it = incidences.constFind(uid), end = incidences.cend(); it != end && it.key() == uid; ++it) {
140  const auto &incidence = it.value();
141  if (recurrenceId.isNull() && !incidence->hasRecurrenceId()) {
142  return incidence;
143  } else if (!recurrenceId.isNull() && incidence->hasRecurrenceId() && recurrenceId == incidence->recurrenceId()) {
144  return incidence;
145  }
146  }
147  return {};
148  }
149 };
150 //@endcond
151 
152 MemoryCalendar::MemoryCalendar(const QTimeZone &timeZone)
153  : Calendar(timeZone)
154  , d(new KCalendarCore::MemoryCalendar::Private(this))
155 {
156 }
157 
159  : Calendar(timeZoneId)
160  , d(new KCalendarCore::MemoryCalendar::Private(this))
161 {
162 }
163 
165 {
166  close(); // NOLINT false clang-analyzer-optin.cplusplus.VirtualCall
167  delete d;
168 }
169 
170 void MemoryCalendar::doSetTimeZone(const QTimeZone &timeZone)
171 {
172  // Reset date based hashes before storing for the new zone.
173  for (auto &table : d->mIncidencesForDate) {
174  table.clear();
175  }
176 
177  for (auto &table : d->mIncidences) {
178  for (const auto &incidence : table) {
179  const QDateTime dt = incidence->dateTime(Incidence::RoleCalendarHashing);
180  if (dt.isValid()) {
181  d->mIncidencesForDate[incidence->type()].insert(dt.toTimeZone(timeZone).date(), incidence);
182  }
183  }
184  }
185 }
186 
188 {
189  setObserversEnabled(false);
190 
191  // Don't call the virtual function deleteEvents() etc, the base class might have
192  // other ways of deleting the data.
193  d->deleteAllIncidences(Incidence::TypeEvent);
194  d->deleteAllIncidences(Incidence::TypeTodo);
195  d->deleteAllIncidences(Incidence::TypeJournal);
196 
197  d->mIncidencesByIdentifier.clear();
198  for (auto &table : d->mDeletedIncidences) {
199  table.clear();
200  }
201 
203 
204  setModified(false);
205 
206  setObserversEnabled(true);
207 }
208 
209 bool MemoryCalendar::deleteIncidence(const Incidence::Ptr &incidence)
210 {
211  // Handle orphaned children
212  // relations is an Incidence's property, not a Todo's, so
213  // we remove relations in deleteIncidence, not in deleteTodo.
215  // Notify while the incidence is still available,
216  // this is necessary so korganizer still has time to query for exceptions
218  incidence->unRegisterObserver(this);
219  const Incidence::IncidenceType type = incidence->type();
220  const QString &uid = incidence->uid();
221  bool deleted = d->deleteIncidence(uid, type, incidence->recurrenceId());
222  if (deleted) {
223  setModified(true);
224  if (deletionTracking()) {
225  d->mDeletedIncidences[type].insert(uid, incidence);
226  }
227 
228  // Delete child-incidences.
229  if (!incidence->hasRecurrenceId() && incidence->recurs()) {
231  }
232  } else {
233  qCWarning(KCALCORE_LOG) << incidence->typeStr() << " not found. uid=" << uid;
234  }
236  return deleted;
237 }
238 
240 {
242  for (auto it = d->mIncidences[incidence->type()].constFind(incidence->uid()), end = d->mIncidences[incidence->type()].constEnd();
243  it != end && it.key() == incidence->uid();
244  ++it) {
245  if (it.value()->hasRecurrenceId()) {
246  qCDebug(KCALCORE_LOG) << "deleting child"
247  << ", type=" << int(incidence->type()) << ", uid="
248  << incidence->uid()
249  // << ", start=" << i->dtStart()
250  << " from calendar";
251  // Don't call deleteIncidence() now since it's modifying the
252  // mIncidences map we're iterating over.
253  instances.append(it.value());
254  }
255  }
258  }
259 
260  return true;
261 }
262 
263 //@cond PRIVATE
264 bool MemoryCalendar::Private::deleteIncidence(const QString &uid, IncidenceBase::IncidenceType type, const QDateTime &recurrenceId)
265 {
266  for (auto it = mIncidences[type].find(uid), end = mIncidences[type].end(); it != end && it.key() == uid; ++it) {
267  Incidence::Ptr incidence = it.value();
268  if (recurrenceId.isNull() && incidence->hasRecurrenceId()) {
269  continue;
270  } else if (!recurrenceId.isNull() && (!incidence->hasRecurrenceId() || recurrenceId != incidence->recurrenceId())) {
271  continue;
272  }
273  mIncidences[type].erase(it);
274  mIncidencesByIdentifier.remove(incidence->instanceIdentifier());
275  const QDateTime dt = incidence->dateTime(Incidence::RoleCalendarHashing);
276  if (dt.isValid()) {
277  mIncidencesForDate[type].remove(dt.toTimeZone(q->timeZone()).date(), incidence);
278  }
279  return true;
280  }
281  return false;
282 }
283 
284 void MemoryCalendar::Private::deleteAllIncidences(Incidence::IncidenceType incidenceType)
285 {
286  for (auto &incidence : mIncidences[incidenceType]) {
287  q->notifyIncidenceAboutToBeDeleted(incidence);
288  incidence->unRegisterObserver(q);
289  }
290  mIncidences[incidenceType].clear();
291  mIncidencesForDate[incidenceType].clear();
292 }
293 
294 Incidence::Ptr MemoryCalendar::Private::incidence(const QString &uid, Incidence::IncidenceType type, const QDateTime &recurrenceId) const
295 {
296  return findIncidence(mIncidences[type], uid, recurrenceId);
297 }
298 
299 Incidence::Ptr MemoryCalendar::Private::deletedIncidence(const QString &uid, const QDateTime &recurrenceId, IncidenceBase::IncidenceType type) const
300 {
301  if (!q->deletionTracking()) {
302  return Incidence::Ptr();
303  }
304 
305  return findIncidence(mDeletedIncidences[type], uid, recurrenceId);
306 }
307 
308 void MemoryCalendar::Private::insertIncidence(const Incidence::Ptr &incidence)
309 {
310  const QString uid = incidence->uid();
311  const Incidence::IncidenceType type = incidence->type();
312  if (!mIncidences[type].contains(uid, incidence)) {
313  mIncidences[type].insert(uid, incidence);
314  mIncidencesByIdentifier.insert(incidence->instanceIdentifier(), incidence);
315  const QDateTime dt = incidence->dateTime(Incidence::RoleCalendarHashing);
316  if (dt.isValid()) {
317  mIncidencesForDate[type].insert(dt.toTimeZone(q->timeZone()).date(), incidence);
318  }
319 
320  } else {
321 #ifndef NDEBUG
322  // if we already have an to-do with this UID, it must be the same incidence,
323  // otherwise something's really broken
324  Q_ASSERT(mIncidences[type].value(uid) == incidence);
325 #endif
326  }
327 }
328 //@endcond
329 
330 bool MemoryCalendar::addIncidence(const Incidence::Ptr &incidence)
331 {
332  d->insertIncidence(incidence);
333 
335 
336  incidence->registerObserver(this);
337 
339 
340  setModified(true);
341 
342  return true;
343 }
344 
345 bool MemoryCalendar::addEvent(const Event::Ptr &event)
346 {
347  return addIncidence(event);
348 }
349 
350 bool MemoryCalendar::deleteEvent(const Event::Ptr &event)
351 {
352  return deleteIncidence(event);
353 }
354 
356 {
358 }
359 
360 Event::Ptr MemoryCalendar::event(const QString &uid, const QDateTime &recurrenceId) const
361 {
362  return d->incidence(uid, Incidence::TypeEvent, recurrenceId).staticCast<Event>();
363 }
364 
365 Event::Ptr MemoryCalendar::deletedEvent(const QString &uid, const QDateTime &recurrenceId) const
366 {
367  return d->deletedIncidence(uid, recurrenceId, Incidence::TypeEvent).staticCast<Event>();
368 }
369 
370 bool MemoryCalendar::addTodo(const Todo::Ptr &todo)
371 {
372  return addIncidence(todo);
373 }
374 
375 bool MemoryCalendar::deleteTodo(const Todo::Ptr &todo)
376 {
377  return deleteIncidence(todo);
378 }
379 
381 {
383 }
384 
385 Todo::Ptr MemoryCalendar::todo(const QString &uid, const QDateTime &recurrenceId) const
386 {
387  return d->incidence(uid, Incidence::TypeTodo, recurrenceId).staticCast<Todo>();
388 }
389 
390 Todo::Ptr MemoryCalendar::deletedTodo(const QString &uid, const QDateTime &recurrenceId) const
391 {
392  return d->deletedIncidence(uid, recurrenceId, Incidence::TypeTodo).staticCast<Todo>();
393 }
394 
395 Todo::List MemoryCalendar::rawTodos(TodoSortField sortField, SortDirection sortDirection) const
396 {
397  return Calendar::sortTodos(d->castIncidenceList<Todo>(d->mIncidences[Incidence::TypeTodo]), sortField, sortDirection);
398 }
399 
401 {
402  if (!deletionTracking()) {
403  return Todo::List();
404  }
405 
406  return Calendar::sortTodos(d->castIncidenceList<Todo>(d->mDeletedIncidences[Incidence::TypeTodo]), sortField, sortDirection);
407 }
408 
409 Todo::List MemoryCalendar::todoInstances(const Incidence::Ptr &todo, TodoSortField sortField, SortDirection sortDirection) const
410 {
411  return Calendar::sortTodos(d->incidenceInstances<Todo>(Incidence::TypeTodo, todo), sortField, sortDirection);
412 }
413 
415 {
416  Todo::List todoList;
417 
418  d->forIncidences<Todo>(d->mIncidencesForDate[Incidence::TypeTodo], date, [&todoList](const Todo::Ptr &todo) {
419  todoList.append(todo);
420  });
421 
422  // Iterate over all todos. Look for recurring todoss that occur on this date
423  d->forIncidences<Todo>(d->mIncidences[Incidence::TypeTodo], [this, &todoList, &date](const Todo::Ptr &todo) {
424  if (todo->recurs() && todo->recursOn(date, timeZone())) {
425  todoList.append(todo);
426  }
427  });
428 
429  return todoList;
430 }
431 
432 Todo::List MemoryCalendar::rawTodos(const QDate &start, const QDate &end, const QTimeZone &timeZone, bool inclusive) const
433 {
434  Q_UNUSED(inclusive); // use only exact dtDue/dtStart, not dtStart and dtEnd
435 
436  Todo::List todoList;
437  const auto ts = timeZone.isValid() ? timeZone : this->timeZone();
438  QDateTime st(start, QTime(0, 0, 0), ts);
439  QDateTime nd(end, QTime(23, 59, 59, 999), ts);
440 
441  // Get todos
442  for (const auto &incidence : d->mIncidences[Incidence::TypeTodo]) {
443  const auto todo = incidence.staticCast<Todo>();
444  if (!isVisible(todo)) {
445  continue;
446  }
447 
448  QDateTime rStart = todo->hasDueDate() ? todo->dtDue() : todo->hasStartDate() ? todo->dtStart() : QDateTime();
449  if (!rStart.isValid()) {
450  continue;
451  }
452 
453  if (!todo->recurs()) { // non-recurring todos
454  if (nd.isValid() && nd < rStart) {
455  continue;
456  }
457  if (st.isValid() && rStart < st) {
458  continue;
459  }
460  } else { // recurring events
461  switch (todo->recurrence()->duration()) {
462  case -1: // infinite
463  break;
464  case 0: // end date given
465  default: // count given
466  QDateTime rEnd(todo->recurrence()->endDate(), QTime(23, 59, 59, 999), ts);
467  if (!rEnd.isValid()) {
468  continue;
469  }
470  if (st.isValid() && rEnd < st) {
471  continue;
472  }
473  break;
474  } // switch(duration)
475  } // if(recurs)
476 
477  todoList.append(todo);
478  }
479 
480  return todoList;
481 }
482 
484 {
485  return alarms(QDateTime(QDate(1900, 1, 1), QTime(0, 0, 0)), to);
486 }
487 
488 Alarm::List MemoryCalendar::alarms(const QDateTime &from, const QDateTime &to, bool excludeBlockedAlarms) const
489 {
490  Q_UNUSED(excludeBlockedAlarms);
491  Alarm::List alarmList;
492 
493  d->forIncidences<Event>(d->mIncidences[Incidence::TypeEvent], [this, &alarmList, &from, &to](const Event::Ptr &e) {
494  if (e->recurs()) {
495  appendRecurringAlarms(alarmList, e, from, to);
496  } else {
497  appendAlarms(alarmList, e, from, to);
498  }
499  });
500 
501  d->forIncidences<Todo>(d->mIncidences[IncidenceBase::TypeTodo], [this, &alarmList, &from, &to](const Todo::Ptr &t) {
502  if (!t->isCompleted()) {
503  appendAlarms(alarmList, t, from, to);
504  if (t->recurs()) {
505  appendRecurringAlarms(alarmList, t, from, to);
506  } else {
507  appendAlarms(alarmList, t, from, to);
508  }
509  }
510  });
511 
512  return alarmList;
513 }
514 
516 {
517  return d->mUpdateLastModified;
518 }
519 
521 {
522  d->mUpdateLastModified = update;
523 }
524 
525 void MemoryCalendar::incidenceUpdate(const QString &uid, const QDateTime &recurrenceId)
526 {
527  Incidence::Ptr inc = incidence(uid, recurrenceId);
528 
529  if (inc) {
530  if (!d->mIncidenceBeingUpdated.isEmpty()) {
531  qCWarning(KCALCORE_LOG) << "Incidence::update() called twice without an updated() call in between.";
532  }
533 
534  // Save it so we can detect changes to uid or recurringId.
535  d->mIncidenceBeingUpdated = inc->instanceIdentifier();
536 
537  const QDateTime dt = inc->dateTime(Incidence::RoleCalendarHashing);
538  if (dt.isValid()) {
539  d->mIncidencesForDate[inc->type()].remove(dt.toTimeZone(timeZone()).date(), inc);
540  }
541  }
542 }
543 
544 void MemoryCalendar::incidenceUpdated(const QString &uid, const QDateTime &recurrenceId)
545 {
546  Incidence::Ptr inc = incidence(uid, recurrenceId);
547 
548  if (inc) {
549  if (d->mIncidenceBeingUpdated.isEmpty()) {
550  qCWarning(KCALCORE_LOG) << "Incidence::updated() called twice without an update() call in between.";
551  } else if (inc->instanceIdentifier() != d->mIncidenceBeingUpdated) {
552  // Instance identifier changed, update our hash table
553  d->mIncidencesByIdentifier.remove(d->mIncidenceBeingUpdated);
554  d->mIncidencesByIdentifier.insert(inc->instanceIdentifier(), inc);
555  }
556 
557  d->mIncidenceBeingUpdated = QString();
558 
559  if (d->mUpdateLastModified) {
560  inc->setLastModified(QDateTime::currentDateTimeUtc());
561  }
562  // we should probably update the revision number here,
563  // or internally in the Event itself when certain things change.
564  // need to verify with ical documentation.
565 
566  const QDateTime dt = inc->dateTime(Incidence::RoleCalendarHashing);
567  if (dt.isValid()) {
568  d->mIncidencesForDate[inc->type()].insert(dt.toTimeZone(timeZone()).date(), inc);
569  }
570 
572 
573  setModified(true);
574  }
575 }
576 
577 Event::List MemoryCalendar::rawEventsForDate(const QDate &date, const QTimeZone &timeZone, EventSortField sortField, SortDirection sortDirection) const
578 {
579  Event::List eventList;
580 
581  if (!date.isValid()) {
582  // There can't be events on invalid dates
583  return eventList;
584  }
585 
586  if (timeZone.isValid() && timeZone != this->timeZone()) {
587  // We cannot use the hash table on date, since time zone is different.
588  eventList = rawEvents(date, date, timeZone, false);
589  return Calendar::sortEvents(std::move(eventList), sortField, sortDirection);
590  }
591 
592  // Iterate over all non-recurring, single-day events that start on this date
593  d->forIncidences<Event>(d->mIncidencesForDate[Incidence::TypeEvent], date, [&eventList](const Event::Ptr &event) {
594  eventList.append(event);
595  });
596 
597  // Iterate over all events. Look for recurring events that occur on this date
598  const auto ts = timeZone.isValid() ? timeZone : this->timeZone();
599  for (const auto &event : d->mIncidences[Incidence::TypeEvent]) {
600  const auto ev = event.staticCast<Event>();
601  if (ev->recurs()) {
602  if (ev->isMultiDay()) {
603  int extraDays = ev->dtStart().date().daysTo(ev->dtEnd().date());
604  for (int i = 0; i <= extraDays; ++i) {
605  if (ev->recursOn(date.addDays(-i), ts)) {
606  eventList.append(ev);
607  break;
608  }
609  }
610  } else {
611  if (ev->recursOn(date, ts)) {
612  eventList.append(ev);
613  }
614  }
615  } else {
616  if (ev->isMultiDay()) {
617  if (ev->dtStart().toTimeZone(ts).date() <= date && ev->dtEnd().toTimeZone(ts).date() >= date) {
618  eventList.append(ev);
619  }
620  }
621  }
622  }
623 
624  return Calendar::sortEvents(std::move(eventList), sortField, sortDirection);
625 }
626 
627 Event::List MemoryCalendar::rawEvents(const QDate &start, const QDate &end, const QTimeZone &timeZone, bool inclusive) const
628 {
629  Event::List eventList;
630  const auto ts = timeZone.isValid() ? timeZone : this->timeZone();
631  QDateTime st(start, QTime(0, 0, 0), ts);
632  QDateTime nd(end, QTime(23, 59, 59, 999), ts);
633 
634  // Get non-recurring events
635  for (const auto &e : d->mIncidences[Incidence::TypeEvent]) {
636  const auto event = e.staticCast<Event>();
637  QDateTime rStart = event->dtStart();
638  if (nd.isValid() && nd < rStart) {
639  continue;
640  }
641  if (inclusive && st.isValid() && rStart < st) {
642  continue;
643  }
644 
645  if (!event->recurs()) { // non-recurring events
646  QDateTime rEnd = event->dtEnd();
647  if (st.isValid() && rEnd < st) {
648  continue;
649  }
650  if (inclusive && nd.isValid() && nd < rEnd) {
651  continue;
652  }
653  } else { // recurring events
654  switch (event->recurrence()->duration()) {
655  case -1: // infinite
656  if (inclusive) {
657  continue;
658  }
659  break;
660  case 0: // end date given
661  default: // count given
662  QDateTime rEnd(event->recurrence()->endDate(), QTime(23, 59, 59, 999), ts);
663  if (!rEnd.isValid()) {
664  continue;
665  }
666  if (st.isValid() && rEnd < st) {
667  continue;
668  }
669  if (inclusive && nd.isValid() && nd < rEnd) {
670  continue;
671  }
672  break;
673  } // switch(duration)
674  } // if(recurs)
675 
676  eventList.append(event);
677  }
678 
679  return eventList;
680 }
681 
682 #if KCALENDARCORE_BUILD_DEPRECATED_SINCE(5, 95)
684 {
685  return rawEventsForDate(kdt.date(), kdt.timeZone());
686 }
687 #endif
688 
690 {
691  return Calendar::sortEvents(d->castIncidenceList<Event>(d->mIncidences[Incidence::TypeEvent]), sortField, sortDirection);
692 }
693 
695 {
696  if (!deletionTracking()) {
697  return Event::List();
698  }
699 
700  return Calendar::sortEvents(d->castIncidenceList<Event>(d->mDeletedIncidences[Incidence::TypeEvent]), sortField, sortDirection);
701 }
702 
703 Event::List MemoryCalendar::eventInstances(const Incidence::Ptr &event, EventSortField sortField, SortDirection sortDirection) const
704 {
705  return Calendar::sortEvents(d->incidenceInstances<Event>(Incidence::TypeEvent, event), sortField, sortDirection);
706 }
707 
708 bool MemoryCalendar::addJournal(const Journal::Ptr &journal)
709 {
710  return addIncidence(journal);
711 }
712 
713 bool MemoryCalendar::deleteJournal(const Journal::Ptr &journal)
714 {
715  return deleteIncidence(journal);
716 }
717 
719 {
721 }
722 
723 Journal::Ptr MemoryCalendar::journal(const QString &uid, const QDateTime &recurrenceId) const
724 {
725  return d->incidence(uid, Incidence::TypeJournal, recurrenceId).staticCast<Journal>();
726 }
727 
728 Journal::Ptr MemoryCalendar::deletedJournal(const QString &uid, const QDateTime &recurrenceId) const
729 {
730  return d->deletedIncidence(uid, recurrenceId, Incidence::TypeJournal).staticCast<Journal>();
731 }
732 
734 {
735  return Calendar::sortJournals(d->castIncidenceList<Journal>(d->mIncidences[Incidence::TypeJournal]), sortField, sortDirection);
736 }
737 
739 {
740  if (!deletionTracking()) {
741  return Journal::List();
742  }
743 
744  return Calendar::sortJournals(d->castIncidenceList<Journal>(d->mDeletedIncidences[Incidence::TypeJournal]), sortField, sortDirection);
745 }
746 
748 {
749  return Calendar::sortJournals(d->incidenceInstances<Journal>(Incidence::TypeJournal, journal), sortField, sortDirection);
750 }
751 
753 {
754  Journal::List journalList;
755 
756  d->forIncidences<Journal>(d->mIncidencesForDate[Incidence::TypeJournal], date, [&journalList](const Journal::Ptr &journal) {
757  journalList.append(journal);
758  });
759 
760  return journalList;
761 }
762 
763 Incidence::Ptr MemoryCalendar::instance(const QString &identifier) const
764 {
765  return d->mIncidencesByIdentifier.value(identifier);
766 }
767 
768 void MemoryCalendar::virtual_hook(int id, void *data)
769 {
770  Q_UNUSED(id);
771  Q_UNUSED(data);
772  Q_ASSERT(false);
773 }
774 
775 #include "moc_memorycalendar.cpp"
Incidence::Ptr incidence(const QString &uid, const QDateTime &recurrenceId={}) const
Returns the Incidence associated with the given unique identifier.
Definition: calendar.cpp:614
Todo::Ptr todo(const QString &uid, const QDateTime &recurrenceId={}) const override
Returns the Todo associated with the given unique identifier.
Journal::Ptr deletedJournal(const QString &uid, const QDateTime &recurrenceId={}) const override
Returns the deleted Journal associated with the given unique identifier.
void appendAlarms(Alarm::List &alarms, const Incidence::Ptr &incidence, const QDateTime &from, const QDateTime &to) const
Appends alarms of incidence in interval to list of alarms.
Definition: calendar.cpp:1203
void notifyIncidenceChanged(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they modified an Incidence.
Definition: calendar.cpp:1088
Todo::List rawTodos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const override
Returns a sorted, unfiltered list of all Todos for this Calendar.
Event::List rawEvents(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const override
Returns a sorted, unfiltered list of all Events for this Calendar.
~MemoryCalendar() override
Destroys the calendar.
Event::Ptr deletedEvent(const QString &uid, const QDateTime &recurrenceId={}) const override
Returns the deleted Event associated with the given unique identifier.
QTimeZone timeZone() const const
TodoSortField
Calendar Todo sort keys.
Definition: calendar.h:80
QHash::iterator erase(QHash::iterator pos)
Type type(const QSqlDatabase &db)
Journal::List journalInstances(const Incidence::Ptr &journal, JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const override
JournalSortField
Calendar Journal sort keys.
Definition: calendar.h:94
Namespace for all KCalendarCore types.
Definition: alarm.h:36
void append(const T &value)
bool isVisible(const Incidence::Ptr &incidence) const
Check if incidence is visible.
Definition: calendar.cpp:381
bool deleteTodoInstances(const Todo::Ptr &todo) override
Delete all to-dos that are instances of recurring to-do todo.
void clear()
bool isNull() const const
static Journal::List sortJournals(const Journal::List &journalList, JournalSortField sortField, SortDirection sortDirection)
Sort a list of Journals.
Definition: calendar.cpp:766
static Todo::List sortTodos(const Todo::List &todoList, TodoSortField sortField, SortDirection sortDirection)
Sort a list of Todos.
Definition: calendar.cpp:669
QDateTime currentDateTimeUtc()
@ TypeTodo
Type is a to-do.
void doSetTimeZone(const QTimeZone &timeZone) override
Let Calendar subclasses set the time specification.
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
bool deleteIncidence(const Incidence::Ptr &incidence) override
Removes an Incidence from the calendar.
bool deleteJournal(const Journal::Ptr &journal) override
Removes a Journal from the calendar.
Provides a Journal in the sense of RFC2445.
Definition: journal.h:32
Journal::List rawJournalsForDate(const QDate &date) const override
Returns an unfiltered list of all Journals for on the specified date.
void incidenceUpdated(const QString &uid, const QDateTime &recurrenceId) override
The Observer interface.
AKONADI_CALENDAR_EXPORT KCalendarCore::Incidence::Ptr incidence(const Akonadi::Item &item)
typename QHash< Key, T >::iterator insert(const Key &key, const T &value)
Incidence::Ptr instance(const QString &identifier) const
Returns an incidence by identifier.
bool deleteIncidenceInstances(const Incidence::Ptr &incidence) override
Delete all incidences that are instances of recurring incidence incidence.
QHash::const_iterator cend() const const
QHash::iterator insert(const Key &key, const T &value)
bool addIncidence(const Incidence::Ptr &incidence) override
Inserts an Incidence into the calendar.
void reserve(int alloc)
virtual void removeRelations(const Incidence::Ptr &incidence)
Removes all Relations from an Incidence.
Definition: calendar.cpp:862
QDateTime toTimeZone(const QTimeZone &timeZone) const const
Represents the main calendar class.
Definition: calendar.h:132
void setObserversEnabled(bool enabled)
Let Calendar subclasses notify that they enabled an Observer.
Definition: calendar.cpp:1198
EventSortField
Calendar Event sort keys.
Definition: calendar.h:70
Provides a To-do in the sense of RFC2445.
Definition: todo.h:33
Q_SCRIPTABLE Q_NOREPLY void start()
int size() const const
bool deleteTodo(const Todo::Ptr &todo) override
Removes a Todo from the calendar.
Alarm::List alarmsTo(const QDateTime &to) const
Return a list of Alarms that occur before the specified timestamp.
Event::List rawEventsForDate(const QDate &date, const QTimeZone &timeZone={}, EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const override
Returns an unfiltered list of all Events which occur on the given date.
Journal::List deletedJournals(JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const override
Returns a sorted, unfiltered list of all deleted Journals for this Calendar.
QSharedPointer< Incidence > Ptr
A shared pointer to an Incidence.
Definition: incidence.h:121
bool addEvent(const Event::Ptr &event) override
Inserts an Event into the calendar.
void virtual_hook(int id, void *data) override
Standard trick to add virtuals later.
bool deletionTracking() const
Returns if deletion tracking is enabled.
Definition: calendar.cpp:1338
bool deleteEventInstances(const Event::Ptr &event) override
Delete all events that are instances of recurring event event.
bool isValid() const const
Todo::List rawTodosForDate(const QDate &date) const override
Returns an unfiltered list of all Todos which due on the specified date.
void appendRecurringAlarms(Alarm::List &alarms, const Incidence::Ptr &incidence, const QDateTime &from, const QDateTime &to) const
Appends alarms of recurring events in interval to list of alarms.
Definition: calendar.cpp:1219
bool isValid() const const
QDate addDays(qint64 ndays) const const
@ RoleCalendarHashing
Role for looking up an incidence in a Calendar.
Todo::List todoInstances(const Incidence::Ptr &todo, TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const override
Returns a sorted, unfiltered list of all possible instances for this recurring Todo.
SortDirection
Calendar Incidence sort directions.
Definition: calendar.h:62
bool deleteJournalInstances(const Journal::Ptr &journal) override
Delete all journals that are instances of recurring journal journal.
bool deleteEvent(const Event::Ptr &event) override
Removes an Event from the calendar.
Event::List eventInstances(const Incidence::Ptr &event, EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const override
Returns a sorted, unfiltered list of all possible instances for this recurring Event.
void notifyIncidenceAboutToBeDeleted(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they will remove an Incidence.
Definition: calendar.cpp:1103
const QList< QKeySequence > & find()
bool updateLastModifiedOnChange() const
Return true if the memory calendar is updating the lastModified field of incidence owned by the calen...
virtual void clearNotebookAssociations()
Clears notebook associations from hash-tables for incidences.
Definition: calendar.cpp:404
bool addTodo(const Todo::Ptr &todo) override
Inserts a Todo into the calendar.
Event::Ptr event(const QString &uid, const QDateTime &recurrenceId={}) const override
Returns the Event associated with the given unique identifier.
IncidenceType
The different types of incidences, per RFC2445.
Journal::List rawJournals(JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const override
Returns a sorted, unfiltered list of all Journals for this Calendar.
int remove(const Key &key)
An abstract base class that provides an interface to various calendar formats.
Definition: calformat.h:38
QTimeZone timeZone() const
Get the time zone used for creating or modifying incidences in the Calendar.
Definition: calendar.cpp:189
void update(Part *part, const QByteArray &data, qint64 dataSize)
Event::List deletedEvents(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const override
Returns a sorted, unfiltered list of all deleted Events for this Calendar.
QDate date() const const
bool isValid() const const
void setModified(bool modified)
Sets if the calendar has been modified.
Definition: calendar.cpp:1015
@ TypeEvent
Type is an event.
bool addJournal(const Journal::Ptr &journal) override
Inserts a Journal into the calendar.
Todo::List deletedTodos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const override
Returns a sorted, unfiltered list of all deleted Todos for this Calendar.
Alarm::List alarms(const QDateTime &from, const QDateTime &to, bool excludeBlockedAlarms=false) const override
Returns a list of Alarms within a time range for this Calendar.
@ TypeJournal
Type is a journal.
virtual Incidence::List instances(const Incidence::Ptr &incidence) const
Returns an unfiltered list of all exceptions of this recurring incidence.
Definition: calendar.cpp:290
int remove(const Key &key, const T &value)
void setUpdateLastModifiedOnChange(bool update)
Govern if the memory calendar is changing the lastModified field of incidence it owns,...
QHash::const_iterator cbegin() const const
Journal::Ptr journal(const QString &uid, const QDateTime &recurrenceId={}) const override
Returns the Journal associated with the given unique identifier.
QSharedPointer< X > staticCast() const const
This class provides a calendar stored in memory.
void incidenceUpdate(const QString &uid, const QDateTime &recurrenceId) override
The IncidenceObserver interface.
typename QHash< Key, T >::const_iterator constFind(const Key &key, const T &value) const const
QVector< Ptr > List
List of events.
Definition: event.h:55
void notifyIncidenceAdded(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they inserted an Incidence.
Definition: calendar.cpp:1064
void close() override
Clears out the current calendar, freeing all used memory etc.
QVector< Ptr > List
List of journals.
Definition: journal.h:43
Incidence::Ptr deleted(const QString &uid, const QDateTime &recurrenceId={}) const
Returns the deleted Incidence associated with the given unique identifier.
Definition: calendar.cpp:630
Todo::Ptr deletedTodo(const QString &uid, const QDateTime &recurrenceId={}) const override
Returns the deleted Todo associated with the given unique identifier.
qint64 daysTo(const QDate &d) const const
const QList< QKeySequence > & end()
static Event::List sortEvents(const Event::List &eventList, EventSortField sortField, SortDirection sortDirection)
Sort a list of Events.
Definition: calendar.cpp:484
virtual void setupRelations(const Incidence::Ptr &incidence)
Setup Relations for an Incidence.
Definition: calendar.cpp:815
MemoryCalendar(const QTimeZone &timeZone)
Constructs a calendar with a specified time zone timeZone.
void notifyIncidenceDeleted(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they removed an Incidence.
Definition: calendar.cpp:1118
This class provides an Event in the sense of RFC2445.
Definition: event.h:32
QVector< Ptr > List
List of to-dos.
Definition: todo.h:44
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Sep 28 2023 03:53:12 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.