libtdepim

tdeabcresourcecached.cpp
1/*
2 This file is part of libtdepim.
3 Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include <tqfile.h>
22
23#include <tdeabc/vcardconverter.h>
24#include <kdebug.h>
25#include <tdelocale.h>
26#include <tdestandarddirs.h>
27
28#include "tdeabcresourcecached.h"
29
30using namespace TDEABC;
31
32ResourceCached::ResourceCached( const TDEConfig *config )
33 : TDEABC::Resource( config ), mIdMapper( "tdeabc/uidmaps/" ),
34 mReloadPolicy( ReloadInterval ), mReloadInterval( 10 ),
35 mKABCReloadTimer( 0, "mKABCReloadTimer" ), mReloaded( false ),
36 mSavePolicy( SaveDelayed ), mSaveInterval( 10 ),
37 mKABCSaveTimer( 0, "mKABCSaveTimer" )
38{
39 connect( &mKABCReloadTimer, TQ_SIGNAL( timeout() ), TQ_SLOT( slotKABCReload() ) );
40 connect( &mKABCSaveTimer, TQ_SIGNAL( timeout() ), TQ_SLOT( slotKABCSave() ) );
41
42 if (config)
43 this->readConfig(const_cast<TDEConfig *>(config));
44}
45
46ResourceCached::~ResourceCached()
47{
48}
49
50void ResourceCached::setReloadPolicy( int i )
51{
52 mReloadPolicy = i;
53
54 setupReloadTimer();
55}
56
57int ResourceCached::reloadPolicy() const
58{
59 return mReloadPolicy;
60}
61
62void ResourceCached::setReloadInterval( int minutes )
63{
64 mReloadInterval = minutes;
65}
66
67int ResourceCached::reloadInterval() const
68{
69 return mReloadInterval;
70}
71
72void ResourceCached::setSavePolicy( int i )
73{
74 mSavePolicy = i;
75
76 setupSaveTimer();
77}
78
79int ResourceCached::savePolicy() const
80{
81 return mSavePolicy;
82}
83
84void ResourceCached::setSaveInterval( int minutes )
85{
86 mSaveInterval = minutes;
87}
88
89int ResourceCached::saveInterval() const
90{
91 return mSaveInterval;
92}
93
94void ResourceCached::writeConfig( TDEConfig *config )
95{
96 config->writeEntry( "ReloadPolicy", mReloadPolicy );
97 config->writeEntry( "ReloadInterval", mReloadInterval );
98
99 config->writeEntry( "SavePolicy", mSavePolicy );
100 config->writeEntry( "SaveInterval", mSaveInterval );
101
102 config->writeEntry( "LastLoad", mLastLoad );
103 config->writeEntry( "LastSave", mLastSave );
104
105 TDEABC::Resource::writeConfig( config );
106}
107
108void ResourceCached::readConfig( TDEConfig *config )
109{
110 mReloadPolicy = config->readNumEntry( "ReloadPolicy", ReloadNever );
111 mReloadInterval = config->readNumEntry( "ReloadInterval", 10 );
112
113 mSaveInterval = config->readNumEntry( "SaveInterval", 10 );
114 mSavePolicy = config->readNumEntry( "SavePolicy", SaveNever );
115
116 mLastLoad = config->readDateTimeEntry( "LastLoad" );
117 mLastSave = config->readDateTimeEntry( "LastSave" );
118
119 setupSaveTimer();
120 setupReloadTimer();
121}
122
123void ResourceCached::setupSaveTimer()
124{
125 if ( mSavePolicy == SaveInterval ) {
126 kdDebug(5800) << "ResourceCached::setSavePolicy(): start save timer (interval "
127 << mSaveInterval << " minutes)." << endl;
128 mKABCSaveTimer.start( mSaveInterval * 60 * 1000 ); // n minutes
129 } else {
130 mKABCSaveTimer.stop();
131 }
132}
133
134void ResourceCached::setupReloadTimer()
135{
136 if ( mReloadPolicy == ReloadInterval ) {
137 kdDebug(5800) << "ResourceCached::setSavePolicy(): start reload timer "
138 "(interval " << mReloadInterval << " minutes)" << endl;
139 mKABCReloadTimer.start( mReloadInterval * 60 * 1000 ); // n minutes
140 } else {
141 mKABCReloadTimer.stop();
142 }
143}
144
145void ResourceCached::slotKABCReload()
146{
147 if ( !isActive() ) return;
148
149 kdDebug(5800) << "ResourceCached::slotKABCReload()" << endl;
150
151 load();
152}
153
154void ResourceCached::slotKABCSave()
155{
156 if ( !isActive() ) return;
157
158 kdDebug(5800) << "ResourceCached::slotKABCSave()" << endl;
159
160 TDEABC::Ticket *ticket = requestSaveTicket();
161 if ( ticket ) {
162 save( ticket );
163 }
164}
165
166void ResourceCached::insertAddressee( const Addressee &addr )
167{
168 if ( !mAddrMap.contains( addr.uid() ) ) { // new contact
169 if ( mDeletedAddressees.contains( addr.uid() ) ) {
170 // it was first removed, then added, so it's an update...
171 mDeletedAddressees.remove( addr.uid() );
172
173 mAddrMap.insert( addr.uid(), addr );
174 mChangedAddressees.insert( addr.uid(), addr );
175 return;
176 }
177
178 mAddrMap.insert( addr.uid(), addr );
179 mAddedAddressees.insert( addr.uid(), addr );
180 } else {
181 TDEABC::Addressee oldAddressee = mAddrMap.find( addr.uid() ).data();
182 if ( oldAddressee != addr ) {
183 mAddrMap.remove( addr.uid() );
184 mAddrMap.insert( addr.uid(), addr );
185 mChangedAddressees.insert( addr.uid(), addr );
186 }
187 }
188}
189
190void ResourceCached::removeAddressee( const Addressee &addr )
191{
192 if ( mAddedAddressees.contains( addr.uid() ) ) {
193 mAddedAddressees.remove( addr.uid() );
194 return;
195 }
196
197 if ( mDeletedAddressees.find( addr.uid() ) == mDeletedAddressees.end() )
198 mDeletedAddressees.insert( addr.uid(), addr );
199
200 mAddrMap.remove( addr.uid() );
201}
202
203void ResourceCached::loadCache()
204{
205 mAddrMap.clear();
206
207 setIdMapperIdentifier();
208 mIdMapper.load();
209
210 // load cache
211 TQFile file( cacheFile() );
212 if ( !file.open( IO_ReadOnly ) )
213 return;
214
215
216 TDEABC::VCardConverter converter;
217#if defined(KABC_VCARD_ENCODING_FIX)
218 TDEABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() );
219#else
220 TQTextStream s( &file );
221 s.setEncoding( TQTextStream::UnicodeUTF8 );
222 TDEABC::Addressee::List list = converter.parseVCards( s.read() );
223#endif
224 TDEABC::Addressee::List::Iterator it;
225
226 for ( it = list.begin(); it != list.end(); ++it ) {
227 (*it).setResource( this );
228 (*it).setChanged( false );
229 mAddrMap.insert( (*it).uid(), *it );
230 }
231
232 file.close();
233}
234
235void ResourceCached::saveCache()
236{
237 setIdMapperIdentifier();
238 mIdMapper.save();
239
240 // save cache
241 TQFile file( cacheFile() );
242 if ( !file.open( IO_WriteOnly ) )
243 return;
244
245 TDEABC::Addressee::List list = mAddrMap.values();
246
247 TDEABC::VCardConverter converter;
248#if defined(KABC_VCARD_ENCODING_FIX)
249 TQCString vCard = converter.createVCardsRaw( list );
250 file.writeBlock( vCard, vCard.length() );
251#else
252 TQString vCard = converter.createVCards( list );
253 file.writeBlock( vCard.utf8(), vCard.utf8().length() );
254#endif
255 file.close();
256}
257
258void ResourceCached::clearCache()
259{
260 // TEST ME
261 mAddrMap.clear();
262}
263
264void ResourceCached::cleanUpCache( const TDEABC::Addressee::List &addrList )
265{
266 // load cache
267 TQFile file( cacheFile() );
268 if ( !file.open( IO_ReadOnly ) )
269 return;
270
271
272 TDEABC::VCardConverter converter;
273#if defined(KABC_VCARD_ENCODING_FIX)
274 TDEABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() );
275#else
276 TQTextStream s( &file );
277 s.setEncoding( TQTextStream::UnicodeUTF8 );
278 TDEABC::Addressee::List list = converter.parseVCards( s.read() );
279#endif
280 TDEABC::Addressee::List::Iterator cacheIt;
281 TDEABC::Addressee::List::ConstIterator it;
282
283 for ( cacheIt = list.begin(); cacheIt != list.end(); ++cacheIt ) {
284 bool found = false;
285 for ( it = addrList.begin(); it != addrList.end(); ++it ) {
286 if ( (*it).uid() == (*cacheIt).uid() )
287 found = true;
288 }
289
290 if ( !found ) {
291 mIdMapper.removeRemoteId( mIdMapper.remoteId( (*cacheIt).uid() ) );
292 mAddrMap.remove( (*cacheIt).uid() );
293 }
294 }
295
296 file.close();
297}
298
299KPIM::IdMapper& ResourceCached::idMapper()
300{
301 return mIdMapper;
302}
303
304bool ResourceCached::hasChanges() const
305{
306 return !( mAddedAddressees.isEmpty() &&
307 mChangedAddressees.isEmpty() &&
308 mDeletedAddressees.isEmpty() );
309}
310
311void ResourceCached::clearChanges()
312{
313 mAddedAddressees.clear();
314 mChangedAddressees.clear();
315 mDeletedAddressees.clear();
316}
317
318void ResourceCached::clearChange( const TDEABC::Addressee &addr )
319{
320 mAddedAddressees.remove( addr.uid() );
321 mChangedAddressees.remove( addr.uid() );
322 mDeletedAddressees.remove( addr.uid() );
323}
324
325void ResourceCached::clearChange( const TQString &uid )
326{
327 mAddedAddressees.remove( uid );
328 mChangedAddressees.remove( uid );
329 mDeletedAddressees.remove( uid );
330}
331
332TDEABC::Addressee::List ResourceCached::addedAddressees() const
333{
334 return mAddedAddressees.values();
335}
336
337TDEABC::Addressee::List ResourceCached::changedAddressees() const
338{
339 return mChangedAddressees.values();
340}
341
342TDEABC::Addressee::List ResourceCached::deletedAddressees() const
343{
344 return mDeletedAddressees.values();
345}
346
347TQString ResourceCached::cacheFile() const
348{
349 return locateLocal( "cache", "tdeabc/tderesources/" + identifier() );
350}
351
352TQString ResourceCached::changesCacheFile( const TQString &type ) const
353{
354 return locateLocal( "cache", "tdeabc/changescache/" + identifier() + "_" + type );
355}
356
357void ResourceCached::saveChangesCache( const TQMap<TQString, TDEABC::Addressee> &map, const TQString &type )
358{
359 TQFile file( changesCacheFile( type ) );
360
361 const TDEABC::Addressee::List list = map.values();
362 if ( list.isEmpty() ) {
363 file.remove();
364 } else {
365 if ( !file.open( IO_WriteOnly ) ) {
366 kdError() << "Can't open changes cache file '" << file.name() << "' for saving." << endl;
367 return;
368 }
369
370 TDEABC::VCardConverter converter;
371#if defined(KABC_VCARD_ENCODING_FIX)
372 const TQCString vCards = converter.createVCardsRaw( list );
373 file.writeBlock( vCards, vCards.length() );
374#else
375 const TQString vCards = converter.createVCards( list );
376 TQCString content = vCards.utf8();
377 file.writeBlock( content, content.length() );
378#endif
379 }
380}
381
382void ResourceCached::saveChangesCache()
383{
384 saveChangesCache( mAddedAddressees, "added" );
385 saveChangesCache( mDeletedAddressees, "deleted" );
386 saveChangesCache( mChangedAddressees, "changed" );
387}
388
389void ResourceCached::loadChangesCache( TQMap<TQString, TDEABC::Addressee> &map, const TQString &type )
390{
391 TQFile file( changesCacheFile( type ) );
392 if ( !file.open( IO_ReadOnly ) )
393 return;
394
395 TDEABC::VCardConverter converter;
396
397#if defined(KABC_VCARD_ENCODING_FIX)
398 const TDEABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() );
399#else
400 TQTextStream s( &file );
401 s.setEncoding( TQTextStream::UnicodeUTF8 );
402 const TDEABC::Addressee::List list = converter.parseVCards( s.read() );
403#endif
404 TDEABC::Addressee::List::ConstIterator it;
405 for ( it = list.begin(); it != list.end(); ++it )
406 map.insert( (*it).uid(), *it );
407
408 file.close();
409}
410
411void ResourceCached::loadChangesCache()
412{
413 loadChangesCache( mAddedAddressees, "added" );
414 loadChangesCache( mDeletedAddressees, "deleted" );
415 loadChangesCache( mChangedAddressees, "changed" );
416}
417
418void ResourceCached::setIdMapperIdentifier()
419{
420 mIdMapper.setIdentifier( type() + "_" + identifier() );
421}
422
423#include "tdeabcresourcecached.moc"