kabcresourcecached.cpp
00001 /* 00002 This file is part of libkdepim. 00003 Copyright (c) 2004 Tobias Koenig <tokoe@kde.org> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include <tqfile.h> 00022 00023 #include <kabc/vcardconverter.h> 00024 #include <kdebug.h> 00025 #include <klocale.h> 00026 #include <kstandarddirs.h> 00027 00028 #include "kabcresourcecached.h" 00029 00030 using namespace KABC; 00031 00032 ResourceCached::ResourceCached( const KConfig *config ) 00033 : KABC::Resource( config ), mIdMapper( "kabc/uidmaps/" ), 00034 mReloadPolicy( ReloadInterval ), mReloadInterval( 10 ), 00035 mKABCReloadTimer( 0, "mKABCReloadTimer" ), mReloaded( false ), 00036 mSavePolicy( SaveDelayed ), mSaveInterval( 10 ), 00037 mKABCSaveTimer( 0, "mKABCSaveTimer" ) 00038 { 00039 connect( &mKABCReloadTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotKABCReload() ) ); 00040 connect( &mKABCSaveTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotKABCSave() ) ); 00041 00042 if (config) 00043 this->readConfig(const_cast<KConfig *>(config)); 00044 } 00045 00046 ResourceCached::~ResourceCached() 00047 { 00048 } 00049 00050 void ResourceCached::setReloadPolicy( int i ) 00051 { 00052 mReloadPolicy = i; 00053 00054 setupReloadTimer(); 00055 } 00056 00057 int ResourceCached::reloadPolicy() const 00058 { 00059 return mReloadPolicy; 00060 } 00061 00062 void ResourceCached::setReloadInterval( int minutes ) 00063 { 00064 mReloadInterval = minutes; 00065 } 00066 00067 int ResourceCached::reloadInterval() const 00068 { 00069 return mReloadInterval; 00070 } 00071 00072 void ResourceCached::setSavePolicy( int i ) 00073 { 00074 mSavePolicy = i; 00075 00076 setupSaveTimer(); 00077 } 00078 00079 int ResourceCached::savePolicy() const 00080 { 00081 return mSavePolicy; 00082 } 00083 00084 void ResourceCached::setSaveInterval( int minutes ) 00085 { 00086 mSaveInterval = minutes; 00087 } 00088 00089 int ResourceCached::saveInterval() const 00090 { 00091 return mSaveInterval; 00092 } 00093 00094 void ResourceCached::writeConfig( KConfig *config ) 00095 { 00096 config->writeEntry( "ReloadPolicy", mReloadPolicy ); 00097 config->writeEntry( "ReloadInterval", mReloadInterval ); 00098 00099 config->writeEntry( "SavePolicy", mSavePolicy ); 00100 config->writeEntry( "SaveInterval", mSaveInterval ); 00101 00102 config->writeEntry( "LastLoad", mLastLoad ); 00103 config->writeEntry( "LastSave", mLastSave ); 00104 00105 KABC::Resource::writeConfig( config ); 00106 } 00107 00108 void ResourceCached::readConfig( KConfig *config ) 00109 { 00110 mReloadPolicy = config->readNumEntry( "ReloadPolicy", ReloadNever ); 00111 mReloadInterval = config->readNumEntry( "ReloadInterval", 10 ); 00112 00113 mSaveInterval = config->readNumEntry( "SaveInterval", 10 ); 00114 mSavePolicy = config->readNumEntry( "SavePolicy", SaveNever ); 00115 00116 mLastLoad = config->readDateTimeEntry( "LastLoad" ); 00117 mLastSave = config->readDateTimeEntry( "LastSave" ); 00118 00119 setupSaveTimer(); 00120 setupReloadTimer(); 00121 } 00122 00123 void ResourceCached::setupSaveTimer() 00124 { 00125 if ( mSavePolicy == SaveInterval ) { 00126 kdDebug(5800) << "ResourceCached::setSavePolicy(): start save timer (interval " 00127 << mSaveInterval << " minutes)." << endl; 00128 mKABCSaveTimer.start( mSaveInterval * 60 * 1000 ); // n minutes 00129 } else { 00130 mKABCSaveTimer.stop(); 00131 } 00132 } 00133 00134 void ResourceCached::setupReloadTimer() 00135 { 00136 if ( mReloadPolicy == ReloadInterval ) { 00137 kdDebug(5800) << "ResourceCached::setSavePolicy(): start reload timer " 00138 "(interval " << mReloadInterval << " minutes)" << endl; 00139 mKABCReloadTimer.start( mReloadInterval * 60 * 1000 ); // n minutes 00140 } else { 00141 mKABCReloadTimer.stop(); 00142 } 00143 } 00144 00145 void ResourceCached::slotKABCReload() 00146 { 00147 if ( !isActive() ) return; 00148 00149 kdDebug(5800) << "ResourceCached::slotKABCReload()" << endl; 00150 00151 load(); 00152 } 00153 00154 void ResourceCached::slotKABCSave() 00155 { 00156 if ( !isActive() ) return; 00157 00158 kdDebug(5800) << "ResourceCached::slotKABCSave()" << endl; 00159 00160 KABC::Ticket *ticket = requestSaveTicket(); 00161 if ( ticket ) { 00162 save( ticket ); 00163 } 00164 } 00165 00166 void ResourceCached::insertAddressee( const Addressee &addr ) 00167 { 00168 if ( !mAddrMap.contains( addr.uid() ) ) { // new contact 00169 if ( mDeletedAddressees.contains( addr.uid() ) ) { 00170 // it was first removed, then added, so it's an update... 00171 mDeletedAddressees.remove( addr.uid() ); 00172 00173 mAddrMap.insert( addr.uid(), addr ); 00174 mChangedAddressees.insert( addr.uid(), addr ); 00175 return; 00176 } 00177 00178 mAddrMap.insert( addr.uid(), addr ); 00179 mAddedAddressees.insert( addr.uid(), addr ); 00180 } else { 00181 KABC::Addressee oldAddressee = mAddrMap.find( addr.uid() ).data(); 00182 if ( oldAddressee != addr ) { 00183 mAddrMap.remove( addr.uid() ); 00184 mAddrMap.insert( addr.uid(), addr ); 00185 mChangedAddressees.insert( addr.uid(), addr ); 00186 } 00187 } 00188 } 00189 00190 void ResourceCached::removeAddressee( const Addressee &addr ) 00191 { 00192 if ( mAddedAddressees.contains( addr.uid() ) ) { 00193 mAddedAddressees.remove( addr.uid() ); 00194 return; 00195 } 00196 00197 if ( mDeletedAddressees.find( addr.uid() ) == mDeletedAddressees.end() ) 00198 mDeletedAddressees.insert( addr.uid(), addr ); 00199 00200 mAddrMap.remove( addr.uid() ); 00201 } 00202 00203 void ResourceCached::loadCache() 00204 { 00205 mAddrMap.clear(); 00206 00207 setIdMapperIdentifier(); 00208 mIdMapper.load(); 00209 00210 // load cache 00211 TQFile file( cacheFile() ); 00212 if ( !file.open( IO_ReadOnly ) ) 00213 return; 00214 00215 00216 KABC::VCardConverter converter; 00217 #if defined(KABC_VCARD_ENCODING_FIX) 00218 KABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() ); 00219 #else 00220 KABC::Addressee::List list = converter.parseVCards( TQString::fromUtf8( file.readAll() ) ); 00221 #endif 00222 KABC::Addressee::List::Iterator it; 00223 00224 for ( it = list.begin(); it != list.end(); ++it ) { 00225 (*it).setResource( this ); 00226 (*it).setChanged( false ); 00227 mAddrMap.insert( (*it).uid(), *it ); 00228 } 00229 00230 file.close(); 00231 } 00232 00233 void ResourceCached::saveCache() 00234 { 00235 setIdMapperIdentifier(); 00236 mIdMapper.save(); 00237 00238 // save cache 00239 TQFile file( cacheFile() ); 00240 if ( !file.open( IO_WriteOnly ) ) 00241 return; 00242 00243 KABC::Addressee::List list = mAddrMap.values(); 00244 00245 KABC::VCardConverter converter; 00246 #if defined(KABC_VCARD_ENCODING_FIX) 00247 TQCString vCard = converter.createVCardsRaw( list ); 00248 file.writeBlock( vCard, vCard.length() ); 00249 #else 00250 TQString vCard = converter.createVCards( list ); 00251 file.writeBlock( vCard.utf8(), vCard.utf8().length() ); 00252 #endif 00253 file.close(); 00254 } 00255 00256 void ResourceCached::clearCache() 00257 { 00258 // TEST ME 00259 mAddrMap.clear(); 00260 } 00261 00262 void ResourceCached::cleanUpCache( const KABC::Addressee::List &addrList ) 00263 { 00264 // load cache 00265 TQFile file( cacheFile() ); 00266 if ( !file.open( IO_ReadOnly ) ) 00267 return; 00268 00269 00270 KABC::VCardConverter converter; 00271 #if defined(KABC_VCARD_ENCODING_FIX) 00272 KABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() ); 00273 #else 00274 KABC::Addressee::List list = converter.parseVCards( TQString::fromUtf8( file.readAll() ) ); 00275 #endif 00276 KABC::Addressee::List::Iterator cacheIt; 00277 KABC::Addressee::List::ConstIterator it; 00278 00279 for ( cacheIt = list.begin(); cacheIt != list.end(); ++cacheIt ) { 00280 bool found = false; 00281 for ( it = addrList.begin(); it != addrList.end(); ++it ) { 00282 if ( (*it).uid() == (*cacheIt).uid() ) 00283 found = true; 00284 } 00285 00286 if ( !found ) { 00287 mIdMapper.removeRemoteId( mIdMapper.remoteId( (*cacheIt).uid() ) ); 00288 mAddrMap.remove( (*cacheIt).uid() ); 00289 } 00290 } 00291 00292 file.close(); 00293 } 00294 00295 KPIM::IdMapper& ResourceCached::idMapper() 00296 { 00297 return mIdMapper; 00298 } 00299 00300 bool ResourceCached::hasChanges() const 00301 { 00302 return !( mAddedAddressees.isEmpty() && 00303 mChangedAddressees.isEmpty() && 00304 mDeletedAddressees.isEmpty() ); 00305 } 00306 00307 void ResourceCached::clearChanges() 00308 { 00309 mAddedAddressees.clear(); 00310 mChangedAddressees.clear(); 00311 mDeletedAddressees.clear(); 00312 } 00313 00314 void ResourceCached::clearChange( const KABC::Addressee &addr ) 00315 { 00316 mAddedAddressees.remove( addr.uid() ); 00317 mChangedAddressees.remove( addr.uid() ); 00318 mDeletedAddressees.remove( addr.uid() ); 00319 } 00320 00321 void ResourceCached::clearChange( const TQString &uid ) 00322 { 00323 mAddedAddressees.remove( uid ); 00324 mChangedAddressees.remove( uid ); 00325 mDeletedAddressees.remove( uid ); 00326 } 00327 00328 KABC::Addressee::List ResourceCached::addedAddressees() const 00329 { 00330 return mAddedAddressees.values(); 00331 } 00332 00333 KABC::Addressee::List ResourceCached::changedAddressees() const 00334 { 00335 return mChangedAddressees.values(); 00336 } 00337 00338 KABC::Addressee::List ResourceCached::deletedAddressees() const 00339 { 00340 return mDeletedAddressees.values(); 00341 } 00342 00343 TQString ResourceCached::cacheFile() const 00344 { 00345 return locateLocal( "cache", "kabc/kresources/" + identifier() ); 00346 } 00347 00348 TQString ResourceCached::changesCacheFile( const TQString &type ) const 00349 { 00350 return locateLocal( "cache", "kabc/changescache/" + identifier() + "_" + type ); 00351 } 00352 00353 void ResourceCached::saveChangesCache( const TQMap<TQString, KABC::Addressee> &map, const TQString &type ) 00354 { 00355 TQFile file( changesCacheFile( type ) ); 00356 00357 const KABC::Addressee::List list = map.values(); 00358 if ( list.isEmpty() ) { 00359 file.remove(); 00360 } else { 00361 if ( !file.open( IO_WriteOnly ) ) { 00362 kdError() << "Can't open changes cache file '" << file.name() << "' for saving." << endl; 00363 return; 00364 } 00365 00366 KABC::VCardConverter converter; 00367 #if defined(KABC_VCARD_ENCODING_FIX) 00368 const TQCString vCards = converter.createVCardsRaw( list ); 00369 file.writeBlock( vCards, vCards.length() ); 00370 #else 00371 const TQString vCards = converter.createVCards( list ); 00372 TQCString content = vCards.utf8(); 00373 file.writeBlock( content, content.length() ); 00374 #endif 00375 } 00376 } 00377 00378 void ResourceCached::saveChangesCache() 00379 { 00380 saveChangesCache( mAddedAddressees, "added" ); 00381 saveChangesCache( mDeletedAddressees, "deleted" ); 00382 saveChangesCache( mChangedAddressees, "changed" ); 00383 } 00384 00385 void ResourceCached::loadChangesCache( TQMap<TQString, KABC::Addressee> &map, const TQString &type ) 00386 { 00387 TQFile file( changesCacheFile( type ) ); 00388 if ( !file.open( IO_ReadOnly ) ) 00389 return; 00390 00391 KABC::VCardConverter converter; 00392 00393 #if defined(KABC_VCARD_ENCODING_FIX) 00394 const KABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() ); 00395 #else 00396 const KABC::Addressee::List list = converter.parseVCards( TQString::fromUtf8( file.readAll() ) ); 00397 #endif 00398 KABC::Addressee::List::ConstIterator it; 00399 for ( it = list.begin(); it != list.end(); ++it ) 00400 map.insert( (*it).uid(), *it ); 00401 00402 file.close(); 00403 } 00404 00405 void ResourceCached::loadChangesCache() 00406 { 00407 loadChangesCache( mAddedAddressees, "added" ); 00408 loadChangesCache( mDeletedAddressees, "deleted" ); 00409 loadChangesCache( mChangedAddressees, "changed" ); 00410 } 00411 00412 void ResourceCached::setIdMapperIdentifier() 00413 { 00414 mIdMapper.setIdentifier( type() + "_" + identifier() ); 00415 } 00416 00417 #include "kabcresourcecached.moc"