1/*
2 This file is part of the kcalcore library.
3
4 Copyright (c) 1998 Preston Brown <pbrown@kde.org>
5 Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org>
6 Copyright (c) 2002,2006,2007 David Jarvie <software@astrojar.org.uk>
7 Copyright (c) 2005, Reinhold Kainhofer <reinhold@kainhofer.com>
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
18
19 You should have received a copy of the GNU Library General Public License
20 along with this library; see the file COPYING.LIB. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA.
23*/
24#ifndef KCALCORE_RECURRENCERULE_H
25#define KCALCORE_RECURRENCERULE_H
26
27#include "kcalcore_export.h"
28#include "sortablelist.h"
29
30#include <KDE/KDateTime>
31
32namespace KCalCore {
33
34// These two are duplicates wrt. incidencebase.h
35typedef SortableList<KDateTime> DateTimeList;
36typedef SortableList<QDate> DateList;
37/* List of times */
38typedef SortableList<QTime> TimeList;
39
40/**
41 This class represents a recurrence rule for a calendar incidence.
42*/
43class KCALCORE_EXPORT RecurrenceRule
44{
45public:
46 class RuleObserver
47 {
48 public:
49 virtual ~RuleObserver();
50 /** This method is called on each change of the recurrence object */
51 virtual void recurrenceChanged(RecurrenceRule *) = 0;
52 };
53 typedef QList<RecurrenceRule*> List;
54
55 /** enum for describing the frequency how an event recurs, if at all. */
56 enum PeriodType {
57 rNone = 0,
58 rSecondly,
59 rMinutely,
60 rHourly,
61 rDaily,
62 rWeekly,
63 rMonthly,
64 rYearly
65 };
66
67 /** structure for describing the n-th weekday of the month/year. */
68 class KCALCORE_EXPORT WDayPos //krazy:exclude=dpointer
69 {
70 public:
71 explicit WDayPos(int ps = 0, short dy = 0);
72 void setDay(short dy);
73 short day() const;
74 void setPos(int ps);
75 int pos() const;
76
77 bool operator==(const RecurrenceRule::WDayPos &pos2) const;
78 bool operator!=(const RecurrenceRule::WDayPos &pos2) const;
79
80 protected:
81 short mDay; // Weekday, 1=monday, 7=sunday
82 int mPos; // week of the day (-1 for last, 1 for first, 0 for all weeks)
83 // Bounded by -366 and +366, 0 means all weeks in that period
84
85 friend KCALCORE_EXPORT QDataStream& operator<<(QDataStream &out, const KCalCore::RecurrenceRule::WDayPos &);
86 friend KCALCORE_EXPORT QDataStream& operator>>(QDataStream &in, KCalCore::RecurrenceRule::WDayPos &);
87 };
88
89 // Q_DECLARE_TYPEINFO(RecurrenceRule::WDayPos, Q_MOVABLE_TYPE) TODO_KDE5
90
91 RecurrenceRule();
92 RecurrenceRule(const RecurrenceRule &r);
93 ~RecurrenceRule();
94
95 bool operator==(const RecurrenceRule &r) const;
96 bool operator!=(const RecurrenceRule &r) const {
97 return !operator==(r);
98 }
99 RecurrenceRule &operator=(const RecurrenceRule &r);
100
101 /** Set if recurrence is read-only or can be changed. */
102 void setReadOnly(bool readOnly);
103
104 /**
105 Returns true if the recurrence is read-only; false if it can be changed.
106 */
107 bool isReadOnly() const;
108
109 /**
110 Returns the event's recurrence status. See the enumeration at the top
111 of this file for possible values.
112 */
113 bool recurs() const;
114 void setRecurrenceType(PeriodType period);
115 PeriodType recurrenceType() const;
116
117 /** Turns off recurrence for the event. */
118 void clear();
119
120 /**
121 Returns the recurrence frequency, in terms of the recurrence time period type.
122 */
123 uint frequency() const;
124
125 /**
126 Sets the recurrence frequency, in terms of the recurrence time period type.
127 */
128 void setFrequency(int freq);
129
130 /**
131 Returns the recurrence start date/time.
132 Note that the recurrence does not necessarily occur on the start date/time.
133 For this to happen, it must actually match the rule.
134 */
135 KDateTime startDt() const;
136
137 /**
138 Sets the recurrence start date/time.
139 Note that setting the start date/time does not make the recurrence occur
140 on that date/time, it simply sets a lower limit to when the recurrences
141 take place (this applies only for the by- rules, not for i.e. an hourly
142 rule where the startDt is the first occurrence).
143
144 Note that setting @p start to a date-only value does not make an all-day
145 recurrence: to do this, call setAllDay(true).
146
147 @param start the recurrence's start date and time
148 */
149 void setStartDt(const KDateTime &start);
150
151 /** Returns whether the start date has no time associated. All-Day
152 means -- according to rfc2445 -- that the event has no time associate. */
153 bool allDay() const;
154
155 /** Sets whether the dtstart is all-day (i.e. has no time attached)
156 *
157 * @param allDay Whether start datetime is all-day
158 */
159 void setAllDay(bool allDay);
160
161 /** Returns the date and time of the last recurrence.
162 * An invalid date is returned if the recurrence has no end.
163 * @param result if non-null, *result is updated to true if successful,
164 * or false if there is no recurrence or its end date cannot be determined.
165 */
166 KDateTime endDt(bool *result = 0) const;
167
168 /** Sets the date and time of the last recurrence.
169 * @param endDateTime the ending date/time after which to stop recurring. */
170 void setEndDt(const KDateTime &endDateTime);
171
172 /**
173 * Returns -1 if the event recurs infinitely, 0 if the end date is set,
174 * otherwise the total number of recurrences, including the initial occurrence.
175 */
176 int duration() const;
177
178 /** Sets the total number of times the event is to occur, including both the
179 * first and last. */
180 void setDuration(int duration);
181
182 /** Returns the number of recurrences up to and including the date/time specified. */
183 int durationTo(const KDateTime &dt) const;
184
185 /** Returns the number of recurrences up to and including the date specified. */
186 int durationTo(const QDate &date) const;
187
188 /**
189 Shift the times of the rule so that they appear at the same clock
190 time as before but in a new time zone. The shift is done from a viewing
191 time zone rather than from the actual rule time zone.
192
193 For example, shifting a rule whose start time is 09:00 America/New York,
194 using an old viewing time zone (@p oldSpec) of Europe/London, to a new time
195 zone (@p newSpec) of Europe/Paris, will result in the time being shifted
196 from 14:00 (which is the London time of the rule start) to 14:00 Paris
197 time.
198
199 @param oldSpec the time specification which provides the clock times
200 @param newSpec the new time specification
201 */
202 void shiftTimes(const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec);
203
204 /** Returns true if the date specified is one on which the event will
205 * recur. The start date returns true only if it actually matches the rule.
206 *
207 * @param date date to check
208 * @param timeSpec time specification for @p date
209 */
210 bool recursOn(const QDate &date, const KDateTime::Spec &timeSpec) const;
211
212 /** Returns true if the date/time specified is one at which the event will
213 * recur. Times are rounded down to the nearest minute to determine the result.
214 * The start date/time returns true only if it actually matches the rule.
215 *
216 * @param dt the date+time to check for recurrency
217 */
218 bool recursAt(const KDateTime &dt) const;
219
220 /** Returns true if the date matches the rules. It does not necessarily
221 mean that this is an actual occurrence. In particular, the method does
222 not check if the date is after the end date, or if the frequency interval
223 matches.
224
225 @param dt the date+time to check for matching the rules
226 */
227 bool dateMatchesRules(const KDateTime &dt) const;
228
229 /** Returns a list of the times on the specified date at which the
230 * recurrence will occur. The returned times should be interpreted in the
231 * context of @p timeSpec.
232 * @param date the date for which to find the recurrence times
233 * @param timeSpec time specification for @p date
234 */
235 TimeList recurTimesOn(const QDate &date, const KDateTime::Spec &timeSpec) const;
236
237 /** Returns a list of all the times at which the recurrence will occur
238 * between two specified times.
239 *
240 * There is a (large) maximum limit to the number of times returned. If due to
241 * this limit the list is incomplete, this is indicated by the last entry being
242 * set to an invalid KDateTime value. If you need further values, call the
243 * method again with a start time set to just after the last valid time returned.
244 * @param start inclusive start of interval
245 * @param end inclusive end of interval
246 * @return list of date/time values
247 */
248 DateTimeList timesInInterval(const KDateTime &start, const KDateTime &end) const;
249
250 /** Returns the date and time of the next recurrence, after the specified date/time.
251 * If the recurrence has no time, the next date after the specified date is returned.
252 * @param preDateTime the date/time after which to find the recurrence.
253 * @return date/time of next recurrence, or invalid date if none.
254 */
255 KDateTime getNextDate(const KDateTime &preDateTime) const;
256
257 /** Returns the date and time of the last previous recurrence, before the specified date/time.
258 * If a time later than 00:00:00 is specified and the recurrence has no time, 00:00:00 on
259 * the specified date is returned if that date recurs.
260 * @param afterDateTime the date/time before which to find the recurrence.
261 * @return date/time of previous recurrence, or invalid date if none.
262 */
263 KDateTime getPreviousDate(const KDateTime &afterDateTime) const;
264
265 void setBySeconds(const QList<int> &bySeconds);
266 void setByMinutes(const QList<int> &byMinutes);
267 void setByHours(const QList<int> &byHours);
268
269 void setByDays(const QList<WDayPos> &byDays);
270 void setByMonthDays(const QList<int> &byMonthDays);
271 void setByYearDays(const QList<int> &byYearDays);
272 void setByWeekNumbers(const QList<int> &byWeekNumbers);
273 void setByMonths(const QList<int> &byMonths);
274 void setBySetPos(const QList<int> &bySetPos);
275 void setWeekStart(short weekStart);
276
277 const QList<int> &bySeconds() const;
278 const QList<int> &byMinutes() const;
279 const QList<int> &byHours() const;
280
281 const QList<WDayPos> &byDays() const;
282 const QList<int> &byMonthDays() const;
283 const QList<int> &byYearDays() const;
284 const QList<int> &byWeekNumbers() const;
285 const QList<int> &byMonths() const;
286 const QList<int> &bySetPos() const;
287 short weekStart() const;
288
289 /**
290 Set the RRULE string for the rule.
291 This is merely stored for future reference. The string is not used in any way
292 by the RecurrenceRule.
293
294 @param rrule the RRULE string
295 */
296 void setRRule(const QString &rrule);
297 QString rrule() const;
298
299 void setDirty();
300 /**
301 Installs an observer. Whenever some setting of this recurrence
302 object is changed, the recurrenceUpdated( Recurrence* ) method
303 of each observer will be called to inform it of changes.
304 @param observer the Recurrence::Observer-derived object, which
305 will be installed as an observer of this object.
306 */
307 void addObserver(RuleObserver *observer);
308
309 /**
310 Removes an observer that was added with addObserver. If the
311 given object was not an observer, it does nothing.
312 @param observer the Recurrence::Observer-derived object to
313 be removed from the list of observers of this object.
314 */
315 void removeObserver(RuleObserver *observer);
316
317 /**
318 Debug output.
319 */
320 void dump() const;
321
322private:
323 //@cond PRIVATE
324 class Private;
325 Private *const d;
326 //@endcond
327
328 friend KCALCORE_EXPORT QDataStream& operator<<(QDataStream &out, const KCalCore::RecurrenceRule *);
329 friend KCALCORE_EXPORT QDataStream& operator>>(QDataStream &in, const KCalCore::RecurrenceRule *);
330};
331
332/**
333 * RecurrenceRule serializer and deserializer.
334 * @since 4.12
335 */
336KCALCORE_EXPORT QDataStream& operator<<(QDataStream &out, const KCalCore::RecurrenceRule *);
337KCALCORE_EXPORT QDataStream& operator>>(QDataStream &in, const KCalCore::RecurrenceRule *);
338
339/**
340 * RecurrenceRule::WDayPos serializer and deserializer.
341 * @since 4.12
342 */
343KCALCORE_EXPORT QDataStream& operator<<(QDataStream &out, const KCalCore::RecurrenceRule::WDayPos &);
344KCALCORE_EXPORT QDataStream& operator>>(QDataStream &in, KCalCore::RecurrenceRule::WDayPos &);
345
346}
347
348#endif
349