kabc Library API Documentation

resourcefile.cpp

00001 /* 00002 This file is part of libkabc. 00003 00004 Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00019 Boston, MA 02111-1307, USA. 00020 */ 00021 00022 #include <signal.h> 00023 #include <sys/types.h> 00024 #include <sys/stat.h> 00025 #include <unistd.h> 00026 00027 #include <qfile.h> 00028 #include <qregexp.h> 00029 #include <qtimer.h> 00030 00031 #include <kapplication.h> 00032 #include <kconfig.h> 00033 #include <kdebug.h> 00034 #include <kio/scheduler.h> 00035 #include <klocale.h> 00036 #include <ksavefile.h> 00037 #include <kstandarddirs.h> 00038 #include <ktempfile.h> 00039 00040 #include "formatfactory.h" 00041 #include "resourcefileconfig.h" 00042 #include "stdaddressbook.h" 00043 #include "lock.h" 00044 00045 #include "resourcefile.h" 00046 00047 using namespace KABC; 00048 00049 class ResourceFile::ResourceFilePrivate 00050 { 00051 public: 00052 KIO::Job *mLoadJob; 00053 bool mIsLoading; 00054 00055 KIO::Job *mSaveJob; 00056 bool mIsSaving; 00057 }; 00058 00059 ResourceFile::ResourceFile( const KConfig *config ) 00060 : Resource( config ), mFormat( 0 ), mLocalTempFile( 0 ), 00061 mAsynchronous( false ), d( new ResourceFilePrivate ) 00062 { 00063 QString fileName, formatName; 00064 00065 if ( config ) { 00066 fileName = config->readPathEntry( "FileName", StdAddressBook::fileName() ); 00067 formatName = config->readEntry( "FileFormat", "vcard" ); 00068 } else { 00069 fileName = StdAddressBook::fileName(); 00070 formatName = "vcard"; 00071 } 00072 00073 init( fileName, formatName ); 00074 } 00075 00076 ResourceFile::ResourceFile( const QString &fileName, 00077 const QString &formatName ) 00078 : Resource( 0 ), mFormat( 0 ), mLocalTempFile( 0 ), 00079 mAsynchronous( false ), d( new ResourceFilePrivate ) 00080 { 00081 init( fileName, formatName ); 00082 } 00083 00084 void ResourceFile::init( const QString &fileName, const QString &formatName ) 00085 { 00086 d->mLoadJob = 0; 00087 d->mIsLoading = false; 00088 d->mSaveJob = 0; 00089 d->mIsSaving = false; 00090 00091 mFormatName = formatName; 00092 00093 FormatFactory *factory = FormatFactory::self(); 00094 mFormat = factory->format( mFormatName ); 00095 00096 if ( !mFormat ) { 00097 mFormatName = "vcard"; 00098 mFormat = factory->format( mFormatName ); 00099 } 00100 00101 connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) ); 00102 connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) ); 00103 connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) ); 00104 00105 setFileName( fileName ); 00106 00107 mLock = 0; 00108 } 00109 00110 ResourceFile::~ResourceFile() 00111 { 00112 if ( d->mIsLoading ) 00113 d->mLoadJob->kill(); 00114 if ( d->mIsSaving ) 00115 d->mSaveJob->kill(); 00116 00117 delete d; 00118 d = 0; 00119 delete mFormat; 00120 mFormat = 0; 00121 delete mLocalTempFile; 00122 mLocalTempFile = 0; 00123 } 00124 00125 void ResourceFile::writeConfig( KConfig *config ) 00126 { 00127 Resource::writeConfig( config ); 00128 00129 if ( mFileName == StdAddressBook::fileName() ) 00130 config->deleteEntry( "FileName" ); 00131 else 00132 config->writePathEntry( "FileName", mFileName ); 00133 00134 config->writeEntry( "FileFormat", mFormatName ); 00135 } 00136 00137 Ticket *ResourceFile::requestSaveTicket() 00138 { 00139 kdDebug(5700) << "ResourceFile::requestSaveTicket()" << endl; 00140 00141 if ( !addressBook() ) return 0; 00142 00143 delete mLock; 00144 mLock = new Lock( mFileName ); 00145 00146 if ( mLock->lock() ) { 00147 addressBook()->emitAddressBookLocked(); 00148 } else { 00149 addressBook()->error( mLock->error() ); 00150 kdDebug(5700) << "ResourceFile::requestSaveTicket(): Unable to lock file '" 00151 << mFileName << "': " << mLock->error() << endl; 00152 return 0; 00153 } 00154 00155 return createTicket( this ); 00156 } 00157 00158 void ResourceFile::releaseSaveTicket( Ticket *ticket ) 00159 { 00160 delete ticket; 00161 00162 delete mLock; 00163 mLock = 0; 00164 00165 addressBook()->emitAddressBookUnlocked(); 00166 } 00167 00168 bool ResourceFile::doOpen() 00169 { 00170 QFile file( mFileName ); 00171 00172 if ( !file.exists() ) { 00173 // try to create the file 00174 bool ok = file.open( IO_WriteOnly ); 00175 if ( ok ) 00176 file.close(); 00177 00178 return ok; 00179 } else { 00180 if ( readOnly() ) { 00181 if ( !file.open( IO_ReadOnly ) ) 00182 return false; 00183 } else { 00184 if ( !file.open( IO_ReadWrite ) ) 00185 return false; 00186 } 00187 00188 if ( file.size() == 0 ) { 00189 file.close(); 00190 return true; 00191 } 00192 00193 bool ok = mFormat->checkFormat( &file ); 00194 file.close(); 00195 00196 return ok; 00197 } 00198 } 00199 00200 void ResourceFile::doClose() 00201 { 00202 } 00203 00204 bool ResourceFile::load() 00205 { 00206 kdDebug(5700) << "ResourceFile::load(): '" << mFileName << "'" << endl; 00207 00208 mAsynchronous = false; 00209 00210 QFile file( mFileName ); 00211 if ( !file.open( IO_ReadOnly ) ) { 00212 addressBook()->error( i18n( "Unable to open file '%1'." ).arg( mFileName ) ); 00213 return false; 00214 } 00215 00216 return mFormat->loadAll( addressBook(), this, &file ); 00217 } 00218 00219 bool ResourceFile::asyncLoad() 00220 { 00221 mAsynchronous = true; 00222 00223 if ( mLocalTempFile ) { 00224 kdDebug(5700) << "stale temp file detected " << mLocalTempFile->name() << endl; 00225 delete mLocalTempFile; 00226 } 00227 00228 mLocalTempFile = new KTempFile(); 00229 mLocalTempFile->setAutoDelete( true ); 00230 mTempFile = mLocalTempFile->name(); 00231 00232 KURL dest, src; 00233 dest.setPath( mTempFile ); 00234 src.setPath( mFileName ); 00235 00236 KIO::Scheduler::checkSlaveOnHold( true ); 00237 d->mLoadJob = KIO::file_copy( src, dest, -1, true, false, false ); 00238 d->mIsLoading = true; 00239 connect( d->mLoadJob, SIGNAL( result( KIO::Job* ) ), 00240 this, SLOT( downloadFinished( KIO::Job* ) ) ); 00241 00242 return true; 00243 } 00244 00245 bool ResourceFile::save( Ticket * ) 00246 { 00247 kdDebug(5700) << "ResourceFile::save()" << endl; 00248 00249 // create backup file 00250 QString extension = "_" + QString::number( QDate::currentDate().dayOfWeek() ); 00251 (void) KSaveFile::backupFile( mFileName, QString::null /*directory*/, 00252 extension ); 00253 00254 mDirWatch.stopScan(); 00255 KSaveFile saveFile( mFileName ); 00256 bool ok = false; 00257 if ( saveFile.status() == 0 && saveFile.file() ) 00258 { 00259 mFormat->saveAll( addressBook(), this, saveFile.file() ); 00260 ok = saveFile.close(); 00261 } 00262 00263 if ( !ok ) 00264 addressBook()->error( i18n( "Unable to save file '%1'." ).arg( mFileName ) ); 00265 mDirWatch.startScan(); 00266 00267 return ok; 00268 } 00269 00270 bool ResourceFile::asyncSave( Ticket * ) 00271 { 00272 QFile file( mTempFile ); 00273 00274 if ( !file.open( IO_WriteOnly ) ) { 00275 emit savingError( this, i18n( "Unable to open file '%1'." ).arg( mTempFile ) ); 00276 return false; 00277 } 00278 00279 mDirWatch.stopScan(); 00280 mFormat->saveAll( addressBook(), this, &file ); 00281 file.close(); 00282 00283 KURL src, dest; 00284 src.setPath( mTempFile ); 00285 dest.setPath( mFileName ); 00286 00287 KIO::Scheduler::checkSlaveOnHold( true ); 00288 d->mSaveJob = KIO::file_copy( src, dest, -1, true, false, false ); 00289 d->mIsSaving = true; 00290 connect( d->mSaveJob, SIGNAL( result( KIO::Job* ) ), 00291 this, SLOT( uploadFinished( KIO::Job* ) ) ); 00292 00293 return true; 00294 } 00295 00296 void ResourceFile::setFileName( const QString &fileName ) 00297 { 00298 mDirWatch.stopScan(); 00299 if ( mDirWatch.contains( mFileName ) ) 00300 mDirWatch.removeFile( mFileName ); 00301 00302 mFileName = fileName; 00303 00304 mDirWatch.addFile( mFileName ); 00305 mDirWatch.startScan(); 00306 } 00307 00308 QString ResourceFile::fileName() const 00309 { 00310 return mFileName; 00311 } 00312 00313 void ResourceFile::setFormat( const QString &format ) 00314 { 00315 mFormatName = format; 00316 delete mFormat; 00317 00318 FormatFactory *factory = FormatFactory::self(); 00319 mFormat = factory->format( mFormatName ); 00320 } 00321 00322 QString ResourceFile::format() const 00323 { 00324 return mFormatName; 00325 } 00326 00327 void ResourceFile::fileChanged() 00328 { 00329 if ( !addressBook() ) 00330 return; 00331 00332 clear(); 00333 if ( mAsynchronous ) 00334 asyncLoad(); 00335 else { 00336 load(); 00337 kdDebug() << "addressBookChanged() " << endl; 00338 addressBook()->emitAddressBookChanged(); 00339 } 00340 } 00341 00342 void ResourceFile::removeAddressee( const Addressee &addr ) 00343 { 00344 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/photos/" ) + addr.uid() ) ); 00345 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/logos/" ) + addr.uid() ) ); 00346 QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/sounds/" ) + addr.uid() ) ); 00347 00348 mAddrMap.erase( addr.uid() ); 00349 } 00350 00351 void ResourceFile::downloadFinished( KIO::Job* ) 00352 { 00353 d->mIsLoading = false; 00354 00355 if ( !mLocalTempFile ) 00356 emit loadingError( this, i18n( "Download failed in some way!" ) ); 00357 00358 QFile file( mTempFile ); 00359 if ( !file.open( IO_ReadOnly ) ) { 00360 emit loadingError( this, i18n( "Unable to open file '%1'." ).arg( mTempFile ) ); 00361 return; 00362 } 00363 00364 if ( !mFormat->loadAll( addressBook(), this, &file ) ) 00365 emit loadingError( this, i18n( "Problems during parsing file '%1'." ).arg( mTempFile ) ); 00366 else 00367 emit loadingFinished( this ); 00368 } 00369 00370 void ResourceFile::uploadFinished( KIO::Job *job ) 00371 { 00372 d->mIsSaving = false; 00373 00374 if ( job->error() ) 00375 emit savingError( this, job->errorString() ); 00376 else 00377 emit savingFinished( this ); 00378 mDirWatch.startScan(); 00379 } 00380 00381 #include "resourcefile.moc"
KDE Logo
This file is part of the documentation for kabc Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Apr 14 00:35:18 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003