summaryrefslogtreecommitdiffstats
path: root/libkcal/recurrence.h
diff options
context:
space:
mode:
Diffstat (limited to 'libkcal/recurrence.h')
-rw-r--r--libkcal/recurrence.h513
1 files changed, 513 insertions, 0 deletions
diff --git a/libkcal/recurrence.h b/libkcal/recurrence.h
new file mode 100644
index 000000000..773a9d635
--- /dev/null
+++ b/libkcal/recurrence.h
@@ -0,0 +1,513 @@
+/*
+ This file is part of libkcal.
+
+ Copyright (c) 1998 Preston Brown <pbrown@kde.org>
+ Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (c) 2002 David Jarvie <software@astrojar.org.uk>
+ Copyright (C) 2005 Reinhold Kainhofer <reinhold@kainhofer.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#ifndef KCAL_RECURRENCE_H
+#define KCAL_RECURRENCE_H
+
+#include <qstring.h>
+#include <qbitarray.h>
+#include <qptrlist.h>
+
+#include "libkcal_export.h"
+#include "recurrencerule.h"
+
+namespace KCal {
+
+class RecurrenceRule;
+
+/**
+ This class represents a recurrence rule for a calendar incidence.
+
+ It manages all recurrence rules, recurrence date/times, exception rules
+ and exception date times that can appear inside calendar items.
+ Each recurrence rule and exception rule is represented as an object
+ of type RecurrenceRule.
+
+ For the simple case where at most one recurrence
+ rule is present, this class provides shortcut methods to set the type:
+ setMinutely()
+ setHourly()
+ setDaily()
+ setWeekly()
+ setMonthly()
+ setYearly()
+ to set/get general information about the recurrence:
+ setEndDate()
+ setEndDateTime()
+ duration()
+ durationTo()
+ setDuration()
+ frequency()
+ setFrequency()
+ and to set/get specific information about the recurrence within the interval:
+ days()
+ monthDays()
+ monthPositions()
+ yearDays()
+ yearDates()
+ yearMonths()
+ yearPositions()
+ addMonthlyPos()
+ addMonthlyDate()
+ addYearlyDay()
+ addYearlyDate()
+ addYearlyPos()
+ addYearlyMonth()
+ These are all available so that you don't have to work on the RecurrenceRule
+ objects themselves.
+ In other words, in that simple situation the interface stays almost the
+ same compared to the old Recurrence class, which allowed only one
+ recurrence rule.
+
+ As soon as your recurrence consists of multiple recurrence rules or exception
+ rules, you cannot use the methods mentioned above any more (since each rule
+ will have a different type and different settings). If you still call
+ any of them, the set*ly methods will remove all rules and add one rule with
+ the specified type. The add* and the other set* methods will change only
+ the first recurrence rule, but leave the others untouched.
+*/
+class LIBKCAL_EXPORT Recurrence : public RecurrenceRule::Observer
+{
+ public:
+ class Observer {
+ public:
+ virtual ~Observer() {}
+ /** This method will be called on each change of the recurrence object */
+ virtual void recurrenceUpdated( Recurrence * ) = 0;
+ };
+
+ /** enumeration for describing how an event recurs, if at all. */
+ enum { rNone = 0, rMinutely = 0x001, rHourly = 0x0002, rDaily = 0x0003,
+ rWeekly = 0x0004, rMonthlyPos = 0x0005, rMonthlyDay = 0x0006,
+ rYearlyMonth = 0x0007, rYearlyDay = 0x0008, rYearlyPos = 0x0009,
+ rOther = 0x000A, rMax=0x00FF };
+
+ Recurrence();
+ Recurrence( const Recurrence& );
+ virtual ~Recurrence();
+
+ bool operator==( const Recurrence& ) const;
+ bool operator!=( const Recurrence& r ) const { return !operator==(r); }
+
+ /** Return the start date/time of the recurrence (Time for floating incidences will be 0:00).
+ @return the current start/time of the recurrence. */
+ QDateTime startDateTime() const;
+ /** Return the start date/time of the recurrence */
+ QDate startDate() const { return mStartDateTime.date(); }
+ /** Set start of recurrence, as a date and time. Also sets the incidence to non-floating.
+ @param start the new start date/time of the incidence.
+ */
+ void setStartDateTime( const QDateTime &start );
+ /** Set start of recurrence, as a date. Also sets the incidence to floating.
+ @param start The new start date of the incidence.
+ */
+ void setStartDate( const QDate &start );
+
+ /** Set whether the recurrence has no time, just a date.
+ * Floating means -- according to rfc2445 -- that the event has no time
+ * associated.
+ * N.B. This property is derived by default from whether setStartDateTime() or
+ * setStartDate() is called.
+ * @return whether the recurrence has a time (false) or it is just a date (true). */
+ bool doesFloat() const { return mFloating; }
+ /** Sets whether the dtstart is a floating time (i.e. has no time attached)
+ @param floats If the recurrence is for all-day item (true) or has a time associated (false).
+ */
+ void setFloats( bool floats );
+
+ /** Set if recurrence is read-only or can be changed. */
+ void setRecurReadOnly(bool readOnly) { mRecurReadOnly = readOnly; }
+ /** Returns true if the recurrence is read-only, or false if it can be changed. */
+ bool recurReadOnly() const { return mRecurReadOnly; }
+
+ /** Returns whether the event recurs at all. */
+ bool doesRecur() const;
+ /** Returns the event's recurrence status. See the enumeration at the top
+ * of this file for possible values. */
+ ushort recurrenceType() const;
+ /** Returns the recurrence status for a recurrence rule.
+ * See the enumeration at the top of this file for possible values. */
+ static ushort recurrenceType( const RecurrenceRule *rrule );
+ /** Returns true if the date specified is one on which the event will
+ * recur. */
+ bool recursOn( const QDate &qd ) const;
+ /** Returns true if the date/time specified is one at which the event will
+ * recur. Times are rounded down to the nearest minute to determine the result. */
+ bool recursAt( const QDateTime & ) const;
+ /** Removes all recurrence rules. Recurrence dates and exceptions are
+ not removed. */
+ void unsetRecurs();
+ /** Removes all recurrence and exception rules and dates. */
+ void clear();
+
+ /** Returns a list of the times on the specified date at which the
+ * recurrence will occur.
+ * @param date the date for which to find the recurrence times.
+ */
+ QValueList<QTime> recurTimesOn(const QDate &date) const;
+
+ /** Returns the date and time of the next recurrence, after the specified date/time.
+ * If the recurrence has no time, the next date after the specified date is returned.
+ * @param preDateTime the date/time after which to find the recurrence.
+ * @return date/time of next recurrence (strictly later than the given QDateTiem), or invalid date if none.
+ */
+ QDateTime getNextDateTime( const QDateTime& preDateTime ) const;
+ /** Returns the date and time of the last previous recurrence, before the specified date/time.
+ * If a time later than 00:00:00 is specified and the recurrence has no time, 00:00:00 on
+ * the specified date is returned if that date recurs.
+ * @param afterDateTime the date/time before which to find the recurrence.
+ * @return date/time of previous recurrence (strictly earlier than the given QDateTime), or invalid date if none.
+ */
+ QDateTime getPreviousDateTime( const QDateTime& afterDateTime ) const;
+
+ /** Returns frequency of recurrence, in terms of the recurrence time period type. */
+ int frequency() const;
+ /** Sets the frequency of recurrence, in terms of the recurrence time period type. */
+ void setFrequency(int freq);
+
+ /**
+ * Returns -1 if the event recurs infinitely, 0 if the end date is set,
+ * otherwise the total number of recurrences, including the initial occurrence.
+ */
+ int duration() const;
+ /** Sets the total number of times the event is to occur, including both the
+ * first and last. */
+ void setDuration(int duration);
+ /** Returns the number of recurrences up to and including the date/time specified. */
+ int durationTo(const QDateTime &) const;
+ /** Returns the number of recurrences up to and including the date specified. */
+ int durationTo( const QDate &date ) const { return durationTo( QDateTime( date, QTime( 23, 59, 59 ) ) ); }
+
+ /** Returns the date/time of the last recurrence.
+ * An invalid date is returned if the recurrence has no end.
+ */
+ QDateTime endDateTime() const;
+ /** Returns the date of the last recurrence.
+ * An invalid date is returned if the recurrence has no end.
+ */
+ QDate endDate() const;
+ /** Sets the date of the last recurrence. The end time is set to the recurrence start time.
+ * @param endDate the ending date after which to stop recurring. If the
+ * incidence is not floating, the end time will be 23:59.*/
+ void setEndDate( const QDate &endDate );
+ /** Sets the date and time of the last recurrence.
+ * @param endDateTime the ending date/time after which to stop recurring. */
+ void setEndDateTime( const QDateTime &endDateTime );
+
+
+
+ /** Sets an event to recur minutely. By default infinite recurrence is used.
+ To set an end date use the method setEndDate and to set the number
+ of occurrences use setDuration.
+
+ This method clears all recurrence rules and adds one rule with a
+ minutely recurrence. All other recurrence components (recurrence
+ date/times, exception date/times and exception rules) are not
+ modified.
+ * @param freq the frequency to recur, e.g. 2 is every other minute
+ */
+ void setMinutely( int freq );
+
+ /** Sets an event to recur hourly. By default infinite recurrence is used.
+ The minute of the recurrence is taken from the start date (if you
+ need to change it, you will have to modify the defaultRRule's
+ byMinute list manually.
+ To set an end date use the method setEndDate and to set the number
+ of occurrences use setDuration.
+
+ This method clears all recurrence rules and adds one rule with a
+ hourly recurrence. All other recurrence components (recurrence
+ date/times, exception date/times and exception rules) are not
+ modified.
+ * @param freq the frequency to recur, e.g. 2 is every other hour
+ */
+ void setHourly( int freq );
+
+ /** Sets an event to recur daily. By default infinite recurrence is used.
+ The minute and second of the recurrence is taken from the start date
+ (if you need to change them, you will have to modify the defaultRRule's
+ byMinute list manually.
+ To set an end date use the method setEndDate and to set the number
+ of occurrences use setDuration.
+
+ This method clears all recurrence rules and adds one rule with a
+ daily recurrence. All other recurrence components (recurrence
+ date/times, exception date/times and exception rules) are not
+ modified.
+ * @param freq the frequency to recur, e.g. 2 is every other day
+ */
+ void setDaily( int freq );
+
+ /** Sets an event to recur weekly. By default infinite recurrence is used.
+ To set an end date use the method setEndDate and to set the number
+ of occurrences use setDuration.
+
+ This method clears all recurrence rules and adds one rule with a
+ weekly recurrence. All other recurrence components (recurrence
+ date/times, exception date/times and exception rules) are not
+ modified.
+ * @param freq the frequency to recur, e.g. every other week etc.
+ * @param weekStart the first day of the week (Monday=1 .. Sunday=7, default is Monday).
+ */
+ void setWeekly( int freq, int weekStart = 1 );
+ /** Sets an event to recur weekly. By default infinite recurrence is used.
+ To set an end date use the method setEndDate and to set the number
+ of occurrences use setDuration.
+
+ This method clears all recurrence rules and adds one rule with a
+ weekly recurrence. All other recurrence components (recurrence
+ date/times, exception date/times and exception rules) are not
+ modified.
+ * @param freq the frequency to recur, e.g. every other week etc.
+ * @param days a 7 bit array indicating which days on which to recur (bit 0 = Monday).
+ * @param weekStart the first day of the week (Monday=1 .. Sunday=7, default is Monday).
+ */
+ void setWeekly( int freq, const QBitArray &days, int weekStart = 1 );
+ /** Adds days to the weekly day recurrence list.
+ * @param days a 7 bit array indicating which days on which to recur (bit 0 = Monday).
+ */
+ void addWeeklyDays( const QBitArray &days );
+ /** Returns the first day of the week. Uses only the
+ * first RRULE if present (i.e. a second RRULE as well as all EXRULES are
+ * ignored!
+ * @return Weekday of the first day of the week (Monday=1 .. Sunday=7)
+ */
+ int weekStart() const;
+ /** Returns week day mask (bit 0 = Monday). */
+ QBitArray days() const; // Emulate the old behavior
+
+ /** Sets an event to recur monthly. By default infinite recurrence is used.
+ The date of the monthly recurrence will be taken from the start date
+ unless you explicitly add one or more recurrence dates with
+ addMonthlyDate or a recurrence position in the month (e.g. first
+ monday) using addMonthlyPos.
+ To set an end date use the method setEndDate and to set the number
+ of occurrences use setDuration.
+
+ This method clears all recurrence rules and adds one rule with a
+ monthly recurrence. All other recurrence components (recurrence
+ date/times, exception date/times and exception rules) are not
+ modified.
+ * @param freq the frequency to recur, e.g. 3 for every third month.
+ */
+ void setMonthly( int freq );
+ /** Adds a position (e.g. first monday) to the monthly recurrence rule.
+ * @param pos the position in the month for the recurrence, with valid
+ * values being 1-5 (5 weeks max in a month).
+ * @param days the days for the position to recur on (bit 0 = Monday).
+ * Example: pos = 2, and bits 0 and 2 are set in days:
+ * the rule is to repeat every 2nd Monday and Wednesday in the month.
+ */
+ void addMonthlyPos( short pos, const QBitArray &days );
+ void addMonthlyPos( short pos, ushort day );
+ /** Adds a date (e.g. the 15th of each month) to the monthly day
+ * recurrence list.
+ * @param day the date in the month to recur.
+ */
+ void addMonthlyDate( short day );
+ /** Returns list of day positions in months. */
+ QValueList<RecurrenceRule::WDayPos> monthPositions() const;
+ /** Returns list of day numbers of a month. */
+ // Emulate old behavior
+ QValueList<int> monthDays() const;
+
+ /** Sets an event to recur yearly. By default, this will recur every year
+ * on the same date (e.g. every year on April 15 if the start date was
+ * April 15).
+ * The day of the year can be specified with addYearlyDay().
+ * The day of the month can be specified with addYearlyByDate
+ * If both a month and a day ar specified with addYearlyMonth and
+ * addYearlyDay, the day is understood as day number within the month.
+ *
+ * A position (e.g. 3rd Sunday of year/month, or last Friday of year/month)
+ * can be specified with addYearlyPos. Again, if a month is specified,
+ * this position is understood as within that month, otherwise within
+ * the year.
+ *
+ * By default infinite recurrence is used. To set an end date use the
+ * method setEndDate and to set the number of occurrences use setDuration.
+
+ This method clears all recurrence rules and adds one rule with a
+ yearly recurrence. All other recurrence components (recurrence
+ date/times, exception date/times and exception rules) are not
+ modified.
+ * @param freq the frequency to recur, e.g. 3 for every third year.
+ */
+ void setYearly( int freq );
+ /** Adds day number of year within a yearly recurrence.
+ * By default infinite recurrence is used. To set an end date use the
+ * method setEndDate and to set the number of occurrences use setDuration.
+ * @param day the day of the year for the event. E.g. if day is 60, this
+ * means Feb 29 in leap years and March 1 in non-leap years.
+ */
+ void addYearlyDay( int day );
+ /** Adds date within a yearly recurrence. The month(s) for the recurrence
+ * can be specified with addYearlyMonth(), otherwise the month of the
+ * start date is used.
+ *
+ * By default infinite recurrence is used. To set an end date use the
+ * method setEndDate and to set the number of occurrences use setDuration.
+ * @param date the day of the month for the event
+ */
+ void addYearlyDate( int date );
+ /** Adds month in yearly recurrence. You can specify specific day numbers
+ * within the months (by calling addYearlyDate()) or specific day positions
+ * within the month (by calling addYearlyPos).
+ * @param _rNum the month in which the event shall recur.
+ */
+ void addYearlyMonth( short _rNum );
+ /** Adds position within month/year within a yearly recurrence. If months
+ * are specified (via addYearlyMonth()), the parameters are understood as
+ * position within these months, otherwise within the year.
+ *
+ * By default infinite recurrence is used.
+ * To set an end date use the method setEndDate and to set the number
+ * of occurrences use setDuration.
+ * @param pos the position in the month/year for the recurrence, with valid
+ * values being 1 to 53 and -1 to -53 (53 weeks max in a year).
+ * @param days the days for the position to recur on (bit 0 = Monday).
+ * Example: pos = 2, and bits 0 and 2 are set in days
+ * If months are specified (via addYearlyMonth), e.g. March, the rule is
+ * to repeat every year on the 2nd Monday and Wednesday of March.
+ * If no months are specified, the fule is to repeat every year on the
+ * 2nd Monday and Wednesday of the year.
+ */
+ void addYearlyPos( short pos, const QBitArray &days );
+
+ /** Returns the day numbers within a yearly recurrence.
+ * @return the days of the year for the event. E.g. if the list contains
+ * 60, this means the recurrence happens on day 60 of the year, i.e.
+ * on Feb 29 in leap years and March 1 in non-leap years.
+ */
+ QValueList<int> yearDays() const;
+ /** Returns the dates within a yearly recurrence.
+ * @return the days of the month for the event. E.g. if the list contains
+ * 13, this means the recurrence happens on the 13th of the month.
+ * The months for the recurrence can be obtained through
+ * yearlyMonths(). If this list is empty, the month of the start
+ * date is used.
+ */
+ QValueList<int> yearDates() const;
+ /** Returns the months within a yearly recurrence.
+ * @return the months for the event. E.g. if the list contains
+ * 11, this means the recurrence happens in November.
+ * The days for the recurrence can be obtained either through
+ * yearDates() if they are given as dates within the month or
+ * through yearlyPositions() if they are given as positions within the
+ * month. If none is specified, the date of the start date is used.
+ */
+ QValueList<int> yearMonths() const;
+ /** Returns the positions within a yearly recurrence.
+ * @return the positions for the event, either within a month (if months
+ * are set through addYearlyMonth()) or within the year.
+ * E.g. if the list contains {Pos=3, Day=5}, this means the third
+ * friday. If a month is set this position is understoodas third
+ * Friday in the given months, otherwise as third Friday of the
+ * year.
+ */
+ /** Returns list of day positions in months, for a recursYearlyPos recurrence rule. */
+ QValueList<RecurrenceRule::WDayPos> yearPositions() const;
+
+ /** Upper date limit for recurrences */
+ static const QDate MAX_DATE;
+
+ /**
+ Debug output.
+ */
+ void dump() const;
+
+
+ // RRULE
+ RecurrenceRule::List rRules() const;
+ void addRRule( RecurrenceRule *rrule );
+ void removeRRule( RecurrenceRule *rrule );
+ // EXRULE
+ RecurrenceRule::List exRules() const;
+ void addExRule( RecurrenceRule *exrule );
+ void removeExRule( RecurrenceRule *exrule );
+
+ // RDATE
+ DateTimeList rDateTimes() const;
+ DateList rDates() const;
+ void setRDateTimes( const DateTimeList &rdates);
+ void setRDates( const DateList &rdates);
+ void addRDateTime( const QDateTime &rdate );
+ void addRDate( const QDate &rdate );
+
+ // ExDATE
+ DateTimeList exDateTimes() const;
+ DateList exDates() const;
+ void setExDateTimes( const DateTimeList &exdates);
+ void setExDates( const DateList &exdates);
+ void addExDateTime( const QDateTime &exdate );
+ void addExDate( const QDate &exdate );
+
+ RecurrenceRule *defaultRRule( bool create = false ) const;
+ RecurrenceRule *defaultRRuleConst() const;
+ void updated();
+
+ /**
+ Installs an observer. Whenever some setting of this recurrence
+ object is changed, the recurrenceUpdated( Recurrence* ) method
+ of each observer will be called to inform it of changes.
+ @param observer the Recurrence::Observer-derived object, which
+ will be installed as an observer of this object.
+ */
+ void addObserver( Observer *observer );
+ /**
+ Removes an observer that was added with addObserver. If the
+ given object was not an observer, it does nothing.
+ @param observer the Recurrence::Observer-derived object to
+ be removed from the list of observers of this object.
+ */
+ void removeObserver( Observer *observer );
+
+ void recurrenceChanged( RecurrenceRule * );
+
+ protected:
+ RecurrenceRule *setNewRecurrenceType( RecurrenceRule::PeriodType type, int freq );
+
+ private:
+ RecurrenceRule::List mExRules;
+ RecurrenceRule::List mRRules;
+ QValueList<QDateTime>mRDateTimes;
+ QValueList<QDate> mRDates;
+ QValueList<QDateTime> mExDateTimes;
+ QValueList<QDate> mExDates;
+
+ QDateTime mStartDateTime; // date/time of first recurrence
+ bool mFloating; // the recurrence has no time, just a date
+ bool mRecurReadOnly;
+
+ // Cache the type of the recurrence with the old system (e.g. MonthlyPos)
+ mutable ushort mCachedType;
+
+ QValueList<Observer*> mObservers;
+
+ class Private;
+ Private *d;
+};
+
+}
+
+#endif