summaryrefslogtreecommitdiffabout
path: root/libkcal/recurrence.h
Unidiff
Diffstat (limited to 'libkcal/recurrence.h') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/recurrence.h401
1 files changed, 401 insertions, 0 deletions
diff --git a/libkcal/recurrence.h b/libkcal/recurrence.h
new file mode 100644
index 0000000..a0f6d84
--- a/dev/null
+++ b/libkcal/recurrence.h
@@ -0,0 +1,401 @@
1/*
2 This file is part of libkcal.
3 Copyright (c) 1998 Preston Brown
4 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (c) 2002 David Jarvie <software@astrojar.org.uk>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
21*/
22#ifndef KCAL_RECURRENCE_H
23#define KCAL_RECURRENCE_H
24
25#include <qstring.h>
26#include <qbitarray.h>
27#include <qptrlist.h>
28
29namespace KCal {
30
31class Incidence;
32
33/**
34 This class represents a recurrence rule for a calendar incidence.
35*/
36class Recurrence
37{
38 public:
39 /** enumeration for describing how an event recurs, if at all. */
40 enum { rNone = 0, rMinutely = 0x001, rHourly = 0x0002, rDaily = 0x0003,
41 rWeekly = 0x0004, rMonthlyPos = 0x0005, rMonthlyDay = 0x0006,
42 rYearlyMonth = 0x0007, rYearlyDay = 0x0008, rYearlyPos = 0x0009 };
43
44 /** Enumeration for specifying what date yearly recurrences of February 29th occur
45 * in non-leap years. */
46 enum Feb29Type {
47 rMar1, // recur on March 1st (default)
48 rFeb28, // recur on February 28th
49 rFeb29 // only recur on February 29th, i.e. don't recur in non-leap years
50 };
51
52 /** structure for Recurs rMonthlyPos */
53 struct rMonthPos {
54 QBitArray rDays;
55 short rPos;
56 bool negative;
57 };
58
59 Recurrence(Incidence *parent, int compatVersion = 0);
60 Recurrence(const Recurrence&, Incidence *parent);
61 ~Recurrence();
62
63 bool operator==( const Recurrence& ) const;
64 bool operator!=( const Recurrence& r ) const { return !operator==(r); }
65
66 Incidence *parent() { return mParent; }
67
68 /** Return the start of the recurrence */
69 QDateTime recurStart() const { return mRecurStart; }
70 /** Returns the number of exception dates for the recurrence */
71 int recurExDatesCount() const { return mRecurExDatesCount; }
72 /** Set start of recurrence, as a date and time. */
73 void setRecurStart(const QDateTime &start);
74 /** Set start of recurrence, as a date with no time.
75 * Recurrence types which are sub-daily (e.g. rHourly) always have a time;
76 * the time is set to 00:00:00 in these cases. */
77 void setRecurStart(const QDate &start);
78 /** Set whether the recurrence has no time, just a date.
79 * Recurrence types which are sub-daily (e.g. rHourly) always have a time
80 * and cannot be set to float.
81 * N.B. This property is derived by default from the parent incidence,
82 * or according to whether a time is specified in setRecurStart(). */
83 void setFloats(bool f);
84 /**
85 Returns whether the recurrence has no time, just a date.
86 */
87 bool doesFloat() const {
88 return mFloats;
89 }
90
91 /** Set if recurrence is read-only or can be changed. */
92 void setRecurReadOnly(bool readOnly) { mRecurReadOnly = readOnly; }
93 bool recurReadOnly() const
94 {
95 return mRecurReadOnly;
96 }
97
98
99 /** Set number of exception dates. */
100 void setRecurExDatesCount(int count) { if (count >= 0) mRecurExDatesCount = count; }
101 /** Set the calendar file version for backwards compatibility.
102 * @var version is the KOrganizer/libkcal version, e.g. 220 for KDE 2.2.0.
103 * Specify version = 0 to cancel compatibility mode.
104 */
105 void setCompatVersion(int version = 0);
106
107 /** Returns the event's recurrence status. See the enumeration at the top
108 * of this file for possible values. */
109 ushort doesRecur() const;
110 /** Returns true if the date specified is one on which the event will
111 * recur. */
112 bool recursOnPure(const QDate &qd) const;
113 /** Returns true if the date/time specified is one at which the event will
114 * recur. Times are rounded down to the nearest minute to determine the result. */
115 bool recursAtPure(const QDateTime &) const;
116 /** Turns off recurrence for the event. */
117 void unsetRecurs();
118
119 /** Returns the date of the next recurrence, after the specified date.
120 * @var preDate the date after which to find the recurrence.
121 * @var last if non-null, *last is set to true if the next recurrence is the
122 * last recurrence, else false.
123 * Reply = date of next recurrence, or invalid date if none.
124 */
125 QDate getNextDate(const QDate& preDate, bool* last = 0) const;
126 /** Returns the date and time of the next recurrence, after the specified date/time.
127 * If the recurrence has no time, the next date after the specified date is returned.
128 * @var preDate the date/time after which to find the recurrence.
129 * @var last if non-null, *last is set to true if the next recurrence is the
130 * last recurrence, else false.
131 * Reply = date/time of next recurrence, or invalid date if none.
132 */
133 QDateTime getNextDateTime(const QDateTime& preDateTime, bool* last = 0) const;
134 /** Returns the date of the last previous recurrence, before the specified date.
135 * @var afterDate the date before which to find the recurrence.
136 * @var last if non-null, *last is set to true if the previous recurrence is the
137 * last recurrence, else false.
138 * Reply = date of previous recurrence, or invalid date if none.
139 */
140 QDate getPreviousDate(const QDate& afterDate, bool* last = 0) const;
141 /** Returns the date and time of the last previous recurrence, before the specified date/time.
142 * If a time later than 00:00:00 is specified and the recurrence has no time, 00:00:00 on
143 * the specified date is returned if that date recurs.
144 * @var afterDate the date/time before which to find the recurrence.
145 * @var last if non-null, *last is set to true if the previous recurrence is the
146 * last recurrence, else false.
147 * Reply = date/time of previous recurrence, or invalid date if none.
148 */
149 QDateTime getPreviousDateTime(const QDateTime& afterDateTime, bool* last = 0) const;
150
151 /** Returns frequency of recurrence, in terms of the recurrence time period type. */
152 int frequency() const;
153 /** Returns the total number of recurrences, including the initial occurrence. */
154 int duration() const;
155 /** Sets the total number of times the event is to occur, including both the
156 * first and last. */
157 void setDuration(int duration);
158 /** Returns the number of recurrences up to and including the date specified. */
159 int durationTo(const QDate &) const;
160 /** Returns the number of recurrences up to and including the date/time specified. */
161 int durationTo(const QDateTime &) const;
162
163 /** Returns the date of the last recurrence.
164 * An invalid date is returned if the recurrence has no end.
165 * Note: for some recurrence types, endDate() can involve significant calculation.
166 */
167 QDate endDate() const;
168 /** Returns the date and time of the last recurrence.
169 * An invalid date is returned if the recurrence has no end.
170 * Note: for some recurrence types, endDateTime() can involve significant calculation.
171 */
172 QDateTime endDateTime() const;
173 /** Returns a string representing the recurrence end date in the format
174 according to the user's locale settings. */
175 QString endDateStr(bool shortfmt=true) const;
176
177 /** Sets an event to recur minutely.
178 * @var _rFreq the frequency to recur, e.g. 2 is every other minute
179 * @var duration the number of times the event is to occur, or -1 to recur indefinitely.
180 */
181 void setMinutely(int _rFreq, int duration);
182 /** Sets an event to recur minutely.
183 * @var _rFreq the frequency to recur, e.g. 2 is every other minute
184 * @var endDateTime the ending date/time after which to stop recurring
185 */
186 void setMinutely(int _rFreq, const QDateTime &endDateTime);
187
188 /** Sets an event to recur hourly.
189 * @var _rFreq the frequency to recur, e.g. 2 is every other hour
190 * @var duration the number of times the event is to occur, or -1 to recur indefinitely.
191 */
192 void setHourly(int _rFreq, int duration);
193 /** Sets an event to recur hourly.
194 * @var _rFreq the frequency to recur, e.g. 2 is every other hour
195 * @var endDateTime the ending date/time after which to stop recurring
196 */
197 void setHourly(int _rFreq, const QDateTime &endDateTime);
198
199 /** Sets an event to recur daily.
200 * @var _rFreq the frequency to recur, e.g. 2 is every other day
201 * @var duration the number of times the event is to occur, or -1 to recur indefinitely.
202 */
203 void setDaily(int _rFreq, int duration);
204 /** Sets an event to recur daily.
205 * @var _rFreq the frequency to recur, e.g. 2 is every other day
206 * @var endDate the ending date after which to stop recurring
207 */
208 void setDaily(int _rFreq, const QDate &endDate);
209
210 /** Sets an event to recur weekly.
211 * @var _rFreq the frequency to recur, e.g. every other week etc.
212 * @var _rDays a 7 bit array indicating which days on which to recur (bit 0 = Monday).
213 * @var duration the number of times the event is to occur, or -1 to recur indefinitely.
214 * @var weekStart the first day of the week (Monday=1 .. Sunday=7, default is Monday).
215 */
216 void setWeekly(int _rFreq, const QBitArray &_rDays, int duration, int weekStart = 1);
217 /** Sets an event to recur weekly.
218 * @var _rFreq the frequency to recur, e.g. every other week etc.
219 * @var _rDays a 7 bit array indicating which days on which to recur (bit 0 = Monday).
220 * @var endDate the date on which to stop recurring.
221 * @var weekStart the first day of the week (Monday=1 .. Sunday=7, default is Monday).
222 */
223 void setWeekly(int _rFreq, const QBitArray &_rDays, const QDate &endDate, int weekStart = 1);
224 /** Returns the first day of the week. Monday=1 .. Sunday=7. */
225 int weekStart() const { return rWeekStart; }
226 /** Returns week day mask (bit 0 = Monday). */
227 const QBitArray &days() const;
228
229 /** Sets an event to recur monthly.
230 * @var type rMonthlyPos or rMonthlyDay
231 * @var _rFreq the frequency to recur, e.g. 3 for every third month.
232 * @var duration the number of times the event is to occur, or -1 to recur indefinitely.
233 */
234 void setMonthly(short type, int _rFreq, int duration);
235 /** same as above, but with ending date not number of recurrences */
236 void setMonthly(short type, int _rFreq, const QDate &endDate);
237 /** Adds a position to the recursMonthlyPos recurrence rule, if it is
238 * set.
239 * @var _rPos the position in the month for the recurrence, with valid
240 * values being 1-5 (5 weeks max in a month).
241 * @var _rDays the days for the position to recur on (bit 0 = Monday).
242 * Example: _rPos = 2, and bits 0 and 2 are set in _rDays:
243 * the rule is to repeat every 2nd Monday and Wednesday in the month.
244 */
245 void addMonthlyPos(short _rPos, const QBitArray &_rDays);
246 /** Adds a position the the recursMonthlyDay list.
247 * @var _rDay the date in the month to recur.
248 */
249 void addMonthlyDay(short _rDay);
250 /** Returns list of day positions in months. */
251 const QPtrList<rMonthPos> &monthPositions() const;
252 /** Returns list of day numbers of a month. */
253 const QPtrList<int> &monthDays() const;
254
255 /** Sets an event to recur yearly.
256 * @var type rYearlyMonth, rYearlyPos or rYearlyDay
257 * @var freq the frequency to recur, e.g. 3 for every third year.
258 * @var duration the number of times the event is to occur, or -1 to recur indefinitely.
259 */
260 void setYearly(int type, int freq, int duration);
261 /** Sets an event to recur yearly ending at \a endDate. */
262 void setYearly(int type, int freq, const QDate &endDate);
263 /** Sets an event to recur yearly on specified dates.
264 * The dates must be specified by calling addYearlyNum().
265 * @var type the way recurrences of February 29th are to be handled in non-leap years.
266 * @var freq the frequency to recur, e.g. 3 for every third year.
267 * @var duration the number of times the event is to occur, or -1 to recur indefinitely.
268 */
269 void setYearlyByDate(Feb29Type type, int freq, int duration);
270 /** Sets an event to recur yearly ending at \a endDate. */
271 void setYearlyByDate(Feb29Type type, int freq, const QDate &endDate);
272 /** Adds position of day or month in year.
273 * N.B. for recursYearlyPos, addYearlyMonthPos() must also be called
274 * to add positions within the month. */
275 void addYearlyNum(short _rNum);
276 /** Adds a position to the recursYearlyPos recurrence rule, if it is set.
277 * N.B. addYearlyNum() must also be called to add recurrence months.
278 * Parameters are the same as for addMonthlyPos().
279 */
280 void addYearlyMonthPos(short _rPos, const QBitArray &_rDays);
281 /** Returns positions of days or months in year. */
282 const QPtrList<int> &yearNums() const;
283 /** Returns list of day positions in months, for a recursYearlyPos recurrence rule. */
284 const QPtrList<rMonthPos> &yearMonthPositions() const;
285 /** Returns how yearly recurrences of February 29th are handled. */
286 Feb29Type feb29YearlyType() const { return mFeb29YearlyType; }
287 /** Sets the default method for handling yearly recurrences of February 29th. */
288 static void setFeb29YearlyTypeDefault(Feb29Type t) { mFeb29YearlyDefaultType = t; }
289 /** Returns the default method for handling yearly recurrences of February 29th. */
290 static Feb29Type setFeb29YearlyTypeDefault() { return mFeb29YearlyDefaultType; }
291
292 /**
293 Debug output.
294 */
295 void dump() const;
296 QString recurrenceText() const;
297
298 protected:
299 enum PeriodFunc { END_DATE_AND_COUNT, COUNT_TO_DATE, NEXT_AFTER_DATE };
300 struct MonthlyData; friend struct MonthlyData;
301 struct YearlyMonthData; friend struct YearlyMonthData;
302 struct YearlyPosData; friend struct YearlyPosData;
303 struct YearlyDayData; friend struct YearlyDayData;
304
305 bool recursSecondly(const QDate &, int secondFreq) const;
306 bool recursMinutelyAt(const QDateTime &dt, int minuteFreq) const;
307 bool recursDaily(const QDate &) const;
308 bool recursWeekly(const QDate &) const;
309 bool recursMonthly(const QDate &) const;
310 bool recursYearlyByMonth(const QDate &) const;
311 bool recursYearlyByPos(const QDate &) const;
312 bool recursYearlyByDay(const QDate &) const;
313
314 QDate getNextDateNoTime(const QDate& preDate, bool* last) const;
315 QDate getPreviousDateNoTime(const QDate& afterDate, bool* last) const;
316
317 void addMonthlyPos_(short _rPos, const QBitArray &_rDays);
318 void setDailySub(short type, int freq, int duration);
319 void setYearly_(short type, Feb29Type, int freq, int duration);
320 int recurCalc(PeriodFunc, QDate &enddate) const;
321 int recurCalc(PeriodFunc, QDateTime &endtime) const;
322 int secondlyCalc(PeriodFunc, QDateTime& endtime, int freq) const;
323 int dailyCalc(PeriodFunc, QDate &enddate) const;
324 int weeklyCalc(PeriodFunc, QDate &enddate) const;
325 int weeklyCalcEndDate(QDate& enddate, int daysPerWeek) const;
326 int weeklyCalcToDate(const QDate& enddate, int daysPerWeek) const;
327 int weeklyCalcNextAfter(QDate& enddate, int daysPerWeek) const;
328 int monthlyCalc(PeriodFunc, QDate &enddate) const;
329 int monthlyCalcEndDate(QDate& enddate, MonthlyData&) const;
330 int monthlyCalcToDate(const QDate& enddate, MonthlyData&) const;
331 int monthlyCalcNextAfter(QDate& enddate, MonthlyData&) const;
332 int yearlyMonthCalc(PeriodFunc, QDate &enddate) const;
333 int yearlyMonthCalcEndDate(QDate& enddate, YearlyMonthData&) const;
334 int yearlyMonthCalcToDate(const QDate& enddate, YearlyMonthData&) const;
335 int yearlyMonthCalcNextAfter(QDate& enddate, YearlyMonthData&) const;
336 int yearlyPosCalc(PeriodFunc, QDate &enddate) const;
337 int yearlyPosCalcEndDate(QDate& enddate, YearlyPosData&) const;
338 int yearlyPosCalcToDate(const QDate& enddate, YearlyPosData&) const;
339 int yearlyPosCalcNextAfter(QDate& enddate, YearlyPosData&) const;
340 int yearlyDayCalc(PeriodFunc, QDate &enddate) const;
341 int yearlyDayCalcEndDate(QDate& enddate, YearlyDayData&) const;
342 int yearlyDayCalcToDate(const QDate& enddate, YearlyDayData&) const;
343 int yearlyDayCalcNextAfter(QDate& enddate, YearlyDayData&) const;
344
345 int countMonthlyPosDays() const;
346 void getMonthlyPosDays(QValueList<int>&, int daysInMonth,
347 int startDayOfWeek) const;
348 bool getMonthlyDayDays(QValueList<int>&, int daysInMonth) const;
349 bool getYearlyMonthMonths(int day, QValueList<int>&,
350 QValueList<int> &leaplist) const;
351
352 int getFirstDayInWeek(int startDay, bool useWeekStart = true) const;
353 int getLastDayInWeek(int endDay, bool useWeekStart = true) const;
354 QDate getFirstDateInMonth(const QDate& earliestDate) const;
355 QDate getLastDateInMonth(const QDate& latestDate) const;
356 QDate getFirstDateInYear(const QDate& earliestDate) const;
357 QDate getLastDateInYear(const QDate& latestDate) const;
358
359 private:
360 // Prohibit copying
361 Recurrence(const Recurrence&);
362 Recurrence &operator=(const Recurrence&);
363
364 short recurs; // should be one of the enums.
365
366 int rWeekStart; // day which starts the week, Monday=1 .. Sunday=7
367 QBitArray rDays; // array of days during week it recurs
368
369 QPtrList<rMonthPos> rMonthPositions; // list of positions during a month
370 // on which an event recurs
371
372 QPtrList<int> rMonthDays; // list of days during a month on
373 // which the event recurs
374
375 QPtrList<int> rYearNums; // either months/days to recur on for rYearly,
376 // sorted in numerical order
377
378 int rFreq; // frequency of period
379
380 // one of the following must be specified
381 int rDuration; // num times to recur (inc. first occurrence), -1 = infinite
382 QDateTime rEndDateTime; // date/time at which to end recurrence
383
384 QDateTime mRecurStart; // date/time of first recurrence
385 bool mFloats; // the recurrence has no time, just a date
386 bool mRecurReadOnly;
387 int mRecurExDatesCount; // number of recurrences (in addition to rDuration) which are excluded
388 Feb29Type mFeb29YearlyType; // how to handle yearly recurrences of February 29th
389 static Feb29Type mFeb29YearlyDefaultType; // default value for mFeb29YearlyType
390
391 // Backwards compatibility for KDE < 3.1.
392 int mCompatVersion; // calendar file version for backwards compatibility
393 short mCompatRecurs; // original 'recurs' in old calendar format, or rNone
394 int mCompatDuration; // original 'rDuration' in old calendar format, or 0
395
396 Incidence *mParent;
397};
398
399}
400
401#endif