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