/* This file is part of libtdepim. Copyright (c) 2004 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include "kabcresourcecached.h" using namespace KABC; ResourceCached::ResourceCached( const KConfig *config ) : KABC::Resource( config ), mIdMapper( "kabc/uidmaps/" ), mReloadPolicy( ReloadInterval ), mReloadInterval( 10 ), mKABCReloadTimer( 0, "mKABCReloadTimer" ), mReloaded( false ), mSavePolicy( SaveDelayed ), mSaveInterval( 10 ), mKABCSaveTimer( 0, "mKABCSaveTimer" ) { connect( &mKABCReloadTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotKABCReload() ) ); connect( &mKABCSaveTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotKABCSave() ) ); if (config) this->readConfig(const_cast(config)); } ResourceCached::~ResourceCached() { } void ResourceCached::setReloadPolicy( int i ) { mReloadPolicy = i; setupReloadTimer(); } int ResourceCached::reloadPolicy() const { return mReloadPolicy; } void ResourceCached::setReloadInterval( int minutes ) { mReloadInterval = minutes; } int ResourceCached::reloadInterval() const { return mReloadInterval; } void ResourceCached::setSavePolicy( int i ) { mSavePolicy = i; setupSaveTimer(); } int ResourceCached::savePolicy() const { return mSavePolicy; } void ResourceCached::setSaveInterval( int minutes ) { mSaveInterval = minutes; } int ResourceCached::saveInterval() const { return mSaveInterval; } void ResourceCached::writeConfig( KConfig *config ) { config->writeEntry( "ReloadPolicy", mReloadPolicy ); config->writeEntry( "ReloadInterval", mReloadInterval ); config->writeEntry( "SavePolicy", mSavePolicy ); config->writeEntry( "SaveInterval", mSaveInterval ); config->writeEntry( "LastLoad", mLastLoad ); config->writeEntry( "LastSave", mLastSave ); KABC::Resource::writeConfig( config ); } void ResourceCached::readConfig( KConfig *config ) { mReloadPolicy = config->readNumEntry( "ReloadPolicy", ReloadNever ); mReloadInterval = config->readNumEntry( "ReloadInterval", 10 ); mSaveInterval = config->readNumEntry( "SaveInterval", 10 ); mSavePolicy = config->readNumEntry( "SavePolicy", SaveNever ); mLastLoad = config->readDateTimeEntry( "LastLoad" ); mLastSave = config->readDateTimeEntry( "LastSave" ); setupSaveTimer(); setupReloadTimer(); } void ResourceCached::setupSaveTimer() { if ( mSavePolicy == SaveInterval ) { kdDebug(5800) << "ResourceCached::setSavePolicy(): start save timer (interval " << mSaveInterval << " minutes)." << endl; mKABCSaveTimer.start( mSaveInterval * 60 * 1000 ); // n minutes } else { mKABCSaveTimer.stop(); } } void ResourceCached::setupReloadTimer() { if ( mReloadPolicy == ReloadInterval ) { kdDebug(5800) << "ResourceCached::setSavePolicy(): start reload timer " "(interval " << mReloadInterval << " minutes)" << endl; mKABCReloadTimer.start( mReloadInterval * 60 * 1000 ); // n minutes } else { mKABCReloadTimer.stop(); } } void ResourceCached::slotKABCReload() { if ( !isActive() ) return; kdDebug(5800) << "ResourceCached::slotKABCReload()" << endl; load(); } void ResourceCached::slotKABCSave() { if ( !isActive() ) return; kdDebug(5800) << "ResourceCached::slotKABCSave()" << endl; KABC::Ticket *ticket = requestSaveTicket(); if ( ticket ) { save( ticket ); } } void ResourceCached::insertAddressee( const Addressee &addr ) { if ( !mAddrMap.contains( addr.uid() ) ) { // new contact if ( mDeletedAddressees.contains( addr.uid() ) ) { // it was first removed, then added, so it's an update... mDeletedAddressees.remove( addr.uid() ); mAddrMap.insert( addr.uid(), addr ); mChangedAddressees.insert( addr.uid(), addr ); return; } mAddrMap.insert( addr.uid(), addr ); mAddedAddressees.insert( addr.uid(), addr ); } else { KABC::Addressee oldAddressee = mAddrMap.find( addr.uid() ).data(); if ( oldAddressee != addr ) { mAddrMap.remove( addr.uid() ); mAddrMap.insert( addr.uid(), addr ); mChangedAddressees.insert( addr.uid(), addr ); } } } void ResourceCached::removeAddressee( const Addressee &addr ) { if ( mAddedAddressees.contains( addr.uid() ) ) { mAddedAddressees.remove( addr.uid() ); return; } if ( mDeletedAddressees.find( addr.uid() ) == mDeletedAddressees.end() ) mDeletedAddressees.insert( addr.uid(), addr ); mAddrMap.remove( addr.uid() ); } void ResourceCached::loadCache() { mAddrMap.clear(); setIdMapperIdentifier(); mIdMapper.load(); // load cache TQFile file( cacheFile() ); if ( !file.open( IO_ReadOnly ) ) return; KABC::VCardConverter converter; #if defined(KABC_VCARD_ENCODING_FIX) KABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() ); #else KABC::Addressee::List list = converter.parseVCards( TQString::fromUtf8( file.readAll() ) ); #endif KABC::Addressee::List::Iterator it; for ( it = list.begin(); it != list.end(); ++it ) { (*it).setResource( this ); (*it).setChanged( false ); mAddrMap.insert( (*it).uid(), *it ); } file.close(); } void ResourceCached::saveCache() { setIdMapperIdentifier(); mIdMapper.save(); // save cache TQFile file( cacheFile() ); if ( !file.open( IO_WriteOnly ) ) return; KABC::Addressee::List list = mAddrMap.values(); KABC::VCardConverter converter; #if defined(KABC_VCARD_ENCODING_FIX) TQCString vCard = converter.createVCardsRaw( list ); file.writeBlock( vCard, vCard.length() ); #else TQString vCard = converter.createVCards( list ); file.writeBlock( vCard.utf8(), vCard.utf8().length() ); #endif file.close(); } void ResourceCached::clearCache() { // TEST ME mAddrMap.clear(); } void ResourceCached::cleanUpCache( const KABC::Addressee::List &addrList ) { // load cache TQFile file( cacheFile() ); if ( !file.open( IO_ReadOnly ) ) return; KABC::VCardConverter converter; #if defined(KABC_VCARD_ENCODING_FIX) KABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() ); #else KABC::Addressee::List list = converter.parseVCards( TQString::fromUtf8( file.readAll() ) ); #endif KABC::Addressee::List::Iterator cacheIt; KABC::Addressee::List::ConstIterator it; for ( cacheIt = list.begin(); cacheIt != list.end(); ++cacheIt ) { bool found = false; for ( it = addrList.begin(); it != addrList.end(); ++it ) { if ( (*it).uid() == (*cacheIt).uid() ) found = true; } if ( !found ) { mIdMapper.removeRemoteId( mIdMapper.remoteId( (*cacheIt).uid() ) ); mAddrMap.remove( (*cacheIt).uid() ); } } file.close(); } KPIM::IdMapper& ResourceCached::idMapper() { return mIdMapper; } bool ResourceCached::hasChanges() const { return !( mAddedAddressees.isEmpty() && mChangedAddressees.isEmpty() && mDeletedAddressees.isEmpty() ); } void ResourceCached::clearChanges() { mAddedAddressees.clear(); mChangedAddressees.clear(); mDeletedAddressees.clear(); } void ResourceCached::clearChange( const KABC::Addressee &addr ) { mAddedAddressees.remove( addr.uid() ); mChangedAddressees.remove( addr.uid() ); mDeletedAddressees.remove( addr.uid() ); } void ResourceCached::clearChange( const TQString &uid ) { mAddedAddressees.remove( uid ); mChangedAddressees.remove( uid ); mDeletedAddressees.remove( uid ); } KABC::Addressee::List ResourceCached::addedAddressees() const { return mAddedAddressees.values(); } KABC::Addressee::List ResourceCached::changedAddressees() const { return mChangedAddressees.values(); } KABC::Addressee::List ResourceCached::deletedAddressees() const { return mDeletedAddressees.values(); } TQString ResourceCached::cacheFile() const { return locateLocal( "cache", "kabc/kresources/" + identifier() ); } TQString ResourceCached::changesCacheFile( const TQString &type ) const { return locateLocal( "cache", "kabc/changescache/" + identifier() + "_" + type ); } void ResourceCached::saveChangesCache( const TQMap &map, const TQString &type ) { TQFile file( changesCacheFile( type ) ); const KABC::Addressee::List list = map.values(); if ( list.isEmpty() ) { file.remove(); } else { if ( !file.open( IO_WriteOnly ) ) { kdError() << "Can't open changes cache file '" << file.name() << "' for saving." << endl; return; } KABC::VCardConverter converter; #if defined(KABC_VCARD_ENCODING_FIX) const TQCString vCards = converter.createVCardsRaw( list ); file.writeBlock( vCards, vCards.length() ); #else const TQString vCards = converter.createVCards( list ); TQCString content = vCards.utf8(); file.writeBlock( content, content.length() ); #endif } } void ResourceCached::saveChangesCache() { saveChangesCache( mAddedAddressees, "added" ); saveChangesCache( mDeletedAddressees, "deleted" ); saveChangesCache( mChangedAddressees, "changed" ); } void ResourceCached::loadChangesCache( TQMap &map, const TQString &type ) { TQFile file( changesCacheFile( type ) ); if ( !file.open( IO_ReadOnly ) ) return; KABC::VCardConverter converter; #if defined(KABC_VCARD_ENCODING_FIX) const KABC::Addressee::List list = converter.parseVCardsRaw( file.readAll().data() ); #else const KABC::Addressee::List list = converter.parseVCards( TQString::fromUtf8( file.readAll() ) ); #endif KABC::Addressee::List::ConstIterator it; for ( it = list.begin(); it != list.end(); ++it ) map.insert( (*it).uid(), *it ); file.close(); } void ResourceCached::loadChangesCache() { loadChangesCache( mAddedAddressees, "added" ); loadChangesCache( mDeletedAddressees, "deleted" ); loadChangesCache( mChangedAddressees, "changed" ); } void ResourceCached::setIdMapperIdentifier() { mIdMapper.setIdentifier( type() + "_" + identifier() ); } #include "kabcresourcecached.moc"