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

kabc

  • kabc
  • plugins
  • file
resourcefile.cpp
1/*
2 This file is part of libkabc.
3
4 Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22#include "resourcefile.h"
23#include "resourcefileconfig.h"
24
25#include "kabc/formatfactory.h"
26#include "kabc/stdaddressbook.h"
27#include "kabc/lock.h"
28
29#include <kio/scheduler.h>
30#include <kconfiggroup.h>
31#include <kdebug.h>
32#include <klocalizedstring.h>
33#include <ksavefile.h>
34#include <kstandarddirs.h>
35#include <ktemporaryfile.h>
36
37#include <QtCore/QFile>
38#include <QtCore/QFileInfo>
39
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <signal.h>
43#include <unistd.h>
44
45using namespace KABC;
46
47typedef QList< QPair<QString, QString> > MissingEntryList;
48
49class ResourceFile::ResourceFilePrivate
50{
51 public:
52 QMap< QString, MissingEntryList > mMissingEntries;
53};
54
55ResourceFile::ResourceFile()
56 : Resource(), mFormat( 0 ), mTempFile( 0 ),
57 mAsynchronous( false ), d( new ResourceFilePrivate )
58{
59 QString fileName, formatName;
60
61 fileName = StdAddressBook::fileName();
62 formatName = QLatin1String( "vcard" );
63
64 init( fileName, formatName );
65}
66
67ResourceFile::ResourceFile( const KConfigGroup &group )
68 : Resource( group ), mFormat( 0 ), mTempFile( 0 ),
69 mAsynchronous( false ), d( new ResourceFilePrivate )
70{
71 QString fileName, formatName;
72
73 fileName = group.readPathEntry( "FileName", StdAddressBook::fileName() );
74 formatName = group.readEntry( "FileFormat", "vcard" );
75
76 init( fileName, formatName );
77}
78
79ResourceFile::ResourceFile( const QString &fileName,
80 const QString &formatName )
81 : Resource(), mFormat( 0 ), mTempFile( 0 ),
82 mAsynchronous( false ), d( new ResourceFilePrivate )
83{
84 init( fileName, formatName );
85}
86
87void ResourceFile::init( const QString &fileName, const QString &formatName )
88{
89 mFormatName = formatName;
90
91 FormatFactory *factory = FormatFactory::self();
92 mFormat = factory->format( mFormatName );
93
94 if ( !mFormat ) {
95 mFormatName = QLatin1String( "vcard" );
96 mFormat = factory->format( mFormatName );
97 }
98
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)) );
102
103 setFileName( fileName );
104
105 mDirWatch.addFile( KStandardDirs::locateLocal( "data", QLatin1String( "kabc/distlists" ) ) );
106
107 mLock = 0;
108}
109
110ResourceFile::~ResourceFile()
111{
112 delete d;
113 d = 0;
114 delete mFormat;
115 mFormat = 0;
116}
117
118void ResourceFile::writeConfig( KConfigGroup &group )
119{
120 Resource::writeConfig( group );
121
122 if ( mFileName == StdAddressBook::fileName() ) {
123 group.deleteEntry( "FileName" );
124 } else {
125 group.writePathEntry( "FileName", mFileName );
126 }
127
128 group.writeEntry( "FileFormat", mFormatName );
129}
130
131Ticket *ResourceFile::requestSaveTicket()
132{
133 kDebug();
134
135 if ( !addressBook() ) {
136 return 0;
137 }
138
139 delete mLock;
140 mLock = new Lock( mFileName );
141
142 if ( mLock->lock() ) {
143 addressBook()->emitAddressBookLocked();
144 } else {
145 addressBook()->error( mLock->error() );
146 kDebug() << "Unable to lock file '" << mFileName
147 << "':" << mLock->error();
148 return 0;
149 }
150
151 return createTicket( this );
152}
153
154void ResourceFile::releaseSaveTicket( Ticket *ticket )
155{
156 delete ticket;
157
158 delete mLock;
159 mLock = 0;
160
161 addressBook()->emitAddressBookUnlocked();
162}
163
164bool ResourceFile::doOpen()
165{
166 QFile file( mFileName );
167
168 if ( !file.exists() ) {
169 // try to create the file
170 bool ok = file.open( QIODevice::WriteOnly );
171 if ( ok ) {
172 file.close();
173 }
174 return ok;
175 } else {
176 QFileInfo fileInfo( mFileName );
177 if ( readOnly() || !fileInfo.isWritable() ) {
178 if ( !file.open( QIODevice::ReadOnly ) ) {
179 return false;
180 }
181 } else {
182 if ( !file.open( QIODevice::ReadWrite ) ) {
183 return false;
184 }
185 }
186
187 if ( file.size() == 0 ) {
188 file.close();
189 return true;
190 }
191
192 bool ok = mFormat->checkFormat( &file );
193 file.close();
194
195 return ok;
196 }
197}
198
199void ResourceFile::doClose()
200{
201}
202
203bool ResourceFile::load()
204{
205 kDebug() << mFileName << "'";
206
207 mAsynchronous = false;
208
209 QFile file( mFileName );
210 if ( !file.open( QIODevice::ReadOnly ) ) {
211 addressBook()->error( i18n( "Unable to open file '%1'.", mFileName ) );
212 return false;
213 }
214
215 if ( !clearAndLoad( &file ) ) {
216 addressBook()->error( i18n( "Problems parsing file '%1'.", mFileName ) );
217 return false;
218 }
219
220 return true;
221}
222
223bool ResourceFile::clearAndLoad( QFile *file )
224{
225 clear();
226
227 bool addresseesOk = mFormat->loadAll( addressBook(), this, file );
228
229 bool listsOk = loadDistributionLists();
230
231 return addresseesOk && listsOk;
232}
233
234bool ResourceFile::asyncLoad()
235{
236 mAsynchronous = true;
237
238 load();
239
240 QTimer::singleShot( 0, this, SLOT(emitLoadingFinished()) );
241
242 return true;
243}
244
245bool ResourceFile::save( Ticket *ticket )
246{
247 Q_UNUSED( ticket );
248 kDebug();
249
250 // create backup file
251 QString extension = QLatin1Char( '_' ) + QString::number( QDate::currentDate().dayOfWeek() );
252 (void) KSaveFile::simpleBackupFile( mFileName, QString(), extension );
253
254 mDirWatch.stopScan();
255
256 KSaveFile saveFile( mFileName );
257 bool ok = false;
258
259 if ( saveFile.open() ) {
260 saveToFile( &saveFile );
261 ok = saveFile.finalize();
262 }
263
264 if ( !ok ) {
265 addressBook()->error( i18n( "Unable to save file '%1'.", mFileName ) );
266 }
267
268 mDirWatch.startScan();
269
270 return ok;
271}
272
273bool ResourceFile::asyncSave( Ticket *ticket )
274{
275 kDebug();
276
277 save( ticket );
278
279 QTimer::singleShot( 0, this, SLOT(emitSavingFinished()) );
280
281 return true;
282}
283
284void ResourceFile::emitLoadingFinished()
285{
286 emit loadingFinished( this );
287}
288
289void ResourceFile::emitSavingFinished()
290{
291 emit savingFinished( this );
292}
293
294bool ResourceFile::loadDistributionLists()
295{
296 KConfig cfg( KStandardDirs::locateLocal( "data", QLatin1String( "kabc/distlists" ) ) );
297
298 KConfigGroup cg( &cfg, "DistributionLists" );
299 KConfigGroup cgId( &cfg, "DistributionLists-Identifiers" );
300 const QStringList entryList = cg.keyList();
301
302 d->mMissingEntries.clear();
303
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() );
308
309 kDebug() << name << QLatin1Char( ':' ) << value.join( QLatin1String( "," ) );
310
311 DistributionList *list = 0;
312 if ( cgId.isValid() ) {
313 const QString identifier = cgId.readEntry( name, QString() );
314 if ( !identifier.isEmpty() ) {
315 list = new DistributionList( this, identifier, name );
316 }
317 }
318
319 if ( list == 0 ) {
320 list = new DistributionList( this, name );
321 }
322
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() ) {
329 email = QString(); //krazy:exclude=nullstrassign
330 }
331
332 kDebug() << "----- Entry" << id;
333
334 Addressee a = addressBook()->findByUid( id );
335 if ( !a.isEmpty() ) {
336 list->insertEntry( a, email );
337 } else {
338 missingEntries.append( qMakePair( id, email ) );
339 }
340
341 if ( entryIt == value.constEnd() ) {
342 break;
343 }
344 ++entryIt;
345 }
346
347 d->mMissingEntries.insert( name, missingEntries );
348 }
349
350 return true;
351}
352
353void ResourceFile::saveDistributionLists()
354{
355 kDebug();
356
357 KConfig cfg( KStandardDirs::locateLocal( "data", QLatin1String( "kabc/distlists" ) ) );
358 KConfigGroup cg( &cfg, "DistributionLists" );
359 cg.deleteGroup();
360 KConfigGroup cgId( &cfg, "DistributionLists-Identifiers" );
361 cgId.deleteGroup();
362
363 QMapIterator<QString, DistributionList*> it( mDistListMap );
364 while ( it.hasNext() ) {
365 DistributionList *list = it.next().value();
366 kDebug() << " Saving '" << list->name() << "'";
367
368 QStringList value;
369 const DistributionList::Entry::List entries = list->entries();
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() );
374 }
375
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 );
382 }
383 }
384
385 cg.writeEntry( list->name(), value );
386 cgId.writeEntry( list->name(), list->identifier() );
387 }
388
389 cfg.sync();
390}
391
392void ResourceFile::saveToFile( QFile *file )
393{
394 mFormat->saveAll( addressBook(), this, file );
395
396 saveDistributionLists();
397}
398
399void ResourceFile::setFileName( const QString &fileName )
400{
401 mDirWatch.stopScan();
402 if ( mDirWatch.contains( mFileName ) ) {
403 mDirWatch.removeFile( mFileName );
404 }
405
406 mFileName = fileName;
407
408 mDirWatch.addFile( mFileName );
409 mDirWatch.startScan();
410}
411
412QString ResourceFile::fileName() const
413{
414 return mFileName;
415}
416
417void ResourceFile::setFormat( const QString &format )
418{
419 mFormatName = format;
420 delete mFormat;
421
422 FormatFactory *factory = FormatFactory::self();
423 mFormat = factory->format( mFormatName );
424}
425
426QString ResourceFile::format() const
427{
428 return mFormatName;
429}
430
431void ResourceFile::fileChanged( const QString &path )
432{
433 kDebug() << path;
434
435 if ( !addressBook() ) {
436 return;
437 }
438
439 if ( path == KStandardDirs::locateLocal( "data", QLatin1String( "kabc/distlists" ) ) ) {
440 // clear old distribution lists
441 // take a copy of mDistListMap, then clear it and finally qDeleteAll
442 // the copy to avoid problems with removeDistributionList() called by
443 // ~DistributionList().
444 DistributionListMap tempDistListMap( mDistListMap );
445 mDistListMap.clear();
446 qDeleteAll( tempDistListMap );
447
448 loadDistributionLists();
449
450 kDebug() << "addressBookChanged()";
451 addressBook()->emitAddressBookChanged();
452
453 return;
454 }
455
456// clear(); // moved to clearAndLoad()
457 if ( mAsynchronous ) {
458 asyncLoad();
459 } else {
460 load();
461 kDebug() << "addressBookChanged()";
462 addressBook()->emitAddressBookChanged();
463 }
464}
465
466void ResourceFile::removeAddressee( const Addressee &addr )
467{
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() );
474
475 mAddrMap.remove( addr.uid() );
476}
477
KABC::AddressBook::emitAddressBookChanged
void emitAddressBookChanged()
Emits the signal addressBookChanged() using this as the parameter.
Definition addressbook.h:597
KABC::AddressBook::error
void error(const QString &msg)
Shows GUI independent error messages.
Definition addressbook.cpp:901
KABC::AddressBook::findByUid
Addressee findByUid(const QString &uid) const
Searches an addressee with the specified unique identifier.
Definition addressbook.cpp:613
KABC::AddressBook::emitAddressBookUnlocked
void emitAddressBookUnlocked()
Emits the signal addressBookUnlocked() using this as the parameter.
Definition addressbook.h:593
KABC::AddressBook::emitAddressBookLocked
void emitAddressBookLocked()
Emits the signal addressBookLocked() using this as the parameter.
Definition addressbook.h:589
KABC::Addressee
address book entry
Definition addressee.h:79
KABC::Addressee::isEmpty
bool isEmpty() const
Return, if the address book entry is empty.
Definition addressee.cpp:428
KABC::Addressee::uid
QString uid() const
Return unique identifier.
Definition addressee.cpp:442
KABC::DistributionList::Entry::List
QList< Entry > List
A list of Entry instances.
Definition distributionlist.h:61
KABC::DistributionList
Distribution list of email addresses.
Definition distributionlist.h:46
KABC::DistributionList::insertEntry
void insertEntry(const Addressee &, const QString &email=QString())
Insert an entry into this distribution list.
Definition distributionlist.cpp:141
KABC::DistributionList::name
QString name() const
Get name of this list.
Definition distributionlist.cpp:136
KABC::DistributionList::identifier
QString identifier() const
Returns the distribution list's identifier.
Definition distributionlist.cpp:126
KABC::DistributionList::entries
Entry::List entries() const
Return list of entries belonging to this distribution list.
Definition distributionlist.cpp:192
KABC::FormatFactory
Class for loading format plugins.
Definition formatfactory.h:95
KABC::FormatFactory::format
Format * format(const QString &type)
Returns a pointer to a format object or a null pointer if format type doesn't exist.
Definition formatfactory.cpp:145
KABC::FormatFactory::self
static FormatFactory * self()
Returns the global format factory.
Definition formatfactory.cpp:68
KABC::Format::saveAll
virtual void saveAll(AddressBook *, Resource *, QFile *file)=0
Save whole addressbook to file.
KABC::Format::loadAll
virtual bool loadAll(AddressBook *, Resource *, QFile *file)=0
Load whole addressbook from file.
KABC::Format::checkFormat
virtual bool checkFormat(QFile *file) const =0
Checks if given file contains the right format.
KABC::Lock
This class provides locking functionality for a file, directory or an arbitrary string-represented re...
Definition lock.h:35
KABC::Lock::error
virtual QString error() const
Returns the lastest error message.
Definition lock.cpp:179
KABC::Lock::lock
virtual bool lock()
Lock resource.
Definition lock.cpp:108
KABC::ResourceFile::doClose
virtual void doClose()
Closes the file again.
Definition resourcefile.cpp:199
KABC::ResourceFile::fileName
QString fileName() const
Return name of file used for loading and saving the address book.
Definition resourcefile.cpp:412
KABC::ResourceFile::doOpen
virtual bool doOpen()
Tries to open the file and checks for the proper format.
Definition resourcefile.cpp:164
KABC::ResourceFile::writeConfig
virtual void writeConfig(KConfigGroup &group)
Writes the config back.
Definition resourcefile.cpp:118
KABC::ResourceFile::removeAddressee
virtual void removeAddressee(const Addressee &addr)
Remove a addressee from its source.
Definition resourcefile.cpp:466
KABC::ResourceFile::asyncSave
virtual bool asyncSave(Ticket *ticket)
Saves all addressees asynchronously.
Definition resourcefile.cpp:273
KABC::ResourceFile::setFileName
void setFileName(const QString &)
Set name of file to be used for saving.
Definition resourcefile.cpp:399
KABC::ResourceFile::asyncLoad
virtual bool asyncLoad()
Loads all addressees asyncronously.
Definition resourcefile.cpp:234
KABC::ResourceFile::save
virtual bool save(Ticket *ticket)
Saves all addresses from address book to file.
Definition resourcefile.cpp:245
KABC::ResourceFile::setFormat
void setFormat(const QString &name)
Sets a new format by name.
Definition resourcefile.cpp:417
KABC::ResourceFile::ResourceFile
ResourceFile()
Default constructor.
Definition resourcefile.cpp:55
KABC::ResourceFile::format
QString format() const
Returns the format name.
Definition resourcefile.cpp:426
KABC::ResourceFile::requestSaveTicket
virtual Ticket * requestSaveTicket()
Requests a save ticket, that is used by save()
Definition resourcefile.cpp:131
KABC::ResourceFile::releaseSaveTicket
virtual void releaseSaveTicket(Ticket *ticket)
Releases the ticket previousely requested with requestSaveTicket().
Definition resourcefile.cpp:154
KABC::ResourceFile::~ResourceFile
~ResourceFile()
Destructor.
Definition resourcefile.cpp:110
KABC::ResourceFile::load
virtual bool load()
Loads all addressees from file to the address book.
Definition resourcefile.cpp:203
KABC::Resource
Definition resource.h:65
KABC::Resource::createTicket
Ticket * createTicket(Resource *)
Factory method, just creates and returns a new Ticket for the given resource.
Definition resource.cpp:279
KABC::Resource::savingFinished
void savingFinished(Resource *resource)
This signal is emitted when the resource has finished the saving of all addressees from the internal ...
KABC::Resource::mAddrMap
Addressee::Map mAddrMap
A mapping from KABC UIDs to the respective addressee.
Definition resource.h:527
KABC::Resource::addressBook
AddressBook * addressBook()
Returns a pointer to the addressbook.
Definition resource.cpp:274
KABC::Resource::clear
virtual void clear()
Removes all addressees and distribution lists from the resource.
Definition resource.cpp:354
KABC::Resource::mDistListMap
DistributionListMap mDistListMap
A mapping from unique identifiers to the respective distribution list.
Definition resource.h:532
KABC::Resource::writeConfig
virtual void writeConfig(KConfigGroup &group)
Writes the resource specific config to file.
Definition resource.cpp:264
KABC::Resource::loadingFinished
void loadingFinished(Resource *resource)
This signal is emitted when the resource has finished the loading of all addressees from the backend ...
KABC::StdAddressBook::fileName
static QString fileName()
Returns the default file name for vcard-based addressbook.
Definition stdaddressbook.cpp:64
KABC::Ticket
Helper class for handling coordinated save of address books.
Definition resource.h:38
KRES::Resource::identifier
QString identifier() const
KRES::Resource::readOnly
virtual bool readOnly() const
KABC
Class that holds a Calendar Url (FBURL/CALADRURI/CALURI)
Definition address.h:29
KABC::DistributionListMap
QMap< QString, DistributionList * > DistributionListMap
Typedef for map from IDs to respective DistribtionList.
Definition distributionlist.h:205
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Wed Jan 24 2024 00:00:00 by doxygen 1.10.0 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.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • 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