1 /*
2   This file is part of the kcalcore library.
3 
4   SPDX-FileCopyrightText: 2001-2003 Cornelius Schumacher <schumacher@kde.org>
5   SPDX-FileCopyrightText: 2003 David Jarvie <djarvie@kde.org>
6   SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
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   @author Cornelius Schumacher \<schumacher@kde.org\>
16 */
17 
18 #ifndef KCALCORE_ALARM_H
19 #define KCALCORE_ALARM_H
20 
21 #include "customproperties.h"
22 #include "duration.h"
23 #include "kcalendarcore_export.h"
24 #include "person.h"
25 
26 #include <QDataStream>
27 #include <QDateTime>
28 #include <QMetaType>
29 #include <QSharedPointer>
30 #include <QString>
31 #include <QStringList>
32 #include <QVector>
33 
34 class QTimeZone;
35 
36 namespace KCalendarCore
37 {
38 class Incidence;
39 
40 /**
41   @brief
42   Represents an alarm notification.
43 
44   Alarms are user notifications that occur at specified times.
45   Notifications can be on-screen pop-up dialogs, email messages,
46   the playing of audio files, or the running of another program.
47 
48   Alarms always belong to a parent Incidence.
49 */
50 class KCALENDARCORE_EXPORT Alarm : public CustomProperties
51 {
52 public:
53     /**
54       The different types of alarms.
55     */
56     enum Type {
57         Invalid, /**< Invalid, or no alarm */
58         Display, /**< Display a dialog box */
59         Procedure, /**< Call a script */
60         Email, /**< Send email */
61         Audio, /**< Play an audio file */
62     };
63 
64     /**
65       A shared pointer to an Alarm object.
66     */
67     typedef QSharedPointer<Alarm> Ptr;
68 
69     /**
70       List of alarms.
71     */
72     typedef QVector<Ptr> List;
73 
74     /**
75       Constructs an alarm belonging to the @p parent Incidence.
76 
77       @param parent is the Incidence this alarm will belong to.
78     */
79     // Can't find a way to use a shared pointer here.
80     // Inside incidence.cpp, it does alarm->setParent( this )
81     explicit Alarm(Incidence *parent);
82 
83     /**
84       Copy constructor.
85       @param other is the alarm to copy.
86     */
87     Alarm(const Alarm &other);
88 
89     /**
90       Destroys the alarm.
91     */
92     ~Alarm() override;
93 
94     /**
95       Copy operator.
96     */
97     Alarm &operator=(const Alarm &);
98 
99     /**
100       Compares two alarms for equality.
101       @param a is the comparison alarm.
102     */
103     bool operator==(const Alarm &a) const;
104 
105     /**
106       Compares two alarms for inequality.
107 
108       @param a is the comparison alarm.
109     */
110     bool operator!=(const Alarm &a) const;
111 
112     /**
113       Sets the @p parent Incidence of the alarm.
114 
115       @param parent is alarm parent Incidence to set.
116 
117       @see parentUid()
118     */
119     // Is there a way to use QSharedPointer here?
120     // although it's safe, Incidence's dtor calls setParent( 0 )
121     // se we don't dereference a deleted pointer here.
122     // Also, I renamed "Incidence *parent()" to "QString parentUid()"
123     // So we don't return raw pointers
124     void setParent(Incidence *parent);
125 
126     /**
127       Returns the parent's incidence UID of the alarm.
128 
129       @see setParent()
130     */
131     // We don't have a share pointer to return, so return the UID.
132     Q_REQUIRED_RESULT QString parentUid() const;
133 
134     /**
135       Sets the #Type for this alarm to @p type.
136       If the specified type is different from the current type of the alarm,
137       then the alarm's type-specific properties are re-initialized.
138 
139       @param type is the alarm #Type to set.
140 
141       @see type()
142     */
143     void setType(Type type);
144 
145     /**
146       Returns the #Type of the alarm.
147 
148       @see setType()
149     */
150     Q_REQUIRED_RESULT Type type() const;
151 
152     /**
153       Sets the #Display type for this alarm.
154       If @p text is specified non-empty, then it is used as the description
155       text to display when the alarm is triggered.
156 
157       @param text is the description to display when the alarm is triggered.
158 
159       @see setText(), text()
160     */
161     void setDisplayAlarm(const QString &text = QString());
162 
163     /**
164       Sets the description @p text to be displayed when the alarm is triggered.
165       Ignored if the alarm is not a display alarm.
166 
167       @param text is the description to display when the alarm is triggered.
168 
169       @see setDisplayAlarm(), text()
170     */
171     void setText(const QString &text);
172 
173     /**
174       Returns the display text string for a #Display alarm type.
175       Returns an empty string if the alarm is not a #Display type.
176 
177       @see setDisplayAlarm(), setText()
178     */
179     Q_REQUIRED_RESULT QString text() const;
180 
181     /**
182       Sets the #Audio type for this alarm and the name of the audio file
183       to play when the alarm is triggered.
184 
185       @param audioFile is the name of the audio file to play when the alarm
186       is triggered.
187 
188       @see setAudioFile(), audioFile()
189     */
190     void setAudioAlarm(const QString &audioFile = QString());
191 
192     /**
193       Sets the name of the audio file to play when the audio alarm is triggered.
194       Ignored if the alarm is not an #Audio type.
195 
196       @param audioFile is the name of the audio file to play when the alarm
197       is triggered.
198 
199       @see setAudioAlarm(), audioFile()
200     */
201     void setAudioFile(const QString &audioFile);
202 
203     /**
204       Returns the audio file name for an #Audio alarm type.
205       Returns an empty string if the alarm is not an #Audio type.
206 
207       @see setAudioAlarm(), setAudioFile()
208     */
209     Q_REQUIRED_RESULT QString audioFile() const;
210 
211     /**
212       Sets the #Procedure type for this alarm and the program (with arguments)
213       to execute when the alarm is triggered.
214 
215       @param programFile is the name of the program file to execute when
216       the alarm is triggered.
217       @param arguments is a string of arguments to supply to @p programFile.
218 
219       @see setProgramFile(), programFile(),
220       setProgramArguments(), programArguments()
221     */
222     void setProcedureAlarm(const QString &programFile, const QString &arguments = QString());
223 
224     /**
225       Sets the program file to execute when the alarm is triggered.
226       Ignored if the alarm is not a #Procedure type.
227 
228       @param programFile is the name of the program file to execute when
229       the alarm is triggered.
230 
231       @see setProcedureAlarm(), programFile(),
232       setProgramArguments(), programArguments()
233     */
234     void setProgramFile(const QString &programFile);
235 
236     /**
237       Returns the program file name for a #Procedure alarm type.
238       Returns an empty string if the alarm is not a #Procedure type.
239 
240       @see setProcedureAlarm(), setProgramFile(),
241       setProgramArguments(), programArguments()
242     */
243     Q_REQUIRED_RESULT QString programFile() const;
244 
245     /**
246       Sets the program arguments string when the alarm is triggered.
247       Ignored if the alarm is not a #Procedure type.
248 
249       @param arguments is a string of arguments to supply to the program.
250 
251       @see setProcedureAlarm(), setProgramFile(), programFile(),
252       programArguments()
253     */
254     void setProgramArguments(const QString &arguments);
255 
256     /**
257       Returns the program arguments string for a #Procedure alarm type.
258       Returns an empty string if the alarm is not a #Procedure type.
259 
260       @see setProcedureAlarm(), setProgramFile(), programFile(),
261       setProgramArguments()
262     */
263     Q_REQUIRED_RESULT QString programArguments() const;
264 
265     /**
266       Sets the #Email type for this alarm and the email @p subject, @p text,
267       @p addresses, and @p attachments that make up an email message to be
268       sent when the alarm is triggered.
269 
270       @param subject is the email subject.
271       @param text is a string containing the body of the email message.
272       @param addressees is Person list of email addresses.
273       @param attachments is a a QStringList of optional file names
274       of email attachments.
275 
276       @see setMailSubject(), setMailText(), setMailAddresses(),
277       setMailAttachments()
278     */
279     void setEmailAlarm(const QString &subject, const QString &text, const Person::List &addressees, const QStringList &attachments = QStringList());
280 
281     /**
282       Sets the email address of an #Email type alarm.
283       Ignored if the alarm is not an #Email type.
284 
285       @param mailAlarmAddress is a Person to receive a mail message when
286       an #Email type alarm is triggered.
287 
288       @see setMailSubject(), setMailText(), setMailAddresses(),
289       setMailAttachment(), setMailAttachments(), mailAddresses()
290     */
291     void setMailAddress(const Person &mailAlarmAddress);
292 
293     /**
294       Sets a list of email addresses of an #Email type alarm.
295       Ignored if the alarm is not an #Email type.
296 
297       @param mailAlarmAddresses is a Person list to receive a mail message
298       when an #Email type alarm is triggered.
299 
300       @see setMailSubject(), setMailText(), setMailAddress(),
301       setMailAttachments(), setMailAttachment(), mailAddresses()
302     */
303     void setMailAddresses(const Person::List &mailAlarmAddresses);
304 
305     /**
306       Adds an address to the list of email addresses to send mail to when the
307       alarm is triggered.
308       Ignored if the alarm is not an #Email type.
309 
310       @param mailAlarmAddress is a Person to add to the list of addresses to
311       receive a mail message when an #Email type alarm is triggered.
312 
313       @see setMailAddress(), setMailAddresses(), mailAddresses()
314     */
315     void addMailAddress(const Person &mailAlarmAddress);
316 
317     /**
318       Returns the list of addresses for an #Email alarm type.
319       Returns an empty list if the alarm is not an #Email type.
320 
321       @see addMailAddress(), setMailAddress(), setMailAddresses()
322     */
323     Q_REQUIRED_RESULT Person::List mailAddresses() const;
324 
325     /**
326       Sets the subject line of a mail message for an #Email alarm type.
327       Ignored if the alarm is not an #Email type.
328 
329       @param mailAlarmSubject is a string to be used as a subject line
330       of an email message to send when the #Email type alarm is triggered.
331 
332       @see setMailText(), setMailAddress(), setMailAddresses(),
333       setMailAttachment(), setMailAttachments(), mailSubject()
334     */
335     void setMailSubject(const QString &mailAlarmSubject);
336 
337     /**
338       Returns the subject line string for an #Email alarm type.
339       Returns an empty string if the alarm is not an #Email type.
340 
341       @see setMailSubject()
342     */
343     Q_REQUIRED_RESULT QString mailSubject() const;
344 
345     /**
346       Sets the filename to attach to a mail message for an #Email alarm type.
347       Ignored if the alarm is not an #Email type.
348 
349       @param mailAttachFile is a string containing a filename to be attached
350       to an email message to send when the #Email type alarm is triggered.
351 
352       @see setMailSubject(), setMailText(), setMailAddress(),
353       setMailAddresses(), setMailAttachments(), mailAttachments()
354     */
355     void setMailAttachment(const QString &mailAttachFile);
356 
357     /**
358       Sets a list of filenames to attach to a mail message for an #Email
359       alarm type. Ignored if the alarm is not an #Email type.
360 
361       @param mailAttachFiles is a QString list of filenames to attach to
362       a mail message when an #Email type alarm is triggered.
363 
364       @see setMailSubject(), setMailText(), setMailAttachment(),
365       setMailAddress(), setMailAddresses()
366     */
367     void setMailAttachments(const QStringList &mailAttachFiles);
368 
369     /**
370       Adds a filename to the list of files to attach to a mail message for
371       an #Email alarm type. Ignored if the alarm is not an #Email type.
372 
373       @param mailAttachFile is a string containing a filename to be attached
374       to an email message to send when the #Email type alarm is triggered.
375 
376       @see setMailAttachment(), setMailAttachments(), mailAttachments()
377     */
378     void addMailAttachment(const QString &mailAttachFile);
379 
380     /**
381       Returns the list of attachment filenames for an #Email alarm type.
382       Returns an empty list if the alarm is not an #Email type.
383 
384       @see addMailAttachment(), setMailAttachment(), setMailAttachments()
385     */
386     Q_REQUIRED_RESULT QStringList mailAttachments() const;
387 
388     /**
389       Sets the body text for an #Email alarm type.
390       Ignored if the alarm is not an #Email type.
391 
392       @param text is a string containing the body text of a mail message
393       when an #Email type alarm is triggered.
394 
395       @see setMailSubject(), setMailAddress(), setMailAddresses(),
396       setMailAttachment(), setMailAttachments()
397     */
398     void setMailText(const QString &text);
399 
400     /**
401       Returns the body text for an #Email alarm type.
402       Returns an empty string if the alarm is not an #Email type.
403 
404       @see setMailText()
405     */
406     Q_REQUIRED_RESULT QString mailText() const;
407 
408     /**
409       Sets the trigger time of the alarm.
410 
411       @param alarmTime is the QDateTime alarm trigger.
412 
413       @see time()
414     */
415     void setTime(const QDateTime &alarmTime);
416 
417     /**
418       Returns the alarm trigger date/time.
419 
420       @see setTime()
421     */
422     Q_REQUIRED_RESULT QDateTime time() const;
423 
424     /**
425       Returns the next alarm trigger date/time after given date/time.
426       Takes recurrent incidences into account.
427 
428       @param preTime date/time from where to start
429       @param ignoreRepetitions don't take repetitions into account
430       @see nextRepetition()
431     */
432     Q_REQUIRED_RESULT QDateTime nextTime(const QDateTime &preTime, bool ignoreRepetitions = false) const;
433 
434     /**
435       Returns the date/time when the last repetition of the alarm goes off.
436       If the alarm does not repeat this is equivalent to calling time().
437 
438       @see setTime()
439     */
440     Q_REQUIRED_RESULT QDateTime endTime() const;
441 
442     /**
443       Returns true if the alarm has a trigger date/time.
444     */
445     Q_REQUIRED_RESULT bool hasTime() const;
446 
447     /**
448       Sets the alarm offset relative to the start of the parent Incidence.
449 
450       @param offset is a Duration to be used as a time relative to the
451       start of the parent Incidence to be used as the alarm trigger.
452 
453       @see setEndOffset(), startOffset(), endOffset()
454     */
455     void setStartOffset(const Duration &offset);
456 
457     /**
458       Returns offset of alarm in time relative to the start of the parent
459       Incidence.  If the alarm's time is not defined in terms of an offset
460       relative  to the start of the event, returns zero.
461 
462       @see setStartOffset(), hasStartOffset()
463     */
464     Q_REQUIRED_RESULT Duration startOffset() const;
465 
466     /**
467       Returns whether the alarm is defined in terms of an offset relative
468       to the start of the parent Incidence.
469 
470       @see startOffset(), setStartOffset()
471     */
472     bool hasStartOffset() const;
473 
474     /**
475       Sets the alarm offset relative to the end of the parent Incidence.
476 
477       @param offset is a Duration to be used as a time relative to the
478       end of the parent Incidence to be used as the alarm trigger.
479 
480       @see setStartOffset(), startOffset(), endOffset()
481     */
482     void setEndOffset(const Duration &offset);
483 
484     /**
485       Returns offset of alarm in time relative to the end of the event.
486       If the alarm's time is not defined in terms of an offset relative
487       to the end of the event, returns zero.
488 
489       @see setEndOffset(), hasEndOffset()
490     */
491     Q_REQUIRED_RESULT Duration endOffset() const;
492 
493     /**
494       Returns whether the alarm is defined in terms of an offset relative
495       to the end of the event.
496 
497       @see endOffset(), setEndOffset()
498     */
499     bool hasEndOffset() const;
500 
501     /**
502       Shift the times of the alarm so that they appear at the same clock
503       time as before but in a new time zone. The shift is done from a viewing
504       time zone rather than from the actual alarm time zone.
505 
506       For example, shifting an alarm whose start time is 09:00 America/New York,
507       using an old viewing time zone (@p oldZone) of Europe/London, to a new
508       time zone (@p newZone) of Europe/Paris, will result in the time being
509       shifted from 14:00 (which is the London time of the alarm start) to
510       14:00 Paris time.
511 
512       @param oldZone the time zone which provides the clock times
513       @param newZone the new time zone
514     */
515     void shiftTimes(const QTimeZone &oldZone, const QTimeZone &newZone);
516 
517     /**
518       Sets the snooze time interval for the alarm.
519 
520       @param alarmSnoozeTime the time between snoozes.
521 
522       @see snoozeTime()
523     */
524     void setSnoozeTime(const Duration &alarmSnoozeTime);
525 
526     /**
527       Returns the snooze time interval.
528 
529       @see setSnoozeTime()
530     */
531     Q_REQUIRED_RESULT Duration snoozeTime() const;
532 
533     /**
534       Sets how many times an alarm is to repeat itself after its initial
535       occurrence (w/snoozes).
536 
537       @param alarmRepeatCount is the number of times an alarm may repeat,
538       excluding the initial occurrence.
539 
540       @see repeatCount()
541     */
542     void setRepeatCount(int alarmRepeatCount);
543 
544     /**
545       Returns how many times an alarm may repeats after its initial occurrence.
546 
547       @see setRepeatCount()
548     */
549     Q_REQUIRED_RESULT int repeatCount() const;
550 
551     /**
552       Returns the date/time of the alarm's initial occurrence or its next
553       repetition after a given time.
554 
555       @param preTime the date/time after which to find the next repetition.
556 
557       @return the date/time of the next repetition, or an invalid date/time
558       if the specified time is at or after the alarm's last repetition.
559 
560       @see previousRepetition()
561     */
562     Q_REQUIRED_RESULT QDateTime nextRepetition(const QDateTime &preTime) const;
563 
564     /**
565       Returns the date/time of the alarm's latest repetition or, if none,
566       its initial occurrence before a given time.
567 
568       @param afterTime is the date/time before which to find the latest
569       repetition.
570 
571       @return the date and time of the latest repetition, or an invalid
572       date/time if the specified time is at or before the alarm's initial
573       occurrence.
574 
575       @see nextRepetition()
576     */
577     Q_REQUIRED_RESULT QDateTime previousRepetition(const QDateTime &afterTime) const;
578 
579     /**
580       Returns the interval between the alarm's initial occurrence and
581       its final repetition.
582     */
583     Q_REQUIRED_RESULT Duration duration() const;
584 
585     /**
586       Toggles the alarm status, i.e, an enable alarm becomes disabled
587       and a disabled alarm becomes enabled.
588 
589       @see enabled(), setEnabled()
590     */
591     void toggleAlarm();
592 
593     /**
594       Sets the enabled status of the alarm.
595       @param enable if true, then enable the alarm; else disable the alarm.
596 
597       @see enabled(), toggleAlarm()
598     */
599     void setEnabled(bool enable);
600 
601     /**
602       Returns the alarm enabled status: true (enabled) or false (disabled).
603 
604       @see setEnabled(), toggleAlarm()
605     */
606     Q_REQUIRED_RESULT bool enabled() const;
607 
608     /**
609       Set if the location radius for the alarm has been defined.
610       @param hasLocationRadius if true, then this alarm has a location radius.
611 
612       @see setLocationRadius()
613     */
614     void setHasLocationRadius(bool hasLocationRadius);
615 
616     /**
617       Returns true if alarm has location radius defined.
618 
619       @see setLocationRadius()
620     */
621     Q_REQUIRED_RESULT bool hasLocationRadius() const;
622 
623     /**
624       Set location radius for the alarm. This means that alarm will be
625       triggered when user approaches the location. Given value will be
626       stored into custom properties as X-LOCATION-RADIUS.
627 
628       @param locationRadius radius in meters
629       @see locationRadius()
630     */
631     void setLocationRadius(int locationRadius);
632 
633     /**
634       Returns the location radius in meters.
635 
636       @see setLocationRadius()
637     */
638     Q_REQUIRED_RESULT int locationRadius() const;
639 
640 protected:
641     /**
642       @copydoc
643       CustomProperties::customPropertyUpdated()
644     */
645     void customPropertyUpdated() override;
646 
647     /**
648       @copydoc
649       IncidenceBase::virtual_hook()
650     */
651     virtual void virtual_hook(int id, void *data);
652 
653 private:
654     //@cond PRIVATE
655     class Private;
656     Private *const d;
657     //@endcond
658     friend KCALENDARCORE_EXPORT QDataStream &operator<<(QDataStream &s, const KCalendarCore::Alarm::Ptr &);
659     friend KCALENDARCORE_EXPORT QDataStream &operator>>(QDataStream &s, const KCalendarCore::Alarm::Ptr &);
660 };
661 /**
662  * Alarm serializer.
663  *
664  * @since 4.12
665  */
666 KCALENDARCORE_EXPORT QDataStream &operator<<(QDataStream &out, const KCalendarCore::Alarm::Ptr &);
667 
668 /**
669  * Alarm deserializer.
670  *
671  * @since 4.12
672  */
673 KCALENDARCORE_EXPORT QDataStream &operator>>(QDataStream &in, const KCalendarCore::Alarm::Ptr &);
674 
675 }
676 
677 //@cond PRIVATE
678 Q_DECLARE_TYPEINFO(KCalendarCore::Alarm::Ptr, Q_MOVABLE_TYPE);
679 Q_DECLARE_METATYPE(KCalendarCore::Alarm::Ptr)
680 //@endcond
681 
682 #endif
683