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 <pbrown@kde.org>
5  SPDX-FileCopyrightText: 2000-2004 Cornelius Schumacher <schumacher@kde.org>
6  SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
7  SPDX-FileCopyrightText: 2006 David Jarvie <djarvie@kde.org>
8  SPDX-FileCopyrightText: 2021 Boris Shmarin <b.shmarin@omp.ru>
9 
10  SPDX-License-Identifier: LGPL-2.0-or-later
11 */
12 /**
13  @file
14  This file is part of the API for handling calendar data and
15  defines the Calendar class.
16 
17  @brief
18  Represents the main calendar class.
19 
20  @author Preston Brown <pbrown@kde.org>
21  @author Cornelius Schumacher <schumacher@kde.org>
22  @author Reinhold Kainhofer <reinhold@kainhofer.com>
23  @author David Jarvie <djarvie@kde.org>
24 */
25 #include "calendar.h"
26 #include "calendar_p.h"
27 #include "calfilter.h"
28 #include "icaltimezones_p.h"
29 #include "sorting.h"
30 #include "visitor.h"
31 
32 #include "kcalendarcore_debug.h"
33 
34 
35 extern "C" {
36 #include <libical/icaltimezone.h>
37 }
38 
39 #include <algorithm>
40 #include <set>
41 
42 using namespace KCalendarCore;
43 
44 /**
45  Template for a class that implements a visitor for adding an Incidence
46  to a resource supporting addEvent(), addTodo() and addJournal() calls.
47 */
48 template<class T>
49 class AddVisitor : public Visitor
50 {
51 public:
52  AddVisitor(T *r)
53  : mResource(r)
54  {
55  }
56 
57  bool visit(const Event::Ptr &e) override
58  {
59  return mResource->addEvent(e);
60  }
61  bool visit(const Todo::Ptr &t) override
62  {
63  return mResource->addTodo(t);
64  }
65  bool visit(const Journal::Ptr &j) override
66  {
67  return mResource->addJournal(j);
68  }
69  bool visit(const FreeBusy::Ptr &) override
70  {
71  return false;
72  }
73 
74 private:
75  T *mResource;
76 };
77 
78 /**
79  Template for a class that implements a visitor for deleting an Incidence
80  from a resource supporting deleteEvent(), deleteTodo() and deleteJournal()
81  calls.
82 */
83 template<class T>
84 class DeleteVisitor : public Visitor
85 {
86 public:
87  DeleteVisitor(T *r)
88  : mResource(r)
89  {
90  }
91 
92  bool visit(const Event::Ptr &e) override
93  {
94  mResource->deleteEvent(e);
95  return true;
96  }
97  bool visit(const Todo::Ptr &t) override
98  {
99  mResource->deleteTodo(t);
100  return true;
101  }
102  bool visit(const Journal::Ptr &j) override
103  {
104  mResource->deleteJournal(j);
105  return true;
106  }
107  bool visit(const FreeBusy::Ptr &) override
108  {
109  return false;
110  }
111 
112 private:
113  T *mResource;
114 };
115 //@endcond
116 
118  : d(new KCalendarCore::Calendar::Private)
119 {
120  if (timeZone.isValid()) {
121  d->mTimeZone = timeZone;
122  } else {
123  d->mTimeZone = QTimeZone::systemTimeZone();
124  }
125 }
126 
127 Calendar::Calendar(const QByteArray &timeZoneId)
128  : d(new KCalendarCore::Calendar::Private)
129 {
131 }
132 
134 {
135  delete d;
136 }
137 
138 Person Calendar::owner() const
139 {
140  return d->mOwner;
141 }
142 
143 void Calendar::setOwner(const Person &owner)
144 {
145  if (owner != d->mOwner) {
146  d->mOwner = owner;
147  setModified(true);
149  }
150 }
151 
152 void Calendar::setTimeZone(const QTimeZone &timeZone)
153 {
154  if (timeZone.isValid()) {
155  d->mTimeZone = timeZone;
156  } else {
157  d->mTimeZone = QTimeZone::systemTimeZone();
158  }
159 
160  doSetTimeZone(d->mTimeZone);
161 }
162 
164 {
165  return d->mTimeZone;
166 }
167 
168 void Calendar::setTimeZoneId(const QByteArray &timeZoneId)
169 {
170  d->mTimeZone = d->timeZoneIdSpec(timeZoneId);
171 
172  doSetTimeZone(d->mTimeZone); // NOLINT false clang-analyzer-optin.cplusplus.VirtualCall
173 }
174 
175 //@cond PRIVATE
176 QTimeZone Calendar::Private::timeZoneIdSpec(const QByteArray &timeZoneId)
177 {
178  if (timeZoneId == QByteArrayLiteral("UTC")) {
179  return QTimeZone::utc();
180  }
181  auto tz = QTimeZone(timeZoneId);
182  if (tz.isValid()) {
183  return tz;
184  }
185  return QTimeZone::systemTimeZone();
186 }
187 //@endcond
188 
190 {
191  return d->mTimeZone.id();
192 }
193 
194 void Calendar::shiftTimes(const QTimeZone &oldZone, const QTimeZone &newZone)
195 {
196  setTimeZone(newZone);
197 
198  int i;
199  int end;
200  Event::List ev = events();
201  for (i = 0, end = ev.count(); i < end; ++i) {
202  ev[i]->shiftTimes(oldZone, newZone);
203  }
204 
205  Todo::List to = todos();
206  for (i = 0, end = to.count(); i < end; ++i) {
207  to[i]->shiftTimes(oldZone, newZone);
208  }
209 
210  Journal::List jo = journals();
211  for (i = 0, end = jo.count(); i < end; ++i) {
212  jo[i]->shiftTimes(oldZone, newZone);
213  }
214 }
215 
217 {
218  if (filter) {
219  d->mFilter = filter;
220  } else {
221  d->mFilter = d->mDefaultFilter;
222  }
224 }
225 
227 {
228  return d->mFilter;
229 }
230 
232 {
233  const Incidence::List rawInc = rawIncidences();
234  QStringList uniqueCategories;
235  QStringList thisCats;
236  // @TODO: For now just iterate over all incidences. In the future,
237  // the list of categories should be built when reading the file.
238  for (const Incidence::Ptr &inc : rawInc) {
239  thisCats = inc->categories();
240  for (const auto &cat : std::as_const(thisCats)) {
241  if (!uniqueCategories.contains(cat)) {
242  uniqueCategories.append(cat);
243  }
244  }
245  }
246  return uniqueCategories;
247 }
248 
250 {
251  return mergeIncidenceList(events(date), todos(date), journals(date));
252 }
253 
255 {
256  return mergeIncidenceList(events(), todos(), journals());
257 }
258 
260 {
262 }
263 
265 {
266  if (incidence) {
267  Event::List elist;
268  Todo::List tlist;
269  Journal::List jlist;
270 
271  if (incidence->type() == Incidence::TypeEvent) {
272  elist = eventInstances(incidence);
273  } else if (incidence->type() == Incidence::TypeTodo) {
274  tlist = todoInstances(incidence);
275  } else if (incidence->type() == Incidence::TypeJournal) {
276  jlist = journalInstances(incidence);
277  }
278  return mergeIncidenceList(elist, tlist, jlist);
279  } else {
280  return Incidence::List();
281  }
282 }
283 
285 {
286  switch (sortField) {
287  case EventSortUnsorted:
288  break;
289 
290  case EventSortStartDate:
291  if (sortDirection == SortDirectionAscending) {
292  std::sort(eventList.begin(), eventList.end(), Events::startDateLessThan);
293  } else {
294  std::sort(eventList.begin(), eventList.end(), Events::startDateMoreThan);
295  }
296  break;
297 
298  case EventSortEndDate:
299  if (sortDirection == SortDirectionAscending) {
300  std::sort(eventList.begin(), eventList.end(), Events::endDateLessThan);
301  } else {
302  std::sort(eventList.begin(), eventList.end(), Events::endDateMoreThan);
303  }
304  break;
305 
306  case EventSortSummary:
307  if (sortDirection == SortDirectionAscending) {
308  std::sort(eventList.begin(), eventList.end(), Events::summaryLessThan);
309  } else {
310  std::sort(eventList.begin(), eventList.end(), Events::summaryMoreThan);
311  }
312  break;
313  }
314 
315  return eventList;
316 }
317 
318 Event::List Calendar::events(const QDate &date, const QTimeZone &timeZone, EventSortField sortField, SortDirection sortDirection) const
319 {
320  Event::List el = rawEventsForDate(date, timeZone, sortField, sortDirection);
321  d->mFilter->apply(&el);
322  return el;
323 }
324 
326 {
327  Event::List el = rawEventsForDate(dt.date(), dt.timeZone());
328  d->mFilter->apply(&el);
329  return el;
330 }
331 
332 Event::List Calendar::events(const QDate &start, const QDate &end, const QTimeZone &timeZone, bool inclusive) const
333 {
334  Event::List el = rawEvents(start, end, timeZone, inclusive);
335  d->mFilter->apply(&el);
336  return el;
337 }
338 
340 {
341  Event::List el = rawEvents(sortField, sortDirection);
342  d->mFilter->apply(&el);
343  return el;
344 }
345 
347 {
348  if (!incidence) {
349  return false;
350  }
351 
352  AddVisitor<Calendar> v(this);
353  return incidence->accept(v, incidence);
354 }
355 
357 {
358  if (!incidence) {
359  return false;
360  }
361 
362  if (beginChange(incidence)) {
363  DeleteVisitor<Calendar> v(this);
364  const bool result = incidence->accept(v, incidence);
366  return result;
367  } else {
368  return false;
369  }
370 }
371 
372 Incidence::Ptr Calendar::createException(const Incidence::Ptr &incidence, const QDateTime &recurrenceId, bool thisAndFuture)
373 {
374  Q_ASSERT(recurrenceId.isValid());
375  if (!incidence || !incidence->recurs() || !recurrenceId.isValid()) {
376  return Incidence::Ptr();
377  }
378 
379  Incidence::Ptr newInc(incidence->clone());
380  const QDateTime current = QDateTime::currentDateTimeUtc();
381  newInc->setCreated(current);
382  newInc->setLastModified(current);
383  newInc->setRevision(0);
384  // Recurring exceptions are not support for now
385  newInc->clearRecurrence();
386 
387  newInc->setRecurrenceId(recurrenceId);
388  newInc->setThisAndFuture(thisAndFuture);
389  newInc->setDtStart(recurrenceId);
390 
391  // Calculate and set the new end of the incidence
392  QDateTime end = incidence->dateTime(IncidenceBase::RoleEnd);
393 
394  if (end.isValid()) {
395  if (incidence->allDay()) {
396  qint64 offset = incidence->dtStart().daysTo(recurrenceId);
397  end = end.addDays(offset);
398  } else {
399  qint64 offset = incidence->dtStart().secsTo(recurrenceId);
400  end = end.addSecs(offset);
401  }
402  newInc->setDateTime(end, IncidenceBase::RoleEnd);
403  }
404  return newInc;
405 }
406 
407 Incidence::Ptr Calendar::incidence(const QString &uid, const QDateTime &recurrenceId) const
408 {
409  Incidence::Ptr i = event(uid, recurrenceId);
410  if (i) {
411  return i;
412  }
413 
414  i = todo(uid, recurrenceId);
415  if (i) {
416  return i;
417  }
418 
419  i = journal(uid, recurrenceId);
420  return i;
421 }
422 
424 {
425  Incidence::List result;
427  std::copy_if(incidences.cbegin(), incidences.cend(), std::back_inserter(result), [&sid](const Incidence::Ptr &in) {
428  return in->schedulingID() == sid;
429  });
430  return result;
431 }
432 
434 {
436  const auto itEnd = incidences.cend();
437  auto it = std::find_if(incidences.cbegin(), itEnd, [&uid](const Incidence::Ptr &in) {
438  return in->schedulingID() == uid;
439  });
440 
441  return it != itEnd ? *it : Incidence::Ptr();
442 }
443 
445 {
446  // Note that To-dos may not have Start DateTimes nor due DateTimes.
447  switch (sortField) {
448  case TodoSortUnsorted:
449  break;
450 
451  case TodoSortStartDate:
452  if (sortDirection == SortDirectionAscending) {
453  std::sort(todoList.begin(), todoList.end(), Todos::startDateLessThan);
454  } else {
455  std::sort(todoList.begin(), todoList.end(), Todos::startDateMoreThan);
456  }
457  break;
458 
459  case TodoSortDueDate:
460  if (sortDirection == SortDirectionAscending) {
461  std::sort(todoList.begin(), todoList.end(), Todos::dueDateLessThan);
462  } else {
463  std::sort(todoList.begin(), todoList.end(), Todos::dueDateMoreThan);
464  }
465  break;
466 
467  case TodoSortPriority:
468  if (sortDirection == SortDirectionAscending) {
469  std::sort(todoList.begin(), todoList.end(), Todos::priorityLessThan);
470  } else {
471  std::sort(todoList.begin(), todoList.end(), Todos::priorityMoreThan);
472  }
473  break;
474 
476  if (sortDirection == SortDirectionAscending) {
477  std::sort(todoList.begin(), todoList.end(), Todos::percentLessThan);
478  } else {
479  std::sort(todoList.begin(), todoList.end(), Todos::percentMoreThan);
480  }
481  break;
482 
483  case TodoSortSummary:
484  if (sortDirection == SortDirectionAscending) {
485  std::sort(todoList.begin(), todoList.end(), Todos::summaryLessThan);
486  } else {
487  std::sort(todoList.begin(), todoList.end(), Todos::summaryMoreThan);
488  }
489  break;
490 
491  case TodoSortCreated:
492  if (sortDirection == SortDirectionAscending) {
493  std::sort(todoList.begin(), todoList.end(), Todos::createdLessThan);
494  } else {
495  std::sort(todoList.begin(), todoList.end(), Todos::createdMoreThan);
496  }
497  break;
498 
499  case TodoSortCategories:
500  if (sortDirection == SortDirectionAscending) {
501  std::sort(todoList.begin(), todoList.end(), Incidences::categoriesLessThan);
502  } else {
503  std::sort(todoList.begin(), todoList.end(), Incidences::categoriesMoreThan);
504  }
505  break;
506  }
507 
508  return todoList;
509 }
510 
511 Todo::List Calendar::todos(TodoSortField sortField, SortDirection sortDirection) const
512 {
513  Todo::List tl = rawTodos(sortField, sortDirection);
514  d->mFilter->apply(&tl);
515  return tl;
516 }
517 
518 Todo::List Calendar::todos(const QDate &date) const
519 {
520  Todo::List el = rawTodosForDate(date);
521  d->mFilter->apply(&el);
522  return el;
523 }
524 
525 Todo::List Calendar::todos(const QDate &start, const QDate &end, const QTimeZone &timeZone, bool inclusive) const
526 {
527  Todo::List tl = rawTodos(start, end, timeZone, inclusive);
528  d->mFilter->apply(&tl);
529  return tl;
530 }
531 
533 {
534  switch (sortField) {
535  case JournalSortUnsorted:
536  break;
537 
538  case JournalSortDate:
539  if (sortDirection == SortDirectionAscending) {
540  std::sort(journalList.begin(), journalList.end(), Journals::dateLessThan);
541  } else {
542  std::sort(journalList.begin(), journalList.end(), Journals::dateMoreThan);
543  }
544  break;
545 
546  case JournalSortSummary:
547  if (sortDirection == SortDirectionAscending) {
548  std::sort(journalList.begin(), journalList.end(), Journals::summaryLessThan);
549  } else {
550  std::sort(journalList.begin(), journalList.end(), Journals::summaryMoreThan);
551  }
552  break;
553  }
554 
555  return journalList;
556 }
557 
559 {
560  Journal::List jl = rawJournals(sortField, sortDirection);
561  d->mFilter->apply(&jl);
562  return jl;
563 }
564 
566 {
568  d->mFilter->apply(&el);
569  return el;
570 }
571 
573 {
574 }
575 
577 {
578  Q_UNUSED(modified);
579  Q_UNUSED(calendar);
580 }
581 
583 {
584  Q_UNUSED(incidence);
585 }
586 
588 {
589  Q_UNUSED(incidence);
590 }
591 
593 {
594  Q_UNUSED(incidence);
595 }
596 
598 {
599  Q_UNUSED(incidence);
600  Q_UNUSED(calendar);
601 }
602 
604 {
605  Q_UNUSED(incidence);
606 }
607 
609 {
610  if (!observer) {
611  return;
612  }
613 
614  if (!d->mObservers.contains(observer)) {
615  d->mObservers.append(observer);
616  } else {
617  d->mNewObserver = true;
618  }
619 }
620 
622 {
623  if (!observer) {
624  return;
625  } else {
626  d->mObservers.removeAll(observer);
627  }
628 }
629 
630 void Calendar::setModified(bool modified)
631 {
632  if (modified != d->mModified || d->mNewObserver) {
633  d->mNewObserver = false;
634  for (CalendarObserver *observer : std::as_const(d->mObservers)) {
635  observer->calendarModified(modified, this);
636  }
637  d->mModified = modified;
638  }
639 }
640 
642 {
643  return d->mModified;
644 }
645 
646 void Calendar::incidenceUpdated(const QString &uid, const QDateTime &recurrenceId)
647 {
648  Incidence::Ptr inc = incidence(uid, recurrenceId);
649 
650  if (!inc) {
651  return;
652  }
653 
654  inc->setLastModified(QDateTime::currentDateTimeUtc());
655  // we should probably update the revision number here,
656  // or internally in the Event itself when certain things change.
657  // need to verify with ical documentation.
658 
660 
661  setModified(true);
662 }
663 
665 {
666  Q_UNUSED(timeZone);
667 }
668 
670 {
671  if (!incidence) {
672  return;
673  }
674 
675  if (!d->mObserversEnabled) {
676  return;
677  }
678 
679  for (CalendarObserver *observer : std::as_const(d->mObservers)) {
680  observer->calendarIncidenceAdded(incidence);
681  }
682 
684  const auto dt = incidence->dateTime(role);
685  if (dt.isValid() && dt.timeZone() != QTimeZone::utc()) {
686  if (!d->mTimeZones.contains(dt.timeZone())) {
687  d->mTimeZones.push_back(dt.timeZone());
688  }
689  }
690  }
691 }
692 
694 {
695  if (!incidence) {
696  return;
697  }
698 
699  if (!d->mObserversEnabled) {
700  return;
701  }
702 
703  for (CalendarObserver *observer : std::as_const(d->mObservers)) {
704  observer->calendarIncidenceChanged(incidence);
705  }
706 }
707 
709 {
710  if (!incidence) {
711  return;
712  }
713 
714  if (!d->mObserversEnabled) {
715  return;
716  }
717 
718  for (CalendarObserver *observer : std::as_const(d->mObservers)) {
719  observer->calendarIncidenceAboutToBeDeleted(incidence);
720  }
721 }
722 
724 {
725  if (!incidence) {
726  return;
727  }
728 
729  if (!d->mObserversEnabled) {
730  return;
731  }
732 
733  for (CalendarObserver *observer : std::as_const(d->mObservers)) {
734  observer->calendarIncidenceDeleted(incidence, this);
735  }
736 }
737 
739 {
740  if (!incidence) {
741  return;
742  }
743 
744  if (!d->mObserversEnabled) {
745  return;
746  }
747 
748  for (CalendarObserver *observer : std::as_const(d->mObservers)) {
749  observer->calendarIncidenceAdditionCanceled(incidence);
750  }
751 }
752 
754 {
755  setModified(true);
756 }
757 
759 {
760  d->mProductId = id;
761 }
762 
763 QString Calendar::productId() const
764 {
765  return d->mProductId;
766 }
767 
768 /** static */
770 {
773 
774  int i;
775  int end;
776  for (i = 0, end = events.count(); i < end; ++i) {
778  }
779 
780  for (i = 0, end = todos.count(); i < end; ++i) {
781  incidences.append(todos[i]);
782  }
783 
784  for (i = 0, end = journals.count(); i < end; ++i) {
786  }
787 
788  return incidences;
789 }
790 
792 {
793  Q_UNUSED(incidence);
794  return true;
795 }
796 
798 {
799  Q_UNUSED(incidence);
800  return true;
801 }
802 
804 {
805  d->mObserversEnabled = enabled;
806 }
807 
809 {
810  QDateTime preTime = from.addSecs(-1);
811 
812  Alarm::List alarmlist = incidence->alarms();
813  for (int i = 0, iend = alarmlist.count(); i < iend; ++i) {
814  if (alarmlist[i]->enabled()) {
815  QDateTime dt = alarmlist[i]->nextRepetition(preTime);
816  if (dt.isValid() && dt <= to) {
817  qCDebug(KCALCORE_LOG) << incidence->summary() << "':" << dt.toString();
818  alarms.append(alarmlist[i]);
819  }
820  }
821  }
822 }
823 
825 {
826  QDateTime dt;
827  bool endOffsetValid = false;
828  Duration endOffset(0);
829  Duration period(from, to);
830 
831  Alarm::List alarmlist = incidence->alarms();
832  for (int i = 0, iend = alarmlist.count(); i < iend; ++i) {
833  Alarm::Ptr a = alarmlist[i];
834  if (a->enabled()) {
835  if (a->hasTime()) {
836  // The alarm time is defined as an absolute date/time
837  dt = a->nextRepetition(from.addSecs(-1));
838  if (!dt.isValid() || dt > to) {
839  continue;
840  }
841  } else {
842  // Alarm time is defined by an offset from the event start or end time.
843  // Find the offset from the event start time, which is also used as the
844  // offset from the recurrence time.
845  Duration offset(0);
846  if (a->hasStartOffset()) {
847  offset = a->startOffset();
848  } else if (a->hasEndOffset()) {
849  offset = a->endOffset();
850  if (!endOffsetValid) {
851  endOffset = Duration(incidence->dtStart(), incidence->dateTime(Incidence::RoleAlarmEndOffset));
852  endOffsetValid = true;
853  }
854  }
855 
856  // Find the incidence's earliest alarm
857  QDateTime alarmStart = offset.end(a->hasEndOffset() ? incidence->dateTime(Incidence::RoleAlarmEndOffset) : incidence->dtStart());
858  if (alarmStart > to) {
859  continue;
860  }
861  QDateTime baseStart = incidence->dtStart();
862  if (from > alarmStart) {
863  alarmStart = from; // don't look earlier than the earliest alarm
864  baseStart = (-offset).end((-endOffset).end(alarmStart));
865  }
866 
867  // Adjust the 'alarmStart' date/time and find the next recurrence at or after it.
868  // Treat the two offsets separately in case one is daily and the other not.
869  dt = incidence->recurrence()->getNextDateTime(baseStart.addSecs(-1));
870  if (!dt.isValid() || (dt = endOffset.end(offset.end(dt))) > to) { // adjust 'dt' to get the alarm time
871  // The next recurrence is too late.
872  if (!a->repeatCount()) {
873  continue;
874  }
875 
876  // The alarm has repetitions, so check whether repetitions of previous
877  // recurrences fall within the time period.
878  bool found = false;
879  Duration alarmDuration = a->duration();
880  for (QDateTime base = baseStart; (dt = incidence->recurrence()->getPreviousDateTime(base)).isValid(); base = dt) {
881  if (a->duration().end(dt) < base) {
882  break; // this recurrence's last repetition is too early, so give up
883  }
884 
885  // The last repetition of this recurrence is at or after 'alarmStart' time.
886  // Check if a repetition occurs between 'alarmStart' and 'to'.
887  int snooze = a->snoozeTime().value(); // in seconds or days
888  if (a->snoozeTime().isDaily()) {
889  Duration toFromDuration(dt, base);
890  int toFrom = toFromDuration.asDays();
891  if (a->snoozeTime().end(from) <= to || (toFromDuration.isDaily() && toFrom % snooze == 0)
892  || (toFrom / snooze + 1) * snooze <= toFrom + period.asDays()) {
893  found = true;
894 #ifndef NDEBUG
895  // for debug output
896  dt = offset.end(dt).addDays(((toFrom - 1) / snooze + 1) * snooze);
897 #endif
898  break;
899  }
900  } else {
901  int toFrom = dt.secsTo(base);
902  if (period.asSeconds() >= snooze || toFrom % snooze == 0 || (toFrom / snooze + 1) * snooze <= toFrom + period.asSeconds()) {
903  found = true;
904 #ifndef NDEBUG
905  // for debug output
906  dt = offset.end(dt).addSecs(((toFrom - 1) / snooze + 1) * snooze);
907 #endif
908  break;
909  }
910  }
911  }
912  if (!found) {
913  continue;
914  }
915  }
916  }
917  qCDebug(KCALCORE_LOG) << incidence->summary() << "':" << dt.toString();
918  alarms.append(a);
919  }
920  }
921 }
922 
924 {
925  d->batchAddingInProgress = true;
926 }
927 
929 {
930  d->batchAddingInProgress = false;
931 }
932 
934 {
935  return d->batchAddingInProgress;
936 }
937 
939 {
940  return alarms(QDateTime(QDate(1900, 1, 1), QTime(0, 0, 0)), to);
941 }
942 
943 void Calendar::virtual_hook(int id, void *data)
944 {
945  Q_UNUSED(id);
946  Q_UNUSED(data);
947  Q_ASSERT(false);
948 }
949 
950 QString Calendar::id() const
951 {
952  return d->mId;
953 }
954 
955 void Calendar::setId(const QString &id)
956 {
957  if (d->mId != id) {
958  d->mId = id;
959  Q_EMIT idChanged();
960  }
961 }
962 
963 QString Calendar::name() const
964 {
965  return d->mName;
966 }
967 
968 void Calendar::setName(const QString &name)
969 {
970  if (d->mName != name) {
971  d->mName = name;
973  }
974 }
975 
976 QIcon Calendar::icon() const
977 {
978  return d->mIcon;
979 }
980 
981 void Calendar::setIcon(const QIcon &icon)
982 {
983  d->mIcon = icon;
985 }
986 
987 AccessMode Calendar::accessMode() const
988 {
989  return d->mAccessMode;
990 }
991 
993 {
994  if (d->mAccessMode != mode) {
995  d->mAccessMode = mode;
997  }
998 }
999 
1000 bool Calendar::isLoading() const
1001 {
1002  return d->mIsLoading;
1003 }
1004 
1005 void Calendar::setIsLoading(bool isLoading)
1006 {
1007  if (d->mIsLoading == isLoading) {
1008  return;
1009  }
1010 
1011  d->mIsLoading = isLoading;
1013 }
1014 
1015 #include "moc_calendar.cpp"
Incidence::Ptr incidence(const QString &uid, const QDateTime &recurrenceId={}) const
Returns the Incidence associated with the given unique identifier.
Definition: calendar.cpp:407
QTimeZone utc()
void append(const T &value)
virtual void calendarIncidenceAboutToBeDeleted(const Incidence::Ptr &incidence)
Notify the Observer that an Incidence will be removed.
Definition: calendar.cpp:592
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:808
virtual void calendarIncidenceAdded(const Incidence::Ptr &incidence)
Notify the Observer that an Incidence has been inserted.
Definition: calendar.cpp:582
QDateTime addSecs(qint64 s) const const
void notifyIncidenceChanged(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they modified an Incidence.
Definition: calendar.cpp:693
static Event::List sortEvents(Event::List &&eventList, EventSortField sortField, SortDirection sortDirection)
Sort a list of Events.
Definition: calendar.cpp:284
@ TodoSortUnsorted
Do not sort Todos.
Definition: calendar.h:81
@ JournalSortDate
Sort Journals chronologically by date.
Definition: calendar.h:96
void accessModeChanged()
Emitted when the AccessMode changes.
Represents a span of time measured in seconds or days.
Definition: duration.h:43
QTimeZone timeZone() const const
TodoSortField
Calendar Todo sort keys.
Definition: calendar.h:80
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:339
void unregisterObserver(CalendarObserver *observer)
Unregisters an Observer for this Calendar.
Definition: calendar.cpp:621
Q_EMITQ_EMIT
@ RoleStartTimeZone
Role for determining an incidence's starting timezone.
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.
void setId(const QString &id)
set a unique identifier for this calendar.
Definition: calendar.cpp:955
void idChanged()
Emitted when the id changes.
int count(const T &value) const const
bool isModified() const
Determine the calendar's modification status.
Definition: calendar.cpp:641
JournalSortField
Calendar Journal sort keys.
Definition: calendar.h:94
QDateTime addDays(qint64 ndays) const const
virtual Todo::List rawTodos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const =0
Returns a sorted, unfiltered list of all Todos for this Calendar.
Namespace for all KCalendarCore types.
Definition: alarm.h:36
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
@ TodoSortCategories
Sort Todos by categories (tags)
Definition: calendar.h:88
virtual void doSetTimeZone(const QTimeZone &timeZone)
Let Calendar subclasses set the time specification.
Definition: calendar.cpp:664
Q_SCRIPTABLE Q_NOREPLY void start()
virtual Incidence::List incidencesFromSchedulingID(const QString &sid) const
Searches all events and todos for an incidence with this scheduling identifier.
Definition: calendar.cpp:423
void setIcon(const QIcon &icon)
Set this calendar's icon.
Definition: calendar.cpp:981
virtual bool deleteIncidence(const Incidence::Ptr &incidence)
Removes an Incidence from the calendar.
Definition: calendar.cpp:356
void incidenceUpdated(const QString &uid, const QDateTime &recurrenceId) override
The Observer interface.
Definition: calendar.cpp:646
virtual bool addIncidence(const Incidence::Ptr &incidence)
Inserts an Incidence into the calendar.
Definition: calendar.cpp:346
QDateTime currentDateTimeUtc()
@ TypeTodo
Type is a to-do.
virtual bool beginChange(const Incidence::Ptr &incidence)
Flag that a change to a Calendar Incidence is starting.
Definition: calendar.cpp:791
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:511
@ TodoSortPercentComplete
Sort Todos by percentage completed.
Definition: calendar.h:85
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.
AccessMode
The calendar's access mode, i.e.
Definition: calendar.h:104
@ EventSortStartDate
Sort Events chronologically, by start date.
Definition: calendar.h:72
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
void nameChanged()
Emitted when the name changes.
void setTimeZone(const QTimeZone &timeZone)
Sets the default time specification zone used for creating or modifying incidences in the Calendar.
Definition: calendar.cpp:152
@ TodoSortSummary
Sort Todos alphabetically, by summary.
Definition: calendar.h:86
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.
CalFilter * filter() const
Returns the calendar filter.
Definition: calendar.cpp:226
virtual void calendarModified(bool modified, Calendar *calendar)
Notify the Observer that a Calendar has been modified.
Definition: calendar.cpp:576
void reserve(int alloc)
void setOwner(const Person &owner)
Sets the owner of the calendar to owner.
Definition: calendar.cpp:143
Represents the main calendar class.
Definition: calendar.h:132
int asSeconds() const
Returns the length of the duration in seconds.
Definition: duration.cpp:186
virtual Event::List rawEventsForDate(const QDate &date, const QTimeZone &timeZone={}, EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const =0
Returns a sorted, unfiltered list of all Events which occur on the given date.
void setObserversEnabled(bool enabled)
Let Calendar subclasses notify that they enabled an Observer.
Definition: calendar.cpp:803
Provides a filter for calendars.
Definition: calfilter.h:42
EventSortField
Calendar Event sort keys.
Definition: calendar.h:70
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:769
qint64 secsTo(const QDateTime &other) const const
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:372
QSharedPointer< Incidence > Ptr
A shared pointer to an Incidence.
Definition: incidence.h:117
static Todo::List sortTodos(Todo::List &&todoList, TodoSortField sortField, SortDirection sortDirection)
Sort a list of Todos.
Definition: calendar.cpp:444
@ EventSortUnsorted
Do not sort Events.
Definition: calendar.h:71
@ TodoSortStartDate
Sort Todos chronologically, by start date.
Definition: calendar.h:82
virtual void calendarIncidenceDeleted(const Incidence::Ptr &incidence, const Calendar *calendar)
Notify the Observer that an Incidence has been removed.
Definition: calendar.cpp:597
bool isValid() const const
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:824
virtual Incidence::Ptr incidenceFromSchedulingID(const QString &sid) const
Returns the Incidence associated with the given scheduling identifier.
Definition: calendar.cpp:433
void setProductId(const QString &id)
Sets the calendar Product ID to id.
Definition: calendar.cpp:758
void setName(const QString &name)
Set the user-visible name for this calendar.
Definition: calendar.cpp:968
QList::const_iterator cend() const const
@ JournalSortUnsorted
Do not sort Journals.
Definition: calendar.h:95
Calendar(const QTimeZone &timeZone)
Constructs a calendar with a specified time zone timeZone.
Definition: calendar.cpp:117
virtual Event::List rawEvents(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const =0
Returns a sorted, unfiltered list of all Events for this Calendar.
int asDays() const
Returns the length of the duration in days.
Definition: duration.cpp:191
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:558
SortDirection
Calendar Incidence sort directions.
Definition: calendar.h:62
This class provides the interface for a visitor of calendar components.
Definition: visitor.h:30
@ TodoSortDueDate
Sort Todos chronologically, by due date.
Definition: calendar.h:83
virtual Incidence::List rawIncidences() const
Returns an unfiltered list of all Incidences for this Calendar.
Definition: calendar.cpp:259
void notifyIncidenceAboutToBeDeleted(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they will remove an Incidence.
Definition: calendar.cpp:708
virtual Incidence::List incidences() const
Returns a filtered list of all Incidences for this Calendar.
Definition: calendar.cpp:254
void customPropertyUpdated() override
Definition: calendar.cpp:753
@ RoleEnd
Role for determining an incidence's dtEnd, will return an invalid QDateTime if the incidence does not...
Alarm::List alarmsTo(const QDateTime &to) const
Return a list of Alarms that occur before the specified timestamp.
Definition: calendar.cpp:938
virtual void calendarIncidenceAdditionCanceled(const Incidence::Ptr &incidence)
Notify the Observer that an addition of Incidence has been canceled.
Definition: calendar.cpp:603
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.
static Journal::List sortJournals(Journal::List &&journalList, JournalSortField sortField, SortDirection sortDirection)
Sort a list of Journals.
Definition: calendar.cpp:532
bool batchAdding() const
Definition: calendar.cpp:933
void ownerChanged()
Emitted when the owner changes.
void notifyIncidenceAdditionCanceled(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they canceled addition of an Incidence.
Definition: calendar.cpp:738
void setFilter(CalFilter *filter)
Sets the calendar filter.
Definition: calendar.cpp:216
virtual void virtual_hook(int id, void *data)
Definition: calendar.cpp:943
QTimeZone systemTimeZone()
virtual bool endChange(const Incidence::Ptr &incidence)
Flag that a change to a Calendar Incidence has completed.
Definition: calendar.cpp:797
@ EventSortEndDate
Sort Events chronologically, by end date.
Definition: calendar.h:73
@ RoleEndTimeZone
Role for determining an incidence's ending timezone.
QTimeZone timeZone() const
Get the time zone used for creating or modifying incidences in the Calendar.
Definition: calendar.cpp:163
QList::const_iterator cbegin() const const
QDate date() const const
@ EventSortSummary
Sort Events alphabetically, by summary.
Definition: calendar.h:74
void registerObserver(CalendarObserver *observer)
Registers an Observer for this Calendar.
Definition: calendar.cpp:608
bool isValid() const const
void setModified(bool modified)
Sets if the calendar has been modified.
Definition: calendar.cpp:630
void setTimeZoneId(const QByteArray &timeZoneId)
Sets the time zone ID used for creating or modifying incidences in the Calendar.
Definition: calendar.cpp:168
@ TypeEvent
Type is an event.
QList< Ptr > List
List of incidences.
Definition: incidence.h:122
@ JournalSortSummary
Sort Journals alphabetically, by summary.
Definition: calendar.h:97
@ TypeJournal
Type is a journal.
virtual Incidence::List instances(const Incidence::Ptr &incidence) const
Returns an unfiltered list of all exceptions of this recurring incidence.
Definition: calendar.cpp:264
@ TodoSortCreated
Sort Todos chronologically, by creation date.
Definition: calendar.h:87
@ SortDirectionAscending
Sort in ascending order (first to last)
Definition: calendar.h:63
void filterChanged()
Emitted when setFilter() is called.
Represents a person, by name and email address.
Definition: person.h:37
QByteArray timeZoneId() const
Returns the time zone ID used for creating or modifying incidences in the calendar.
Definition: calendar.cpp:189
@ RoleAlarmEndOffset
Role for an incidence alarm's ending offset date/time.
virtual Journal::Ptr journal(const QString &uid, const QDateTime &recurrenceId={}) const =0
Returns the Journal associated with the given unique identifier.
void setIsLoading(bool isLoading)
Sets the loading state of this calendar.
Definition: calendar.cpp:1005
QString toString(Qt::DateFormat format) const const
void notifyIncidenceAdded(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they inserted an Incidence.
Definition: calendar.cpp:669
virtual Todo::Ptr todo(const QString &uid, const QDateTime &recurrenceId={}) const =0
Returns the Todo associated with the given unique identifier.
bool isDaily() const
Returns whether the duration is specified in terms of days rather than seconds.
Definition: duration.cpp:181
void iconChanged()
Emitted when the icon name changes.
virtual Journal::List rawJournals(JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending) const =0
Returns a sorted, unfiltered list of all Journals for this Calendar.
@ TodoSortPriority
Sort Todos by priority.
Definition: calendar.h:84
virtual Journal::List rawJournalsForDate(const QDate &date) const =0
Returns an unfiltered list of all Journals for on the specified date.
virtual void endBatchAdding()
Tells the Calendar that you stopped adding a batch of incidences.
Definition: calendar.cpp:928
virtual Event::Ptr event(const QString &uid, const QDateTime &recurrenceId={}) const =0
Returns the Event associated with the given unique identifier.
void isLoadingChanged()
Emitted when the loading state changed.
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:194
virtual Todo::List rawTodosForDate(const QDate &date) const =0
Returns an unfiltered list of all Todos which due on the specified date.
void notifyIncidenceDeleted(const Incidence::Ptr &incidence)
Let Calendar subclasses notify that they removed an Incidence.
Definition: calendar.cpp:723
void setAccessMode(const AccessMode mode)
Set this calendar's AccessMode, i.e.
Definition: calendar.cpp:992
virtual void calendarIncidenceChanged(const Incidence::Ptr &incidence)
Notify the Observer that an Incidence has been modified.
Definition: calendar.cpp:587
virtual void startBatchAdding()
Call this to tell the calendar that you're adding a batch of incidences.
Definition: calendar.cpp:923
QStringList categories() const
Returns a list of all categories used by Incidences in this Calendar.
Definition: calendar.cpp:231
~Calendar() override
Destroys the calendar.
Definition: calendar.cpp:133
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Thu Feb 15 2024 03:58:54 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.