kabc
resourcedir.cpp
00001 /* 00002 This file is part of libkabc. 00003 Copyright (c) 2002 - 2003 Tobias Koenig <tokoe@kde.org> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "resourcedir.h" 00022 #include "resourcedirconfig.h" 00023 00024 #include "kabc/addressbook.h" 00025 #include "kabc/formatfactory.h" 00026 #include "kabc/stdaddressbook.h" 00027 #include "kabc/lock.h" 00028 00029 #include <kconfiggroup.h> 00030 #include <kdebug.h> 00031 #include <kgenericfactory.h> 00032 #include <kglobal.h> 00033 #include <klocale.h> 00034 #include <kstandarddirs.h> 00035 #include <kurlrequester.h> 00036 00037 #include <sys/types.h> 00038 #include <sys/stat.h> 00039 #include <errno.h> 00040 #include <signal.h> 00041 #include <unistd.h> 00042 00043 using namespace KABC; 00044 00045 class ResourceDir::Private 00046 { 00047 public: 00048 Private( ResourceDir *parent ) 00049 : mParent( parent ), mFormat( 0 ), mAsynchronous( false ) 00050 { 00051 } 00052 00053 ~Private() 00054 { 00055 delete mFormat; 00056 mFormat = 0; 00057 } 00058 00059 void pathChanged(); 00060 void init( const QString &path, const QString &format ); 00061 00062 ResourceDir *mParent; 00063 Format *mFormat; 00064 KDirWatch mDirWatch; 00065 00066 QString mPath; 00067 QString mFormatName; 00068 00069 Lock *mLock; 00070 00071 bool mAsynchronous; 00072 }; 00073 00074 void ResourceDir::Private::init( const QString &path, const QString &format ) 00075 { 00076 mFormatName = format; 00077 00078 FormatFactory *factory = FormatFactory::self(); 00079 mFormat = factory->format( mFormatName ); 00080 00081 if ( !mFormat ) { 00082 mFormatName = QLatin1String( "vcard" ); 00083 mFormat = factory->format( mFormatName ); 00084 } 00085 00086 mLock = 0; 00087 00088 mParent->connect( &mDirWatch, SIGNAL(dirty(QString)), SLOT(pathChanged()) ); 00089 mParent->connect( &mDirWatch, SIGNAL(created(QString)), SLOT(pathChanged()) ); 00090 mParent->connect( &mDirWatch, SIGNAL(deleted(QString)), SLOT(pathChanged()) ); 00091 00092 mParent->setPath( path ); 00093 } 00094 00095 void ResourceDir::Private::pathChanged() 00096 { 00097 if ( !mParent->addressBook() ) { 00098 return; 00099 } 00100 00101 mParent->clear(); 00102 if ( mAsynchronous ) { 00103 mParent->asyncLoad(); 00104 } else { 00105 mParent->load(); 00106 mParent->addressBook()->emitAddressBookChanged(); 00107 } 00108 } 00109 00110 ResourceDir::ResourceDir() 00111 : Resource(), d( new Private( this ) ) 00112 { 00113 d->init( StdAddressBook::directoryName(), QLatin1String( "vcard" ) ); 00114 } 00115 00116 ResourceDir::ResourceDir( const KConfigGroup &group ) 00117 : Resource( group ), d( new Private( this ) ) 00118 { 00119 d->init( group.readPathEntry( "FilePath", StdAddressBook::directoryName() ), 00120 group.readEntry( "FileFormat", "vcard" ) ); 00121 } 00122 00123 ResourceDir::ResourceDir( const QString &path, const QString &format ) 00124 : Resource(), d( new Private( this ) ) 00125 { 00126 d->init( path, format ); 00127 } 00128 00129 ResourceDir::~ResourceDir() 00130 { 00131 delete d; 00132 } 00133 00134 void ResourceDir::writeConfig( KConfigGroup &group ) 00135 { 00136 Resource::writeConfig( group ); 00137 00138 if ( d->mPath == StdAddressBook::directoryName() ) { 00139 group.deleteEntry( "FilePath" ); 00140 } else { 00141 group.writePathEntry( "FilePath", d->mPath ); 00142 } 00143 00144 group.writeEntry( "FileFormat", d->mFormatName ); 00145 } 00146 00147 Ticket *ResourceDir::requestSaveTicket() 00148 { 00149 kDebug(); 00150 00151 if ( !addressBook() ) { 00152 return 0; 00153 } 00154 00155 delete d->mLock; 00156 d->mLock = new Lock( d->mPath ); 00157 00158 if ( d->mLock->lock() ) { 00159 addressBook()->emitAddressBookLocked(); 00160 } else { 00161 addressBook()->error( d->mLock->error() ); 00162 kDebug() << "Unable to lock path '" << d->mPath 00163 << "':" << d->mLock->error(); 00164 return 0; 00165 } 00166 00167 return createTicket( this ); 00168 } 00169 00170 void ResourceDir::releaseSaveTicket( Ticket *ticket ) 00171 { 00172 delete ticket; 00173 00174 delete d->mLock; 00175 d->mLock = 0; 00176 } 00177 00178 bool ResourceDir::doOpen() 00179 { 00180 QDir dir( d->mPath ); 00181 if ( !dir.exists() ) { // no directory available 00182 return dir.mkdir( dir.path() ); 00183 } else { 00184 const QStringList lst = dir.entryList( QDir::Files ); 00185 if ( lst.isEmpty() ) { //path doesn't exist or list of file empty 00186 return true; 00187 } 00188 QString testName = lst.first(); 00189 QFile file( d->mPath + QDir::separator() + testName ); 00190 if ( file.open( QIODevice::ReadOnly ) ) { 00191 return true; 00192 } 00193 if ( file.size() == 0 ) { 00194 return true; 00195 } 00196 00197 bool ok = d->mFormat->checkFormat( &file ); 00198 file.close(); 00199 return ok; 00200 } 00201 } 00202 00203 void ResourceDir::doClose() 00204 { 00205 } 00206 00207 bool ResourceDir::load() 00208 { 00209 kDebug() << d->mPath << "'"; 00210 00211 d->mAsynchronous = false; 00212 00213 QDir dir( d->mPath ); 00214 QStringList files = dir.entryList( QDir::Files ); 00215 00216 QStringList::Iterator it; 00217 bool ok = true; 00218 for ( it = files.begin(); it != files.end(); ++it ) { 00219 QFile file( d->mPath + QDir::separator() + (*it) ); 00220 00221 if ( !file.open( QIODevice::ReadOnly ) ) { 00222 addressBook()->error( i18n( "Unable to open file '%1' for reading", file.fileName() ) ); 00223 ok = false; 00224 continue; 00225 } 00226 00227 if ( !d->mFormat->loadAll( addressBook(), this, &file ) ) { 00228 ok = false; 00229 } 00230 00231 file.close(); 00232 } 00233 00234 return ok; 00235 } 00236 00237 bool ResourceDir::asyncLoad() 00238 { 00239 d->mAsynchronous = true; 00240 00241 bool ok = load(); 00242 if ( !ok ) { 00243 emit loadingError( this, i18n( "Loading resource '%1' failed!", resourceName() ) ); 00244 } else { 00245 emit loadingFinished( this ); 00246 } 00247 00248 return ok; 00249 } 00250 00251 bool ResourceDir::save( Ticket * ) 00252 { 00253 kDebug() << d->mPath << "'"; 00254 00255 Addressee::Map::Iterator it; 00256 bool ok = true; 00257 00258 d->mDirWatch.stopScan(); 00259 00260 for ( it = mAddrMap.begin(); it != mAddrMap.end(); ++it ) { 00261 if ( !it.value().changed() ) { 00262 continue; 00263 } 00264 00265 QFile file( d->mPath + QDir::separator() + (*it).uid() ); 00266 if ( !file.open( QIODevice::WriteOnly ) ) { 00267 addressBook()->error( i18n( "Unable to open file '%1' for writing", file.fileName() ) ); 00268 continue; 00269 } 00270 00271 d->mFormat->save( *it, &file ); 00272 00273 // mark as unchanged 00274 (*it).setChanged( false ); 00275 00276 file.close(); 00277 } 00278 00279 d->mDirWatch.startScan(); 00280 00281 return ok; 00282 } 00283 00284 bool ResourceDir::asyncSave( Ticket *ticket ) 00285 { 00286 bool ok = save( ticket ); 00287 if ( !ok ) { 00288 emit savingError( this, i18n( "Saving resource '%1' failed!", resourceName() ) ); 00289 } else { 00290 emit savingFinished( this ); 00291 } 00292 return ok; 00293 } 00294 00295 void ResourceDir::setPath( const QString &path ) 00296 { 00297 d->mDirWatch.stopScan(); 00298 if ( d->mDirWatch.contains( d->mPath ) ) { 00299 d->mDirWatch.removeDir( d->mPath ); 00300 } 00301 00302 d->mPath = path; 00303 d->mDirWatch.addDir( d->mPath, KDirWatch::WatchFiles ); 00304 d->mDirWatch.startScan(); 00305 } 00306 00307 QString ResourceDir::path() const 00308 { 00309 return d->mPath; 00310 } 00311 00312 void ResourceDir::setFormat( const QString &format ) 00313 { 00314 d->mFormatName = format; 00315 00316 delete d->mFormat; 00317 00318 FormatFactory *factory = FormatFactory::self(); 00319 d->mFormat = factory->format( d->mFormatName ); 00320 } 00321 00322 QString ResourceDir::format() const 00323 { 00324 return d->mFormatName; 00325 } 00326 00327 void ResourceDir::removeAddressee( const Addressee &addr ) 00328 { 00329 QFile::remove( d->mPath + QDir::separator() + addr.uid() ); 00330 mAddrMap.remove( addr.uid() ); 00331 } 00332 00333 #include "resourcedir.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 22:20:25 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 22:20:25 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.