KCalendarCore

calendar.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: 2000-2004 Cornelius Schumacher <[email protected]>
6  SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <[email protected]>
7  SPDX-FileCopyrightText: 2006 David Jarvie <[email protected]>
8 
9  SPDX-License-Identifier: LGPL-2.0-or-later
10 */
24 #include "calendar.h"
25 #include "calendar_p.h"
26 #include "calfilter.h"
27 #include "icaltimezones_p.h"
28 #include "sorting.h"
29 #include "visitor.h"
30 
31 #include "kcalendarcore_debug.h"
32 
33 #include <QTimeZone>
34 
35 extern "C" {
36 #include <icaltimezone.h>
37 }
38 
39 #include <algorithm> // for std::remove()
40 
41 using namespace KCalendarCore;
42 
46 template <typename K, typename V>
48 {
49  QVector<V> v;
50  v.reserve(c.size());
51  for (typename QMultiHash<K, V>::const_iterator it = c.begin(), end = c.end(); it != end; ++it) {
52  v.push_back(it.value());
53  }
54  return v;
55 }
56 
57 template <typename K, typename V>
58 QVector<V> values(const QMultiHash<K, V> &c, const K &x)
59 {
60  QVector<V> v;
61  typename QMultiHash<K, V>::const_iterator it = c.find(x);
62  while (it != c.end() && it.key() == x) {
63  v.push_back(it.value());
64  ++it;
65  }
66  return v;
67 }
68 
73 template<class T>
74 class AddVisitor : public Visitor
75 {
76 public:
77  AddVisitor(T *r) : mResource(r) {}
78 
79  bool visit(const Event::Ptr &e) override {
80  return mResource->addEvent(e);
81  }
82  bool visit(const Todo::Ptr &t) override {
83  return mResource->addTodo(t);
84  }
85  bool visit(const Journal::Ptr &j) override {
86  return mResource->addJournal(j);
87  }
88  bool visit(const FreeBusy::Ptr &) override {
89  return false;
90  }
91 
92 private:
93  T *mResource;
94 };
95 
101 template<class T>
102 class DeleteVisitor : public Visitor
103 {
104 public:
105  DeleteVisitor(T *r) : mResource(r) {}
106 
107  bool visit(const Event::Ptr &e) override {
108  mResource->deleteEvent(e);
109  return true;
110  }
111  bool visit(const Todo::Ptr &t) override {
112  mResource->deleteTodo(t);
113  return true;
114  }
115  bool visit(const Journal::Ptr &j) override {
116  mResource->deleteJournal(j);
117  return true;
118  }
119  bool visit(const FreeBusy::Ptr &) override {
120  return false;
121  }
122 
123 private:
124  T *mResource;
125 };
126 //@endcond
127 
129  : d(new KCalendarCore::Calendar::Private)
130 {
131  if (timeZone.isValid()) {
132  d->mTimeZone = timeZone;
133  } else {
134  d->mTimeZone = QTimeZone::systemTimeZone();
135  }
136 }
137 
139  : d(new KCalendarCore::Calendar::Private)
140 {
141  setTimeZoneId(timeZoneId);
142 }
143 
145 {
146  delete d;
147 }
148 
149 Person Calendar::owner() const
150 {
151  return d->mOwner;
152 }
153 
155 {
156  d->mOwner = owner;
157  setModified(true);
158 }
159 
161 {
162  if (timeZone.isValid()) {
163  d->mTimeZone = timeZone;
164  } else {
165  d->mTimeZone = QTimeZone::systemTimeZone();
166  }
167 
168  doSetTimeZone(d->mTimeZone);
169 }
170 
172 {
173  return d->mTimeZone;
174 }
175 
177 {
178  d->mTimeZone = d->timeZoneIdSpec(timeZoneId);
179 
180  doSetTimeZone(d->mTimeZone); //NOLINT false clang-analyzer-optin.cplusplus.VirtualCall
181 }
182 
183 //@cond PRIVATE
184 QTimeZone Calendar::Private::timeZoneIdSpec(const QByteArray &timeZoneId)
185 {
186  if (timeZoneId == QByteArrayLiteral("UTC")) {
187  return QTimeZone::utc();
188  }
189  auto tz = QTimeZone(timeZoneId);
190  if (tz.isValid()) {
191  return tz;
192  }
193  return QTimeZone::systemTimeZone();
194 }
195 //@endcond
196 
198 {
199  return d->mTimeZone.id();
200 }
201 
202 void Calendar::shiftTimes(const QTimeZone &oldZone, const QTimeZone &newZone)
203 {
204  setTimeZone(newZone);
205 
206  int i, end;
207  Event::List ev = events();
208  for (i = 0, end = ev.count(); i < end; ++i) {
209  ev[i]->shiftTimes(oldZone, newZone);
210  }
211 
212  Todo::List to = todos();
213  for (i = 0, end = to.count(); i < end; ++i) {
214  to[i]->shiftTimes(oldZone, newZone);
215  }
216 
217  Journal::List jo = journals();
218  for (i = 0, end = jo.count(); i < end; ++i) {
219  jo[i]->shiftTimes(oldZone, newZone);
220  }
221 }
222 
224 {
225  if (filter) {
226  d->mFilter = filter;
227  } else {
228  d->mFilter = d->mDefaultFilter;
229  }
230  emit filterChanged();
231 }
232 
234 {
235  return d->mFilter;
236 }
237 
239 {
240  Incidence::List rawInc(rawIncidences());
241  QStringList cats, thisCats;
242  // @TODO: For now just iterate over all incidences. In the future,
243  // the list of categories should be built when reading the file.
244  for (Incidence::List::ConstIterator i = rawInc.constBegin();
245  i != rawInc.constEnd(); ++i) {
246  thisCats = (*i)->categories();
247  for (QStringList::ConstIterator si = thisCats.constBegin();
248  si != thisCats.constEnd(); ++si) {
249  if (!cats.contains(*si)) {
250  cats.append(*si);
251  }
252  }
253  }
254  return cats;
255 }
256 
258 {
259  return mergeIncidenceList(events(date), todos(date), journals(date));
260 }
261 
263 {
264  return mergeIncidenceList(events(), todos(), journals());
265 }
266 
268 {
270 }
271 
273 {
274  if (incidence) {
275  Event::List elist;
276  Todo::List tlist;
277  Journal::List jlist;
278 
279  if (incidence->type() == Incidence::TypeEvent) {
280  elist = eventInstances(incidence);
281  } else if (incidence->type() == Incidence::TypeTodo) {
282  tlist = todoInstances(incidence);
283  } else if (incidence->type() == Incidence::TypeJournal) {
284  jlist = journalInstances(incidence);
285  }
286  return mergeIncidenceList(elist, tlist, jlist);
287  } else {
288  return Incidence::List();
289  }
290 }
291 
293 {
294  if (incidence) {
295  Incidence::List list;
296  Incidence::List vals = values(d->mNotebookIncidences);
298  for (it = vals.constBegin(); it != vals.constEnd(); ++it) {
299  if (((incidence->dtStart() == (*it)->dtStart()) ||
300  (!incidence->dtStart().isValid() && !(*it)->dtStart().isValid())) &&
301  (incidence->summary() == (*it)->summary())) {
302  list.append(*it);
303  }
304  }
305  return list;
306  } else {
307  return Incidence::List();
308  }
309 }
310 
312 {
313  if (d->mNotebooks.contains(notebook)) {
314  return false;
315  } else {
316  d->mNotebooks.insert(notebook, isVisible);
317  return true;
318  }
319 }
320 
322 {
323  if (!d->mNotebooks.contains(notebook)) {
324  return false;
325  } else {
326  d->mNotebooks.insert(notebook, isVisible);
327  const QList<Incidence::Ptr> incidences = d->mNotebookIncidences.values(notebook);
328  for (Incidence::Ptr incidence : incidences) {
329  QHash<Incidence::Ptr, bool>::Iterator it = d->mIncidenceVisibility.find(incidence);
330  if (it != d->mIncidenceVisibility.end())
331  *it = isVisible;
332  }
333  return true;
334  }
335 }
336 
338 {
339  if (!d->mNotebooks.contains(notebook)) {
340  return false;
341  } else {
342  return d->mNotebooks.remove(notebook);
343  }
344 }
345 
347 {
348  if (!d->mNotebooks.contains(notebook)) {
349  return false;
350  } else {
351  d->mDefaultNotebook = notebook;
352  return true;
353  }
354 }
355 
357 {
358  return d->mDefaultNotebook;
359 }
360 
362 {
363  return d->mNotebooks.contains(notebook);
364 }
365 
367 {
368  if (d->mIncidenceVisibility.contains(incidence)) {
369  return d->mIncidenceVisibility[incidence];
370  }
371  const QString nuid = notebook(incidence);
372  bool rv;
373  if (d->mNotebooks.contains(nuid)) {
374  rv = d->mNotebooks.value(nuid);
375  } else {
376  // NOTE returns true also for nonexisting notebooks for compatibility
377  rv = true;
378  }
379  d->mIncidenceVisibility[incidence] = rv;
380  return rv;
381 }
382 
384 {
385  QHash<QString, bool>::ConstIterator it = d->mNotebooks.constFind(notebook);
386  return (it != d->mNotebooks.constEnd()) ? *it : true;
387 }
388 
390 {
391  d->mNotebookIncidences.clear();
392  d->mUidToNotebook.clear();
393  d->mIncidenceVisibility.clear();
394 }
395 
397 {
398  if (!inc) {
399  return false;
400  }
401 
402  if (!notebook.isEmpty() &&
403  !incidence(inc->uid(), inc->recurrenceId())) {
404  qCWarning(KCALCORE_LOG) << "cannot set notebook until incidence has been added";
405  return false;
406  }
407 
408  if (d->mUidToNotebook.contains(inc->uid())) {
409  QString old = d->mUidToNotebook.value(inc->uid());
410  if (!old.isEmpty() && notebook != old) {
411  if (inc->hasRecurrenceId()) {
412  qCWarning(KCALCORE_LOG) << "cannot set notebook for child incidences";
413  return false;
414  }
415  // Move all possible children also.
416  Incidence::List list = instances(inc);
418  for (it = list.begin(); it != list.end(); ++it) {
419  d->mNotebookIncidences.remove(old, *it);
420  d->mNotebookIncidences.insert(notebook, *it);
421  }
422  notifyIncidenceChanged(inc); // for removing from old notebook
423  // don not remove from mUidToNotebook to keep deleted incidences
424  d->mNotebookIncidences.remove(old, inc);
425  }
426  }
427  if (!notebook.isEmpty()) {
428  d->mUidToNotebook.insert(inc->uid(), notebook);
429  d->mNotebookIncidences.insert(notebook, inc);
430  qCDebug(KCALCORE_LOG) << "setting notebook" << notebook << "for" << inc->uid();
431  notifyIncidenceChanged(inc); // for inserting into new notebook
432  }
433 
434  return true;
435 }
436 
438 {
439  if (incidence) {
440  return d->mUidToNotebook.value(incidence->uid());
441  } else {
442  return QString();
443  }
444 }
445 
447 {
448  return d->mUidToNotebook.value(uid);
449 }
450 
452 {
453  return d->mNotebookIncidences.uniqueKeys();
454 }
455 
457 {
458  if (notebook.isEmpty()) {
459  return values(d->mNotebookIncidences);
460  } else {
461  return values(d->mNotebookIncidences, notebook);
462  }
463 }
464 
467  EventSortField sortField,
468  SortDirection sortDirection)
469 {
470  if (eventList.isEmpty()) {
471  return Event::List();
472  }
473 
474  Event::List eventListSorted;
475 
476  // Notice we alphabetically presort Summaries first.
477  // We do this so comparison "ties" stay in a nice order.
478  eventListSorted = eventList;
479  switch (sortField) {
480  case EventSortUnsorted:
481  break;
482 
483  case EventSortStartDate:
484  if (sortDirection == SortDirectionAscending) {
485  std::sort(eventListSorted.begin(), eventListSorted.end(), Events::startDateLessThan);
486  } else {
487  std::sort(eventListSorted.begin(), eventListSorted.end(), Events::startDateMoreThan);
488  }
489  break;
490 
491  case EventSortEndDate:
492  if (sortDirection == SortDirectionAscending) {
493  std::sort(eventListSorted.begin(), eventListSorted.end(), Events::endDateLessThan);
494  } else {
495  std::sort(eventListSorted.begin(), eventListSorted.end(), Events::endDateMoreThan);
496  }
497  break;
498 
499  case EventSortSummary:
500  if (sortDirection == SortDirectionAscending) {
501  std::sort(eventListSorted.begin(), eventListSorted.end(), Events::summaryLessThan);
502  } else {
503  std::sort(eventListSorted.begin(), eventListSorted.end(), Events::summaryMoreThan);
504  }
505  break;
506  }
507 
508  return eventListSorted;
509 
510 }
511 
513  const QTimeZone &timeZone,
514  EventSortField sortField,
515  SortDirection sortDirection) const
516 {
517  Event::List el = rawEventsForDate(date, timeZone, sortField, sortDirection);
518  d->mFilter->apply(&el);
519  return el;
520 }
521 
523 {
524  Event::List el = rawEventsForDate(dt);
525  d->mFilter->apply(&el);
526  return el;
527 }
528 
529 Event::List Calendar::events(const QDate &start, const QDate &end,
530  const QTimeZone &timeZone,
531  bool inclusive) const
532 {
533  Event::List el = rawEvents(start, end, timeZone, inclusive);
534  d->mFilter->apply(&el);
535  return el;
536 }
537 
539  SortDirection sortDirection) const
540 {
541  Event::List el = rawEvents(sortField, sortDirection);
542  d->mFilter->apply(&el);
543  return el;
544 }
545 
547 {
548  if (!incidence) {
549  return false;
550  }
551 
552  AddVisitor<Calendar> v(this);
553  return incidence->accept(v, incidence);
554 }
555 
557 {
558  if (!incidence) {
559  return false;
560  }
561 
562  if (beginChange(incidence)) {
563  DeleteVisitor<Calendar> v(this);
564  const bool result = incidence->accept(v, incidence);
565  endChange(incidence);
566  return result;
567  } else {
568  return false;
569  }
570 }
571 
573  const QDateTime &recurrenceId,
574  bool thisAndFuture)
575 {
576  Q_ASSERT(recurrenceId.isValid());
577  if (!incidence || !incidence->recurs() || !recurrenceId.isValid()) {
578  return Incidence::Ptr();
579  }
580 
581  Incidence::Ptr newInc(incidence->clone());
582  newInc->setCreated(QDateTime::currentDateTimeUtc());
583  newInc->setRevision(0);
584  //Recurring exceptions are not support for now
585  newInc->clearRecurrence();
586 
587  newInc->setRecurrenceId(recurrenceId);
588  newInc->setThisAndFuture(thisAndFuture);
589  newInc->setDtStart(recurrenceId);
590 
591  // Calculate and set the new end of the incidence
592  QDateTime end = incidence->dateTime(IncidenceBase::RoleEnd);
593 
594  if (end.isValid()) {
595  if (incidence->allDay()) {
596  qint64 offset = incidence->dtStart().daysTo(recurrenceId);
597  end = end.addDays(offset);
598  } else {
599  qint64 offset = incidence->dtStart().secsTo(recurrenceId);
600  end = end.addSecs(offset);
601  }
602  newInc->setDateTime(end, IncidenceBase::RoleEnd);
603  }
604  return newInc;
605 }
606 
608  const QDateTime &recurrenceId) const
609 {
610  Incidence::Ptr i = event(uid, recurrenceId);
611  if (i) {
612  return i;
613  }
614 
615  i = todo(uid, recurrenceId);
616  if (i) {
617  return i;
618  }
619 
620  i = journal(uid, recurrenceId);
621  return i;
622 }
623 
624 Incidence::Ptr Calendar::deleted(const QString &uid, const QDateTime &recurrenceId) const
625 {
626  Incidence::Ptr i = deletedEvent(uid, recurrenceId);
627  if (i) {
628  return i;
629  }
630 
631  i = deletedTodo(uid, recurrenceId);
632  if (i) {
633  return i;
634  }
635 
636  i = deletedJournal(uid, recurrenceId);
637  return i;
638 }
639 
641 {
642  Incidence::List result;
644  Incidence::List::const_iterator it = incidences.begin();
645  for (; it != incidences.end(); ++it) {
646  if ((*it)->schedulingID() == sid) {
647  result.append(*it);
648  }
649  }
650  return result;
651 }
652 
654 {
656  Incidence::List::const_iterator it = incidences.begin();
657  for (; it != incidences.end(); ++it) {
658  if ((*it)->schedulingID() == uid) {
659  // Touchdown, and the crowd goes wild
660  return *it;
661  }
662  }
663  // Not found
664  return Incidence::Ptr();
665 }
666 
669  TodoSortField sortField,
670  SortDirection sortDirection)
671 {
672  if (todoList.isEmpty()) {
673  return Todo::List();
674  }
675 
676  Todo::List todoListSorted;
677 
678  // Notice we alphabetically presort Summaries first.
679  // We do this so comparison "ties" stay in a nice order.
680 
681  // Note that To-dos may not have Start DateTimes nor due DateTimes.
682 
683  todoListSorted = todoList;
684  switch (sortField) {
685  case TodoSortUnsorted:
686  break;
687 
688  case TodoSortStartDate:
689  if (sortDirection == SortDirectionAscending) {
690  std::sort(todoListSorted.begin(), todoListSorted.end(), Todos::startDateLessThan);
691  } else {
692  std::sort(todoListSorted.begin(), todoListSorted.end(), Todos::startDateMoreThan);
693  }
694  break;
695 
696  case TodoSortDueDate:
697  if (sortDirection == SortDirectionAscending) {
698  std::sort(todoListSorted.begin(), todoListSorted.end(), Todos::dueDateLessThan);
699  } else {
700  std::sort(todoListSorted.begin(), todoListSorted.end(), Todos::dueDateMoreThan);
701  }
702  break;
703 
704  case TodoSortPriority:
705  if (sortDirection == SortDirectionAscending) {
706  std::sort(todoListSorted.begin(), todoListSorted.end(), Todos::priorityLessThan);
707  } else {
708  std::sort(todoListSorted.begin(), todoListSorted.end(), Todos::priorityMoreThan);
709  }
710  break;
711 
713  if (sortDirection == SortDirectionAscending) {
714  std::sort(todoListSorted.begin(), todoListSorted.end(), Todos::percentLessThan);
715  } else {
716  std::sort(todoListSorted.begin(), todoListSorted.end(), Todos::percentMoreThan);
717  }
718  break;
719 
720  case TodoSortSummary:
721  if (sortDirection == SortDirectionAscending) {
722  std::sort(todoListSorted.begin(), todoListSorted.end(), Todos::summaryLessThan);
723  } else {
724  std::sort(todoListSorted.begin(), todoListSorted.end(), Todos::summaryMoreThan);
725  }
726  break;
727 
728  case TodoSortCreated:
729  if (sortDirection == SortDirectionAscending) {
730  std::sort(todoListSorted.begin(), todoListSorted.end(), Todos::createdLessThan);
731  } else {
732  std::sort(todoListSorted.begin(), todoListSorted.end(), Todos::createdMoreThan);
733  }
734  break;
735  }
736 
737  return todoListSorted;
738 }
739 
741  SortDirection sortDirection) const
742 {
743  Todo::List tl = rawTodos(sortField, sortDirection);
744  d->mFilter->apply(&tl);
745  return tl;
746 }
747 
748 Todo::List Calendar::todos(const QDate &date) const
749 {
750  Todo::List el = rawTodosForDate(date);
751  d->mFilter->apply(&el);
752  return el;
753 }
754 
755 Todo::List Calendar::todos(const QDate &start, const QDate &end,
756  const QTimeZone &timeZone, bool inclusive) const
757 {
758  Todo::List tl = rawTodos(start, end, timeZone, inclusive);
759  d->mFilter->apply(&tl);
760  return tl;
761 }
762 
765  JournalSortField sortField,
766  SortDirection sortDirection)
767 {
768  if (journalList.isEmpty()) {
769  return Journal::List();
770  }
771 
772  Journal::List journalListSorted = journalList;
773 
774  switch (sortField) {
775  case JournalSortUnsorted:
776  break;
777 
778  case JournalSortDate:
779  if (sortDirection == SortDirectionAscending) {
780  std::sort(journalListSorted.begin(), journalListSorted.end(), Journals::dateLessThan);
781  } else {
782  std::sort(journalListSorted.begin(), journalListSorted.end(), Journals::dateMoreThan);
783  }
784  break;
785 
786  case JournalSortSummary:
787  if (sortDirection == SortDirectionAscending) {
788  std::sort(journalListSorted.begin(), journalListSorted.end(), Journals::summaryLessThan);
789  } else {
790  std::sort(journalListSorted.begin(), journalListSorted.end(), Journals::summaryMoreThan);
791  }
792  break;
793  }
794 
795  return journalListSorted;
796 }
797 
799  SortDirection sortDirection) const
800 {
801  Journal::List jl = rawJournals(sortField, sortDirection);
802  d->mFilter->apply(&jl);
803  return jl;
804 }
805 
807 {
809  d->mFilter->apply(&el);
810  return el;
811 }
812 
813 // When this is called, the to-dos have already been added to the calendar.
814 // This method is only about linking related to-dos.
815 void Calendar::setupRelations(const Incidence::Ptr &forincidence)
816 {
817  if (!forincidence) {
818  return;
819  }
820 
821  const QString uid = forincidence->uid();
822 
823  // First, go over the list of orphans and see if this is their parent
824  Incidence::List l = values(d->mOrphans, uid);
825  d->mOrphans.remove(uid);
826  if (!l.isEmpty()) {
827  Incidence::List &relations = d->mIncidenceRelations[uid];
828  relations.reserve(relations.count() + l.count());
829  for (int i = 0, end = l.count(); i < end; ++i) {
830  relations.append(l[i]);
831  d->mOrphanUids.remove(l[i]->uid());
832  }
833  }
834 
835  // Now see about this incidences parent
836  if (forincidence->relatedTo().isEmpty() && !forincidence->relatedTo().isEmpty()) {
837  // Incidence has a uid it is related to but is not registered to it yet.
838  // Try to find it
839  Incidence::Ptr parent = incidence(forincidence->relatedTo());
840  if (parent) {
841  // Found it
842 
843  // look for hierarchy loops
844  if (isAncestorOf(forincidence, parent)) {
845  forincidence->setRelatedTo(QString());
846  qCWarning(KCALCORE_LOG) << "hierarchy loop between "
847  << forincidence->uid()
848  << " and " << parent->uid();
849  } else {
850  d->mIncidenceRelations[parent->uid()].append(forincidence);
851  }
852  } else {
853  // Not found, put this in the mOrphans list
854  // Note that the mOrphans dict might contain multiple entries with the
855  // same key! which are multiple children that wait for the parent
856  // incidence to be inserted.
857  d->mOrphans.insert(forincidence->relatedTo(), forincidence);
858  d->mOrphanUids.insert(forincidence->uid(), forincidence);
859  }
860  }
861 }
862 
863 // If a to-do with sub-to-dos is deleted, move it's sub-to-dos to the orphan list
865 {
866  if (!incidence) {
867  qCDebug(KCALCORE_LOG) << "Warning: incidence is 0";
868  return;
869  }
870 
871  const QString uid = incidence->uid();
872 
873  for (const Incidence::Ptr &i : qAsConst(d->mIncidenceRelations[uid])) {
874  if (!d->mOrphanUids.contains(i->uid())) {
875  d->mOrphans.insert(uid, i);
876  d->mOrphanUids.insert(i->uid(), i);
877  i->setRelatedTo(uid);
878  }
879  }
880 
881  const QString parentUid = incidence->relatedTo();
882 
883  // If this incidence is related to something else, tell that about it
884  if (!parentUid.isEmpty()) {
885  Incidence::List &relations = d->mIncidenceRelations[parentUid];
886  relations.erase(
887  std::remove(relations.begin(), relations.end(), incidence),
888  relations.end());
889  }
890 
891  // Remove this one from the orphans list
892  if (d->mOrphanUids.remove(uid)) {
893  // This incidence is located in the orphans list - it should be removed
894  // Since the mOrphans dict might contain the same key (with different
895  // child incidence pointers!) multiple times, take care that we remove
896  // the correct one. So we need to remove all items with the given
897  // parent UID, and readd those that are not for this item. Also, there
898  // might be other entries with differnet UID that point to this
899  // incidence (this might happen when the relatedTo of the item is
900  // changed before its parent is inserted. This might happen with
901  // groupware servers....). Remove them, too
902  QStringList relatedToUids;
903 
904  // First, create a list of all keys in the mOrphans list which point
905  // to the removed item
906  relatedToUids << incidence->relatedTo();
908  it != d->mOrphans.end(); ++it) {
909  if (it.value()->uid() == uid) {
910  relatedToUids << it.key();
911  }
912  }
913 
914  // now go through all uids that have one entry that point to the incidence
915  for (QStringList::const_iterator uidit = relatedToUids.constBegin();
916  uidit != relatedToUids.constEnd(); ++uidit) {
917  Incidence::List tempList;
918  // Remove all to get access to the remaining entries
919  const Incidence::List l = values(d->mOrphans, *uidit);
920  d->mOrphans.remove(*uidit);
921  for (const Incidence::Ptr &i : l) {
922  if (i != incidence) {
923  tempList.append(i);
924  }
925  }
926  // Readd those that point to a different orphan incidence
927  for (Incidence::List::Iterator incit = tempList.begin();
928  incit != tempList.end(); ++incit) {
929  d->mOrphans.insert(*uidit, *incit);
930  }
931  }
932  }
933 
934  // Make sure the deleted incidence doesn't relate to a non-deleted incidence,
935  // since that would cause trouble in MemoryCalendar::close(), as the deleted
936  // incidences are destroyed after the non-deleted incidences. The destructor
937  // of the deleted incidences would then try to access the already destroyed
938  // non-deleted incidence, which would segfault.
939  //
940  // So in short: Make sure dead incidences don't point to alive incidences
941  // via the relation.
942  //
943  // This crash is tested in MemoryCalendarTest::testRelationsCrash().
944 // incidence->setRelatedTo( Incidence::Ptr() );
945 }
946 
948  const Incidence::Ptr &incidence) const
949 {
950  if (!incidence || incidence->relatedTo().isEmpty()) {
951  return false;
952  } else if (incidence->relatedTo() == ancestor->uid()) {
953  return true;
954  } else {
955  return isAncestorOf(ancestor, this->incidence(incidence->relatedTo()));
956  }
957 }
958 
960 {
961  return d->mIncidenceRelations[uid];
962 }
963 
965 {
966 }
967 
969 {
970  Q_UNUSED(modified);
971  Q_UNUSED(calendar);
972 }
973 
975 {
976  Q_UNUSED(incidence);
977 }
978 
980 {
981  Q_UNUSED(incidence);
982 }
983 
985 {
986  Q_UNUSED(incidence);
987 }
988 
990 {
991  Q_UNUSED(incidence);
992  Q_UNUSED(calendar);
993 }
994 
996 {
997  Q_UNUSED(incidence);
998 }
999 
1001 {
1002  if (!observer) {
1003  return;
1004  }
1005 
1006  if (!d->mObservers.contains(observer)) {
1007  d->mObservers.append(observer);
1008  } else {
1009  d->mNewObserver = true;
1010  }
1011 }
1012 
1014 {
1015  if (!observer) {
1016  return;
1017  } else {
1018  d->mObservers.removeAll(observer);
1019  }
1020 }
1021 
1023 {
1024  return false;
1025 }
1026 
1027 void Calendar::setModified(bool modified)
1028 {
1029  if (modified != d->mModified || d->mNewObserver) {
1030  d->mNewObserver = false;
1031  for (CalendarObserver *observer : qAsConst(d->mObservers)) {
1032  observer->calendarModified(modified, this);
1033  }
1034  d->mModified = modified;
1035  }
1036 }
1037 
1039 {
1040  return d->mModified;
1041 }
1042 
1044 {
1045  return true;
1046 }
1047 
1049 {
1050  return true;
1051 }
1052 
1053 void Calendar::incidenceUpdated(const QString &uid, const QDateTime &recurrenceId)
1054 {
1055  Incidence::Ptr inc = incidence(uid, recurrenceId);
1056 
1057  if (!inc) {
1058  return;
1059  }
1060 
1061  inc->setLastModified(QDateTime::currentDateTimeUtc());
1062  // we should probably update the revision number here,
1063  // or internally in the Event itself when certain things change.
1064  // need to verify with ical documentation.
1065 
1067 
1068  setModified(true);
1069 }
1070 
1072 {
1073  Q_UNUSED(timeZone);
1074 }
1075 
1077 {
1078  if (!incidence) {
1079  return;
1080  }
1081 
1082  if (!d->mObserversEnabled) {
1083  return;
1084  }
1085 
1086  for (CalendarObserver *observer : qAsConst(d->mObservers)) {
1087  observer->calendarIncidenceAdded(incidence);
1088  }
1089 
1091  const auto dt = incidence->dateTime(role);
1092  if (dt.isValid() && dt.timeZone() != QTimeZone::utc()) {
1093  if (!d->mTimeZones.contains(dt.timeZone())) {
1094  d->mTimeZones.push_back(dt.timeZone());
1095  }
1096  }
1097  }
1098 }
1099 
1101 {
1102  if (!incidence) {
1103  return;
1104  }
1105 
1106  if (!d->mObserversEnabled) {
1107  return;
1108  }
1109 
1110  for (CalendarObserver *observer : qAsConst(d->mObservers)) {
1111  observer->calendarIncidenceChanged(incidence);
1112  }
1113 }
1114 
1116 {
1117  if (!incidence) {
1118  return;
1119  }
1120 
1121  if (!d->mObserversEnabled) {
1122  return;
1123  }
1124 
1125  for (CalendarObserver *observer : qAsConst(d->mObservers)) {
1126  observer->calendarIncidenceAboutToBeDeleted(incidence);
1127  }
1128 }
1129 
1131 {
1132  if (!incidence) {
1133  return;
1134  }
1135 
1136  if (!d->mObserversEnabled) {
1137  return;
1138  }
1139 
1140  for (CalendarObserver *observer : qAsConst(d->mObservers)) {
1141  observer->calendarIncidenceDeleted(incidence, this);
1142  }
1143 }
1144 
1146 {
1147  if (!incidence) {
1148  return;
1149  }
1150 
1151  if (!d->mObserversEnabled) {
1152  return;
1153  }
1154 
1155  for (CalendarObserver *observer : qAsConst(d->mObservers)) {
1156  observer->calendarIncidenceAdditionCanceled(incidence);
1157  }
1158 }
1159 
1161 {
1162  setModified(true);
1163 }
1164 
1166 {
1167  d->mProductId = id;
1168 }
1169 
1171 {
1172  return d->mProductId;
1173 }
1174 
1177  const Todo::List &todos,
1178  const Journal::List &journals)
1179 {
1181  incidences.reserve(events.count() + todos.count() + journals.count());
1182 
1183  int i, end;
1184  for (i = 0, end = events.count(); i < end; ++i) {
1185  incidences.append(events[i]);
1186  }
1187 
1188  for (i = 0, end = todos.count(); i < end; ++i) {
1189  incidences.append(todos[i]);
1190  }
1191 
1192  for (i = 0, end = journals.count(); i < end; ++i) {
1193  incidences.append(journals[i]);
1194  }
1195 
1196  return incidences;
1197 }
1198 
1200 {
1201  Q_UNUSED(incidence);
1202  return true;
1203 }
1204 
1206 {
1207  Q_UNUSED(incidence);
1208  return true;
1209 }
1210 
1212 {
1213  d->mObserversEnabled = enabled;
1214 }
1215 
1217  const QDateTime &from, const QDateTime &to) const
1218 {
1219  QDateTime preTime = from.addSecs(-1);
1220 
1221  Alarm::List alarmlist = incidence->alarms();
1222  for (int i = 0, iend = alarmlist.count(); i < iend; ++i) {
1223  if (alarmlist[i]->enabled()) {
1224  QDateTime dt = alarmlist[i]->nextRepetition(preTime);
1225  if (dt.isValid() && dt <= to) {
1226  qCDebug(KCALCORE_LOG) << incidence->summary() << "':" << dt.toString();
1227  alarms.append(alarmlist[i]);
1228  }
1229  }
1230  }
1231 }
1232 
1234  const Incidence::Ptr &incidence,
1235  const QDateTime &from,
1236  const QDateTime &to) const
1237 {
1238  QDateTime dt;
1239  bool endOffsetValid = false;
1240  Duration endOffset(0);
1241  Duration period(from, to);
1242 
1243  Alarm::List alarmlist = incidence->alarms();
1244  for (int i = 0, iend = alarmlist.count(); i < iend; ++i) {
1245  Alarm::Ptr a = alarmlist[i];
1246  if (a->enabled()) {
1247  if (a->hasTime()) {
1248  // The alarm time is defined as an absolute date/time
1249  dt = a->nextRepetition(from.addSecs(-1));
1250  if (!dt.isValid() || dt > to) {
1251  continue;
1252  }
1253  } else {
1254  // Alarm time is defined by an offset from the event start or end time.
1255  // Find the offset from the event start time, which is also used as the
1256  // offset from the recurrence time.
1257  Duration offset(0);
1258  if (a->hasStartOffset()) {
1259  offset = a->startOffset();
1260  } else if (a->hasEndOffset()) {
1261  offset = a->endOffset();
1262  if (!endOffsetValid) {
1263  endOffset = Duration(incidence->dtStart(),
1264  incidence->dateTime(Incidence::RoleAlarmEndOffset));
1265  endOffsetValid = true;
1266  }
1267  }
1268 
1269  // Find the incidence's earliest alarm
1270  QDateTime alarmStart =
1271  offset.end(a->hasEndOffset() ? incidence->dateTime(Incidence::RoleAlarmEndOffset) :
1272  incidence->dtStart());
1273  if (alarmStart > to) {
1274  continue;
1275  }
1276  QDateTime baseStart = incidence->dtStart();
1277  if (from > alarmStart) {
1278  alarmStart = from; // don't look earlier than the earliest alarm
1279  baseStart = (-offset).end((-endOffset).end(alarmStart));
1280  }
1281 
1282  // Adjust the 'alarmStart' date/time and find the next recurrence at or after it.
1283  // Treate the two offsets separately in case one is daily and the other not.
1284  dt = incidence->recurrence()->getNextDateTime(baseStart.addSecs(-1));
1285  if (!dt.isValid() ||
1286  (dt = endOffset.end(offset.end(dt))) > to) { // adjust 'dt' to get the alarm time
1287  // The next recurrence is too late.
1288  if (!a->repeatCount()) {
1289  continue;
1290  }
1291 
1292  // The alarm has repetitions, so check whether repetitions of previous
1293  // recurrences fall within the time period.
1294  bool found = false;
1295  Duration alarmDuration = a->duration();
1296  for (QDateTime base = baseStart;
1297  (dt = incidence->recurrence()->getPreviousDateTime(base)).isValid();
1298  base = dt) {
1299  if (a->duration().end(dt) < base) {
1300  break; // this recurrence's last repetition is too early, so give up
1301  }
1302 
1303  // The last repetition of this recurrence is at or after 'alarmStart' time.
1304  // Check if a repetition occurs between 'alarmStart' and 'to'.
1305  int snooze = a->snoozeTime().value(); // in seconds or days
1306  if (a->snoozeTime().isDaily()) {
1307  Duration toFromDuration(dt, base);
1308  int toFrom = toFromDuration.asDays();
1309  if (a->snoozeTime().end(from) <= to ||
1310  (toFromDuration.isDaily() && toFrom % snooze == 0) ||
1311  (toFrom / snooze + 1) * snooze <= toFrom + period.asDays()) {
1312  found = true;
1313 #ifndef NDEBUG
1314  // for debug output
1315  dt = offset.end(dt).addDays(((toFrom - 1) / snooze + 1) * snooze);
1316 #endif
1317  break;
1318  }
1319  } else {
1320  int toFrom = dt.secsTo(base);
1321  if (period.asSeconds() >= snooze ||
1322  toFrom % snooze == 0 ||
1323  (toFrom / snooze + 1) * snooze <= toFrom + period.asSeconds()) {
1324  found = true;
1325 #ifndef NDEBUG
1326  // for debug output
1327  dt = offset.end(dt).addSecs(((toFrom - 1) / snooze + 1) * snooze);
1328 #endif
1329  break;
1330  }
1331  }
1332  }
1333  if (!found) {
1334  continue;
1335  }
1336  }
1337  }
1338  qCDebug(KCALCORE_LOG) << incidence->summary() << "':" << dt.toString();
1339  alarms.append(a);
1340  }
1341  }
1342 }
1343 
1345 {
1346  d->batchAddingInProgress = true;
1347 }
1348 
1350 {
1351  d->batchAddingInProgress = false;
1352 }
1353 
1355 {
1356  return d->batchAddingInProgress;
1357 }
1358 
1360 {
1361  d->mDeletionTracking = enable;
1362 }
1363 
1365 {
1366  return d->mDeletionTracking;
1367 }
1368 
1369 void Calendar::virtual_hook(int id, void *data)
1370 {
1371  Q_UNUSED(id);
1372  Q_UNUSED(data);
1373  Q_ASSERT(false);
1374 }
1375 
Do not sort Journals.
Definition: calendar.h:92
JournalSortField
Calendar Journal sort keys.
Definition: calendar.h:91
Sort Todos alphabetically, by summary.
Definition: calendar.h:84
QString toString(Qt::DateFormat format) const const
virtual Incidence::Ptr incidenceFromSchedulingID(const QString &sid) const
Returns the Incidence associated with the given scheduling identifier.
Definition: calendar.cpp:653
virtual void calendarModified(bool modified, Calendar *calendar)
Notify the Observer that a Calendar has been modified.
Definition: calendar.cpp:968
typedef Iterator
void setProductId(const QString &id)
Sets the calendar Product ID to id.
Definition: calendar.cpp:1165
TodoSortField
Calendar Todo sort keys.
Definition: calendar.h:78
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:1216
void setObserversEnabled(bool enabled)
Let Calendar subclasses notify that they enabled an Observer.
Definition: calendar.cpp:1211
Represents the main calendar class.
Definition: calendar.h:119
void setFilter(CalFilter *filter)
Sets the calendar filter.
Definition: calendar.cpp:223
CalFilter * filter() const
Returns the calendar filter.
Definition: calendar.cpp:233
virtual bool endChange(const Incidence::Ptr &incidence)
Flag that a change to a Calendar Incidence has completed.
Definition: calendar.cpp:1205
The CalendarObserver class.
Definition: calendar.h:1207
static Event::List sortEvents(const Event::List &eventList, EventSortField sortField, SortDirection sortDirection)
Sort a list of Events.
Definition: calendar.cpp:466
virtual void calendarIncidenceAboutToBeDeleted(const Incidence::Ptr &incidence)
Notify the Observer that an Incidence will be removed.
Definition: calendar.cpp:984
This class provides the interface for a visitor of calendar components.
Definition: visitor.h:31
QStringList categories() const
Returns a list of all categories used by Incidences in this Calendar.
Definition: calendar.cpp:238
void setModified(bool modified)
Sets if the calendar has been modified.
Definition: calendar.cpp:1027
virtual Journal::List rawJournalsForDate(const QDate &date) const =0
Returns an unfiltered list of all Journals for on the specified date.
Incidence::Ptr deleted(const QString &uid, const QDateTime &recurrenceId={}) const
Returns the deleted Incidence associated with the given unique identifier.
Definition: calendar.cpp:624
virtual void calendarIncidenceChanged(const Incidence::Ptr &incidence)
Notify the Observer that an Incidence has been modified.
Definition: calendar.cpp:979
void append(const T &value)
virtual Event::Ptr event(const QString &uid, const QDateTime &recurrenceId={}) const =0
Returns the Event associated with the given unique identifier.
QVector::iterator begin()
Sort Todos by priority.
Definition: calendar.h:82
Person owner() const
Returns the owner of the calendar.
Represents a person, by name and email address.
Definition: person.h:38
virtual Todo::Ptr todo(const QString &uid, const QDateTime &recurrenceId={}) const =0
Returns the Todo associated with the given unique identifier.
virtual Event::List events(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const
Returns a sorted, filtered list of all Events for this Calendar.
Definition: calendar.cpp:538
virtual void calendarIncidenceAdditionCanceled(const Incidence::Ptr &incidence)
Notify the Observer that an addition of Incidence has been canceled.
Definition: calendar.cpp:995
QDateTime end(const QDateTime &start) const
Computes a duration end time by adding the number of seconds or days in the duration to the specified...
Definition: duration.cpp:172
Sort Todos chronologically, by creation date.
Definition: calendar.h:85
int size() const const
QVector::const_iterator constEnd() const const
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
QVector::iterator erase(QVector::iterator begin, QVector::iterator end)
void setTimeZone(const QTimeZone &timeZone)
Sets the default time specification zone used for creating or modifying incidences in the Calendar...
Definition: calendar.cpp:160
QSharedPointer< Incidence > Ptr
A shared pointer to an Incidence.
Definition: incidence.h:115
QHash::const_iterator constFind(const Key &key) const const
virtual void removeRelations(const Incidence::Ptr &incidence)
Removes all Relations from an Incidence.
Definition: calendar.cpp:864
virtual Journal::Ptr deletedJournal(const QString &uid, const QDateTime &recurrenceId={}) const =0
Returns the deleted Journal associated with the given unique identifier.
bool isAncestorOf(const Incidence::Ptr &ancestor, const Incidence::Ptr &incidence) const
Checks if ancestor is an ancestor of incidence.
Definition: calendar.cpp:947
bool hasValidNotebook(const QString &notebook) const
Check if calendar knows about the given notebook.
Definition: calendar.cpp:361
QByteArray timeZoneId() const
Returns the time zone ID used for creating or modifying incidences in the calendar.
Definition: calendar.cpp:197
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:1233
typedef ConstIterator
int asDays() const
Returns the length of the duration in days.
Definition: duration.cpp:193
virtual QString notebook(const Incidence::Ptr &incidence) const
Get incidence&#39;s notebook.
Definition: calendar.cpp:437
void setTimeZoneId(const QByteArray &timeZoneId)
Sets the time zone ID used for creating or modifying incidences in the Calendar.
Definition: calendar.cpp:176
virtual Alarm::List alarms(const QDateTime &from, const QDateTime &to, bool excludeBlockedAlarms=false) const =0
Returns a list of Alarms within a time range for this Calendar.
void notifyIncidenceAboutToBeDeleted(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they will remove an Incidence.
Definition: calendar.cpp:1115
Sort Events alphabetically, by summary.
Definition: calendar.h:72
virtual void doSetTimeZone(const QTimeZone &timeZone)
Let Calendar subclasses set the time specification.
Definition: calendar.cpp:1071
~Calendar() override
Destroys the calendar.
Definition: calendar.cpp:144
Do not sort Events.
Definition: calendar.h:69
virtual Todo::List rawTodos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const =0
Returns a sorted, unfiltered list of all Todos for this Calendar.
QTimeZone timeZone() const
Get the time zone used for creating or modifying incidences in the Calendar.
Definition: calendar.cpp:171
void customPropertyUpdated() override
Definition: calendar.cpp:1160
bool isModified() const
Determine the calendar&#39;s modification status.
Definition: calendar.cpp:1038
QVector< V > values(const QMultiHash< K, V > &c)
Make a QHash::value that returns a QVector.
Definition: calendar.cpp:47
virtual Event::Ptr deletedEvent(const QString &uid, const QDateTime &recurrenceId={}) const =0
Returns the deleted Event associated with the given unique identifier.
void notifyIncidenceChanged(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they modified an Incidence.
Definition: calendar.cpp:1100
void notifyIncidenceAdded(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they inserted an Incidence.
Definition: calendar.cpp:1076
Represents a span of time measured in seconds or days.
Definition: duration.h:44
Role for determining an incidence&#39;s starting timezone.
bool deleteNotebook(const QString &notebook)
Delete notebook information from calendar.
Definition: calendar.cpp:337
virtual void calendarIncidenceDeleted(const Incidence::Ptr &incidence, const Calendar *calendar)
Notify the Observer that an Incidence has been removed.
Definition: calendar.cpp:989
void append(const T &value)
void setDeletionTracking(bool enable)
Enables or disabled deletion tracking.
Definition: calendar.cpp:1359
QHash::const_iterator constEnd() const const
bool addNotebook(const QString &notebook, bool isVisible)
Add notebook information into calendar.
Definition: calendar.cpp:311
virtual Event::List rawEventsForDate(const QDateTime &dt) const =0
Returns an unfiltered list of all Events which occur on the given timestamp.
void shiftTimes(const QTimeZone &oldZone, const QTimeZone &newZone)
Shifts the times of all incidences so that they appear at the same clock time as before but in a new ...
Definition: calendar.cpp:202
Role for determining an incidence&#39;s ending timezone.
Sort Todos chronologically, by start date.
Definition: calendar.h:80
QTimeZone utc()
Calendar(const QTimeZone &timeZone)
Constructs a calendar with a specified time zone timeZone.
Definition: calendar.cpp:128
bool deletionTracking() const
Returns if deletion tracking is enabled.
Definition: calendar.cpp:1364
void registerObserver(CalendarObserver *observer)
Registers an Observer for this Calendar.
Definition: calendar.cpp:1000
EventSortField
Calendar Event sort keys.
Definition: calendar.h:68
bool isEmpty() const const
bool isDaily() const
Returns whether the duration is specified in terms of days rather than seconds.
Definition: duration.cpp:183
QHash::iterator begin()
This file is part of the API for handling calendar data and defines the Calendar class.
QTimeZone systemTimeZone()
QString productId() const
Returns the calendar&#39;s Product ID.
virtual void calendarIncidenceAdded(const Incidence::Ptr &incidence)
Notify the Observer that an Incidence has been inserted.
Definition: calendar.cpp:974
void incidenceUpdated(const QString &uid, const QDateTime &recurrenceId) override
The Observer interface.
Definition: calendar.cpp:1053
static Incidence::List mergeIncidenceList(const Event::List &events, const Todo::List &todos, const Journal::List &journals)
Create a merged list of Events, Todos, and Journals.
Definition: calendar.cpp:1176
virtual bool beginChange(const Incidence::Ptr &incidence)
Flag that a change to a Calendar Incidence is starting.
Definition: calendar.cpp:1199
virtual Incidence::List duplicates(const Incidence::Ptr &incidence)
List all possible duplicate incidences.
Definition: calendar.cpp:292
Sort Events chronologically, by end date.
Definition: calendar.h:71
virtual Todo::Ptr deletedTodo(const QString &uid, const QDateTime &recurrenceId={}) const =0
Returns the deleted Todo associated with the given unique identifier.
QVector< Ptr > List
List of events.
Definition: event.h:53
virtual void endBatchAdding()
Tells the Calendar that you stoped adding a batch of incidences.
Definition: calendar.cpp:1349
void notifyIncidenceAdditionCanceled(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they canceled addition of an Incidence.
Definition: calendar.cpp:1145
void reserve(int size)
QHash::iterator find(const Key &key)
Sort in ascending order (first to last)
Definition: calendar.h:61
QVector< Ptr > List
List of to-dos.
Definition: todo.h:42
virtual void virtual_hook(int id, void *data)
Definition: calendar.cpp:1369
bool updateNotebook(const QString &notebook, bool isVisible)
Update notebook information in calendar.
Definition: calendar.cpp:321
QString defaultNotebook() const
Get uid of default notebook.
Definition: calendar.cpp:356
Sort Todos chronologically, by due date.
Definition: calendar.h:81
bool isValid() const const
virtual Todo::List todos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const
Returns a sorted, filtered list of all Todos for this Calendar.
Definition: calendar.cpp:740
virtual void startBatchAdding()
Call this to tell the calendar that you&#39;re adding a batch of incidences.
Definition: calendar.cpp:1344
bool isVisible(const Incidence::Ptr &incidence) const
Check if incidence is visible.
Definition: calendar.cpp:366
virtual bool save()
Syncs changes in memory to persistent storage.
Definition: calendar.cpp:1043
QVector::const_iterator constBegin() const const
static Journal::List sortJournals(const Journal::List &journalList, JournalSortField sortField, SortDirection sortDirection)
Sort a list of Journals.
Definition: calendar.cpp:764
static Todo::List sortTodos(const Todo::List &todoList, TodoSortField sortField, SortDirection sortDirection)
Sort a list of Todos.
Definition: calendar.cpp:668
bool batchAdding() const
Definition: calendar.cpp:1354
qint64 secsTo(const QDateTime &other) const const
Do not sort Todos.
Definition: calendar.h:79
bool isEmpty() const const
virtual Incidence::List instances(const Incidence::Ptr &incidence) const
Returns an unfiltered list of all exceptions of this recurring incidence.
Definition: calendar.cpp:272
SortDirection
Calendar Incidence sort directions.
Definition: calendar.h:60
static Incidence::Ptr createException(const Incidence::Ptr &incidence, const QDateTime &recurrenceId, bool thisAndFuture=false)
Creates an exception for an occurrence from a recurring Incidence.
Definition: calendar.cpp:572
Incidence::Ptr incidence(const QString &uid, const QDateTime &recurrenceId={}) const
Returns the Incidence associated with the given unique identifier.
Definition: calendar.cpp:607
typedef ConstIterator
Role for determining an incidence&#39;s dtEnd, will return an invalid QDateTime if the incidence does not...
void unregisterObserver(CalendarObserver *observer)
Unregisters an Observer for this Calendar.
Definition: calendar.cpp:1013
QVector< Ptr > List
List of journals.
Definition: journal.h:41
virtual Journal::List journals(JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const
Returns a sorted, filtered list of all Journals for this Calendar.
Definition: calendar.cpp:798
int count(const T &value) const const
QVector< Ptr > List
List of incidences.
Definition: incidence.h:120
bool isValid() const const
Sort Events chronologically, by start date.
Definition: calendar.h:70
virtual Event::List eventInstances(const Incidence::Ptr &event, EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const =0
Returns a sorted, unfiltered list of all possible instances for this recurring Event.
void push_back(const T &value)
Sort Todos by percentage completed.
Definition: calendar.h:83
virtual bool setNotebook(const Incidence::Ptr &incidence, const QString &notebook)
Associate notebook for an incidence.
Definition: calendar.cpp:396
virtual void setupRelations(const Incidence::Ptr &incidence)
Setup Relations for an Incidence.
Definition: calendar.cpp:815
Provides a filter for calendars.
Definition: calfilter.h:43
void notifyIncidenceDeleted(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they removed an Incidence.
Definition: calendar.cpp:1130
typedef const_iterator
int asSeconds() const
Returns the length of the duration in seconds.
Definition: duration.cpp:188
bool setDefaultNotebook(const QString &notebook)
set DefaultNotebook information to calendar.
Definition: calendar.cpp:346
virtual Event::List rawEvents(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const =0
Returns a sorted, unfiltered list of all Events for this Calendar.
QHash::iterator end()
virtual bool isSaving() const
Determine if the calendar is currently being saved.
Definition: calendar.cpp:1022
QList::const_iterator constEnd() const const
void setOwner(const Person &owner)
Sets the owner of the calendar to owner.
Definition: calendar.cpp:154
QList::const_iterator constBegin() const const
This file is part of the API for handling calendar data and defines the CalFilter class...
QDateTime addSecs(qint64 s) const const
Sort Journals alphabetically, by summary.
Definition: calendar.h:94
virtual bool deleteIncidence(const Incidence::Ptr &incidence)
Removes an Incidence from the calendar.
Definition: calendar.cpp:556
typename QHash< Key, T >::iterator find(const Key &key, const T &value)
QObject * parent() const const
virtual ~CalendarObserver()
Destructor.
Definition: calendar.cpp:964
QDateTime addDays(qint64 ndays) const const
virtual Journal::Ptr journal(const QString &uid, const QDateTime &recurrenceId={}) const =0
Returns the Journal associated with the given unique identifier.
virtual bool addIncidence(const Incidence::Ptr &incidence)
Inserts an Incidence into the calendar.
Definition: calendar.cpp:546
virtual Journal::List rawJournals(JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const =0
Returns a sorted, unfiltered list of all Journals for this Calendar.
QVector::iterator end()
virtual Todo::List rawTodosForDate(const QDate &date) const =0
Returns an unfiltered list of all Todos which due on the specified date.
virtual Incidence::List incidences() const
Returns a filtered list of all Incidences for this Calendar.
Definition: calendar.cpp:262
QDateTime currentDateTimeUtc()
Incidence::List relations(const QString &uid) const
Returns a list of incidences that have a relation of RELTYPE parent to incidence uid.
Definition: calendar.cpp:959
void filterChanged()
Emitted when setFilter() is called.
virtual QStringList notebooks() const
List all uids of notebooks currently in the memory.
Definition: calendar.cpp:451
Namespace for all KCalendarCore types.
Definition: alarm.h:36
virtual bool reload()
Loads the calendar contents from storage.
Definition: calendar.cpp:1048
virtual Incidence::List incidencesFromSchedulingID(const QString &sid) const
Searches all events and todos for an incidence with this scheduling identifier.
Definition: calendar.cpp:640
Role for an incidence alarm&#39;s ending offset date/time.
virtual Todo::List todoInstances(const Incidence::Ptr &todo, TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const =0
Returns a sorted, unfiltered list of all possible instances for this recurring Todo.
virtual void clearNotebookAssociations()
Clears notebook associations from hash-tables for incidences.
Definition: calendar.cpp:389
Sort Journals chronologically by date.
Definition: calendar.h:93
virtual Incidence::List rawIncidences() const
Returns an unfiltered list of all Incidences for this Calendar.
Definition: calendar.cpp:267
virtual Journal::List journalInstances(const Incidence::Ptr &journal, JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const =0
Returns a sorted, unfiltered list of all instances for this recurring Journal.
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sun Oct 25 2020 22:55:11 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.