1/*
2 This file is part of the kcalcore library.
3
4 Copyright (c) 2002 Cornelius Schumacher <schumacher@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21/**
22 @file
23 This file is part of the API for handling calendar data and
24 defines the FileStorage class.
25
26 @brief
27 This class provides a calendar storage as a local file.
28
29 @author Cornelius Schumacher \<schumacher@kde.org\>
30*/
31#include "filestorage.h"
32#include "exceptions.h"
33#include "icalformat.h"
34#include "memorycalendar.h"
35#include "vcalformat.h"
36
37#include <KDebug>
38
39using namespace KCalCore;
40
41/*
42 Private class that helps to provide binary compatibility between releases.
43*/
44//@cond PRIVATE
45class KCalCore::FileStorage::Private
46{
47public:
48 Private(const QString &fileName, CalFormat *format)
49 : mFileName(fileName),
50 mSaveFormat(format)
51 {}
52 ~Private() {
53 delete mSaveFormat;
54 }
55
56 QString mFileName;
57 CalFormat *mSaveFormat;
58};
59//@endcond
60
61FileStorage::FileStorage(const Calendar::Ptr &cal, const QString &fileName,
62 CalFormat *format)
63 : CalStorage(cal),
64 d(new Private(fileName, format))
65{
66}
67
68FileStorage::~FileStorage()
69{
70 delete d;
71}
72
73void FileStorage::setFileName(const QString &fileName)
74{
75 d->mFileName = fileName;
76}
77
78QString FileStorage::fileName() const
79{
80 return d->mFileName;
81}
82
83void FileStorage::setSaveFormat(CalFormat *format)
84{
85 delete d->mSaveFormat;
86 d->mSaveFormat = format;
87}
88
89CalFormat *FileStorage::saveFormat() const
90{
91 return d->mSaveFormat;
92}
93
94bool FileStorage::open()
95{
96 return true;
97}
98
99bool FileStorage::load()
100{
101 if (d->mFileName.isEmpty()) {
102 kWarning() << "Empty filename while trying to load";
103 return false;
104 }
105
106 // Always try to load with iCalendar. It will detect, if it is actually a
107 // vCalendar file.
108 bool success;
109 QString productId;
110 // First try the supplied format. Otherwise fall through to iCalendar, then
111 // to vCalendar
112 success = saveFormat() && saveFormat()->load(calendar(), d->mFileName);
113 if (success) {
114 productId = saveFormat()->loadedProductId();
115 } else {
116 ICalFormat iCal;
117
118 success = iCal.load(calendar(), d->mFileName);
119
120 if (success) {
121 productId = iCal.loadedProductId();
122 } else {
123 if (iCal.exception()) {
124 if (iCal.exception()->code() == Exception::CalVersion1) {
125 // Expected non vCalendar file, but detected vCalendar
126 kDebug() << "Fallback to VCalFormat";
127 VCalFormat vCal;
128 success = vCal.load(calendar(), d->mFileName);
129 productId = vCal.loadedProductId();
130 if (!success) {
131 if (vCal.exception()) {
132 kWarning() << "Exception while importing:" << vCal.exception()->code();
133 }
134 return false;
135 }
136 } else {
137 return false;
138 }
139 } else {
140 kWarning() << "There should be an exception set.";
141 return false;
142 }
143 }
144 }
145
146 calendar()->setProductId(productId);
147 calendar()->setModified(false);
148
149 return true;
150}
151
152bool FileStorage::save()
153{
154 kDebug();
155 if (d->mFileName.isEmpty()) {
156 return false;
157 }
158
159 CalFormat *format = d->mSaveFormat ? d->mSaveFormat : new ICalFormat;
160
161 bool success = format->save(calendar(), d->mFileName);
162
163 if (success) {
164 calendar()->setModified(false);
165 } else {
166 if (!format->exception()) {
167 kDebug() << "Error. There should be an expection set.";
168 } else {
169 kDebug() << int(format->exception()->code());
170 }
171 }
172
173 if (!d->mSaveFormat) {
174 delete format;
175 }
176
177 return success;
178}
179
180bool FileStorage::close()
181{
182 return true;
183}
184