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

kabc

  • sources
  • kde-4.12
  • kdepimlibs
  • 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 
45 using namespace KABC;
46 
47 typedef QList< QPair<QString, QString> > MissingEntryList;
48 
49 class ResourceFile::ResourceFilePrivate
50 {
51  public:
52  QMap< QString, MissingEntryList > mMissingEntries;
53 };
54 
55 ResourceFile::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 
67 ResourceFile::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 
79 ResourceFile::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 
87 void 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 
110 ResourceFile::~ResourceFile()
111 {
112  delete d;
113  d = 0;
114  delete mFormat;
115  mFormat = 0;
116 }
117 
118 void 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 
131 Ticket *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 
154 void ResourceFile::releaseSaveTicket( Ticket *ticket )
155 {
156  delete ticket;
157 
158  delete mLock;
159  mLock = 0;
160 
161  addressBook()->emitAddressBookUnlocked();
162 }
163 
164 bool 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 
199 void ResourceFile::doClose()
200 {
201 }
202 
203 bool 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 
223 bool 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 
234 bool ResourceFile::asyncLoad()
235 {
236  mAsynchronous = true;
237 
238  load();
239 
240  QTimer::singleShot( 0, this, SLOT(emitLoadingFinished()) );
241 
242  return true;
243 }
244 
245 bool 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 
273 bool 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 
284 void ResourceFile::emitLoadingFinished()
285 {
286  emit loadingFinished( this );
287 }
288 
289 void ResourceFile::emitSavingFinished()
290 {
291  emit savingFinished( this );
292 }
293 
294 bool 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 
353 void 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 
392 void ResourceFile::saveToFile( QFile *file )
393 {
394  mFormat->saveAll( addressBook(), this, file );
395 
396  saveDistributionLists();
397 }
398 
399 void 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 
412 QString ResourceFile::fileName() const
413 {
414  return mFileName;
415 }
416 
417 void 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 
426 QString ResourceFile::format() const
427 {
428  return mFormatName;
429 }
430 
431 void 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 
466 void 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::FormatFactory
Class for loading format plugins.
Definition: formatfactory.h:94
KABC::DistributionList::entries
Entry::List entries() const
Return list of entries belonging to this distribution list.
Definition: distributionlist.cpp:192
KABC::FormatFactory::self
static FormatFactory * self()
Returns the global format factory.
Definition: formatfactory.cpp:68
KABC::AddressBook::emitAddressBookChanged
void emitAddressBookChanged()
Emits the signal addressBookChanged() using this as the parameter.
Definition: addressbook.h:597
KABC::Resource::clear
virtual void clear()
Removes all addressees and distribution lists from the resource.
Definition: resource.cpp:354
KABC::Lock
This class provides locking functionality for a file, directory or an arbitrary string-represented re...
Definition: lock.h:34
KABC::AddressBook::error
void error(const QString &msg)
Shows GUI independent error messages.
Definition: addressbook.cpp:901
KABC::ResourceFile::save
virtual bool save(Ticket *ticket)
Saves all addresses from address book to file.
Definition: resourcefile.cpp:245
KABC::DistributionList::insertEntry
void insertEntry(const Addressee &, const QString &email=QString())
Insert an entry into this distribution list.
Definition: distributionlist.cpp:141
KABC::StdAddressBook::fileName
static QString fileName()
Returns the default file name for vcard-based addressbook.
Definition: stdaddressbook.cpp:64
KABC::ResourceFile::requestSaveTicket
virtual Ticket * requestSaveTicket()
Requests a save ticket, that is used by save()
Definition: resourcefile.cpp:131
KABC::DistributionList
Distribution list of email addresses.
Definition: distributionlist.h:45
KABC::DistributionList::Entry::List
QList< Entry > List
A list of Entry instances.
Definition: distributionlist.h:61
KABC::AddressBook::findByUid
Addressee findByUid(const QString &uid) const
Searches an addressee with the specified unique identifier.
Definition: addressbook.cpp:613
KABC::Ticket
Helper class for handling coordinated save of address books.
Definition: resource.h:37
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::ResourceFile::fileName
QString fileName() const
Return name of file used for loading and saving the address book.
Definition: resourcefile.cpp:412
KABC::ResourceFile::ResourceFile
ResourceFile()
Default constructor.
Definition: resourcefile.cpp:55
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::DistributionList::name
QString name() const
Get name of this list.
Definition: distributionlist.cpp:136
KABC::Resource::savingFinished
void savingFinished(Resource *resource)
This signal is emitted when the resource has finished the saving of all addressees from the internal ...
KRES::Resource::identifier
QString identifier() const
KABC::ResourceFile::doOpen
virtual bool doOpen()
Tries to open the file and checks for the proper format.
Definition: resourcefile.cpp:164
KABC::ResourceFile::doClose
virtual void doClose()
Closes the file again.
Definition: resourcefile.cpp:199
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::DistributionList::identifier
QString identifier() const
Returns the distribution list's identifier.
Definition: distributionlist.cpp:126
KABC::Lock::lock
virtual bool lock()
Lock resource.
Definition: lock.cpp:108
KRES::Resource::readOnly
virtual bool readOnly() const
KABC::ResourceFile::format
QString format() const
Returns the format name.
Definition: resourcefile.cpp:426
KABC::Addressee::isEmpty
bool isEmpty() const
Return, if the address book entry is empty.
Definition: addressee.cpp:363
KABC::Addressee
address book entry
Definition: addressee.h:74
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::ResourceFile::asyncSave
virtual bool asyncSave(Ticket *ticket)
Saves all addressees asynchronously.
Definition: resourcefile.cpp:273
KABC::ResourceFile::asyncLoad
virtual bool asyncLoad()
Loads all addressees asyncronously.
Definition: resourcefile.cpp:234
KABC::AddressBook::emitAddressBookUnlocked
void emitAddressBookUnlocked()
Emits the signal addressBookUnlocked() using this as the parameter.
Definition: addressbook.h:593
KABC::ResourceFile::removeAddressee
virtual void removeAddressee(const Addressee &addr)
Remove a addressee from its source.
Definition: resourcefile.cpp:466
KABC::Resource
Definition: resource.h:64
KABC::ResourceFile::setFileName
void setFileName(const QString &)
Set name of file to be used for saving.
Definition: resourcefile.cpp:399
KABC::Lock::error
virtual QString error() const
Returns the lastest error message.
Definition: lock.cpp:179
KABC::Addressee::uid
QString uid() const
Return unique identifier.
Definition: addressee.cpp:377
KABC::ResourceFile::writeConfig
virtual void writeConfig(KConfigGroup &group)
Writes the config back.
Definition: resourcefile.cpp:118
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::mDistListMap
DistributionListMap mDistListMap
A mapping from unique identifiers to the respective distribution list.
Definition: resource.h:532
KABC::AddressBook::emitAddressBookLocked
void emitAddressBookLocked()
Emits the signal addressBookLocked() using this as the parameter.
Definition: addressbook.h:589
KABC::Resource::addressBook
AddressBook * addressBook()
Returns a pointer to the addressbook.
Definition: resource.cpp:274
KABC::Format::checkFormat
virtual bool checkFormat(QFile *file) const =0
Checks if given file contains the right format.
KABC::Resource::mAddrMap
Addressee::Map mAddrMap
A mapping from KABC UIDs to the respective addressee.
Definition: resource.h:527
KABC::ResourceFile::releaseSaveTicket
virtual void releaseSaveTicket(Ticket *ticket)
Releases the ticket previousely requested with requestSaveTicket().
Definition: resourcefile.cpp:154
KABC::Resource::writeConfig
virtual void writeConfig(KConfigGroup &group)
Writes the resource specific config to file.
Definition: resource.cpp:264
KABC::ResourceFile::setFormat
void setFormat(const QString &name)
Sets a new format by name.
Definition: resourcefile.cpp:417
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:01:05 by doxygen 1.8.7 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 API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



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