|
|
|
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 libtdeabc may be helpful.
|
|
|
|
|
|
|
|
|
|
|
|
General Concepts
|
|
|
|
=================
|
|
|
|
|
|
|
|
In libtdeabc the storage and management of contacts is devided in 2 layers.
|
|
|
|
|
|
|
|
******************
|
|
|
|
Management Layer *
|
|
|
|
******************
|
|
|
|
|
|
|
|
.-------------------.
|
|
|
|
| TDEABC::AddressBook |
|
|
|
|
.--------------------------------.
|
|
|
|
| TDEABC::Addressee | => Iterators
|
|
|
|
| TDEABC::Addressee |
|
|
|
|
| TDEABC::Addressee | => Search functions
|
|
|
|
| ... |
|
|
|
|
`--------------------------------'
|
|
|
|
|
|
|
|
|
- - - - - - - - - - - | - - - - - - - - - - - - -
|
|
|
|
|
|
|
|
|
*************** |
|
|
|
|
Storage Layer * |
|
|
|
|
*************** | .......................
|
|
|
|
| . . - Network
|
|
|
|
.---------------. | . .---------------. .
|
|
|
|
| ResourceFile |----+-----| ResourceLDAP | .
|
|
|
|
`---------------' | . `---------------' .
|
|
|
|
.---------------. | . .---------------. .
|
|
|
|
| ResourceDir |----+-----| ResourceNet | .
|
|
|
|
`---------------' . `---------------' .
|
|
|
|
. .
|
|
|
|
.......................
|
|
|
|
|
|
|
|
|
|
|
|
The Management Layer
|
|
|
|
---------------------
|
|
|
|
The Management Layer consists of the two classes TDEABC::AddressBook and
|
|
|
|
TDEABC::Addressee. TDEABC::AddressBook is a container for TDEABC::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 TDEABC::Addressee represents a single contact and contains all data
|
|
|
|
a vCard could store (as specified in RFC 2426).
|
|
|
|
|
|
|
|
The Storage Layer
|
|
|
|
------------------
|
|
|
|
The Storage Layer consists of the class TDEABC::Resource and its derived classes.
|
|
|
|
These classes are used by TDEABC::AddressBook to load and store the contacts to
|
|
|
|
the single backends.
|
|
|
|
At the moment libtdeabc 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 TDEIO 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 TDEABC::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 libtdeabc for several tasks:
|
|
|
|
|
|
|
|
|
|
|
|
Using TDEABC::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 TDEABC::StdAddressBook, which loads all resources of the standard
|
|
|
|
address book of the user automatically. You can use it the following way:
|
|
|
|
|
|
|
|
|
|
|
|
#include <tdeabc/stdaddressbook.h>
|
|
|
|
|
|
|
|
1: TDEABC::AddressBook *ab = TDEABC::StdAddressBook::self();
|
|
|
|
2: TDEABC::AddressBook::Iterator it;
|
|
|
|
3: for ( it = ab->begin(); it != ab->end(); ++it ) {
|
|
|
|
4: TDEABC::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 TDEABC::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 TDEABC::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 TDEABC::AddressBook and handle the resource stuff manually.
|
|
|
|
The following code will create a file resource and save a contact into it:
|
|
|
|
|
|
|
|
|
|
|
|
#include <tdeabc/addressbook.h>
|
|
|
|
#include <tdeabc/resourcefile.h>
|
|
|
|
|
|
|
|
1: TDEABC::AddressBook ab;
|
|
|
|
2:
|
|
|
|
3: // create a file resource
|
|
|
|
4: TDEABC::Resource *res = new TDEABC::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: TDEABC::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: TDEABC::TimeZone tz( 60 ); // takes time shift in minutes as argument
|
|
|
|
24: addr.setTimeZone( tz );
|
|
|
|
25:
|
|
|
|
26: // GEO
|
|
|
|
27: TDEABC::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: TDEABC::Secrecy secrecy( TDEABC::Secrecy::Confidential );
|
|
|
|
38: addr.setSecrecy( secrecy );
|
|
|
|
39:
|
|
|
|
40: // PHOTO or LOGO
|
|
|
|
41: TDEABC::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: TDEABC::PhoneNumber phoneHome( "0351 5466738", TDEABC::PhoneNumber::Home );
|
|
|
|
54: TDEABC::PhoneNumber phoneWork( "0351 2335411", TDEABC::PhoneNumber::Work );
|
|
|
|
55: addr.insertPhoneNumber( phoneHome );
|
|
|
|
56: addr.insertPhoneNumber( phoneWork );
|
|
|
|
57:
|
|
|
|
58: // ADR
|
|
|
|
59: TDEABC::Address homeAddr( TDEABC::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: TDEABC::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 TDEABC::AddressBook is created. In line 4 you creat the
|
|
|
|
TDEABC::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 libtdeabc 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 TDEABC::Addressee is created, which we will fill now with data,
|
|
|
|
before inserting it into the TDEABC::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 TDEABC::TimeZone to store the timezone. This class
|
|
|
|
takes the time shift in minutes.
|
|
|
|
|
|
|
|
In line 27 the TDEABC::Geo class is used for storing the geographical
|
|
|
|
information. The arguments are the latitude and longitude as float values.
|
|
|
|
|
|
|
|
TDEABC::Secrecy in line 37 represents the CLASS entity of a vCard and can take
|
|
|
|
TDEABC::Secrecy::Public, TDEABC::Secrecy::Private or TDEABC::Secrecy::Confidential
|
|
|
|
as argument.
|
|
|
|
|
|
|
|
In line 41 we make use of TDEABC::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 TDEABC::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
|
|
|
|
libtdeabc provides the TDEABC::PhoneNumber class, which takes the phone number in
|
|
|
|
string representation as first argument and the type as second. The types can
|
|
|
|
be combined, so 'TDEABC::PhoneNumber::Home | TDEABC::PhoneNumber::Fax' would be
|
|
|
|
the Home Fax.
|
|
|
|
|
|
|
|
In line 59 we create a TDEABC::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 contains the name of the
|
|
|
|
custom entry and the third argument the value in string representation.
|
|
|
|
|
|
|
|
In line 71 we finally insert the TDEABC::Addressee object into the
|
|
|
|
TDEABC::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
|
|
|
|
TDEABC::Addressee.setResource( TDEABC::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 TDEABC::AddressBook provides the function
|
|
|
|
requestSaveTicket( TDEABC::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 TDEABC::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 TDEABC::AddressBook class
|
|
|
|
and for the ResourceFile. For more information about the API of TDEABC::Addressee
|
|
|
|
please take a look at the official API documentation or the header files.
|
|
|
|
|
|
|
|
|
|
|
|
Distribution Lists
|
|
|
|
-------------------
|
|
|
|
libtdeabc 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,
|
|
|
|
TDEABC::DistributionListManager and TDEABC::DistributionList. The first one keeps
|
|
|
|
track of all available distribution lists and the latter one is the
|
|
|
|
representation of one list.
|
|
|
|
|
|
|
|
|
|
|
|
#include <tdeabc/distributionlist.h>
|
|
|
|
#include <tdeabc/stdaddressbook.h>
|
|
|
|
|
|
|
|
1: TDEABC::DistributionListManager manager( TDEABC::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: TDEABC::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 TDEABC::DistributionListManager is created. The manager takes
|
|
|
|
a pointer to a TDEABC::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/.trinity/share/apps/tdeabc/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 TDEABC::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.
|
|
|
|
|
|
|
|
<tdeabc/distributionlist.h> contains also the declaration for the class
|
|
|
|
TDEABC::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 <tdeabc/distributionlist.h>
|
|
|
|
|
|
|
|
1: connect( TDEABC::DistributionListWatcher::self(), SIGNAL( changed() ),
|
|
|
|
2: this, SLOT( slotDistributionListChanged() ) );
|
|
|
|
|
|
|
|
You see, as usual, easy ;)
|
|
|
|
|