• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.3 API Reference
  • KDE Home
  • Contact Us
 

kabc

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., 51 Franklin Street, Fifth Floor,
00019     Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "resourcefile.h"
00023 #include "resourcefileconfig.h"
00024 
00025 #include "kabc/formatfactory.h"
00026 #include "kabc/stdaddressbook.h"
00027 #include "kabc/lock.h"
00028 
00029 #include <kio/scheduler.h>
00030 #include <kconfiggroup.h>
00031 #include <kdebug.h>
00032 #include <klocale.h>
00033 #include <ksavefile.h>
00034 #include <kstandarddirs.h>
00035 #include <ktemporaryfile.h>
00036 
00037 #include <QtCore/QFile>
00038 #include <QtCore/QFileInfo>
00039 
00040 #include <sys/types.h>
00041 #include <sys/stat.h>
00042 #include <signal.h>
00043 #include <unistd.h>
00044 
00045 using namespace KABC;
00046 
00047 typedef QList< QPair<QString, QString> > MissingEntryList;
00048 
00049 class ResourceFile::ResourceFilePrivate
00050 {
00051   public:
00052     QMap< QString, MissingEntryList > mMissingEntries;
00053 };
00054 
00055 ResourceFile::ResourceFile()
00056   : Resource(), mFormat( 0 ), mTempFile( 0 ),
00057     mAsynchronous( false ), d( new ResourceFilePrivate )
00058 {
00059   QString fileName, formatName;
00060 
00061   fileName = StdAddressBook::fileName();
00062   formatName = QLatin1String( "vcard" );
00063 
00064   init( fileName, formatName );
00065 }
00066 
00067 ResourceFile::ResourceFile( const KConfigGroup &group )
00068   : Resource( group ), mFormat( 0 ), mTempFile( 0 ),
00069     mAsynchronous( false ), d( new ResourceFilePrivate )
00070 {
00071   QString fileName, formatName;
00072 
00073   fileName = group.readPathEntry( "FileName", StdAddressBook::fileName() );
00074   formatName = group.readEntry( "FileFormat", "vcard" );
00075 
00076   init( fileName, formatName );
00077 }
00078 
00079 ResourceFile::ResourceFile( const QString &fileName,
00080                             const QString &formatName )
00081   : Resource(), mFormat( 0 ), mTempFile( 0 ),
00082     mAsynchronous( false ), d( new ResourceFilePrivate )
00083 {
00084   init( fileName, formatName );
00085 }
00086 
00087 void ResourceFile::init( const QString &fileName, const QString &formatName )
00088 {
00089   mFormatName = formatName;
00090 
00091   FormatFactory *factory = FormatFactory::self();
00092   mFormat = factory->format( mFormatName );
00093 
00094   if ( !mFormat ) {
00095     mFormatName = QLatin1String( "vcard" );
00096     mFormat = factory->format( mFormatName );
00097   }
00098 
00099   connect( &mDirWatch, SIGNAL(dirty(QString)), SLOT(fileChanged(QString)) );
00100   connect( &mDirWatch, SIGNAL(created(QString)), SLOT(fileChanged(QString)) );
00101   connect( &mDirWatch, SIGNAL(deleted(QString)), SLOT(fileChanged(QString)) );
00102 
00103   setFileName( fileName );
00104 
00105   mDirWatch.addFile( KStandardDirs::locateLocal( "data", QLatin1String( "kabc/distlists" ) ) );
00106 
00107   mLock = 0;
00108 }
00109 
00110 ResourceFile::~ResourceFile()
00111 {
00112   delete d;
00113   d = 0;
00114   delete mFormat;
00115   mFormat = 0;
00116 }
00117 
00118 void ResourceFile::writeConfig( KConfigGroup &group )
00119 {
00120   Resource::writeConfig( group );
00121 
00122   if ( mFileName == StdAddressBook::fileName() ) {
00123     group.deleteEntry( "FileName" );
00124   } else {
00125     group.writePathEntry( "FileName", mFileName );
00126   }
00127 
00128   group.writeEntry( "FileFormat", mFormatName );
00129 }
00130 
00131 Ticket *ResourceFile::requestSaveTicket()
00132 {
00133   kDebug();
00134 
00135   if ( !addressBook() ) {
00136     return 0;
00137   }
00138 
00139   delete mLock;
00140   mLock = new Lock( mFileName );
00141 
00142   if ( mLock->lock() ) {
00143     addressBook()->emitAddressBookLocked();
00144   } else {
00145     addressBook()->error( mLock->error() );
00146     kDebug() << "Unable to lock file '" << mFileName
00147              << "':" << mLock->error();
00148     return 0;
00149   }
00150 
00151   return createTicket( this );
00152 }
00153 
00154 void ResourceFile::releaseSaveTicket( Ticket *ticket )
00155 {
00156   delete ticket;
00157 
00158   delete mLock;
00159   mLock = 0;
00160 
00161   addressBook()->emitAddressBookUnlocked();
00162 }
00163 
00164 bool ResourceFile::doOpen()
00165 {
00166   QFile file( mFileName );
00167 
00168   if ( !file.exists() ) {
00169     // try to create the file
00170     bool ok = file.open( QIODevice::WriteOnly );
00171     if ( ok ) {
00172       file.close();
00173     }
00174     return ok;
00175   } else {
00176     QFileInfo fileInfo( mFileName );
00177     if ( readOnly() || !fileInfo.isWritable() ) {
00178       if ( !file.open( QIODevice::ReadOnly ) ) {
00179         return false;
00180       }
00181     } else {
00182       if ( !file.open( QIODevice::ReadWrite ) ) {
00183         return false;
00184       }
00185     }
00186 
00187     if ( file.size() == 0 ) {
00188       file.close();
00189       return true;
00190     }
00191 
00192     bool ok = mFormat->checkFormat( &file );
00193     file.close();
00194 
00195     return ok;
00196   }
00197 }
00198 
00199 void ResourceFile::doClose()
00200 {
00201 }
00202 
00203 bool ResourceFile::load()
00204 {
00205   kDebug() << mFileName << "'";
00206 
00207   mAsynchronous = false;
00208 
00209   QFile file( mFileName );
00210   if ( !file.open( QIODevice::ReadOnly ) ) {
00211     addressBook()->error( i18n( "Unable to open file '%1'.", mFileName ) );
00212     return false;
00213   }
00214 
00215   if ( !clearAndLoad( &file ) ) {
00216       addressBook()->error( i18n( "Problems parsing file '%1'.", mFileName ) );
00217     return false;
00218   }
00219 
00220   return true;
00221 }
00222 
00223 bool ResourceFile::clearAndLoad( QFile *file )
00224 {
00225   clear();
00226 
00227   bool addresseesOk = mFormat->loadAll( addressBook(), this, file );
00228 
00229   bool listsOk = loadDistributionLists();
00230 
00231   return addresseesOk && listsOk;
00232 }
00233 
00234 bool ResourceFile::asyncLoad()
00235 {
00236   mAsynchronous = true;
00237 
00238   load();
00239 
00240   QTimer::singleShot( 0, this, SLOT(emitLoadingFinished()) );
00241 
00242   return true;
00243 }
00244 
00245 bool ResourceFile::save( Ticket *ticket )
00246 {
00247   Q_UNUSED( ticket );
00248   kDebug();
00249 
00250   // create backup file
00251   QString extension = QLatin1Char( '_' ) + QString::number( QDate::currentDate().dayOfWeek() );
00252   (void) KSaveFile::simpleBackupFile( mFileName, QString(), extension );
00253 
00254   mDirWatch.stopScan();
00255 
00256   KSaveFile saveFile( mFileName );
00257   bool ok = false;
00258 
00259   if ( saveFile.open() ) {
00260     saveToFile( &saveFile );
00261     ok = saveFile.finalize();
00262   }
00263 
00264   if ( !ok ) {
00265     addressBook()->error( i18n( "Unable to save file '%1'.", mFileName ) );
00266   }
00267 
00268   mDirWatch.startScan();
00269 
00270   return ok;
00271 }
00272 
00273 bool ResourceFile::asyncSave( Ticket *ticket )
00274 {
00275   kDebug();
00276 
00277   save( ticket );
00278 
00279   QTimer::singleShot( 0, this, SLOT(emitSavingFinished()) );
00280 
00281   return true;
00282 }
00283 
00284 void ResourceFile::emitLoadingFinished()
00285 {
00286   emit loadingFinished( this );
00287 }
00288 
00289 void ResourceFile::emitSavingFinished()
00290 {
00291   emit savingFinished( this );
00292 }
00293 
00294 bool ResourceFile::loadDistributionLists()
00295 {
00296   KConfig cfg( KStandardDirs::locateLocal( "data", QLatin1String( "kabc/distlists" ) ) );
00297 
00298   KConfigGroup cg( &cfg, "DistributionLists" );
00299   KConfigGroup cgId( &cfg, "DistributionLists-Identifiers" );
00300   const QStringList entryList = cg.keyList();
00301 
00302   d->mMissingEntries.clear();
00303 
00304   QStringList::ConstIterator it;
00305   for ( it = entryList.constBegin(); it != entryList.constEnd(); ++it ) {
00306     const QString name = *it;
00307     const QStringList value = cg.readEntry( name, QStringList() );
00308 
00309     kDebug() << name << QLatin1Char( ':' ) << value.join( QLatin1String( "," ) );
00310 
00311     DistributionList *list = 0;
00312     if ( cgId.isValid() ) {
00313       const QString identifier = cgId.readEntry( name, QString() );
00314       if ( !identifier.isEmpty() ) {
00315         list = new DistributionList( this, identifier, name );
00316       }
00317     }
00318 
00319     if ( list == 0 ) {
00320       list = new DistributionList( this, name );
00321     }
00322 
00323     MissingEntryList missingEntries;
00324     QStringList::ConstIterator entryIt = value.constBegin();
00325     while ( entryIt != value.constEnd() ) {
00326       QString id = *entryIt++;
00327       QString email = entryIt != value.constEnd() ? *entryIt : QString();
00328       if ( email.isEmpty() && !email.isNull() ) {
00329         email = QString(); //krazy:exclude=nullstrassign
00330       }
00331 
00332       kDebug() << "----- Entry" << id;
00333 
00334       Addressee a = addressBook()->findByUid( id );
00335       if ( !a.isEmpty() ) {
00336         list->insertEntry( a, email );
00337       } else {
00338         missingEntries.append( qMakePair( id, email ) );
00339       }
00340 
00341       if ( entryIt == value.constEnd() ) {
00342         break;
00343       }
00344       ++entryIt;
00345     }
00346 
00347     d->mMissingEntries.insert( name, missingEntries );
00348   }
00349 
00350   return true;
00351 }
00352 
00353 void ResourceFile::saveDistributionLists()
00354 {
00355   kDebug();
00356 
00357   KConfig cfg( KStandardDirs::locateLocal( "data", QLatin1String( "kabc/distlists" ) ) );
00358   KConfigGroup cg( &cfg, "DistributionLists" );
00359   cg.deleteGroup();
00360   KConfigGroup cgId( &cfg, "DistributionLists-Identifiers" );
00361   cgId.deleteGroup();
00362 
00363   QMapIterator<QString, DistributionList*> it( mDistListMap );
00364   while ( it.hasNext() ) {
00365     DistributionList *list = it.next().value();
00366     kDebug() << "  Saving '" << list->name() << "'";
00367 
00368     QStringList value;
00369     const DistributionList::Entry::List entries = list->entries();
00370     DistributionList::Entry::List::ConstIterator it;
00371     for ( it = entries.begin(); it != entries.end(); ++it ) {
00372       value.append( (*it).addressee().uid() );
00373       value.append( (*it).email() );
00374     }
00375 
00376     if ( d->mMissingEntries.find( list->name() ) != d->mMissingEntries.end() ) {
00377       const MissingEntryList missList = d->mMissingEntries[ list->name() ];
00378       MissingEntryList::ConstIterator missIt;
00379       for ( missIt = missList.begin(); missIt != missList.end(); ++missIt ) {
00380         value.append( (*missIt).first );
00381         value.append( (*missIt).second );
00382       }
00383     }
00384 
00385     cg.writeEntry( list->name(), value );
00386     cgId.writeEntry( list->name(), list->identifier() );
00387   }
00388 
00389   cfg.sync();
00390 }
00391 
00392 void ResourceFile::saveToFile( QFile *file )
00393 {
00394   mFormat->saveAll( addressBook(), this, file );
00395 
00396   saveDistributionLists();
00397 }
00398 
00399 void ResourceFile::setFileName( const QString &fileName )
00400 {
00401   mDirWatch.stopScan();
00402   if ( mDirWatch.contains( mFileName ) ) {
00403     mDirWatch.removeFile( mFileName );
00404   }
00405 
00406   mFileName = fileName;
00407 
00408   mDirWatch.addFile( mFileName );
00409   mDirWatch.startScan();
00410 }
00411 
00412 QString ResourceFile::fileName() const
00413 {
00414   return mFileName;
00415 }
00416 
00417 void ResourceFile::setFormat( const QString &format )
00418 {
00419   mFormatName = format;
00420   delete mFormat;
00421 
00422   FormatFactory *factory = FormatFactory::self();
00423   mFormat = factory->format( mFormatName );
00424 }
00425 
00426 QString ResourceFile::format() const
00427 {
00428   return mFormatName;
00429 }
00430 
00431 void ResourceFile::fileChanged( const QString &path )
00432 {
00433   kDebug() << path;
00434 
00435   if ( !addressBook() ) {
00436     return;
00437   }
00438 
00439   if ( path == KStandardDirs::locateLocal( "data", QLatin1String( "kabc/distlists" ) ) ) {
00440     // clear old distribution lists
00441     // take a copy of mDistListMap, then clear it and finally qDeleteAll
00442     // the copy to avoid problems with removeDistributionList() called by
00443     // ~DistributionList().
00444     DistributionListMap tempDistListMap( mDistListMap );
00445     mDistListMap.clear();
00446     qDeleteAll( tempDistListMap );
00447 
00448     loadDistributionLists();
00449 
00450     kDebug() << "addressBookChanged()";
00451     addressBook()->emitAddressBookChanged();
00452 
00453     return;
00454   }
00455 
00456 //  clear(); // moved to clearAndLoad()
00457   if ( mAsynchronous ) {
00458     asyncLoad();
00459   } else {
00460     load();
00461     kDebug() << "addressBookChanged()";
00462     addressBook()->emitAddressBookChanged();
00463   }
00464 }
00465 
00466 void ResourceFile::removeAddressee( const Addressee &addr )
00467 {
00468   QFile::remove( KStandardDirs::locateLocal(
00469                    "data", QLatin1String( "kabc/photos/" ) ) + addr.uid() );
00470   QFile::remove( KStandardDirs::locateLocal(
00471                    "data", QLatin1String( "kabc/logos/" ) ) + addr.uid() );
00472   QFile::remove( KStandardDirs::locateLocal(
00473                    "data", QLatin1String( "kabc/sounds/" ) ) + addr.uid() );
00474 
00475   mAddrMap.remove( addr.uid() );
00476 }
00477 
00478 #include "resourcefile.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon May 14 2012 05:09:41 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kabc

Skip menu "kabc"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.8.3 API Reference

Skip menu "kdepimlibs-4.8.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal