/* This file is part of the kcalcore library. Copyright (c) 2002 Cornelius Schumacher Copyright (C) 2003-2004 Reinhold Kainhofer Copyright (C) 2012 Christian Mollekopf 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. */ /** @file This file is part of the API for handling calendar data and defines classes for managing compatibility between different calendar formats. @author Cornelius Schumacher \ @author Reinhold Kainhofer \ */ #ifndef KCALCORE_COMPAT_P_H #define KCALCORE_COMPAT_P_H #include "incidence.h" #include // for Q_DISABLE_COPY() #include #include namespace KCalCore { class Compat; /** @brief Factory for creating the right Compat object. @internal */ class CompatFactory { public: /** Creates the appropriate Compat class as determined by the Product ID. @param productId is a string containing a valid Product ID from a supported calendar format. @return A pointer to a Compat object which is owned by the caller. */ static Compat *createCompat(const QString &productId, const QString &implementationVersion); }; /** @brief This class provides compatibility to older or broken calendar files. @internal */ class Compat { public: /** Constructor. */ Compat(); /** Destructor. */ virtual ~Compat(); /** Fixes the recurrence rule for an incidence. @param incidence is a pointer to an Incidence object that may need its recurrence rule fixed. */ virtual void fixRecurrence(const Incidence::Ptr &incidence); /** Fixes an empty summary for an incidence. @param incidence is a pointer to an Incidence object that may need its summary fixed. */ virtual void fixEmptySummary(const Incidence::Ptr &incidence); /** Fixes the alarms list an incidence. @param incidence is a pointer to an Incidence object that may need its alarms fixed. */ virtual void fixAlarms(const Incidence::Ptr &incidence); /** Fixes the end date for floating events. @param date is the end date to fix. */ virtual void fixFloatingEnd(QDate &date); /** Fixes the priority. @param priority is the priority value to fix. @return an integer representing a valid priority value. */ virtual int fixPriority(int priority); /** Returns true if a timezone shift should be used; false otherwise. */ virtual bool useTimeZoneShift(); /** Sets the created and dtstamp. */ virtual void setCreatedToDtStamp(const Incidence::Ptr &incidence, const KDateTime &dtstamp); private: //@cond PRIVATE Q_DISABLE_COPY(Compat) class Private; Private *d; //@endcond }; /** @brief Decorator so multiple compatibility classes can be stacked. */ class CompatDecorator : public Compat { public: explicit CompatDecorator(Compat *decoratedCompat); virtual ~CompatDecorator(); /** @copydoc Compat::fixRecurrence() */ virtual void fixRecurrence(const Incidence::Ptr &incidence); /** @copydoc Compat::fixEmptySummary() */ virtual void fixEmptySummary(const Incidence::Ptr &incidence); /** @copydoc Compat::fixAlarms() */ virtual void fixAlarms(const Incidence::Ptr &incidence); /** @copydoc Compat::fixFloatingEnd() */ virtual void fixFloatingEnd(QDate &date); /** @copydoc Compat::fixPriority() */ virtual int fixPriority(int priority); /** @copydoc Compat::useTimeZoneShift() */ virtual bool useTimeZoneShift(); /** @copydoc Compat::setCreatedToDtStamp() */ virtual void setCreatedToDtStamp(const Incidence::Ptr &incidence, const KDateTime &dtstamp); private: //@cond PRIVATE Q_DISABLE_COPY(CompatDecorator) class Private; Private *d; //@endcond }; /** @brief Compatibility class for KOrganizer pre-3.5 calendar files. Before kde 3.5, the start date was not automatically a recurring date. So, if the start date doesn't match the recurrence rule, we need to add an ex-date for the date start. If a duration was given, the DTSTART was only counted if it matched, so by accident this was already the correct behavior, so we don't need to adjust the duration. */ class CompatPre35 : public Compat { public: /** @copydoc Compat::fixRecurrence() */ virtual void fixRecurrence(const Incidence::Ptr &incidence); private: //@cond PRIVATE class Private; Private *d; //@endcond }; /** @brief Compatibility class for KOrganizer pre-3.4 calendar files. */ class CompatPre34 : public CompatPre35 { public: /** @copydoc Compat::fixPriority() */ virtual int fixPriority(int priority); private: //@cond PRIVATE class Private; Private *d; //@endcond }; /** @brief Compatibility class for KOrganizer pre-3.2 calendar files. The recurrence has a specified number of repetitions. Pre-3.2, this was extended by the number of exception dates. This is also rfc 2445-compliant. The duration of an RRULE also counts events that are later excluded via EXDATE or EXRULE. */ class CompatPre32 : public CompatPre34 { public: /** @copydoc Compat::fixRecurrence() */ virtual void fixRecurrence(const Incidence::Ptr &incidence); private: //@cond PRIVATE class Private; Private *d; //@endcond }; /** @brief Compatibility class for KOrganizer pre-3.1 calendar files. Before kde 3.1, floating events (events without a date) had 0:00 of their last day as the end date. E.g. 28.5.2005 0:00 until 28.5.2005 0:00 for an event that lasted the whole day on May 28, 2005. According to RFC 2445, the end date for such an event needs to be 29.5.2005 0:00. Update: We misunderstood rfc 2445 in this regard. For all-day events, the DTEND is the last day of the event. See a mail from the Author or rfc 2445: http://www.imc.org/ietf-calendar/archive1/msg03648.html However, as all other applications also got this wrong, we'll just leave it as it is and use the wrong interpretation (was also discussed on ietf-calsify) */ class CompatPre31 : public CompatPre32 { public: /** @copydoc Compat::fixFloatingEnd() */ virtual void fixFloatingEnd(QDate &date); /** @copydoc Compat::fixRecurrence() */ virtual void fixRecurrence(const Incidence::Ptr &incidence); private: //@cond PRIVATE class Private; Private *d; //@endcond }; /** @brief Compatibility class for KOrganizer prerelease 3.2 calendar files. */ class Compat32PrereleaseVersions : public Compat { public: /** @copydoc Compat::useTimeZoneShift() */ virtual bool useTimeZoneShift(); private: //@cond PRIVATE class Private; Private *d; //@endcond }; /** @brief Compatibility class for Outlook 9 calendar files. In Outlook 9, alarms have the wrong sign. I.e. RFC 2445 says that negative values for the trigger are before the event's start. Outlook/exchange, however used positive values. */ class CompatOutlook9 : public Compat { public: /** @copydoc Compat::fixAlarms() */ virtual void fixAlarms(const Incidence::Ptr &incidence); private: //@cond PRIVATE class Private; Private *d; //@endcond }; /** @brief Compatibility class for Kontact < 4.10 calendar files. */ class CompatPre410 : public CompatDecorator { public: explicit CompatPre410(Compat *decoratedCompat); /** @copydoc Compat::setCreatedToDtStamp() */ virtual void setCreatedToDtStamp(const Incidence::Ptr &incidence, const KDateTime &dtstamp); private: //@cond PRIVATE class Private; Private *d; //@endcond }; } #endif