File indexing completed on 2024-04-14 03:50:48

0001 /*
0002   This file is part of the kcalcore library.
0003 
0004   SPDX-FileCopyrightText: 1998 Preston Brown <pbrown@kde.org>
0005   SPDX-FileCopyrightText: 2001, 2003 Cornelius Schumacher <schumacher@kde.org>
0006   SPDX-FileCopyrightText: 2002, 2006, 2007 David Jarvie <djarvie@kde.org>
0007   SPDX-FileCopyrightText: 2005 Reinhold Kainhofer <reinhold@kainhofer.com>
0008 
0009   SPDX-License-Identifier: LGPL-2.0-or-later
0010 */
0011 #ifndef KCALCORE_RECURRENCERULE_H
0012 #define KCALCORE_RECURRENCERULE_H
0013 
0014 #include "kcalendarcore_export.h"
0015 
0016 #include <QDateTime>
0017 #include <QTimeZone>
0018 
0019 class QTimeZone;
0020 
0021 namespace KCalendarCore
0022 {
0023 // These two are duplicates wrt. incidencebase.h
0024 typedef QList<QDate> DateList;
0025 /* List of times */
0026 typedef QList<QTime> TimeList;
0027 
0028 /**
0029   This class represents a recurrence rule for a calendar incidence.
0030 */
0031 class KCALENDARCORE_EXPORT RecurrenceRule
0032 {
0033 public:
0034     class RuleObserver
0035     {
0036     public:
0037         virtual ~RuleObserver();
0038         /** This method is called on each change of the recurrence object */
0039         virtual void recurrenceChanged(RecurrenceRule *) = 0;
0040     };
0041     typedef QList<RecurrenceRule *> List;
0042 
0043     /** enum for describing the frequency how an event recurs, if at all. */
0044     enum PeriodType {
0045         rNone = 0,
0046         rSecondly,
0047         rMinutely,
0048         rHourly,
0049         rDaily,
0050         rWeekly,
0051         rMonthly,
0052         rYearly,
0053     };
0054 
0055     /** structure for describing the n-th weekday of the month/year. */
0056     class KCALENDARCORE_EXPORT WDayPos // krazy:exclude=dpointer
0057     {
0058     public:
0059         explicit WDayPos(int ps = 0, short dy = 0);
0060         void setDay(short dy);
0061         short day() const;
0062         void setPos(int ps);
0063         int pos() const;
0064 
0065         bool operator==(const RecurrenceRule::WDayPos &pos2) const;
0066         bool operator!=(const RecurrenceRule::WDayPos &pos2) const;
0067 
0068     protected:
0069         short mDay; // Weekday, 1=monday, 7=sunday
0070         int mPos; // week of the day (-1 for last, 1 for first, 0 for all weeks)
0071         // Bounded by -366 and +366, 0 means all weeks in that period
0072 
0073         friend KCALENDARCORE_EXPORT QDataStream &operator<<(QDataStream &out, const KCalendarCore::RecurrenceRule::WDayPos &);
0074         friend KCALENDARCORE_EXPORT QDataStream &operator>>(QDataStream &in, KCalendarCore::RecurrenceRule::WDayPos &);
0075     };
0076 
0077     RecurrenceRule();
0078     RecurrenceRule(const RecurrenceRule &r);
0079     ~RecurrenceRule();
0080 
0081     bool operator==(const RecurrenceRule &r) const;
0082     bool operator!=(const RecurrenceRule &r) const
0083     {
0084         return !operator==(r);
0085     }
0086 
0087     RecurrenceRule &operator=(const RecurrenceRule &r);
0088 
0089     /** Set if recurrence is read-only or can be changed. */
0090     void setReadOnly(bool readOnly);
0091 
0092     /**
0093       Returns true if the recurrence is read-only; false if it can be changed.
0094     */
0095     Q_REQUIRED_RESULT bool isReadOnly() const;
0096 
0097     /**
0098       Returns the event's recurrence status.  See the enumeration at the top
0099       of this file for possible values.
0100     */
0101     Q_REQUIRED_RESULT bool recurs() const;
0102     void setRecurrenceType(PeriodType period);
0103     Q_REQUIRED_RESULT PeriodType recurrenceType() const;
0104 
0105     /** Turns off recurrence for the event. */
0106     void clear();
0107 
0108     /**
0109       Returns the recurrence frequency, in terms of the recurrence time period type.
0110     */
0111     Q_REQUIRED_RESULT uint frequency() const;
0112 
0113     /**
0114       Sets the recurrence frequency, in terms of the recurrence time period type.
0115     */
0116     void setFrequency(int freq);
0117 
0118     /**
0119       Returns the recurrence start date/time.
0120       Note that the recurrence does not necessarily occur on the start date/time.
0121       For this to happen, it must actually match the rule.
0122     */
0123     Q_REQUIRED_RESULT QDateTime startDt() const;
0124 
0125     /**
0126       Sets the recurrence start date/time.
0127       Note that setting the start date/time does not make the recurrence occur
0128       on that date/time, it simply sets a lower limit to when the recurrences
0129       take place (this applies only for the by- rules, not for i.e. an hourly
0130       rule where the startDt is the first occurrence).
0131 
0132       Note that setting @p start to a date-only value does not make an all-day
0133       recurrence: to do this, call setAllDay(true).
0134 
0135       @param start the recurrence's start date and time
0136     */
0137     void setStartDt(const QDateTime &start);
0138 
0139     /** Returns whether the start date has no time associated. All-Day
0140         means -- according to rfc2445 -- that the event has no time associate. */
0141     Q_REQUIRED_RESULT bool allDay() const;
0142 
0143     /** Sets whether the dtstart is all-day (i.e. has no time attached)
0144      *
0145      * @param allDay Whether start datetime is all-day
0146      */
0147     void setAllDay(bool allDay);
0148 
0149     /** Returns the date and time of the last recurrence.
0150      * An invalid date is returned if the recurrence has no end.
0151      * @param result if non-null, *result is updated to true if successful,
0152      * or false if there is no recurrence or its end date cannot be determined.
0153      */
0154     Q_REQUIRED_RESULT QDateTime endDt(bool *result = nullptr) const;
0155 
0156     /** Sets the date and time of the last recurrence.
0157      * @param endDateTime the ending date/time after which to stop recurring. */
0158     void setEndDt(const QDateTime &endDateTime);
0159 
0160     /**
0161      * Returns -1 if the event recurs infinitely, 0 if the end date is set,
0162      * otherwise the total number of recurrences, including the initial occurrence.
0163      */
0164     Q_REQUIRED_RESULT int duration() const;
0165 
0166     /** Sets the total number of times the event is to occur, including both the
0167      * first and last. */
0168     void setDuration(int duration);
0169 
0170     /** Returns the number of recurrences up to and including the date/time specified. */
0171     Q_REQUIRED_RESULT int durationTo(const QDateTime &dt) const;
0172 
0173     /** Returns the number of recurrences up to and including the date specified. */
0174     Q_REQUIRED_RESULT int durationTo(const QDate &date) const;
0175 
0176     /**
0177       Shift the times of the rule so that they appear at the same clock
0178       time as before but in a new time zone. The shift is done from a viewing
0179       time zone rather than from the actual rule time zone.
0180 
0181       For example, shifting a rule whose start time is 09:00 America/New York,
0182       using an old viewing time zone (@p oldTz) of Europe/London, to a new time
0183       zone (@p newTz) of Europe/Paris, will result in the time being shifted
0184       from 14:00 (which is the London time of the rule start) to 14:00 Paris
0185       time.
0186 
0187       @param oldTz the time specification which provides the clock times
0188       @param newTz the new time specification
0189     */
0190     void shiftTimes(const QTimeZone &oldTz, const QTimeZone &newTz);
0191 
0192     /** Returns true if the date specified is one on which the event will
0193      * recur. The start date returns true only if it actually matches the rule.
0194      *
0195      * @param date date to check
0196      * @param timeZone time specification for @p date
0197      */
0198     Q_REQUIRED_RESULT bool recursOn(const QDate &date, const QTimeZone &timeZone) const;
0199 
0200     /** Returns true if the date/time specified is one at which the event will
0201      * recur. Times are rounded down to the nearest minute to determine the result.
0202      * The start date/time returns true only if it actually matches the rule.
0203      *
0204      * @param dt the date+time to check for recurrency
0205      */
0206     Q_REQUIRED_RESULT bool recursAt(const QDateTime &dt) const;
0207 
0208     /** Returns true if the date matches the rules. It does not necessarily
0209         mean that this is an actual occurrence. In particular, the method does
0210         not check if the date is after the end date, or if the frequency interval
0211         matches.
0212 
0213         @param dt the date+time to check for matching the rules
0214      */
0215     Q_REQUIRED_RESULT bool dateMatchesRules(const QDateTime &dt) const;
0216 
0217     /** Returns a list of the times on the specified date at which the
0218      * recurrence will occur. The returned times should be interpreted in the
0219      * context of @p timeZone.
0220      * @param date the date for which to find the recurrence times
0221      * @param timeZone time specification for @p date
0222      */
0223     Q_REQUIRED_RESULT TimeList recurTimesOn(const QDate &date, const QTimeZone &timeZone) const;
0224 
0225     /** Returns a list of all the times at which the recurrence will occur
0226      * between two specified times.
0227      *
0228      * There is a (large) maximum limit to the number of times returned. If due to
0229      * this limit the list is incomplete, this is indicated by the last entry being
0230      * set to an invalid QDateTime value. If you need further values, call the
0231      * method again with a start time set to just after the last valid time returned.
0232      * @param start inclusive start of interval
0233      * @param end inclusive end of interval
0234      * @return list of date/time values
0235      */
0236     Q_REQUIRED_RESULT QList<QDateTime> timesInInterval(const QDateTime &start, const QDateTime &end) const;
0237 
0238     /** Returns the date and time of the next recurrence, after the specified date/time.
0239      * If the recurrence has no time, the next date after the specified date is returned.
0240      * @param preDateTime the date/time after which to find the recurrence.
0241      * @return date/time of next recurrence, or invalid date if none.
0242      */
0243     Q_REQUIRED_RESULT QDateTime getNextDate(const QDateTime &preDateTime) const;
0244 
0245     /** Returns the date and time of the last previous recurrence, before the specified date/time.
0246      * If a time later than 00:00:00 is specified and the recurrence has no time, 00:00:00 on
0247      * the specified date is returned if that date recurs.
0248      * @param afterDateTime the date/time before which to find the recurrence.
0249      * @return date/time of previous recurrence, or invalid date if none.
0250      */
0251     Q_REQUIRED_RESULT QDateTime getPreviousDate(const QDateTime &afterDateTime) const;
0252 
0253     void setBySeconds(const QList<int> &bySeconds);
0254     void setByMinutes(const QList<int> &byMinutes);
0255     void setByHours(const QList<int> &byHours);
0256 
0257     void setByDays(const QList<WDayPos> &byDays);
0258     void setByMonthDays(const QList<int> &byMonthDays);
0259     void setByYearDays(const QList<int> &byYearDays);
0260     void setByWeekNumbers(const QList<int> &byWeekNumbers);
0261     void setByMonths(const QList<int> &byMonths);
0262     void setBySetPos(const QList<int> &bySetPos);
0263     void setWeekStart(short weekStart);
0264 
0265     const QList<int> &bySeconds() const;
0266     const QList<int> &byMinutes() const;
0267     const QList<int> &byHours() const;
0268 
0269     const QList<WDayPos> &byDays() const;
0270     const QList<int> &byMonthDays() const;
0271     const QList<int> &byYearDays() const;
0272     const QList<int> &byWeekNumbers() const;
0273     const QList<int> &byMonths() const;
0274     const QList<int> &bySetPos() const;
0275     short weekStart() const;
0276 
0277     /**
0278       Set the RRULE string for the rule.
0279       This is merely stored for future reference. The string is not used in any way
0280       by the RecurrenceRule.
0281 
0282       @param rrule the RRULE string
0283      */
0284     void setRRule(const QString &rrule);
0285     Q_REQUIRED_RESULT QString rrule() const;
0286 
0287     void setDirty();
0288     /**
0289       Installs an observer. Whenever some setting of this recurrence
0290       object is changed, the recurrenceUpdated( Recurrence* ) method
0291       of each observer will be called to inform it of changes.
0292       @param observer the Recurrence::Observer-derived object, which
0293       will be installed as an observer of this object.
0294     */
0295     void addObserver(RuleObserver *observer);
0296 
0297     /**
0298       Removes an observer that was added with addObserver. If the
0299       given object was not an observer, it does nothing.
0300       @param observer the Recurrence::Observer-derived object to
0301       be removed from the list of observers of this object.
0302     */
0303     void removeObserver(RuleObserver *observer);
0304 
0305     /**
0306       Debug output.
0307     */
0308     void dump() const;
0309 
0310 private:
0311     //@cond PRIVATE
0312     class Private;
0313     Private *const d;
0314     //@endcond
0315 
0316     friend KCALENDARCORE_EXPORT QDataStream &operator<<(QDataStream &out, const KCalendarCore::RecurrenceRule *);
0317     friend KCALENDARCORE_EXPORT QDataStream &operator>>(QDataStream &in, const KCalendarCore::RecurrenceRule *);
0318 };
0319 
0320 /**
0321  * RecurrenceRule serializer and deserializer.
0322  * @since 4.12
0323  */
0324 KCALENDARCORE_EXPORT QDataStream &operator<<(QDataStream &out, const KCalendarCore::RecurrenceRule *);
0325 KCALENDARCORE_EXPORT QDataStream &operator>>(QDataStream &in, const KCalendarCore::RecurrenceRule *);
0326 
0327 /**
0328  * RecurrenceRule::WDayPos serializer and deserializer.
0329  * @since 4.12
0330  */
0331 KCALENDARCORE_EXPORT QDataStream &operator<<(QDataStream &out, const KCalendarCore::RecurrenceRule::WDayPos &);
0332 KCALENDARCORE_EXPORT QDataStream &operator>>(QDataStream &in, KCalendarCore::RecurrenceRule::WDayPos &);
0333 }
0334 
0335 Q_DECLARE_TYPEINFO(KCalendarCore::RecurrenceRule::WDayPos, Q_RELOCATABLE_TYPE);
0336 
0337 #endif