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 | |
32 | namespace KCalCore { |
33 | |
34 | // These two are duplicates wrt. incidencebase.h |
35 | typedef SortableList<KDateTime> DateTimeList; |
36 | typedef SortableList<QDate> DateList; |
37 | /* List of times */ |
38 | typedef SortableList<QTime> TimeList; |
39 | |
40 | /** |
41 | This class represents a recurrence rule for a calendar incidence. |
42 | */ |
43 | class KCALCORE_EXPORT RecurrenceRule |
44 | { |
45 | public: |
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 | |
322 | private: |
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 | */ |
336 | KCALCORE_EXPORT QDataStream& operator<<(QDataStream &out, const KCalCore::RecurrenceRule *); |
337 | KCALCORE_EXPORT QDataStream& operator>>(QDataStream &in, const KCalCore::RecurrenceRule *); |
338 | |
339 | /** |
340 | * RecurrenceRule::WDayPos serializer and deserializer. |
341 | * @since 4.12 |
342 | */ |
343 | KCALCORE_EXPORT QDataStream& operator<<(QDataStream &out, const KCalCore::RecurrenceRule::WDayPos &); |
344 | KCALCORE_EXPORT QDataStream& operator>>(QDataStream &in, KCalCore::RecurrenceRule::WDayPos &); |
345 | |
346 | } |
347 | |
348 | #endif |
349 | |