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() )
00103 return dir.mkdir( dir.path() );
00104
00105 QString testName = dir.entryList( QDir::Files )[0];
00106 if ( testName.isNull() || testName.isEmpty() )
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
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
00202 QFile file( mLockUniqueName );
00203 file.open( IO_WriteOnly );
00204 file.close();
00205
00206
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
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"
This file is part of the documentation for kdelibs Version 3.1.0.