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

0001 /*
0002   This file is part of the kcalcore library.
0003 
0004   SPDX-FileCopyrightText: 2002 Cornelius Schumacher <schumacher@kde.org>
0005   SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
0006   SPDX-FileCopyrightText: 2012 Christian Mollekopf <mollekopf@kolabsys.com>
0007 
0008   SPDX-License-Identifier: LGPL-2.0-or-later
0009 */
0010 /**
0011   @file
0012   This file is part of the API for handling calendar data and defines
0013   classes for managing compatibility between different calendar formats.
0014 
0015   @author Cornelius Schumacher \<schumacher@kde.org\>
0016   @author Reinhold Kainhofer \<reinhold@kainhofer.com\>
0017 */
0018 
0019 #ifndef KCALCORE_COMPAT_P_H
0020 #define KCALCORE_COMPAT_P_H
0021 
0022 #include "incidence.h"
0023 
0024 #include <QtGlobal> // for Q_DISABLE_COPY()
0025 
0026 #include <memory>
0027 
0028 class QDate;
0029 class QString;
0030 
0031 namespace KCalendarCore
0032 {
0033 class Compat;
0034 
0035 /**
0036   @brief
0037   Factory for creating the right Compat object.
0038 
0039   @internal
0040 */
0041 class CompatFactory
0042 {
0043 public:
0044     /**
0045       Creates the appropriate Compat class as determined by the Product ID.
0046 
0047       @param productId is a string containing a valid Product ID from
0048       a supported calendar format.
0049       @return A pointer to a Compat object which is owned by the caller.
0050     */
0051     static Compat *createCompat(const QString &productId, const QString &implementationVersion);
0052 };
0053 
0054 /**
0055   @brief
0056   This class provides compatibility to older or broken calendar files.
0057 
0058   @internal
0059 */
0060 class Compat
0061 {
0062 public:
0063     /**
0064       Destructor.
0065     */
0066     virtual ~Compat();
0067 
0068     /**
0069       Fixes the recurrence rule for an incidence.
0070       @param incidence is a pointer to an Incidence object that may
0071       need its recurrence rule fixed.
0072     */
0073     virtual void fixRecurrence(const Incidence::Ptr &incidence);
0074 
0075     /**
0076       Fixes an empty summary for an incidence.
0077       @param incidence is a pointer to an Incidence object that may need
0078       its summary fixed.
0079     */
0080     virtual void fixEmptySummary(const Incidence::Ptr &incidence);
0081 
0082     /**
0083       Fixes the alarms list an incidence.
0084       @param incidence is a pointer to an Incidence object that may need
0085       its alarms fixed.
0086     */
0087     virtual void fixAlarms(const Incidence::Ptr &incidence);
0088 
0089     /**
0090       Fixes the end date for floating events.
0091       @param date is the end date to fix.
0092     */
0093     virtual void fixFloatingEnd(QDate &date);
0094 
0095     /**
0096       Fixes the priority.
0097       @param priority is the priority value to fix.
0098       @return an integer representing a valid priority value.
0099     */
0100     virtual int fixPriority(int priority);
0101 
0102     /**
0103       Returns true if a timezone shift should be used; false otherwise.
0104     */
0105     virtual bool useTimeZoneShift() const;
0106 
0107     /**
0108       Sets the created and dtstamp.
0109     */
0110     virtual void setCreatedToDtStamp(const Incidence::Ptr &incidence, const QDateTime &dtstamp);
0111 };
0112 
0113 /**
0114   @brief
0115   Decorator so multiple compatibility classes can be stacked.
0116 */
0117 class CompatDecorator : public Compat
0118 {
0119 public:
0120     explicit CompatDecorator(Compat *decoratedCompat);
0121     ~CompatDecorator() override;
0122 
0123     /**
0124       @copydoc
0125       Compat::fixRecurrence()
0126     */
0127     void fixRecurrence(const Incidence::Ptr &incidence) override;
0128 
0129     /**
0130       @copydoc
0131       Compat::fixEmptySummary()
0132     */
0133     void fixEmptySummary(const Incidence::Ptr &incidence) override;
0134 
0135     /**
0136       @copydoc
0137       Compat::fixAlarms()
0138     */
0139     void fixAlarms(const Incidence::Ptr &incidence) override;
0140 
0141     /**
0142       @copydoc
0143       Compat::fixFloatingEnd()
0144     */
0145     void fixFloatingEnd(QDate &date) override;
0146 
0147     /**
0148       @copydoc
0149       Compat::fixPriority()
0150     */
0151     int fixPriority(int priority) override;
0152 
0153     /**
0154       @copydoc
0155       Compat::useTimeZoneShift()
0156     */
0157     bool useTimeZoneShift() const override;
0158 
0159     /**
0160       @copydoc
0161       Compat::setCreatedToDtStamp()
0162     */
0163     void setCreatedToDtStamp(const Incidence::Ptr &incidence, const QDateTime &dtstamp) override;
0164 
0165 private:
0166     Q_DISABLE_COPY(CompatDecorator)
0167     std::unique_ptr<Compat> m_compat;
0168 };
0169 
0170 /**
0171   @brief
0172   Compatibility class for KOrganizer pre-3.5 calendar files.
0173 
0174   Before kde 3.5, the start date was not automatically a recurring date.
0175   So, if the start date doesn't match the recurrence rule, we need to add
0176   an ex-date for the date start. If a duration was given, the DTSTART was
0177   only counted if it matched, so by accident this was already the correct
0178   behavior, so we don't need to adjust the duration.
0179 */
0180 class CompatPre35 : public Compat
0181 {
0182 public:
0183     /**
0184       @copydoc
0185       Compat::fixRecurrence()
0186     */
0187     void fixRecurrence(const Incidence::Ptr &incidence) override;
0188 };
0189 
0190 /**
0191   @brief
0192   Compatibility class for KOrganizer pre-3.4 calendar files.
0193 */
0194 class CompatPre34 : public CompatPre35
0195 {
0196 public:
0197     /**
0198       @copydoc
0199       Compat::fixPriority()
0200     */
0201     int fixPriority(int priority) override;
0202 };
0203 
0204 /**
0205   @brief
0206   Compatibility class for KOrganizer pre-3.2 calendar files.
0207 
0208   The recurrence has a specified number of repetitions.
0209   Pre-3.2, this was extended by the number of exception dates.
0210   This is also rfc 2445-compliant. The duration of an RRULE also counts
0211   events that are later excluded via EXDATE or EXRULE.
0212 */
0213 class CompatPre32 : public CompatPre34
0214 {
0215 public:
0216     /**
0217       @copydoc
0218       Compat::fixRecurrence()
0219     */
0220     void fixRecurrence(const Incidence::Ptr &incidence) override;
0221 };
0222 
0223 /**
0224   @brief
0225   Compatibility class for KOrganizer pre-3.1 calendar files.
0226 
0227   Before kde 3.1, floating events (events without a date) had 0:00 of their
0228   last day as the end date. E.g. 28.5.2005  0:00 until 28.5.2005 0:00 for an
0229   event that lasted the whole day on May 28, 2005. According to RFC 2445, the
0230   end date for such an event needs to be 29.5.2005 0:00.
0231 
0232   Update: We misunderstood rfc 2445 in this regard. For all-day events, the
0233   DTEND is the last day of the event. See a mail from the Author or rfc 2445:
0234     http://www.imc.org/ietf-calendar/archive1/msg03648.html
0235   However, as all other applications also got this wrong, we'll just leave it
0236   as it is and use the wrong interpretation (was also discussed on ietf-calsify)
0237 */
0238 class CompatPre31 : public CompatPre32
0239 {
0240 public:
0241     /**
0242       @copydoc
0243       Compat::fixFloatingEnd()
0244     */
0245     void fixFloatingEnd(QDate &date) override;
0246 
0247     /**
0248       @copydoc
0249       Compat::fixRecurrence()
0250     */
0251     void fixRecurrence(const Incidence::Ptr &incidence) override;
0252 };
0253 
0254 /**
0255   @brief
0256   Compatibility class for KOrganizer prerelease 3.2 calendar files.
0257 */
0258 class Compat32PrereleaseVersions : public Compat
0259 {
0260 public:
0261     /**
0262       @copydoc
0263       Compat::useTimeZoneShift()
0264     */
0265     bool useTimeZoneShift() const override;
0266 };
0267 
0268 /**
0269   @brief
0270   Compatibility class for Outlook 9 calendar files.
0271 
0272   In Outlook 9, alarms have the wrong sign. I.e. RFC 2445 says that negative
0273   values for the trigger are before the event's start. Outlook/exchange,
0274   however used positive values.
0275 */
0276 class CompatOutlook9 : public Compat
0277 {
0278 public:
0279     /**
0280       @copydoc
0281       Compat::fixAlarms()
0282     */
0283     void fixAlarms(const Incidence::Ptr &incidence) override;
0284 };
0285 
0286 /**
0287   @brief
0288   Compatibility class for Kontact < 4.10 calendar files.
0289 */
0290 class CompatPre410 : public CompatDecorator
0291 {
0292 public:
0293     explicit CompatPre410(Compat *decoratedCompat);
0294     /**
0295       @copydoc
0296       Compat::setCreatedToDtStamp()
0297     */
0298     void setCreatedToDtStamp(const Incidence::Ptr &incidence, const QDateTime &dtstamp) override;
0299 };
0300 
0301 }
0302 
0303 #endif