kabc Library API Documentation

resourcedir.cpp

00001 #include <sys/types.h>
00002 #include <sys/stat.h>
00003 #include <unistd.h>
00004 
00005 #include <qregexp.h>
00006 #include <qtimer.h>
00007 #include <qwidget.h>
00008 
00009 #include <kapplication.h>
00010 #include <kconfig.h>
00011 #include <kdebug.h>
00012 #include <kgenericfactory.h>
00013 #include <kglobal.h>
00014 #include <klocale.h>
00015 #include <kstandarddirs.h>
00016 #include <kurlrequester.h>
00017 
00018 #include "addressbook.h"
00019 
00020 #include "formatfactory.h"
00021 
00022 #include "resourcedirconfig.h"
00023 #include "stdaddressbook.h"
00024 
00025 #include "resourcedir.h"
00026 
00027 using namespace KABC;
00028 
00029 extern "C"
00030 {
00031   ResourceConfigWidget *config_widget( QWidget *parent ) {
00032     KGlobal::locale()->insertCatalogue("kabc_dir");
00033     return new ResourceDirConfig( parent, "ResourceDirConfig" );
00034   }
00035 
00036   Resource *resource( AddressBook *ab, const KConfig *config ) {
00037     KGlobal::locale()->insertCatalogue("kabc_dir");
00038     return new ResourceDir( ab, config );
00039   }
00040 }
00041 
00042 
00043 ResourceDir::ResourceDir( AddressBook *addressBook, const KConfig *config )
00044     : Resource( addressBook )
00045 {
00046   QString path = config->readEntry( "FilePath" );
00047   QString type = config->readEntry( "FileFormat" );
00048 
00049   FormatFactory *factory = FormatFactory::self();
00050   FormatPlugin *format = factory->format( type );
00051 
00052   init( path, format );
00053 }
00054 
00055 ResourceDir::ResourceDir( AddressBook *addressBook, const QString &path,
00056                           FormatPlugin *format ) :
00057   Resource( addressBook )
00058 {
00059   init( path, format );
00060 }
00061 
00062 ResourceDir::~ResourceDir()
00063 {
00064   delete mFormat;
00065 }
00066 
00067 
00068 void ResourceDir::init( const QString &path, FormatPlugin *format )
00069 {
00070   if ( !format ) {
00071     FormatFactory *factory = FormatFactory::self();
00072     mFormat = factory->format( "vcard" );
00073   } else {
00074     mFormat = format;
00075   }
00076 
00077   connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( pathChanged() ) );
00078   connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( pathChanged() ) );
00079   connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( pathChanged() ) );
00080 
00081   setPath( path );
00082 }
00083 
00084 Ticket *ResourceDir::requestSaveTicket()
00085 {
00086   kdDebug(5700) << "ResourceDir::requestSaveTicket()" << endl;
00087 
00088   if ( !addressBook() ) return 0;
00089 
00090   if ( !lock( mPath ) ) {
00091     kdDebug(5700) << "ResourceDir::requestSaveTicket(): Unable to lock path '"
00092                   << mPath << "'" << endl;
00093     return 0;
00094   }
00095   return createTicket( this );
00096 }
00097 
00098 
00099 bool ResourceDir::open()
00100 {
00101   QDir dir( mPath );
00102   if ( !dir.exists() ) // no directory available
00103     return dir.mkdir( dir.path() );
00104 
00105   QString testName = dir.entryList( QDir::Files )[0];
00106   if ( testName.isNull() || testName.isEmpty() ) // no file in directory
00107     return true;
00108 
00109   QFile file( mPath + "/" + testName );
00110   if ( !file.open( IO_ReadOnly ) )
00111     return true;
00112 
00113   if ( file.size() == 0 )
00114     return true;
00115 
00116   bool ok = mFormat->checkFormat( &file );
00117   file.close();
00118 
00119   return ok;
00120 }
00121 
00122 void ResourceDir::close()
00123 {
00124 }
00125 
00126 bool ResourceDir::load()
00127 {
00128   kdDebug(5700) << "ResourceDir::load(): '" << mPath << "'" << endl;
00129 
00130   QDir dir( mPath );
00131   QStringList files = dir.entryList( QDir::Files );
00132 
00133   QStringList::Iterator it;
00134   bool ok = true;
00135   for ( it = files.begin(); it != files.end(); ++it ) {
00136     QFile file( mPath + "/" + (*it) );
00137 
00138     if ( !file.open( IO_ReadOnly ) ) {
00139       addressBook()->error( i18n( "Unable to open file '%1' for reading" ).arg( file.name() ) );
00140       ok = false;
00141       continue;
00142     }
00143 
00144     if ( !mFormat->loadAll( addressBook(), this, &file ) )
00145       ok = false;
00146 
00147     file.close();
00148   }
00149 
00150   return ok;
00151 }
00152 
00153 bool ResourceDir::save( Ticket *ticket )
00154 {
00155   kdDebug(5700) << "ResourceDir::save(): '" << mPath << "'" << endl;
00156   
00157   AddressBook::Iterator it;
00158   bool ok = true;
00159 
00160   for ( it = addressBook()->begin(); it != addressBook()->end(); ++it ) {
00161     if ( (*it).resource() != this || !(*it).changed() )
00162       continue;
00163 
00164     QFile file( mPath + "/" + (*it).uid() );
00165     if ( !file.open( IO_WriteOnly ) ) {
00166       addressBook()->error( i18n( "Unable to open file '%1' for writing" ).arg( file.name() ) );
00167       continue;
00168     }
00169 
00170     mFormat->save( *it, &file );
00171 
00172     // mark as unchanged
00173     (*it).setChanged( false );
00174 
00175     file.close();
00176   }
00177 
00178   delete ticket;
00179   unlock( mPath );
00180 
00181   return ok;
00182 }
00183 
00184 bool ResourceDir::lock( const QString &path )
00185 {
00186   kdDebug(5700) << "ResourceDir::lock()" << endl;
00187 
00188   QString p = path;
00189   p.replace( QRegExp("/"), "_" );
00190 
00191   QString lockName = locateLocal( "data", "kabc/lock/" + p + ".lock" );
00192   kdDebug(5700) << "-- lock name: " << lockName << endl;
00193 
00194   if ( QFile::exists( lockName ) ) return false;
00195 
00196   QString lockUniqueName;
00197   lockUniqueName = p + kapp->randomString( 8 );
00198   mLockUniqueName = locateLocal( "data", "kabc/lock/" + lockUniqueName );
00199   kdDebug(5700) << "-- lock unique name: " << mLockUniqueName << endl;
00200 
00201   // Create unique file
00202   QFile file( mLockUniqueName );
00203   file.open( IO_WriteOnly );
00204   file.close();
00205 
00206   // Create lock file
00207   int result = ::link( QFile::encodeName( mLockUniqueName ),
00208                        QFile::encodeName( lockName ) );
00209 
00210   if ( result == 0 ) {
00211     addressBook()->emitAddressBookLocked();
00212     return true;
00213   }
00214 
00215   // TODO: check stat
00216 
00217   return false;
00218 }
00219 
00220 void ResourceDir::unlock( const QString &path )
00221 {
00222   QString p = path;
00223   p.replace( QRegExp( "/" ), "_" );
00224 
00225   QString lockName = locate( "data", "kabc/lock/" + p + ".lock" );
00226   ::unlink( QFile::encodeName( lockName ) );
00227   QFile::remove( mLockUniqueName );
00228   addressBook()->emitAddressBookUnlocked();
00229 }
00230 
00231 void ResourceDir::setPath( const QString &path )
00232 {
00233   mDirWatch.stopScan();
00234   mDirWatch.removeDir( mPath );
00235 
00236   mPath = path;
00237   mDirWatch.addDir( mPath, true );
00238   mDirWatch.startScan();
00239 }
00240 
00241 QString ResourceDir::path() const
00242 {
00243   return mPath;
00244 }
00245 
00246 void ResourceDir::pathChanged()
00247 {
00248   load();
00249   addressBook()->emitAddressBookChanged();
00250 }
00251 
00252 QString ResourceDir::identifier() const
00253 {
00254     return path();
00255 }
00256 
00257 void ResourceDir::removeAddressee( const Addressee& addr )
00258 {
00259     QFile::remove( mPath + "/" + addr.uid() );
00260 }
00261 
00262 void ResourceDir::cleanUp()
00263 {
00264   unlock( mPath );
00265 }
00266 
00267 #include "resourcedir.moc"
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Oct 8 12:22:08 2003 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2001