KCalendarCore

incidence.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the kcalcore library.
3 
4  SPDX-FileCopyrightText: 2001 Cornelius Schumacher <[email protected]>
5  SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 /**
10  @file
11  This file is part of the API for handling calendar data and
12  defines the Incidence class.
13 
14  @brief
15  Provides the class common to non-FreeBusy (Events, To-dos, Journals)
16  calendar components known as incidences.
17 
18  @author Cornelius Schumacher <[email protected]>
19  @author Reinhold Kainhofer <[email protected]>
20 */
21 
22 #include "incidence.h"
23 #include "incidence_p.h"
24 #include "calformat.h"
25 #include "kcalendarcore_debug.h"
26 #include "utils_p.h"
27 
28 #include <math.h>
29 
30 #include <QStringList>
31 #include <QTextDocument> // for .toHtmlEscaped() and Qt::mightBeRichText()
32 #include <QTime>
33 #include <QTimeZone>
34 
35 using namespace KCalendarCore;
36 
37 IncidencePrivate::IncidencePrivate() = default;
38 
39 IncidencePrivate::IncidencePrivate(const IncidencePrivate &p)
40  : IncidenceBasePrivate(p)
41  , mCreated(p.mCreated)
42  , mDescription(p.mDescription)
43  , mSummary(p.mSummary)
44  , mLocation(p.mLocation)
45  , mCategories(p.mCategories)
46  , mResources(p.mResources)
47  , mStatusString(p.mStatusString)
48  , mSchedulingID(p.mSchedulingID)
49  , mRelatedToUid(p.mRelatedToUid)
50  , mRecurrenceId(p.mRecurrenceId)
51  , mConferences(p.mConferences)
52  , mGeoLatitude(p.mGeoLatitude)
53  , mGeoLongitude(p.mGeoLongitude)
54  , mRecurrence(nullptr)
55  , mRevision(p.mRevision)
56  , mPriority(p.mPriority)
57  , mStatus(p.mStatus)
58  , mSecrecy(p.mSecrecy)
59  , mColor(p.mColor)
60  , mDescriptionIsRich(p.mDescriptionIsRich)
61  , mSummaryIsRich(p.mSummaryIsRich)
62  , mLocationIsRich(p.mLocationIsRich)
63  , mThisAndFuture(p.mThisAndFuture)
64  , mLocalOnly(false)
65 {
66 }
67 
68 IncidencePrivate::IncidencePrivate(const Incidence &other)
69  : IncidencePrivate(*other.d_func())
70 {
71 }
72 
73 void IncidencePrivate::clear()
74 {
75  mAlarms.clear();
76  mAttachments.clear();
77  delete mRecurrence;
78  mRecurrence = nullptr;
79 }
80 
81 void IncidencePrivate::init(Incidence *q, const IncidencePrivate &other)
82 {
83  mRevision = other.mRevision;
84  mCreated = other.mCreated;
85  mDescription = other.mDescription;
86  mDescriptionIsRich = other.mDescriptionIsRich;
87  mSummary = other.mSummary;
88  mSummaryIsRich = other.mSummaryIsRich;
89  mCategories = other.mCategories;
90  mRelatedToUid = other.mRelatedToUid;
91  mResources = other.mResources;
92  mStatusString = other.mStatusString;
93  mStatus = other.mStatus;
94  mSecrecy = other.mSecrecy;
95  mPriority = other.mPriority;
96  mLocation = other.mLocation;
97  mLocationIsRich = other.mLocationIsRich;
98  mGeoLatitude = other.mGeoLatitude;
99  mGeoLongitude = other.mGeoLongitude;
100  mRecurrenceId = other.mRecurrenceId;
101  mConferences = other.mConferences;
102  mThisAndFuture = other.mThisAndFuture;
103  mLocalOnly = other.mLocalOnly;
104  mColor = other.mColor;
105 
106  // Alarms and Attachments are stored in ListBase<...>, which is a QValueList<...*>.
107  // We need to really duplicate the objects stored therein, otherwise deleting
108  // i will also delete all attachments from this object (setAutoDelete...)
109  mAlarms.reserve(other.mAlarms.count());
110  for (const Alarm::Ptr &alarm : std::as_const(other.mAlarms)) {
111  Alarm::Ptr b(new Alarm(*alarm.data()));
112  b->setParent(q);
113  mAlarms.append(b);
114  }
115 
116  mAttachments = other.mAttachments;
117  if (other.mRecurrence) {
118  mRecurrence = new Recurrence(*(other.mRecurrence));
119  mRecurrence->addObserver(q);
120  } else {
121  mRecurrence = nullptr;
122  }
123 }
124 
125 bool IncidencePrivate::validStatus(Incidence::Status status)
126 {
127  return status == Incidence::StatusNone;
128 }
129 //@endcond
130 
131 #if KCALENDARCORE_BUILD_DEPRECATED_SINCE(5, 91)
133  : IncidenceBase(new IncidencePrivate)
134 {
135  recreate();
137 }
138 
140  : IncidenceBase(i, new IncidencePrivate(*(i.d_func())))
141  , Recurrence::RecurrenceObserver()
142 {
143  Q_D(Incidence);
144  d->init(this, *(i.d_func()));
146 }
147 #endif
148 
149 Incidence::Incidence(IncidencePrivate *p)
150  : IncidenceBase(p)
151 {
152  recreate();
154 }
155 
156 Incidence::Incidence(const Incidence &other, IncidencePrivate *p)
157  : IncidenceBase(other, p)
158  , Recurrence::RecurrenceObserver()
159 {
160  Q_D(Incidence);
161  d->init(this, *(other.d_func()));
163 }
164 
166 {
167  // Alarm has a raw incidence pointer, so we must set it to 0
168  // so Alarm doesn't use it after Incidence is destroyed
169  Q_D(const Incidence);
170  for (const Alarm::Ptr &alarm : std::as_const(d->mAlarms)) {
171  alarm->setParent(nullptr);
172  }
173  delete d->mRecurrence;
174 }
175 
176 //@cond PRIVATE
177 // A string comparison that considers that null and empty are the same
178 static bool stringCompare(const QString &s1, const QString &s2)
179 {
180  return (s1.isEmpty() && s2.isEmpty()) || (s1 == s2);
181 }
182 
183 //@endcond
185 {
186  Q_D(Incidence);
187  if (&other != this) {
188  d->clear();
189  // TODO: should relations be cleared out, as in destructor???
190  IncidenceBase::assign(other);
191  const Incidence *i = static_cast<const Incidence *>(&other);
192  d->init(this, *(i->d_func()));
193  }
194 
195  return *this;
196 }
197 
198 bool Incidence::equals(const IncidenceBase &incidence) const
199 {
200  if (!IncidenceBase::equals(incidence)) {
201  return false;
202  }
203 
204  // If they weren't the same type IncidenceBase::equals would had returned false already
205  const Incidence *i2 = static_cast<const Incidence *>(&incidence);
206 
207  const Alarm::List alarmList = alarms();
208  const Alarm::List otherAlarmsList = i2->alarms();
209  if (alarmList.count() != otherAlarmsList.count()) {
210  return false;
211  }
212 
213  auto matchFunc = [](const Alarm::Ptr &a, const Alarm::Ptr &b) {
214  return *a == *b;
215  };
216 
217  const auto [it1, it2] = std::mismatch(alarmList.cbegin(), alarmList.cend(), otherAlarmsList.cbegin(), otherAlarmsList.cend(), matchFunc);
218  // Checking the iterator from one list only, since both lists are the same size
219  if (it1 != alarmList.cend()) {
220  return false;
221  }
222 
223  const Attachment::List attachmentList = attachments();
224  const Attachment::List otherAttachmentList = i2->attachments();
225  if (attachmentList.count() != otherAttachmentList.count()) {
226  return false;
227  }
228 
229  const auto [at1, at2] = std::mismatch(attachmentList.cbegin(), attachmentList.cend(), otherAttachmentList.cbegin(), otherAttachmentList.cend());
230 
231  // Checking the iterator from one list only, since both lists are the same size
232  if (at1 != attachmentList.cend()) {
233  return false;
234  }
235 
236  Q_D(const Incidence);
237  bool recurrenceEqual = (d->mRecurrence == nullptr && i2->d_func()->mRecurrence == nullptr);
238  if (!recurrenceEqual) {
239  recurrence(); // create if doesn't exist
240  i2->recurrence(); // create if doesn't exist
241  recurrenceEqual = d->mRecurrence != nullptr && i2->d_func()->mRecurrence != nullptr
242  && *d->mRecurrence == *i2->d_func()->mRecurrence;
243  }
244 
245  if (!qFuzzyCompare(d->mGeoLatitude, i2->d_func()->mGeoLatitude) || !qFuzzyCompare(d->mGeoLongitude, i2->d_func()->mGeoLongitude)) {
246  return false;
247  }
248  // clang-format off
249  return
250  recurrenceEqual
251  && created() == i2->created()
252  && stringCompare(description(), i2->description())
254  && stringCompare(summary(), i2->summary())
255  && summaryIsRich() == i2->summaryIsRich()
256  && categories() == i2->categories()
257  && stringCompare(relatedTo(), i2->relatedTo())
258  && resources() == i2->resources()
259  && d->mStatus == i2->d_func()->mStatus
260  && (d->mStatus == StatusNone || stringCompare(d->mStatusString, i2->d_func()->mStatusString))
261  && secrecy() == i2->secrecy()
262  && priority() == i2->priority()
263  && stringCompare(location(), i2->location())
264  && locationIsRich() == i2->locationIsRich()
265  && stringCompare(color(), i2->color())
266  && stringCompare(schedulingID(), i2->schedulingID())
267  && recurrenceId() == i2->recurrenceId()
268  && conferences() == i2->conferences()
269  && thisAndFuture() == i2->thisAndFuture();
270  // clang-format on
271 }
272 
274 {
275  if (hasRecurrenceId()) {
276  return uid() + recurrenceId().toString(Qt::ISODate);
277  }
278  return uid();
279 }
280 
282 {
283  const QDateTime nowUTC = QDateTime::currentDateTimeUtc();
284  setCreated(nowUTC);
285 
287  setRevision(0);
288  setLastModified(nowUTC); // NOLINT false clang-analyzer-optin.cplusplus.VirtualCall
289 }
290 
292 {
293  Q_D(const Incidence);
294  if (!d->mLocalOnly) {
296  }
297 }
298 
299 void Incidence::setReadOnly(bool readOnly)
300 {
301  Q_D(const Incidence);
302  IncidenceBase::setReadOnly(readOnly);
303  if (d->mRecurrence) {
304  d->mRecurrence->setRecurReadOnly(readOnly);
305  }
306 }
307 
308 void Incidence::setLocalOnly(bool localOnly)
309 {
310  if (mReadOnly) {
311  return;
312  }
313  Q_D(Incidence);
314  d->mLocalOnly = localOnly;
315 }
316 
318 {
319  Q_D(const Incidence);
320  return d->mLocalOnly;
321 }
322 
323 void Incidence::setAllDay(bool allDay)
324 {
325  if (mReadOnly) {
326  return;
327  }
328  Q_D(const Incidence);
329  if (d->mRecurrence) {
330  d->mRecurrence->setAllDay(allDay);
331  }
332  IncidenceBase::setAllDay(allDay);
333 }
334 
335 void Incidence::setCreated(const QDateTime &created)
336 {
337  Q_D(Incidence);
338  if (mReadOnly || d->mLocalOnly) {
339  return;
340  }
341 
342  update();
343  d->mCreated = created.toUTC();
344  const auto ct = d->mCreated.time();
345  // Remove milliseconds
346  d->mCreated.setTime(QTime(ct.hour(), ct.minute(), ct.second()));
348  updated();
349 }
350 
351 QDateTime Incidence::created() const
352 {
353  Q_D(const Incidence);
354  return d->mCreated;
355 }
356 
358 {
359  Q_D(Incidence);
360  if (mReadOnly || d->mLocalOnly) {
361  return;
362  }
363 
364  update();
365  d->mRevision = rev;
367  updated();
368 }
369 
371 {
372  Q_D(const Incidence);
373  return d->mRevision;
374 }
375 
377 {
378  Q_D(const Incidence);
380  if (d->mRecurrence && dirtyFields().contains(FieldDtStart)) {
381  d->mRecurrence->setStartDateTime(dt, allDay());
382  }
383 }
384 
385 void Incidence::shiftTimes(const QTimeZone &oldZone, const QTimeZone &newZone)
386 {
387  Q_D(const Incidence);
388  IncidenceBase::shiftTimes(oldZone, newZone);
389  if (d->mRecurrence) {
390  d->mRecurrence->shiftTimes(oldZone, newZone);
391  }
392  if (d->mAlarms.count() > 0) {
393  update();
394  for (auto alarm : d->mAlarms) {
395  alarm->shiftTimes(oldZone, newZone);
396  }
398  updated();
399  }
400 }
401 
402 void Incidence::setDescription(const QString &description, bool isRich)
403 {
404  if (mReadOnly) {
405  return;
406  }
407  update();
408  Q_D(Incidence);
409  d->mDescription = description;
410  d->mDescriptionIsRich = isRich;
412  updated();
413 }
414 
415 void Incidence::setDescription(const QString &description)
416 {
417  setDescription(description, Qt::mightBeRichText(description));
418 }
419 
420 QString Incidence::description() const
421 {
422  Q_D(const Incidence);
423  return d->mDescription;
424 }
425 
427 {
428  Q_D(const Incidence);
429  if (descriptionIsRich()) {
430  return d->mDescription;
431  } else {
432  return d->mDescription.toHtmlEscaped().replace(QLatin1Char('\n'), QStringLiteral("<br/>"));
433  }
434 }
435 
437 {
438  Q_D(const Incidence);
439  return d->mDescriptionIsRich;
440 }
441 
442 void Incidence::setSummary(const QString &summary, bool isRich)
443 {
444  if (mReadOnly) {
445  return;
446  }
447  Q_D(Incidence);
448  if (d->mSummary != summary || d->mSummaryIsRich != isRich) {
449  update();
450  d->mSummary = summary;
451  d->mSummaryIsRich = isRich;
453  updated();
454  }
455 }
456 
457 void Incidence::setSummary(const QString &summary)
458 {
459  setSummary(summary, Qt::mightBeRichText(summary));
460 }
461 
462 QString Incidence::summary() const
463 {
464  Q_D(const Incidence);
465  return d->mSummary;
466 }
467 
469 {
470  Q_D(const Incidence);
471  if (summaryIsRich()) {
472  return d->mSummary;
473  } else {
474  return d->mSummary.toHtmlEscaped().replace(QLatin1Char('\n'), QStringLiteral("<br/>"));
475  }
476 }
477 
479 {
480  Q_D(const Incidence);
481  return d->mSummaryIsRich;
482 }
483 
484 void Incidence::setCategories(const QStringList &categories)
485 {
486  if (mReadOnly) {
487  return;
488  }
489 
490  Q_D(Incidence);
491  update();
492  d->mCategories = categories;
494  updated();
495 }
496 
498 {
499  if (mReadOnly) {
500  return;
501  }
502  update();
504 
505  Q_D(Incidence);
506  d->mCategories.clear();
507 
508  if (catStr.isEmpty()) {
509  updated();
510  return;
511  }
512 
513  d->mCategories = catStr.split(QLatin1Char(','));
514 
515  for (auto &category : d->mCategories) {
516  category = category.trimmed();
517  }
518 
519  updated();
520 }
521 
522 QStringList Incidence::categories() const
523 {
524  Q_D(const Incidence);
525  return d->mCategories;
526 }
527 
529 {
530  Q_D(const Incidence);
531  return d->mCategories.join(QLatin1Char(','));
532 }
533 
534 void Incidence::setRelatedTo(const QString &relatedToUid, RelType relType)
535 {
536  // TODO: RFC says that an incidence can have more than one related-to field
537  // even for the same relType.
538 
539  Q_D(Incidence);
540  if (d->mRelatedToUid[relType] != relatedToUid) {
541  update();
542  d->mRelatedToUid[relType] = relatedToUid;
544  updated();
545  }
546 }
547 
549 {
550  Q_D(const Incidence);
551  return d->mRelatedToUid.value(relType);
552 }
553 
554 void Incidence::setColor(const QString &colorName)
555 {
556  if (mReadOnly) {
557  return;
558  }
559  Q_D(Incidence);
560  if (!stringCompare(d->mColor, colorName)) {
561  update();
562  d->mColor = colorName;
564  updated();
565  }
566 }
567 
569 {
570  Q_D(const Incidence);
571  return d->mColor;
572 }
573 
574 // %%%%%%%%%%%% Recurrence-related methods %%%%%%%%%%%%%%%%%%%%
575 
577 {
578  Q_D(const Incidence);
579  if (!d->mRecurrence) {
580  d->mRecurrence = new Recurrence();
581  d->mRecurrence->setStartDateTime(dateTime(RoleRecurrenceStart), allDay());
582  d->mRecurrence->setAllDay(allDay());
583  d->mRecurrence->setRecurReadOnly(mReadOnly);
584  d->mRecurrence->addObserver(const_cast<KCalendarCore::Incidence *>(this));
585  }
586 
587  return d->mRecurrence;
588 }
589 
591 {
592  Q_D(const Incidence);
593  delete d->mRecurrence;
594  d->mRecurrence = nullptr;
595 }
596 
598 {
599  Q_D(const Incidence);
600  if (d->mRecurrence) {
601  return d->mRecurrence->recurrenceType();
602  } else {
603  return Recurrence::rNone;
604  }
605 }
606 
607 bool Incidence::recurs() const
608 {
609  Q_D(const Incidence);
610  if (d->mRecurrence) {
611  return d->mRecurrence->recurs();
612  } else {
613  return false;
614  }
615 }
616 
617 bool Incidence::recursOn(const QDate &date, const QTimeZone &timeZone) const
618 {
619  Q_D(const Incidence);
620  return d->mRecurrence && d->mRecurrence->recursOn(date, timeZone);
621 }
622 
623 bool Incidence::recursAt(const QDateTime &qdt) const
624 {
625  Q_D(const Incidence);
626  return d->mRecurrence && d->mRecurrence->recursAt(qdt);
627 }
628 
630 {
631  QDateTime start = dtStart();
632  QDateTime end = dateTime(RoleEndRecurrenceBase);
633 
634  QList<QDateTime> result;
635 
636  // TODO_Recurrence: Also work if only due date is given...
637  if (!start.isValid() && !end.isValid()) {
638  return result;
639  }
640 
641  // if the incidence doesn't recur,
642  QDateTime kdate(date, {}, timeZone);
643  if (!recurs()) {
644  if (start.date() <= date && end.date() >= date) {
645  result << start;
646  }
647  return result;
648  }
649 
650  qint64 days = start.daysTo(end);
651  // Account for possible recurrences going over midnight, while the original event doesn't
652  QDate tmpday(date.addDays(-days - 1));
653  QDateTime tmp;
654  while (tmpday <= date) {
655  if (recurrence()->recursOn(tmpday, timeZone)) {
656  const QList<QTime> times = recurrence()->recurTimesOn(tmpday, timeZone);
657  for (const QTime &time : times) {
658  tmp = QDateTime(tmpday, time, start.timeZone());
659  if (endDateForStart(tmp) >= kdate) {
660  result << tmp;
661  }
662  }
663  }
664  tmpday = tmpday.addDays(1);
665  }
666  return result;
667 }
668 
670 {
671  QDateTime start = dtStart();
672  QDateTime end = dateTime(RoleEndRecurrenceBase);
673 
674  QList<QDateTime> result;
675 
676  // TODO_Recurrence: Also work if only due date is given...
677  if (!start.isValid() && !end.isValid()) {
678  return result;
679  }
680 
681  // if the incidence doesn't recur,
682  if (!recurs()) {
683  if (!(start > datetime || end < datetime)) {
684  result << start;
685  }
686  return result;
687  }
688 
689  qint64 days = start.daysTo(end);
690  // Account for possible recurrences going over midnight, while the original event doesn't
691  QDate tmpday(datetime.date().addDays(-days - 1));
692  QDateTime tmp;
693  while (tmpday <= datetime.date()) {
694  if (recurrence()->recursOn(tmpday, datetime.timeZone())) {
695  // Get the times during the day (in start date's time zone) when recurrences happen
696  const QList<QTime> times = recurrence()->recurTimesOn(tmpday, start.timeZone());
697  for (const QTime &time : times) {
698  tmp = QDateTime(tmpday, time, start.timeZone());
699  if (!(tmp > datetime || endDateForStart(tmp) < datetime)) {
700  result << tmp;
701  }
702  }
703  }
704  tmpday = tmpday.addDays(1);
705  }
706  return result;
707 }
708 
710 {
711  QDateTime start = dtStart();
712  QDateTime end = dateTime(RoleEndRecurrenceBase);
713  if (!end.isValid()) {
714  return start;
715  }
716  if (!start.isValid()) {
717  return end;
718  }
719 
720  return startDt.addSecs(start.secsTo(end));
721 }
722 
723 void Incidence::addAttachment(const Attachment &attachment)
724 {
725  if (mReadOnly || attachment.isEmpty()) {
726  return;
727  }
728 
729  Q_D(Incidence);
730  update();
731  d->mAttachments.append(attachment);
733  updated();
734 }
735 
737 {
738  Q_D(Incidence);
739  auto it = std::remove_if(d->mAttachments.begin(), d->mAttachments.end(), [&mime](const Attachment &a) {
740  return a.mimeType() == mime;
741  });
742  if (it != d->mAttachments.end()) {
743  update();
744  d->mAttachments.erase(it, d->mAttachments.end());
746  updated();
747  }
748 }
749 
750 Attachment::List Incidence::attachments() const
751 {
752  Q_D(const Incidence);
753  return d->mAttachments;
754 }
755 
756 Attachment::List Incidence::attachments(const QString &mime) const
757 {
758  Q_D(const Incidence);
759  Attachment::List attachments;
760  for (const Attachment &attachment : std::as_const(d->mAttachments)) {
761  if (attachment.mimeType() == mime) {
762  attachments.append(attachment);
763  }
764  }
765  return attachments;
766 }
767 
769 {
770  Q_D(Incidence);
771  update();
773  d->mAttachments.clear();
774  updated();
775 }
776 
777 void Incidence::setResources(const QStringList &resources)
778 {
779  if (mReadOnly) {
780  return;
781  }
782 
783  update();
784  Q_D(Incidence);
785  d->mResources = resources;
787  updated();
788 }
789 
791 {
792  Q_D(const Incidence);
793  return d->mResources;
794 }
795 
796 void Incidence::setPriority(int priority)
797 {
798  if (mReadOnly) {
799  return;
800  }
801 
802  if (priority < 0 || priority > 9) {
803  qCWarning(KCALCORE_LOG) << "Ignoring invalid priority" << priority;
804  return;
805  }
806 
807  update();
808  Q_D(Incidence);
809  d->mPriority = priority;
811  updated();
812 }
813 
814 int Incidence::priority() const
815 {
816  Q_D(const Incidence);
817  return d->mPriority;
818 }
819 
821 {
822  if (mReadOnly) {
823  qCWarning(KCALCORE_LOG) << "Attempt to set status of read-only incidence";
824  return;
825  }
826 
827  Q_D(Incidence);
828  if (d->validStatus(status)) {
829  update();
830  d->mStatus = status;
831  d->mStatusString.clear();
833  updated();
834  } else {
835  qCWarning(KCALCORE_LOG) << "Ignoring invalid status" << status << "for" << typeStr();
836  }
837 }
838 
840 {
841  if (mReadOnly) {
842  return;
843  }
844 
845  update();
846  Q_D(Incidence);
847  d->mStatus = status.isEmpty() ? StatusNone : StatusX;
848  d->mStatusString = status;
850  updated();
851 }
852 
853 Incidence::Status Incidence::status() const
854 {
855  Q_D(const Incidence);
856  return d->mStatus;
857 }
858 
860 {
861  Q_D(const Incidence);
862  if (d->mStatus == StatusX) {
863  return d->mStatusString;
864  } else {
865  return QString();
866  }
867 }
868 
870 {
871  if (mReadOnly) {
872  return;
873  }
874 
875  update();
876  Q_D(Incidence);
877  d->mSecrecy = secrecy;
879  updated();
880 }
881 
882 Incidence::Secrecy Incidence::secrecy() const
883 {
884  Q_D(const Incidence);
885  return d->mSecrecy;
886 }
887 
889 {
890  Q_D(const Incidence);
891  return d->mAlarms;
892 }
893 
895 {
896  Q_D(Incidence);
897  Alarm::Ptr alarm(new Alarm(this));
898  addAlarm(alarm);
899  return alarm;
900 }
901 
902 void Incidence::addAlarm(const Alarm::Ptr &alarm)
903 {
904  Q_D(Incidence);
905  update();
906  d->mAlarms.append(alarm);
908  updated();
909 }
910 
912 {
913  Q_D(Incidence);
914  const int index = d->mAlarms.indexOf(alarm);
915  if (index > -1) {
916  update();
917  d->mAlarms.remove(index);
919  updated();
920  }
921 }
922 
924 {
925  update();
926  Q_D(Incidence);
927  d->mAlarms.clear();
929  updated();
930 }
931 
933 {
934  Q_D(const Incidence);
935  return std::any_of(d->mAlarms.cbegin(), d->mAlarms.cend(), [](const Alarm::Ptr &alarm) {
936  return alarm->enabled();
937  });
938 }
939 
940 Conference::List Incidence::conferences() const
941 {
942  Q_D(const Incidence);
943  return d->mConferences;
944 }
945 
946 void Incidence::addConference(const Conference &conference)
947 {
948  update();
949  Q_D(Incidence);
950  d->mConferences.push_back(conference);
952  updated();
953 }
954 
956 {
957  update();
958  Q_D(Incidence);
959  d->mConferences = conferences;
961  updated();
962 }
963 
965 {
966  update();
967  Q_D(Incidence);
968  d->mConferences.clear();
970  updated();
971 }
972 
973 void Incidence::setLocation(const QString &location, bool isRich)
974 {
975  if (mReadOnly) {
976  return;
977  }
978 
979  Q_D(Incidence);
980  if (d->mLocation != location || d->mLocationIsRich != isRich) {
981  update();
982  d->mLocation = location;
983  d->mLocationIsRich = isRich;
985  updated();
986  }
987 }
988 
989 void Incidence::setLocation(const QString &location)
990 {
991  setLocation(location, Qt::mightBeRichText(location));
992 }
993 
994 QString Incidence::location() const
995 {
996  Q_D(const Incidence);
997  return d->mLocation;
998 }
999 
1001 {
1002  Q_D(const Incidence);
1003  if (locationIsRich()) {
1004  return d->mLocation;
1005  } else {
1006  return d->mLocation.toHtmlEscaped().replace(QLatin1Char('\n'), QStringLiteral("<br/>"));
1007  }
1008 }
1009 
1011 {
1012  Q_D(const Incidence);
1013  return d->mLocationIsRich;
1014 }
1015 
1016 void Incidence::setSchedulingID(const QString &sid, const QString &uid)
1017 {
1018  if (!uid.isEmpty()) {
1019  setUid(uid);
1020  }
1021  Q_D(Incidence);
1022  if (sid != d->mSchedulingID) {
1023  update();
1024  d->mSchedulingID = sid;
1026  updated();
1027  }
1028 }
1029 
1031 {
1032  Q_D(const Incidence);
1033  if (d->mSchedulingID.isNull()) {
1034  // Nothing set, so use the normal uid
1035  return uid();
1036  }
1037  return d->mSchedulingID;
1038 }
1039 
1040 bool Incidence::hasGeo() const
1041 {
1042  Q_D(const Incidence);
1043  // For internal consistency, return false if either coordinate is invalid.
1044  return d->mGeoLatitude != INVALID_LATLON && d->mGeoLongitude != INVALID_LATLON;
1045 }
1046 #if KCALENDARCORE_BUILD_DEPRECATED_SINCE(5, 89)
1047 void Incidence::setHasGeo(bool hasGeo)
1048 {
1049  if (mReadOnly) {
1050  return;
1051  }
1052 
1053  Q_D(Incidence);
1054  if (!hasGeo) {
1055  update();
1056  d->mGeoLatitude = INVALID_LATLON;
1057  d->mGeoLongitude = INVALID_LATLON;
1060  updated();
1061  }
1062  // If hasGeo is true, the caller should set latitude and longitude to legal values..
1063 }
1064 #endif
1065 float Incidence::geoLatitude() const
1066 {
1067  Q_D(const Incidence);
1068  // For internal consistency, both coordinates are considered invalid if either is.
1069  return (INVALID_LATLON == d->mGeoLongitude) ? INVALID_LATLON : d->mGeoLatitude;
1070 }
1071 
1072 void Incidence::setGeoLatitude(float geolatitude)
1073 {
1074  if (mReadOnly) {
1075  return;
1076  }
1077 
1078  if (isnan(geolatitude)) {
1079  geolatitude = INVALID_LATLON;
1080  }
1081  if (geolatitude != INVALID_LATLON && (geolatitude < -90.0 || geolatitude > 90.0)) {
1082  qCWarning(KCALCORE_LOG) << "Ignoring invalid latitude" << geolatitude;
1083  return;
1084  }
1085 
1086  Q_D(Incidence);
1087  update();
1088  d->mGeoLatitude = geolatitude;
1090  updated();
1091 }
1092 
1093 float Incidence::geoLongitude() const
1094 {
1095  Q_D(const Incidence);
1096  // For internal consistency, both coordinates are considered invalid if either is.
1097  return (INVALID_LATLON == d->mGeoLatitude) ? INVALID_LATLON : d->mGeoLongitude;
1098 }
1099 
1100 void Incidence::setGeoLongitude(float geolongitude)
1101 {
1102  if (mReadOnly) {
1103  return;
1104  }
1105 
1106  if (isnan(geolongitude)) {
1107  geolongitude = INVALID_LATLON;
1108  }
1109  if (geolongitude != INVALID_LATLON && (geolongitude < -180.0 || geolongitude > 180.0)) {
1110  qCWarning(KCALCORE_LOG) << "Ignoring invalid longitude" << geolongitude;
1111  return;
1112  }
1113 
1114  Q_D(Incidence);
1115  update();
1116  d->mGeoLongitude = geolongitude;
1118  updated();
1119 }
1120 
1122 {
1123  Q_D(const Incidence);
1124  return (allDay() && d->mRecurrenceId.date().isValid()) || d->mRecurrenceId.isValid();
1125 }
1126 
1128 {
1129  Q_D(const Incidence);
1130  return d->mRecurrenceId;
1131 }
1132 
1133 void Incidence::setThisAndFuture(bool thisAndFuture)
1134 {
1135  Q_D(Incidence);
1136  d->mThisAndFuture = thisAndFuture;
1137 }
1138 
1140 {
1141  Q_D(const Incidence);
1142  return d->mThisAndFuture;
1143 }
1144 
1145 void Incidence::setRecurrenceId(const QDateTime &recurrenceId)
1146 {
1147  if (!mReadOnly) {
1148  update();
1149  Q_D(Incidence);
1150  d->mRecurrenceId = recurrenceId;
1152  updated();
1153  }
1154 }
1155 
1156 /** Observer interface for the recurrence class. If the recurrence is changed,
1157  this method will be called for the incidence the recurrence object
1158  belongs to. */
1160 {
1161  Q_D(const Incidence);
1162  if (recurrence == d->mRecurrence) {
1163  update();
1165  updated();
1166  }
1167 }
1168 
1169 //@cond PRIVATE
1170 #define ALT_DESC_FIELD "X-ALT-DESC"
1171 #define ALT_DESC_PARAMETERS QStringLiteral("FMTTYPE=text/html")
1172 //@endcond
1173 
1175 {
1176  const QString value = nonKDECustomProperty(ALT_DESC_FIELD);
1177  const QString parameter = nonKDECustomPropertyParameters(ALT_DESC_FIELD);
1178 
1179  return parameter == ALT_DESC_PARAMETERS && !value.isEmpty();
1180 }
1181 
1182 void Incidence::setAltDescription(const QString &altdescription)
1183 {
1184  if (altdescription.isEmpty()) {
1185  removeNonKDECustomProperty(ALT_DESC_FIELD);
1186  } else {
1187  setNonKDECustomProperty(ALT_DESC_FIELD, altdescription, ALT_DESC_PARAMETERS);
1188  }
1189 }
1190 
1192 {
1193  if (!hasAltDescription()) {
1194  return QString();
1195  } else {
1196  return nonKDECustomProperty(ALT_DESC_FIELD);
1197  }
1198 }
1199 
1200 /** static */
1202 {
1203  return QStringList() << QStringLiteral("text/calendar") << KCalendarCore::Event::eventMimeType() << KCalendarCore::Todo::todoMimeType()
1205 }
1206 
1208 {
1209  Q_D(const Incidence);
1210  serializeQDateTimeAsKDateTime(out, d->mCreated);
1211  out << d->mRevision << d->mDescription << d->mDescriptionIsRich << d->mSummary << d->mSummaryIsRich << d->mLocation << d->mLocationIsRich << d->mCategories
1212  << d->mResources << d->mStatusString << d->mPriority << d->mSchedulingID << d->mGeoLatitude << d->mGeoLongitude
1213  << hasGeo(); // No longer used, but serialized/deserialized for compatibility.
1214  serializeQDateTimeAsKDateTime(out, d->mRecurrenceId);
1215  out << d->mThisAndFuture << d->mLocalOnly << d->mStatus << d->mSecrecy << (d->mRecurrence ? true : false) << (qint32)d->mAttachments.count()
1216  << (qint32)d->mAlarms.count() << (qint32)d->mConferences.count() << d->mRelatedToUid;
1217 
1218  if (d->mRecurrence) {
1219  out << d->mRecurrence;
1220  }
1221 
1222  for (const Attachment &attachment : std::as_const(d->mAttachments)) {
1223  out << attachment;
1224  }
1225 
1226  for (const Alarm::Ptr &alarm : std::as_const(d->mAlarms)) {
1227  out << alarm;
1228  }
1229 
1230  for (const Conference &conf : std::as_const(d->mConferences)) {
1231  out << conf;
1232  }
1233 }
1234 
1236 {
1237  bool hasGeo; // No longer used, but serialized/deserialized for compatibility.
1238  quint32 status;
1239  quint32 secrecy;
1240  bool hasRecurrence;
1241  int attachmentCount;
1242  int alarmCount;
1243  int conferencesCount;
1244  QMap<int, QString> relatedToUid;
1245  Q_D(Incidence);
1246  deserializeKDateTimeAsQDateTime(in, d->mCreated);
1247  in >> d->mRevision >> d->mDescription >> d->mDescriptionIsRich >> d->mSummary >> d->mSummaryIsRich >> d->mLocation >> d->mLocationIsRich >> d->mCategories
1248  >> d->mResources >> d->mStatusString >> d->mPriority >> d->mSchedulingID >> d->mGeoLatitude >> d->mGeoLongitude >> hasGeo;
1249  deserializeKDateTimeAsQDateTime(in, d->mRecurrenceId);
1250  in >> d->mThisAndFuture >> d->mLocalOnly >> status >> secrecy >> hasRecurrence >> attachmentCount >> alarmCount >> conferencesCount >> relatedToUid;
1251 
1252  if (hasRecurrence) {
1253  d->mRecurrence = new Recurrence();
1254  d->mRecurrence->addObserver(const_cast<KCalendarCore::Incidence *>(this));
1255  in >> d->mRecurrence;
1256  }
1257 
1258  d->mAttachments.clear();
1259  d->mAlarms.clear();
1260  d->mConferences.clear();
1261 
1262  d->mAttachments.reserve(attachmentCount);
1263  for (int i = 0; i < attachmentCount; ++i) {
1264  Attachment attachment;
1265  in >> attachment;
1266  d->mAttachments.append(attachment);
1267  }
1268 
1269  d->mAlarms.reserve(alarmCount);
1270  for (int i = 0; i < alarmCount; ++i) {
1271  Alarm::Ptr alarm = Alarm::Ptr(new Alarm(this));
1272  in >> alarm;
1273  d->mAlarms.append(alarm);
1274  }
1275 
1276  d->mConferences.reserve(conferencesCount);
1277  for (int i = 0; i < conferencesCount; ++i) {
1278  Conference conf;
1279  in >> conf;
1280  d->mConferences.push_back(conf);
1281  }
1282 
1283  d->mStatus = static_cast<Incidence::Status>(status);
1284  d->mSecrecy = static_cast<Incidence::Secrecy>(secrecy);
1285 
1286  d->mRelatedToUid.clear();
1287 
1288  auto it = relatedToUid.cbegin();
1289  auto end = relatedToUid.cend();
1290  for (; it != end; ++it) {
1291  d->mRelatedToUid.insert(static_cast<Incidence::RelType>(it.key()), it.value());
1292  }
1293 }
1294 
1295 namespace
1296 {
1297 template<typename T>
1298 QVariantList toVariantList(int size, typename QVector<T>::ConstIterator begin, typename QVector<T>::ConstIterator end)
1299 {
1300  QVariantList l;
1301  l.reserve(size);
1302  std::transform(begin, end, std::back_inserter(l), [](const T &val) {
1303  return QVariant::fromValue(val);
1304  });
1305  return l;
1306 }
1307 
1308 } // namespace
1309 
1310 QVariantList Incidence::attachmentsVariant() const
1311 {
1312  Q_D(const Incidence);
1313  return toVariantList<Attachment>(d->mAttachments.size(), d->mAttachments.cbegin(), d->mAttachments.cend());
1314 }
1315 
1316 QVariantList Incidence::conferencesVariant() const
1317 {
1318  Q_D(const Incidence);
1319  return toVariantList<Conference>(d->mConferences.size(), d->mConferences.cbegin(), d->mConferences.cend());
1320 }
1321 
1322 #include "moc_incidence.cpp"
bool hasAltDescription() const
Returns true if the alternative (=text/html) description is available.
Definition: incidence.cpp:1174
void setNonKDECustomProperty(const QByteArray &name, const QString &value, const QString &parameters=QString())
Create or modify a non-KDE or non-standard custom calendar property.
@ FieldGeoLongitude
Field representing the longitude part of the GEO component.
QString categoriesStr() const
Returns the incidence categories as a comma separated string.
Definition: incidence.cpp:528
Status
The different types of overall incidence status or confirmation.
Definition: incidence.h:84
bool descriptionIsRich() const
Returns true if incidence description contains RichText; false otherwise.
Definition: incidence.cpp:436
void serialize(QDataStream &out) const override
Sub-type specific serialization.
Definition: incidence.cpp:1207
QDateTime addSecs(qint64 s) const const
void setSummary(const QString &summary, bool isRich)
Sets the incidence summary.
Definition: incidence.cpp:442
static QStringList mimeTypes()
Returns the list of possible mime types in an Incidence object: "text/calendar" "application/x-vnd....
Definition: incidence.cpp:1201
@ FieldGeoLatitude
Field representing the latitude part of the GEO component.
void setCreated(const QDateTime &dt)
Sets the incidence creation date/time.
Definition: incidence.cpp:335
virtual QList< QDateTime > startDateTimesForDate(const QDate &date, const QTimeZone &timeZone) const
Calculates the start date/time for all recurrences that happen at some time on the given date (might ...
Definition: incidence.cpp:629
virtual QByteArray typeStr() const =0
Prints the type of incidence as a string.
QString nonKDECustomPropertyParameters(const QByteArray &name) const
Return the parameters of a non-KDE or non-standard custom calendar property.
void clearConferences()
Removes all conferences from the incidence.
Definition: incidence.cpp:964
@ FieldSecrecy
Field representing the CLASS component.
void addAttachment(const Attachment &attachment)
Adds an attachment to the incidence.
Definition: incidence.cpp:723
QTimeZone timeZone() const const
QString nonKDECustomProperty(const QByteArray &name) const
Return the value of a non-KDE or non-standard custom calendar property.
QVariant fromValue(const T &value)
void resetDirtyFields()
Resets dirty fields.
bool recurs() const
Returns whether the event recurs at all.
Definition: incidence.cpp:607
@ StatusNone
No status.
Definition: incidence.h:85
@ FieldCategories
Field representing the CATEGORIES component.
@ FieldStatus
Field representing the STATUS component.
QString richLocation() const
Returns the incidence location in rich text format.
Definition: incidence.cpp:1000
QVector::const_iterator cend() const const
void setRecurrenceId(const QDateTime &recurrenceId)
Set the incidences recurrenceId.
Definition: incidence.cpp:1145
Recurrence * recurrence() const
Returns the recurrence rule associated with this incidence.
Definition: incidence.cpp:576
static QLatin1String todoMimeType()
Returns the Akonadi specific sub MIME type of a KCalendarCore::Todo.
Definition: todo.cpp:612
bool localOnly() const
Get the localOnly status.
Definition: incidence.cpp:317
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
virtual void setDtStart(const QDateTime &dtStart)
Sets the incidence's starting date/time with a QDateTime.
Namespace for all KCalendarCore types.
Definition: alarm.h:36
QTime time() const const
void append(const T &value)
void update()
Call this to notify the observers after the IncidenceBase object will be changed.
@ FieldAttachment
Field representing the ATTACH component.
QString instanceIdentifier() const
Returns a unique identifier for a specific instance of an incidence.
Definition: incidence.cpp:273
QSet< IncidenceBase::Field > dirtyFields() const
Returns a QSet with all Fields that were changed since the incidence was created or resetDirtyFields(...
void clearAttachments()
Removes all attachments and frees the memory used by them.
Definition: incidence.cpp:768
bool locationIsRich() const
Returns true if incidence location contains RichText; false otherwise.
Definition: incidence.cpp:1010
void removeNonKDECustomProperty(const QByteArray &name)
Delete a non-KDE or non-standard custom calendar property.
void setRevision(int rev)
Sets the number of revisions this incidence has seen.
Definition: incidence.cpp:357
virtual IncidenceBase & assign(const IncidenceBase &other)
Provides polymorfic assignment.
@ FieldConferences
Field representing the CONFERENCE component.
QDateTime currentDateTimeUtc()
Provides the abstract base class common to non-FreeBusy (Events, To-dos, Journals) calendar component...
Definition: incidence.h:59
@ FieldSchedulingId
Field representing the X-KDE-LIBKCAL-ID component.
void setAllDay(bool allDay) override
Definition: incidence.cpp:323
@ FieldColor
Field representing the COLOR component.
bool mightBeRichText(const QString &text)
void setUid(const QString &uid)
Sets the unique id for the incidence to uid.
~Incidence() override
Destroys an incidence.
Definition: incidence.cpp:165
void setLocalOnly(bool localonly)
Set localOnly state of incidence.
Definition: incidence.cpp:308
@ FieldCreated
Field representing the CREATED component.
void setStatus(Status status)
Sets the incidence status to a standard Status value.
Definition: incidence.cpp:820
void setGeoLatitude(float geolatitude)
Set the incidence's geoLatitude.
Definition: incidence.cpp:1072
Alarm::Ptr newAlarm()
Create a new incidence alarm.
Definition: incidence.cpp:894
QString customStatus() const
Returns the non-standard status value.
Definition: incidence.cpp:859
@ FieldDescription
Field representing the DESCRIPTION component.
void removeAlarm(const Alarm::Ptr &alarm)
Removes the specified alarm from the incidence.
Definition: incidence.cpp:911
void setCustomStatus(const QString &status)
Sets the incidence Status to a non-standard status value.
Definition: incidence.cpp:839
virtual QList< QDateTime > startDateTimesForDateTime(const QDateTime &datetime) const
Calculates the start date/time for all recurrences that happen at the given time.
Definition: incidence.cpp:669
@ FieldPriority
Field representing the PRIORITY component.
An abstract class that provides a common base for all calendar incidence classes.
Definition: incidencebase.h:98
void shiftTimes(const QTimeZone &oldZone, const QTimeZone &newZone) override
Shift the times of the incidence so that they appear at the same clock time as before but in a new ti...
Definition: incidence.cpp:385
bool recursAt(const QDateTime &dt) const
Returns true if the date/time specified is one at which the event will recur.
Definition: incidence.cpp:623
QStringList resources() const
Returns the incidence resources as a list of strings.
Definition: incidence.cpp:790
Q_SCRIPTABLE Q_NOREPLY void start()
void clearRecurrence()
Removes all recurrence and exception rules and dates.
Definition: incidence.cpp:590
void setAltDescription(const QString &altdescription)
Sets the incidence's alternative (=text/html) description.
Definition: incidence.cpp:1182
@ FieldRevision
Field representing the SEQUENCE component.
void updated()
Call this to notify the observers after the IncidenceBase object has changed.
QDateTime recurrenceId() const override
Returns the incidence recurrenceId.
Definition: incidence.cpp:1127
void recreate()
Recreate incidence.
Definition: incidence.cpp:281
@ FieldRelatedTo
Field representing the RELATED-TO component.
QString relatedTo(RelType relType=RelTypeParent) const
Returns a UID string for the incidence that is related to this one.
Definition: incidence.cpp:548
@ FieldRecurrence
Field representing the EXDATE, EXRULE, RDATE, and RRULE components.
void clearAlarms()
Removes all alarms.
Definition: incidence.cpp:923
QVector::const_iterator cbegin() const const
void recurrenceUpdated(Recurrence *recurrence) override
Observer interface for the recurrence class.
Definition: incidence.cpp:1159
static QString createUniqueId()
Creates a unique id string.
Definition: calformat.cpp:95
bool equals(const IncidenceBase &incidence) const override
Compares this with Incidence incidence for equality.
Definition: incidence.cpp:198
bool isEmpty() const const
bool hasEnabledAlarms() const
Returns true if any of the incidence alarms are enabled; false otherwise.
Definition: incidence.cpp:932
static QLatin1String eventMimeType()
Returns the Akonadi specific sub MIME type of a KCalendarCore::Event.
Definition: event.cpp:335
QSharedPointer< Alarm > Ptr
A shared pointer to an Alarm object.
Definition: alarm.h:67
void deserialize(QDataStream &in) override
Sub-type specific deserialization.
Definition: incidence.cpp:1235
Q_SCRIPTABLE CaptureState status()
void setThisAndFuture(bool thisAndFuture)
Set to true if the exception also applies to all future occurrences.
Definition: incidence.cpp:1133
QString color() const
Returns the color, if any is defined, for this incidence.
Definition: incidence.cpp:568
virtual QDateTime endDateForStart(const QDateTime &startDt) const
Returns the end date/time of the incidence occurrence if it starts at specified date/time.
Definition: incidence.cpp:709
void setReadOnly(bool readonly) override
Set readonly state of incidence.
Definition: incidence.cpp:299
void setRelatedTo(const QString &uid, RelType relType=RelTypeParent)
Relates another incidence to this one, by UID.
Definition: incidence.cpp:534
virtual QDateTime dateTime(DateTimeRole role) const =0
Returns a date/time corresponding to the specified DateTimeRole.
Represents information related to an attachment for a Calendar Incidence.
Definition: attachment.h:46
QDate addDays(qint64 ndays) const const
QString schedulingID() const
Returns the incidence scheduling ID.
Definition: incidence.cpp:1030
void setSecrecy(Secrecy secrecy)
Sets the incidence Secrecy.
Definition: incidence.cpp:869
virtual void setReadOnly(bool readOnly)
Sets readonly status.
void setResources(const QStringList &resources)
Sets a list of incidence resources.
Definition: incidence.cpp:777
void setGeoLongitude(float geolongitude)
Set the incidence's geoLongitude.
Definition: incidence.cpp:1100
Represents information related to a conference information of an Calendar Incidence,...
Definition: conference.h:31
QDateTime toUTC() const const
void setDtStart(const QDateTime &dt) override
Sets the incidence starting date/time.
Definition: incidence.cpp:376
void setDescription(const QString &description, bool isRich)
Sets the incidence description.
Definition: incidence.cpp:402
@ FieldAlarms
Field representing the VALARM component.
void setConferences(const Conference::List &conferences)
Replaces all conferences in the incidence with given conferences.
Definition: incidence.cpp:955
static QLatin1String journalMimeType()
Returns the Akonadi specific sub MIME type of a KCalendarCore::Journal.
Definition: journal.cpp:128
QString altDescription() const
Returns the incidence alternative (=text/html) description.
Definition: incidence.cpp:1191
bool thisAndFuture() const
Returns true if the exception also applies to all future occurrences.
Definition: incidence.cpp:1139
@ FieldSummary
Field representing the SUMMARY component.
void setLocation(const QString &location, bool isRich)
Sets the incidence location.
Definition: incidence.cpp:973
void setPriority(int priority)
Sets the incidences priority.
Definition: incidence.cpp:796
@ FieldRecurrenceId
Field representing the RECURRENCE-ID component.
TimeList recurTimesOn(const QDate &date, const QTimeZone &timeZone) const
Returns a list of the times on the specified date at which the recurrence will occur.
Definition: recurrence.cpp:995
This class represents a recurrence rule for a calendar incidence.
Definition: recurrence.h:76
virtual void shiftTimes(const QTimeZone &oldZone, const QTimeZone &newZone)
Shift the times of the incidence so that they appear at the same clock time as before but in a new ti...
QDate date() const const
Secrecy
The different types of incidence access classifications.
Definition: incidence.h:101
@ RoleRecurrenceStart
Role for determining the start of the recurrence.
bool summaryIsRich() const
Returns true if incidence summary contains RichText; false otherwise.
Definition: incidence.cpp:478
IncidenceBase & assign(const IncidenceBase &other) override
Provides polymorfic assignment.
Definition: incidence.cpp:184
int count(const T &value) const const
Represents an alarm notification.
Definition: alarm.h:50
@ FieldResources
Field representing the RESOURCES component.
void setCategories(const QStringList &categories)
Sets the incidence category list.
Definition: incidence.cpp:484
virtual bool equals(const IncidenceBase &incidenceBase) const
Provides polymorfic comparison for equality.
QString richDescription() const
Returns the incidence description in rich text format.
Definition: incidence.cpp:426
void setSchedulingID(const QString &sid, const QString &uid=QString())
Set the incidence scheduling ID.
Definition: incidence.cpp:1016
Incidence()
Constructs an empty incidence.
Definition: incidence.cpp:132
QString toString(Qt::DateFormat format) const const
@ StatusX
a non-standard status string
Definition: incidence.h:94
ushort recurrenceType() const
Returns the event's recurrence status.
Definition: incidence.cpp:597
bool mReadOnly
Identifies a read-only incidence.
bool hasRecurrenceId() const
Returns true if the incidence has recurrenceId, otherwise return false.
Definition: incidence.cpp:1121
int revision() const
Returns the number of revisions this incidence has seen.
Definition: incidence.cpp:370
RelType
The different types of RELTYPE values specified by the RFC.
Definition: incidence.h:112
void setColor(const QString &colorName)
Set the incidence color, as added in RFC7986.
Definition: incidence.cpp:554
void addConference(const Conference &conference)
Adds a conference to the incidence.
Definition: incidence.cpp:946
void addAlarm(const Alarm::Ptr &alarm)
Adds an alarm to the incidence.
Definition: incidence.cpp:902
void deleteAttachments(const QString &mime)
Removes all attachments of the specified MIME type from the incidence.
Definition: incidence.cpp:736
void setFieldDirty(IncidenceBase::Field field)
Marks Field field as dirty.
Alarm::List alarms() const
Returns a list of all incidence alarms.
Definition: incidence.cpp:888
void setLastModified(const QDateTime &lm) override
Definition: incidence.cpp:291
Q_D(Todo)
Private class that helps to provide binary compatibility between releases.
virtual void setAllDay(bool allDay)
Sets whether the incidence is all-day, i.e.
QString richSummary() const
Returns the incidence summary in rich text format.
Definition: incidence.cpp:468
virtual void setLastModified(const QDateTime &lm)
Sets the time the incidence was last modified to lm.
@ FieldDtStart
Field representing the DTSTART component.
void setHasGeo(bool hasGeo)
Sets if the incidence has geo data.
Definition: incidence.cpp:1047
virtual bool recursOn(const QDate &date, const QTimeZone &timeZone) const
Returns true if the date specified is one on which the event will recur.
Definition: incidence.cpp:617
@ FieldLocation
Field representing the LOCATION component.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Sep 26 2023 03:53:18 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.