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 "stdaddressbook.h"
22#include "resource.h"
23
24#include "kresources/manager.h"
25
26#include <kdebug.h>
27#include <klocalizedstring.h>
28#include <kconfig.h>
29#include <kstandarddirs.h>
30#include <kconfiggroup.h>
31
32 #include <QCoreApplication>
33
34#include <stdlib.h>
35
36using namespace KABC;
37
38class StdAddressBook::Private
39{
40 public:
41 Private( StdAddressBook *parent )
42 : mParent( parent )
43 {
44 }
45
46 void init( bool asynchronous );
47 bool saveAll();
48
49 StdAddressBook *mParent;
50 static bool mAutomaticSave;
51};
52
53static StdAddressBook *s_gStdAddressBook = 0;
54bool StdAddressBook::Private::mAutomaticSave = true;
55
56static void deleteGlobalStdAddressBook()
57{
58 if ( s_gStdAddressBook ) {
59 delete s_gStdAddressBook;
60 s_gStdAddressBook = 0;
61 }
62}
63
64QString StdAddressBook::fileName()
65{
66 return KStandardDirs::locateLocal( "data", QLatin1String( "kabc/std.vcf" ) );
67}
68
69QString StdAddressBook::directoryName()
70{
71 return KStandardDirs::locateLocal( "data", QLatin1String( "kabc/stdvcf" ) );
72}
73
74StdAddressBook *StdAddressBook::self()
75{
76 kDebug();
77
78 // delegate to other self() method since the only difference
79 // was the constructor being used and their only difference is
80 // what they pass to Private::init()
81 return self( false );
82}
83
84StdAddressBook *StdAddressBook::self( bool asynchronous )
85{
86 kDebug() << "asynchronous=" << asynchronous;
87
88 if ( !s_gStdAddressBook ) {
89 s_gStdAddressBook = new StdAddressBook( asynchronous, false );
90
91 kDebug() << "calling init after instance creation";
92 s_gStdAddressBook->d->init( asynchronous );
93
94 // We don't use a global static here for this reason:
95 //
96 // There are problems with the destruction order: The destructor of
97 // StdAddressBook calls save(), which for LDAP address books, needs KIO
98 // (more specific: KProtocolInfo) to be still alive. However, with a global
99 // static, KProtocolInfo is already deleted, and the app will crash.
100 //
101 // qAddPostRoutine deletes the objects when the QApplication is destroyed,
102 // which is earlier than the global statics, so this will work.
103 qAddPostRoutine( deleteGlobalStdAddressBook );
104 }
105
106 return s_gStdAddressBook;
107}
108
109StdAddressBook::StdAddressBook()
110 : AddressBook( QString() ), d( new Private( this ) )
111{
112 kDebug();
113
114 d->init( false );
115}
116
117StdAddressBook::StdAddressBook( bool asynchronous )
118 : AddressBook( QString() ), d( new Private( this ) )
119{
120 kDebug();
121
122 d->init( asynchronous );
123}
124
125StdAddressBook::StdAddressBook( bool asynchronous, bool doInit )
126 : AddressBook( QString() ), d( new Private( this ) )
127{
128 kDebug();
129
130 if ( doInit ) {
131 d->init( asynchronous );
132 }
133}
134
135StdAddressBook::~StdAddressBook()
136{
137 if ( Private::mAutomaticSave ) {
138 d->saveAll();
139 }
140
141 delete d;
142}
143
144void StdAddressBook::Private::init( bool asynchronous )
145{
146 KRES::Manager<Resource> *manager = mParent->resourceManager();
147
148 KRES::Manager<Resource>::ActiveIterator it;
149 for ( it = manager->activeBegin(); it != manager->activeEnd(); ++it ) {
150 ( *it )->setAddressBook( mParent );
151 if ( !( *it )->open() ) {
152 mParent->error( i18n( "Unable to open resource '%1'.", ( *it )->resourceName() ) );
153 continue;
154 }
155 mParent->connect( *it, SIGNAL(loadingFinished(Resource*)),
156 mParent, SLOT(resourceLoadingFinished(Resource*)) );
157 mParent->connect( *it, SIGNAL(savingFinished(Resource*)),
158 mParent, SLOT(resourceSavingFinished(Resource*)) );
159
160 mParent->connect( *it, SIGNAL(loadingError(Resource*,QString)),
161 mParent, SLOT(resourceLoadingError(Resource*,QString)) );
162 mParent->connect( *it, SIGNAL(savingError(Resource*,QString)),
163 mParent, SLOT(resourceSavingError(Resource*,QString)) );
164 }
165
166 Resource *res = mParent->standardResource();
167 if ( !res ) {
168 res = manager->createResource( QLatin1String( "file" ) );
169 if ( res ) {
170 res->setResourceName( i18n( "Default Address Book" ) );
171 mParent->addResource( res );
172 } else {
173 kDebug() << "No resource available!!!";
174 }
175 }
176
177 mParent->setStandardResource( res );
178 manager->writeConfig();
179
180 if ( asynchronous ) {
181 mParent->asyncLoad();
182 } else {
183 mParent->load();
184 }
185}
186
187bool StdAddressBook::Private::saveAll()
188{
189 kDebug();
190 bool ok = true;
191
192 KRES::Manager<Resource>::ActiveIterator it;
193 KRES::Manager<Resource> *manager = mParent->resourceManager();
194 for ( it = manager->activeBegin(); it != manager->activeEnd(); ++it ) {
195 if ( !( *it )->readOnly() && ( *it )->isOpen() ) {
196 Ticket *ticket = mParent->requestSaveTicket( *it );
197 if ( !ticket ) {
198 mParent->error( i18n( "Unable to save to resource '%1'. It is locked.",
199 ( *it )->resourceName() ) );
200 return false;
201 }
202
203 if ( !mParent->AddressBook::save( ticket ) ) {
204 ok = false;
205 mParent->releaseSaveTicket( ticket );
206 }
207 }
208 }
209
210 return ok;
211}
212
213bool StdAddressBook::save()
214{
215 kDebug();
216
217 if ( s_gStdAddressBook ) {
218 return s_gStdAddressBook->d->saveAll();
219 } else {
220 return true;
221 }
222}
223
224void StdAddressBook::close()
225{
226 delete s_gStdAddressBook;
227 s_gStdAddressBook = 0;
228}
229
230void StdAddressBook::setAutomaticSave( bool enable )
231{
232 Private::mAutomaticSave = enable;
233}
234
235bool StdAddressBook::automaticSave()
236{
237 return Private::mAutomaticSave;
238}
239
240Addressee StdAddressBook::whoAmI() const
241{
242 KConfig _config( QLatin1String( "kabcrc" ) );
243 KConfigGroup config(&_config, "General" );
244
245 return findByUid( config.readEntry( "WhoAmI" ) );
246}
247
248void StdAddressBook::setWhoAmI( const Addressee &addr )
249{
250 KConfig _config( QLatin1String( "kabcrc" ) );
251 KConfigGroup config(&_config, "General" );
252
253 config.writeEntry( "WhoAmI", addr.uid() );
254}
255