• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.11.5 API Reference
  • KDE Home
  • Contact Us
 

KCalCore Library

  • kcalcore
incidence.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the kcalcore library.
3 
4  Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
5  Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
35 #include "incidence.h"
36 #include "calformat.h"
37 
38 #include <KMimeType>
39 #include <KTemporaryFile>
40 #include <KDebug>
41 
42 #include <QTextDocument> // for Qt::escape() and Qt::mightBeRichText()
43 #include <QTime>
44 
45 using namespace KCalCore;
46 
51 //@cond PRIVATE
52 class KCalCore::Incidence::Private
53 {
54 public:
55  Private()
56  : mRevision(0),
57  mDescriptionIsRich(false),
58  mSummaryIsRich(false),
59  mLocationIsRich(false),
60  mRecurrence(0),
61  mStatus(StatusNone),
62  mSecrecy(SecrecyPublic),
63  mPriority(0),
64  mGeoLatitude(INVALID_LATLON),
65  mGeoLongitude(INVALID_LATLON),
66  mHasGeo(false),
67  mThisAndFuture(false),
68  mLocalOnly(false)
69  {
70  }
71 
72  Private(const Private &p)
73  : mCreated(p.mCreated),
74  mRevision(p.mRevision),
75  mDescription(p.mDescription),
76  mDescriptionIsRich(p.mDescriptionIsRich),
77  mSummary(p.mSummary),
78  mSummaryIsRich(p.mSummaryIsRich),
79  mLocation(p.mLocation),
80  mLocationIsRich(p.mLocationIsRich),
81  mCategories(p.mCategories),
82  mRecurrence(0),
83  mResources(p.mResources),
84  mStatus(p.mStatus),
85  mStatusString(p.mStatusString),
86  mSecrecy(p.mSecrecy),
87  mPriority(p.mPriority),
88  mSchedulingID(p.mSchedulingID),
89  mRelatedToUid(p.mRelatedToUid),
90  mGeoLatitude(p.mGeoLatitude),
91  mGeoLongitude(p.mGeoLongitude),
92  mHasGeo(p.mHasGeo),
93  mRecurrenceId(p.mRecurrenceId),
94  mThisAndFuture(p.mThisAndFuture),
95  mLocalOnly(false)
96  {
97  }
98 
99  void clear()
100  {
101  mAlarms.clear();
102  mAttachments.clear();
103  delete mRecurrence;
104  mRecurrence = 0;
105  }
106 
107  void init(Incidence *dest, const Incidence &src)
108  {
109  mRevision = src.d->mRevision;
110  mCreated = src.d->mCreated;
111  mDescription = src.d->mDescription;
112  mSummary = src.d->mSummary;
113  mCategories = src.d->mCategories;
114  mRelatedToUid = src.d->mRelatedToUid;
115  mResources = src.d->mResources;
116  mStatusString = src.d->mStatusString;
117  mStatus = src.d->mStatus;
118  mSecrecy = src.d->mSecrecy;
119  mPriority = src.d->mPriority;
120  mLocation = src.d->mLocation;
121  mGeoLatitude = src.d->mGeoLatitude;
122  mGeoLongitude = src.d->mGeoLongitude;
123  mHasGeo = src.d->mHasGeo;
124  mRecurrenceId = src.d->mRecurrenceId;
125  mThisAndFuture = src.d->mThisAndFuture;
126  mLocalOnly = src.d->mLocalOnly;
127 
128  // Alarms and Attachments are stored in ListBase<...>, which is a QValueList<...*>.
129  // We need to really duplicate the objects stored therein, otherwise deleting
130  // i will also delete all attachments from this object (setAutoDelete...)
131  foreach(Alarm::Ptr alarm, src.d->mAlarms) {
132  Alarm::Ptr b(new Alarm(*alarm.data()));
133  b->setParent(dest);
134  mAlarms.append(b);
135  }
136 
137  foreach(Attachment::Ptr attachment, src.d->mAttachments) {
138  Attachment::Ptr a(new Attachment(*attachment));
139  mAttachments.append(a);
140  }
141 
142  if (src.d->mRecurrence) {
143  mRecurrence = new Recurrence(*(src.d->mRecurrence));
144  mRecurrence->addObserver(dest);
145  } else {
146  mRecurrence = 0;
147  }
148  }
149 
150  KDateTime mCreated; // creation datetime
151  int mRevision; // revision number
152 
153  QString mDescription; // description string
154  bool mDescriptionIsRich; // description string is richtext.
155  QString mSummary; // summary string
156  bool mSummaryIsRich; // summary string is richtext.
157  QString mLocation; // location string
158  bool mLocationIsRich; // location string is richtext.
159  QStringList mCategories; // category list
160  mutable Recurrence *mRecurrence; // recurrence
161  Attachment::List mAttachments; // attachments list
162  Alarm::List mAlarms; // alarms list
163  QStringList mResources; // resources list (not calendar resources)
164  Status mStatus; // status
165  QString mStatusString; // status string, for custom status
166  Secrecy mSecrecy; // secrecy
167  int mPriority; // priority: 1 = highest, 2 = less, etc.
168  QString mSchedulingID; // ID for scheduling mails
169 
170  QMap<RelType,QString> mRelatedToUid;// incidence uid this is related to, for each relType
171  float mGeoLatitude; // Specifies latitude in decimal degrees
172  float mGeoLongitude; // Specifies longitude in decimal degrees
173  bool mHasGeo; // if incidence has geo data
174  QHash<Attachment::Ptr,QString> mTempFiles; // Temporary files for writing attachments to.
175  KDateTime mRecurrenceId; // recurrenceId
176  bool mThisAndFuture;
177  bool mLocalOnly; // allow changes that won't go to the server
178 };
179 //@endcond
180 
181 Incidence::Incidence()
182  : IncidenceBase(), d(new KCalCore::Incidence::Private)
183 {
184  recreate();
185  resetDirtyFields();
186 }
187 
188 Incidence::Incidence(const Incidence &i)
189  : IncidenceBase(i),
190  Recurrence::RecurrenceObserver(),
191  d(new KCalCore::Incidence::Private(*i.d))
192 {
193  d->init(this, i);
194  resetDirtyFields();
195 }
196 
197 Incidence::~Incidence()
198 {
199  // Alarm has a raw incidence pointer, so we must set it to 0
200  // so Alarm doesn't use it after Incidence is destroyed
201  foreach(Alarm::Ptr alarm, d->mAlarms) {
202  alarm->setParent(0);
203  }
204 
205  delete d->mRecurrence;
206  delete d;
207 }
208 
209 //@cond PRIVATE
210 // A string comparison that considers that null and empty are the same
211 static bool stringCompare(const QString &s1, const QString &s2)
212 {
213  return (s1.isEmpty() && s2.isEmpty()) || (s1 == s2);
214 }
215 
216 //@endcond
217 IncidenceBase &Incidence::assign(const IncidenceBase &other)
218 {
219  if (&other != this) {
220  d->clear();
221  //TODO: should relations be cleared out, as in destructor???
222  IncidenceBase::assign(other);
223  const Incidence *i = static_cast<const Incidence*>(&other);
224  d->init(this, *i);
225  }
226 
227  return *this;
228 }
229 
230 bool Incidence::equals(const IncidenceBase &incidence) const
231 {
232  if (!IncidenceBase::equals(incidence)) {
233  return false;
234  }
235 
236  // If they weren't the same type IncidenceBase::equals would had returned false already
237  const Incidence *i2 = static_cast<const Incidence *>(&incidence);
238 
239  if (alarms().count() != i2->alarms().count()) {
240  return false;
241  }
242 
243  Alarm::List::ConstIterator a1 = alarms().constBegin();
244  Alarm::List::ConstIterator a1end = alarms().constEnd();
245  Alarm::List::ConstIterator a2 = i2->alarms().constBegin();
246  Alarm::List::ConstIterator a2end = i2->alarms().constEnd();
247  for (; a1 != a1end && a2 != a2end; ++a1, ++a2) {
248  if (**a1 == **a2) {
249  continue;
250  } else {
251  return false;
252  }
253  }
254 
255  if (attachments().count() != i2->attachments().count()) {
256  return false;
257  }
258 
259  Attachment::List::ConstIterator att1 = attachments().constBegin();
260  const Attachment::List::ConstIterator att1end = attachments().constEnd();
261  Attachment::List::ConstIterator att2 = i2->attachments().constBegin();
262  const Attachment::List::ConstIterator att2end = i2->attachments().constEnd();
263  for (; att1 != att1end && att2 != att2end; ++att1, ++att2) {
264  if (**att1 == **att2) {
265  continue;
266  } else {
267  return false;
268  }
269  }
270 
271  bool recurrenceEqual = (d->mRecurrence == 0 && i2->d->mRecurrence == 0);
272  if (!recurrenceEqual) {
273  recurrence(); // create if doesn't exist
274  i2->recurrence(); // create if doesn't exist
275  recurrenceEqual = d->mRecurrence != 0 &&
276  i2->d->mRecurrence != 0 &&
277  *d->mRecurrence == *i2->d->mRecurrence;
278  }
279 
280  return
281  recurrenceEqual &&
282  created() == i2->created() &&
283  stringCompare(description(), i2->description()) &&
284  stringCompare(summary(), i2->summary()) &&
285  categories() == i2->categories() &&
286  stringCompare(relatedTo(), i2->relatedTo()) &&
287  resources() == i2->resources() &&
288  d->mStatus == i2->d->mStatus &&
289  (d->mStatus == StatusNone ||
290  stringCompare(d->mStatusString, i2->d->mStatusString)) &&
291  secrecy() == i2->secrecy() &&
292  priority() == i2->priority() &&
293  stringCompare(location(), i2->location()) &&
294  stringCompare(schedulingID(), i2->schedulingID()) &&
295  recurrenceId() == i2->recurrenceId() &&
296  thisAndFuture() == i2->thisAndFuture();
297 }
298 
299 QString Incidence::instanceIdentifier() const
300 {
301  if (hasRecurrenceId()) {
302  return uid() + recurrenceId().toString();
303  }
304  return uid();
305 }
306 
307 void Incidence::recreate()
308 {
309  const KDateTime nowUTC = KDateTime::currentUtcDateTime();
310  setCreated(nowUTC);
311 
312  setSchedulingID(QString(), CalFormat::createUniqueId());
313  setRevision(0);
314  setLastModified(nowUTC);
315 }
316 
317 void Incidence::setLastModified(const KDateTime &lm)
318 {
319  if (!d->mLocalOnly) {
320  IncidenceBase::setLastModified(lm);
321  }
322 }
323 
324 void Incidence::setReadOnly(bool readOnly)
325 {
326  IncidenceBase::setReadOnly(readOnly);
327  if (d->mRecurrence) {
328  d->mRecurrence->setRecurReadOnly(readOnly);
329  }
330 }
331 
332 void Incidence::setLocalOnly(bool localOnly)
333 {
334  if (mReadOnly) {
335  return;
336  }
337  d->mLocalOnly = localOnly;
338 }
339 
340 bool Incidence::localOnly() const
341 {
342  return d->mLocalOnly;
343 }
344 
345 void Incidence::setAllDay(bool allDay)
346 {
347  if (mReadOnly) {
348  return;
349  }
350  if (d->mRecurrence) {
351  d->mRecurrence->setAllDay(allDay);
352  }
353  IncidenceBase::setAllDay(allDay);
354 }
355 
356 void Incidence::setCreated(const KDateTime &created)
357 {
358  if (mReadOnly || d->mLocalOnly) {
359  return;
360  }
361 
362  d->mCreated = created.toUtc();
363  setFieldDirty(FieldCreated);
364 
365 // FIXME: Shouldn't we call updated for the creation date, too?
366 // updated();
367 }
368 
369 KDateTime Incidence::created() const
370 {
371  return d->mCreated;
372 }
373 
374 void Incidence::setRevision(int rev)
375 {
376  if (mReadOnly || d->mLocalOnly) {
377  return;
378  }
379 
380  update();
381 
382  d->mRevision = rev;
383  setFieldDirty(FieldRevision);
384  updated();
385 }
386 
387 int Incidence::revision() const
388 {
389  return d->mRevision;
390 }
391 
392 void Incidence::setDtStart(const KDateTime &dt)
393 {
394  if (d->mRecurrence) {
395  d->mRecurrence->setStartDateTime(dt);
396  }
397  IncidenceBase::setDtStart(dt);
398 }
399 
400 void Incidence::shiftTimes(const KDateTime::Spec &oldSpec,
401  const KDateTime::Spec &newSpec)
402 {
403  IncidenceBase::shiftTimes(oldSpec, newSpec);
404  if (d->mRecurrence) {
405  d->mRecurrence->shiftTimes(oldSpec, newSpec);
406  }
407  for (int i = 0, end = d->mAlarms.count(); i < end; ++i) {
408  d->mAlarms[i]->shiftTimes(oldSpec, newSpec);
409  }
410 }
411 
412 void Incidence::setDescription(const QString &description, bool isRich)
413 {
414  if (mReadOnly) {
415  return;
416  }
417  update();
418  d->mDescription = description;
419  d->mDescriptionIsRich = isRich;
420  setFieldDirty(FieldDescription);
421  updated();
422 }
423 
424 void Incidence::setDescription(const QString &description)
425 {
426  setDescription(description, Qt::mightBeRichText(description));
427 }
428 
429 QString Incidence::description() const
430 {
431  return d->mDescription;
432 }
433 
434 QString Incidence::richDescription() const
435 {
436  if (descriptionIsRich()) {
437  return d->mDescription;
438  } else {
439  return Qt::escape(d->mDescription).replace('\n', "<br/>");
440  }
441 }
442 
443 bool Incidence::descriptionIsRich() const
444 {
445  return d->mDescriptionIsRich;
446 }
447 
448 void Incidence::setSummary(const QString &summary, bool isRich)
449 {
450  if (mReadOnly) {
451  return;
452  }
453  update();
454  d->mSummary = summary;
455  d->mSummaryIsRich = isRich;
456  setFieldDirty(FieldSummary);
457  updated();
458 }
459 
460 void Incidence::setSummary(const QString &summary)
461 {
462  setSummary(summary, Qt::mightBeRichText(summary));
463 }
464 
465 QString Incidence::summary() const
466 {
467  return d->mSummary;
468 }
469 
470 QString Incidence::richSummary() const
471 {
472  if (summaryIsRich()) {
473  return d->mSummary;
474  } else {
475  return Qt::escape(d->mSummary).replace('\n', "<br/>");
476  }
477 }
478 
479 bool Incidence::summaryIsRich() const
480 {
481  return d->mSummaryIsRich;
482 }
483 
484 void Incidence::setCategories(const QStringList &categories)
485 {
486  if (mReadOnly) {
487  return;
488  }
489 
490  update();
491  d->mCategories = categories;
492  updated();
493 }
494 
495 void Incidence::setCategories(const QString &catStr)
496 {
497  if (mReadOnly) {
498  return;
499  }
500  update();
501  setFieldDirty(FieldCategories);
502 
503  d->mCategories.clear();
504 
505  if (catStr.isEmpty()) {
506  updated();
507  return;
508  }
509 
510  d->mCategories = catStr.split(',');
511 
512  QStringList::Iterator it;
513  for (it = d->mCategories.begin(); it != d->mCategories.end(); ++it) {
514  *it = (*it).trimmed();
515  }
516 
517  updated();
518 }
519 
520 QStringList Incidence::categories() const
521 {
522  return d->mCategories;
523 }
524 
525 QString Incidence::categoriesStr() const
526 {
527  return d->mCategories.join(",");
528 }
529 
530 void Incidence::setRelatedTo(const QString &relatedToUid, RelType relType)
531 {
532  // TODO: RFC says that an incidence can have more than one related-to field
533  // even for the same relType.
534 
535  if (d->mRelatedToUid[relType] != relatedToUid) {
536  update();
537  d->mRelatedToUid[relType] = relatedToUid;
538  setFieldDirty(FieldRelatedTo);
539  updated();
540  }
541 }
542 
543 QString Incidence::relatedTo(RelType relType) const
544 {
545  return d->mRelatedToUid.value(relType);
546 }
547 
548 // %%%%%%%%%%%% Recurrence-related methods %%%%%%%%%%%%%%%%%%%%
549 
550 Recurrence *Incidence::recurrence() const
551 {
552  if (!d->mRecurrence) {
553  d->mRecurrence = new Recurrence();
554  d->mRecurrence->setStartDateTime(dateTime(RoleRecurrenceStart));
555  d->mRecurrence->setAllDay(allDay());
556  d->mRecurrence->setRecurReadOnly(mReadOnly);
557  d->mRecurrence->addObserver(const_cast<KCalCore::Incidence*>(this));
558  }
559 
560  return d->mRecurrence;
561 }
562 
563 void Incidence::clearRecurrence()
564 {
565  delete d->mRecurrence;
566  d->mRecurrence = 0;
567 }
568 
569 ushort Incidence::recurrenceType() const
570 {
571  if (d->mRecurrence) {
572  return d->mRecurrence->recurrenceType();
573  } else {
574  return Recurrence::rNone;
575  }
576 }
577 
578 bool Incidence::recurs() const
579 {
580  if (d->mRecurrence) {
581  return d->mRecurrence->recurs();
582  } else {
583  return false;
584  }
585 }
586 
587 bool Incidence::recursOn(const QDate &date,
588  const KDateTime::Spec &timeSpec) const
589 {
590  return d->mRecurrence && d->mRecurrence->recursOn(date, timeSpec);
591 }
592 
593 bool Incidence::recursAt(const KDateTime &qdt) const
594 {
595  return d->mRecurrence && d->mRecurrence->recursAt(qdt);
596 }
597 
598 QList<KDateTime> Incidence::startDateTimesForDate(const QDate &date,
599  const KDateTime::Spec &timeSpec) const
600 {
601  KDateTime start = dtStart();
602  KDateTime end = dateTime(RoleEndRecurrenceBase);
603 
604  QList<KDateTime> result;
605 
606  // TODO_Recurrence: Also work if only due date is given...
607  if (!start.isValid() && ! end.isValid()) {
608  return result;
609  }
610 
611  // if the incidence doesn't recur,
612  KDateTime kdate(date, timeSpec);
613  if (!recurs()) {
614  if (!(start > kdate || end < kdate)) {
615  result << start;
616  }
617  return result;
618  }
619 
620  int days = start.daysTo(end);
621  // Account for possible recurrences going over midnight, while the original event doesn't
622  QDate tmpday(date.addDays(-days - 1));
623  KDateTime tmp;
624  while (tmpday <= date) {
625  if (recurrence()->recursOn(tmpday, timeSpec)) {
626  QList<QTime> times = recurrence()->recurTimesOn(tmpday, timeSpec);
627  foreach(const QTime &time, times) {
628  tmp = KDateTime(tmpday, time, start.timeSpec());
629  if (endDateForStart(tmp) >= kdate) {
630  result << tmp;
631  }
632  }
633  }
634  tmpday = tmpday.addDays(1);
635  }
636  return result;
637 }
638 
639 QList<KDateTime> Incidence::startDateTimesForDateTime(const KDateTime &datetime) const
640 {
641  KDateTime start = dtStart();
642  KDateTime end = dateTime(RoleEndRecurrenceBase);
643 
644  QList<KDateTime> result;
645 
646  // TODO_Recurrence: Also work if only due date is given...
647  if (!start.isValid() && ! end.isValid()) {
648  return result;
649  }
650 
651  // if the incidence doesn't recur,
652  if (!recurs()) {
653  if (!(start > datetime || end < datetime)) {
654  result << start;
655  }
656  return result;
657  }
658 
659  int days = start.daysTo(end);
660  // Account for possible recurrences going over midnight, while the original event doesn't
661  QDate tmpday(datetime.date().addDays(-days - 1));
662  KDateTime tmp;
663  while (tmpday <= datetime.date()) {
664  if (recurrence()->recursOn(tmpday, datetime.timeSpec())) {
665  // Get the times during the day (in start date's time zone) when recurrences happen
666  QList<QTime> times = recurrence()->recurTimesOn(tmpday, start.timeSpec());
667  foreach(const QTime &time, times) {
668  tmp = KDateTime(tmpday, time, start.timeSpec());
669  if (!(tmp > datetime || endDateForStart(tmp) < datetime)) {
670  result << tmp;
671  }
672  }
673  }
674  tmpday = tmpday.addDays(1);
675  }
676  return result;
677 }
678 
679 KDateTime Incidence::endDateForStart(const KDateTime &startDt) const
680 {
681  KDateTime start = dtStart();
682  KDateTime end = dateTime(RoleEndRecurrenceBase);
683  if (!end.isValid()) {
684  return start;
685  }
686  if (!start.isValid()) {
687  return end;
688  }
689 
690  return startDt.addSecs(start.secsTo(end));
691 }
692 
693 void Incidence::addAttachment(const Attachment::Ptr &attachment)
694 {
695  if (mReadOnly || !attachment) {
696  return;
697  }
698 
699  Q_ASSERT(!d->mAttachments.contains(attachment));
700 
701  update();
702  d->mAttachments.append(attachment);
703  setFieldDirty(FieldAttachment);
704  updated();
705 }
706 
707 void Incidence::deleteAttachment(const Attachment::Ptr &attachment)
708 {
709  int index = d->mAttachments.indexOf(attachment);
710  if (index > -1) {
711  setFieldDirty(FieldAttachment);
712  d->mAttachments.remove(index);
713  }
714 }
715 
716 void Incidence::deleteAttachments(const QString &mime)
717 {
718  Attachment::List result;
719  Attachment::List::Iterator it = d->mAttachments.begin();
720  while (it != d->mAttachments.end()) {
721  if ((*it)->mimeType() != mime) {
722  result += *it;
723  }
724  ++it;
725  }
726  d->mAttachments = result;
727  setFieldDirty(FieldAttachment);
728 }
729 
730 Attachment::List Incidence::attachments() const
731 {
732  return d->mAttachments;
733 }
734 
735 Attachment::List Incidence::attachments(const QString &mime) const
736 {
737  Attachment::List attachments;
738  foreach(Attachment::Ptr attachment, d->mAttachments) {
739  if (attachment->mimeType() == mime) {
740  attachments.append(attachment);
741  }
742  }
743  return attachments;
744 }
745 
746 void Incidence::clearAttachments()
747 {
748  setFieldDirty(FieldAttachment);
749  d->mAttachments.clear();
750 }
751 
752 QString Incidence::writeAttachmentToTempFile(const Attachment::Ptr &attachment) const
753 {
754  if (d->mTempFiles.contains(attachment)) {
755  return d->mTempFiles.value(attachment);
756  }
757  KTemporaryFile *file = new KTemporaryFile();
758 
759  QStringList patterns = KMimeType::mimeType(attachment->mimeType())->patterns();
760 
761  if (!patterns.empty()) {
762  file->setSuffix(QString(patterns.first()).remove('*'));
763  }
764  file->setAutoRemove(true);
765  file->open();
766  // read-only not to give the idea that it could be written to
767  file->setPermissions(QFile::ReadUser);
768  file->write(QByteArray::fromBase64(attachment->data()));
769  d->mTempFiles.insert(attachment, file->fileName());
770  file->close();
771  return d->mTempFiles.value(attachment);
772 }
773 
774 void Incidence::clearTempFiles()
775 {
776  QHash<Attachment::Ptr,QString>::const_iterator it = d->mTempFiles.constBegin();
777  const QHash<Attachment::Ptr,QString>::const_iterator end = d->mTempFiles.constEnd();
778  for (; it != end; ++it) {
779  QFile::remove(it.value());
780  }
781  d->mTempFiles.clear();
782 }
783 
784 void Incidence::setResources(const QStringList &resources)
785 {
786  if (mReadOnly) {
787  return;
788  }
789 
790  update();
791  d->mResources = resources;
792  setFieldDirty(FieldResources);
793  updated();
794 }
795 
796 QStringList Incidence::resources() const
797 {
798  return d->mResources;
799 }
800 
801 void Incidence::setPriority(int priority)
802 {
803  if (mReadOnly) {
804  return;
805  }
806 
807  update();
808  d->mPriority = priority;
809  setFieldDirty(FieldPriority);
810  updated();
811 }
812 
813 int Incidence::priority() const
814 {
815  return d->mPriority;
816 }
817 
818 void Incidence::setStatus(Incidence::Status status)
819 {
820  if (mReadOnly || status == StatusX) {
821  return;
822  }
823 
824  update();
825  d->mStatus = status;
826  d->mStatusString.clear();
827  setFieldDirty(FieldStatus);
828  updated();
829 }
830 
831 void Incidence::setCustomStatus(const QString &status)
832 {
833  if (mReadOnly) {
834  return;
835  }
836 
837  update();
838  d->mStatus = status.isEmpty() ? StatusNone : StatusX;
839  d->mStatusString = status;
840  setFieldDirty(FieldStatus);
841  updated();
842 }
843 
844 Incidence::Status Incidence::status() const
845 {
846  return d->mStatus;
847 }
848 
849 QString Incidence::customStatus() const
850 {
851  if (d->mStatus == StatusX) {
852  return d->mStatusString;
853  } else {
854  return QString();
855  }
856 }
857 
858 void Incidence::setSecrecy(Incidence::Secrecy secrecy)
859 {
860  if (mReadOnly) {
861  return;
862  }
863 
864  update();
865  d->mSecrecy = secrecy;
866  setFieldDirty(FieldSecrecy);
867  updated();
868 }
869 
870 Incidence::Secrecy Incidence::secrecy() const
871 {
872  return d->mSecrecy;
873 }
874 
875 Alarm::List Incidence::alarms() const
876 {
877  return d->mAlarms;
878 }
879 
880 Alarm::Ptr Incidence::newAlarm()
881 {
882  Alarm::Ptr alarm(new Alarm(this));
883  d->mAlarms.append(alarm);
884  return alarm;
885 }
886 
887 void Incidence::addAlarm(const Alarm::Ptr &alarm)
888 {
889  update();
890  d->mAlarms.append(alarm);
891  setFieldDirty(FieldAlarms);
892  updated();
893 }
894 
895 void Incidence::removeAlarm(const Alarm::Ptr &alarm)
896 {
897  const int index = d->mAlarms.indexOf(alarm);
898  if (index > -1) {
899  update();
900  d->mAlarms.remove(index);
901  setFieldDirty(FieldAlarms);
902  updated();
903  }
904 }
905 
906 void Incidence::clearAlarms()
907 {
908  update();
909  d->mAlarms.clear();
910  setFieldDirty(FieldAlarms);
911  updated();
912 }
913 
914 bool Incidence::hasEnabledAlarms() const
915 {
916  foreach(Alarm::Ptr alarm, d->mAlarms) {
917  if (alarm->enabled()) {
918  return true;
919  }
920  }
921  return false;
922 }
923 
924 void Incidence::setLocation(const QString &location, bool isRich)
925 {
926  if (mReadOnly) {
927  return;
928  }
929 
930  update();
931  d->mLocation = location;
932  d->mLocationIsRich = isRich;
933  setFieldDirty(FieldLocation);
934  updated();
935 }
936 
937 void Incidence::setLocation(const QString &location)
938 {
939  setLocation(location, Qt::mightBeRichText(location));
940 }
941 
942 QString Incidence::location() const
943 {
944  return d->mLocation;
945 }
946 
947 QString Incidence::richLocation() const
948 {
949  if (locationIsRich()) {
950  return d->mLocation;
951  } else {
952  return Qt::escape(d->mLocation).replace('\n', "<br/>");
953  }
954 }
955 
956 bool Incidence::locationIsRich() const
957 {
958  return d->mLocationIsRich;
959 }
960 
961 void Incidence::setSchedulingID(const QString &sid, const QString &uid)
962 {
963  d->mSchedulingID = sid;
964  if (!uid.isEmpty()) {
965  setUid(uid);
966  }
967  setFieldDirty(FieldSchedulingId);
968 }
969 
970 QString Incidence::schedulingID() const
971 {
972  if (d->mSchedulingID.isNull()) {
973  // Nothing set, so use the normal uid
974  return uid();
975  }
976  return d->mSchedulingID;
977 }
978 
979 bool Incidence::hasGeo() const
980 {
981  return d->mHasGeo;
982 }
983 
984 void Incidence::setHasGeo(bool hasGeo)
985 {
986  if (mReadOnly) {
987  return;
988  }
989 
990  if (hasGeo == d->mHasGeo) {
991  return;
992  }
993 
994  update();
995  d->mHasGeo = hasGeo;
996  setFieldDirty(FieldGeoLatitude);
997  setFieldDirty(FieldGeoLongitude);
998  updated();
999 }
1000 
1001 float Incidence::geoLatitude() const
1002 {
1003  return d->mGeoLatitude;
1004 }
1005 
1006 void Incidence::setGeoLatitude(float geolatitude)
1007 {
1008  if (mReadOnly) {
1009  return;
1010  }
1011 
1012  update();
1013  d->mGeoLatitude = geolatitude;
1014  setFieldDirty(FieldGeoLatitude);
1015  updated();
1016 }
1017 
1018 float Incidence::geoLongitude() const
1019 {
1020  return d->mGeoLongitude;
1021 }
1022 
1023 void Incidence::setGeoLongitude(float geolongitude)
1024 {
1025  if (!mReadOnly) {
1026  update();
1027  d->mGeoLongitude = geolongitude;
1028  setFieldDirty(FieldGeoLongitude);
1029  updated();
1030  }
1031 }
1032 
1033 bool Incidence::hasRecurrenceId() const
1034 {
1035  return d->mRecurrenceId.isValid();
1036 }
1037 
1038 KDateTime Incidence::recurrenceId() const
1039 {
1040  return d->mRecurrenceId;
1041 }
1042 
1043 void Incidence::setThisAndFuture(bool thisAndFuture)
1044 {
1045  d->mThisAndFuture = thisAndFuture;
1046 }
1047 
1048 bool Incidence::thisAndFuture() const
1049 {
1050  return d->mThisAndFuture;
1051 }
1052 
1053 void Incidence::setRecurrenceId(const KDateTime &recurrenceId)
1054 {
1055  if (!mReadOnly) {
1056  update();
1057  d->mRecurrenceId = recurrenceId;
1058  setFieldDirty(FieldRecurrenceId);
1059  updated();
1060  }
1061 }
1062 
1066 void Incidence::recurrenceUpdated(Recurrence *recurrence)
1067 {
1068  if (recurrence == d->mRecurrence) {
1069  update();
1070  updated();
1071  }
1072 }
1073 
1074 //@cond PRIVATE
1075 #define ALT_DESC_FIELD "X-ALT-DESC"
1076 #define ALT_DESC_PARAMETERS "FMTTYPE=text/html"
1077 //@endcond
1078 
1079 bool Incidence::hasAltDescription() const
1080 {
1081  const QString value = nonKDECustomProperty(ALT_DESC_FIELD);
1082  const QString parameter = nonKDECustomPropertyParameters(ALT_DESC_FIELD);
1083 
1084  return parameter == ALT_DESC_PARAMETERS && !value.isEmpty();
1085 }
1086 
1087 void Incidence::setAltDescription(const QString &altdescription)
1088 {
1089  if (altdescription.isEmpty()) {
1090  removeNonKDECustomProperty(ALT_DESC_FIELD);
1091  } else {
1092  setNonKDECustomProperty(ALT_DESC_FIELD,
1093  altdescription,
1094  ALT_DESC_PARAMETERS);
1095  }
1096 }
1097 
1098 QString Incidence::altDescription() const
1099 {
1100  if (!hasAltDescription()) {
1101  return QString();
1102  } else {
1103  return nonKDECustomProperty(ALT_DESC_FIELD);
1104  }
1105 }
1106 
1107 bool Incidence::supportsGroupwareCommunication() const
1108 {
1109  return type() == TypeEvent || type() == TypeTodo;
1110 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Fri Jan 17 2014 22:11:59 by doxygen 1.8.3.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCalCore Library

Skip menu "KCalCore Library"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepimlibs-4.11.5 API Reference

Skip menu "kdepimlibs-4.11.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal