libkcal

recurrencerule.h

Go to the documentation of this file.
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 
00054 namespace KCal {
00055 
00056 typedef QValueList<QDateTime> DateTimeList;
00057 typedef QValueList<QDate> DateList;
00058 typedef QValueList<QTime> TimeList;
00059 
00060 
00061 
00062 
00066 class LIBKCAL_EXPORT RecurrenceRule
00067 {
00068   public:
00069     class Observer {
00070       public:
00071         virtual ~Observer() {}
00073         virtual void recurrenceChanged( RecurrenceRule * ) = 0;
00074     };
00075     typedef ListBase<RecurrenceRule> List;
00077     enum PeriodType { rNone = 0,
00078            rSecondly, rMinutely, rHourly,
00079            rDaily, rWeekly, rMonthly, rYearly
00080          };
00082     class WDayPos {
00083     public:
00084       WDayPos( int ps = 0 , short dy = 0 ) : mDay(dy), mPos(ps) {}
00085       short day() const { return mDay; }
00086       int pos() const { return mPos; }
00087       void setDay( short dy ) { mDay = dy; }
00088       void setPos( int ps ) { mPos = ps; }
00089 
00090       bool operator==( const RecurrenceRule::WDayPos &pos2 ) const {
00091           return ( mDay == pos2.mDay ) && ( mPos == pos2.mPos );
00092         }
00093     protected:
00094       short mDay;  // Weekday, 1=monday, 7=sunday
00095       int mPos;    // week of the day (-1 for last, 1 for first, 0 for all weeks)
00096                    // Bounded by -366 and +366, 0 means all weeks in that period
00097     };
00098 
00099     RecurrenceRule( /*Incidence *parent, int compatVersion = 0*/ );
00100     RecurrenceRule(const RecurrenceRule&);
00101     ~RecurrenceRule();
00102 
00103     bool operator==( const RecurrenceRule& ) const;
00104     bool operator!=( const RecurrenceRule& r ) const  { return !operator==(r); }
00105     RecurrenceRule &operator=(const RecurrenceRule&);
00106 
00107 //     Incidence *parent() const { return mParent; }
00108 
00109 
00111     void setReadOnly(bool readOnly) { mIsReadOnly = readOnly; }
00113     bool isReadOnly() const  { return mIsReadOnly; }
00114 
00115 
00118     bool doesRecur() const { return mPeriod!=rNone; }
00119     void setRecurrenceType( PeriodType period );
00120     PeriodType recurrenceType() const { return mPeriod; }
00122     void clear();
00123 
00124 
00126     uint frequency() const { return mFrequency; }
00128     void setFrequency( int freq );
00129 
00130 
00132     QDateTime startDt() const   { return mDateStart; }
00134     void setStartDt(const QDateTime &start);
00135 
00138     bool doesFloat() const { return mFloating; }
00140     void setFloats( bool floats );
00141 
00142 
00148     QDateTime endDt( bool* result = 0 ) const;
00151     void setEndDt(const QDateTime &endDateTime);
00152 
00153 
00158     int duration() const { return mDuration; }
00161     void setDuration(int duration);
00162 //     /** Returns the number of recurrences up to and including the date specified. */
00163 //     int durationTo(const QDate &) const;
00165     int durationTo(const QDateTime &) const;
00167     int durationTo( const QDate &date ) const { return durationTo( QDateTime( date, QTime( 23, 59, 59 ) ) ); }
00168 
00169 
00170 
00173     bool recursOn( const QDate &qd ) const;
00177     bool recursAt( const QDateTime & ) const;
00182     bool dateMatchesRules( const QDateTime &qdt ) const;
00183 
00184 
00189     TimeList recurTimesOn( const QDate &date ) const;
00190 
00191 
00197     QDateTime getNextDate( const QDateTime& preDateTime ) const;
00204     QDateTime getPreviousDate( const QDateTime& afterDateTime ) const;
00205 
00206 
00207 
00208 
00209     void setBySeconds( const QValueList<int> bySeconds );
00210     void setByMinutes( const QValueList<int> byMinutes );
00211     void setByHours( const QValueList<int> byHours );
00212 
00213     void setByDays( const QValueList<WDayPos> byDays );
00214     void setByMonthDays( const QValueList<int> byMonthDays );
00215     void setByYearDays( const QValueList<int> byYearDays );
00216     void setByWeekNumbers( const QValueList<int> byWeekNumbers );
00217     void setByMonths( const QValueList<int> byMonths );
00218     void setBySetPos( const QValueList<int> bySetPos );
00219     void setWeekStart( short weekStart );
00220 
00221     const QValueList<int> &bySeconds() const { return mBySeconds; }
00222     const QValueList<int> &byMinutes() const { return mByMinutes; }
00223     const QValueList<int> &byHours() const { return mByHours; }
00224 
00225     const QValueList<WDayPos> &byDays() const { return mByDays; }
00226     const QValueList<int> &byMonthDays() const { return mByMonthDays; }
00227     const QValueList<int> &byYearDays() const { return mByYearDays; }
00228     const QValueList<int> &byWeekNumbers() const { return mByWeekNumbers; }
00229     const QValueList<int> &byMonths() const { return mByMonths; }
00230     const QValueList<int> &bySetPos() const { return mBySetPos; }
00231     short weekStart() const { return mWeekStart; }
00232 
00233 
00234     void setDirty();
00242     void addObserver( Observer *observer );
00249     void removeObserver( Observer *observer );
00250 
00254     void dump() const;
00255     QString mRRule;
00256 
00257   private:
00258     class Constraint {
00259       public:
00260         typedef QValueList<Constraint> List;
00261 
00262         Constraint( int wkst = 1 );
00263 /*         Constraint( const Constraint &con ) :
00264                      year(con.year), month(con.month), day(con.day),
00265                      hour(con.hour), minute(con.minute), second(con.second),
00266                      weekday(con.weekday), weeknumber(con.weeknumber),
00267                      yearday(con.yearday), weekstart(con.weekstart) {}*/
00268         Constraint( const QDateTime &preDate, PeriodType type, int wkst );
00269         void clear();
00270 
00271         int year;       // 0 means unspecified
00272         int month;      // 0 means unspecified
00273         int day;        // 0 means unspecified
00274         int hour;       // -1 means unspecified
00275         int minute;     // -1 means unspecified
00276         int second;     // -1 means unspecified
00277         int weekday;    //  0 means unspecified
00278         int weekdaynr;  // index of weekday in month/year (0=unspecified)
00279         int weeknumber; //  0 means unspecified
00280         int yearday;    //  0 means unspecified
00281         int weekstart;  //  first day of week (1=monday, 7=sunday, 0=unspec.)
00282 
00283         bool readDateTime( const QDateTime &preDate, PeriodType type );
00284         bool matches( const QDate &dt, RecurrenceRule::PeriodType type ) const;
00285         bool matches( const QDateTime &dt, RecurrenceRule::PeriodType type ) const;
00286         bool isConsistent() const;
00287         bool isConsistent( PeriodType period ) const;
00288         bool increase( PeriodType type, int freq );
00289         QDateTime intervalDateTime( PeriodType type ) const;
00290         DateTimeList dateTimes( PeriodType type ) const;
00291         void dump() const;
00292     };
00293 
00294     Constraint getNextValidDateInterval( const QDateTime &preDate, PeriodType type ) const;
00295     Constraint getPreviousValidDateInterval( const QDateTime &preDate, PeriodType type ) const;
00296     DateTimeList datesForInterval( const Constraint &interval, PeriodType type ) const;
00297     bool mergeIntervalConstraint( Constraint *merged, const Constraint &conit,
00298                                   const Constraint &interval ) const;
00299     bool buildCache() const;
00300 
00301 
00302     PeriodType mPeriod;
00303     QDateTime mDateStart;
00308     int mDuration;
00309     QDateTime mDateEnd;
00310     uint mFrequency;
00311 
00312     bool mIsReadOnly;
00313     bool mFloating;
00314 
00315     QValueList<int> mBySeconds;     // values: second 0-59
00316     QValueList<int> mByMinutes;     // values: minute 0-59
00317     QValueList<int> mByHours;       // values: hour 0-23
00318 
00319     QValueList<WDayPos> mByDays;   // n-th weekday of the month or year
00320     QValueList<int> mByMonthDays;   // values: day -31 to -1 and 1-31
00321     QValueList<int> mByYearDays;    // values: day -366 to -1 and 1-366
00322     QValueList<int> mByWeekNumbers; // values: week -53 to -1 and 1-53
00323     QValueList<int> mByMonths;      // values: month 1-12
00324     QValueList<int> mBySetPos;      // values: position -366 to -1 and 1-366
00325     short mWeekStart;               // first day of the week (1=Monday, 7=Sunday)
00326 
00327     Constraint::List mConstraints;
00328     void buildConstraints();
00329     bool mDirty;
00330     QValueList<Observer*> mObservers;
00331 
00332     // Cache for duration
00333     mutable DateTimeList mCachedDates;
00334     mutable bool mCached;
00335     mutable QDateTime mCachedDateEnd;
00336 
00337     class Private;
00338     Private *d;
00339 };
00340 
00341 }
00342 
00343 #endif