1 /*
2 This file is part of the kcalcore library.
3
4 SPDX-FileCopyrightText: 1998 Preston Brown <pbrown@kde.org>
5 SPDX-FileCopyrightText: 2001 Cornelius Schumacher <schumacher@kde.org>
6 SPDX-FileCopyrightText: 2003 David Jarvie <djarvie@kde.org>
7
8 SPDX-License-Identifier: LGPL-2.0-or-later
9 */
10 /**
11 @file
12 This file is part of the API for handling calendar data and
13 defines the Alarm class.
14
15 @brief
16 Represents an alarm notification.
17
18 @author Cornelius Schumacher \<schumacher@kde.org\>
19 */
20 #include "alarm.h"
21 #include "incidence.h"
22 #include "utils_p.h"
23
24 #include <QTime>
25 #include <QTimeZone>
26
27 using namespace KCalendarCore;
28
29 /**
30 Private class that helps to provide binary compatibility between releases.
31 @internal
32 */
33 //@cond PRIVATE
34 class Q_DECL_HIDDEN KCalendarCore::Alarm::Private
35 {
36 public:
Private()37 Private()
38 : mParent(nullptr)
39 , mType(Alarm::Invalid)
40 , mAlarmSnoozeTime(5)
41 , mAlarmRepeatCount(0)
42 , mEndOffset(false)
43 , mHasTime(false)
44 , mAlarmEnabled(false)
45 , mHasLocationRadius(false)
46 , mLocationRadius(0)
47 {
48 }
49
50 Incidence *mParent = nullptr; // the incidence which this alarm belongs to
51
52 Type mType; // type of alarm
53 QString mDescription; // text to display/email body/procedure arguments
54 QString mFile; // program to run/optional audio file to play
55 QString mMailSubject; // subject of email
56 QStringList mMailAttachFiles; // filenames to attach to email
57 Person::List mMailAddresses; // who to mail for reminder
58
59 QDateTime mAlarmTime; // time at which to trigger the alarm
60 Duration mAlarmSnoozeTime; // how long after alarm to snooze before
61 // triggering again
62 int mAlarmRepeatCount; // number of times for alarm to repeat
63 // after the initial time
64
65 Duration mOffset; // time relative to incidence DTSTART
66 // to trigger the alarm
67 bool mEndOffset; // if true, mOffset relates to DTEND, not DTSTART
68 bool mHasTime; // use mAlarmTime, not mOffset
69 bool mAlarmEnabled;
70
71 bool mHasLocationRadius;
72 int mLocationRadius; // location radius for the alarm
73 };
74 //@endcond
75
Alarm(Incidence * parent)76 Alarm::Alarm(Incidence *parent)
77 : d(new KCalendarCore::Alarm::Private)
78 {
79 d->mParent = parent;
80 }
81
Alarm(const Alarm & other)82 Alarm::Alarm(const Alarm &other)
83 : CustomProperties(other)
84 , d(new KCalendarCore::Alarm::Private(*other.d))
85 {
86 }
87
~Alarm()88 Alarm::~Alarm()
89 {
90 delete d;
91 }
92
operator =(const Alarm & a)93 Alarm &Alarm::operator=(const Alarm &a)
94 {
95 if (&a != this) {
96 d->mParent = a.d->mParent;
97 d->mType = a.d->mType;
98 d->mDescription = a.d->mDescription;
99 d->mFile = a.d->mFile;
100 d->mMailAttachFiles = a.d->mMailAttachFiles;
101 d->mMailAddresses = a.d->mMailAddresses;
102 d->mMailSubject = a.d->mMailSubject;
103 d->mAlarmSnoozeTime = a.d->mAlarmSnoozeTime;
104 d->mAlarmRepeatCount = a.d->mAlarmRepeatCount;
105 d->mAlarmTime = a.d->mAlarmTime;
106 d->mOffset = a.d->mOffset;
107 d->mEndOffset = a.d->mEndOffset;
108 d->mHasTime = a.d->mHasTime;
109 d->mAlarmEnabled = a.d->mAlarmEnabled;
110 }
111
112 return *this;
113 }
114
compareMailAddresses(const Person::List & list1,const Person::List & list2)115 static bool compareMailAddresses(const Person::List &list1, const Person::List &list2)
116 {
117 if (list1.count() == list2.count()) {
118 for (int i = 0; i < list1.count(); ++i) {
119 if (list1.at(i) != list2.at(i)) {
120 return false;
121 }
122 }
123 return true;
124 }
125
126 return false;
127 }
128
operator ==(const Alarm & rhs) const129 bool Alarm::operator==(const Alarm &rhs) const
130 {
131 if (d->mType != rhs.d->mType //
132 || d->mAlarmSnoozeTime != rhs.d->mAlarmSnoozeTime //
133 || d->mAlarmRepeatCount != rhs.d->mAlarmRepeatCount //
134 || d->mAlarmEnabled != rhs.d->mAlarmEnabled //
135 || d->mHasTime != rhs.d->mHasTime //
136 || d->mHasLocationRadius != rhs.d->mHasLocationRadius //
137 || d->mLocationRadius != rhs.d->mLocationRadius) {
138 return false;
139 }
140
141 if (d->mHasTime) {
142 if (d->mAlarmTime != rhs.d->mAlarmTime) {
143 return false;
144 }
145 } else {
146 if (d->mOffset != rhs.d->mOffset || d->mEndOffset != rhs.d->mEndOffset) {
147 return false;
148 }
149 }
150
151 switch (d->mType) {
152 case Display:
153 return d->mDescription == rhs.d->mDescription;
154
155 case Email:
156 return d->mDescription == rhs.d->mDescription //
157 && d->mMailAttachFiles == rhs.d->mMailAttachFiles //
158 && compareMailAddresses(d->mMailAddresses, rhs.d->mMailAddresses) //
159 && d->mMailSubject == rhs.d->mMailSubject;
160
161 case Procedure:
162 return d->mFile == rhs.d->mFile && d->mDescription == rhs.d->mDescription;
163
164 case Audio:
165 return d->mFile == rhs.d->mFile;
166
167 case Invalid:
168 break;
169 }
170 return false;
171 }
172
operator !=(const Alarm & a) const173 bool Alarm::operator!=(const Alarm &a) const
174 {
175 return !operator==(a);
176 }
177
setType(Alarm::Type type)178 void Alarm::setType(Alarm::Type type)
179 {
180 if (type == d->mType) {
181 return;
182 }
183
184 if (d->mParent) {
185 d->mParent->update();
186 }
187 switch (type) {
188 case Display:
189 d->mDescription.clear();
190 break;
191 case Procedure:
192 d->mFile.clear();
193 d->mDescription.clear();
194 break;
195 case Audio:
196 d->mFile.clear();
197 break;
198 case Email:
199 d->mMailSubject.clear();
200 d->mDescription.clear();
201 d->mMailAddresses.clear();
202 d->mMailAttachFiles.clear();
203 break;
204 case Invalid:
205 break;
206 default:
207 if (d->mParent) {
208 d->mParent->updated(); // not really
209 }
210 return;
211 }
212 d->mType = type;
213 if (d->mParent) {
214 d->mParent->updated();
215 }
216 }
217
type() const218 Alarm::Type Alarm::type() const
219 {
220 return d->mType;
221 }
222
setAudioAlarm(const QString & audioFile)223 void Alarm::setAudioAlarm(const QString &audioFile)
224 {
225 if (d->mParent) {
226 d->mParent->update();
227 }
228 d->mType = Audio;
229 d->mFile = audioFile;
230 if (d->mParent) {
231 d->mParent->updated();
232 }
233 }
234
setAudioFile(const QString & audioFile)235 void Alarm::setAudioFile(const QString &audioFile)
236 {
237 if (d->mType == Audio) {
238 if (d->mParent) {
239 d->mParent->update();
240 }
241 d->mFile = audioFile;
242 if (d->mParent) {
243 d->mParent->updated();
244 }
245 }
246 }
247
audioFile() const248 QString Alarm::audioFile() const
249 {
250 return (d->mType == Audio) ? d->mFile : QString();
251 }
252
setProcedureAlarm(const QString & programFile,const QString & arguments)253 void Alarm::setProcedureAlarm(const QString &programFile, const QString &arguments)
254 {
255 if (d->mParent) {
256 d->mParent->update();
257 }
258 d->mType = Procedure;
259 d->mFile = programFile;
260 d->mDescription = arguments;
261 if (d->mParent) {
262 d->mParent->updated();
263 }
264 }
265
setProgramFile(const QString & programFile)266 void Alarm::setProgramFile(const QString &programFile)
267 {
268 if (d->mType == Procedure) {
269 if (d->mParent) {
270 d->mParent->update();
271 }
272 d->mFile = programFile;
273 if (d->mParent) {
274 d->mParent->updated();
275 }
276 }
277 }
278
programFile() const279 QString Alarm::programFile() const
280 {
281 return (d->mType == Procedure) ? d->mFile : QString();
282 }
283
setProgramArguments(const QString & arguments)284 void Alarm::setProgramArguments(const QString &arguments)
285 {
286 if (d->mType == Procedure) {
287 if (d->mParent) {
288 d->mParent->update();
289 }
290 d->mDescription = arguments;
291 if (d->mParent) {
292 d->mParent->updated();
293 }
294 }
295 }
296
programArguments() const297 QString Alarm::programArguments() const
298 {
299 return (d->mType == Procedure) ? d->mDescription : QString();
300 }
301
setEmailAlarm(const QString & subject,const QString & text,const Person::List & addressees,const QStringList & attachments)302 void Alarm::setEmailAlarm(const QString &subject, const QString &text, const Person::List &addressees, const QStringList &attachments)
303 {
304 if (d->mParent) {
305 d->mParent->update();
306 }
307 d->mType = Email;
308 d->mMailSubject = subject;
309 d->mDescription = text;
310 d->mMailAddresses = addressees;
311 d->mMailAttachFiles = attachments;
312 if (d->mParent) {
313 d->mParent->updated();
314 }
315 }
316
setMailAddress(const Person & mailAddress)317 void Alarm::setMailAddress(const Person &mailAddress)
318 {
319 if (d->mType == Email) {
320 if (d->mParent) {
321 d->mParent->update();
322 }
323 d->mMailAddresses.clear();
324 d->mMailAddresses.append(mailAddress);
325 if (d->mParent) {
326 d->mParent->updated();
327 }
328 }
329 }
330
setMailAddresses(const Person::List & mailAddresses)331 void Alarm::setMailAddresses(const Person::List &mailAddresses)
332 {
333 if (d->mType == Email) {
334 if (d->mParent) {
335 d->mParent->update();
336 }
337 d->mMailAddresses += mailAddresses;
338 if (d->mParent) {
339 d->mParent->updated();
340 }
341 }
342 }
343
addMailAddress(const Person & mailAddress)344 void Alarm::addMailAddress(const Person &mailAddress)
345 {
346 if (d->mType == Email) {
347 if (d->mParent) {
348 d->mParent->update();
349 }
350 d->mMailAddresses.append(mailAddress);
351 if (d->mParent) {
352 d->mParent->updated();
353 }
354 }
355 }
356
mailAddresses() const357 Person::List Alarm::mailAddresses() const
358 {
359 return (d->mType == Email) ? d->mMailAddresses : Person::List();
360 }
361
setMailSubject(const QString & mailAlarmSubject)362 void Alarm::setMailSubject(const QString &mailAlarmSubject)
363 {
364 if (d->mType == Email) {
365 if (d->mParent) {
366 d->mParent->update();
367 }
368 d->mMailSubject = mailAlarmSubject;
369 if (d->mParent) {
370 d->mParent->updated();
371 }
372 }
373 }
374
mailSubject() const375 QString Alarm::mailSubject() const
376 {
377 return (d->mType == Email) ? d->mMailSubject : QString();
378 }
379
setMailAttachment(const QString & mailAttachFile)380 void Alarm::setMailAttachment(const QString &mailAttachFile)
381 {
382 if (d->mType == Email) {
383 if (d->mParent) {
384 d->mParent->update();
385 }
386 d->mMailAttachFiles.clear();
387 d->mMailAttachFiles += mailAttachFile;
388 if (d->mParent) {
389 d->mParent->updated();
390 }
391 }
392 }
393
setMailAttachments(const QStringList & mailAttachFiles)394 void Alarm::setMailAttachments(const QStringList &mailAttachFiles)
395 {
396 if (d->mType == Email) {
397 if (d->mParent) {
398 d->mParent->update();
399 }
400 d->mMailAttachFiles = mailAttachFiles;
401 if (d->mParent) {
402 d->mParent->updated();
403 }
404 }
405 }
406
addMailAttachment(const QString & mailAttachFile)407 void Alarm::addMailAttachment(const QString &mailAttachFile)
408 {
409 if (d->mType == Email) {
410 if (d->mParent) {
411 d->mParent->update();
412 }
413 d->mMailAttachFiles += mailAttachFile;
414 if (d->mParent) {
415 d->mParent->updated();
416 }
417 }
418 }
419
mailAttachments() const420 QStringList Alarm::mailAttachments() const
421 {
422 return (d->mType == Email) ? d->mMailAttachFiles : QStringList();
423 }
424
setMailText(const QString & text)425 void Alarm::setMailText(const QString &text)
426 {
427 if (d->mType == Email) {
428 if (d->mParent) {
429 d->mParent->update();
430 }
431 d->mDescription = text;
432 if (d->mParent) {
433 d->mParent->updated();
434 }
435 }
436 }
437
mailText() const438 QString Alarm::mailText() const
439 {
440 return (d->mType == Email) ? d->mDescription : QString();
441 }
442
setDisplayAlarm(const QString & text)443 void Alarm::setDisplayAlarm(const QString &text)
444 {
445 if (d->mParent) {
446 d->mParent->update();
447 }
448 d->mType = Display;
449 if (!text.isNull()) {
450 d->mDescription = text;
451 }
452 if (d->mParent) {
453 d->mParent->updated();
454 }
455 }
456
setText(const QString & text)457 void Alarm::setText(const QString &text)
458 {
459 if (d->mType == Display) {
460 if (d->mParent) {
461 d->mParent->update();
462 }
463 d->mDescription = text;
464 if (d->mParent) {
465 d->mParent->updated();
466 }
467 }
468 }
469
text() const470 QString Alarm::text() const
471 {
472 return (d->mType == Display) ? d->mDescription : QString();
473 }
474
setTime(const QDateTime & alarmTime)475 void Alarm::setTime(const QDateTime &alarmTime)
476 {
477 if (d->mParent) {
478 d->mParent->update();
479 }
480 d->mAlarmTime = alarmTime;
481 d->mHasTime = true;
482
483 if (d->mParent) {
484 d->mParent->updated();
485 }
486 }
487
time() const488 QDateTime Alarm::time() const
489 {
490 if (hasTime()) {
491 return d->mAlarmTime;
492 } else if (d->mParent) {
493 if (d->mEndOffset) {
494 QDateTime dt = d->mParent->dateTime(Incidence::RoleAlarmEndOffset);
495 return d->mOffset.end(dt);
496 } else {
497 QDateTime dt = d->mParent->dateTime(Incidence::RoleAlarmStartOffset);
498 return d->mOffset.end(dt);
499 }
500 } else {
501 return QDateTime();
502 }
503 }
504
nextTime(const QDateTime & preTime,bool ignoreRepetitions) const505 QDateTime Alarm::nextTime(const QDateTime &preTime, bool ignoreRepetitions) const
506 {
507 if (d->mParent && d->mParent->recurs()) {
508 QDateTime dtEnd = d->mParent->dateTime(Incidence::RoleAlarmEndOffset);
509
510 QDateTime dtStart = d->mParent->dtStart();
511 // Find the incidence's earliest alarm
512 // Alarm time is defined by an offset from the event start or end time.
513 QDateTime alarmStart = d->mOffset.end(d->mEndOffset ? dtEnd : dtStart);
514 // Find the offset from the event start time, which is also used as the
515 // offset from the recurrence time.
516 Duration alarmOffset(dtStart, alarmStart);
517 /*
518 qCDebug(KCALCORE_LOG) << "dtStart " << dtStart;
519 qCDebug(KCALCORE_LOG) << "dtEnd " << dtEnd;
520 qCDebug(KCALCORE_LOG) << "alarmStart " << alarmStart;
521 qCDebug(KCALCORE_LOG) << "alarmOffset " << alarmOffset.value();
522 qCDebug(KCALCORE_LOG) << "preTime " << preTime;
523 */
524 if (alarmStart > preTime) {
525 // No need to go further.
526 return alarmStart;
527 }
528 if (d->mAlarmRepeatCount && !ignoreRepetitions) {
529 // The alarm has repetitions, so check whether repetitions of previous
530 // recurrences happen after given time.
531 QDateTime prevRecurrence = d->mParent->recurrence()->getPreviousDateTime(preTime);
532 if (prevRecurrence.isValid()) {
533 QDateTime prevLastRepeat = alarmOffset.end(duration().end(prevRecurrence));
534 // qCDebug(KCALCORE_LOG) << "prevRecurrence" << prevRecurrence;
535 // qCDebug(KCALCORE_LOG) << "prevLastRepeat" << prevLastRepeat;
536 if (prevLastRepeat > preTime) {
537 // Yes they did, return alarm offset to previous recurrence.
538 QDateTime prevAlarm = alarmOffset.end(prevRecurrence);
539 // qCDebug(KCALCORE_LOG) << "prevAlarm " << prevAlarm;
540 return prevAlarm;
541 }
542 }
543 }
544 // Check the next recurrence now.
545 QDateTime nextRecurrence = d->mParent->recurrence()->getNextDateTime(preTime);
546 if (nextRecurrence.isValid()) {
547 QDateTime nextAlarm = alarmOffset.end(nextRecurrence);
548 /*
549 qCDebug(KCALCORE_LOG) << "nextRecurrence" << nextRecurrence;
550 qCDebug(KCALCORE_LOG) << "nextAlarm " << nextAlarm;
551 */
552 if (nextAlarm > preTime) {
553 // It's first alarm takes place after given time.
554 return nextAlarm;
555 }
556 }
557 } else {
558 // Not recurring.
559 QDateTime alarmTime = time();
560 if (alarmTime > preTime) {
561 return alarmTime;
562 }
563 }
564 return QDateTime();
565 }
566
hasTime() const567 bool Alarm::hasTime() const
568 {
569 return d->mHasTime;
570 }
571
shiftTimes(const QTimeZone & oldZone,const QTimeZone & newZone)572 void Alarm::shiftTimes(const QTimeZone &oldZone, const QTimeZone &newZone)
573 {
574 if (d->mParent) {
575 d->mParent->update();
576 }
577 d->mAlarmTime = d->mAlarmTime.toTimeZone(oldZone);
578 d->mAlarmTime.setTimeZone(newZone);
579 if (d->mParent) {
580 d->mParent->updated();
581 }
582 }
583
setSnoozeTime(const Duration & alarmSnoozeTime)584 void Alarm::setSnoozeTime(const Duration &alarmSnoozeTime)
585 {
586 if (alarmSnoozeTime.value() > 0) {
587 if (d->mParent) {
588 d->mParent->update();
589 }
590 d->mAlarmSnoozeTime = alarmSnoozeTime;
591 if (d->mParent) {
592 d->mParent->updated();
593 }
594 }
595 }
596
snoozeTime() const597 Duration Alarm::snoozeTime() const
598 {
599 return d->mAlarmSnoozeTime;
600 }
601
setRepeatCount(int alarmRepeatCount)602 void Alarm::setRepeatCount(int alarmRepeatCount)
603 {
604 if (d->mParent) {
605 d->mParent->update();
606 }
607 d->mAlarmRepeatCount = alarmRepeatCount;
608 if (d->mParent) {
609 d->mParent->updated();
610 }
611 }
612
repeatCount() const613 int Alarm::repeatCount() const
614 {
615 return d->mAlarmRepeatCount;
616 }
617
duration() const618 Duration Alarm::duration() const
619 {
620 return Duration(d->mAlarmSnoozeTime.value() * d->mAlarmRepeatCount, d->mAlarmSnoozeTime.type());
621 }
622
nextRepetition(const QDateTime & preTime) const623 QDateTime Alarm::nextRepetition(const QDateTime &preTime) const
624 {
625 QDateTime at = nextTime(preTime);
626 if (at > preTime) {
627 return at;
628 }
629 if (!d->mAlarmRepeatCount) {
630 // there isn't an occurrence after the specified time
631 return QDateTime();
632 }
633 qint64 repetition;
634 int interval = d->mAlarmSnoozeTime.value();
635 bool daily = d->mAlarmSnoozeTime.isDaily();
636 if (daily) {
637 qint64 daysTo = at.daysTo(preTime);
638 if (preTime.time() <= at.time()) {
639 --daysTo;
640 }
641 repetition = daysTo / interval + 1;
642 } else {
643 repetition = at.secsTo(preTime) / interval + 1;
644 }
645 if (repetition > d->mAlarmRepeatCount) {
646 // all repetitions have finished before the specified time
647 return QDateTime();
648 }
649 return daily ? at.addDays(int(repetition * interval)) : at.addSecs(repetition * interval);
650 }
651
previousRepetition(const QDateTime & afterTime) const652 QDateTime Alarm::previousRepetition(const QDateTime &afterTime) const
653 {
654 QDateTime at = time();
655 if (at >= afterTime) {
656 // alarm's first/only time is at/after the specified time
657 return QDateTime();
658 }
659 if (!d->mAlarmRepeatCount) {
660 return at;
661 }
662 qint64 repetition;
663 int interval = d->mAlarmSnoozeTime.value();
664 bool daily = d->mAlarmSnoozeTime.isDaily();
665 if (daily) {
666 qint64 daysTo = at.daysTo(afterTime);
667 if (afterTime.time() <= at.time()) {
668 --daysTo;
669 }
670 repetition = daysTo / interval;
671 } else {
672 repetition = (at.secsTo(afterTime) - 1) / interval;
673 }
674 if (repetition > d->mAlarmRepeatCount) {
675 repetition = d->mAlarmRepeatCount;
676 }
677 return daily ? at.addDays(int(repetition * interval)) : at.addSecs(repetition * interval);
678 }
679
endTime() const680 QDateTime Alarm::endTime() const
681 {
682 if (!d->mAlarmRepeatCount) {
683 return time();
684 }
685 if (d->mAlarmSnoozeTime.isDaily()) {
686 return time().addDays(d->mAlarmRepeatCount * d->mAlarmSnoozeTime.asDays());
687 } else {
688 return time().addSecs(d->mAlarmRepeatCount * d->mAlarmSnoozeTime.asSeconds());
689 }
690 }
691
toggleAlarm()692 void Alarm::toggleAlarm()
693 {
694 if (d->mParent) {
695 d->mParent->update();
696 }
697 d->mAlarmEnabled = !d->mAlarmEnabled;
698 if (d->mParent) {
699 d->mParent->updated();
700 }
701 }
702
setEnabled(bool enable)703 void Alarm::setEnabled(bool enable)
704 {
705 if (d->mParent) {
706 d->mParent->update();
707 }
708 d->mAlarmEnabled = enable;
709 if (d->mParent) {
710 d->mParent->updated();
711 }
712 }
713
enabled() const714 bool Alarm::enabled() const
715 {
716 return d->mAlarmEnabled;
717 }
718
setStartOffset(const Duration & offset)719 void Alarm::setStartOffset(const Duration &offset)
720 {
721 if (d->mParent) {
722 d->mParent->update();
723 }
724 d->mOffset = offset;
725 d->mEndOffset = false;
726 d->mHasTime = false;
727 if (d->mParent) {
728 d->mParent->updated();
729 }
730 }
731
startOffset() const732 Duration Alarm::startOffset() const
733 {
734 return (d->mHasTime || d->mEndOffset) ? Duration(0) : d->mOffset;
735 }
736
hasStartOffset() const737 bool Alarm::hasStartOffset() const
738 {
739 return !d->mHasTime && !d->mEndOffset;
740 }
741
hasEndOffset() const742 bool Alarm::hasEndOffset() const
743 {
744 return !d->mHasTime && d->mEndOffset;
745 }
746
setEndOffset(const Duration & offset)747 void Alarm::setEndOffset(const Duration &offset)
748 {
749 if (d->mParent) {
750 d->mParent->update();
751 }
752 d->mOffset = offset;
753 d->mEndOffset = true;
754 d->mHasTime = false;
755 if (d->mParent) {
756 d->mParent->updated();
757 }
758 }
759
endOffset() const760 Duration Alarm::endOffset() const
761 {
762 return (d->mHasTime || !d->mEndOffset) ? Duration(0) : d->mOffset;
763 }
764
setParent(Incidence * parent)765 void Alarm::setParent(Incidence *parent)
766 {
767 d->mParent = parent;
768 }
769
parentUid() const770 QString Alarm::parentUid() const
771 {
772 return d->mParent ? d->mParent->uid() : QString();
773 }
774
customPropertyUpdated()775 void Alarm::customPropertyUpdated()
776 {
777 if (d->mParent) {
778 d->mParent->update();
779 d->mParent->updated();
780 }
781 }
782
setHasLocationRadius(bool hasLocationRadius)783 void Alarm::setHasLocationRadius(bool hasLocationRadius)
784 {
785 if (d->mParent) {
786 d->mParent->update();
787 }
788 d->mHasLocationRadius = hasLocationRadius;
789 if (hasLocationRadius) {
790 setNonKDECustomProperty("X-LOCATION-RADIUS", QString::number(d->mLocationRadius));
791 } else {
792 removeNonKDECustomProperty("X-LOCATION-RADIUS");
793 }
794 if (d->mParent) {
795 d->mParent->updated();
796 }
797 }
798
hasLocationRadius() const799 bool Alarm::hasLocationRadius() const
800 {
801 return d->mHasLocationRadius;
802 }
803
setLocationRadius(int locationRadius)804 void Alarm::setLocationRadius(int locationRadius)
805 {
806 if (d->mParent) {
807 d->mParent->update();
808 }
809 d->mLocationRadius = locationRadius;
810 if (d->mParent) {
811 d->mParent->updated();
812 }
813 }
814
locationRadius() const815 int Alarm::locationRadius() const
816 {
817 return d->mLocationRadius;
818 }
819
operator <<(QDataStream & out,const KCalendarCore::Alarm::Ptr & a)820 QDataStream &KCalendarCore::operator<<(QDataStream &out, const KCalendarCore::Alarm::Ptr &a)
821 {
822 if (a) {
823 out << ((quint32)a->d->mType) << a->d->mAlarmSnoozeTime << a->d->mAlarmRepeatCount << a->d->mEndOffset << a->d->mHasTime << a->d->mAlarmEnabled
824 << a->d->mHasLocationRadius << a->d->mLocationRadius << a->d->mOffset;
825
826 serializeQDateTimeAsKDateTime(out, a->d->mAlarmTime);
827
828 out << a->d->mFile << a->d->mMailSubject << a->d->mDescription << a->d->mMailAttachFiles << a->d->mMailAddresses;
829 }
830 return out;
831 }
832
operator >>(QDataStream & in,const KCalendarCore::Alarm::Ptr & a)833 QDataStream &KCalendarCore::operator>>(QDataStream &in, const KCalendarCore::Alarm::Ptr &a)
834 {
835 if (a) {
836 quint32 type;
837 in >> type;
838 a->d->mType = static_cast<Alarm::Type>(type);
839 in >> a->d->mAlarmSnoozeTime >> a->d->mAlarmRepeatCount >> a->d->mEndOffset >> a->d->mHasTime >> a->d->mAlarmEnabled >> a->d->mHasLocationRadius
840 >> a->d->mLocationRadius >> a->d->mOffset;
841 deserializeKDateTimeAsQDateTime(in, a->d->mAlarmTime);
842 in >> a->d->mFile >> a->d->mMailSubject >> a->d->mDescription >> a->d->mMailAttachFiles >> a->d->mMailAddresses;
843 }
844 return in;
845 }
846
virtual_hook(int id,void * data)847 void Alarm::virtual_hook(int id, void *data)
848 {
849 Q_UNUSED(id);
850 Q_UNUSED(data);
851 Q_ASSERT(false);
852 }
853