1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
|
The KDE Address Book Framework
===============================
The KDE address book framework tries to provide an easy to use and powerful
mechanism to handle contacts in all KDE applications.
If you want to make use of it, this small introduction to programming
with libkabc may be helpful.
General Concepts
=================
In libkabc the storage and management of contacts is devided in 2 layers.
******************
Management Layer *
******************
.-------------------.
| KABC::AddressBook |
.--------------------------------.
| KABC::Addressee | => Iterators
| KABC::Addressee |
| KABC::Addressee | => Search functions
| ... |
`--------------------------------'
|
- - - - - - - - - - - | - - - - - - - - - - - - -
|
*************** |
Storage Layer * |
*************** | .......................
| . . - Network
.---------------. | . .---------------. .
| ResourceFile |----+-----| ResourceLDAP | .
`---------------' | . `---------------' .
.---------------. | . .---------------. .
| ResourceDir |----+-----| ResourceNet | .
`---------------' . `---------------' .
. .
.......................
The Management Layer
---------------------
The Management Layer consists of the two classes KABC::AddressBook and
KABC::Addressee. KABC::AddressBook is a container for KABC::Addressee objects
and provides 2 kinds of access methods.
1) Iterators
With iterators you can iterate over each of the contacts of the
address book and perform an action on it
2) Search functions
With search functions you can search for contacts with special attributes
such as "all contacts with the name 'Harald'"
The class KABC::Addressee represents a single contact and tqcontains all data
a vCard could store (as specified in RFC 2426).
The Storage Layer
------------------
The Storage Layer consists of the class KABC::Resource and its derived classes.
These classes are used by KABC::AddressBook to load and store the contacts to
the single backends.
At the moment libkabc provides 4 types of resources:
1) ResourceFile
- stores all contacts in a single file
2) ResourceDir
- stores each contact in its own file with the unique identifier of the
contact as a filename, will all of the files together in one directory
3) ResourceLDAP
- stores all of the contacts on a LDAP server
4) ResourceNet
- stores all contacts in a single file, which can be accessable via HTTP,
FTP, Fish, WebDAV, POP3, IMAP or whatever the KIO frame work supports
In general the developer does not have to take how to save the single contacts.
He just has to plug one of the above mentioned resources into KABC::AddressBook
and perform a save action.
Examples
=========
Like a picture, C/C++ code is worth a 1000 words I'd like to give you a
lot of examples now, how to use libkabc for several tasks:
Using KABC::StdAddressBook and Iterators
-----------------------------------------
Normally you have to plugin the resources manually into the addressbook object
and call the load() function before you can access the contacts, but there is
a special class KABC::StdAddressBook, which loads all resources of the standard
address book of the user automatically. You can use it the following way:
#include <kabc/stdaddressbook.h>
1: KABC::AddressBook *ab = KABC::StdAddressBook::self();
2: KABC::AddressBook::Iterator it;
3: for ( it = ab->begin(); it != ab->end(); ++it ) {
4: KABC::Addressee addr = (*it);
5:
6: kdDebug() << "Name = " << addr.formattedName() << endl;
7: }
The above example prints out the names of all the contacts in the user's address
book. In line 1 you retrieve a pointer to the user's standard address book
(provided by KABC::StdAddressBook via a singleton design pattern).
In line 2 an iterator is defined, which is used in line 3 to iterate over the
whole address book. The assignment in line 4 is intended only to show more
clearly how iterators function.
You could also use (*it).formattedName() directly. In line 6 the formatted name
of the current contact is printed out to stderr.
As you can see that's all magic, and it's quite easy ;)
Using KABC::AddressBook manually
---------------------------------
In some cases you don't want to load the user's standard address book, but,
for example, just a single vCard. For this purpose you have to use the
class KABC::AddressBook and handle the resource stuff manually.
The following code will create a file resource and save a contact into it:
#include <kabc/addressbook.h>
#include <kabc/resourcefile.h>
1: KABC::AddressBook ab;
2:
3: // create a file resource
4: KABC::Resource *res = new KABC::ResourceFile( "/home/user/myvcard.vcf", "vcard" );
5:
6: if ( !ab.addResource( res ) ) {
7: kdDebug() << "Unable to open resource" << endl;
8: return 1;
9: }
10:
11: if ( !ab.load() ) {
12: kdDebug() << "Unable to load address book!" << endl;
13: return 2;
14: }
15:
16: KABC::Addressee addr;
17: addr.setNameFromString( "Otto Harald Meyer" );
18: addr.setBirthday( QDate( 1982, 07, 19 ) );
19: addr.setNickName( "otto" );
20: addr.setMailer( "kmail" );
21:
22: // TZ
23: KABC::TimeZone tz( 60 ); // takes time shift in minutes as argument
24: addr.setTimeZone( tz );
25:
26: // GEO
27: KABC::Geo geo( 52.5, 13.36 ); // takes latitude and longitude as argument
28: addr.setGeo( geo );
29:
30: addr.setTitle( "dude, the" );
31: addr.setRole( "developer" );
32: addr.setOrganization( "KDE e.V." );
33: addr.setNote( "Yet another senseless note..." );
34: addr.setUrl( KURL( "http://kaddressbook.org" ) );
35:
36: // CLASS
37: KABC::Secrecy secrecy( KABC::Secrecy::Confidential );
38: addr.setSecrecy( secrecy );
39:
40: // PHOTO or LOGO
41: KABC::Picture photo;
42: QImage img;
43: if ( img.load( "face.png", "PNG" ) ) {
44: photo.setData( img );
45: photo.setType( "image/png" );
46: addr.setPhoto( photo );
47: }
48:
49: addr.insertEmail( "otto@kde.se", true ); // preferred email
50: addr.insertEmail( "otti@yahoo.com", false );
51:
52: // TEL
53: KABC::PhoneNumber phoneHome( "0351 5466738", KABC::PhoneNumber::Home );
54: KABC::PhoneNumber phoneWork( "0351 2335411", KABC::PhoneNumber::Work );
55: addr.insertPhoneNumber( phoneHome );
56: addr.insertPhoneNumber( phoneWork );
57:
58: // ADR
59: KABC::Address homeAddr( KABC::Address::Home );
60: homeAddr.setStreet( "Milliwaystreet 42" );
61: homeAddr.setLocality( "London" );
62: homeAddr.setRegion( "Saxony" );
63: homeAddr.setPostalCode( "43435" );
64: homeAddr.setCountry( "Germany" );
65: addr.insertAddress( homeAddr );
66:
67: addr.insertCategory( "LUG-Dresden-Members" );
68:
69: addr.insertCustom( "KADDRESSBOOK", "X-Anniversary", "21.04.2009" );
70:
71: ab.insertAddressee( addr ); // will be assigned to the standard resource
72: // automatically
73:
74: KABC::Ticket *ticket = ab.requestSaveTicket( res );
75: if ( !ticket ) {
76: kdError() << "Resource is locked by other application!" << endl;
77: } else {
78: if ( !ab.save( ticket ) ) {
79: kdError() << "Saving failed!" << endl;
80: ab.releaseSaveTicket( ticket );
81: }
82:
83: }
84:
85: return 0;
In line 1 the KABC::AddressBook is created. In line 4 you creat the
KABC::ResourceFile (which will handle the loading/saving).
The resource takes 2 arguments, the first is the file name and the
second one the file format. At the moment libkabc supports two file formats:
1) vCard, as specified in RFC 2426
2) Binary, which increases performance during loading and saving
In line 6 we try to plug the resource into the addressbook. The addressbook
class tries to open the resource immediately and returns whether opening was
successful. We add here only one resource, but you can add as many resources
as you want.
In line 11 we try to load all contacts from the backends into the address book.
As before, it returns whether opening was successful.
In line 16 a KABC::Addressee is created, which we will fill now with data,
before inserting it into the KABC::AddressBook.
The setNameFromString() function in the following line takes a string as
argument and tries to parse it into the single name components such as: given
name, family name, additional names, honoric prefix and honoric suffix.
You can set these values manually as well by calling
addr.setGivenName( "Otto" );
and
addr.setFamilyName( "Meyer" );
etc. etc.
In line 23 we use the class KABC::TimeZone to store the timezone. This class
takes the time shift in minutes.
In line 27 the KABC::Geo class is used for storing the geographical
information. The arguments are the latitude and longitude as float values.
KABC::Secrecy in line 37 represents the CLASS entity of a vCard and can take
KABC::Secrecy::Public, KABC::Secrecy::Private or KABC::Secrecy::Confidential
as argument.
In line 41 we make use of KABC::Picture class to store the photo of the
contact. This class can contain either an URL or the raw image data in form
of a QImage, in this example we use the latter.
In line 43 we try to load the image "face.png" from the local directory and
assign this QImage to the KABC::Picture class via the setData() function.
Additionally we set the type of the picture to "image/png".
From 49 - 50 we insert 2 email addresses with the first one as preferred
(second argument is true).
In 53 and the following 3 lines we add two telephone numbers. For this purpose
libkabc provides the KABC::PhoneNumber class, which takes the phone number in
string representation as first argument and the type as second. The types can
be combined, so 'KABC::PhoneNumber::Home | KABC::PhoneNumber::Fax' would be
the Home Fax.
In line 59 we create a KABC::Address object and set the single parts in the
following lines.
In line 67 we assign the contact to a special category.
A contact can also contain custom entries, which are not specified in the API,
so you can add custom values with insertCustom() as shown in line 69.
The first argument of this function should be the name of the application, so
2 applications which use the same custom entry accidentally, do not overwrite
the data for each other. The second argument tqcontains the name of the
custom entry and the third argument the value in string representation.
In line 71 we finally insert the KABC::Addressee object into the
KABC::AddressBook. Since we have only one resource loaded, the contact is
automatically assigned to this resource. If you have several writeable
resources loaded, you should ask the user which resource the contact shall
belong to and assign the selected resource to the contact with
KABC::Addressee.setResource( KABC::Resource *resource );
before inserting it into the address book.
To prevent multiple access to one resource and possible resulting data loss
we have to lock the resource before saving our changes.
For this purpose KABC::AddressBook provides the function
requestSaveTicket( KABC::Resource* )
which takes a pointer to the resource which shall be saved as argument and
returns a so called 'Save Ticket' if locking succeeded or a null pointer
if the resource is already locked by another application.
So when we retrieved a valid ticket in line 74, we try to save our changes in
line 78.
The KABC::AddressBook::save() function takes the save ticket as argument and
returns whether saving succeeded. It also releases the save ticket when successful.
Important!
If the save() call fails, you have to release the save ticket manually, as is
done in line 80, otherwise possible locks, created by the resources, won't be
removed.
You can see also, that manual use is quite easy for the KABC::AddressBook class
and for the ResourceFile. For more information about the API of KABC::Addressee
please take a look at the official API documentation or the header files.
Distribution Lists
-------------------
libkabc provides so called distribution lists to group contacts. These lists
just store the uid of contacts, so they can be used for every kind of contact
grouping. There are 2 classes which handle the whole distribution list tasks,
KABC::DistributionListManager and KABC::DistributionList. The first one keeps
track of all available distribution lists and the latter one is the
representation of one list.
#include <kabc/distributionlist.h>
#include <kabc/stdaddressbook.h>
1: KABC::DistributionListManager manager( KABC::StdAddressBook::self() );
2:
3: // load the lists
4: manager.load();
5:
6: QStringList listNames = manager.listNames();
7: QStringList::Iterator it;
8: for ( it = listNames.begin(); it != listNames.end(); ++it ) {
9: KABC::DistributionList *list = manager.list( *it );
10: kdDebug() << list->name() << endl;
11:
12: QStringList emails = list->emails();
13: QStringList::Iterator eit;
14: for ( eit = emails.begin(); eit != emails.end(); ++eit )
15: kdDebug() << QString( "\t%1" ).arg( (*eit).latin1() ) << endl;
16: }
In the first line a KABC::DistributionListManager is created. The manager takes
a pointer to a KABC::AddressBook, because he has to resolve the stored uids to
currently available email addresses.
In line 4 the manager loads all distribution lists from the central config file
$HOME/.kde/share/apps/kabc/distlists.
The next line queries the names of all available distribution lists, which are
used in line 9 to retrieve a pointer to the specific list.
Now that you have a KABC::DistributionList object, you can performe the
following actions on it:
- set / get the name
- insert an entry
- remove an entry
- get a list of all email addresses
- get a list of all entries (which includes the uids)
In line 12 we query all email addresses of every resource and print them out.
<kabc/distributionlist.h> tqcontains also the declaration for the class
KABC::DistributionListWatcher. This class exists only once per application and
its only job is to emit a signal as soon as the distribution list file has
changed. So to make your application aware of changes use the following code:
#include <kabc/distributionlist.h>
1: connect( KABC::DistributionListWatcher::self(), SIGNAL( changed() ),
2: this, SLOT( slotDistributionListChanged() ) );
You see, as usual, easy ;)
|