-rw-r--r-- | libkcal/recurrence.h | 401 |
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 | |||
29 | namespace KCal { | ||
30 | |||
31 | class Incidence; | ||
32 | |||
33 | /** | ||
34 | This class represents a recurrence rule for a calendar incidence. | ||
35 | */ | ||
36 | class 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 | ||