File indexing completed on 2024-04-21 07:39:29

0001 /*
0002   This file is part of the kcalcore library.
0003 
0004   SPDX-FileCopyrightText: 2002 Cornelius Schumacher <schumacher@kde.org>
0005 
0006   SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 /**
0009   @file
0010   This file is part of the API for handling calendar data and
0011   defines the FileStorage class.
0012 
0013   @brief
0014   This class provides a calendar storage as a local file.
0015 
0016   @author Cornelius Schumacher \<schumacher@kde.org\>
0017 */
0018 #include "filestorage.h"
0019 #include "exceptions.h"
0020 #include "icalformat.h"
0021 #include "memorycalendar.h"
0022 #include "vcalformat.h"
0023 
0024 #include "kcalendarcore_debug.h"
0025 
0026 using namespace KCalendarCore;
0027 
0028 /*
0029   Private class that helps to provide binary compatibility between releases.
0030 */
0031 //@cond PRIVATE
0032 class Q_DECL_HIDDEN KCalendarCore::FileStorage::Private
0033 {
0034 public:
0035     Private(const QString &fileName, CalFormat *format)
0036         : mFileName(fileName)
0037         , mSaveFormat(format)
0038     {
0039     }
0040     ~Private()
0041     {
0042         delete mSaveFormat;
0043     }
0044 
0045     QString mFileName;
0046     CalFormat *mSaveFormat = nullptr;
0047 };
0048 //@endcond
0049 
0050 FileStorage::FileStorage(const Calendar::Ptr &cal, const QString &fileName, CalFormat *format)
0051     : CalStorage(cal)
0052     , d(new Private(fileName, format))
0053 {
0054 }
0055 
0056 FileStorage::~FileStorage()
0057 {
0058     delete d;
0059 }
0060 
0061 void FileStorage::setFileName(const QString &fileName)
0062 {
0063     d->mFileName = fileName;
0064 }
0065 
0066 QString FileStorage::fileName() const
0067 {
0068     return d->mFileName;
0069 }
0070 
0071 void FileStorage::setSaveFormat(CalFormat *format)
0072 {
0073     delete d->mSaveFormat;
0074     d->mSaveFormat = format;
0075 }
0076 
0077 CalFormat *FileStorage::saveFormat() const
0078 {
0079     return d->mSaveFormat;
0080 }
0081 
0082 bool FileStorage::open()
0083 {
0084     return true;
0085 }
0086 
0087 bool FileStorage::load()
0088 {
0089     if (d->mFileName.isEmpty()) {
0090         qCWarning(KCALCORE_LOG) << "Empty filename while trying to load";
0091         return false;
0092     }
0093 
0094     // Always try to load with iCalendar. It will detect, if it is actually a
0095     // vCalendar file.
0096     bool success;
0097     QString productId;
0098     // First try the supplied format. Otherwise fall through to iCalendar, then
0099     // to vCalendar
0100     success = saveFormat() && saveFormat()->load(calendar(), d->mFileName);
0101     if (success) {
0102         productId = saveFormat()->loadedProductId();
0103     } else {
0104         ICalFormat iCal;
0105 
0106         success = iCal.load(calendar(), d->mFileName);
0107 
0108         if (success) {
0109             productId = iCal.loadedProductId();
0110         } else {
0111             if (iCal.exception()) {
0112                 if ((iCal.exception()->code() == Exception::ParseErrorIcal) || (iCal.exception()->code() == Exception::CalVersion1)) {
0113                     // Possible vCalendar or invalid iCalendar encountered
0114                     qCDebug(KCALCORE_LOG) << d->mFileName << " is an invalid iCalendar or possibly a vCalendar.";
0115                     qCDebug(KCALCORE_LOG) << "Try to load it as a vCalendar";
0116                     VCalFormat vCal;
0117                     success = vCal.load(calendar(), d->mFileName);
0118                     productId = vCal.loadedProductId();
0119                     if (!success) {
0120                         if (vCal.exception()) {
0121                             qCWarning(KCALCORE_LOG) << d->mFileName << " is not a valid vCalendar file."
0122                                                     << " exception code " << vCal.exception()->code();
0123                         }
0124                         return false;
0125                     }
0126                 } else {
0127                     return false;
0128                 }
0129             } else {
0130                 qCWarning(KCALCORE_LOG) << "There should be an exception set.";
0131                 return false;
0132             }
0133         }
0134     }
0135 
0136     calendar()->setProductId(productId);
0137     calendar()->setModified(false);
0138 
0139     return true;
0140 }
0141 
0142 bool FileStorage::save()
0143 {
0144     if (d->mFileName.isEmpty()) {
0145         return false;
0146     }
0147 
0148     CalFormat *format = d->mSaveFormat ? d->mSaveFormat : new ICalFormat;
0149 
0150     bool success = format->save(calendar(), d->mFileName);
0151 
0152     if (success) {
0153         calendar()->setModified(false);
0154     } else {
0155         if (!format->exception()) {
0156             qCDebug(KCALCORE_LOG) << "Error. There should be an exception set.";
0157         } else {
0158             qCDebug(KCALCORE_LOG) << int(format->exception()->code());
0159         }
0160     }
0161 
0162     if (!d->mSaveFormat) {
0163         delete format;
0164     }
0165 
0166     return success;
0167 }
0168 
0169 bool FileStorage::close()
0170 {
0171     return true;
0172 }
0173 
0174 #include "moc_filestorage.cpp"