| # kabc Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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"

This file is part of the documentation for kabc Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:31:30 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003