00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef KCAL_RECURRENCERULE_H
00025 #define KCAL_RECURRENCERULE_H
00026
00027 #include <qdatetime.h>
00028 #include <libkcal/listbase.h>
00029
00030 #include "libkcal_export.h"
00031
00032 template <class T>
00033 Q_INLINE_TEMPLATES void qSortUnique( QValueList<T> &lst )
00034 {
00035 qHeapSort( lst );
00036 if ( lst.isEmpty() ) return;
00037
00038
00039 QValueListIterator<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 Q_INLINE_TEMPLATES int findGE( const QValueList<T> &lst, const T &value, int start )
00055 {
00056
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 Q_INLINE_TEMPLATES int findGT( const QValueList<T> &lst, const T &value, int start )
00073 {
00074
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 Q_INLINE_TEMPLATES int findLE( const QValueList<T> &lst, const T &value, int start )
00091 {
00092
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 Q_INLINE_TEMPLATES int findLT( const QValueList<T> &lst, const T &value, int start )
00108 {
00109
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 Q_INLINE_TEMPLATES int findSorted( const QValueList<T> &lst, const T &value, int start )
00125 {
00126
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 Q_INLINE_TEMPLATES int removeSorted( QValueList<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 Q_INLINE_TEMPLATES bool containsSorted( const QValueList<T> &lst, const T &value )
00152 {
00153 return findSorted( lst, value, 0 ) >= 0;
00154 }
00155
00156
00157 namespace KCal {
00158
00159 typedef QValueList<QDateTime> DateTimeList;
00160 typedef QValueList<QDate> DateList;
00161 typedef QValueList<QTime> 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;
00198 int mPos;
00199
00200 };
00201
00202 RecurrenceRule( );
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
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 QDateTime startDt() const { return mDateStart; }
00237 void setStartDt(const QDateTime &start);
00238
00241 bool doesFloat() const { return mFloating; }
00243 void setFloats( bool floats );
00244
00245
00251 QDateTime endDt( bool* result = 0 ) const;
00254 void setEndDt(const QDateTime &endDateTime);
00255
00256
00261 int duration() const { return mDuration; }
00264 void setDuration(int duration);
00265
00266
00268 int durationTo(const QDateTime &) const;
00270 int durationTo( const QDate &date ) const { return durationTo( QDateTime( date, QTime( 23, 59, 59 ) ) ); }
00271
00272
00273
00276 bool recursOn( const QDate &qd ) const;
00280 bool recursAt( const QDateTime & ) const;
00285 bool dateMatchesRules( const QDateTime &qdt ) const;
00286
00287
00292 TimeList recurTimesOn( const QDate &date ) const;
00293
00305 DateTimeList timesInInterval( const QDateTime &start, const QDateTime &end ) const;
00306
00312 QDateTime getNextDate( const QDateTime& preDateTime ) const;
00319 QDateTime getPreviousDate( const QDateTime& afterDateTime ) const;
00320
00321
00322
00323
00324 void setBySeconds( const QValueList<int> bySeconds );
00325 void setByMinutes( const QValueList<int> byMinutes );
00326 void setByHours( const QValueList<int> byHours );
00327
00328 void setByDays( const QValueList<WDayPos> byDays );
00329 void setByMonthDays( const QValueList<int> byMonthDays );
00330 void setByYearDays( const QValueList<int> byYearDays );
00331 void setByWeekNumbers( const QValueList<int> byWeekNumbers );
00332 void setByMonths( const QValueList<int> byMonths );
00333 void setBySetPos( const QValueList<int> bySetPos );
00334 void setWeekStart( short weekStart );
00335
00336 const QValueList<int> &bySeconds() const { return mBySeconds; }
00337 const QValueList<int> &byMinutes() const { return mByMinutes; }
00338 const QValueList<int> &byHours() const { return mByHours; }
00339
00340 const QValueList<WDayPos> &byDays() const { return mByDays; }
00341 const QValueList<int> &byMonthDays() const { return mByMonthDays; }
00342 const QValueList<int> &byYearDays() const { return mByYearDays; }
00343 const QValueList<int> &byWeekNumbers() const { return mByWeekNumbers; }
00344 const QValueList<int> &byMonths() const { return mByMonths; }
00345 const QValueList<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 QString mRRule;
00371
00372 private:
00373 class Constraint {
00374 public:
00375 typedef QValueList<Constraint> List;
00376
00377 Constraint( int wkst = 1 );
00378
00379
00380
00381
00382
00383 Constraint( const QDateTime &preDate, PeriodType type, int wkst );
00384 void clear();
00385
00386 int year;
00387 int month;
00388 int day;
00389 int hour;
00390 int minute;
00391 int second;
00392 int weekday;
00393 int weekdaynr;
00394 int weeknumber;
00395 int yearday;
00396 int weekstart;
00397
00398 bool readDateTime( const QDateTime &preDate, PeriodType type );
00399 bool matches( const QDate &dt, RecurrenceRule::PeriodType type ) const;
00400 bool matches( const QDateTime &dt, RecurrenceRule::PeriodType type ) const;
00401 bool isConsistent() const;
00402 bool isConsistent( PeriodType period ) const;
00403 bool increase( PeriodType type, int freq );
00404 QDateTime intervalDateTime( PeriodType type ) const;
00405 DateTimeList dateTimes( PeriodType type ) const;
00406 void dump() const;
00407 };
00408
00409 Constraint getNextValidDateInterval( const QDateTime &preDate, PeriodType type ) const;
00410 Constraint getPreviousValidDateInterval( const QDateTime &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 QDateTime mDateStart;
00423 int mDuration;
00424 QDateTime mDateEnd;
00425 uint mFrequency;
00426
00427 bool mIsReadOnly;
00428 bool mFloating;
00429
00430 QValueList<int> mBySeconds;
00431 QValueList<int> mByMinutes;
00432 QValueList<int> mByHours;
00433
00434 QValueList<WDayPos> mByDays;
00435 QValueList<int> mByMonthDays;
00436 QValueList<int> mByYearDays;
00437 QValueList<int> mByWeekNumbers;
00438 QValueList<int> mByMonths;
00439 QValueList<int> mBySetPos;
00440 short mWeekStart;
00441
00442 Constraint::List mConstraints;
00443 void buildConstraints();
00444 bool mDirty;
00445 QValueList<Observer*> mObservers;
00446
00447
00448 mutable DateTimeList mCachedDates;
00449 mutable QDateTime mCachedDateEnd;
00450 mutable QDateTime mCachedLastDate;
00451 mutable bool mCached;
00452
00453 bool mNoByRules;
00454 uint mTimedRepetition;
00455
00456 class Private;
00457 Private *d;
00458 };
00459
00460 }
00461
00462 #endif