libkcal

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 <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   // Remove all duplicates from the times list
00038   // TODO: Make this more efficient!
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( QValueList<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 Q_INLINE_TEMPLATES int findGT( QValueList<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 Q_INLINE_TEMPLATES int findSorted( QValueList<T> &lst, const T &value, int start )
00091 {
00092   // Do a binary search to find the 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 && value == lst[st] ) ? st : -1;
00104 }
00105 
00106 template <class T>
00107 Q_INLINE_TEMPLATES int removeSorted( QValueList<T> &lst, const T &value, int start )
00108 {
00109   int i = findSorted( lst, value, start );
00110   if ( i >= 0 ) {
00111     lst.remove( lst.at( i ) );
00112   }
00113   return i;
00114 }
00115 
00116 namespace KCal {
00117 
00118 typedef QValueList<QDateTime> DateTimeList;
00119 typedef QValueList<QDate> DateList;
00120 typedef QValueList<QTime> TimeList;
00121 
00122 
00123 
00124 
00128 class LIBKCAL_EXPORT RecurrenceRule
00129 {
00130   public:
00131     class Observer {
00132       public:
00133         virtual ~Observer() {}
00135         virtual void recurrenceChanged( RecurrenceRule * ) = 0;
00136     };
00137     typedef ListBase<RecurrenceRule> List;
00139     enum PeriodType { rNone = 0,
00140            rSecondly, rMinutely, rHourly,
00141            rDaily, rWeekly, rMonthly, rYearly
00142          };
00144     class WDayPos {
00145     public:
00146       WDayPos( int ps = 0 , short dy = 0 ) : mDay(dy), mPos(ps) {}
00147       short day() const { return mDay; }
00148       int pos() const { return mPos; }
00149       void setDay( short dy ) { mDay = dy; }
00150       void setPos( int ps ) { mPos = ps; }
00151 
00152       bool operator==( const RecurrenceRule::WDayPos &pos2 ) const {
00153           return ( mDay == pos2.mDay ) && ( mPos == pos2.mPos );
00154         }
00155     protected:
00156       short mDay;  // Weekday, 1=monday, 7=sunday
00157       int mPos;    // week of the day (-1 for last, 1 for first, 0 for all weeks)
00158                    // Bounded by -366 and +366, 0 means all weeks in that period
00159     };
00160 
00161     RecurrenceRule( /*Incidence *parent, int compatVersion = 0*/ );
00162     RecurrenceRule(const RecurrenceRule&);
00163     ~RecurrenceRule();
00164 
00165     bool operator==( const RecurrenceRule& ) const;
00166     bool operator!=( const RecurrenceRule& r ) const  { return !operator==(r); }
00167     RecurrenceRule &operator=(const RecurrenceRule&);
00168 
00169 //     Incidence *parent() const { return mParent; }
00170 
00171 
00173     void setReadOnly(bool readOnly) { mIsReadOnly = readOnly; }
00175     bool isReadOnly() const  { return mIsReadOnly; }
00176 
00177 
00180     bool doesRecur() const { return mPeriod!=rNone; }
00181     void setRecurrenceType( PeriodType period );
00182     PeriodType recurrenceType() const { return mPeriod; }
00184     void clear();
00185 
00186 
00188     uint frequency() const { return mFrequency; }
00190     void setFrequency( int freq );
00191 
00192 
00194     QDateTime startDt() const   { return mDateStart; }
00196     void setStartDt(const QDateTime &start);
00197 
00200     bool doesFloat() const { return mFloating; }
00202     void setFloats( bool floats );
00203 
00204 
00210     QDateTime endDt( bool* result = 0 ) const;
00213     void setEndDt(const QDateTime &endDateTime);
00214 
00215 
00220     int duration() const { return mDuration; }
00223     void setDuration(int duration);
00224 //     /** Returns the number of recurrences up to and including the date specified. */
00225 //     int durationTo(const QDate &) const;
00227     int durationTo(const QDateTime &) const;
00229     int durationTo( const QDate &date ) const { return durationTo( QDateTime( date, QTime( 23, 59, 59 ) ) ); }
00230 
00231 
00232 
00235     bool recursOn( const QDate &qd ) const;
00239     bool recursAt( const QDateTime & ) const;
00244     bool dateMatchesRules( const QDateTime &qdt ) const;
00245 
00246 
00251     TimeList recurTimesOn( const QDate &date ) const;
00252 
00264     DateTimeList timesInInterval( const QDateTime &start, const QDateTime &end ) const;
00265 
00271     QDateTime getNextDate( const QDateTime& preDateTime ) const;
00278     QDateTime getPreviousDate( const QDateTime& afterDateTime ) const;
00279 
00280 
00281 
00282 
00283     void setBySeconds( const QValueList<int> bySeconds );
00284     void setByMinutes( const QValueList<int> byMinutes );
00285     void setByHours( const QValueList<int> byHours );
00286 
00287     void setByDays( const QValueList<WDayPos> byDays );
00288     void setByMonthDays( const QValueList<int> byMonthDays );
00289     void setByYearDays( const QValueList<int> byYearDays );
00290     void setByWeekNumbers( const QValueList<int> byWeekNumbers );
00291     void setByMonths( const QValueList<int> byMonths );
00292     void setBySetPos( const QValueList<int> bySetPos );
00293     void setWeekStart( short weekStart );
00294 
00295     const QValueList<int> &bySeconds() const { return mBySeconds; }
00296     const QValueList<int> &byMinutes() const { return mByMinutes; }
00297     const QValueList<int> &byHours() const { return mByHours; }
00298 
00299     const QValueList<WDayPos> &byDays() const { return mByDays; }
00300     const QValueList<int> &byMonthDays() const { return mByMonthDays; }
00301     const QValueList<int> &byYearDays() const { return mByYearDays; }
00302     const QValueList<int> &byWeekNumbers() const { return mByWeekNumbers; }
00303     const QValueList<int> &byMonths() const { return mByMonths; }
00304     const QValueList<int> &bySetPos() const { return mBySetPos; }
00305     short weekStart() const { return mWeekStart; }
00306 
00307 
00308     void setDirty();
00316     void addObserver( Observer *observer );
00323     void removeObserver( Observer *observer );
00324 
00328     void dump() const;
00329     QString mRRule;
00330 
00331   private:
00332     class Constraint {
00333       public:
00334         typedef QValueList<Constraint> List;
00335 
00336         Constraint( int wkst = 1 );
00337 /*         Constraint( const Constraint &con ) :
00338                      year(con.year), month(con.month), day(con.day),
00339                      hour(con.hour), minute(con.minute), second(con.second),
00340                      weekday(con.weekday), weeknumber(con.weeknumber),
00341                      yearday(con.yearday), weekstart(con.weekstart) {}*/
00342         Constraint( const QDateTime &preDate, PeriodType type, int wkst );
00343         void clear();
00344 
00345         int year;       // 0 means unspecified
00346         int month;      // 0 means unspecified
00347         int day;        // 0 means unspecified
00348         int hour;       // -1 means unspecified
00349         int minute;     // -1 means unspecified
00350         int second;     // -1 means unspecified
00351         int weekday;    //  0 means unspecified
00352         int weekdaynr;  // index of weekday in month/year (0=unspecified)
00353         int weeknumber; //  0 means unspecified
00354         int yearday;    //  0 means unspecified
00355         int weekstart;  //  first day of week (1=monday, 7=sunday, 0=unspec.)
00356 
00357         bool readDateTime( const QDateTime &preDate, PeriodType type );
00358         bool matches( const QDate &dt, RecurrenceRule::PeriodType type ) const;
00359         bool matches( const QDateTime &dt, RecurrenceRule::PeriodType type ) const;
00360         bool isConsistent() const;
00361         bool isConsistent( PeriodType period ) const;
00362         bool increase( PeriodType type, int freq );
00363         QDateTime intervalDateTime( PeriodType type ) const;
00364         DateTimeList dateTimes( PeriodType type ) const;
00365         void dump() const;
00366     };
00367 
00368     Constraint getNextValidDateInterval( const QDateTime &preDate, PeriodType type ) const;
00369     Constraint getPreviousValidDateInterval( const QDateTime &preDate, PeriodType type ) const;
00370     DateTimeList datesForInterval( const Constraint &interval, PeriodType type ) const;
00371     bool mergeIntervalConstraint( Constraint *merged, const Constraint &conit,
00372                                   const Constraint &interval ) const;
00373     bool buildCache() const;
00374 
00375 
00376     PeriodType mPeriod;
00377     QDateTime mDateStart;
00382     int mDuration;
00383     QDateTime mDateEnd;
00384     uint mFrequency;
00385 
00386     bool mIsReadOnly;
00387     bool mFloating;
00388 
00389     QValueList<int> mBySeconds;     // values: second 0-59
00390     QValueList<int> mByMinutes;     // values: minute 0-59
00391     QValueList<int> mByHours;       // values: hour 0-23
00392 
00393     QValueList<WDayPos> mByDays;   // n-th weekday of the month or year
00394     QValueList<int> mByMonthDays;   // values: day -31 to -1 and 1-31
00395     QValueList<int> mByYearDays;    // values: day -366 to -1 and 1-366
00396     QValueList<int> mByWeekNumbers; // values: week -53 to -1 and 1-53
00397     QValueList<int> mByMonths;      // values: month 1-12
00398     QValueList<int> mBySetPos;      // values: position -366 to -1 and 1-366
00399     short mWeekStart;               // first day of the week (1=Monday, 7=Sunday)
00400 
00401     Constraint::List mConstraints;
00402     void buildConstraints();
00403     bool mDirty;
00404     QValueList<Observer*> mObservers;
00405 
00406     // Cache for duration
00407     mutable DateTimeList mCachedDates;
00408     mutable QDateTime mCachedDateEnd;
00409     mutable QDateTime mCachedLastDate;   // when mCachedDateEnd invalid, last date checked
00410     mutable bool mCached;
00411 
00412     bool mNoByRules;        // no BySeconds, ByMinutes, ... rules exist
00413     uint mTimedRepetition;  // repeats at a regular number of seconds interval, or 0
00414 
00415     class Private;
00416     Private *d;
00417 };
00418 
00419 }
00420 
00421 #endif
KDE Home | KDE Accessibility Home | Description of Access Keys