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