22#include "resourcefile.h"
23#include "resourcefileconfig.h"
25#include "kabc/formatfactory.h"
26#include "kabc/stdaddressbook.h"
29#include <kio/scheduler.h>
30#include <kconfiggroup.h>
32#include <klocalizedstring.h>
34#include <kstandarddirs.h>
35#include <ktemporaryfile.h>
37#include <QtCore/QFile>
38#include <QtCore/QFileInfo>
47typedef QList< QPair<QString, QString> > MissingEntryList;
49class ResourceFile::ResourceFilePrivate
52 QMap< QString, MissingEntryList > mMissingEntries;
56 :
Resource(), mFormat( 0 ), mTempFile( 0 ),
57 mAsynchronous( false ), d( new ResourceFilePrivate )
62 formatName = QLatin1String(
"vcard" );
68 :
Resource( group ), mFormat( 0 ), mTempFile( 0 ),
69 mAsynchronous( false ), d( new ResourceFilePrivate )
74 formatName = group.readEntry(
"FileFormat",
"vcard" );
80 const QString &formatName )
81 :
Resource(), mFormat( 0 ), mTempFile( 0 ),
82 mAsynchronous( false ), d( new ResourceFilePrivate )
87void 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 ) ) {
223bool 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()) );
284void ResourceFile::emitLoadingFinished()
289void ResourceFile::emitSavingFinished()
294bool 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() );
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 );
353void 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 );
392void 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 );
431void 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() );
void emitAddressBookChanged()
Emits the signal addressBookChanged() using this as the parameter.
void error(const QString &msg)
Shows GUI independent error messages.
Addressee findByUid(const QString &uid) const
Searches an addressee with the specified unique identifier.
void emitAddressBookUnlocked()
Emits the signal addressBookUnlocked() using this as the parameter.
void emitAddressBookLocked()
Emits the signal addressBookLocked() using this as the parameter.
bool isEmpty() const
Return, if the address book entry is empty.
QString uid() const
Return unique identifier.
QList< Entry > List
A list of Entry instances.
Distribution list of email addresses.
void insertEntry(const Addressee &, const QString &email=QString())
Insert an entry into this distribution list.
QString name() const
Get name of this list.
QString identifier() const
Returns the distribution list's identifier.
Entry::List entries() const
Return list of entries belonging to this distribution list.
This class provides locking functionality for a file, directory or an arbitrary string-represented re...
virtual QString error() const
Returns the lastest error message.
virtual bool lock()
Lock resource.
virtual void doClose()
Closes the file again.
QString fileName() const
Return name of file used for loading and saving the address book.
virtual bool doOpen()
Tries to open the file and checks for the proper format.
virtual void writeConfig(KConfigGroup &group)
Writes the config back.
virtual void removeAddressee(const Addressee &addr)
Remove a addressee from its source.
virtual bool asyncSave(Ticket *ticket)
Saves all addressees asynchronously.
void setFileName(const QString &)
Set name of file to be used for saving.
virtual bool asyncLoad()
Loads all addressees asyncronously.
virtual bool save(Ticket *ticket)
Saves all addresses from address book to file.
void setFormat(const QString &name)
Sets a new format by name.
ResourceFile()
Default constructor.
QString format() const
Returns the format name.
virtual Ticket * requestSaveTicket()
Requests a save ticket, that is used by save()
virtual void releaseSaveTicket(Ticket *ticket)
Releases the ticket previousely requested with requestSaveTicket().
~ResourceFile()
Destructor.
virtual bool load()
Loads all addressees from file to the address book.
Ticket * createTicket(Resource *)
Factory method, just creates and returns a new Ticket for the given resource.
void savingFinished(Resource *resource)
This signal is emitted when the resource has finished the saving of all addressees from the internal ...
Addressee::Map mAddrMap
A mapping from KABC UIDs to the respective addressee.
AddressBook * addressBook()
Returns a pointer to the addressbook.
virtual void clear()
Removes all addressees and distribution lists from the resource.
DistributionListMap mDistListMap
A mapping from unique identifiers to the respective distribution list.
virtual void writeConfig(KConfigGroup &group)
Writes the resource specific config to file.
void loadingFinished(Resource *resource)
This signal is emitted when the resource has finished the loading of all addressees from the backend ...
static QString fileName()
Returns the default file name for vcard-based addressbook.
Helper class for handling coordinated save of address books.
QString identifier() const
virtual bool readOnly() const
Class that holds a Calendar Url (FBURL/CALADRURI/CALURI)
QMap< QString, DistributionList * > DistributionListMap
Typedef for map from IDs to respective DistribtionList.