2
/* Ekiga -- A VoIP and Video-Conferencing application
3
* Copyright (C) 2000-2006 Damien Sandras
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program 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
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20
* Ekiga is licensed under the GPL license and as a special exception,
21
* you have permission to link or otherwise combine this program with the
22
* programs OPAL, OpenH323 and PWLIB, and distribute the combination,
23
* without applying the requirements of the GNU GPL to the OPAL, OpenH323
24
* and PWLIB programs, as long as you do follow the requirements of the
25
* GNU GPL for all the rest of the software thus combined.
30
* gmcontacts-gmconf.cpp - description
31
* ---------------------------
32
* begin : Mon Apr 19 2004
33
* copyright : (C) 2004-2006 by Julien Puydt
34
* (C) 2004-2006 by Damien Sandras
35
* (C) 2006 by Kilian Krause
36
* description : Implementation of an addressbook using gmconf
41
#include "../../config.h"
44
#include "gmcontacts.h"
45
#ifndef _GM_CONTACTS_H_INSIDE__
46
#define _GM_CONTACTS_H_INSIDE__
47
#include "gmcontacts-local.h"
48
#include "gmcontacts-convert.h"
49
#undef _GM_CONTACTS_H_INSIDE__
55
* The following is the implementation of the local addressbooks, when
56
* gnomemeeting is compiled without evolution-data-server support: it uses
57
* the configuration system (gmconf) to store the data.
59
* Everything is stored under CONTACTS_KEY, in the following form:
60
* - an addressbook identifier is an integer starting at 1 ;
61
* (stored as a string) ;
62
* - the integer key CONTACTS_KEY "max_aid" stores the maximum addressbook
63
* identifier (to know when to stop when searching the list of addressbooks:
64
* there may be an empty slot in the middle after a removal, so looking for
65
* empty slot isn't a good idea) ;
66
* - the addressbook is stored in the CONTACTS_KEY (string of the aid)
68
* - the addressbook features are directly stored in the namespace: for example
69
* CONTACTS_KEY (string of the aid)"/name" stores the name of the
71
* - a contact identifier is an integer starting at 1 (and has a meaning in the
73
* - a contact is stored as a vcard in the addressbook namespace:
74
* CONTACTS_KEY (string of the aid) "/" (string of the uid) ;
75
* - the integer key CONTACTS_KEY (string of the aid)"/max_uid" stores the
76
* maximum contact identifier (for the same reasons as above).
78
* NB: starting the counts at 1 has the bonus that a 0 can mean "doesn't exist"
81
#define CONTACTS_KEY "/apps/" PACKAGE_NAME "/contacts/"
85
* Declaration of the helper functions
88
/* this function checks if str2 is a substring of str2
90
static gboolean str_contains (const gchar *str1, const gchar *str2);
92
/* this function retrieves the contact with the given "coordinates"
93
* from the configuration ; it wants and checks aid > 0 and uid > 0.
95
static GmContact *get_contact (gint aid,
99
/* this function stores the given contact in the configuration, at the
100
* given "coordinates" ; it wants and checks aid > 0, and contact != NULL
101
* with a valid (> 0) uid.
103
static gboolean store_contact (GmContact *contact,
107
/* this function retrieves the addressbook with the given identifier
108
* from the configuration ; it wants and checks aid > 0.
110
static GmAddressbook *get_addressbook (gint aid);
113
/* this function stores the addressbook in the configuration, at the
114
* given identifier ; it wants and checks addb != NULL with a valid aid.
116
static gboolean store_addressbook (GmAddressbook *addb);
119
/* this function returns the first available addressbook identifier
120
* (that can be max_aid+1 or the old identifier of a removed group)
122
static gint get_available_aid ();
125
/* this function returns the first available contact identifier
126
* available in the given group (again, that can be either max_uid+1 or
127
* the old identifier of a removed contact) [it wants and checks aid > 0]
129
static gint get_available_uid (gint aid);
133
* Implementation of the helper functions
138
gboolean str_contains (const gchar *str1, const gchar *str2)
140
return (g_strrstr (str1, str2) != NULL);
145
get_contact (gint aid,
150
GmContact *contact = NULL;
152
g_return_val_if_fail (aid > 0, NULL);
153
g_return_val_if_fail (uid > 0, NULL);
155
key = g_strdup_printf (CONTACTS_KEY "%d/%d", aid, uid);
156
vcard = gm_conf_get_string (key);
160
contact = vcard_to_gmcontact (vcard);
161
contact->uid = g_strdup_printf ("%d", uid);
169
store_contact (GmContact *contact,
177
g_return_val_if_fail (contact != NULL, FALSE);
178
g_return_val_if_fail (contact->uid != NULL, FALSE);
179
g_return_val_if_fail (aid > 0, FALSE);
181
uid = strtol (contact->uid, NULL, 10);
182
g_return_val_if_fail (uid > 0, FALSE);
184
vcard = gmcontact_to_vcard (contact);
185
key = g_strdup_printf (CONTACTS_KEY "%d/%d", aid, uid);
186
gm_conf_set_string (key, vcard);
190
key = g_strdup_printf (CONTACTS_KEY "%d/max_uid", aid);
191
max_uid = gm_conf_get_int (key);
193
gm_conf_set_int (key, uid);
200
static GmAddressbook *
201
get_addressbook (gint aid)
203
GmAddressbook *addb = NULL;
207
g_return_val_if_fail (aid > 0, NULL);
209
addb = gm_addressbook_new ();
211
addb->aid = g_strdup_printf ("%d", aid);
213
key = g_strdup_printf (CONTACTS_KEY "%d/name", aid);
214
str = gm_conf_get_string (key);
216
addb->name = g_strdup (str);
219
key = g_strdup_printf (CONTACTS_KEY "%d/url", aid);
220
str = gm_conf_get_string (key);
222
addb->url = g_strdup (str);
225
key = g_strdup_printf (CONTACTS_KEY "%d/call_attribute", aid);
226
str = gm_conf_get_string (key);
228
addb->call_attribute = g_strdup (str);
231
if (addb->name == NULL
233
&& addb->call_attribute == NULL) {
234
gm_addressbook_delete (addb);
243
store_addressbook (GmAddressbook *addb)
249
g_return_val_if_fail (addb != NULL, FALSE);
250
g_return_val_if_fail (addb->aid != NULL, FALSE);
252
aid = strtol (addb->aid, NULL, 10);
254
g_return_val_if_fail (aid > 0, FALSE);
256
key = g_strdup_printf (CONTACTS_KEY "%d/name", aid);
257
if (addb->name != NULL)
258
gm_conf_set_string (key, addb->name);
260
gm_conf_destroy (key);
263
key = g_strdup_printf (CONTACTS_KEY "%d/url", aid);
264
if (addb->url != NULL)
265
gm_conf_set_string (key, addb->url);
267
gm_conf_destroy (key);
270
key = g_strdup_printf (CONTACTS_KEY "%d/call_attribute", aid);
271
if (addb->call_attribute != NULL)
272
gm_conf_set_string (key, addb->call_attribute);
274
gm_conf_destroy (key);
277
max_aid = gm_conf_get_int (CONTACTS_KEY "max_aid");
279
gm_conf_set_int (CONTACTS_KEY "max_aid", aid);
290
GmAddressbook *addb = NULL;
292
max_aid = gm_conf_get_int (CONTACTS_KEY "max_aid");
294
for (aid = 1; aid < max_aid + 1; aid++) {
295
addb = get_addressbook (aid);
298
gm_addressbook_delete (addb);
306
get_available_uid (gint aid)
311
GmContact *contact = NULL;
313
g_return_val_if_fail (aid > 0, 1);
315
key = g_strdup_printf (CONTACTS_KEY "%d/max_uid", aid);
316
max_uid = gm_conf_get_int (key);
319
for (uid = 1; uid < max_uid + 1; uid++) {
320
contact = get_contact (aid, uid);
323
gmcontact_delete (contact);
331
* Implementation of the public api
338
GmContact *contact = NULL;
340
contact = g_new (GmContact, 1);
342
contact->fullname = NULL;
343
contact->categories = NULL;
345
contact->location = NULL;
346
contact->speeddial = NULL;
347
contact->comment = NULL;
348
contact->software = NULL;
349
contact->email = NULL;
350
contact->state = CONTACT_AVAILABLE;
351
contact->video_capable = FALSE;
359
gmcontact_copy (GmContact *orig)
361
GmContact *contact = NULL;
363
contact = g_new (GmContact, 1);
365
contact->fullname = g_strdup (orig->fullname);
366
contact->categories = g_strdup (orig->categories);
367
contact->url = g_strdup (orig->url);
368
contact->location = g_strdup (orig->location);
369
contact->speeddial = g_strdup (orig->speeddial);
370
contact->comment = g_strdup (orig->comment);
371
contact->software = g_strdup (orig->software);
372
contact->email = g_strdup (orig->email);
373
contact->state = orig->state;
374
contact->video_capable = orig->video_capable;
375
contact->uid = g_strdup (orig->uid);
382
gmcontact_delete (GmContact *contact)
387
g_free (contact->fullname);
388
g_free (contact->url);
389
g_free (contact->speeddial);
390
g_free (contact->categories);
391
g_free (contact->comment);
392
g_free (contact->software);
393
g_free (contact->email);
394
g_free (contact->uid);
401
gm_addressbook_new ()
403
GmAddressbook *addressbook = NULL;
405
addressbook = g_new (GmAddressbook, 1);
407
addressbook->name = NULL;
408
addressbook->url = NULL;
409
addressbook->aid = g_strdup_printf ("%010d", g_random_int());
410
addressbook->call_attribute = NULL;
417
gm_addressbook_delete (GmAddressbook *addressbook)
422
g_free (addressbook->url);
423
g_free (addressbook->aid);
424
g_free (addressbook->name);
425
g_free (addressbook->call_attribute);
427
g_free (addressbook);
432
gnomemeeting_get_local_addressbooks ()
436
GmAddressbook *addb = NULL;
437
GSList *result = NULL;
439
max_aid = gm_conf_get_int (CONTACTS_KEY "max_aid");
441
for (i = 1; i <= max_aid ; i++) {
442
addb = get_addressbook (i);
444
result = g_slist_append (result, (gpointer)addb);
452
gnomemeeting_local_addressbook_get_contacts (GmAddressbook *addb,
454
gboolean partial_match,
455
const gchar *fullname,
457
const gchar *categorie,
458
const gchar *location,
459
const gchar *speeddial)
466
gboolean matching = TRUE;
467
GmContact *contact = NULL;
468
GSList *result = NULL;
469
GmAddressbook *addb_loop = NULL;
473
aid = strtol (addb->aid, NULL, 10);
475
g_return_val_if_fail (aid > 0, NULL);
477
key = g_strdup_printf (CONTACTS_KEY "%d/max_uid", aid);
478
max_uid = gm_conf_get_int (key);
481
for (uid = 1; uid <= max_uid ; uid++) {
482
contact = get_contact (aid, uid);
483
if (contact != NULL) {
492
if (str_contains (contact->fullname, fullname)) {
503
if (str_contains (contact->url, url)) {
514
if (str_contains (contact->categories, categorie)) {
525
if (str_contains (contact->speeddial, speeddial)) {
538
&& speeddial == NULL)
539
matching = TRUE; /* nothing was tested, so the contact is good */
542
result = g_slist_append (result, (gpointer)contact);
544
gmcontact_delete (contact);
549
max_aid = gm_conf_get_int (CONTACTS_KEY "max_aid");
550
for (aid = 1; aid <= max_aid; aid++) {
551
addb_loop = get_addressbook (aid);
552
if (addb_loop != NULL)
553
result = g_slist_concat (result, gnomemeeting_local_addressbook_get_contacts (addb_loop, nbr, partial_match, fullname, url, categorie, location, speeddial));
557
nbr = g_slist_length (result);
564
gnomemeeting_local_addressbook_add (GmAddressbook *addb)
568
g_return_val_if_fail (addb != NULL, FALSE);
570
aid = get_available_aid ();
576
addb->aid = g_strdup_printf ("%d", aid);
578
return store_addressbook (addb);
583
gnomemeeting_local_addressbook_delete (GmAddressbook *addb)
587
gchar *namespc = NULL;
589
g_return_val_if_fail (addb != NULL, FALSE);
591
aid = strtol (addb->aid, NULL, 10);
593
g_return_val_if_fail (aid > 0, FALSE);
595
namespc = g_strdup_printf (CONTACTS_KEY "%d", aid);
596
gm_conf_destroy (namespc);
599
max_aid = gm_conf_get_int (CONTACTS_KEY "max_aid");
601
if (max_aid == aid) {
602
/* FIXME: bad! Need a proper loop to detect the last really
603
* used aid (another helper function would be nice, I think)
605
gm_conf_set_int (CONTACTS_KEY "max_aid", aid - 1);
613
gnomemeeting_local_addressbook_modify (GmAddressbook *addb)
615
g_return_val_if_fail (addb != NULL, FALSE);
617
return store_addressbook (addb);
622
gnomemeeting_local_addressbook_delete_contact (GmAddressbook *addb,
628
gchar *namespc = NULL;
631
g_return_val_if_fail (addb != NULL, FALSE);
632
g_return_val_if_fail (contact != NULL, FALSE);
634
aid = strtol (addb->aid, NULL, 10);
635
g_return_val_if_fail (aid > 0, FALSE);
637
uid = strtol (contact->uid, NULL, 10);
638
g_return_val_if_fail (uid > 0, FALSE);
640
namespc = g_strdup_printf (CONTACTS_KEY "%d/%d", aid, uid);
641
gm_conf_destroy (namespc);
644
key = g_strdup_printf (CONTACTS_KEY "%d/max_uid", aid);
645
max_uid = gm_conf_get_int (key);
648
if (max_uid == uid) {
649
/* FIXME: bad! Need a proper loop to detect the last really
650
* used uid (another helper function would be nice, I think)
652
key = g_strdup_printf (CONTACTS_KEY "%d/max_uid", aid);
653
gm_conf_set_int (key, uid - 1);
662
gnomemeeting_local_addressbook_add_contact (GmAddressbook *addb,
668
g_return_val_if_fail (addb != NULL, FALSE);
669
g_return_val_if_fail (contact != NULL, FALSE);
671
aid = strtol (addb->aid, NULL, 10);
672
g_return_val_if_fail (aid > 0, FALSE);
674
uid = get_available_uid (aid);
675
contact->uid = g_strdup_printf ("%d", uid);
677
return store_contact (contact, aid);
682
gnomemeeting_local_addressbook_modify_contact (GmAddressbook *addb,
687
g_return_val_if_fail (addb != NULL, FALSE);
688
g_return_val_if_fail (contact != NULL, FALSE);
690
aid = strtol (addb->aid, NULL, 10);
691
g_return_val_if_fail (aid > 0, FALSE);
693
return store_contact (contact, aid);
698
gnomemeeting_local_addressbook_is_editable (GmAddressbook *)
705
gnomemeeting_local_addressbook_init (gchar *group_name,
708
GmAddressbook *addb = NULL;
710
GSList *addressbooks = NULL;
711
GSList *addressbooks_iter = NULL;
712
gboolean found = false;
714
addressbooks = gnomemeeting_get_local_addressbooks ();
715
addressbooks_iter = addressbooks;
716
while (addressbooks_iter && !found) {
718
if (addressbooks_iter->data) {
720
addb = GM_ADDRESSBOOK (addressbooks_iter->data);
721
if (addb && addb->name && !strcmp (source_name, addb->name))
724
addressbooks_iter = g_slist_next (addressbooks_iter);
726
g_slist_foreach (addressbooks, (GFunc) gm_addressbook_delete, NULL);
727
g_slist_free (addressbooks);
732
addb = gm_addressbook_new ();
733
addb->name = g_strdup (source_name);
734
gnomemeeting_addressbook_add (addb);
735
gm_addressbook_delete (addb);
740
gnomemeeting_local_addressbook_has_fullname (GmAddressbook *)
747
gnomemeeting_local_addressbook_has_url (GmAddressbook *)
754
gnomemeeting_local_addressbook_has_speeddial (GmAddressbook *)
761
gnomemeeting_local_addressbook_has_categories (GmAddressbook *)
768
gnomemeeting_local_addressbook_has_location (GmAddressbook *)
775
gnomemeeting_local_addressbook_has_comment (GmAddressbook *)
782
gnomemeeting_local_addressbook_has_software (GmAddressbook *)
789
gnomemeeting_local_addressbook_has_email (GmAddressbook *)
795
gboolean gnomemeeting_local_addressbook_has_state (GmAddressbook *)