22 #include "resourcefile.h"
23 #include "resourcefileconfig.h"
25 #include "kabc/formatfactory.h"
26 #include "kabc/stdaddressbook.h"
27 #include "kabc/lock.h"
29 #include <kio/scheduler.h>
30 #include <kconfiggroup.h>
32 #include <klocalizedstring.h>
33 #include <ksavefile.h>
34 #include <kstandarddirs.h>
35 #include <ktemporaryfile.h>
37 #include <QtCore/QFile>
38 #include <QtCore/QFileInfo>
40 #include <sys/types.h>
47 typedef QList< QPair<QString, QString> > MissingEntryList;
49 class ResourceFile::ResourceFilePrivate
52 QMap< QString, MissingEntryList > mMissingEntries;
56 :
Resource(), mFormat( 0 ), mTempFile( 0 ),
57 mAsynchronous( false ), d( new ResourceFilePrivate )
62 formatName = QLatin1String(
"vcard" );
64 init( fileName, formatName );
68 :
Resource( group ), mFormat( 0 ), mTempFile( 0 ),
69 mAsynchronous( false ), d( new ResourceFilePrivate )
74 formatName = group.readEntry(
"FileFormat",
"vcard" );
76 init( fileName, formatName );
80 const QString &formatName )
81 :
Resource(), mFormat( 0 ), mTempFile( 0 ),
82 mAsynchronous( false ), d( new ResourceFilePrivate )
84 init( fileName, formatName );
87 void ResourceFile::init(
const QString &fileName,
const QString &formatName )
89 mFormatName = formatName;
92 mFormat = factory->
format( mFormatName );
95 mFormatName = QLatin1String(
"vcard" );
96 mFormat = factory->
format( mFormatName );
99 connect( &mDirWatch, SIGNAL(dirty(QString)), SLOT(fileChanged(QString)) );
100 connect( &mDirWatch, SIGNAL(created(QString)), SLOT(fileChanged(QString)) );
101 connect( &mDirWatch, SIGNAL(deleted(QString)), SLOT(fileChanged(QString)) );
105 mDirWatch.addFile( KStandardDirs::locateLocal(
"data", QLatin1String(
"kabc/distlists" ) ) );
123 group.deleteEntry(
"FileName" );
125 group.writePathEntry(
"FileName", mFileName );
128 group.writeEntry(
"FileFormat", mFormatName );
140 mLock =
new Lock( mFileName );
142 if ( mLock->
lock() ) {
146 kDebug() <<
"Unable to lock file '" << mFileName
147 <<
"':" << mLock->
error();
166 QFile file( mFileName );
168 if ( !file.exists() ) {
170 bool ok = file.open( QIODevice::WriteOnly );
176 QFileInfo fileInfo( mFileName );
177 if (
readOnly() || !fileInfo.isWritable() ) {
178 if ( !file.open( QIODevice::ReadOnly ) ) {
182 if ( !file.open( QIODevice::ReadWrite ) ) {
187 if ( file.size() == 0 ) {
205 kDebug() << mFileName <<
"'";
207 mAsynchronous =
false;
209 QFile file( mFileName );
210 if ( !file.open( QIODevice::ReadOnly ) ) {
215 if ( !clearAndLoad( &file ) ) {
223 bool ResourceFile::clearAndLoad( QFile *file )
229 bool listsOk = loadDistributionLists();
231 return addresseesOk && listsOk;
236 mAsynchronous =
true;
240 QTimer::singleShot( 0,
this, SLOT(emitLoadingFinished()) );
251 QString extension = QLatin1Char(
'_' ) + QString::number( QDate::currentDate().dayOfWeek() );
252 (void) KSaveFile::simpleBackupFile( mFileName, QString(), extension );
254 mDirWatch.stopScan();
256 KSaveFile saveFile( mFileName );
259 if ( saveFile.open() ) {
260 saveToFile( &saveFile );
261 ok = saveFile.finalize();
268 mDirWatch.startScan();
279 QTimer::singleShot( 0,
this, SLOT(emitSavingFinished()) );
284 void ResourceFile::emitLoadingFinished()
289 void ResourceFile::emitSavingFinished()
294 bool ResourceFile::loadDistributionLists()
296 KConfig cfg( KStandardDirs::locateLocal(
"data", QLatin1String(
"kabc/distlists" ) ) );
298 KConfigGroup cg( &cfg,
"DistributionLists" );
299 KConfigGroup cgId( &cfg,
"DistributionLists-Identifiers" );
300 const QStringList entryList = cg.keyList();
302 d->mMissingEntries.clear();
304 QStringList::ConstIterator it;
305 for ( it = entryList.constBegin(); it != entryList.constEnd(); ++it ) {
306 const QString name = *it;
307 const QStringList value = cg.readEntry( name, QStringList() );
309 kDebug() << name << QLatin1Char(
':' ) << value.join( QLatin1String(
"," ) );
312 if ( cgId.isValid() ) {
313 const QString
identifier = cgId.readEntry( name, QString() );
314 if ( !identifier.isEmpty() ) {
323 MissingEntryList missingEntries;
324 QStringList::ConstIterator entryIt = value.constBegin();
325 while ( entryIt != value.constEnd() ) {
326 QString
id = *entryIt++;
327 QString email = entryIt != value.constEnd() ? *entryIt : QString();
328 if ( email.isEmpty() && !email.isNull() ) {
332 kDebug() <<
"----- Entry" << id;
338 missingEntries.append( qMakePair(
id, email ) );
341 if ( entryIt == value.constEnd() ) {
347 d->mMissingEntries.insert( name, missingEntries );
353 void ResourceFile::saveDistributionLists()
357 KConfig cfg( KStandardDirs::locateLocal(
"data", QLatin1String(
"kabc/distlists" ) ) );
358 KConfigGroup cg( &cfg,
"DistributionLists" );
360 KConfigGroup cgId( &cfg,
"DistributionLists-Identifiers" );
363 QMapIterator<QString, DistributionList*> it(
mDistListMap );
364 while ( it.hasNext() ) {
366 kDebug() <<
" Saving '" << list->
name() <<
"'";
370 DistributionList::Entry::List::ConstIterator it;
371 for ( it = entries.begin(); it != entries.end(); ++it ) {
372 value.append( ( *it ).addressee().uid() );
373 value.append( ( *it ).email() );
376 if ( d->mMissingEntries.find( list->
name() ) != d->mMissingEntries.end() ) {
377 const MissingEntryList missList = d->mMissingEntries[ list->
name() ];
378 MissingEntryList::ConstIterator missIt;
379 for ( missIt = missList.begin(); missIt != missList.end(); ++missIt ) {
380 value.append( ( *missIt ).first );
381 value.append( ( *missIt ).second );
385 cg.writeEntry( list->
name(), value );
392 void ResourceFile::saveToFile( QFile *file )
396 saveDistributionLists();
401 mDirWatch.stopScan();
402 if ( mDirWatch.contains( mFileName ) ) {
403 mDirWatch.removeFile( mFileName );
408 mDirWatch.addFile( mFileName );
409 mDirWatch.startScan();
423 mFormat = factory->
format( mFormatName );
431 void ResourceFile::fileChanged(
const QString &path )
439 if ( path == KStandardDirs::locateLocal(
"data", QLatin1String(
"kabc/distlists" ) ) ) {
446 qDeleteAll( tempDistListMap );
448 loadDistributionLists();
450 kDebug() <<
"addressBookChanged()";
457 if ( mAsynchronous ) {
461 kDebug() <<
"addressBookChanged()";
468 QFile::remove( KStandardDirs::locateLocal(
469 "data", QLatin1String(
"kabc/photos/" ) ) + addr.
uid() );
470 QFile::remove( KStandardDirs::locateLocal(
471 "data", QLatin1String(
"kabc/logos/" ) ) + addr.
uid() );
472 QFile::remove( KStandardDirs::locateLocal(
473 "data", QLatin1String(
"kabc/sounds/" ) ) + addr.
uid() );
Entry::List entries() const
Return list of entries belonging to this distribution list.
void emitAddressBookChanged()
Emits the signal addressBookChanged() using this as the parameter.
virtual void clear()
Removes all addressees and distribution lists from the resource.
This class provides locking functionality for a file, directory or an arbitrary string-represented re...
void error(const QString &msg)
Shows GUI independent error messages.
virtual bool save(Ticket *ticket)
Saves all addresses from address book to file.
void insertEntry(const Addressee &, const QString &email=QString())
Insert an entry into this distribution list.
static QString fileName()
Returns the default file name for vcard-based addressbook.
virtual Ticket * requestSaveTicket()
Requests a save ticket, that is used by save()
Distribution list of email addresses.
QList< Entry > List
A list of Entry instances.
Addressee findByUid(const QString &uid) const
Searches an addressee with the specified unique identifier.
Helper class for handling coordinated save of address books.
QString fileName() const
Return name of file used for loading and saving the address book.
ResourceFile()
Default constructor.
~ResourceFile()
Destructor.
virtual bool load()
Loads all addressees from file to the address book.
QString name() const
Get name of this list.
void savingFinished(Resource *resource)
This signal is emitted when the resource has finished the saving of all addressees from the internal ...
QString identifier() const
virtual bool doOpen()
Tries to open the file and checks for the proper format.
virtual void doClose()
Closes the file again.
QString identifier() const
Returns the distribution list's identifier.
virtual bool lock()
Lock resource.
virtual bool readOnly() const
QString format() const
Returns the format name.
bool isEmpty() const
Return, if the address book entry is empty.
void loadingFinished(Resource *resource)
This signal is emitted when the resource has finished the loading of all addressees from the backend ...
virtual bool asyncSave(Ticket *ticket)
Saves all addressees asynchronously.
virtual bool asyncLoad()
Loads all addressees asyncronously.
void emitAddressBookUnlocked()
Emits the signal addressBookUnlocked() using this as the parameter.
virtual void removeAddressee(const Addressee &addr)
Remove a addressee from its source.
void setFileName(const QString &)
Set name of file to be used for saving.
virtual QString error() const
Returns the lastest error message.
QString uid() const
Return unique identifier.
virtual void writeConfig(KConfigGroup &group)
Writes the config back.
Ticket * createTicket(Resource *)
Factory method, just creates and returns a new Ticket for the given resource.
DistributionListMap mDistListMap
A mapping from unique identifiers to the respective distribution list.
void emitAddressBookLocked()
Emits the signal addressBookLocked() using this as the parameter.
AddressBook * addressBook()
Returns a pointer to the addressbook.
Addressee::Map mAddrMap
A mapping from KABC UIDs to the respective addressee.
virtual void releaseSaveTicket(Ticket *ticket)
Releases the ticket previousely requested with requestSaveTicket().
virtual void writeConfig(KConfigGroup &group)
Writes the resource specific config to file.
void setFormat(const QString &name)
Sets a new format by name.