libkcal

recurrencerule.h
1 /*
2  This file is part of libkcal.
3 
4  Copyright (c) 1998 Preston Brown <pbrown@kde.org>
5  Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org>
6  Copyright (c) 2002 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 <tqdatetime.h>
28 #include <libkcal/listbase.h>
29 
30 #include "libkcal_export.h"
31 
32 template <class T>
33 TQ_INLINE_TEMPLATES void qSortUnique( TQValueList<T> &lst )
34 {
35  qHeapSort( lst );
36  if ( lst.isEmpty() ) return;
37  // Remove all duplicates from the times list
38  // TODO: Make this more efficient!
39  TQValueListIterator<T> it = lst.begin();
40  T last = *it;
41  ++it;
42  T newlast;
43  while ( it != lst.end() ) {
44  newlast = (*it);
45  if ( newlast == last ) it = lst.remove( it );
46  else {
47  last = newlast;
48  ++it;
49  }
50  }
51 }
52 
53 template <class T>
54 TQ_INLINE_TEMPLATES int findGE( const TQValueList<T> &lst, const T &value, int start )
55 {
56  // Do a binary search to find the first item >= value
57  int st = start - 1;
58  int end = lst.count();
59  while ( end - st > 1 ) {
60  int i = ( st + end ) / 2;
61  if ( value <= lst[i] ) {
62  end = i;
63  } else {
64  st = i;
65  }
66  }
67  ++st;
68  return ( st == int( lst.count() ) ) ? -1 : st;
69 }
70 
71 template <class T>
72 TQ_INLINE_TEMPLATES int findGT( const TQValueList<T> &lst, const T &value, int start )
73 {
74  // Do a binary search to find the first item > value
75  int st = start - 1;
76  int end = lst.count();
77  while ( end - st > 1 ) {
78  int i = ( st + end ) / 2;
79  if ( value < lst[i] ) {
80  end = i;
81  } else {
82  st = i;
83  }
84  }
85  ++st;
86  return ( st == int( lst.count() ) ) ? -1 : st;
87 }
88 
89 template <class T>
90 TQ_INLINE_TEMPLATES int findLE( const TQValueList<T> &lst, const T &value, int start )
91 {
92  // Do a binary search to find the last item <= value
93  int st = start - 1;
94  int end = lst.count();
95  while ( end - st > 1 ) {
96  int i = ( st + end ) / 2;
97  if ( value < lst[i] ) {
98  end = i;
99  } else {
100  st = i;
101  }
102  }
103  return ( end > start ) ? st : -1;
104 }
105 
106 template <class T>
107 TQ_INLINE_TEMPLATES int findLT( const TQValueList<T> &lst, const T &value, int start )
108 {
109  // Do a binary search to find the last item < value
110  int st = start - 1;
111  int end = lst.count();
112  while ( end - st > 1 ) {
113  int i = ( st + end ) / 2;
114  if ( value <= lst[i] ) {
115  end = i;
116  } else {
117  st = i;
118  }
119  }
120  return ( end > start ) ? st : -1;
121 }
122 
123 template <class T>
124 TQ_INLINE_TEMPLATES int findSorted( const TQValueList<T> &lst, const T &value, int start )
125 {
126  // Do a binary search to find the item == value
127  int st = start - 1;
128  int end = lst.count();
129  while ( end - st > 1 ) {
130  int i = ( st + end ) / 2;
131  if ( value < lst[i] ) {
132  end = i;
133  } else {
134  st = i;
135  }
136  }
137  return ( end > start && value == lst[st] ) ? st : -1;
138 }
139 
140 template <class T>
141 TQ_INLINE_TEMPLATES int removeSorted( TQValueList<T> &lst, const T &value, int start )
142 {
143  int i = findSorted( lst, value, start );
144  if ( i >= 0 ) {
145  lst.remove( lst.at( i ) );
146  }
147  return i;
148 }
149 
150 template <class T>
151 TQ_INLINE_TEMPLATES bool containsSorted( const TQValueList<T> &lst, const T &value )
152 {
153  return findSorted( lst, value, 0 ) >= 0;
154 }
155 
156 
157 namespace KCal {
158 
159 typedef TQValueList<TQDateTime> DateTimeList;
160 typedef TQValueList<TQDate> DateList;
161 typedef TQValueList<TQTime> TimeList;
162 
163 
164 
165 
169 class LIBKCAL_EXPORT RecurrenceRule
170 {
171  public:
172  class Observer {
173  public:
174  virtual ~Observer() {}
176  virtual void recurrenceChanged( RecurrenceRule * ) = 0;
177  };
180  enum PeriodType { rNone = 0,
181  rSecondly, rMinutely, rHourly,
182  rDaily, rWeekly, rMonthly, rYearly
183  };
185  class WDayPos {
186  public:
187  WDayPos( int ps = 0 , short dy = 0 ) : mDay(dy), mPos(ps) {}
188  short day() const { return mDay; }
189  int pos() const { return mPos; }
190  void setDay( short dy ) { mDay = dy; }
191  void setPos( int ps ) { mPos = ps; }
192 
193  bool operator==( const RecurrenceRule::WDayPos &pos2 ) const {
194  return ( mDay == pos2.mDay ) && ( mPos == pos2.mPos );
195  }
196  protected:
197  short mDay; // Weekday, 1=monday, 7=sunday
198  int mPos; // week of the day (-1 for last, 1 for first, 0 for all weeks)
199  // Bounded by -366 and +366, 0 means all weeks in that period
200  };
201 
202  RecurrenceRule( /*Incidence *parent, int compatVersion = 0*/ );
204  ~RecurrenceRule();
205 
206  bool operator==( const RecurrenceRule& ) const;
207  bool operator!=( const RecurrenceRule& r ) const { return !operator==(r); }
208  RecurrenceRule &operator=(const RecurrenceRule&);
209 
210 // Incidence *parent() const { return mParent; }
211 
212 
214  void setReadOnly(bool readOnly) { mIsReadOnly = readOnly; }
216  bool isReadOnly() const { return mIsReadOnly; }
217 
218 
221  bool doesRecur() const { return mPeriod!=rNone; }
222  void setRecurrenceType( PeriodType period );
223  PeriodType recurrenceType() const { return mPeriod; }
225  void clear();
226 
227 
229  uint frequency() const { return mFrequency; }
231  void setFrequency( int freq );
232 
233 
235  TQDateTime startDt() const { return mDateStart; }
237  void setStartDt(const TQDateTime &start);
238 
241  bool doesFloat() const { return mFloating; }
243  void setFloats( bool floats );
244 
245 
251  TQDateTime endDt( bool* result = 0 ) const;
254  void setEndDt(const TQDateTime &endDateTime);
255 
256 
261  int duration() const { return mDuration; }
264  void setDuration(int duration);
265 // /** Returns the number of recurrences up to and including the date specified. */
266 // int durationTo(const TQDate &) const;
268  int durationTo(const TQDateTime &) const;
270  int durationTo( const TQDate &date ) const { return durationTo( TQDateTime( date, TQTime( 23, 59, 59 ) ) ); }
271 
272 
273 
276  bool recursOn( const TQDate &qd ) const;
280  bool recursAt( const TQDateTime & ) const;
285  bool dateMatchesRules( const TQDateTime &qdt ) const;
286 
287 
292  TimeList recurTimesOn( const TQDate &date ) const;
293 
305  DateTimeList timesInInterval( const TQDateTime &start, const TQDateTime &end ) const;
306 
312  TQDateTime getNextDate( const TQDateTime& preDateTime ) const;
319  TQDateTime getPreviousDate( const TQDateTime& afterDateTime ) const;
320 
321 
322 
323 
324  void setBySeconds( const TQValueList<int> bySeconds );
325  void setByMinutes( const TQValueList<int> byMinutes );
326  void setByHours( const TQValueList<int> byHours );
327 
328  void setByDays( const TQValueList<WDayPos> byDays );
329  void setByMonthDays( const TQValueList<int> byMonthDays );
330  void setByYearDays( const TQValueList<int> byYearDays );
331  void setByWeekNumbers( const TQValueList<int> byWeekNumbers );
332  void setByMonths( const TQValueList<int> byMonths );
333  void setBySetPos( const TQValueList<int> bySetPos );
334  void setWeekStart( short weekStart );
335 
336  const TQValueList<int> &bySeconds() const { return mBySeconds; }
337  const TQValueList<int> &byMinutes() const { return mByMinutes; }
338  const TQValueList<int> &byHours() const { return mByHours; }
339 
340  const TQValueList<WDayPos> &byDays() const { return mByDays; }
341  const TQValueList<int> &byMonthDays() const { return mByMonthDays; }
342  const TQValueList<int> &byYearDays() const { return mByYearDays; }
343  const TQValueList<int> &byWeekNumbers() const { return mByWeekNumbers; }
344  const TQValueList<int> &byMonths() const { return mByMonths; }
345  const TQValueList<int> &bySetPos() const { return mBySetPos; }
346  short weekStart() const { return mWeekStart; }
347 
348 
349  void setDirty();
357  void addObserver( Observer *observer );
364  void removeObserver( Observer *observer );
365 
369  void dump() const;
370  TQString mRRule;
371 
372  private:
373  class Constraint {
374  public:
375  typedef TQValueList<Constraint> List;
376 
377  Constraint( int wkst = 1 );
378 /* Constraint( const Constraint &con ) :
379  year(con.year), month(con.month), day(con.day),
380  hour(con.hour), minute(con.minute), second(con.second),
381  weekday(con.weekday), weeknumber(con.weeknumber),
382  yearday(con.yearday), weekstart(con.weekstart) {}*/
383  Constraint( const TQDateTime &preDate, PeriodType type, int wkst );
384  void clear();
385 
386  int year; // 0 means unspecified
387  int month; // 0 means unspecified
388  int day; // 0 means unspecified
389  int hour; // -1 means unspecified
390  int minute; // -1 means unspecified
391  int second; // -1 means unspecified
392  int weekday; // 0 means unspecified
393  int weekdaynr; // index of weekday in month/year (0=unspecified)
394  int weeknumber; // 0 means unspecified
395  int yearday; // 0 means unspecified
396  int weekstart; // first day of week (1=monday, 7=sunday, 0=unspec.)
397 
398  bool readDateTime( const TQDateTime &preDate, PeriodType type );
399  bool matches( const TQDate &dt, RecurrenceRule::PeriodType type ) const;
400  bool matches( const TQDateTime &dt, RecurrenceRule::PeriodType type ) const;
401  bool isConsistent() const;
402  bool isConsistent( PeriodType period ) const;
403  bool increase( PeriodType type, int freq );
404  TQDateTime intervalDateTime( PeriodType type ) const;
405  DateTimeList dateTimes( PeriodType type ) const;
406  void dump() const;
407  };
408 
409  Constraint getNextValidDateInterval( const TQDateTime &preDate, PeriodType type ) const;
410  Constraint getPreviousValidDateInterval( const TQDateTime &preDate, PeriodType type ) const;
411  DateTimeList datesForInterval( const Constraint &interval, PeriodType type ) const;
412  bool mergeIntervalConstraint( Constraint *merged, const Constraint &conit,
413  const Constraint &interval ) const;
414  bool buildCache() const;
415 
416 
417  PeriodType mPeriod;
418  TQDateTime mDateStart;
423  int mDuration;
424  TQDateTime mDateEnd;
425  uint mFrequency;
426 
427  bool mIsReadOnly;
428  bool mFloating;
429 
430  TQValueList<int> mBySeconds; // values: second 0-59
431  TQValueList<int> mByMinutes; // values: minute 0-59
432  TQValueList<int> mByHours; // values: hour 0-23
433 
434  TQValueList<WDayPos> mByDays; // n-th weekday of the month or year
435  TQValueList<int> mByMonthDays; // values: day -31 to -1 and 1-31
436  TQValueList<int> mByYearDays; // values: day -366 to -1 and 1-366
437  TQValueList<int> mByWeekNumbers; // values: week -53 to -1 and 1-53
438  TQValueList<int> mByMonths; // values: month 1-12
439  TQValueList<int> mBySetPos; // values: position -366 to -1 and 1-366
440  short mWeekStart; // first day of the week (1=Monday, 7=Sunday)
441 
442  Constraint::List mConstraints;
443  void buildConstraints();
444  bool mDirty;
445  TQValueList<Observer*> mObservers;
446 
447  // Cache for duration
448  mutable DateTimeList mCachedDates;
449  mutable TQDateTime mCachedDateEnd;
450  mutable TQDateTime mCachedLastDate; // when mCachedDateEnd invalid, last date checked
451  mutable bool mCached;
452 
453  bool mNoByRules; // no BySeconds, ByMinutes, ... rules exist
454  uint mTimedRepetition; // repeats at a regular number of seconds interval, or 0
455 
456  class Private;
457  Private *d;
458 };
459 
460 }
461 
462 #endif