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 ResourceFile::ResourceFile( const KConfig *config )
00050   : Resource( config ), mFormat( 0 ), mLocalTempFile( 0 ),
00051     mAsynchronous( false )
00052 {
00053   QString fileName, formatName;
00054 
00055   if ( config ) {
00056     fileName = config->readPathEntry( "FileName", StdAddressBook::fileName() );
00057     formatName = config->readEntry( "FileFormat", "vcard" );
00058   } else {
00059     fileName = StdAddressBook::fileName();
00060     formatName = "vcard";
00061   }
00062 
00063   init( fileName, formatName );
00064 }
00065 
00066 ResourceFile::ResourceFile( const QString &fileName,
00067                             const QString &formatName )
00068   : Resource( 0 ), mFormat( 0 ), mLocalTempFile( 0 ),
00069     mAsynchronous( false )
00070 {
00071   init( fileName, formatName );
00072 }
00073 
00074 void ResourceFile::init( const QString &fileName, const QString &formatName )
00075 {
00076   mFormatName = formatName;
00077 
00078   FormatFactory *factory = FormatFactory::self();
00079   mFormat = factory->format( mFormatName );
00080 
00081   if ( !mFormat ) {
00082     mFormatName = "vcard";
00083     mFormat = factory->format( mFormatName );
00084   }
00085 
00086   connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( fileChanged() ) );
00087   connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( fileChanged() ) );
00088   connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( fileChanged() ) );
00089 
00090   setFileName( fileName );
00091 
00092   mLock = 0;
00093 }
00094 
00095 ResourceFile::~ResourceFile()
00096 {
00097   delete mFormat;
00098   mFormat = 0;
00099   delete mLocalTempFile;
00100   mLocalTempFile = 0;
00101 }
00102 
00103 void ResourceFile::writeConfig( KConfig *config )
00104 {
00105   Resource::writeConfig( config );
00106 
00107   if ( mFileName == StdAddressBook::fileName() )
00108     config->deleteEntry( "FileName" );
00109   else
00110     config->writePathEntry( "FileName", mFileName );
00111 
00112   config->writeEntry( "FileFormat", mFormatName );
00113 }
00114 
00115 Ticket *ResourceFile::requestSaveTicket()
00116 {
00117   kdDebug(5700) << "ResourceFile::requestSaveTicket()" << endl;
00118 
00119   if ( !addressBook() ) return 0;
00120 
00121   delete mLock;
00122   mLock = new Lock( mFileName );
00123 
00124   if ( mLock->lock() ) {
00125     addressBook()->emitAddressBookLocked();
00126   } else {
00127     addressBook()->error( mLock->error() );
00128     kdDebug(5700) << "ResourceFile::requestSaveTicket(): Unable to lock file '"
00129                   << mFileName << "': " << mLock->error() << endl;
00130     return 0;
00131   }
00132 
00133   return createTicket( this );
00134 }
00135 
00136 void ResourceFile::releaseSaveTicket( Ticket *ticket )
00137 {
00138   delete ticket;
00139 
00140   delete mLock;
00141   mLock = 0;
00142 
00143   addressBook()->emitAddressBookUnlocked();
00144 }
00145 
00146 bool ResourceFile::doOpen()
00147 {
00148   QFile file( mFileName );
00149 
00150   if ( !file.exists() ) {
00151     // try to create the file
00152     bool ok = file.open( IO_WriteOnly );
00153     if ( ok )
00154       file.close();
00155 
00156     return ok;
00157   } else {
00158     if ( readOnly() ) {
00159       if ( !file.open( IO_ReadOnly ) )
00160         return false;
00161     } else {    
00162     if ( !file.open( IO_ReadWrite ) )
00163       return false;
00164     }
00165     if ( file.size() == 0 ) {
00166       file.close();
00167       return true;
00168     }
00169 
00170     bool ok = mFormat->checkFormat( &file );
00171     file.close();
00172 
00173     return ok;
00174   }
00175 }
00176 
00177 void ResourceFile::doClose()
00178 {
00179 }
00180 
00181 bool ResourceFile::load()
00182 {
00183   kdDebug(5700) << "ResourceFile::load(): '" << mFileName << "'" << endl;
00184 
00185   mAsynchronous = false;
00186 
00187   QFile file( mFileName );
00188   if ( !file.open( IO_ReadOnly ) ) {
00189     addressBook()->error( i18n( "Unable to open file '%1'." ).arg( mFileName ) );
00190     return false;
00191   }
00192 
00193   return mFormat->loadAll( addressBook(), this, &file );
00194 }
00195 
00196 bool ResourceFile::asyncLoad()
00197 {
00198   mAsynchronous = true;
00199 
00200   if ( mLocalTempFile ) {
00201     kdDebug(5700) << "stale temp file detected " << mLocalTempFile->name() << endl;
00202     delete mLocalTempFile;
00203   }
00204 
00205   mLocalTempFile = new KTempFile();
00206   mLocalTempFile->setAutoDelete( true );
00207   mTempFile = mLocalTempFile->name();
00208 
00209   KURL dest, src;
00210   dest.setPath( mTempFile );
00211   src.setPath( mFileName );
00212 
00213   KIO::Scheduler::checkSlaveOnHold( true );
00214   KIO::Job * job = KIO::file_copy( src, dest, -1, true, false, false );
00215   connect( job, SIGNAL( result( KIO::Job* ) ),
00216            this, SLOT( downloadFinished( KIO::Job* ) ) );
00217 
00218   return true;
00219 }
00220 
00221 bool ResourceFile::save( Ticket * )
00222 {
00223   kdDebug(5700) << "ResourceFile::save()" << endl;
00224 
00225   // create backup file
00226   QString extension = "_" + QString::number( QDate::currentDate().dayOfWeek() );
00227   (void) KSaveFile::backupFile( mFileName, QString::null /*directory*/,
00228                                 extension );
00229 
00230   mDirWatch.stopScan();
00231   KSaveFile saveFile( mFileName );
00232   bool ok = false;
00233   if ( saveFile.status() == 0 && saveFile.file() )
00234   {
00235     mFormat->saveAll( addressBook(), this, saveFile.file() );
00236     ok = saveFile.close();
00237   }
00238 
00239   if ( !ok )
00240     addressBook()->error( i18n( "Unable to save file '%1'." ).arg( mFileName ) );
00241   mDirWatch.startScan();
00242 
00243   return ok;
00244 }
00245 
00246 bool ResourceFile::asyncSave( Ticket * )
00247 {
00248   QFile file( mTempFile );
00249 
00250   if ( !file.open( IO_WriteOnly ) ) {
00251     emit savingError( this, i18n( "Unable to open file '%1'." ).arg( mTempFile ) );
00252     return false;
00253   }
00254 
00255   mDirWatch.stopScan();
00256   mFormat->saveAll( addressBook(), this, &file );
00257   file.close();
00258 
00259   KURL src, dest;
00260   src.setPath( mTempFile );
00261   dest.setPath( mFileName );
00262 
00263   KIO::Scheduler::checkSlaveOnHold( true );
00264   KIO::Job * job = KIO::file_copy( src, dest, -1, true, false, false );
00265   connect( job, SIGNAL( result( KIO::Job* ) ),
00266            this, SLOT( uploadFinished( KIO::Job* ) ) );
00267 
00268   return true;
00269 }
00270 
00271 void ResourceFile::setFileName( const QString &fileName )
00272 {
00273   mDirWatch.stopScan();
00274   if ( mDirWatch.contains( mFileName ) )
00275     mDirWatch.removeFile( mFileName );
00276 
00277   mFileName = fileName;
00278 
00279   mDirWatch.addFile( mFileName );
00280   mDirWatch.startScan();
00281 }
00282 
00283 QString ResourceFile::fileName() const
00284 {
00285   return mFileName;
00286 }
00287 
00288 void ResourceFile::setFormat( const QString &format )
00289 {
00290   mFormatName = format;
00291   delete mFormat;
00292 
00293   FormatFactory *factory = FormatFactory::self();
00294   mFormat = factory->format( mFormatName );
00295 }
00296 
00297 QString ResourceFile::format() const
00298 {
00299   return mFormatName;
00300 }
00301 
00302 void ResourceFile::fileChanged()
00303 {
00304   if ( !addressBook() )
00305     return;
00306 
00307   clear();
00308   if ( mAsynchronous )
00309     asyncLoad();
00310   else {
00311     load();
00312     kdDebug() << "addressBookChanged() " << endl;
00313     addressBook()->emitAddressBookChanged();
00314   }
00315 }
00316 
00317 void ResourceFile::removeAddressee( const Addressee &addr )
00318 {
00319   QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/photos/" ) + addr.uid() ) );
00320   QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/logos/" ) + addr.uid() ) );
00321   QFile::remove( QFile::encodeName( locateLocal( "data", "kabc/sounds/" ) + addr.uid() ) );
00322 
00323   mAddrMap.erase( addr.uid() );
00324 }
00325 
00326 void ResourceFile::downloadFinished( KIO::Job* )
00327 {
00328   if ( !mLocalTempFile )
00329     emit loadingError( this, i18n( "Download failed in some way!" ) );
00330 
00331   QFile file( mTempFile );
00332   if ( !file.open( IO_ReadOnly ) ) {
00333     emit loadingError( this, i18n( "Unable to open file '%1'." ).arg( mTempFile ) );
00334     return;
00335   }
00336 
00337   if ( !mFormat->loadAll( addressBook(), this, &file ) )
00338     emit loadingError( this, i18n( "Problems during parsing file '%1'." ).arg( mTempFile ) );
00339   else
00340     emit loadingFinished( this );
00341 }
00342 
00343 void ResourceFile::uploadFinished( KIO::Job *job )
00344 {
00345   if ( job->error() )
00346     emit savingError( this, job->errorString() );
00347   else
00348     emit savingFinished( this );
00349   mDirWatch.startScan();
00350 }
00351 
00352 #include "resourcefile.moc"
KDE Logo
This file is part of the documentation for kabc Library Version 3.3.90.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 30 10:21:07 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003