resourcedir.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <errno.h>
00022 #include <signal.h>
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025 #include <unistd.h>
00026
00027 #include <qregexp.h>
00028 #include <qtimer.h>
00029 #include <qwidget.h>
00030
00031 #include <kapplication.h>
00032 #include <kconfig.h>
00033 #include <kdebug.h>
00034 #include <kgenericfactory.h>
00035 #include <kglobal.h>
00036 #include <klocale.h>
00037 #include <kstandarddirs.h>
00038 #include <kurlrequester.h>
00039
00040 #include "addressbook.h"
00041 #include "formatfactory.h"
00042 #include "resourcedirconfig.h"
00043 #include "stdaddressbook.h"
00044 #include "lock.h"
00045
00046 #include "resourcedir.h"
00047
00048 using namespace KABC;
00049
00050 extern "C"
00051 {
00052 void *init_kabc_dir()
00053 {
00054 return new KRES::PluginFactory<ResourceDir,ResourceDirConfig>();
00055 }
00056 }
00057
00058
00059 ResourceDir::ResourceDir( const KConfig *config )
00060 : Resource( config ), mAsynchronous( false )
00061 {
00062 if ( config ) {
00063 init( config->readPathEntry( "FilePath", StdAddressBook::directoryName() ),
00064 config->readEntry( "FileFormat", "vcard" ) );
00065 } else {
00066 init( StdAddressBook::directoryName(), "vcard" );
00067 }
00068 }
00069
00070 ResourceDir::ResourceDir( const QString &path, const QString &format )
00071 : Resource( 0 ), mAsynchronous( false )
00072 {
00073 init( path, format );
00074 }
00075
00076 void ResourceDir::init( const QString &path, const QString &format )
00077 {
00078 mFormatName = format;
00079
00080 FormatFactory *factory = FormatFactory::self();
00081 mFormat = factory->format( mFormatName );
00082
00083 if ( !mFormat ) {
00084 mFormatName = "vcard";
00085 mFormat = factory->format( mFormatName );
00086 }
00087
00088 mLock = 0;
00089
00090 connect( &mDirWatch, SIGNAL( dirty(const QString&) ), SLOT( pathChanged() ) );
00091 connect( &mDirWatch, SIGNAL( created(const QString&) ), SLOT( pathChanged() ) );
00092 connect( &mDirWatch, SIGNAL( deleted(const QString&) ), SLOT( pathChanged() ) );
00093
00094 setPath( path );
00095 }
00096
00097 ResourceDir::~ResourceDir()
00098 {
00099 delete mFormat;
00100 mFormat = 0;
00101 }
00102
00103 void ResourceDir::writeConfig( KConfig *config )
00104 {
00105 Resource::writeConfig( config );
00106
00107 if ( mPath == StdAddressBook::directoryName() )
00108 config->deleteEntry( "FilePath" );
00109 else
00110 config->writePathEntry( "FilePath", mPath );
00111
00112 config->writeEntry( "FileFormat", mFormatName );
00113 }
00114
00115 Ticket *ResourceDir::requestSaveTicket()
00116 {
00117 kdDebug(5700) << "ResourceDir::requestSaveTicket()" << endl;
00118
00119 if ( !addressBook() ) return 0;
00120
00121 delete mLock;
00122 mLock = new Lock( mPath );
00123
00124 if ( mLock->lock() ) {
00125 addressBook()->emitAddressBookLocked();
00126 } else {
00127 addressBook()->error( mLock->error() );
00128 kdDebug(5700) << "ResourceFile::requestSaveTicket(): Unable to lock path '"
00129 << mPath << "': " << mLock->error() << endl;
00130 return 0;
00131 }
00132
00133 return createTicket( this );
00134 }
00135
00136 void ResourceDir::releaseSaveTicket( Ticket *ticket )
00137 {
00138 delete ticket;
00139
00140 delete mLock;
00141 mLock = 0;
00142 }
00143
00144 bool ResourceDir::doOpen()
00145 {
00146 QDir dir( mPath );
00147 if ( !dir.exists() ) {
00148 return dir.mkdir( dir.path() );
00149 } else {
00150 QString testName = dir.entryList( QDir::Files )[0];
00151 if ( testName.isNull() || testName.isEmpty() )
00152 return true;
00153
00154 QFile file( mPath + "/" + testName );
00155 if ( file.open( IO_ReadOnly ) )
00156 return true;
00157
00158 if ( file.size() == 0 )
00159 return true;
00160
00161 bool ok = mFormat->checkFormat( &file );
00162 file.close();
00163 return ok;
00164 }
00165 }
00166
00167 void ResourceDir::doClose()
00168 {
00169 }
00170
00171 bool ResourceDir::load()
00172 {
00173 kdDebug(5700) << "ResourceDir::load(): '" << mPath << "'" << endl;
00174
00175 mAsynchronous = false;
00176
00177 QDir dir( mPath );
00178 QStringList files = dir.entryList( QDir::Files );
00179
00180 QStringList::Iterator it;
00181 bool ok = true;
00182 for ( it = files.begin(); it != files.end(); ++it ) {
00183 QFile file( mPath + "/" + (*it) );
00184
00185 if ( !file.open( IO_ReadOnly ) ) {
00186 addressBook()->error( i18n( "Unable to open file '%1' for reading" ).arg( file.name() ) );
00187 ok = false;
00188 continue;
00189 }
00190
00191 if ( !mFormat->loadAll( addressBook(), this, &file ) )
00192 ok = false;
00193
00194 file.close();
00195 }
00196
00197 return ok;
00198 }
00199
00200 bool ResourceDir::asyncLoad()
00201 {
00202 mAsynchronous = true;
00203
00204 bool ok = load();
00205 if ( !ok )
00206 emit loadingError( this, i18n( "Loading resource '%1' failed!" )
00207 .arg( resourceName() ) );
00208 else
00209 emit loadingFinished( this );
00210
00211 return ok;
00212 }
00213
00214 bool ResourceDir::save( Ticket * )
00215 {
00216 kdDebug(5700) << "ResourceDir::save(): '" << mPath << "'" << endl;
00217
00218 Addressee::Map::Iterator it;
00219 bool ok = true;
00220
00221 mDirWatch.stopScan();
00222
00223 for ( it = mAddrMap.begin(); it != mAddrMap.end(); ++it ) {
00224 if ( !it.data().changed() )
00225 continue;
00226
00227 QFile file( mPath + "/" + (*it).uid() );
00228 if ( !file.open( IO_WriteOnly ) ) {
00229 addressBook()->error( i18n( "Unable to open file '%1' for writing" ).arg( file.name() ) );
00230 continue;
00231 }
00232
00233 mFormat->save( *it, &file );
00234
00235
00236 (*it).setChanged( false );
00237
00238 file.close();
00239 }
00240
00241 mDirWatch.startScan();
00242
00243 return ok;
00244 }
00245
00246 bool ResourceDir::asyncSave( Ticket *ticket )
00247 {
00248 bool ok = save( ticket );
00249 if ( !ok )
00250 emit savingError( this, i18n( "Saving resource '%1' failed!" )
00251 .arg( resourceName() ) );
00252 else
00253 emit savingFinished( this );
00254
00255 return ok;
00256 }
00257
00258 void ResourceDir::setPath( const QString &path )
00259 {
00260 mDirWatch.stopScan();
00261 if ( mDirWatch.contains( mPath ) )
00262 mDirWatch.removeDir( mPath );
00263
00264 mPath = path;
00265 mDirWatch.addDir( mPath, true );
00266 mDirWatch.startScan();
00267 }
00268
00269 QString ResourceDir::path() const
00270 {
00271 return mPath;
00272 }
00273
00274 void ResourceDir::setFormat( const QString &format )
00275 {
00276 mFormatName = format;
00277
00278 if ( mFormat )
00279 delete mFormat;
00280
00281 FormatFactory *factory = FormatFactory::self();
00282 mFormat = factory->format( mFormatName );
00283 }
00284
00285 QString ResourceDir::format() const
00286 {
00287 return mFormatName;
00288 }
00289
00290 void ResourceDir::pathChanged()
00291 {
00292 if ( !addressBook() )
00293 return;
00294
00295 clear();
00296 if ( mAsynchronous )
00297 asyncLoad();
00298 else {
00299 load();
00300 addressBook()->emitAddressBookChanged();
00301 }
00302 }
00303
00304 void ResourceDir::removeAddressee( const Addressee& addr )
00305 {
00306 QFile::remove( mPath + "/" + addr.uid() );
00307 mAddrMap.erase( addr.uid() );
00308 }
00309
00310 #include "resourcedir.moc"
|