1 | /* |
2 | This file is part of the kcal library. |
3 | |
4 | Copyright (c) 1998 Preston Brown <pbrown@kde.org> |
5 | Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org> |
6 | |
7 | This library is free software; you can redistribute it and/or |
8 | modify it under the terms of the GNU Library General Public |
9 | License as published by the Free Software Foundation; either |
10 | version 2 of the License, or (at your option) any later version. |
11 | |
12 | This library is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | Library General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU Library General Public License |
18 | along with this library; see the file COPYING.LIB. If not, write to |
19 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 | Boston, MA 02110-1301, USA. |
21 | */ |
22 | /** |
23 | @file |
24 | This file is part of the API for handling calendar data and |
25 | defines the ResourceLocal class. |
26 | |
27 | @author Preston Brown <pbrown@kde.org> |
28 | @author Cornelius Schumacher <schumacher@kde.org> |
29 | */ |
30 | |
31 | #include "resourcelocal.h" |
32 | #include "resourcelocal_p.h" |
33 | #include "resourcelocalconfig.h" |
34 | #include "vcalformat.h" |
35 | #include "icalformat.h" |
36 | #include "calendarlocal.h" |
37 | #include "exceptions.h" |
38 | #include "incidence.h" |
39 | #include "event.h" |
40 | #include "todo.h" |
41 | #include "journal.h" |
42 | |
43 | #include <kresources/configwidget.h> |
44 | |
45 | #include <typeinfo> |
46 | #include <stdlib.h> |
47 | |
48 | #include <QtCore/QString> |
49 | |
50 | #include <kdebug.h> |
51 | #include <klocalizedstring.h> |
52 | #include <kurl.h> |
53 | #include <kdirwatch.h> |
54 | #include <kstandarddirs.h> |
55 | #include <kconfiggroup.h> |
56 | |
57 | |
58 | using namespace KCal; |
59 | |
60 | ResourceLocal::ResourceLocal() |
61 | : ResourceCached(), d( new ResourceLocal::Private() ) |
62 | { |
63 | d->mLock = 0; |
64 | d->mURL = KUrl(); |
65 | d->mFormat = new ICalFormat(); |
66 | init(); |
67 | } |
68 | |
69 | ResourceLocal::ResourceLocal( const KConfigGroup &group ) |
70 | : ResourceCached( group ), d( new ResourceLocal::Private() ) |
71 | { |
72 | d->mLock = 0; |
73 | QString url = group.readPathEntry( "CalendarURL" , QString() ); |
74 | d->mURL = KUrl( url ); |
75 | |
76 | QString format = group.readEntry( "Format" ); |
77 | if ( format == "ical" ) { |
78 | d->mFormat = new ICalFormat(); |
79 | } else if ( format == "vcal" ) { |
80 | d->mFormat = new VCalFormat(); |
81 | } else { |
82 | d->mFormat = new ICalFormat(); |
83 | } |
84 | init(); |
85 | } |
86 | |
87 | ResourceLocal::ResourceLocal( const QString &fileName ) |
88 | : ResourceCached(), d( new ResourceLocal::Private ) |
89 | { |
90 | d->mURL = KUrl::fromPath( fileName ); |
91 | d->mFormat = new ICalFormat(); |
92 | init(); |
93 | } |
94 | |
95 | void ResourceLocal::writeConfig( KConfigGroup &group ) |
96 | { |
97 | kDebug(); |
98 | |
99 | ResourceCalendar::writeConfig( group ); |
100 | group.writePathEntry( "CalendarURL" , d->mURL.prettyUrl() ); |
101 | |
102 | if ( typeid( *d->mFormat ) == typeid( ICalFormat ) ) { |
103 | group.writeEntry( "Format" , "ical" ); |
104 | } else if ( typeid( *d->mFormat ) == typeid( VCalFormat ) ) { |
105 | group.writeEntry( "Format" , "vcal" ); |
106 | } else { |
107 | kDebug() << "ERROR: Unknown format type" ; |
108 | } |
109 | } |
110 | |
111 | void ResourceLocal::init() |
112 | { |
113 | |
114 | setType( "file" ); |
115 | |
116 | setSavePolicy( SaveDelayed ); |
117 | |
118 | connect( &d->mDirWatch, SIGNAL(dirty(QString)), |
119 | SLOT(reload()) ); |
120 | connect( &d->mDirWatch, SIGNAL(created(QString)), |
121 | SLOT(reload()) ); |
122 | connect( &d->mDirWatch, SIGNAL(deleted(QString)), |
123 | SLOT(reload()) ); |
124 | |
125 | d->mLock = new KABC::Lock( d->mURL.path() ); |
126 | |
127 | d->mDirWatch.addFile( d->mURL.path() ); |
128 | d->mDirWatch.startScan(); |
129 | } |
130 | |
131 | ResourceLocal::~ResourceLocal() |
132 | { |
133 | d->mDirWatch.stopScan(); |
134 | close(); |
135 | |
136 | delete d->mLock; |
137 | delete d; |
138 | } |
139 | |
140 | KDateTime ResourceLocal::readLastModified() |
141 | { |
142 | QFileInfo fi( d->mURL.path() ); |
143 | return KDateTime( fi.lastModified() ); // use local time zone |
144 | } |
145 | |
146 | bool ResourceLocal::doLoad( bool syncCache ) |
147 | { |
148 | Q_UNUSED( syncCache ); |
149 | |
150 | bool success; |
151 | if ( !KStandardDirs::exists( d->mURL.path() ) ) { |
152 | kDebug() << "File doesn't exist yet." ; |
153 | // Save the empty calendar, so the calendar file will be created. |
154 | success = doSave( true ); |
155 | } else { |
156 | success = calendar()->load( d->mURL.path() ); |
157 | if ( success ) { |
158 | d->mLastModified = readLastModified(); |
159 | } |
160 | } |
161 | |
162 | return success; |
163 | } |
164 | |
165 | bool ResourceLocal::doSave( bool syncCache ) |
166 | { |
167 | Q_UNUSED( syncCache ); |
168 | bool success = calendar()->save( d->mURL.path() ); |
169 | kDebug() << "Save of " << d->mURL.path() << "was " << success; |
170 | d->mLastModified = readLastModified(); |
171 | |
172 | return success; |
173 | } |
174 | |
175 | bool ResourceLocal::doSave( bool syncCache, Incidence *incidence ) |
176 | { |
177 | return ResourceCached::doSave( syncCache, incidence ); |
178 | } |
179 | |
180 | KABC::Lock *ResourceLocal::lock() |
181 | { |
182 | return d->mLock; |
183 | } |
184 | |
185 | bool ResourceLocal::doReload() |
186 | { |
187 | kDebug(); |
188 | |
189 | if ( !isOpen() ) { |
190 | kDebug() << "trying to reload from a closed file" ; |
191 | return false; |
192 | } |
193 | |
194 | if ( d->mLastModified == readLastModified() ) { |
195 | kDebug() << "file not modified since last read." ; |
196 | return false; |
197 | } |
198 | |
199 | calendar()->close(); |
200 | calendar()->load( d->mURL.path() ); |
201 | return true; |
202 | } |
203 | |
204 | void ResourceLocal::reload() |
205 | { |
206 | if ( doReload() ) { |
207 | emit resourceChanged( this ); |
208 | } |
209 | } |
210 | |
211 | void ResourceLocal::dump() const |
212 | { |
213 | ResourceCalendar::dump(); |
214 | kDebug() << " Url:" << d->mURL.url(); |
215 | } |
216 | |
217 | QString ResourceLocal::fileName() const |
218 | { |
219 | return d->mURL.path(); |
220 | } |
221 | |
222 | bool ResourceLocal::setFileName( const QString &fileName ) |
223 | { |
224 | bool open = isOpen(); |
225 | if ( open ) { |
226 | close(); |
227 | } |
228 | delete d->mLock; |
229 | d->mDirWatch.stopScan(); |
230 | d->mDirWatch.removeFile( d->mURL.path() ); |
231 | d->mURL = KUrl::fromPath( fileName ); |
232 | d->mLock = new KABC::Lock( d->mURL.path() ); |
233 | d->mDirWatch.addFile( d->mURL.path() ); |
234 | d->mDirWatch.startScan(); |
235 | return true; |
236 | } |
237 | |
238 | bool ResourceLocal::setValue( const QString &key, const QString &value ) |
239 | { |
240 | if ( key == "File" ) { |
241 | return setFileName( value ); |
242 | } else { |
243 | return false; |
244 | } |
245 | } |
246 | |
247 | bool ResourceLocal::operator==( const ResourceLocal &other ) |
248 | { |
249 | return |
250 | d->mURL == other.d->mURL && |
251 | d->mLastModified == other.d->mLastModified; |
252 | } |
253 | |
254 | ResourceLocal &ResourceLocal::operator=( const ResourceLocal &other ) |
255 | { |
256 | // check for self assignment |
257 | if ( &other == this ) { |
258 | return *this; |
259 | } |
260 | |
261 | d->mURL = other.d->mURL; |
262 | d->mLastModified = other.d->mLastModified; |
263 | return *this; |
264 | } |
265 | |