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

KDE's Doxygen guidelines are available online.