1/*
2 This file is part of libkabc.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "addressbook.h"
22#include "distributionlist.h"
23#include "errorhandler.h"
24#include "resource.h"
25
26#include <kdebug.h>
27#include <kglobal.h>
28#include <kcomponentdata.h>
29#include <klocalizedstring.h>
30#include <kstandarddirs.h>
31
32
33using namespace KABC;
34
35class AddressBook::Private
36{
37 public:
38 Field::List mAllFields;
39 ErrorHandler *mErrorHandler;
40 KConfig *mConfig;
41 KRES::Manager<Resource> *mManager;
42 QList<Resource*> mPendingLoadResources;
43 QList<Resource*> mPendingSaveResources;
44 Iterator end;
45 ConstIterator constEnd;
46};
47
48struct AddressBook::Iterator::IteratorData
49{
50 Resource::Iterator mIt;
51 QList<Resource*> mResources;
52 int mCurrRes;
53};
54
55struct AddressBook::ConstIterator::ConstIteratorData
56{
57 Resource::ConstIterator mIt;
58 QList<Resource*> mResources;
59 int mCurrRes;
60};
61
62AddressBook::Iterator::Iterator()
63 : d( new IteratorData )
64{
65}
66
67AddressBook::Iterator::Iterator( const AddressBook::Iterator &i )
68 : d( new IteratorData )
69{
70 d->mIt = i.d->mIt;
71 d->mResources = i.d->mResources;
72 d->mCurrRes = i.d->mCurrRes;
73}
74
75AddressBook::Iterator &AddressBook::Iterator::operator=
76 ( const AddressBook::Iterator &i )
77{
78 if ( this == &i ) {
79 return *this; // guard against self assignment
80 }
81
82 d->mIt = i.d->mIt;
83 d->mResources = i.d->mResources;
84 d->mCurrRes = i.d->mCurrRes;
85
86 return *this;
87}
88
89AddressBook::Iterator::~Iterator()
90{
91 delete d;
92}
93
94const Addressee &AddressBook::Iterator::operator*() const
95{
96 return *( d->mIt );
97}
98
99Addressee &AddressBook::Iterator::operator*()
100{
101 return *( d->mIt );
102}
103
104Addressee *AddressBook::Iterator::operator->()
105{
106 return &( *( d->mIt ) );
107}
108
109AddressBook::Iterator &AddressBook::Iterator::operator++()
110{
111 do {
112 bool jumped = false;
113 while ( d->mIt == ( d->mResources[ d->mCurrRes ] )->end() ) {
114 // at end of addressee list of resource
115 if ( d->mCurrRes == d->mResources.count() - 1 ) {
116 return *this;
117 }
118
119 d->mCurrRes++; // jump to next resource
120
121 jumped = true;
122 d->mIt = ( d->mResources[ d->mCurrRes ] )->begin();
123 }
124
125 if ( !jumped ) {
126 ( d->mIt )++;
127 }
128
129 } while ( d->mIt == ( d->mResources[ d->mCurrRes ] )->end() );
130
131 return *this;
132}
133
134AddressBook::Iterator &AddressBook::Iterator::operator++( int )
135{
136 do {
137 bool jumped = false;
138 while ( d->mIt == ( d->mResources[ d->mCurrRes ] )->end() ) {
139 // at end of addressee list of resource
140 if ( d->mCurrRes == d->mResources.count() - 1 ) {
141 return *this;
142 }
143
144 d->mCurrRes++; // jump to next resource
145
146 jumped = true;
147 d->mIt = ( d->mResources[ d->mCurrRes ] )->begin();
148 }
149
150 if ( !jumped ) {
151 ( d->mIt )++;
152 }
153
154 } while ( d->mIt == ( d->mResources[ d->mCurrRes ] )->end() );
155
156 return *this;
157}
158
159AddressBook::Iterator &AddressBook::Iterator::operator--()
160{
161 ( d->mIt )--;
162
163 return *this;
164}
165
166AddressBook::Iterator &AddressBook::Iterator::operator--( int )
167{
168 ( d->mIt )--;
169
170 return *this;
171}
172
173bool AddressBook::Iterator::operator==( const Iterator &it ) const
174{
175 return d->mIt == it.d->mIt;
176}
177
178bool AddressBook::Iterator::operator!=( const Iterator &it ) const
179{
180 return d->mIt != it.d->mIt;
181}
182
183AddressBook::ConstIterator::ConstIterator()
184 : d( new ConstIteratorData )
185{
186}
187
188AddressBook::ConstIterator::ConstIterator( const AddressBook::ConstIterator &i )
189 : d( new ConstIteratorData )
190{
191 d->mIt = i.d->mIt;
192 d->mResources = i.d->mResources;
193 d->mCurrRes = i.d->mCurrRes;
194}
195
196#ifndef QT_STRICT_ITERATORS
197AddressBook::ConstIterator::ConstIterator( const AddressBook::Iterator &i )
198 :d( new ConstIteratorData )
199{
200 d->mIt = i.d->mIt;
201 d->mResources = i.d->mResources;
202 d->mCurrRes = i.d->mCurrRes;
203}
204#endif
205
206AddressBook::ConstIterator &AddressBook::ConstIterator::operator=
207 ( const AddressBook::ConstIterator &i )
208{
209 if ( this == &i ) {
210 return *this; // guard for self assignment
211 }
212
213 d->mIt = i.d->mIt;
214 d->mResources = i.d->mResources;
215 d->mCurrRes = i.d->mCurrRes;
216
217 return *this;
218}
219
220AddressBook::ConstIterator::~ConstIterator()
221{
222 delete d;
223}
224
225const Addressee &AddressBook::ConstIterator::operator*() const
226{
227 return *( d->mIt );
228}
229
230const Addressee *AddressBook::ConstIterator::operator->() const
231{
232 return &( *( d->mIt ) );
233}
234
235AddressBook::ConstIterator &AddressBook::ConstIterator::operator++()
236{
237 do {
238 bool jumped = false;
239 while ( d->mIt == ( d->mResources[ d->mCurrRes ] )->constEnd() ) {
240 // at end of addressee list of resource
241 if ( d->mCurrRes == d->mResources.count() - 1 ) {
242 return *this;
243 }
244
245 d->mCurrRes++; // jump to next resource
246
247 jumped = true;
248 d->mIt = ( d->mResources[ d->mCurrRes ] )->constBegin();
249 }
250
251 if ( !jumped ) {
252 ( d->mIt )++;
253 }
254
255 } while ( d->mIt == ( d->mResources[ d->mCurrRes ] )->constEnd() );
256
257 return *this;
258}
259
260AddressBook::ConstIterator &AddressBook::ConstIterator::operator++(int)
261{
262 do {
263 bool jumped = false;
264 while ( d->mIt == ( d->mResources[ d->mCurrRes ] )->constEnd() ) {
265 // at end of addressee list of resource
266 if ( d->mCurrRes == d->mResources.count() - 1 ) {
267 return *this;
268 }
269
270 d->mCurrRes++; // jump to next resource
271
272 jumped = true;
273 d->mIt = ( d->mResources[ d->mCurrRes ] )->constBegin();
274 }
275
276 if ( !jumped ) {
277 ( d->mIt )++;
278 }
279
280 } while ( d->mIt == ( d->mResources[ d->mCurrRes ] )->constEnd() );
281
282 return *this;
283}
284
285AddressBook::ConstIterator &AddressBook::ConstIterator::operator--()
286{
287 ( d->mIt )--;
288 return *this;
289}
290
291AddressBook::ConstIterator &AddressBook::ConstIterator::operator--(int)
292{
293 ( d->mIt )--;
294 return *this;
295}
296
297bool AddressBook::ConstIterator::operator==( const ConstIterator &it ) const
298{
299 return d->mIt == it.d->mIt;
300}
301
302bool AddressBook::ConstIterator::operator!=( const ConstIterator &it ) const
303{
304 return d->mIt != it.d->mIt;
305}
306
307AddressBook::AddressBook()
308 : d( new Private )
309{
310 d->mErrorHandler = 0;
311 d->mConfig = 0;
312 d->mManager = new KRES::Manager<Resource>( QLatin1String( "contact" ) );
313 d->end.d->mResources = QList<Resource*>();
314 d->end.d->mCurrRes = -1;
315 d->constEnd.d->mResources = QList<Resource*>();
316 d->constEnd.d->mCurrRes = -1;
317}
318
319AddressBook::AddressBook( const QString &config )
320 : d( new Private )
321{
322 d->mErrorHandler = 0;
323 if ( config.isEmpty() ) {
324 d->mConfig = 0;
325 } else {
326 d->mConfig = new KConfig( config );
327 }
328 d->mManager = new KRES::Manager<Resource>( QLatin1String( "contact" ) );
329 d->mManager->readConfig( d->mConfig );
330 d->end.d->mResources = QList<Resource*>();
331 d->end.d->mCurrRes = -1;
332 d->constEnd.d->mResources = QList<Resource*>();
333 d->constEnd.d->mCurrRes = -1;
334}
335
336AddressBook::~AddressBook()
337{
338 delete d->mManager;
339 d->mManager = 0;
340 delete d->mConfig;
341 d->mConfig = 0;
342 delete d->mErrorHandler;
343 d->mErrorHandler = 0;
344 delete d;
345}
346
347bool AddressBook::load()
348{
349 kDebug();
350
351 clear();
352
353 KRES::Manager<Resource>::ActiveIterator it;
354 bool ok = true;
355 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
356 if ( !( *it )->load() ) {
357 error( i18n( "Unable to load resource '%1'", ( *it )->resourceName() ) );
358 ok = false;
359 }
360 }
361
362 return ok;
363}
364
365bool AddressBook::asyncLoad()
366{
367 kDebug();
368
369 clear();
370
371 KRES::Manager<Resource>::ActiveIterator it;
372 bool ok = true;
373 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
374 d->mPendingLoadResources.append( *it );
375 if ( !( *it )->asyncLoad() ) {
376 error( i18n( "Unable to load resource '%1'", ( *it )->resourceName() ) );
377 ok = false;
378 }
379 }
380
381 return ok;
382}
383
384bool AddressBook::save( Ticket *ticket )
385{
386 kDebug();
387
388 if ( ticket->resource() ) {
389 bool ok = ticket->resource()->save( ticket );
390 if ( ok ) {
391 ticket->resource()->releaseSaveTicket( ticket );
392 }
393 return ok;
394 }
395
396 return false;
397}
398
399bool AddressBook::asyncSave( Ticket *ticket )
400{
401 kDebug();
402
403 if ( ticket->resource() ) {
404 d->mPendingSaveResources.append( ticket->resource() );
405 bool ok = ticket->resource()->asyncSave( ticket );
406 if ( ok ) {
407 ticket->resource()->releaseSaveTicket( ticket );
408 }
409 return ok;
410 }
411
412 return false;
413}
414
415AddressBook::Iterator AddressBook::begin()
416{
417 QList<Resource*> list;
418 KRES::Manager<Resource>::ActiveIterator resIt;
419 for ( resIt = d->mManager->activeBegin();
420 resIt != d->mManager->activeEnd(); ++resIt ) {
421 list.append( *resIt );
422 }
423
424 if ( list.count() == 0 ) {
425 return end();
426 }
427
428 Iterator it = Iterator();
429 it.d->mResources = list;
430 it.d->mCurrRes = 0;
431 it.d->mIt = ( it.d->mResources[ it.d->mCurrRes ] )->begin();
432
433 while ( it.d->mIt == ( it.d->mResources[ it.d->mCurrRes ] )->end() ) {
434 if ( it.d->mCurrRes == it.d->mResources.count() - 1 ) {
435 return end();
436 }
437
438 it.d->mCurrRes++;
439
440 it.d->mIt = ( it.d->mResources[ it.d->mCurrRes ] )->begin();
441 }
442
443 return it;
444}
445
446AddressBook::ConstIterator AddressBook::begin() const
447{
448 QList<Resource*> list;
449 KRES::Manager<Resource>::ActiveIterator resIt;
450 for ( resIt = d->mManager->activeBegin();
451 resIt != d->mManager->activeEnd(); ++resIt ) {
452 list.append( *resIt );
453 }
454
455 if ( list.count() == 0 ) {
456 return end();
457 }
458
459 ConstIterator it = ConstIterator();
460 it.d->mResources = list;
461 it.d->mCurrRes = 0;
462 it.d->mIt = ( it.d->mResources[ it.d->mCurrRes ] )->constBegin();
463
464 while ( it.d->mIt == ( it.d->mResources[ it.d->mCurrRes ] )->constEnd() ) {
465 if ( it.d->mCurrRes == it.d->mResources.count() - 1 ) {
466 return end();
467 }
468
469 it.d->mCurrRes++;
470
471 it.d->mIt = ( it.d->mResources[ it.d->mCurrRes ] )->constBegin();
472 }
473
474 return it;
475}
476
477AddressBook::Iterator AddressBook::end()
478{
479 KRES::Manager<Resource>::ActiveIterator resIt = d->mManager->activeEnd();
480
481 if ( resIt == d->mManager->activeBegin() || ! *( --resIt ) ) {
482 // no resource available
483 d->end.d->mIt = Resource::Iterator();
484 } else {
485 d->end.d->mIt = ( *resIt )->end();
486 }
487
488 return d->end;
489}
490
491AddressBook::ConstIterator AddressBook::end() const
492{
493 KRES::Manager<Resource>::ActiveIterator resIt = d->mManager->activeEnd();
494
495 if ( resIt == d->mManager->activeBegin() || ! *( --resIt ) ) {
496 // no resource available
497 d->constEnd.d->mIt = Resource::ConstIterator();
498 } else {
499 d->constEnd.d->mIt = ( *resIt )->constEnd();
500 }
501
502 return d->constEnd;
503}
504
505void AddressBook::clear()
506{
507 KRES::Manager<Resource>::ActiveIterator it;
508 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
509 ( *it )->clear();
510 }
511}
512
513Ticket *AddressBook::requestSaveTicket( Resource *resource )
514{
515 kDebug();
516
517 if ( !resource ) {
518 resource = standardResource();
519 }
520
521 KRES::Manager<Resource>::ActiveIterator it;
522 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
523 if ( ( *it ) == resource ) {
524 if ( ( *it )->readOnly() || !( *it )->isOpen() ) {
525 return 0;
526 } else {
527 return ( *it )->requestSaveTicket();
528 }
529 }
530 }
531
532 return 0;
533}
534
535void AddressBook::releaseSaveTicket( Ticket *ticket )
536{
537 if ( !ticket ) {
538 return;
539 }
540
541 if ( ticket->resource() ) {
542 ticket->resource()->releaseSaveTicket( ticket );
543 }
544}
545
546void AddressBook::insertAddressee( const Addressee &a )
547{
548 Resource *resource = a.resource();
549 if ( resource == 0 ) {
550 resource = standardResource();
551 }
552
553 Resource::Iterator it;
554 Addressee fAddr = resource->findByUid( a.uid() );
555
556 Addressee addr( a );
557 if ( !fAddr.isEmpty() ) {
558 if ( fAddr != a ) {
559 addr.setRevision( QDateTime::currentDateTime() );
560 } else {
561 if ( fAddr.resource() == 0 ) {
562 fAddr.setResource( resource );
563 //NOTE: Should we have setChanged( true ) here?
564 resource->insertAddressee( fAddr );
565 }
566 return;
567 }
568 }
569
570 addr.setResource( resource );
571 addr.setChanged( true );
572 resource->insertAddressee( addr );
573}
574
575void AddressBook::removeAddressee( const Addressee &a )
576{
577 if ( a.resource() ) {
578 a.resource()->removeAddressee( a );
579 }
580}
581
582void AddressBook::removeAddressee( const Iterator &it )
583{
584 if ( ( *it ).resource() ) {
585 ( *it ).resource()->removeAddressee( *it );
586 }
587}
588
589AddressBook::Iterator AddressBook::find( const Addressee &a )
590{
591 Iterator it;
592 for ( it = begin(); it != end(); ++it ) {
593 if ( a.uid() == ( *it ).uid() ) {
594 return it;
595 }
596 }
597
598 return end();
599}
600
601AddressBook::ConstIterator AddressBook::find( const Addressee &a ) const
602{
603 ConstIterator it;
604 for ( it = begin(); it != end(); ++it ) {
605 if ( a.uid() == ( *it ).uid() ) {
606 return it;
607 }
608 }
609
610 return end();
611}
612
613Addressee AddressBook::findByUid( const QString &uid ) const
614{
615 KRES::Manager<Resource>::ActiveIterator it;
616 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
617 Addressee addr = ( *it )->findByUid( uid );
618 if ( !addr.isEmpty() ) {
619 return addr;
620 }
621 }
622
623 return Addressee();
624}
625
626Addressee::List AddressBook::allAddressees() const
627{
628 Addressee::List list;
629
630 ConstIterator it;
631 for ( it = begin(); it != end(); ++it ) {
632 list.append( *it );
633 }
634
635 return list;
636}
637
638Addressee::List AddressBook::findByName( const QString &name ) const
639{
640 Addressee::List results;
641
642 KRES::Manager<Resource>::ActiveIterator it;
643 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
644 results += ( *it )->findByName( name );
645 }
646
647 return results;
648}
649
650Addressee::List AddressBook::findByEmail( const QString &email ) const
651{
652 Addressee::List results;
653
654 KRES::Manager<Resource>::ActiveIterator it;
655 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
656 results += ( *it )->findByEmail( email );
657 }
658
659 return results;
660}
661
662Addressee::List AddressBook::findByCategory( const QString &category ) const
663{
664 Addressee::List results;
665
666 KRES::Manager<Resource>::ActiveIterator it;
667 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
668 results += ( *it )->findByCategory( category );
669 }
670
671 return results;
672}
673
674DistributionList *AddressBook::createDistributionList( const QString &name, Resource *resource )
675{
676 if ( resource == 0 ) {
677 resource = standardResource();
678 }
679
680 return new DistributionList( resource, name );
681}
682
683void AddressBook::removeDistributionList( DistributionList *list )
684{
685 if ( !list || !list->resource() ) {
686 return;
687 }
688
689 list->resource()->removeDistributionList( list );
690}
691
692DistributionList *AddressBook::findDistributionListByIdentifier( const QString &identifier )
693{
694 KRES::Manager<Resource>::ActiveIterator it;
695 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
696 DistributionList *list = ( *it )->findDistributionListByIdentifier( identifier );
697 if ( list ) {
698 return list;
699 }
700 }
701
702 return 0;
703}
704
705DistributionList *AddressBook::findDistributionListByName( const QString &name,
706 Qt::CaseSensitivity caseSensitivity )
707{
708 KRES::Manager<Resource>::ActiveIterator it;
709 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
710 DistributionList *list = ( *it )->findDistributionListByName( name, caseSensitivity );
711 if ( list ) {
712 return list;
713 }
714 }
715
716 return 0;
717}
718
719QList<DistributionList*> AddressBook::allDistributionLists()
720{
721 QList<DistributionList*> results;
722
723 KRES::Manager<Resource>::ActiveIterator it;
724 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
725 results += ( *it )->allDistributionLists();
726 }
727
728 return results;
729}
730
731QStringList AddressBook::allDistributionListNames() const
732{
733 QStringList results;
734
735 KRES::Manager<Resource>::ActiveIterator it;
736 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
737 results += ( *it )->allDistributionListNames();
738 }
739
740 return results;
741}
742
743void AddressBook::dump() const
744{
745 kDebug() << "--- begin ---";
746
747 ConstIterator it;
748 for ( it = begin(); it != end(); ++it ) {
749 kDebug() << ( *it ).toString();
750 }
751
752 kDebug() << "--- end ---";
753}
754
755QString AddressBook::identifier() const
756{
757 QStringList identifier;
758
759 KRES::Manager<Resource>::ActiveIterator it;
760 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
761 if ( !( *it )->identifier().isEmpty() ) {
762 identifier.append( ( *it )->identifier() );
763 }
764 }
765
766 return identifier.join( QLatin1String( ":" ) );
767}
768
769Field::List AddressBook::fields( int category ) const
770{
771 if ( d->mAllFields.isEmpty() ) {
772 d->mAllFields = Field::allFields();
773 }
774
775 if ( category == Field::All ) {
776 return d->mAllFields;
777 }
778
779 Field::List result;
780 Field::List::ConstIterator it;
781 for ( it = d->mAllFields.constBegin(); it != d->mAllFields.constEnd(); ++it ) {
782 if ( ( *it )->category() & category ) {
783 result.append( *it );
784 }
785 }
786
787 return result;
788}
789
790bool AddressBook::addCustomField( const QString &label,
791 int category,
792 const QString &key,
793 const QString &app ) const
794{
795 if ( d->mAllFields.isEmpty() ) {
796 d->mAllFields = Field::allFields();
797 }
798
799 QString a = app.isNull() ? KGlobal::mainComponent().componentName() : app;
800 QString k = key.isNull() ? label : key;
801
802 Field *field = Field::createCustomField( label, category, k, a );
803
804 if ( !field ) {
805 return false;
806 }
807
808 d->mAllFields.append( field );
809
810 return true;
811}
812
813QDataStream &KABC::operator<<( QDataStream &s, const AddressBook &ab )
814{
815 if ( !ab.d ) {
816 return s;
817 }
818
819 return s;// << ab.d->mAddressees;
820}
821
822QDataStream &KABC::operator>>( QDataStream &s, AddressBook &ab )
823{
824 if ( !ab.d ) {
825 return s;
826 }
827
828 return s;// s >> ab.d->mAddressees;
829}
830
831bool AddressBook::addResource( Resource *resource )
832{
833 if ( !resource->open() ) {
834 kDebug() << "can't add resource";
835 return false;
836 }
837
838 d->mManager->add( resource );
839 resource->setAddressBook( this );
840
841 connect( resource, SIGNAL(loadingFinished(Resource*)),
842 this, SLOT(resourceLoadingFinished(Resource*)) );
843 connect( resource, SIGNAL(savingFinished(Resource*)),
844 this, SLOT(resourceSavingFinished(Resource*)) );
845
846 connect( resource, SIGNAL(loadingError(Resource*,QString)),
847 this, SLOT(resourceLoadingError(Resource*,QString)) );
848 connect( resource, SIGNAL(savingError(Resource*,QString)),
849 this, SLOT(resourceSavingError(Resource*,QString)) );
850
851 return true;
852}
853
854bool AddressBook::removeResource( Resource *resource )
855{
856 resource->close();
857
858 if ( resource == standardResource() ) {
859 d->mManager->setStandardResource( 0 );
860 }
861
862 resource->setAddressBook( 0 );
863
864 disconnect( resource, SIGNAL(loadingFinished(Resource*)),
865 this, SLOT(resourceLoadingFinished(Resource*)) );
866 disconnect( resource, SIGNAL(savingFinished(Resource*)),
867 this, SLOT(resourceSavingFinished(Resource*)) );
868
869 disconnect( resource, SIGNAL(loadingError(Resource*,QString)),
870 this, SLOT(resourceLoadingError(Resource*,QString)) );
871 disconnect( resource, SIGNAL(savingError(Resource*,QString)),
872 this, SLOT(resourceLoadingError(Resource*,QString)) );
873
874 d->mManager->remove( resource );
875
876 return true;
877}
878
879QList<Resource*> AddressBook::resources() const
880{
881 QList<Resource*> list;
882
883 KRES::Manager<Resource>::ActiveIterator it;
884 for ( it = d->mManager->activeBegin(); it != d->mManager->activeEnd(); ++it ) {
885 if ( d->mManager->standardResource() == ( *it ) ) {
886 list.prepend( *it );
887 } else {
888 list.append( *it );
889 }
890 }
891
892 return list;
893}
894
895void AddressBook::setErrorHandler( ErrorHandler *handler )
896{
897 delete d->mErrorHandler;
898 d->mErrorHandler = handler;
899}
900
901void AddressBook::error( const QString &msg )
902{
903 if ( !d->mErrorHandler ) {
904 // create default error handler
905 d->mErrorHandler = new ConsoleErrorHandler();
906 }
907
908 if ( d->mErrorHandler ) {
909 d->mErrorHandler->error( msg );
910 } else {
911 kError() << "no error handler defined";
912 }
913}
914
915void AddressBook::setStandardResource( Resource *resource )
916{
917 d->mManager->setStandardResource( resource );
918}
919
920Resource *AddressBook::standardResource()
921{
922 return d->mManager->standardResource();
923}
924
925KRES::Manager<Resource> *AddressBook::resourceManager()
926{
927 return d->mManager;
928}
929
930bool AddressBook::loadingHasFinished() const
931{
932 return d->mPendingLoadResources.isEmpty();
933}
934
935void AddressBook::resourceLoadingFinished( Resource *resource )
936{
937 d->mPendingLoadResources.removeAll( resource );
938 emit loadingFinished( resource );
939
940 if ( d->mPendingLoadResources.count() == 0 ) {
941 emit addressBookChanged( this );
942 }
943}
944
945void AddressBook::resourceSavingFinished( Resource *resource )
946{
947 d->mPendingSaveResources.removeAll( resource );
948
949 emit savingFinished( resource );
950}
951
952void AddressBook::resourceLoadingError( Resource *resource,
953 const QString &errMsg )
954{
955 error( errMsg );
956
957 d->mPendingLoadResources.removeAll( resource );
958 if ( d->mPendingLoadResources.count() == 0 ) {
959 emit addressBookChanged( this );
960 }
961}
962
963void AddressBook::resourceSavingError( Resource *resource,
964 const QString &errMsg )
965{
966 error( errMsg );
967
968 d->mPendingSaveResources.removeAll( resource );
969}
970