recurrencerule.h
00001 /* 00002 This file is part of libkcal. 00003 00004 Copyright (c) 1998 Preston Brown <pbrown@kde.org> 00005 Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org> 00006 Copyright (c) 2002 David Jarvie <software@astrojar.org.uk> 00007 Copyright (c) 2005, Reinhold Kainhofer <reinhold@kainhofer.com> 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Library General Public 00011 License as published by the Free Software Foundation; either 00012 version 2 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Library General Public License for more details. 00018 00019 You should have received a copy of the GNU Library General Public License 00020 along with this library; see the file COPYING.LIB. If not, write to 00021 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00022 Boston, MA 02110-1301, USA. 00023 */ 00024 #ifndef KCAL_RECURRENCERULE_H 00025 #define KCAL_RECURRENCERULE_H 00026 00027 #include <tqdatetime.h> 00028 #include <libkcal/listbase.h> 00029 00030 #include "libkcal_export.h" 00031 00032 template <class T> 00033 TQ_INLINE_TEMPLATES void qSortUnique( TQValueList<T> &lst ) 00034 { 00035 qHeapSort( lst ); 00036 if ( lst.isEmpty() ) return; 00037 // Remove all duplicates from the times list 00038 // TODO: Make this more efficient! 00039 TQValueListIterator<T> it = lst.begin(); 00040 T last = *it; 00041 ++it; 00042 T newlast; 00043 while ( it != lst.end() ) { 00044 newlast = (*it); 00045 if ( newlast == last ) it = lst.remove( it ); 00046 else { 00047 last = newlast; 00048 ++it; 00049 } 00050 } 00051 } 00052 00053 template <class T> 00054 TQ_INLINE_TEMPLATES int findGE( const TQValueList<T> &lst, const T &value, int start ) 00055 { 00056 // Do a binary search to find the first item >= value 00057 int st = start - 1; 00058 int end = lst.count(); 00059 while ( end - st > 1 ) { 00060 int i = ( st + end ) / 2; 00061 if ( value <= lst[i] ) { 00062 end = i; 00063 } else { 00064 st = i; 00065 } 00066 } 00067 ++st; 00068 return ( st == int( lst.count() ) ) ? -1 : st; 00069 } 00070 00071 template <class T> 00072 TQ_INLINE_TEMPLATES int findGT( const TQValueList<T> &lst, const T &value, int start ) 00073 { 00074 // Do a binary search to find the first item > value 00075 int st = start - 1; 00076 int end = lst.count(); 00077 while ( end - st > 1 ) { 00078 int i = ( st + end ) / 2; 00079 if ( value < lst[i] ) { 00080 end = i; 00081 } else { 00082 st = i; 00083 } 00084 } 00085 ++st; 00086 return ( st == int( lst.count() ) ) ? -1 : st; 00087 } 00088 00089 template <class T> 00090 TQ_INLINE_TEMPLATES int findLE( const TQValueList<T> &lst, const T &value, int start ) 00091 { 00092 // Do a binary search to find the last item <= value 00093 int st = start - 1; 00094 int end = lst.count(); 00095 while ( end - st > 1 ) { 00096 int i = ( st + end ) / 2; 00097 if ( value < lst[i] ) { 00098 end = i; 00099 } else { 00100 st = i; 00101 } 00102 } 00103 return ( end > start ) ? st : -1; 00104 } 00105 00106 template <class T> 00107 TQ_INLINE_TEMPLATES int findLT( const TQValueList<T> &lst, const T &value, int start ) 00108 { 00109 // Do a binary search to find the last item < value 00110 int st = start - 1; 00111 int end = lst.count(); 00112 while ( end - st > 1 ) { 00113 int i = ( st + end ) / 2; 00114 if ( value <= lst[i] ) { 00115 end = i; 00116 } else { 00117 st = i; 00118 } 00119 } 00120 return ( end > start ) ? st : -1; 00121 } 00122 00123 template <class T> 00124 TQ_INLINE_TEMPLATES int findSorted( const TQValueList<T> &lst, const T &value, int start ) 00125 { 00126 // Do a binary search to find the item == value 00127 int st = start - 1; 00128 int end = lst.count(); 00129 while ( end - st > 1 ) { 00130 int i = ( st + end ) / 2; 00131 if ( value < lst[i] ) { 00132 end = i; 00133 } else { 00134 st = i; 00135 } 00136 } 00137 return ( end > start && value == lst[st] ) ? st : -1; 00138 } 00139 00140 template <class T> 00141 TQ_INLINE_TEMPLATES int removeSorted( TQValueList<T> &lst, const T &value, int start ) 00142 { 00143 int i = findSorted( lst, value, start ); 00144 if ( i >= 0 ) { 00145 lst.remove( lst.at( i ) ); 00146 } 00147 return i; 00148 } 00149 00150 template <class T> 00151 TQ_INLINE_TEMPLATES bool containsSorted( const TQValueList<T> &lst, const T &value ) 00152 { 00153 return findSorted( lst, value, 0 ) >= 0; 00154 } 00155 00156 00157 namespace KCal { 00158 00159 typedef TQValueList<TQDateTime> DateTimeList; 00160 typedef TQValueList<TQDate> DateList; 00161 typedef TQValueList<TQTime> TimeList; 00162 00163 00164 00165 00169 class LIBKCAL_EXPORT RecurrenceRule 00170 { 00171 public: 00172 class Observer { 00173 public: 00174 virtual ~Observer() {} 00176 virtual void recurrenceChanged( RecurrenceRule * ) = 0; 00177 }; 00178 typedef ListBase<RecurrenceRule> List; 00180 enum PeriodType { rNone = 0, 00181 rSecondly, rMinutely, rHourly, 00182 rDaily, rWeekly, rMonthly, rYearly 00183 }; 00185 class WDayPos { 00186 public: 00187 WDayPos( int ps = 0 , short dy = 0 ) : mDay(dy), mPos(ps) {} 00188 short day() const { return mDay; } 00189 int pos() const { return mPos; } 00190 void setDay( short dy ) { mDay = dy; } 00191 void setPos( int ps ) { mPos = ps; } 00192 00193 bool operator==( const RecurrenceRule::WDayPos &pos2 ) const { 00194 return ( mDay == pos2.mDay ) && ( mPos == pos2.mPos ); 00195 } 00196 protected: 00197 short mDay; // Weekday, 1=monday, 7=sunday 00198 int mPos; // week of the day (-1 for last, 1 for first, 0 for all weeks) 00199 // Bounded by -366 and +366, 0 means all weeks in that period 00200 }; 00201 00202 RecurrenceRule( /*Incidence *parent, int compatVersion = 0*/ ); 00203 RecurrenceRule(const RecurrenceRule&); 00204 ~RecurrenceRule(); 00205 00206 bool operator==( const RecurrenceRule& ) const; 00207 bool operator!=( const RecurrenceRule& r ) const { return !operator==(r); } 00208 RecurrenceRule &operator=(const RecurrenceRule&); 00209 00210 // Incidence *parent() const { return mParent; } 00211 00212 00214 void setReadOnly(bool readOnly) { mIsReadOnly = readOnly; } 00216 bool isReadOnly() const { return mIsReadOnly; } 00217 00218 00221 bool doesRecur() const { return mPeriod!=rNone; } 00222 void setRecurrenceType( PeriodType period ); 00223 PeriodType recurrenceType() const { return mPeriod; } 00225 void clear(); 00226 00227 00229 uint frequency() const { return mFrequency; } 00231 void setFrequency( int freq ); 00232 00233 00235 TQDateTime startDt() const { return mDateStart; } 00237 void setStartDt(const TQDateTime &start); 00238 00241 bool doesFloat() const { return mFloating; } 00243 void setFloats( bool floats ); 00244 00245 00251 TQDateTime endDt( bool* result = 0 ) const; 00254 void setEndDt(const TQDateTime &endDateTime); 00255 00256 00261 int duration() const { return mDuration; } 00264 void setDuration(int duration); 00265 // /** Returns the number of recurrences up to and including the date specified. */ 00266 // int durationTo(const TQDate &) const; 00268 int durationTo(const TQDateTime &) const; 00270 int durationTo( const TQDate &date ) const { return durationTo( TQDateTime( date, TQTime( 23, 59, 59 ) ) ); } 00271 00272 00273 00276 bool recursOn( const TQDate &qd ) const; 00280 bool recursAt( const TQDateTime & ) const; 00285 bool dateMatchesRules( const TQDateTime &qdt ) const; 00286 00287 00292 TimeList recurTimesOn( const TQDate &date ) const; 00293 00305 DateTimeList timesInInterval( const TQDateTime &start, const TQDateTime &end ) const; 00306 00312 TQDateTime getNextDate( const TQDateTime& preDateTime ) const; 00319 TQDateTime getPreviousDate( const TQDateTime& afterDateTime ) const; 00320 00321 00322 00323 00324 void setBySeconds( const TQValueList<int> bySeconds ); 00325 void setByMinutes( const TQValueList<int> byMinutes ); 00326 void setByHours( const TQValueList<int> byHours ); 00327 00328 void setByDays( const TQValueList<WDayPos> byDays ); 00329 void setByMonthDays( const TQValueList<int> byMonthDays ); 00330 void setByYearDays( const TQValueList<int> byYearDays ); 00331 void setByWeekNumbers( const TQValueList<int> byWeekNumbers ); 00332 void setByMonths( const TQValueList<int> byMonths ); 00333 void setBySetPos( const TQValueList<int> bySetPos ); 00334 void setWeekStart( short weekStart ); 00335 00336 const TQValueList<int> &bySeconds() const { return mBySeconds; } 00337 const TQValueList<int> &byMinutes() const { return mByMinutes; } 00338 const TQValueList<int> &byHours() const { return mByHours; } 00339 00340 const TQValueList<WDayPos> &byDays() const { return mByDays; } 00341 const TQValueList<int> &byMonthDays() const { return mByMonthDays; } 00342 const TQValueList<int> &byYearDays() const { return mByYearDays; } 00343 const TQValueList<int> &byWeekNumbers() const { return mByWeekNumbers; } 00344 const TQValueList<int> &byMonths() const { return mByMonths; } 00345 const TQValueList<int> &bySetPos() const { return mBySetPos; } 00346 short weekStart() const { return mWeekStart; } 00347 00348 00349 void setDirty(); 00357 void addObserver( Observer *observer ); 00364 void removeObserver( Observer *observer ); 00365 00369 void dump() const; 00370 TQString mRRule; 00371 00372 private: 00373 class Constraint { 00374 public: 00375 typedef TQValueList<Constraint> List; 00376 00377 Constraint( int wkst = 1 ); 00378 /* Constraint( const Constraint &con ) : 00379 year(con.year), month(con.month), day(con.day), 00380 hour(con.hour), minute(con.minute), second(con.second), 00381 weekday(con.weekday), weeknumber(con.weeknumber), 00382 yearday(con.yearday), weekstart(con.weekstart) {}*/ 00383 Constraint( const TQDateTime &preDate, PeriodType type, int wkst ); 00384 void clear(); 00385 00386 int year; // 0 means unspecified 00387 int month; // 0 means unspecified 00388 int day; // 0 means unspecified 00389 int hour; // -1 means unspecified 00390 int minute; // -1 means unspecified 00391 int second; // -1 means unspecified 00392 int weekday; // 0 means unspecified 00393 int weekdaynr; // index of weekday in month/year (0=unspecified) 00394 int weeknumber; // 0 means unspecified 00395 int yearday; // 0 means unspecified 00396 int weekstart; // first day of week (1=monday, 7=sunday, 0=unspec.) 00397 00398 bool readDateTime( const TQDateTime &preDate, PeriodType type ); 00399 bool matches( const TQDate &dt, RecurrenceRule::PeriodType type ) const; 00400 bool matches( const TQDateTime &dt, RecurrenceRule::PeriodType type ) const; 00401 bool isConsistent() const; 00402 bool isConsistent( PeriodType period ) const; 00403 bool increase( PeriodType type, int freq ); 00404 TQDateTime intervalDateTime( PeriodType type ) const; 00405 DateTimeList dateTimes( PeriodType type ) const; 00406 void dump() const; 00407 }; 00408 00409 Constraint getNextValidDateInterval( const TQDateTime &preDate, PeriodType type ) const; 00410 Constraint getPreviousValidDateInterval( const TQDateTime &preDate, PeriodType type ) const; 00411 DateTimeList datesForInterval( const Constraint &interval, PeriodType type ) const; 00412 bool mergeIntervalConstraint( Constraint *merged, const Constraint &conit, 00413 const Constraint &interval ) const; 00414 bool buildCache() const; 00415 00416 00417 PeriodType mPeriod; 00418 TQDateTime mDateStart; 00423 int mDuration; 00424 TQDateTime mDateEnd; 00425 uint mFrequency; 00426 00427 bool mIsReadOnly; 00428 bool mFloating; 00429 00430 TQValueList<int> mBySeconds; // values: second 0-59 00431 TQValueList<int> mByMinutes; // values: minute 0-59 00432 TQValueList<int> mByHours; // values: hour 0-23 00433 00434 TQValueList<WDayPos> mByDays; // n-th weekday of the month or year 00435 TQValueList<int> mByMonthDays; // values: day -31 to -1 and 1-31 00436 TQValueList<int> mByYearDays; // values: day -366 to -1 and 1-366 00437 TQValueList<int> mByWeekNumbers; // values: week -53 to -1 and 1-53 00438 TQValueList<int> mByMonths; // values: month 1-12 00439 TQValueList<int> mBySetPos; // values: position -366 to -1 and 1-366 00440 short mWeekStart; // first day of the week (1=Monday, 7=Sunday) 00441 00442 Constraint::List mConstraints; 00443 void buildConstraints(); 00444 bool mDirty; 00445 TQValueList<Observer*> mObservers; 00446 00447 // Cache for duration 00448 mutable DateTimeList mCachedDates; 00449 mutable TQDateTime mCachedDateEnd; 00450 mutable TQDateTime mCachedLastDate; // when mCachedDateEnd invalid, last date checked 00451 mutable bool mCached; 00452 00453 bool mNoByRules; // no BySeconds, ByMinutes, ... rules exist 00454 uint mTimedRepetition; // repeats at a regular number of seconds interval, or 0 00455 00456 class Private; 00457 Private *d; 00458 }; 00459 00460 } 00461 00462 #endif