libkdepim

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"