libtdepim

tdeabcresourcecached.cpp

00001 /*
00002     This file is part of libtdepim.
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 <tdeabc/vcardconverter.h>
00024 #include <kdebug.h>
00025 #include <tdelocale.h>
00026 #include <kstandarddirs.h>
00027 
00028 #include "tdeabcresourcecached.h"
00029 
00030 using namespace TDEABC;
00031 
00032 ResourceCached::ResourceCached( const TDEConfig *config )
00033   : TDEABC::Resource( config ), mIdMapper( "tdeabc/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<TDEConfig *>(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( TDEConfig *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   TDEABC::Resource::writeConfig( config );
00106 }
00107 
00108 void ResourceCached::readConfig( TDEConfig *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   TDEABC::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     TDEABC::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   TDEABC::VCardConverter converter;
00217 #if defined(KABC_VCARD_ENCODING_FIX)
00218   TDEABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() );
00219 #else
00220   TQTextStream s( &file );
00221   s.setEncoding( TQTextStream::UnicodeUTF8 );
00222   TDEABC::Addressee::List list = converter.parseVCards( s.read() );
00223 #endif
00224   TDEABC::Addressee::List::Iterator it;
00225 
00226   for ( it = list.begin(); it != list.end(); ++it ) {
00227     (*it).setResource( this );
00228     (*it).setChanged( false );
00229     mAddrMap.insert( (*it).uid(), *it );
00230   }
00231 
00232   file.close();
00233 }
00234 
00235 void ResourceCached::saveCache()
00236 {
00237   setIdMapperIdentifier();
00238   mIdMapper.save();
00239 
00240   // save cache
00241   TQFile file( cacheFile() );
00242   if ( !file.open( IO_WriteOnly ) )
00243     return;
00244 
00245   TDEABC::Addressee::List list = mAddrMap.values();
00246 
00247   TDEABC::VCardConverter converter;
00248 #if defined(KABC_VCARD_ENCODING_FIX)
00249   TQCString vCard = converter.createVCardsRaw( list );
00250   file.writeBlock( vCard, vCard.length() );
00251 #else
00252   TQString vCard = converter.createVCards( list );
00253   file.writeBlock( vCard.utf8(), vCard.utf8().length() );
00254 #endif
00255   file.close();
00256 }
00257 
00258 void ResourceCached::clearCache()
00259 {
00260   // TEST ME
00261   mAddrMap.clear();
00262 }
00263 
00264 void ResourceCached::cleanUpCache( const TDEABC::Addressee::List &addrList )
00265 {
00266   // load cache
00267   TQFile file( cacheFile() );
00268   if ( !file.open( IO_ReadOnly ) )
00269     return;
00270 
00271 
00272   TDEABC::VCardConverter converter;
00273 #if defined(KABC_VCARD_ENCODING_FIX)
00274   TDEABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() );
00275 #else
00276   TQTextStream s( &file );
00277   s.setEncoding( TQTextStream::UnicodeUTF8 );
00278   TDEABC::Addressee::List list = converter.parseVCards( s.read() );
00279 #endif
00280   TDEABC::Addressee::List::Iterator cacheIt;
00281   TDEABC::Addressee::List::ConstIterator it;
00282 
00283   for ( cacheIt = list.begin(); cacheIt != list.end(); ++cacheIt ) {
00284     bool found = false;
00285     for ( it = addrList.begin(); it != addrList.end(); ++it ) {
00286       if ( (*it).uid() == (*cacheIt).uid() )
00287         found = true;
00288     }
00289 
00290     if ( !found ) {
00291       mIdMapper.removeRemoteId( mIdMapper.remoteId( (*cacheIt).uid() ) );
00292       mAddrMap.remove( (*cacheIt).uid() );
00293     }
00294   }
00295 
00296   file.close();
00297 }
00298 
00299 KPIM::IdMapper& ResourceCached::idMapper()
00300 {
00301   return mIdMapper;
00302 }
00303 
00304 bool ResourceCached::hasChanges() const
00305 {
00306   return !( mAddedAddressees.isEmpty() &&
00307             mChangedAddressees.isEmpty() &&
00308             mDeletedAddressees.isEmpty() );
00309 }
00310 
00311 void ResourceCached::clearChanges()
00312 {
00313   mAddedAddressees.clear();
00314   mChangedAddressees.clear();
00315   mDeletedAddressees.clear();
00316 }
00317 
00318 void ResourceCached::clearChange( const TDEABC::Addressee &addr )
00319 {
00320   mAddedAddressees.remove( addr.uid() );
00321   mChangedAddressees.remove( addr.uid() );
00322   mDeletedAddressees.remove( addr.uid() );
00323 }
00324 
00325 void ResourceCached::clearChange( const TQString &uid )
00326 {
00327   mAddedAddressees.remove( uid );
00328   mChangedAddressees.remove( uid );
00329   mDeletedAddressees.remove( uid );
00330 }
00331 
00332 TDEABC::Addressee::List ResourceCached::addedAddressees() const
00333 {
00334   return mAddedAddressees.values();
00335 }
00336 
00337 TDEABC::Addressee::List ResourceCached::changedAddressees() const
00338 {
00339   return mChangedAddressees.values();
00340 }
00341 
00342 TDEABC::Addressee::List ResourceCached::deletedAddressees() const
00343 {
00344   return mDeletedAddressees.values();
00345 }
00346 
00347 TQString ResourceCached::cacheFile() const
00348 {
00349   return locateLocal( "cache", "tdeabc/tderesources/" + identifier() );
00350 }
00351 
00352 TQString ResourceCached::changesCacheFile( const TQString &type ) const
00353 {
00354   return locateLocal( "cache", "tdeabc/changescache/" + identifier() + "_" + type );
00355 }
00356 
00357 void ResourceCached::saveChangesCache( const TQMap<TQString, TDEABC::Addressee> &map, const TQString &type )
00358 {
00359   TQFile file( changesCacheFile( type ) );
00360 
00361   const TDEABC::Addressee::List list = map.values();
00362   if ( list.isEmpty() ) {
00363     file.remove();
00364   } else {
00365     if ( !file.open( IO_WriteOnly ) ) {
00366       kdError() << "Can't open changes cache file '" << file.name() << "' for saving." << endl;
00367       return;
00368     }
00369 
00370     TDEABC::VCardConverter converter;
00371 #if defined(KABC_VCARD_ENCODING_FIX)
00372     const TQCString vCards = converter.createVCardsRaw( list );
00373     file.writeBlock( vCards, vCards.length() );
00374 #else
00375     const TQString vCards = converter.createVCards( list );
00376     TQCString content = vCards.utf8();
00377     file.writeBlock( content, content.length() );
00378 #endif
00379   }
00380 }
00381 
00382 void ResourceCached::saveChangesCache()
00383 {
00384   saveChangesCache( mAddedAddressees, "added" );
00385   saveChangesCache( mDeletedAddressees, "deleted" );
00386   saveChangesCache( mChangedAddressees, "changed" );
00387 }
00388 
00389 void ResourceCached::loadChangesCache( TQMap<TQString, TDEABC::Addressee> &map, const TQString &type )
00390 {
00391   TQFile file( changesCacheFile( type ) );
00392   if ( !file.open( IO_ReadOnly ) )
00393     return;
00394 
00395   TDEABC::VCardConverter converter;
00396 
00397 #if defined(KABC_VCARD_ENCODING_FIX)
00398   const TDEABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() );
00399 #else
00400   TQTextStream s( &file );
00401   s.setEncoding( TQTextStream::UnicodeUTF8 );
00402   const TDEABC::Addressee::List list = converter.parseVCards( s.read() );
00403 #endif
00404   TDEABC::Addressee::List::ConstIterator it;
00405   for ( it = list.begin(); it != list.end(); ++it )
00406     map.insert( (*it).uid(), *it );
00407 
00408   file.close();
00409 }
00410 
00411 void ResourceCached::loadChangesCache()
00412 {
00413   loadChangesCache( mAddedAddressees, "added" );
00414   loadChangesCache( mDeletedAddressees, "deleted" );
00415   loadChangesCache( mChangedAddressees, "changed" );
00416 }
00417 
00418 void ResourceCached::setIdMapperIdentifier()
00419 {
00420   mIdMapper.setIdentifier( type() + "_" + identifier() );
00421 }
00422 
00423 #include "tdeabcresourcecached.moc"