aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/backend/pas
diff options
context:
space:
mode:
Diffstat (limited to 'addressbook/backend/pas')
-rw-r--r--addressbook/backend/pas/Makefile.am14
-rw-r--r--addressbook/backend/pas/pas-backend-card-sexp.c239
-rw-r--r--addressbook/backend/pas/pas-backend-card-sexp.h13
-rw-r--r--addressbook/backend/pas/pas-backend-file.c1315
-rw-r--r--addressbook/backend/pas/pas-backend-file.h6
-rw-r--r--addressbook/backend/pas/pas-backend-ldap.c1405
-rw-r--r--addressbook/backend/pas/pas-backend-summary.c80
-rw-r--r--addressbook/backend/pas/pas-backend-summary.h14
-rw-r--r--addressbook/backend/pas/pas-backend-sync.c395
-rw-r--r--addressbook/backend/pas/pas-backend-sync.h81
-rw-r--r--addressbook/backend/pas/pas-backend-vcf.c632
-rw-r--r--addressbook/backend/pas/pas-backend-vcf.h35
-rw-r--r--addressbook/backend/pas/pas-backend.c582
-rw-r--r--addressbook/backend/pas/pas-backend.h119
-rw-r--r--addressbook/backend/pas/pas-book-factory.c260
-rw-r--r--addressbook/backend/pas/pas-book-view.c362
-rw-r--r--addressbook/backend/pas/pas-book-view.h29
-rw-r--r--addressbook/backend/pas/pas-book.c830
-rw-r--r--addressbook/backend/pas/pas-book.h202
-rw-r--r--addressbook/backend/pas/pas-card-cursor.c139
-rw-r--r--addressbook/backend/pas/pas-card-cursor.h56
-rw-r--r--addressbook/backend/pas/pas-marshal.list1
-rw-r--r--addressbook/backend/pas/pas-types.h32
-rw-r--r--addressbook/backend/pas/ximian-vcard.h81
24 files changed, 3509 insertions, 3413 deletions
diff --git a/addressbook/backend/pas/Makefile.am b/addressbook/backend/pas/Makefile.am
index c618050ca2..b602a21512 100644
--- a/addressbook/backend/pas/Makefile.am
+++ b/addressbook/backend/pas/Makefile.am
@@ -42,7 +42,7 @@ ldapschemadir = $(privdatadir)
ldapschema_DATA= $(LDAP_SCHEMA)
privlib_LIBRARIES = libpas.a
-noinst_LIBRARIES = libpasfile.a $(LDAP_BACKEND)
+noinst_LIBRARIES = libpasfile.a libpasvcf.a $(LDAP_BACKEND)
pasincludedir = $(privincludedir)/pas
@@ -54,7 +54,8 @@ pasinclude_HEADERS = \
pas-backend-card-sexp.h \
pas-backend.h \
pas-backend-summary.h \
- pas-card-cursor.h
+ pas-backend-sync.h \
+ pas-types.h
libpas_a_SOURCES = \
$(pasinclude_HEADERS) \
@@ -66,13 +67,18 @@ libpas_a_SOURCES = \
pas-backend-file.c \
pas-backend.c \
pas-backend-summary.c \
- pas-card-cursor.c \
- pas-marshal.c
+ pas-backend-sync.c \
+ pas-marshal.c \
+ ximian-vcard.h
libpasfile_a_SOURCES = \
pas-backend-file.c \
pas-backend-file.h
+libpasvcf_a_SOURCES = \
+ pas-backend-vcf.c \
+ pas-backend-vcf.h
+
if ENABLE_LDAP
libpasldap_a_SOURCES = \
$(LDAP_BACKEND_FILES)
diff --git a/addressbook/backend/pas/pas-backend-card-sexp.c b/addressbook/backend/pas/pas-backend-card-sexp.c
index e7b5d8a87d..1ccb4f2433 100644
--- a/addressbook/backend/pas/pas-backend-card-sexp.c
+++ b/addressbook/backend/pas/pas-backend-card-sexp.c
@@ -22,7 +22,6 @@
#include <string.h>
#include <e-util/e-sexp.h>
-#include <ebook/e-card-simple.h>
#include <gal/widgets/e-unicode.h>
static GObjectClass *parent_class;
@@ -35,17 +34,17 @@ struct _PASBackendCardSExpPrivate {
};
struct _SearchContext {
- ECardSimple *card;
+ EContact *contact;
};
static gboolean
-compare_email (ECardSimple *card, const char *str,
+compare_email (EContact *contact, const char *str,
char *(*compare)(const char*, const char*))
{
int i;
- for (i = E_CARD_SIMPLE_EMAIL_ID_EMAIL; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i ++) {
- const char *email = e_card_simple_get_email (card, i);
+ for (i = E_CONTACT_EMAIL_1; i <= E_CONTACT_EMAIL_3; i ++) {
+ const char *email = e_contact_get_const (contact, i);
if (email && compare(email, str))
return TRUE;
@@ -55,32 +54,36 @@ compare_email (ECardSimple *card, const char *str,
}
static gboolean
-compare_phone (ECardSimple *card, const char *str,
+compare_phone (EContact *contact, const char *str,
char *(*compare)(const char*, const char*))
{
int i;
+ gboolean rv = FALSE;
- for (i = E_CARD_SIMPLE_PHONE_ID_ASSISTANT; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) {
- const ECardPhone *phone = e_card_simple_get_phone (card, i);
+ for (i = E_CONTACT_FIRST_PHONE_ID; i <= E_CONTACT_LAST_PHONE_ID; i ++) {
+ char *phone = e_contact_get (contact, i);
- if (phone && compare(phone->number, str))
- return TRUE;
+ rv = phone && compare(phone, str);
+ g_free (phone);
+
+ if (rv)
+ break;
}
- return FALSE;
+ return rv;
}
static gboolean
-compare_name (ECardSimple *card, const char *str,
+compare_name (EContact *contact, const char *str,
char *(*compare)(const char*, const char*))
{
const char *name;
- name = e_card_simple_get_const (card, E_CARD_SIMPLE_FIELD_FULL_NAME);
+ name = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
if (name && compare (name, str))
return TRUE;
- name = e_card_simple_get_const (card, E_CARD_SIMPLE_FIELD_FAMILY_NAME);
+ name = e_contact_get_const (contact, E_CONTACT_FAMILY_NAME);
if (name && compare (name, str))
return TRUE;
@@ -88,7 +91,7 @@ compare_name (ECardSimple *card, const char *str,
}
static gboolean
-compare_address (ECardSimple *card, const char *str,
+compare_address (EContact *contact, const char *str,
char *(*compare)(const char*, const char*))
{
g_warning("address searching not implemented\n");
@@ -96,23 +99,17 @@ compare_address (ECardSimple *card, const char *str,
}
static gboolean
-compare_category (ECardSimple *card, const char *str,
+compare_category (EContact *contact, const char *str,
char *(*compare)(const char*, const char*))
{
- EList *categories;
- EIterator *iterator;
- ECard *ecard;
+ GList *categories;
+ GList *iterator;
gboolean ret_val = FALSE;
- g_object_get (card,
- "card", &ecard,
- NULL);
- g_object_get (ecard,
- "category_list", &categories,
- NULL);
+ categories = e_contact_get (contact, E_CONTACT_CATEGORY_LIST);
- for (iterator = e_list_get_iterator(categories); e_iterator_is_valid (iterator); e_iterator_next (iterator)) {
- const char *category = e_iterator_get (iterator);
+ for (iterator = categories; iterator; iterator = iterator->next) {
+ const char *category = iterator->data;
if (compare(category, str)) {
ret_val = TRUE;
@@ -120,83 +117,45 @@ compare_category (ECardSimple *card, const char *str,
}
}
- g_object_unref (iterator);
- e_card_free_empty_lists (ecard);
- g_object_unref (categories);
- g_object_unref (ecard);
- return ret_val;
-}
-
-static gboolean
-compare_arbitrary (ECardSimple *card, const char *str,
- char *(*compare)(const char*, const char*))
-{
- EList *list;
- EIterator *iterator;
- ECard *ecard;
- gboolean ret_val = FALSE;
-
- g_object_get (card,
- "card", &ecard,
- NULL);
- g_object_get (ecard,
- "arbitrary", &list,
- NULL);
-
- for (iterator = e_list_get_iterator(list); e_iterator_is_valid (iterator); e_iterator_next (iterator)) {
- const ECardArbitrary *arbitrary = e_iterator_get (iterator);
+ g_list_foreach (categories, (GFunc)g_free, NULL);
+ g_list_free (categories);
- if (compare(arbitrary->key, str)) {
- ret_val = TRUE;
- break;
- }
- }
-
- g_object_unref (iterator);
- e_card_free_empty_lists (ecard);
- g_object_unref (list);
- g_object_unref (ecard);
return ret_val;
}
static struct prop_info {
- ECardSimpleField field_id;
+ EContactField field_id;
const char *query_prop;
- const char *ecard_prop;
#define PROP_TYPE_NORMAL 0x01
#define PROP_TYPE_LIST 0x02
-#define PROP_TYPE_LISTITEM 0x03
-#define PROP_TYPE_ID 0x04
int prop_type;
- gboolean (*list_compare)(ECardSimple *ecard, const char *str,
+ gboolean (*list_compare)(EContact *contact, const char *str,
char *(*compare)(const char*, const char*));
} prop_info_table[] = {
-#define NORMAL_PROP(f,q,e) {f, q, e, PROP_TYPE_NORMAL, NULL}
-#define ID_PROP {0, "id", NULL, PROP_TYPE_ID, NULL}
-#define LIST_PROP(q,e,c) {0, q, e, PROP_TYPE_LIST, c}
-
- /* query prop, ecard prop, type, list compare function */
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_FILE_AS, "file_as", "file_as" ),
- LIST_PROP ( "full_name", "full_name", compare_name), /* not really a list, but we need to compare both full and surname */
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_URL, "url", "url" ),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_MAILER, "mailer", "mailer"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_ORG, "org", "org"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_ORG_UNIT, "org_unit", "org_unit"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_OFFICE, "office", "office"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_TITLE, "title", "title"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_ROLE, "role", "role"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_MANAGER, "manager", "manager"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_ASSISTANT, "assistant", "assistant"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_NICKNAME, "nickname", "nickname"),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_SPOUSE, "spouse", "spouse" ),
- NORMAL_PROP ( E_CARD_SIMPLE_FIELD_NOTE, "note", "note"),
- ID_PROP,
- LIST_PROP ( "email", "email", compare_email ),
- LIST_PROP ( "phone", "phone", compare_phone ),
- LIST_PROP ( "address", "address", compare_address ),
- LIST_PROP ( "category", "category", compare_category ),
- LIST_PROP ( "arbitrary", "arbitrary", compare_arbitrary )
+#define NORMAL_PROP(f,q) {f, q, PROP_TYPE_NORMAL, NULL}
+#define LIST_PROP(q,c) {0, q, PROP_TYPE_LIST, c}
+
+ /* query prop, type, list compare function */
+ NORMAL_PROP ( E_CONTACT_FILE_AS, "file_as" ),
+ LIST_PROP ( "full_name", compare_name), /* not really a list, but we need to compare both full and surname */
+ NORMAL_PROP ( E_CONTACT_HOMEPAGE_URL, "url"),
+ NORMAL_PROP ( E_CONTACT_MAILER, "mailer"),
+ NORMAL_PROP ( E_CONTACT_ORG, "org"),
+ NORMAL_PROP ( E_CONTACT_ORG_UNIT, "org_unit"),
+ NORMAL_PROP ( E_CONTACT_OFFICE, "office"),
+ NORMAL_PROP ( E_CONTACT_TITLE, "title"),
+ NORMAL_PROP ( E_CONTACT_ROLE, "role"),
+ NORMAL_PROP ( E_CONTACT_MANAGER, "manager"),
+ NORMAL_PROP ( E_CONTACT_ASSISTANT, "assistant"),
+ NORMAL_PROP ( E_CONTACT_NICKNAME, "nickname"),
+ NORMAL_PROP ( E_CONTACT_SPOUSE, "spouse" ),
+ NORMAL_PROP ( E_CONTACT_NOTE, "note"),
+ NORMAL_PROP ( E_CONTACT_UID, "id"),
+ LIST_PROP ( "email", compare_email ),
+ LIST_PROP ( "phone", compare_phone ),
+ LIST_PROP ( "address", compare_address ),
+ LIST_PROP ( "category", compare_category ),
};
static int num_prop_infos = sizeof(prop_info_table) / sizeof(prop_info_table[0]);
@@ -225,28 +184,10 @@ entry_compare(SearchContext *ctx, struct _ESExp *f,
info = &prop_info_table[i];
if (info->prop_type == PROP_TYPE_NORMAL) {
- char *prop = NULL;
- /* searches where the query's property
- maps directly to an ecard property */
-
- prop = e_card_simple_get (ctx->card, info->field_id);
-
- if (prop && compare(prop, argv[1]->value.string)) {
- truth = TRUE;
- }
- if ((!prop) && compare("", argv[1]->value.string)) {
- truth = TRUE;
- }
- g_free (prop);
- } else if (info->prop_type == PROP_TYPE_LIST) {
- /* the special searches that match any of the list elements */
- truth = info->list_compare (ctx->card, argv[1]->value.string, compare);
- } else if (info->prop_type == PROP_TYPE_ID) {
const char *prop = NULL;
- /* searches where the query's property
- maps directly to an ecard property */
+ /* straight string property matches */
- prop = e_card_get_id (ctx->card->card);
+ prop = e_contact_get_const (ctx->contact, info->field_id);
if (prop && compare(prop, argv[1]->value.string)) {
truth = TRUE;
@@ -255,6 +196,10 @@ entry_compare(SearchContext *ctx, struct _ESExp *f,
truth = TRUE;
}
}
+ else if (info->prop_type == PROP_TYPE_LIST) {
+ /* the special searches that match any of the list elements */
+ truth = info->list_compare (ctx->contact, argv[1]->value.string, compare);
+ }
/* if we're looking at all fields and find a match,
or if we're just looking at this one field,
@@ -335,6 +280,51 @@ func_beginswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *da
return entry_compare (ctx, f, argc, argv, beginswith_helper);
}
+static ESExpResult *
+func_exists(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
+{
+ SearchContext *ctx = data;
+ ESExpResult *r;
+ int truth = FALSE;
+
+ if (argc == 1
+ && argv[0]->type == ESEXP_RES_STRING) {
+ char *propname;
+ struct prop_info *info = NULL;
+ int i;
+
+ propname = argv[0]->value.string;
+
+ for (i = 0; i < num_prop_infos; i ++) {
+ if (!strcmp (prop_info_table[i].query_prop, propname)) {
+ info = &prop_info_table[i];
+
+ if (info->prop_type == PROP_TYPE_NORMAL) {
+ const char *prop = NULL;
+ /* searches where the query's property
+ maps directly to an ecard property */
+
+ prop = e_contact_get_const (ctx->contact, info->field_id);
+
+ if (prop && *prop)
+ truth = TRUE;
+ }
+ else if (info->prop_type == PROP_TYPE_LIST) {
+ /* the special searches that match any of the list elements */
+ truth = info->list_compare (ctx->contact, "", (char *(*)(const char*, const char*)) e_utf8_strstrcase);
+ }
+
+ break;
+ }
+ }
+
+ }
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
+ r->value.bool = truth;
+
+ return r;
+}
+
/* 'builtin' functions */
static struct {
char *name;
@@ -346,25 +336,27 @@ static struct {
{ "is", func_is, 0 },
{ "beginswith", func_beginswith, 0 },
{ "endswith", func_endswith, 0 },
+ { "exists", func_exists, 0 },
};
gboolean
-pas_backend_card_sexp_match_ecard (PASBackendCardSExp *sexp, ECard *ecard)
+pas_backend_card_sexp_match_contact (PASBackendCardSExp *sexp, EContact *contact)
{
ESExpResult *r;
gboolean retval;
- sexp->priv->search_context->card = e_card_simple_new (ecard);
-
- /* if it's not a valid vcard why is it in our db? :) */
- if (!sexp->priv->search_context->card)
+ if (!contact) {
+ g_warning ("null EContact passed to pas_backend_card_sexp_match_contact");
return FALSE;
+ }
+
+ sexp->priv->search_context->contact = g_object_ref (contact);
r = e_sexp_eval(sexp->priv->search_sexp);
retval = (r && r->type == ESEXP_RES_BOOL && r->value.bool);
- g_object_unref(sexp->priv->search_context->card);
+ g_object_unref(sexp->priv->search_context->contact);
e_sexp_result_free(sexp->priv->search_sexp, r);
@@ -374,14 +366,14 @@ pas_backend_card_sexp_match_ecard (PASBackendCardSExp *sexp, ECard *ecard)
gboolean
pas_backend_card_sexp_match_vcard (PASBackendCardSExp *sexp, const char *vcard)
{
- ECard *card;
+ EContact *contact;
gboolean retval;
- card = e_card_new ((char*)vcard);
+ contact = e_contact_new_from_vcard (vcard);
- retval = pas_backend_card_sexp_match_ecard (sexp, card);
+ retval = pas_backend_card_sexp_match_contact (sexp, contact);
- g_object_unref(card);
+ g_object_unref(contact);
return retval;
}
@@ -404,7 +396,8 @@ pas_backend_card_sexp_new (const char *text)
if (symbols[i].type == 1) {
e_sexp_add_ifunction(sexp->priv->search_sexp, 0, symbols[i].name,
(ESExpIFunc *)symbols[i].func, sexp->priv->search_context);
- } else {
+ }
+ else {
e_sexp_add_function(sexp->priv->search_sexp, 0, symbols[i].name,
symbols[i].func, sexp->priv->search_context);
}
diff --git a/addressbook/backend/pas/pas-backend-card-sexp.h b/addressbook/backend/pas/pas-backend-card-sexp.h
index eb7c7c6641..7efb697fb0 100644
--- a/addressbook/backend/pas/pas-backend-card-sexp.h
+++ b/addressbook/backend/pas/pas-backend-card-sexp.h
@@ -26,7 +26,8 @@
#include <glib.h>
#include <glib-object.h>
-#include <ebook/e-card.h>
+#include <ebook/e-contact.h>
+#include <pas/pas-types.h>
#define PAS_TYPE_BACKEND_CARD_SEXP (pas_backend_card_sexp_get_type ())
#define PAS_BACKEND_CARD_SEXP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_CARD_SEXP, PASBackendCardSExp))
@@ -37,19 +38,19 @@
typedef struct _PASBackendCardSExpPrivate PASBackendCardSExpPrivate;
-typedef struct {
+struct _PASBackendCardSExp {
GObject parent_object;
PASBackendCardSExpPrivate *priv;
-} PASBackendCardSExp;
+};
-typedef struct {
+struct _PASBackendCardSExpClass {
GObjectClass parent_class;
-} PASBackendCardSExpClass;
+};
PASBackendCardSExp *pas_backend_card_sexp_new (const char *text);
GType pas_backend_card_sexp_get_type (void);
gboolean pas_backend_card_sexp_match_vcard (PASBackendCardSExp *sexp, const char *vcard);
-gboolean pas_backend_card_sexp_match_ecard (PASBackendCardSExp *sexp, ECard *ecard);
+gboolean pas_backend_card_sexp_match_contact (PASBackendCardSExp *sexp, EContact *contact);
#endif /* __PAS_BACKEND_CARD_SEXP_H__ */
diff --git a/addressbook/backend/pas/pas-backend-file.c b/addressbook/backend/pas/pas-backend-file.c
index b11c62cb86..06923d7b08 100644
--- a/addressbook/backend/pas/pas-backend-file.c
+++ b/addressbook/backend/pas/pas-backend-file.c
@@ -8,12 +8,18 @@
#include "config.h"
#include "pas-backend-file.h"
+#include "pas-backend-card-sexp.h"
+#include "pas-backend-summary.h"
+#include "pas-book.h"
+#include "pas-book-view.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
+#include <dirent.h>
#include <time.h>
+#include <errno.h>
#include <db.h>
#include <sys/stat.h>
@@ -28,15 +34,12 @@
#include <gal/util/e-util.h>
#include <gal/widgets/e-unicode.h>
-#include <ebook/e-card-simple.h>
+#include <ebook/e-contact.h>
#include <e-util/e-dbhash.h>
#include <e-util/e-db3-utils.h>
#include <libgnome/gnome-i18n.h>
-#include "pas-book.h"
-#include "pas-card-cursor.h"
-#include "pas-backend-card-sexp.h"
-#include "pas-backend-summary.h"
+#define CHANGES_DB_SUFFIX ".changes.db"
#define PAS_BACKEND_FILE_VERSION_NAME "PAS-DB-VERSION"
#define PAS_BACKEND_FILE_VERSION "0.2"
@@ -44,47 +47,17 @@
#define PAS_ID_PREFIX "pas-id-"
#define SUMMARY_FLUSH_TIMEOUT 5000
-static PASBackendClass *pas_backend_file_parent_class;
-typedef struct _PASBackendFileCursorPrivate PASBackendFileCursorPrivate;
-typedef struct _PASBackendFileBookView PASBackendFileBookView;
-typedef struct _PASBackendFileSearchContext PASBackendFileSearchContext;
-typedef struct _PasBackendFileChangeContext PASBackendFileChangeContext;
+static PASBackendSyncClass *pas_backend_file_parent_class;
struct _PASBackendFilePrivate {
char *uri;
+ char *dirname;
char *filename;
+ char *summary_filename;
DB *file_db;
- EList *book_views;
- GHashTable *address_lists;
PASBackendSummary *summary;
};
-struct _PASBackendFileCursorPrivate {
- PASBackend *backend;
- PASBook *book;
-
- GList *elements;
- guint32 num_elements;
-};
-
-struct _PASBackendFileBookView {
- PASBookView *book_view;
- gchar *search;
- PASBackendCardSExp *card_sexp;
- gchar *change_id;
- PASBackendFileChangeContext *change_context;
-};
-
-struct _PasBackendFileChangeContext {
- DB *db;
-
- GList *add_cards;
- GList *add_ids;
- GList *mod_cards;
- GList *mod_ids;
- GList *del_ids;
-};
-
static void
string_to_dbt(const char *str, DBT *dbt)
{
@@ -104,7 +77,8 @@ build_summary (PASBackendFilePrivate *bfpriv)
db_error = db->cursor (db, NULL, &dbc, 0);
if (db_error != 0) {
- g_warning ("pas_backend_file_build_all_cards_list: error building list\n");
+ g_warning ("build_summary: error building list\n");
+ return;
}
memset (&vcard_dbt, 0, sizeof (vcard_dbt));
@@ -117,7 +91,7 @@ build_summary (PASBackendFilePrivate *bfpriv)
if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1
|| strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
- pas_backend_summary_add_card (bfpriv->summary, vcard_dbt.data);
+ pas_backend_summary_add_contact (bfpriv->summary, vcard_dbt.data);
}
db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
@@ -126,21 +100,17 @@ build_summary (PASBackendFilePrivate *bfpriv)
}
static void
-do_summary_query (PASBackendFile *bf,
- PASBackendFileBookView *view,
- gboolean completion_search)
+do_summary_query (PASBackendFile *bf,
+ PASBookView *view)
{
- GPtrArray *ids = pas_backend_summary_search (bf->priv->summary, view->search);
+ GPtrArray *ids = pas_backend_summary_search (bf->priv->summary, pas_book_view_get_card_query (view));
int db_error = 0;
- GList *cards = NULL;
- gint card_count = 0, card_threshold = 20, card_threshold_max = 3000;
DB *db = bf->priv->file_db;
DBT id_dbt, vcard_dbt;
int i;
for (i = 0; i < ids->len; i ++) {
char *id = g_ptr_array_index (ids, i);
- char *vcard = NULL;
#if SUMMARY_STORES_ENOUGH_INFO
/* this is disabled for the time being because lists
@@ -150,6 +120,11 @@ do_summary_query (PASBackendFile *bf,
if (completion_search) {
vcard = pas_backend_summary_get_summary_vcard (bf->priv->summary,
id);
+ if (vcard) {
+ EContact *contact = e_contact_new_from_vcard (vcard_dbt.data);
+ pas_book_view_notify_update (view, contact);
+ g_object_unref (contact);
+ }
}
else {
#endif
@@ -159,166 +134,19 @@ do_summary_query (PASBackendFile *bf,
db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
if (db_error == 0)
- vcard = g_strdup (vcard_dbt.data);
+ pas_book_view_notify_update (view, vcard_dbt.data);
#if SUMMARY_STORES_ENOUGH_INFO
}
#endif
-
- if (vcard) {
- cards = g_list_prepend (cards, vcard);
- card_count ++;
-
- /* If we've accumulated a number of checks, pass them off to the client. */
- if (card_count >= card_threshold) {
- pas_book_view_notify_add (view->book_view, cards);
- /* Clean up the handed-off data. */
- g_list_foreach (cards, (GFunc)g_free, NULL);
- g_list_free (cards);
- cards = NULL;
- card_count = 0;
-
- /* Yeah, this scheme is overly complicated. But I like it. */
- if (card_threshold < card_threshold_max) {
- card_threshold = MIN (2*card_threshold, card_threshold_max);
- }
- }
- }
- else
- continue; /* XXX */
}
g_ptr_array_free (ids, TRUE);
- if (card_count)
- pas_book_view_notify_add (view->book_view, cards);
-
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
-
- g_list_foreach (cards, (GFunc)g_free, NULL);
- g_list_free (cards);
-}
-
-static PASBackendFileBookView *
-pas_backend_file_book_view_copy(const PASBackendFileBookView *book_view, void *closure)
-{
- PASBackendFileBookView *new_book_view;
- new_book_view = g_new (PASBackendFileBookView, 1);
- new_book_view->book_view = book_view->book_view;
-
- new_book_view->search = g_strdup(book_view->search);
- new_book_view->card_sexp = book_view->card_sexp;
- if (new_book_view->card_sexp)
- g_object_ref(new_book_view->card_sexp);
-
- new_book_view->change_id = g_strdup(book_view->change_id);
- if (book_view->change_context) {
- new_book_view->change_context = g_new(PASBackendFileChangeContext, 1);
- new_book_view->change_context->db = book_view->change_context->db;
- new_book_view->change_context->add_cards = book_view->change_context->add_cards;
- new_book_view->change_context->add_ids = book_view->change_context->add_ids;
- new_book_view->change_context->mod_cards = book_view->change_context->mod_cards;
- new_book_view->change_context->mod_ids = book_view->change_context->mod_ids;
- new_book_view->change_context->del_ids = book_view->change_context->del_ids;
- } else
- new_book_view->change_context = NULL;
-
- return new_book_view;
-}
-
-static void
-pas_backend_file_book_view_free(PASBackendFileBookView *book_view, void *closure)
-{
- g_free(book_view->search);
- if (book_view->card_sexp)
- g_object_unref (book_view->card_sexp);
-
- g_free(book_view->change_id);
- if (book_view->change_context) {
- g_list_foreach (book_view->change_context->add_cards, (GFunc)g_free, NULL);
- g_list_foreach (book_view->change_context->add_ids, (GFunc)g_free, NULL);
- g_list_foreach (book_view->change_context->mod_cards, (GFunc)g_free, NULL);
- g_list_foreach (book_view->change_context->mod_ids, (GFunc)g_free, NULL);
- g_list_foreach (book_view->change_context->del_ids, (GFunc)g_free, NULL);
- g_list_free (book_view->change_context->add_cards);
- g_list_free (book_view->change_context->add_ids);
- g_list_free (book_view->change_context->mod_cards);
- g_list_free (book_view->change_context->mod_ids);
- g_list_free (book_view->change_context->del_ids);
- }
- g_free(book_view->change_context);
-
- g_free(book_view);
-}
-
-static long
-get_length(PASCardCursor *cursor, gpointer data)
-{
- PASBackendFileCursorPrivate *cursor_data = (PASBackendFileCursorPrivate *) data;
-
- return cursor_data->num_elements;
+ pas_book_view_notify_complete (view, GNOME_Evolution_Addressbook_Success);
}
static char *
-get_nth(PASCardCursor *cursor, long n, gpointer data)
-{
- PASBackendFileCursorPrivate *cursor_data = (PASBackendFileCursorPrivate *) data;
- GList *nth_item = g_list_nth(cursor_data->elements, n);
-
- return g_strdup((char*)nth_item->data);
-}
-
-static void
-cursor_destroy(gpointer data, GObject *where_object_was)
-{
- CORBA_Environment ev;
- GNOME_Evolution_Addressbook_Book corba_book;
- PASBackendFileCursorPrivate *cursor_data = (PASBackendFileCursorPrivate *) data;
-
- corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(cursor_data->book));
-
- CORBA_exception_init(&ev);
-
- GNOME_Evolution_Addressbook_Book_unref(corba_book, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("cursor_destroy: Exception unreffing "
- "corba book.\n");
- }
-
- CORBA_exception_free(&ev);
-
- g_list_foreach(cursor_data->elements, (GFunc)g_free, NULL);
- g_list_free (cursor_data->elements);
-
- g_free(cursor_data);
-}
-
-static void
-view_destroy(gpointer data, GObject *where_object_was)
-{
- PASBook *book = (PASBook *)data;
- PASBackendFile *bf;
- EIterator *iterator;
- gboolean success = FALSE;
-
- bf = PAS_BACKEND_FILE(pas_book_get_backend(book));
- for (iterator = e_list_get_iterator(bf->priv->book_views); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- const PASBackendFileBookView *view = e_iterator_get(iterator);
- if (view->book_view == (PASBookView*)where_object_was) {
- e_iterator_delete(iterator);
- success = TRUE;
- break;
- }
- }
- if (!success)
- g_warning ("Failed to remove from book_views list");
- g_object_unref(iterator);
-
- bonobo_object_unref(BONOBO_OBJECT(book));
-}
-
-static char *
-pas_backend_file_create_unique_id (char *vcard)
+pas_backend_file_create_unique_id (void)
{
/* use a 32 counter and the 32 bit timestamp to make an id.
it's doubtful 2^32 id's will be created in a second, so we
@@ -327,46 +155,18 @@ pas_backend_file_create_unique_id (char *vcard)
return g_strdup_printf (PAS_ID_PREFIX "%08lX%08X", time(NULL), c++);
}
-static gboolean
-vcard_matches_search (const PASBackendFileBookView *view, char *vcard_string)
-{
- /* If this is not a search context view, it doesn't match be default */
- if (view->card_sexp == NULL)
- return FALSE;
-
- return pas_backend_card_sexp_match_vcard (view->card_sexp, vcard_string);
-}
-
-static gboolean
-ecard_matches_search (const PASBackendFileBookView *view, ECard *card)
-{
- /* If this is not a search context view, it doesn't match be default */
- if (view->card_sexp == NULL)
- return FALSE;
-
- return pas_backend_card_sexp_match_ecard (view->card_sexp, card);
-}
-
typedef struct {
PASBackendFile *bf;
PASBook *book;
- const PASBackendFileBookView *view;
+ PASBookView *view;
DBC *dbc;
- int card_count;
- int card_threshold;
- int card_threshold_max;
- GList *cards;
-
gboolean done_first;
- gboolean search_needed;
} FileBackendSearchClosure;
static void
free_search_closure (FileBackendSearchClosure *closure)
{
- g_list_foreach (closure->cards, (GFunc)g_free, NULL);
- g_list_free (closure->cards);
g_free (closure);
}
@@ -397,32 +197,11 @@ pas_backend_file_search_timeout (gpointer data)
/* don't include the version in the list of cards */
if (strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
char *vcard_string = vcard_dbt.data;
+ EContact *contact = e_contact_new_from_vcard (vcard_string);
- /* check if the vcard matches the search sexp */
- if ((!closure->search_needed) || vcard_matches_search (closure->view, vcard_string)) {
- closure->cards = g_list_prepend (closure->cards, g_strdup (vcard_string));
- closure->card_count ++;
- }
-
- /* If we've accumulated a number of checks, pass them off to the client. */
- if (closure->card_count >= closure->card_threshold) {
- pas_book_view_notify_add (closure->view->book_view, closure->cards);
- /* Clean up the handed-off data. */
- g_list_foreach (closure->cards, (GFunc)g_free, NULL);
- g_list_free (closure->cards);
- closure->cards = NULL;
- closure->card_count = 0;
-
- /* Yeah, this scheme is overly complicated. But I like it. */
- if (closure->card_threshold < closure->card_threshold_max) {
- closure->card_threshold = MIN (2*closure->card_threshold, closure->card_threshold_max);
- }
-
- /* return here, we'll do the next lump in the next callback */
- g_timeout_add (200, pas_backend_file_search_timeout, closure);
-
- return FALSE;
- }
+ /* notify_update will check if it matches for us */
+ pas_book_view_notify_update (closure->view, contact);
+ g_object_unref (contact);
}
db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
@@ -435,10 +214,7 @@ pas_backend_file_search_timeout (gpointer data)
free_search_closure (closure);
}
- if (closure->card_count)
- pas_book_view_notify_add (closure->view->book_view, closure->cards);
-
- pas_book_view_notify_complete (closure->view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
+ pas_book_view_notify_complete (closure->view, GNOME_Evolution_Addressbook_Success);
free_search_closure (closure);
@@ -448,49 +224,25 @@ pas_backend_file_search_timeout (gpointer data)
static void
pas_backend_file_search (PASBackendFile *bf,
- PASBook *book,
- const PASBackendFileBookView *cnstview,
- gboolean completion_search)
+ PASBookView *book_view)
{
- PASBackendFileBookView *view = (PASBackendFileBookView *)cnstview;
- gboolean search_needed;
-
- search_needed = TRUE;
-
- if ( ! strcmp (view->search, "(contains \"x-evolution-any-field\" \"\")"))
- search_needed = FALSE;
+ const char *query = pas_book_view_get_card_query (book_view);
- if (search_needed)
- pas_book_view_notify_status_message (view->book_view, _("Searching..."));
+ if ( ! strcmp (query, "(contains \"x-evolution-any-field\" \"\")"))
+ pas_book_view_notify_status_message (book_view, _("Loading..."));
else
- pas_book_view_notify_status_message (view->book_view, _("Loading..."));
-
- if (view->card_sexp) {
- g_object_unref (view->card_sexp);
- view->card_sexp = NULL;
- }
-
- view->card_sexp = pas_backend_card_sexp_new (view->search);
-
- if (!view->card_sexp) {
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_InvalidQuery);
- return;
- }
+ pas_book_view_notify_status_message (book_view, _("Searching..."));
- if (pas_backend_summary_is_summary_query (bf->priv->summary, view->search)) {
- do_summary_query (bf, view, completion_search);
+ if (pas_backend_summary_is_summary_query (bf->priv->summary, query)) {
+ do_summary_query (bf, book_view);
}
else {
FileBackendSearchClosure *closure = g_new0 (FileBackendSearchClosure, 1);
DB *db = bf->priv->file_db;
int db_error;
- closure->card_threshold = 20;
- closure->card_threshold_max = 3000;
- closure->search_needed = search_needed;
- closure->view = view;
+ closure->view = book_view;
closure->bf = bf;
- closure->book = book;
db_error = db->cursor (db, NULL, &closure->dbc, 0);
@@ -502,257 +254,81 @@ pas_backend_file_search (PASBackendFile *bf,
}
}
-static void
-pas_backend_file_changes_foreach_key (const char *key, gpointer user_data)
+static EContact *
+do_create(PASBackendFile *bf,
+ const char *vcard_req)
{
- PASBackendFileChangeContext *ctx = user_data;
- DB *db = ctx->db;
- DBT id_dbt, vcard_dbt;
- int db_error = 0;
-
- string_to_dbt (key, &id_dbt);
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
- db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
-
- if (db_error != 0) {
- char *id = id_dbt.data;
-
- ctx->del_ids = g_list_append (ctx->del_ids, g_strdup (id));
- }
-}
-
-static void
-pas_backend_file_changes (PASBackendFile *bf,
- PASBook *book,
- const PASBackendFileBookView *cnstview)
-{
- int db_error = 0;
- DBT id_dbt, vcard_dbt;
- char *filename;
- EDbHash *ehash;
- GList *i, *v;
- DB *db = bf->priv->file_db;
- DBC *dbc;
- PASBackendFileBookView *view = (PASBackendFileBookView *)cnstview;
- PASBackendFileChangeContext *ctx = cnstview->change_context;
- char *dirname, *slash;
-
- memset (&id_dbt, 0, sizeof (id_dbt));
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
-
- /* Find the changed ids */
- dirname = g_strdup (bf->priv->filename);
- slash = strrchr (dirname, '/');
- *slash = '\0';
-
- filename = g_strdup_printf ("%s/%s.db", dirname, view->change_id);
- ehash = e_dbhash_new (filename);
- g_free (filename);
- g_free (dirname);
-
- db_error = db->cursor (db, NULL, &dbc, 0);
-
- if (db_error != 0) {
- g_warning ("pas_backend_file_changes: error building list\n");
- } else {
- db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST);
-
- while (db_error == 0) {
-
- /* don't include the version in the list of cards */
- if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1
- || strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
- ECard *card;
- char *id = id_dbt.data;
- char *vcard_string;
-
- /* Remove fields the user can't change
- * and can change without the rest of the
- * card changing
- */
- card = e_card_new (vcard_dbt.data);
- g_object_set (card, "last_use", NULL, "use_score", 0.0, NULL);
- vcard_string = e_card_get_vcard_assume_utf8 (card);
- g_object_unref (card);
-
- /* check what type of change has occurred, if any */
- switch (e_dbhash_compare (ehash, id, vcard_string)) {
- case E_DBHASH_STATUS_SAME:
- break;
- case E_DBHASH_STATUS_NOT_FOUND:
- ctx->add_cards = g_list_append (ctx->add_cards,
- vcard_string);
- ctx->add_ids = g_list_append (ctx->add_ids, g_strdup(id));
- break;
- case E_DBHASH_STATUS_DIFFERENT:
- ctx->mod_cards = g_list_append (ctx->mod_cards,
- vcard_string);
- ctx->mod_ids = g_list_append (ctx->mod_ids, g_strdup(id));
- break;
- }
- }
-
- db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
- }
- dbc->c_close (dbc);
- }
-
- e_dbhash_foreach_key (ehash, (EDbHashFunc)pas_backend_file_changes_foreach_key, view->change_context);
-
- /* Send the changes */
- if (db_error != DB_NOTFOUND) {
- g_warning ("pas_backend_file_changes: error building list\n");
- } else {
- if (ctx->add_cards != NULL)
- pas_book_view_notify_add (view->book_view, ctx->add_cards);
-
- if (ctx->mod_cards != NULL)
- pas_book_view_notify_change (view->book_view, ctx->mod_cards);
-
- for (v = ctx->del_ids; v != NULL; v = v->next){
- char *id = v->data;
- pas_book_view_notify_remove_1 (view->book_view, id);
- }
-
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
- }
-
- /* Update the hash */
- for (i = ctx->add_ids, v = ctx->add_cards; i != NULL; i = i->next, v = v->next){
- char *id = i->data;
- char *vcard = v->data;
-
- e_dbhash_add (ehash, id, vcard);
- g_free (i->data);
- g_free (v->data);
- }
- for (i = ctx->mod_ids, v = ctx->mod_cards; i != NULL; i = i->next, v = v->next){
- char *id = i->data;
- char *vcard = v->data;
-
- e_dbhash_add (ehash, id, vcard);
- g_free (i->data);
- g_free (v->data);
- }
- for (i = ctx->del_ids; i != NULL; i = i->next){
- char *id = i->data;
-
- e_dbhash_remove (ehash, id);
- g_free (i->data);
- }
-
- e_dbhash_write (ehash);
- e_dbhash_destroy (ehash);
-}
-
-static char *
-do_create(PASBackend *backend,
- char *vcard_req,
- char **vcard_ptr)
-{
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
DB *db = bf->priv->file_db;
DBT id_dbt, vcard_dbt;
int db_error;
char *id;
- ECard *card;
+ EContact *contact;
char *vcard;
- char *ret_val;
- id = pas_backend_file_create_unique_id (vcard_req);
+ id = pas_backend_file_create_unique_id ();
string_to_dbt (id, &id_dbt);
-
- card = e_card_new(vcard_req);
- e_card_set_id(card, id);
- vcard = e_card_get_vcard_assume_utf8(card);
+
+ contact = e_contact_new_from_vcard (vcard_req);
+ e_contact_set(contact, E_CONTACT_UID, id);
+ vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
string_to_dbt (vcard, &vcard_dbt);
db_error = db->put (db, NULL, &id_dbt, &vcard_dbt, 0);
+ g_free (vcard);
+
if (0 == db_error) {
db_error = db->sync (db, 0);
if (db_error != 0)
g_warning ("db->sync failed.\n");
- ret_val = id;
-
}
else {
- g_free (id);
- ret_val = NULL;
+ g_object_unref (contact);
+ contact = NULL;
}
- g_object_unref(card);
- card = NULL;
-
- if (vcard_ptr && ret_val)
- *vcard_ptr = vcard;
- else
- g_free (vcard);
-
- return ret_val;
+ g_free (id);
+ return contact;
}
-static void
-pas_backend_file_process_create_card (PASBackend *backend,
- PASBook *book,
- PASCreateCardRequest *req)
+static PASBackendSyncStatus
+pas_backend_file_create_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *vcard,
+ EContact **contact)
{
- char *id;
- char *vcard;
- EIterator *iterator;
PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- id = do_create(backend, req->vcard, &vcard);
- if (id) {
- for (iterator = e_list_get_iterator(bf->priv->book_views); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- const PASBackendFileBookView *view = e_iterator_get(iterator);
- if (vcard_matches_search (view, vcard)) {
- bonobo_object_ref (BONOBO_OBJECT (view->book_view));
- pas_book_view_notify_add_1 (view->book_view, vcard);
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
- bonobo_object_unref (BONOBO_OBJECT (view->book_view));
- }
- }
- g_object_unref(iterator);
-
- pas_book_respond_create (
- book,
- GNOME_Evolution_Addressbook_BookListener_Success,
- id);
-
- pas_backend_summary_add_card (bf->priv->summary, vcard);
-
- g_free(vcard);
- g_free(id);
+ *contact = do_create (bf, vcard);
+ if (*contact) {
+ pas_backend_summary_add_contact (bf->priv->summary, *contact);
+ return GNOME_Evolution_Addressbook_Success;
}
else {
/* XXX need a different call status for this case, i
think */
- pas_book_respond_create (
- book,
- GNOME_Evolution_Addressbook_BookListener_CardNotFound,
- "");
+ return GNOME_Evolution_Addressbook_ContactNotFound;
}
}
-static void
-pas_backend_file_process_remove_cards (PASBackend *backend,
- PASBook *book,
- PASRemoveCardsRequest *req)
+static PASBackendSyncStatus
+pas_backend_file_remove_contacts (PASBackendSync *backend,
+ PASBook *book,
+ GList *id_list,
+ GList **ids)
{
PASBackendFile *bf = PAS_BACKEND_FILE (backend);
DB *db = bf->priv->file_db;
DBT id_dbt, vcard_dbt;
int db_error;
- EIterator *iterator;
- const char *id;
+ char *id;
GList *l;
GList *removed_cards = NULL;
- GNOME_Evolution_Addressbook_BookListener_CallStatus rv = GNOME_Evolution_Addressbook_BookListener_Success;
+ GNOME_Evolution_Addressbook_CallStatus rv = GNOME_Evolution_Addressbook_Success;
- for (l = req->ids; l; l = l->next) {
+ for (l = id_list; l; l = l->next) {
id = l->data;
string_to_dbt (id, &id_dbt);
@@ -760,17 +336,17 @@ pas_backend_file_process_remove_cards (PASBackend *backend,
db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
if (0 != db_error) {
- rv = GNOME_Evolution_Addressbook_BookListener_CardNotFound;
+ rv = GNOME_Evolution_Addressbook_ContactNotFound;
continue;
}
db_error = db->del (db, NULL, &id_dbt, 0);
if (0 != db_error) {
- rv = GNOME_Evolution_Addressbook_BookListener_CardNotFound;
+ rv = GNOME_Evolution_Addressbook_ContactNotFound;
continue;
}
- removed_cards = g_list_prepend (removed_cards, e_card_new (vcard_dbt.data));
+ removed_cards = g_list_prepend (removed_cards, id);
}
/* if we actually removed some, try to sync */
@@ -780,53 +356,30 @@ pas_backend_file_process_remove_cards (PASBackend *backend,
g_warning ("db->sync failed.\n");
}
- for (iterator = e_list_get_iterator (bf->priv->book_views); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- const PASBackendFileBookView *view = e_iterator_get(iterator);
- GList *view_removed = NULL;
- for (l = removed_cards; l; l = l->next) {
- ECard *removed_card = l->data;
- if (ecard_matches_search (view, removed_card)) {
- view_removed = g_list_prepend (view_removed, (char*)e_card_get_id (removed_card));
- }
- }
- if (view_removed) {
- bonobo_object_ref (BONOBO_OBJECT (view->book_view));
- pas_book_view_notify_remove (view->book_view, view_removed);
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
- bonobo_object_unref (BONOBO_OBJECT (view->book_view));
- g_list_free (view_removed);
- }
- }
- g_object_unref(iterator);
-
- pas_book_respond_remove (book, rv);
+ *ids = removed_cards;
for (l = removed_cards; l; l = l->next) {
- ECard *c = l->data;
- pas_backend_summary_remove_card (bf->priv->summary, e_card_get_id (c));
- g_object_unref (c);
+ char *id = l->data;
+ pas_backend_summary_remove_contact (bf->priv->summary, id);
}
- g_list_free (removed_cards);
+ return rv;
}
-static void
-pas_backend_file_process_modify_card (PASBackend *backend,
- PASBook *book,
- PASModifyCardRequest *req)
+static PASBackendSyncStatus
+pas_backend_file_modify_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *vcard,
+ EContact **contact)
{
PASBackendFile *bf = PAS_BACKEND_FILE (backend);
DB *db = bf->priv->file_db;
DBT id_dbt, vcard_dbt;
int db_error;
- EIterator *iterator;
- ECard *card;
- const char *id, *lookup_id;
- char *old_vcard_string;
+ char *id, *lookup_id;
- /* create a new ecard from the request data */
- card = e_card_new(req->vcard);
- id = e_card_get_id(card);
+ *contact = e_contact_new_from_vcard (vcard);
+ id = e_contact_get(*contact, E_CONTACT_UID);
/* This is disgusting, but for a time cards were added with
ID's that are no longer used (they contained both the uri
@@ -844,15 +397,10 @@ pas_backend_file_process_modify_card (PASBackend *backend,
/* get the old ecard - the one that's presently in the db */
db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
- if (0 != db_error) {
- pas_book_respond_modify (
- book,
- GNOME_Evolution_Addressbook_BookListener_CardNotFound);
- return;
- }
- old_vcard_string = g_strdup(vcard_dbt.data);
+ if (0 != db_error)
+ return GNOME_Evolution_Addressbook_ContactNotFound;
- string_to_dbt (req->vcard, &vcard_dbt);
+ string_to_dbt (vcard, &vcard_dbt);
db_error = db->put (db, NULL, &id_dbt, &vcard_dbt, 0);
@@ -861,55 +409,50 @@ pas_backend_file_process_modify_card (PASBackend *backend,
if (db_error != 0)
g_warning ("db->sync failed.\n");
- for (iterator = e_list_get_iterator(bf->priv->book_views); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- CORBA_Environment ev;
- const PASBackendFileBookView *view = e_iterator_get(iterator);
- gboolean old_match, new_match;
-
- CORBA_exception_init(&ev);
-
- bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
-
- old_match = vcard_matches_search (view, old_vcard_string);
- new_match = vcard_matches_search (view, req->vcard);
- if (old_match && new_match)
- pas_book_view_notify_change_1 (view->book_view, req->vcard);
- else if (new_match)
- pas_book_view_notify_add_1 (view->book_view, req->vcard);
- else /* if (old_match) */
- pas_book_view_notify_remove_1 (view->book_view, id);
+ pas_backend_summary_remove_contact (bf->priv->summary, id);
+ pas_backend_summary_add_contact (bf->priv->summary, *contact);
+ }
+ g_free (id);
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
+ if (0 == db_error)
+ return GNOME_Evolution_Addressbook_Success;
+ else
+ return GNOME_Evolution_Addressbook_ContactNotFound;
+}
- bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
+static PASBackendSyncStatus
+pas_backend_file_get_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *id,
+ char **vcard)
+{
+ PASBackendFile *bf;
+ DB *db;
+ DBT id_dbt, vcard_dbt;
+ int db_error = 0;
- CORBA_exception_free (&ev);
- }
+ bf = PAS_BACKEND_FILE (pas_book_get_backend (book));
+ db = bf->priv->file_db;
- g_object_unref(iterator);
+ string_to_dbt (id, &id_dbt);
+ memset (&vcard_dbt, 0, sizeof (vcard_dbt));
- pas_book_respond_modify (
- book,
- GNOME_Evolution_Addressbook_BookListener_Success);
+ db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
- pas_backend_summary_remove_card (bf->priv->summary, id);
- pas_backend_summary_add_card (bf->priv->summary, req->vcard);
- }
- else {
- pas_book_respond_modify (
- book,
- GNOME_Evolution_Addressbook_BookListener_CardNotFound);
+ if (db_error == 0) {
+ *vcard = g_strdup (vcard_dbt.data);
+ return GNOME_Evolution_Addressbook_Success;
+ } else {
+ *vcard = g_strdup ("");
+ return GNOME_Evolution_Addressbook_ContactNotFound;
}
-
- g_free(old_vcard_string);
-
- g_object_unref(card);
}
-static void
-pas_backend_file_build_cards_list(PASBackend *backend,
- PASBackendFileCursorPrivate *cursor_data,
- char *search)
+static PASBackendSyncStatus
+pas_backend_file_get_contact_list (PASBackendSync *backend,
+ PASBook *book,
+ const char *query,
+ GList **contacts)
{
PASBackendFile *bf = PAS_BACKEND_FILE (backend);
DB *db = bf->priv->file_db;
@@ -918,8 +461,10 @@ pas_backend_file_build_cards_list(PASBackend *backend,
DBT id_dbt, vcard_dbt;
PASBackendCardSExp *card_sexp = NULL;
gboolean search_needed;
-
- cursor_data->elements = NULL;
+ const char *search = query;
+ GList *contact_list = NULL;
+
+ printf ("pas_backend_file_get_contact_list (%s)\n", search);
search_needed = TRUE;
@@ -927,14 +472,16 @@ pas_backend_file_build_cards_list(PASBackend *backend,
search_needed = FALSE;
card_sexp = pas_backend_card_sexp_new (search);
-
- if (!card_sexp)
- g_warning ("pas_backend_file_build_all_cards_list: error building list\n");
+ if (!card_sexp) {
+ /* XXX this needs to be an invalid query error of some sort*/
+ return GNOME_Evolution_Addressbook_ContactNotFound;
+ }
db_error = db->cursor (db, NULL, &dbc, 0);
if (db_error != 0) {
- g_warning ("pas_backend_file_build_all_cards_list: error building list\n");
+ /* XXX this needs to be some CouldNotOpen error */
+ return GNOME_Evolution_Addressbook_ContactNotFound;
}
memset (&vcard_dbt, 0, sizeof (vcard_dbt));
@@ -948,7 +495,7 @@ pas_backend_file_build_cards_list(PASBackend *backend,
|| strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
if ((!search_needed) || (card_sexp != NULL && pas_backend_card_sexp_match_vcard (card_sexp, vcard_dbt.data))) {
- cursor_data->elements = g_list_prepend (cursor_data->elements, g_strdup (vcard_dbt.data));
+ contact_list = g_list_append (contact_list, g_strdup (vcard_dbt.data));
}
}
@@ -956,274 +503,211 @@ pas_backend_file_build_cards_list(PASBackend *backend,
}
- if (db_error != DB_NOTFOUND) {
- g_warning ("pas_backend_file_build_all_cards_list: error building list\n");
- }
- else {
- cursor_data->num_elements = g_list_length (cursor_data->elements);
- cursor_data->elements = g_list_reverse (cursor_data->elements);
- }
+ *contacts = contact_list;
+ return db_error != DB_NOTFOUND
+ ? GNOME_Evolution_Addressbook_OtherError
+ : GNOME_Evolution_Addressbook_Success;
}
static void
-pas_backend_file_process_get_vcard (PASBackend *backend,
- PASBook *book,
- PASGetVCardRequest *req)
+pas_backend_file_start_book_view (PASBackend *backend,
+ PASBookView *book_view)
{
- PASBackendFile *bf;
- DB *db;
- DBT id_dbt, vcard_dbt;
- int db_error = 0;
- char *card;
- GNOME_Evolution_Addressbook_BookListener_CallStatus status;
-
- bf = PAS_BACKEND_FILE (pas_book_get_backend (book));
- db = bf->priv->file_db;
-
- string_to_dbt (req->id, &id_dbt);
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
-
- db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
+ pas_backend_file_search (PAS_BACKEND_FILE (backend), book_view);
+}
- if (db_error == 0) {
- card = vcard_dbt.data;
- status = GNOME_Evolution_Addressbook_BookListener_Success;
- } else {
- card = "";
- status = GNOME_Evolution_Addressbook_BookListener_CardNotFound;
- }
+typedef struct {
+ DB *db;
- pas_book_respond_get_vcard (book,
- status,
- card);
-}
+ GList *add_cards;
+ GList *add_ids;
+ GList *mod_cards;
+ GList *mod_ids;
+ GList *del_ids;
+} PASBackendFileChangeContext;
static void
-pas_backend_file_process_get_cursor (PASBackend *backend,
- PASBook *book,
- PASGetCursorRequest *req)
+pas_backend_file_changes_foreach_key (const char *key, gpointer user_data)
{
- /*
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- DB *db = bf->priv->file_db;
- DBT id_dbt, vcard_dbt;
- */
- CORBA_Environment ev;
- int db_error = 0;
- PASBackendFileCursorPrivate *cursor_data;
- PASCardCursor *cursor;
- GNOME_Evolution_Addressbook_Book corba_book;
-
- cursor_data = g_new(PASBackendFileCursorPrivate, 1);
- cursor_data->backend = backend;
- cursor_data->book = book;
-
- pas_backend_file_build_cards_list(backend, cursor_data, req->search);
-
- corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(book));
-
- CORBA_exception_init(&ev);
-
- GNOME_Evolution_Addressbook_Book_ref(corba_book, &ev);
+ PASBackendFileChangeContext *ctx = user_data;
+ DB *db = ctx->db;
+ DBT id_dbt, vcard_dbt;
+ int db_error = 0;
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("pas_backend_file_process_get_cursor: Exception reffing "
- "corba book.\n");
- }
-
- CORBA_exception_free(&ev);
+ string_to_dbt (key, &id_dbt);
+ memset (&vcard_dbt, 0, sizeof (vcard_dbt));
+ db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
- cursor = pas_card_cursor_new(get_length,
- get_nth,
- cursor_data);
+ if (db_error != 0) {
+ char *id = id_dbt.data;
- g_object_weak_ref (G_OBJECT (cursor),
- cursor_destroy, cursor_data);
-
- pas_book_respond_get_cursor (
- book,
- (db_error == 0
- ? GNOME_Evolution_Addressbook_BookListener_Success
- : GNOME_Evolution_Addressbook_BookListener_CardNotFound),
- cursor);
+ ctx->del_ids = g_list_append (ctx->del_ids,
+ g_strdup (id));
+ }
}
-static void
-pas_backend_file_process_get_book_view (PASBackend *backend,
- PASBook *book,
- PASGetBookViewRequest *req)
+static PASBackendSyncStatus
+pas_backend_file_get_changes (PASBackendSync *backend,
+ PASBook *book,
+ const char *change_id,
+ GList **changes_out)
{
PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- PASBookView *book_view;
- PASBackendFileBookView view;
- EIterator *iterator;
-
- bonobo_object_ref(BONOBO_OBJECT(book));
-
- book_view = pas_book_view_new (req->listener);
-
- g_object_weak_ref (G_OBJECT (book_view), view_destroy, book);
-
- view.book_view = book_view;
- view.search = g_strdup (req->search);
- view.card_sexp = NULL;
- view.change_id = NULL;
- view.change_context = NULL;
-
- e_list_append(bf->priv->book_views, &view);
-
- pas_book_respond_get_book_view (book,
- (book_view != NULL
- ? GNOME_Evolution_Addressbook_BookListener_Success
- : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */),
- book_view);
-
- if (!pas_backend_is_loaded (backend))
- return;
+ int db_error = 0;
+ DBT id_dbt, vcard_dbt;
+ char *filename;
+ EDbHash *ehash;
+ GList *i, *v;
+ DB *db = bf->priv->file_db;
+ DBC *dbc;
+ GList *changes = NULL;
+ PASBackendFileChangeContext ctx;
+ PASBackendSyncStatus result;
- iterator = e_list_get_iterator(bf->priv->book_views);
- e_iterator_last(iterator);
- pas_backend_file_search (bf, book, e_iterator_get(iterator), FALSE);
- g_object_unref(iterator);
-}
+ memset (&id_dbt, 0, sizeof (id_dbt));
+ memset (&vcard_dbt, 0, sizeof (vcard_dbt));
-static void
-pas_backend_file_process_get_completion_view (PASBackend *backend,
- PASBook *book,
- PASGetCompletionViewRequest *req)
-{
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- PASBookView *book_view;
- PASBackendFileBookView view;
- EIterator *iterator;
+ memset (&ctx, 0, sizeof (ctx));
- bonobo_object_ref(BONOBO_OBJECT(book));
+ ctx.db = db;
- book_view = pas_book_view_new (req->listener);
+ /* Find the changed ids */
+ filename = g_strdup_printf ("%s/%s" CHANGES_DB_SUFFIX, bf->priv->dirname, change_id);
+ ehash = e_dbhash_new (filename);
+ g_free (filename);
- g_object_weak_ref (G_OBJECT (book_view), view_destroy, book);
+ db_error = db->cursor (db, NULL, &dbc, 0);
- view.book_view = book_view;
- view.search = g_strdup (req->search);
- view.card_sexp = NULL;
- view.change_id = NULL;
- view.change_context = NULL;
+ if (db_error != 0) {
+ g_warning ("pas_backend_file_changes: error building list\n");
+ } else {
+ db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST);
- e_list_append(bf->priv->book_views, &view);
+ while (db_error == 0) {
- pas_book_respond_get_completion_view (book,
- (book_view != NULL
- ? GNOME_Evolution_Addressbook_BookListener_Success
- : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */),
- book_view);
+ /* don't include the version in the list of cards */
+ if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1
+ || strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
+ EContact *contact;
+ char *id = id_dbt.data;
+ char *vcard_string;
+
+ /* Remove fields the user can't change
+ * and can change without the rest of the
+ * card changing
+ */
+ contact = e_contact_new_from_vcard (vcard_dbt.data);
+#if notyet
+ g_object_set (card, "last_use", NULL, "use_score", 0.0, NULL);
+#endif
+ vcard_string = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ g_object_unref (contact);
+
+ /* check what type of change has occurred, if any */
+ switch (e_dbhash_compare (ehash, id, vcard_string)) {
+ case E_DBHASH_STATUS_SAME:
+ break;
+ case E_DBHASH_STATUS_NOT_FOUND:
+ ctx.add_cards = g_list_append (ctx.add_cards, vcard_string);
+ ctx.add_ids = g_list_append (ctx.add_ids, g_strdup(id));
+ break;
+ case E_DBHASH_STATUS_DIFFERENT:
+ ctx.mod_cards = g_list_append (ctx.mod_cards, vcard_string);
+ ctx.mod_ids = g_list_append (ctx.mod_ids, g_strdup(id));
+ break;
+ }
+ }
- if (!pas_backend_is_loaded (backend))
- return;
+ db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
+ }
+ dbc->c_close (dbc);
+ }
- iterator = e_list_get_iterator(bf->priv->book_views);
- e_iterator_last(iterator);
- pas_backend_file_search (bf, book, e_iterator_get(iterator), TRUE);
- g_object_unref(iterator);
-}
+ e_dbhash_foreach_key (ehash, (EDbHashFunc)pas_backend_file_changes_foreach_key, &ctx);
-static void
-pas_backend_file_process_get_changes (PASBackend *backend,
- PASBook *book,
- PASGetChangesRequest *req)
-{
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- PASBookView *book_view;
- PASBackendFileBookView view;
- PASBackendFileChangeContext ctx;
- EIterator *iterator;
-
- bonobo_object_ref(BONOBO_OBJECT(book));
-
- book_view = pas_book_view_new (req->listener);
-
- g_object_weak_ref (G_OBJECT (book_view), view_destroy, book);
-
- pas_book_respond_get_changes (book,
- (book_view != NULL
- ? GNOME_Evolution_Addressbook_BookListener_Success
- : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */),
- book_view);
-
- view.book_view = book_view;
- view.change_id = req->change_id;
- view.change_context = &ctx;
- ctx.db = bf->priv->file_db;
- ctx.add_cards = NULL;
- ctx.add_ids = NULL;
- ctx.mod_cards = NULL;
- ctx.mod_ids = NULL;
- ctx.del_ids = NULL;
- view.search = NULL;
- view.card_sexp = NULL;
-
- e_list_append(bf->priv->book_views, &view);
+ /* Send the changes */
+ if (db_error != DB_NOTFOUND) {
+ g_warning ("pas_backend_file_changes: error building list\n");
+ *changes_out = NULL;
+ result = GNOME_Evolution_Addressbook_OtherError;
+ }
+ else {
+ /* Update the hash and build our changes list */
+ for (i = ctx.add_ids, v = ctx.add_cards; i != NULL; i = i->next, v = v->next){
+ char *id = i->data;
+ char *vcard = v->data;
+
+ e_dbhash_add (ehash, id, vcard);
+ changes = g_list_prepend (changes,
+ pas_backend_change_add_new (vcard));
+
+ g_free (i->data);
+ g_free (v->data);
+ }
+ for (i = ctx.mod_ids, v = ctx.mod_cards; i != NULL; i = i->next, v = v->next){
+ char *id = i->data;
+ char *vcard = v->data;
+
+ e_dbhash_add (ehash, id, vcard);
+ changes = g_list_prepend (changes,
+ pas_backend_change_modify_new (vcard));
+
+ g_free (i->data);
+ g_free (v->data);
+ }
+ for (i = ctx.del_ids; i != NULL; i = i->next){
+ char *id = i->data;
+
+ e_dbhash_remove (ehash, id);
+ changes = g_list_prepend (changes,
+ pas_backend_change_delete_new (id));
+ g_free (i->data);
+ }
- if (!pas_backend_is_loaded (backend))
- return;
+ e_dbhash_write (ehash);
- iterator = e_list_get_iterator(bf->priv->book_views);
- e_iterator_last(iterator);
- pas_backend_file_changes (bf, book, e_iterator_get(iterator));
- g_object_unref(iterator);
-}
+ result = GNOME_Evolution_Addressbook_Success;
+ *changes_out = changes;
+ }
-static void
-pas_backend_file_process_check_connection (PASBackend *backend,
- PASBook *book,
- PASCheckConnectionRequest *req)
-{
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
+ e_dbhash_destroy (ehash);
- pas_book_report_connection (book, bf->priv->file_db != NULL);
+ return GNOME_Evolution_Addressbook_Success;
}
static char *
pas_backend_file_extract_path_from_uri (const char *uri)
{
- g_assert (strncasecmp (uri, "file:", 5) == 0);
+ g_assert (strncasecmp (uri, "file://", 7) == 0);
- return g_strdup (uri + 5);
+ return g_strdup (uri + 7);
}
-static void
-pas_backend_file_process_authenticate_user (PASBackend *backend,
- PASBook *book,
- PASAuthenticateUserRequest *req)
+static PASBackendSyncStatus
+pas_backend_file_authenticate_user (PASBackendSync *backend,
+ PASBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method)
{
- pas_book_respond_authenticate_user (book,
- GNOME_Evolution_Addressbook_BookListener_Success);
+ return GNOME_Evolution_Addressbook_Success;
}
-static void
-pas_backend_file_process_get_supported_fields (PASBackend *backend,
- PASBook *book,
- PASGetSupportedFieldsRequest *req)
+static PASBackendSyncStatus
+pas_backend_file_get_supported_fields (PASBackendSync *backend,
+ PASBook *book,
+ GList **fields_out)
{
- EList *fields = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL);
- ECardSimple *simple;
- ECard *card;
+ GList *fields = NULL;
int i;
- /* we support everything, so instantiate an e-card, and loop
- through all fields, adding their ecard_fields. */
+ /* XXX we need a way to say "we support everything", since the
+ file backend does */
+ for (i = 1; i < E_CONTACT_FIELD_LAST; i ++)
+ fields = g_list_append (fields, g_strdup (e_contact_field_name (i)));
- card = e_card_new ("");
- simple = e_card_simple_new (card);
-
- for (i = 0; i < E_CARD_SIMPLE_FIELD_LAST; i ++)
- e_list_append (fields, e_card_simple_get_ecard_field (simple, i));
-
- g_object_unref (card);
- g_object_unref (simple);
-
- pas_book_respond_get_supported_fields (book,
- GNOME_Evolution_Addressbook_BookListener_Success,
- fields);
+ *fields_out = fields;
+ return GNOME_Evolution_Addressbook_Success;
}
/*
@@ -1273,9 +757,9 @@ pas_backend_file_upgrade_db (PASBackendFile *bf, char *old_version)
while (db_error == 0) {
if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1
|| strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
- ECard *card;
+ EContact *contact;
- card = e_card_new (vcard_dbt.data);
+ contact = e_contact_new_from_vcard (vcard_dbt.data);
/* the cards we're looking for are
created with a normal id dbt, but
@@ -1283,12 +767,12 @@ pas_backend_file_upgrade_db (PASBackendFile *bf, char *old_version)
to something that doesn't match.
so, we need to modify the card to
have the same id as the the dbt. */
- if (strcmp (id_dbt.data, e_card_get_id (card))) {
+ if (strcmp (id_dbt.data, e_contact_get_const (contact, E_CONTACT_UID))) {
char *vcard;
- e_card_set_id (card, id_dbt.data);
+ e_contact_set (contact, E_CONTACT_UID, id_dbt.data);
- vcard = e_card_get_vcard (card);
+ vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
string_to_dbt (vcard, &vcard_dbt);
db_error = db->put (db, NULL,
@@ -1300,7 +784,7 @@ pas_backend_file_upgrade_db (PASBackendFile *bf, char *old_version)
card_failed++;
}
- g_object_unref (card);
+ g_object_unref (contact);
}
db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
@@ -1352,30 +836,21 @@ pas_backend_file_maybe_upgrade_db (PASBackendFile *bf)
return ret_val;
}
-#define INITIAL_VCARD "BEGIN:VCARD\n\
-X-EVOLUTION-FILE-AS:Ximian, Inc.\n\
-LABEL;WORK;QUOTED-PRINTABLE:401 Park Drive 3 West=0ABoston, MA 02215=0AUSA\n\
-TEL;WORK;VOICE:(617) 375-3800\n\
-TEL;WORK;FAX:(617) 236-8630\n\
-EMAIL;INTERNET:hello@ximian.com\n\
-URL:www.ximian.com/\n\
-ORG:Ximian, Inc.;\n\
-NOTE:Welcome to the Ximian Addressbook.\n\
-END:VCARD"
-
-static GNOME_Evolution_Addressbook_BookListener_CallStatus
+#include "ximian-vcard.h"
+
+static GNOME_Evolution_Addressbook_CallStatus
pas_backend_file_load_uri (PASBackend *backend,
- const char *uri)
+ const char *uri,
+ gboolean only_if_exists)
{
PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- char *filename;
+ char *dirname, *filename;
gboolean writable = FALSE;
int db_error;
DB *db;
int major, minor, patch;
time_t db_mtime;
struct stat sb;
- char *summary_filename;
g_free(bf->priv->uri);
bf->priv->uri = g_strdup (uri);
@@ -1386,18 +861,19 @@ pas_backend_file_load_uri (PASBackend *backend,
minor != 1 ||
patch != 17) {
g_warning ("Wrong version of libdb.");
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
}
- filename = pas_backend_file_extract_path_from_uri (uri);
+ dirname = pas_backend_file_extract_path_from_uri (uri);
+ filename = g_build_filename (dirname, "addressbook.db", NULL);
db_error = e_db3_utils_maybe_recover (filename);
if (db_error != 0)
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
db_error = db_create (&db, NULL, 0);
if (db_error != 0)
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
db_error = db->open (db, filename, NULL, DB_HASH, 0, 0666);
@@ -1405,7 +881,7 @@ pas_backend_file_load_uri (PASBackend *backend,
db_error = e_db3_utils_upgrade_format (filename);
if (db_error != 0)
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
db_error = db->open (db, filename, NULL, DB_HASH, 0, 0666);
}
@@ -1418,23 +894,27 @@ pas_backend_file_load_uri (PASBackend *backend,
db_error = db->open (db, filename, NULL, DB_HASH, DB_RDONLY, 0666);
if (db_error != 0) {
- db_error = db->open (db, filename, NULL, DB_HASH, DB_CREATE, 0666);
-
- if (db_error == 0) {
- char *create_initial_file;
- char *dir;
+ int rv;
+
+ /* the database didn't exist, so we create the
+ directory then the .db */
+ rv = mkdir (dirname, 0777);
+ if (rv == -1 && errno != EEXIST) {
+ g_warning ("failed to make directory %s: %s", dirname, strerror (errno));
+ if (errno == EACCES || errno == EPERM)
+ return GNOME_Evolution_Addressbook_PermissionDenied;
+ else
+ return GNOME_Evolution_Addressbook_OtherError;
+ }
- dir = g_path_get_dirname(filename);
- create_initial_file = g_build_filename (dir, "create-initial", NULL);
+ db_error = db->open (db, filename, NULL, DB_HASH, DB_CREATE, 0666);
- if (g_file_test(create_initial_file, G_FILE_TEST_EXISTS)) {
- char *id;
- id = do_create(backend, INITIAL_VCARD, NULL);
- g_free (id);
- }
+ if (db_error == 0 && !only_if_exists) {
+ EContact *contact;
- g_free(create_initial_file);
- g_free(dir);
+ contact = do_create(bf, XIMIAN_VCARD);
+ /* XXX check errors here */
+ g_object_unref (contact);
writable = TRUE;
}
@@ -1443,28 +923,30 @@ pas_backend_file_load_uri (PASBackend *backend,
if (db_error != 0) {
bf->priv->file_db = NULL;
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
}
if (!pas_backend_file_maybe_upgrade_db (bf)) {
db->close (db, 0);
bf->priv->file_db = NULL;
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
}
+ g_free (bf->priv->dirname);
g_free (bf->priv->filename);
+ bf->priv->dirname = dirname;
bf->priv->filename = filename;
if (stat (bf->priv->filename, &sb) == -1) {
db->close (db, 0);
bf->priv->file_db = NULL;
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
}
db_mtime = sb.st_mtime;
- summary_filename = g_strconcat (bf->priv->filename, ".summary", NULL);
- bf->priv->summary = pas_backend_summary_new (summary_filename, SUMMARY_FLUSH_TIMEOUT);
- g_free (summary_filename);
+ g_free (bf->priv->summary_filename);
+ bf->priv->summary_filename = g_strconcat (bf->priv->filename, ".summary", NULL);
+ bf->priv->summary = pas_backend_summary_new (bf->priv->summary_filename, SUMMARY_FLUSH_TIMEOUT);
if (pas_backend_summary_is_up_to_date (bf->priv->summary, db_mtime) == FALSE
|| pas_backend_summary_load (bf->priv->summary) == FALSE ) {
@@ -1473,20 +955,76 @@ pas_backend_file_load_uri (PASBackend *backend,
pas_backend_set_is_loaded (backend, TRUE);
pas_backend_set_is_writable (backend, writable);
- return GNOME_Evolution_Addressbook_BookListener_Success;
+
+ return GNOME_Evolution_Addressbook_Success;
}
-/* Get_uri handler for the addressbook file backend */
-static const char *
-pas_backend_file_get_uri (PASBackend *backend)
+static int
+select_changes (const struct dirent *d)
{
- PASBackendFile *bf;
+ char *p;
+
+ if (strlen (d->d_name) < strlen (CHANGES_DB_SUFFIX))
+ return 0;
+
+ p = strstr (d->d_name, CHANGES_DB_SUFFIX);
+ if (!p)
+ return 0;
+
+ if (strlen (p) != strlen (CHANGES_DB_SUFFIX))
+ return 0;
+
+ return 1;
+}
+
+static PASBackendSyncStatus
+pas_backend_file_remove (PASBackendSync *backend,
+ PASBook *book)
+{
+ PASBackendFile *bf = PAS_BACKEND_FILE (backend);
+ struct dirent **namelist;
+ int n;
+
+ if (-1 == unlink (bf->priv->filename)) {
+ if (errno == EACCES || errno == EPERM)
+ return GNOME_Evolution_Addressbook_PermissionDenied;
+ else
+ return GNOME_Evolution_Addressbook_OtherError;
+ }
- bf = PAS_BACKEND_FILE (backend);
+ /* unref the summary before we remove the file so it's not written out again */
+ g_object_unref (bf->priv->summary);
+ bf->priv->summary = NULL;
+ if (-1 == unlink (bf->priv->filename))
+ g_warning ("failed to remove summary file `%s`: %s", bf->priv->summary_filename, strerror (errno));
+
+ /* scandir to select all the "*.changes.db" files, then remove them */
+ n = scandir (bf->priv->dirname,
+ &namelist, select_changes, alphasort);
+ if (n < 0) {
+ g_warning ("scandir of directory `%s' failed: %s", bf->priv->dirname, strerror (errno));
+ }
+ else {
+ while (n -- ) {
+ char *full_path = g_build_filename (bf->priv->dirname, namelist[n]->d_name, NULL);
+ if (-1 == unlink (full_path)) {
+ g_warning ("failed to remove change db `%s': %s", full_path, strerror (errno));
+ }
+ g_free (full_path);
+ free (namelist[n]);
+ }
+ free (namelist);
+ }
- g_assert (bf->priv->uri != NULL);
+ if (-1 == rmdir (bf->priv->dirname))
+ g_warning ("failed to remove directory `%s`: %s", bf->priv->dirname, strerror (errno));
- return bf->priv->uri;
+ /* we may not have actually succeeded in removing the
+ backend's files/dirs, but there's nothing we can do about
+ it here.. the only time we should return failure is if we
+ failed to remove the actual data. a failure should mean
+ that the addressbook is still valid */
+ return GNOME_Evolution_Addressbook_Success;
}
static char *
@@ -1495,6 +1033,12 @@ pas_backend_file_get_static_capabilities (PASBackend *backend)
return g_strdup("local,do-initial-query,bulk-removes");
}
+static GNOME_Evolution_Addressbook_CallStatus
+pas_backend_file_cancel_operation (PASBackend *backend, PASBook *book)
+{
+ return GNOME_Evolution_Addressbook_CouldNotCancel;
+}
+
static gboolean
pas_backend_file_construct (PASBackendFile *backend)
{
@@ -1534,11 +1078,12 @@ pas_backend_file_dispose (GObject *object)
bf = PAS_BACKEND_FILE (object);
if (bf->priv) {
- g_object_unref(bf->priv->book_views);
if (bf->priv->summary)
g_object_unref(bf->priv->summary);
g_free (bf->priv->uri);
g_free (bf->priv->filename);
+ g_free (bf->priv->dirname);
+ g_free (bf->priv->summary_filename);
g_free (bf->priv);
bf->priv = NULL;
@@ -1551,28 +1096,29 @@ static void
pas_backend_file_class_init (PASBackendFileClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- PASBackendClass *parent_class;
+ PASBackendSyncClass *sync_class;
+ PASBackendClass *backend_class;
pas_backend_file_parent_class = g_type_class_peek_parent (klass);
- parent_class = PAS_BACKEND_CLASS (klass);
+ sync_class = PAS_BACKEND_SYNC_CLASS (klass);
+ backend_class = PAS_BACKEND_CLASS (klass);
/* Set the virtual methods. */
- parent_class->load_uri = pas_backend_file_load_uri;
- parent_class->get_uri = pas_backend_file_get_uri;
- parent_class->get_static_capabilities = pas_backend_file_get_static_capabilities;
-
- parent_class->create_card = pas_backend_file_process_create_card;
- parent_class->remove_cards = pas_backend_file_process_remove_cards;
- parent_class->modify_card = pas_backend_file_process_modify_card;
- parent_class->check_connection = pas_backend_file_process_check_connection;
- parent_class->get_vcard = pas_backend_file_process_get_vcard;
- parent_class->get_cursor = pas_backend_file_process_get_cursor;
- parent_class->get_book_view = pas_backend_file_process_get_book_view;
- parent_class->get_completion_view = pas_backend_file_process_get_completion_view;
- parent_class->get_changes = pas_backend_file_process_get_changes;
- parent_class->authenticate_user = pas_backend_file_process_authenticate_user;
- parent_class->get_supported_fields = pas_backend_file_process_get_supported_fields;
+ backend_class->load_uri = pas_backend_file_load_uri;
+ backend_class->get_static_capabilities = pas_backend_file_get_static_capabilities;
+ backend_class->start_book_view = pas_backend_file_start_book_view;
+ backend_class->cancel_operation = pas_backend_file_cancel_operation;
+
+ sync_class->remove_sync = pas_backend_file_remove;
+ sync_class->create_contact_sync = pas_backend_file_create_contact;
+ sync_class->remove_contacts_sync = pas_backend_file_remove_contacts;
+ sync_class->modify_contact_sync = pas_backend_file_modify_contact;
+ sync_class->get_contact_sync = pas_backend_file_get_contact;
+ sync_class->get_contact_list_sync = pas_backend_file_get_contact_list;
+ sync_class->get_changes_sync = pas_backend_file_get_changes;
+ sync_class->authenticate_user_sync = pas_backend_file_authenticate_user;
+ sync_class->get_supported_fields_sync = pas_backend_file_get_supported_fields;
object_class->dispose = pas_backend_file_dispose;
}
@@ -1583,7 +1129,6 @@ pas_backend_file_init (PASBackendFile *backend)
PASBackendFilePrivate *priv;
priv = g_new0 (PASBackendFilePrivate, 1);
- priv->book_views = e_list_new((EListCopyFunc) pas_backend_file_book_view_copy, (EListFreeFunc) pas_backend_file_book_view_free, NULL);
priv->uri = NULL;
backend->priv = priv;
@@ -1610,7 +1155,7 @@ pas_backend_file_get_type (void)
(GInstanceInitFunc) pas_backend_file_init
};
- type = g_type_register_static (PAS_TYPE_BACKEND, "PASBackendFile", &info, 0);
+ type = g_type_register_static (PAS_TYPE_BACKEND_SYNC, "PASBackendFile", &info, 0);
}
return type;
diff --git a/addressbook/backend/pas/pas-backend-file.h b/addressbook/backend/pas/pas-backend-file.h
index fd98d2cdd5..6e1a77b119 100644
--- a/addressbook/backend/pas/pas-backend-file.h
+++ b/addressbook/backend/pas/pas-backend-file.h
@@ -5,7 +5,7 @@
#ifndef __PAS_BACKEND_FILE_H__
#define __PAS_BACKEND_FILE_H__
-#include "pas-backend.h"
+#include "pas-backend-sync.h"
#define PAS_TYPE_BACKEND_FILE (pas_backend_file_get_type ())
#define PAS_BACKEND_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_FILE, PASBackendFile))
@@ -17,12 +17,12 @@
typedef struct _PASBackendFilePrivate PASBackendFilePrivate;
typedef struct {
- PASBackend parent_object;
+ PASBackendSync parent_object;
PASBackendFilePrivate *priv;
} PASBackendFile;
typedef struct {
- PASBackendClass parent_class;
+ PASBackendSyncClass parent_class;
} PASBackendFileClass;
PASBackend *pas_backend_file_new (void);
diff --git a/addressbook/backend/pas/pas-backend-ldap.c b/addressbook/backend/pas/pas-backend-ldap.c
index 1e8677e559..9c44e9983f 100644
--- a/addressbook/backend/pas/pas-backend-ldap.c
+++ b/addressbook/backend/pas/pas-backend-ldap.c
@@ -34,13 +34,13 @@
#include <sys/time.h>
#include <e-util/e-sexp.h>
-#include <ebook/e-card-simple.h>
+#include <ebook/e-contact.h>
#include <libgnome/gnome-i18n.h>
#include "pas-backend-ldap.h"
#include "pas-backend-card-sexp.h"
#include "pas-book.h"
-#include "pas-card-cursor.h"
+#include "pas-book-view.h"
#include <stdlib.h>
@@ -59,14 +59,6 @@ typedef enum {
/* timeout for ldap_result */
#define LDAP_RESULT_TIMEOUT_MILLIS 10
-/* smart grouping stuff */
-#define GROUPING_INITIAL_SIZE 1
-#define GROUPING_MAXIMUM_SIZE 200
-
-/* the next two are in milliseconds */
-#define GROUPING_MINIMUM_WAIT 0 /* we never send updates faster than this, to avoid totally spamming the UI */
-#define GROUPING_MAXIMUM_WAIT 250 /* we always send updates (if there are pending cards) when we hit this */
-
#define TV_TO_MILLIS(timeval) ((timeval).tv_sec * 1000 + (timeval).tv_usec / 1000)
/* the objectClasses we need */
@@ -107,12 +99,10 @@ struct _PASBackendLDAPPrivate {
was not built into openldap. */
PASBackendLDAPUseTLS use_tls;
- EList *book_views;
-
LDAP *ldap;
- EList *supported_fields;
- EList *supported_auth_methods;
+ GList *supported_fields;
+ GList *supported_auth_methods;
/* whether or not there's support for the objectclass we need
to store all our additional fields */
@@ -138,7 +128,6 @@ struct _PASBackendLDAPBookView {
PASBookView *book_view;
PASBackendLDAPPrivate *blpriv;
gchar *search;
- PASBackendCardSExp *card_sexp;
int limit;
LDAPOp *search_op;
@@ -160,122 +149,129 @@ static void ldap_op_add (LDAPOp *op, PASBackend *backend, PASBook *book,
PASBookView *view, int id, LDAPOpHandler handler, LDAPOpDtor dtor);
static void ldap_op_finished (LDAPOp *op);
-static void ldap_search_op_timeout (LDAPOp *op, glong cur_millis);
-
static gboolean poll_ldap (PASBackendLDAP *bl);
-static ECardSimple *build_card_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasses);
+static EContact *build_contact_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasses);
+
+static void email_populate (EContact *contact, char **values);
+struct berval** email_ber (EContact *contact);
+static gboolean email_compare (EContact *contact1, EContact *contact2);
-static void email_populate (ECardSimple *card, char **values);
-struct berval** email_ber (ECardSimple *card);
-static gboolean email_compare (ECardSimple *ecard1, ECardSimple *ecard2);
+static void homephone_populate (EContact *contact, char **values);
+struct berval** homephone_ber (EContact *contact);
+static gboolean homephone_compare (EContact *contact1, EContact *contact2);
-static void homephone_populate (ECardSimple *card, char **values);
-struct berval** homephone_ber (ECardSimple *card);
-static gboolean homephone_compare (ECardSimple *ecard1, ECardSimple *ecard2);
+static void business_populate (EContact *contact, char **values);
+struct berval** business_ber (EContact *contact);
+static gboolean business_compare (EContact *contact1, EContact *contact2);
-static void business_populate (ECardSimple *card, char **values);
-struct berval** business_ber (ECardSimple *card);
-static gboolean business_compare (ECardSimple *ecard1, ECardSimple *ecard2);
+static void anniversary_populate (EContact *contact, char **values);
+struct berval** anniversary_ber (EContact *contact);
+static gboolean anniversary_compare (EContact *contact1, EContact *contact2);
-static void anniversary_populate (ECardSimple *card, char **values);
-struct berval** anniversary_ber (ECardSimple *card);
-static gboolean anniversary_compare (ECardSimple *ecard1, ECardSimple *ecard2);
+static void birthday_populate (EContact *contact, char **values);
+struct berval** birthday_ber (EContact *contact);
+static gboolean birthday_compare (EContact *contact1, EContact *contact2);
-static void birthday_populate (ECardSimple *card, char **values);
-struct berval** birthday_ber (ECardSimple *card);
-static gboolean birthday_compare (ECardSimple *ecard1, ECardSimple *ecard2);
+static void category_populate (EContact *contact, char **values);
+struct berval** category_ber (EContact *contact);
+static gboolean category_compare (EContact *contact1, EContact *contact2);
-static void category_populate (ECardSimple *card, char **values);
-struct berval** category_ber (ECardSimple *card);
-static gboolean category_compare (ECardSimple *ecard1, ECardSimple *ecard2);
+static void photo_populate (EContact *contact, struct berval **ber_values);
struct prop_info {
- ECardSimpleField field_id;
- char *query_prop;
+ EContactField field_id;
char *ldap_attr;
#define PROP_TYPE_STRING 0x01
-#define PROP_TYPE_COMPLEX 0x02
-#define PROP_DN 0x04
-#define PROP_EVOLVE 0x08
+#define PROP_TYPE_COMPLEX 0x02
+#define PROP_TYPE_BINARY 0x04
+#define PROP_DN 0x08
+#define PROP_EVOLVE 0x10
+#define PROP_WRITE_ONLY 0x20
int prop_type;
/* the remaining items are only used for the TYPE_COMPLEX props */
- /* used when reading from the ldap server populates ECard with the values in **values. */
- void (*populate_ecard_func)(ECardSimple *card, char **values);
+ /* used when reading from the ldap server populates EContact with the values in **values. */
+ void (*populate_contact_func)(EContact *contact, char **values);
/* used when writing to an ldap server. returns a NULL terminated array of berval*'s */
- struct berval** (*ber_func)(ECardSimple *card);
+ struct berval** (*ber_func)(EContact *contact);
/* used to compare list attributes */
- gboolean (*compare_func)(ECardSimple *card1, ECardSimple *card2);
+ gboolean (*compare_func)(EContact *contact1, EContact *contact2);
+
+ void (*binary_populate_contact_func)(EContact *contact, struct berval **ber_values);
} prop_info[] = {
-#define COMPLEX_PROP(fid,q,a,ctor,ber,cmp) {fid, q, a, PROP_TYPE_COMPLEX, ctor, ber, cmp}
-#define E_COMPLEX_PROP(fid,q,a,ctor,ber,cmp) {fid, q, a, PROP_TYPE_COMPLEX | PROP_EVOLVE, ctor, ber, cmp}
-#define STRING_PROP(fid,q,a) {fid, q, a, PROP_TYPE_STRING}
-#define E_STRING_PROP(fid,q,a) {fid, q, a, PROP_TYPE_STRING | PROP_EVOLVE}
+#define BINARY_PROP(fid,a,ctor,ber,cmp) {fid, a, PROP_TYPE_BINARY, NULL, ber, cmp, ctor}
+#define COMPLEX_PROP(fid,a,ctor,ber,cmp) {fid, a, PROP_TYPE_COMPLEX, ctor, ber, cmp}
+#define E_COMPLEX_PROP(fid,a,ctor,ber,cmp) {fid, a, PROP_TYPE_COMPLEX | PROP_EVOLVE, ctor, ber, cmp}
+#define STRING_PROP(fid,a) {fid, a, PROP_TYPE_STRING}
+#define WRITE_ONLY_STRING_PROP(fid,a) {fid, a, PROP_TYPE_STRING | PROP_WRITE_ONLY}
+#define E_STRING_PROP(fid,a) {fid, a, PROP_TYPE_STRING | PROP_EVOLVE}
/* name fields */
- STRING_PROP (E_CARD_SIMPLE_FIELD_FULL_NAME, "full_name", "cn" ),
- STRING_PROP (E_CARD_SIMPLE_FIELD_FAMILY_NAME, "family_name", "sn" ),
+ STRING_PROP (E_CONTACT_FULL_NAME, "cn" ),
+ WRITE_ONLY_STRING_PROP (E_CONTACT_FAMILY_NAME, "sn" ),
/* email addresses */
- COMPLEX_PROP (E_CARD_SIMPLE_FIELD_EMAIL, "email", "mail", email_populate, email_ber, email_compare),
+ COMPLEX_PROP (E_CONTACT_EMAIL, "mail", email_populate, email_ber, email_compare),
/* phone numbers */
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_PRIMARY, "primary_phone", "primaryPhone"),
- COMPLEX_PROP (E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, "business_phone", "telephoneNumber", business_populate, business_ber, business_compare),
- COMPLEX_PROP (E_CARD_SIMPLE_FIELD_PHONE_HOME, "home_phone", "homePhone", homephone_populate, homephone_ber, homephone_compare),
- STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_MOBILE, "mobile_phone", "mobile"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_CAR, "car_phone", "carPhone"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_FAX, "business_fax", "facsimileTelephoneNumber"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_HOME_FAX, "home_fax", "homeFacsimileTelephoneNumber"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_OTHER, "other_phone", "otherPhone"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_OTHER_FAX, "other_fax", "otherFacsimileTelephoneNumber"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_ISDN, "isdn", "internationaliSDNNumber"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_PAGER, "pager", "pager"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_RADIO, "radio", "radio"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_TELEX, "telex", "telex"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_ASSISTANT, "assistant_phone", "assistantPhone"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_COMPANY, "company_phone", "companyPhone"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_CALLBACK, "callback_phone", "callbackPhone"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_PHONE_TTYTDD, "tty", "tty"),
+ E_STRING_PROP (E_CONTACT_PHONE_PRIMARY, "primaryPhone"),
+ COMPLEX_PROP (E_CONTACT_PHONE_BUSINESS, "telephoneNumber", business_populate, business_ber, business_compare),
+ COMPLEX_PROP (E_CONTACT_PHONE_HOME, "homePhone", homephone_populate, homephone_ber, homephone_compare),
+ STRING_PROP (E_CONTACT_PHONE_MOBILE, "mobile"),
+ E_STRING_PROP (E_CONTACT_PHONE_CAR, "carPhone"),
+ STRING_PROP (E_CONTACT_PHONE_BUSINESS_FAX, "facsimileTelephoneNumber"),
+ E_STRING_PROP (E_CONTACT_PHONE_HOME_FAX, "homeFacsimileTelephoneNumber"),
+ E_STRING_PROP (E_CONTACT_PHONE_OTHER, "otherPhone"),
+ E_STRING_PROP (E_CONTACT_PHONE_OTHER_FAX, "otherFacsimileTelephoneNumber"),
+ STRING_PROP (E_CONTACT_PHONE_ISDN, "internationaliSDNNumber"),
+ STRING_PROP (E_CONTACT_PHONE_PAGER, "pager"),
+ E_STRING_PROP (E_CONTACT_PHONE_RADIO, "radio"),
+ E_STRING_PROP (E_CONTACT_PHONE_TELEX, "telex"),
+ E_STRING_PROP (E_CONTACT_PHONE_ASSISTANT, "assistantPhone"),
+ E_STRING_PROP (E_CONTACT_PHONE_COMPANY, "companyPhone"),
+ E_STRING_PROP (E_CONTACT_PHONE_CALLBACK, "callbackPhone"),
+ E_STRING_PROP (E_CONTACT_PHONE_TTYTDD, "tty"),
/* org information */
- STRING_PROP (E_CARD_SIMPLE_FIELD_ORG, "org", "o"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_ORG_UNIT, "org_unit", "ou"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_OFFICE, "office", "roomNumber"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_TITLE, "title", "title"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_ROLE, "role", "businessRole"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_MANAGER, "manager", "managerName"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_ASSISTANT, "assistant", "assistantName"),
+ STRING_PROP (E_CONTACT_ORG, "o"),
+ STRING_PROP (E_CONTACT_ORG_UNIT, "ou"),
+ STRING_PROP (E_CONTACT_OFFICE, "roomNumber"),
+ STRING_PROP (E_CONTACT_TITLE, "title"),
+ E_STRING_PROP (E_CONTACT_ROLE, "businessRole"),
+ E_STRING_PROP (E_CONTACT_MANAGER, "managerName"),
+ E_STRING_PROP (E_CONTACT_ASSISTANT, "assistantName"),
/* addresses */
- STRING_PROP (E_CARD_SIMPLE_FIELD_ADDRESS_BUSINESS, "business_address", "postalAddress"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_ADDRESS_HOME, "home_address", "homePostalAddress"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_ADDRESS_OTHER, "other_address", "otherPostalAddress"),
+ STRING_PROP (E_CONTACT_ADDRESS_LABEL_WORK, "postalAddress"),
+ STRING_PROP (E_CONTACT_ADDRESS_LABEL_HOME, "homePostalAddress"),
+ E_STRING_PROP (E_CONTACT_ADDRESS_LABEL_OTHER, "otherPostalAddress"),
+
+ /* photos */
+ BINARY_PROP (E_CONTACT_PHOTO, "jpegPhoto", photo_populate, NULL/*XXX*/, NULL/*XXX*/),
/* misc fields */
- STRING_PROP (E_CARD_SIMPLE_FIELD_URL, "url", "labeledURI"),
+ STRING_PROP (E_CONTACT_HOMEPAGE_URL, "labeledURI"),
/* map nickname to displayName */
- STRING_PROP (E_CARD_SIMPLE_FIELD_NICKNAME, "nickname", "displayName"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_SPOUSE, "spouse", "spouseName"),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_NOTE, "note", "note"),
- E_COMPLEX_PROP (E_CARD_SIMPLE_FIELD_ANNIVERSARY, "anniversary", "anniversary", anniversary_populate, anniversary_ber, anniversary_compare),
- E_COMPLEX_PROP (E_CARD_SIMPLE_FIELD_BIRTH_DATE, "birth_date", "birthDate", birthday_populate, birthday_ber, birthday_compare),
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_MAILER, "mailer", "mailer"),
-
- E_STRING_PROP (E_CARD_SIMPLE_FIELD_FILE_AS, "file_as", "fileAs"),
- E_COMPLEX_PROP (E_CARD_SIMPLE_FIELD_CATEGORIES, "categories", "category", category_populate, category_ber, category_compare),
-
- STRING_PROP (E_CARD_SIMPLE_FIELD_CALURI, "caluri", "calCalURI"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_FBURL, "fburl", "calFBURL"),
- STRING_PROP (E_CARD_SIMPLE_FIELD_ICSCALENDAR, "icscalendar", "icsCalendar"),
-
-/* E_CARD_SIMPLE_FIELD_NAME_OR_ORG, */
-
+ STRING_PROP (E_CONTACT_NICKNAME, "displayName"),
+ E_STRING_PROP (E_CONTACT_SPOUSE, "spouseName"),
+ E_STRING_PROP (E_CONTACT_NOTE, "note"),
+ E_COMPLEX_PROP (E_CONTACT_ANNIVERSARY, "anniversary", anniversary_populate, anniversary_ber, anniversary_compare),
+ E_COMPLEX_PROP (E_CONTACT_BIRTH_DATE, "birthDate", birthday_populate, birthday_ber, birthday_compare),
+ E_STRING_PROP (E_CONTACT_MAILER, "mailer"),
+
+ E_STRING_PROP (E_CONTACT_FILE_AS, "fileAs"),
+#if notyet
+ E_COMPLEX_PROP (E_CONTACT_CATEGORIES, "category", category_populate, category_ber, category_compare),
+
+ STRING_PROP (E_CONTACT_CALURI, "calCalURI"),
+ STRING_PROP (E_CONTACT_FBURL, "calFBURL"),
+ STRING_PROP (E_CONTACT_ICSCALENDAR, "icsCalendar"),
+#endif
#undef E_STRING_PROP
#undef STRING_PROP
@@ -285,6 +281,7 @@ struct prop_info {
static int num_prop_infos = sizeof(prop_info) / sizeof(prop_info[0]);
+#if 0
static void
remove_view (int msgid, LDAPOp *op, PASBookView *view)
{
@@ -321,7 +318,6 @@ view_destroy(gpointer data, GObject *where_object_was)
/* free up the view structure */
g_free (view->search);
- g_object_unref (view->card_sexp);
g_free (view);
/* and remove it from our list */
@@ -349,6 +345,7 @@ view_destroy(gpointer data, GObject *where_object_was)
g_object_unref (iter);
}
+#endif
static void
book_view_notify_status (PASBookView *view, const char *status)
@@ -361,6 +358,7 @@ book_view_notify_status (PASBookView *view, const char *status)
static PASBookView*
find_book_view (PASBackendLDAP *bl)
{
+#if 0
EIterator *iter = e_list_get_iterator (bl->priv->book_views);
PASBookView *rv = NULL;
@@ -374,6 +372,7 @@ find_book_view (PASBackendLDAP *bl)
g_object_unref (iter);
return rv;
+#endif
}
static void
@@ -381,21 +380,21 @@ add_to_supported_fields (PASBackendLDAP *bl, char **attrs, GHashTable *attr_hash
{
int i;
for (i = 0; attrs[i]; i ++) {
- char *query_prop = g_hash_table_lookup (attr_hash, attrs[i]);
+ char *query_prop = g_hash_table_lookup (attr_hash, g_strdup (attrs[i]));
if (query_prop) {
- e_list_append (bl->priv->supported_fields, query_prop);
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup (query_prop));
/* handle the list attributes here */
if (!strcmp (query_prop, "email")) {
- e_list_append (bl->priv->supported_fields, "email_2");
- e_list_append (bl->priv->supported_fields, "email_3");
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup ("email_2"));
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup ("email_3"));
}
else if (!strcmp (query_prop, "business_phone")) {
- e_list_append (bl->priv->supported_fields, "business_phone_2");
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup ("business_phone_2"));
}
else if (!strcmp (query_prop, "home_phone")) {
- e_list_append (bl->priv->supported_fields, "home_phone_2");
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup ("home_phone_2"));
}
}
}
@@ -408,7 +407,7 @@ add_oc_attributes_to_supported_fields (PASBackendLDAP *bl, LDAPObjectClass *oc)
GHashTable *attr_hash = g_hash_table_new (g_str_hash, g_str_equal);
for (i = 0; i < num_prop_infos; i ++)
- g_hash_table_insert (attr_hash, prop_info[i].ldap_attr, prop_info[i].query_prop);
+ g_hash_table_insert (attr_hash, prop_info[i].ldap_attr, (char*)e_contact_field_name (prop_info[i].field_id));
if (oc->oc_at_oids_must)
add_to_supported_fields (bl, oc->oc_at_oids_must, attr_hash);
@@ -591,22 +590,21 @@ query_ldap_root_dse (PASBackendLDAP *bl)
values = ldap_get_values (ldap, resp, "supportedSASLMechanisms");
if (values) {
char *auth_method;
- if (bl->priv->supported_auth_methods)
- g_object_unref (bl->priv->supported_auth_methods);
- bl->priv->supported_auth_methods = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL);
+ if (bl->priv->supported_auth_methods) {
+ g_list_foreach (bl->priv->supported_auth_methods, (GFunc)g_free, NULL);
+ g_list_free (bl->priv->supported_auth_methods);
+ }
+ bl->priv->supported_auth_methods = NULL;
auth_method = g_strdup_printf ("ldap/simple-binddn|%s", _("Using Distinguished Name (DN)"));
- e_list_append (bl->priv->supported_auth_methods, auth_method);
- g_free (auth_method);
+ bl->priv->supported_auth_methods = g_list_append (bl->priv->supported_auth_methods, auth_method);
auth_method = g_strdup_printf ("ldap/simple-email|%s", _("Using Email Address"));
- e_list_append (bl->priv->supported_auth_methods, auth_method);
- g_free (auth_method);
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_auth_methods, auth_method);
for (i = 0; values[i]; i++) {
auth_method = g_strdup_printf ("sasl/%s|%s", values[i], values[i]);
- e_list_append (bl->priv->supported_auth_methods, auth_method);
- g_free (auth_method);
+ bl->priv->supported_fields = g_list_append (bl->priv->supported_auth_methods, auth_method);
g_message ("supported SASL mechanism: %s", values[i]);
}
ldap_value_free (values);
@@ -633,7 +631,7 @@ query_ldap_root_dse (PASBackendLDAP *bl)
return LDAP_SUCCESS;
}
-static GNOME_Evolution_Addressbook_BookListener_CallStatus
+static GNOME_Evolution_Addressbook_CallStatus
pas_backend_ldap_connect (PASBackendLDAP *bl)
{
PASBackendLDAPPrivate *blpriv = bl->priv;
@@ -667,7 +665,7 @@ pas_backend_ldap_connect (PASBackendLDAP *bl)
g_message ("TLS not available (fatal version), v3 protocol could not be established (ldap_error 0x%02x)", ldap_error);
ldap_unbind (blpriv->ldap);
blpriv->ldap = NULL;
- return GNOME_Evolution_Addressbook_BookListener_TLSNotAvailable;
+ return GNOME_Evolution_Addressbook_TLSNotAvailable;
}
if (bl->priv->ldap_port == LDAPS_PORT && bl->priv->use_tls == PAS_BACKEND_LDAP_TLS_ALWAYS) {
@@ -681,7 +679,7 @@ pas_backend_ldap_connect (PASBackendLDAP *bl)
g_message ("TLS not available (fatal version), (ldap_error 0x%02x)", ldap_error);
ldap_unbind (blpriv->ldap);
blpriv->ldap = NULL;
- return GNOME_Evolution_Addressbook_BookListener_TLSNotAvailable;
+ return GNOME_Evolution_Addressbook_TLSNotAvailable;
}
else {
g_message ("TLS not available (ldap_error 0x%02x)", ldap_error);
@@ -700,7 +698,7 @@ pas_backend_ldap_connect (PASBackendLDAP *bl)
if (ldap_error == LDAP_SERVER_DOWN) {
/* we only want this to be fatal if the server is down. */
g_warning ("failed to bind anonymously while connecting (ldap_error 0x%02x)", ldap_error);
- return GNOME_Evolution_Addressbook_BookListener_RepositoryOffline;
+ return GNOME_Evolution_Addressbook_RepositoryOffline;
}
ldap_error = query_ldap_root_dse (bl);
@@ -722,7 +720,7 @@ pas_backend_ldap_connect (PASBackendLDAP *bl)
check_schema_support (bl);
pas_backend_set_is_loaded (PAS_BACKEND (bl), TRUE);
- return GNOME_Evolution_Addressbook_BookListener_Success;
+ return GNOME_Evolution_Addressbook_Success;
}
else
g_warning ("Failed to perform root dse query anonymously, (ldap_error 0x%02x)", ldap_error);
@@ -734,7 +732,7 @@ pas_backend_ldap_connect (PASBackendLDAP *bl)
blpriv->ldap_port,
blpriv->ldap_rootdn ? blpriv->ldap_rootdn : "");
blpriv->connected = FALSE;
- return GNOME_Evolution_Addressbook_BookListener_RepositoryOffline;
+ return GNOME_Evolution_Addressbook_RepositoryOffline;
}
static gboolean
@@ -742,14 +740,14 @@ pas_backend_ldap_reconnect (PASBackendLDAP *bl, PASBookView *book_view, int ldap
{
/* we need to reconnect if we were previously connected */
if (bl->priv->connected && ldap_status == LDAP_SERVER_DOWN) {
- GNOME_Evolution_Addressbook_BookListener_CallStatus status;
+ GNOME_Evolution_Addressbook_CallStatus status;
int ldap_error = LDAP_SUCCESS;
book_view_notify_status (book_view, _("Reconnecting to LDAP server..."));
status = pas_backend_ldap_connect (bl);
- if (status != GNOME_Evolution_Addressbook_BookListener_Success) {
+ if (status != GNOME_Evolution_Addressbook_Success) {
book_view_notify_status (book_view, "");
return FALSE;
}
@@ -836,27 +834,27 @@ static int
ldap_error_to_response (int ldap_error)
{
if (ldap_error == LDAP_SUCCESS)
- return GNOME_Evolution_Addressbook_BookListener_Success;
+ return GNOME_Evolution_Addressbook_Success;
else if (LDAP_NAME_ERROR (ldap_error))
- return GNOME_Evolution_Addressbook_BookListener_CardNotFound;
+ return GNOME_Evolution_Addressbook_ContactNotFound;
else if (ldap_error == LDAP_INSUFFICIENT_ACCESS)
- return GNOME_Evolution_Addressbook_BookListener_PermissionDenied;
+ return GNOME_Evolution_Addressbook_PermissionDenied;
else if (ldap_error == LDAP_SERVER_DOWN)
- return GNOME_Evolution_Addressbook_BookListener_RepositoryOffline;
+ return GNOME_Evolution_Addressbook_RepositoryOffline;
else if (ldap_error == LDAP_ALREADY_EXISTS)
- return GNOME_Evolution_Addressbook_BookListener_CardIdAlreadyExists;
+ return GNOME_Evolution_Addressbook_ContactIdAlreadyExists;
else
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
+ return GNOME_Evolution_Addressbook_OtherError;
}
static char *
-create_dn_from_ecard (ECardSimple *card, const char *root_dn)
+create_dn_from_contact (EContact *contact, const char *root_dn)
{
char *cn, *cn_part = NULL;
char *dn;
- cn = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_FULL_NAME);
+ cn = e_contact_get (contact, E_CONTACT_FULL_NAME);
if (cn) {
if (strchr (cn, ',')) {
/* need to escape commas */
@@ -921,7 +919,7 @@ free_mods (GPtrArray *mods)
}
static GPtrArray*
-build_mods_from_ecards (PASBackendLDAP *bl, ECardSimple *current, ECardSimple *new, gboolean *new_dn_needed)
+build_mods_from_contacts (PASBackendLDAP *bl, EContact *current, EContact *new, gboolean *new_dn_needed)
{
gboolean adding = (current == NULL);
GPtrArray *result = g_ptr_array_new();
@@ -946,12 +944,12 @@ build_mods_from_ecards (PASBackendLDAP *bl, ECardSimple *current, ECardSimple *n
if (prop_info[i].prop_type & PROP_EVOLVE && !bl->priv->evolutionPersonSupported)
continue;
- /* get the value for the new card, and compare it to
- the value in the current card to see if we should
+ /* get the value for the new contact, and compare it to
+ the value in the current contact to see if we should
update it -- if adding is TRUE, short circuit the
check. */
if (prop_info[i].prop_type & PROP_TYPE_STRING) {
- new_prop = e_card_simple_get (new, prop_info[i].field_id);
+ new_prop = e_contact_get (new, prop_info[i].field_id);
new_prop_present = (new_prop != NULL);
}
else {
@@ -962,7 +960,7 @@ build_mods_from_ecards (PASBackendLDAP *bl, ECardSimple *current, ECardSimple *n
/* need to set INCLUDE to true if the field needs to
show up in the ldap modify request */
if (adding) {
- /* if we're creating a new card, include it if the
+ /* if we're creating a new contact, include it if the
field is there at all */
if (prop_info[i].prop_type & PROP_TYPE_STRING)
include = (new_prop_present && *new_prop); /* empty strings cause problems */
@@ -970,13 +968,13 @@ build_mods_from_ecards (PASBackendLDAP *bl, ECardSimple *current, ECardSimple *n
include = new_prop_present;
}
else {
- /* if we're modifying an existing card,
+ /* if we're modifying an existing contact,
include it if the current field value is
different than the new one, if it didn't
exist previously, or if it's been
removed. */
if (prop_info[i].prop_type & PROP_TYPE_STRING) {
- current_prop = e_card_simple_get (current, prop_info[i].field_id);
+ current_prop = e_contact_get (current, prop_info[i].field_id);
current_prop_present = (current_prop != NULL);
if (new_prop && current_prop)
@@ -1112,23 +1110,24 @@ add_objectclass_mod (PASBackendLDAP *bl, GPtrArray *mod_array, GList *existing_o
typedef struct {
LDAPOp op;
char *dn;
- ECardSimple *new_card;
+ EContact *new_contact;
} LDAPCreateOp;
static void
-create_card_handler (LDAPOp *op, LDAPMessage *res)
+create_contact_handler (LDAPOp *op, LDAPMessage *res)
{
LDAPCreateOp *create_op = (LDAPCreateOp*)op;
PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
LDAP *ldap = bl->priv->ldap;
+ EContact *contact;
int ldap_error;
int response;
if (LDAP_RES_ADD != ldap_msgtype (res)) {
- g_warning ("incorrect msg type %d passed to create_card_handler", ldap_msgtype (res));
+ g_warning ("incorrect msg type %d passed to create_contact_handler", ldap_msgtype (res));
pas_book_respond_create (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError,
- create_op->dn);
+ GNOME_Evolution_Addressbook_OtherError,
+ NULL);
ldap_op_finished (op);
return;
}
@@ -1136,75 +1135,34 @@ create_card_handler (LDAPOp *op, LDAPMessage *res)
ldap_parse_result (ldap, res, &ldap_error,
NULL, NULL, NULL, NULL, 0);
- if (ldap_error == LDAP_SUCCESS) {
- /* the card was created, let's let the views know about it */
- EIterator *iter;
-
- iter = e_list_get_iterator (bl->priv->book_views);
- while (e_iterator_is_valid (iter)) {
- CORBA_Environment ev;
- gboolean match;
- PASBackendLDAPBookView *view = (PASBackendLDAPBookView*)e_iterator_get (iter);
- char *new_vcard;
-
- CORBA_exception_init(&ev);
-
- bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
-
- new_vcard = e_card_simple_get_vcard_assume_utf8 (create_op->new_card);
-
- match = pas_backend_card_sexp_match_vcard (view->card_sexp,
- new_vcard);
- if (match) {
- pas_book_view_notify_add_1 (view->book_view,
- new_vcard);
- }
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
-
- g_free (new_vcard);
-
- bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
-
- e_iterator_next (iter);
- }
- g_object_unref (iter);
- }
- else {
- ldap_perror (ldap, "create_card");
- }
-
- if (op->view)
- pas_book_view_notify_complete (op->view, GNOME_Evolution_Addressbook_BookViewListener_Success);
-
/* and lastly respond */
response = ldap_error_to_response (ldap_error);
pas_book_respond_create (op->book,
response,
- create_op->dn);
+ create_op->new_contact);
ldap_op_finished (op);
}
static void
-create_card_dtor (LDAPOp *op)
+create_contact_dtor (LDAPOp *op)
{
LDAPCreateOp *create_op = (LDAPCreateOp*)op;
g_free (create_op->dn);
- g_object_unref (create_op->new_card);
+ g_object_unref (create_op->new_contact);
g_free (create_op);
}
static void
-pas_backend_ldap_process_create_card (PASBackend *backend,
- PASBook *book,
- PASCreateCardRequest *req)
+pas_backend_ldap_process_create_contact (PASBackend *backend,
+ PASBook *book,
+ const char *vcard)
{
LDAPCreateOp *create_op = g_new (LDAPCreateOp, 1);
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
PASBookView *book_view;
- int create_card_msgid;
- ECard *new_ecard;
+ int create_contact_msgid;
int response;
int err;
GPtrArray *mod_array;
@@ -1213,18 +1171,17 @@ pas_backend_ldap_process_create_card (PASBackend *backend,
book_view = find_book_view (bl);
- printf ("vcard = %s\n", req->vcard);
+ printf ("vcard = %s\n", vcard);
- new_ecard = e_card_new (req->vcard);
- create_op->new_card = e_card_simple_new (new_ecard);
+ create_op->new_contact = e_contact_new_from_vcard (vcard);
- create_op->dn = create_dn_from_ecard (create_op->new_card, bl->priv->ldap_rootdn);
- e_card_simple_set_id (create_op->new_card, create_op->dn); /* for the notification code below */
+ create_op->dn = create_dn_from_contact (create_op->new_contact, bl->priv->ldap_rootdn);
+ e_contact_set (create_op->new_contact, E_CONTACT_UID, create_op->dn);
ldap = bl->priv->ldap;
/* build our mods */
- mod_array = build_mods_from_ecards (bl, NULL, create_op->new_card, NULL);
+ mod_array = build_mods_from_contacts (bl, NULL, create_op->new_contact, NULL);
#if 0
if (!mod_array) {
@@ -1232,10 +1189,10 @@ pas_backend_ldap_process_create_card (PASBackend *backend,
UnsupportedAttribute back */
pas_book_respond_create (book,
GNOME_Evolution_Addressbook_BookListener_UnsupportedField,
- create_op->dn);
+ NULL);
g_free (create_op->dn);
- g_object_unref (create_op->new_card);
+ g_object_unref (create_op->new_contact);
g_free (create_op);
return;
}
@@ -1288,10 +1245,10 @@ pas_backend_ldap_process_create_card (PASBackend *backend,
ldap_mods = (LDAPMod**)mod_array->pdata;
do {
- book_view_notify_status (book_view, _("Adding card to LDAP server..."));
+ book_view_notify_status (book_view, _("Adding contact to LDAP server..."));
err = ldap_add_ext (ldap, create_op->dn, ldap_mods,
- NULL, NULL, &create_card_msgid);
+ NULL, NULL, &create_contact_msgid);
} while (pas_backend_ldap_reconnect (bl, book_view, err));
@@ -1302,15 +1259,15 @@ pas_backend_ldap_process_create_card (PASBackend *backend,
response = ldap_error_to_response (err);
pas_book_respond_create (create_op->op.book,
response,
- create_op->dn);
- create_card_dtor ((LDAPOp*)create_op);
+ NULL);
+ create_contact_dtor ((LDAPOp*)create_op);
return;
}
else {
g_print ("ldap_add_ext returned %d\n", err);
ldap_op_add ((LDAPOp*)create_op, backend, book,
- book_view, create_card_msgid,
- create_card_handler, create_card_dtor);
+ book_view, create_contact_msgid,
+ create_contact_handler, create_contact_dtor);
}
}
@@ -1321,16 +1278,18 @@ typedef struct {
} LDAPRemoveOp;
static void
-remove_card_handler (LDAPOp *op, LDAPMessage *res)
+remove_contact_handler (LDAPOp *op, LDAPMessage *res)
{
LDAPRemoveOp *remove_op = (LDAPRemoveOp*)op;
PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
int ldap_error;
+ GList *ids = NULL;
if (LDAP_RES_DELETE != ldap_msgtype (res)) {
- g_warning ("incorrect msg type %d passed to remove_card_handler", ldap_msgtype (res));
- pas_book_respond_remove (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError);
+ g_warning ("incorrect msg type %d passed to remove_contact_handler", ldap_msgtype (res));
+ pas_book_respond_remove_contacts (op->book,
+ GNOME_Evolution_Addressbook_OtherError,
+ NULL);
ldap_op_finished (op);
return;
}
@@ -1338,39 +1297,15 @@ remove_card_handler (LDAPOp *op, LDAPMessage *res)
ldap_parse_result (bl->priv->ldap, res, &ldap_error,
NULL, NULL, NULL, NULL, 0);
- if (ldap_error == LDAP_SUCCESS) {
- /* the card was removed, let's let the views know about it */
- EIterator *iter = e_list_get_iterator (bl->priv->book_views);
-
- while (e_iterator_is_valid (iter)) {
- CORBA_Environment ev;
- PASBackendLDAPBookView *view = (PASBackendLDAPBookView*)e_iterator_get (iter);
-
- CORBA_exception_init(&ev);
-
- bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
-
- pas_book_view_notify_remove_1 (view->book_view, remove_op->id);
-
- bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
-
- e_iterator_next (iter);
- }
- g_object_unref (iter);
- }
- else {
- ldap_perror (bl->priv->ldap, "remove_card");
- }
-
- pas_book_respond_remove (remove_op->op.book,
- ldap_error_to_response (ldap_error));
-
- if (op->view)
- pas_book_view_notify_complete (op->view, GNOME_Evolution_Addressbook_BookViewListener_Success);
+ ids = g_list_append (ids, remove_op->id);
+ pas_book_respond_remove_contacts (remove_op->op.book,
+ ldap_error_to_response (ldap_error),
+ ids);
+ g_list_free (ids);
}
static void
-remove_card_dtor (LDAPOp *op)
+remove_contact_dtor (LDAPOp *op)
{
LDAPRemoveOp *remove_op = (LDAPRemoveOp*)op;
@@ -1379,9 +1314,9 @@ remove_card_dtor (LDAPOp *op)
}
static void
-pas_backend_ldap_process_remove_cards (PASBackend *backend,
- PASBook *book,
- PASRemoveCardsRequest *req)
+pas_backend_ldap_process_remove_contacts (PASBackend *backend,
+ PASBook *book,
+ GList *ids)
{
LDAPRemoveOp *remove_op = g_new (LDAPRemoveOp, 1);
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
@@ -1396,10 +1331,10 @@ pas_backend_ldap_process_remove_cards (PASBackend *backend,
** capabilities, we should only get 1 length lists here, so
** the id we're deleting is the first and only id in the list.
*/
- remove_op->id = g_strdup (req->ids->data);
+ remove_op->id = g_strdup (ids->data);
do {
- book_view_notify_status (book_view, _("Removing card from LDAP server..."));
+ book_view_notify_status (book_view, _("Removing contact from LDAP server..."));
ldap_error = ldap_delete_ext (bl->priv->ldap,
remove_op->id,
@@ -1407,16 +1342,17 @@ pas_backend_ldap_process_remove_cards (PASBackend *backend,
} while (pas_backend_ldap_reconnect (bl, book_view, ldap_error));
if (ldap_error != LDAP_SUCCESS) {
- pas_book_respond_remove (remove_op->op.book,
- ldap_error_to_response (ldap_error));
- remove_card_dtor ((LDAPOp*)remove_op);
+ pas_book_respond_remove_contacts (remove_op->op.book,
+ ldap_error_to_response (ldap_error),
+ NULL);
+ remove_contact_dtor ((LDAPOp*)remove_op);
return;
}
else {
g_print ("ldap_delete_ext returned %d\n", ldap_error);
ldap_op_add ((LDAPOp*)remove_op, backend, book,
book_view, remove_msgid,
- remove_card_handler, remove_card_dtor);
+ remove_contact_handler, remove_contact_dtor);
}
}
@@ -1427,23 +1363,21 @@ pas_backend_ldap_process_remove_cards (PASBackend *backend,
** The modification request is actually composed of 2 separate
** requests. Since we need to get a list of theexisting objectclasses
** used by the ldap server for the entry, and since the UI only sends
-** us the current card, we need to query the ldap server for the
-** existing card.
+** us the current contact, we need to query the ldap server for the
+** existing contact.
**
*/
typedef struct {
LDAPOp op;
- const char *id; /* the id of the card we're modifying */
- char *current_vcard; /* current in the LDAP db */
- ECardSimple *current_card;
- char *vcard; /* the VCard we want to store */
- ECardSimple *card;
+ const char *id; /* the id of the contact we're modifying */
+ EContact *current_contact;
+ EContact *contact;
GList *existing_objectclasses;
} LDAPModifyOp;
static void
-modify_card_modify_handler (LDAPOp *op, LDAPMessage *res)
+modify_contact_modify_handler (LDAPOp *op, LDAPMessage *res)
{
LDAPModifyOp *modify_op = (LDAPModifyOp*)op;
PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
@@ -1451,9 +1385,10 @@ modify_card_modify_handler (LDAPOp *op, LDAPMessage *res)
int ldap_error;
if (LDAP_RES_MODIFY != ldap_msgtype (res)) {
- g_warning ("incorrect msg type %d passed to modify_card_handler", ldap_msgtype (res));
+ g_warning ("incorrect msg type %d passed to modify_contact_handler", ldap_msgtype (res));
pas_book_respond_modify (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError);
+ GNOME_Evolution_Addressbook_OtherError,
+ NULL);
ldap_op_finished (op);
return;
}
@@ -1461,48 +1396,15 @@ modify_card_modify_handler (LDAPOp *op, LDAPMessage *res)
ldap_parse_result (ldap, res, &ldap_error,
NULL, NULL, NULL, NULL, 0);
- if (ldap_error == LDAP_SUCCESS) {
- /* the card was modified, let's let the views know about it */
- EIterator *iter = e_list_get_iterator (bl->priv->book_views);
- while (e_iterator_is_valid (iter)) {
- CORBA_Environment ev;
- gboolean old_match, new_match;
- PASBackendLDAPBookView *view = (PASBackendLDAPBookView*)e_iterator_get (iter);
-
- CORBA_exception_init(&ev);
-
- bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
-
- old_match = pas_backend_card_sexp_match_vcard (view->card_sexp,
- modify_op->current_vcard);
- new_match = pas_backend_card_sexp_match_vcard (view->card_sexp,
- modify_op->vcard);
- if (old_match && new_match)
- pas_book_view_notify_change_1 (view->book_view, modify_op->vcard);
- else if (new_match)
- pas_book_view_notify_add_1 (view->book_view, modify_op->vcard);
- else /* if (old_match) */
- pas_book_view_notify_remove_1 (view->book_view, e_card_simple_get_id (modify_op->card));
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
-
- bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
-
- e_iterator_next (iter);
- }
- g_object_unref (iter);
- }
- else {
- ldap_perror (ldap, "ldap_modify_s");
- }
-
/* and lastly respond */
pas_book_respond_modify (op->book,
- ldap_error_to_response (ldap_error));
+ ldap_error_to_response (ldap_error),
+ modify_op->contact);
ldap_op_finished (op);
}
static void
-modify_card_search_handler (LDAPOp *op, LDAPMessage *res)
+modify_contact_search_handler (LDAPOp *op, LDAPMessage *res)
{
LDAPModifyOp *modify_op = (LDAPModifyOp*)op;
PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
@@ -1520,14 +1422,14 @@ modify_card_search_handler (LDAPOp *op, LDAPMessage *res)
if (!e) {
g_warning ("uh, this shouldn't happen");
pas_book_respond_modify (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError);
+ GNOME_Evolution_Addressbook_OtherError,
+ NULL);
ldap_op_finished (op);
return;
}
- modify_op->current_card = build_card_from_entry (ldap, e,
- &modify_op->existing_objectclasses);
- modify_op->current_vcard = e_card_simple_get_vcard_assume_utf8 (modify_op->current_card);
+ modify_op->current_contact = build_contact_from_entry (ldap, e,
+ &modify_op->existing_objectclasses);
}
else if (msg_type == LDAP_RES_SEARCH_RESULT) {
int ldap_error;
@@ -1535,7 +1437,7 @@ modify_card_search_handler (LDAPOp *op, LDAPMessage *res)
GPtrArray *mod_array;
gboolean differences;
gboolean need_new_dn;
- int modify_card_msgid;
+ int modify_contact_msgid;
/* grab the result code, and set up the actual modify
if it was successful */
@@ -1545,13 +1447,14 @@ modify_card_search_handler (LDAPOp *op, LDAPMessage *res)
if (ldap_error != LDAP_SUCCESS) {
/* more here i'm sure */
pas_book_respond_modify (op->book,
- ldap_error_to_response (ldap_error));
+ ldap_error_to_response (ldap_error),
+ NULL);
ldap_op_finished (op);
return;
}
/* build our mods */
- mod_array = build_mods_from_ecards (bl, modify_op->current_card, modify_op->card, &need_new_dn);
+ mod_array = build_mods_from_contacts (bl, modify_op->current_contact, modify_op->contact, &need_new_dn);
differences = mod_array->len > 0;
if (differences) {
@@ -1569,17 +1472,18 @@ modify_card_search_handler (LDAPOp *op, LDAPMessage *res)
/* actually perform the ldap modify */
ldap_error = ldap_modify_ext (ldap, modify_op->id, ldap_mods,
- NULL, NULL, &modify_card_msgid);
+ NULL, NULL, &modify_contact_msgid);
if (ldap_error == LDAP_SUCCESS) {
- op->handler = modify_card_modify_handler;
+ op->handler = modify_contact_modify_handler;
ldap_op_change_id ((LDAPOp*)modify_op,
- modify_card_msgid);
+ modify_contact_msgid);
}
else {
g_warning ("ldap_modify_ext returned %d\n", ldap_error);
pas_book_respond_modify (op->book,
- ldap_error_to_response (ldap_error));
+ ldap_error_to_response (ldap_error),
+ NULL);
ldap_op_finished (op);
return;
}
@@ -1591,84 +1495,80 @@ modify_card_search_handler (LDAPOp *op, LDAPMessage *res)
else {
g_warning ("unhandled result type %d returned", msg_type);
pas_book_respond_modify (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError);
+ GNOME_Evolution_Addressbook_OtherError,
+ NULL);
ldap_op_finished (op);
}
}
static void
-modify_card_dtor (LDAPOp *op)
+modify_contact_dtor (LDAPOp *op)
{
LDAPModifyOp *modify_op = (LDAPModifyOp*)op;
g_list_foreach (modify_op->existing_objectclasses, (GFunc)g_free, NULL);
g_list_free (modify_op->existing_objectclasses);
- g_free (modify_op->current_vcard);
- if (modify_op->current_card)
- g_object_unref (modify_op->current_card);
- g_free (modify_op->vcard);
- if (modify_op->card)
- g_object_unref (modify_op->card);
+ if (modify_op->current_contact)
+ g_object_unref (modify_op->current_contact);
+ if (modify_op->contact)
+ g_object_unref (modify_op->contact);
g_free (modify_op);
}
static void
-pas_backend_ldap_process_modify_card (PASBackend *backend,
- PASBook *book,
- PASModifyCardRequest *req)
+pas_backend_ldap_process_modify_contact (PASBackend *backend,
+ PASBook *book,
+ const char *vcard)
{
LDAPModifyOp *modify_op = g_new0 (LDAPModifyOp, 1);
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- ECard *new_ecard;
int ldap_error;
LDAP *ldap;
- int modify_card_msgid;
+ int modify_contact_msgid;
PASBookView *book_view;
book_view = find_book_view (bl);
- modify_op->vcard = g_strdup (req->vcard);
- new_ecard = e_card_new (modify_op->vcard);
- modify_op->card = e_card_simple_new (new_ecard);
- g_object_unref (new_ecard);
- modify_op->id = e_card_simple_get_id(modify_op->card);
+ modify_op->contact = e_contact_new_from_vcard (vcard);
+ modify_op->id = e_contact_get_const (modify_op->contact, E_CONTACT_UID);
ldap = bl->priv->ldap;
- book_view_notify_status (book_view, _("Modifying card from LDAP server..."));
+ book_view_notify_status (book_view, _("Modifying contact from LDAP server..."));
do {
- book_view_notify_status (book_view, _("Modifying card from LDAP server..."));
+ book_view_notify_status (book_view, _("Modifying contact from LDAP server..."));
ldap_error = ldap_search_ext (ldap, modify_op->id,
LDAP_SCOPE_BASE,
"(objectclass=*)",
NULL, 0, NULL, NULL,
NULL, /* XXX timeout */
- 1, &modify_card_msgid);
+ 1, &modify_contact_msgid);
} while (pas_backend_ldap_reconnect (bl, book_view, ldap_error));
if (ldap_error == LDAP_SUCCESS) {
ldap_op_add ((LDAPOp*)modify_op, backend, book,
- book_view, modify_card_msgid,
- modify_card_search_handler, modify_card_dtor);
+ book_view, modify_contact_msgid,
+ modify_contact_search_handler, modify_contact_dtor);
}
else {
g_warning ("ldap_search_ext returned %d\n", ldap_error);
pas_book_respond_modify (book,
- GNOME_Evolution_Addressbook_BookListener_OtherError);
- modify_card_dtor ((LDAPOp*)modify_op);
+ GNOME_Evolution_Addressbook_OtherError,
+ NULL);
+ modify_contact_dtor ((LDAPOp*)modify_op);
}
}
typedef struct {
LDAPOp op;
-} LDAPGetVCardOp;
+} LDAPGetContactOp;
static void
-get_vcard_handler (LDAPOp *op, LDAPMessage *res)
+get_contact_handler (LDAPOp *op, LDAPMessage *res)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
int msg_type;
@@ -1679,37 +1579,37 @@ get_vcard_handler (LDAPOp *op, LDAPMessage *res)
msg_type = ldap_msgtype (res);
if (msg_type == LDAP_RES_SEARCH_ENTRY) {
LDAPMessage *e = ldap_first_entry(bl->priv->ldap, res);
- ECardSimple *simple;
+ EContact *contact;
char *vcard;
if (!e) {
g_warning ("uh, this shouldn't happen");
- pas_book_respond_get_vcard (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError,
- "");
+ pas_book_respond_get_contact (op->book,
+ GNOME_Evolution_Addressbook_OtherError,
+ "");
ldap_op_finished (op);
return;
}
- simple = build_card_from_entry (bl->priv->ldap, e, NULL);
- vcard = e_card_simple_get_vcard_assume_utf8 (simple);
- pas_book_respond_get_vcard (op->book,
- GNOME_Evolution_Addressbook_BookListener_Success,
- vcard);
+ contact = build_contact_from_entry (bl->priv->ldap, e, NULL);
+ vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ pas_book_respond_get_contact (op->book,
+ GNOME_Evolution_Addressbook_Success,
+ vcard);
g_free (vcard);
- g_object_unref (simple);
+ g_object_unref (contact);
ldap_op_finished (op);
}
else if (msg_type == LDAP_RES_SEARCH_RESULT) {
int ldap_error;
ldap_parse_result (bl->priv->ldap, res, &ldap_error,
NULL, NULL, NULL, NULL, 0);
- pas_book_respond_get_vcard (op->book, ldap_error_to_response (ldap_error), "");
+ pas_book_respond_get_contact (op->book, ldap_error_to_response (ldap_error), "");
ldap_op_finished (op);
}
else {
g_warning ("unhandled result type %d returned", msg_type);
- pas_book_respond_get_vcard (op->book, GNOME_Evolution_Addressbook_BookListener_OtherError,
+ pas_book_respond_get_contact (op->book, GNOME_Evolution_Addressbook_OtherError,
"");
ldap_op_finished (op);
}
@@ -1717,254 +1617,75 @@ get_vcard_handler (LDAPOp *op, LDAPMessage *res)
}
static void
-get_vcard_dtor (LDAPOp *op)
+get_contact_dtor (LDAPOp *op)
{
- LDAPGetVCardOp *get_vcard_op = (LDAPGetVCardOp*)op;
+ LDAPGetContactOp *get_contact_op = (LDAPGetContactOp*)op;
- g_free (get_vcard_op);
+ g_free (get_contact_op);
}
static void
-pas_backend_ldap_process_get_vcard (PASBackend *backend,
- PASBook *book,
- PASGetVCardRequest *req)
+pas_backend_ldap_process_get_contact (PASBackend *backend,
+ PASBook *book,
+ const char *id)
{
- LDAPGetVCardOp *get_vcard_op = g_new0 (LDAPGetVCardOp, 1);
+ LDAPGetContactOp *get_contact_op = g_new0 (LDAPGetContactOp, 1);
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
LDAP *ldap = bl->priv->ldap;
- int get_vcard_msgid;
+ int get_contact_msgid;
PASBookView *book_view;
int ldap_error;
book_view = find_book_view (bl);
do {
- ldap_error = ldap_search_ext (ldap, req->id,
+ ldap_error = ldap_search_ext (ldap, id,
LDAP_SCOPE_BASE,
"(objectclass=*)",
NULL, 0, NULL, NULL,
NULL, /* XXX timeout */
- 1, &get_vcard_msgid);
+ 1, &get_contact_msgid);
} while (pas_backend_ldap_reconnect (bl, book_view, ldap_error));
if (ldap_error == LDAP_SUCCESS) {
- ldap_op_add ((LDAPOp*)get_vcard_op, backend, book,
- book_view, get_vcard_msgid,
- get_vcard_handler, get_vcard_dtor);
+ ldap_op_add ((LDAPOp*)get_contact_op, backend, book,
+ book_view, get_contact_msgid,
+ get_contact_handler, get_contact_dtor);
}
else {
- pas_book_respond_get_vcard (book,
+ pas_book_respond_get_contact (book,
ldap_error_to_response (ldap_error),
"");
- get_vcard_dtor ((LDAPOp*)get_vcard_op);
+ get_contact_dtor ((LDAPOp*)get_contact_op);
}
}
-typedef struct {
- LDAPOp op;
- PASBackendLDAPCursorPrivate *cursor_data;
- gboolean responded; /* if FALSE, we need to free cursor_data in the dtor */
-} LDAPGetCursorOp;
-
-static long
-get_length(PASCardCursor *cursor, gpointer data)
-{
- PASBackendLDAPCursorPrivate *cursor_data = (PASBackendLDAPCursorPrivate *) data;
-
- return cursor_data->num_elements;
-}
-
-static char *
-get_nth(PASCardCursor *cursor, long n, gpointer data)
-{
- PASBackendLDAPCursorPrivate *cursor_data = (PASBackendLDAPCursorPrivate *) data;
-
- g_return_val_if_fail (n < cursor_data->num_elements, NULL);
-
- return (char*)g_list_nth (cursor_data->elements, n);
-}
-
-static void
-cursor_destroy(gpointer data, GObject *where_object_was)
-{
- PASBackendLDAPCursorPrivate *cursor_data = (PASBackendLDAPCursorPrivate *) data;
- if (cursor_data->book) {
- CORBA_Environment ev;
- GNOME_Evolution_Addressbook_Book corba_book;
-
- corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(cursor_data->book));
-
- CORBA_exception_init(&ev);
-
- GNOME_Evolution_Addressbook_Book_unref(corba_book, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("cursor_destroy: Exception unreffing "
- "corba book.\n");
- }
-
- CORBA_exception_free(&ev);
- }
-
- /* free the ldap specific cursor information */
- g_list_foreach (cursor_data->elements, (GFunc)g_free, NULL);
- g_list_free (cursor_data->elements);
-
- g_free(cursor_data);
-}
-
-static void
-get_cursor_handler (LDAPOp *op, LDAPMessage *res)
-{
- LDAPGetCursorOp *cursor_op = (LDAPGetCursorOp*)op;
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
- LDAP *ldap = bl->priv->ldap;
- int msg_type;
-
- msg_type = ldap_msgtype (res);
- if (msg_type == LDAP_RES_SEARCH_ENTRY) {
- LDAPMessage *e;
-
- e = ldap_first_entry (ldap, res);
- while (e) {
- ECardSimple *simple;
-
- simple = build_card_from_entry (ldap, e, NULL);
- if (simple) {
- char *vcard = e_card_simple_get_vcard_assume_utf8 (simple);
- cursor_op->cursor_data->num_elements ++;
- cursor_op->cursor_data->elements = g_list_prepend (cursor_op->cursor_data->elements,
- vcard);
- g_object_unref (simple);
- }
- }
- }
- else if (msg_type == LDAP_RES_SEARCH_RESULT) {
- PASCardCursor *cursor = CORBA_OBJECT_NIL;
- int ldap_error;
- ldap_parse_result (bl->priv->ldap, res, &ldap_error,
- NULL, NULL, NULL, NULL, 0);
-
- if (ldap_error == LDAP_SUCCESS) {
- cursor = pas_card_cursor_new(get_length,
- get_nth,
- cursor_op->cursor_data);
-
- g_object_weak_ref (G_OBJECT (cursor), cursor_destroy, cursor_op->cursor_data);
-
- cursor_op->responded = TRUE;
- }
-
- pas_book_respond_get_cursor (cursor_op->cursor_data->book,
- ldap_error_to_response (ldap_error),
- cursor);
-
- ldap_op_finished (op);
- }
- else {
- g_warning ("unhandled result type %d returned", msg_type);
- pas_book_respond_get_cursor (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError,
- CORBA_OBJECT_NIL);
- ldap_op_finished (op);
- }
-}
-
-static void
-get_cursor_dtor (LDAPOp *op)
-{
- LDAPGetCursorOp *cursor_op = (LDAPGetCursorOp*)op;
-
- if (!cursor_op->responded) {
- cursor_destroy (cursor_op->cursor_data, NULL);
- }
-
- g_free (op);
-}
-
-static void
-pas_backend_ldap_process_get_cursor (PASBackend *backend,
- PASBook *book,
- PASGetCursorRequest *req)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- LDAP *ldap = bl->priv->ldap;
- int ldap_error;
- int get_cursor_msgid;
- LDAPGetCursorOp *cursor_op;
- PASBookView *book_view;
-
- book_view = find_book_view (bl);
-
- cursor_op = g_new0 (LDAPGetCursorOp, 1);
- cursor_op->cursor_data = g_new0 (PASBackendLDAPCursorPrivate, 1);
-
- do {
- ldap_error = ldap_search_ext (ldap,
- bl->priv->ldap_rootdn,
- bl->priv->ldap_scope,
- "(objectclass=*)",
- NULL, 0,
- NULL, NULL, NULL, /* timeout */
- 0, &get_cursor_msgid);
- } while (pas_backend_ldap_reconnect (bl, book_view, ldap_error));
-
- if (ldap_error == LDAP_SUCCESS) {
- CORBA_Environment ev;
- GNOME_Evolution_Addressbook_Book corba_book;
-
- corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(book));
-
- CORBA_exception_init(&ev);
-
- GNOME_Evolution_Addressbook_Book_ref(corba_book, &ev);
-
- cursor_op->cursor_data->backend = backend;
- cursor_op->cursor_data->book = book;
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("pas_backend_ldap_process_get_cursor: Exception reffing "
- "corba book.\n");
- }
-
- CORBA_exception_free(&ev);
-
-
- ldap_op_add ((LDAPOp*)cursor_op, backend, book,
- NULL, get_cursor_msgid, get_cursor_handler, get_cursor_dtor);
- }
- else {
- pas_book_respond_get_cursor (book,
- ldap_error_to_response (ldap_error),
- CORBA_OBJECT_NIL);
- get_cursor_dtor ((LDAPOp*)cursor_op);
- }
-}
+static EContactField email_ids[3] = {
+ E_CONTACT_EMAIL_1,
+ E_CONTACT_EMAIL_2,
+ E_CONTACT_EMAIL_3
+};
-
/* List property functions */
static void
-email_populate(ECardSimple *card, char **values)
+email_populate(EContact *contact, char **values)
{
int i;
-
- for (i = 0; values[i] && i < 3; i ++) {
- e_card_simple_set_email (card, i, values[i]);
- }
+ for (i = 0; values[i] && i < 3; i ++)
+ e_contact_set (contact, email_ids[i], values[i]);
}
struct berval**
-email_ber(ECardSimple *card)
+email_ber(EContact *contact)
{
struct berval** result;
const char *emails[3];
- int i, j, num;
+ int i, j, num = 0;
- num = 0;
for (i = 0; i < 3; i ++) {
- emails[i] = e_card_simple_get_email (card, E_CARD_SIMPLE_EMAIL_ID_EMAIL + i);
+ emails[i] = e_contact_get (contact, email_ids[i]);
if (emails[i])
num++;
}
@@ -1991,15 +1712,15 @@ email_ber(ECardSimple *card)
}
static gboolean
-email_compare (ECardSimple *ecard1, ECardSimple *ecard2)
+email_compare (EContact *contact1, EContact *contact2)
{
const char *email1, *email2;
int i;
for (i = 0; i < 3; i ++) {
gboolean equal;
- email1 = e_card_simple_get_email (ecard1, E_CARD_SIMPLE_EMAIL_ID_EMAIL + i);
- email2 = e_card_simple_get_email (ecard2, E_CARD_SIMPLE_EMAIL_ID_EMAIL + i);
+ email1 = e_contact_get_const (contact1, email_ids[i]);
+ email2 = e_contact_get_const (contact2, email_ids[i]);
if (email1 && email2)
equal = !strcmp (email1, email2);
@@ -2014,26 +1735,26 @@ email_compare (ECardSimple *ecard1, ECardSimple *ecard2)
}
static void
-homephone_populate(ECardSimple *card, char **values)
+homephone_populate(EContact *contact, char **values)
{
if (values[0]) {
- e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_HOME, values[0]);
+ e_contact_set (contact, E_CONTACT_PHONE_HOME, values[0]);
if (values[1])
- e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_HOME_2, values[1]);
+ e_contact_set (contact, E_CONTACT_PHONE_HOME_2, values[1]);
}
}
struct berval**
-homephone_ber(ECardSimple *card)
+homephone_ber(EContact *contact)
{
struct berval** result;
const char *homephones[3];
int i, j, num;
num = 0;
- if ((homephones[0] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_HOME)))
+ if ((homephones[0] = e_contact_get (contact, E_CONTACT_PHONE_HOME)))
num++;
- if ((homephones[1] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_HOME_2)))
+ if ((homephones[1] = e_contact_get (contact, E_CONTACT_PHONE_HOME_2)))
num++;
if (num == 0)
@@ -2058,16 +1779,16 @@ homephone_ber(ECardSimple *card)
}
static gboolean
-homephone_compare (ECardSimple *ecard1, ECardSimple *ecard2)
+homephone_compare (EContact *contact1, EContact *contact2)
{
- int phone_ids[2] = { E_CARD_SIMPLE_FIELD_PHONE_HOME, E_CARD_SIMPLE_FIELD_PHONE_HOME_2 };
+ int phone_ids[2] = { E_CONTACT_PHONE_HOME, E_CONTACT_PHONE_HOME_2 };
const char *phone1, *phone2;
int i;
for (i = 0; i < 2; i ++) {
gboolean equal;
- phone1 = e_card_simple_get (ecard1, phone_ids[i]);
- phone2 = e_card_simple_get (ecard2, phone_ids[i]);
+ phone1 = e_contact_get (contact1, phone_ids[i]);
+ phone2 = e_contact_get (contact2, phone_ids[i]);
if (phone1 && phone2)
equal = !strcmp (phone1, phone2);
@@ -2082,26 +1803,26 @@ homephone_compare (ECardSimple *ecard1, ECardSimple *ecard2)
}
static void
-business_populate(ECardSimple *card, char **values)
+business_populate(EContact *contact, char **values)
{
if (values[0]) {
- e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, values[0]);
+ e_contact_set (contact, E_CONTACT_PHONE_BUSINESS, values[0]);
if (values[1])
- e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2, values[1]);
+ e_contact_set (contact, E_CONTACT_PHONE_BUSINESS_2, values[1]);
}
}
struct berval**
-business_ber(ECardSimple *card)
+business_ber(EContact *contact)
{
struct berval** result;
const char *business_phones[3];
int i, j, num;
num = 0;
- if ((business_phones[0] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS)))
+ if ((business_phones[0] = e_contact_get (contact, E_CONTACT_PHONE_BUSINESS)))
num++;
- if ((business_phones[1] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2)))
+ if ((business_phones[1] = e_contact_get (contact, E_CONTACT_PHONE_BUSINESS_2)))
num++;
if (num == 0)
@@ -2126,16 +1847,16 @@ business_ber(ECardSimple *card)
}
static gboolean
-business_compare (ECardSimple *ecard1, ECardSimple *ecard2)
+business_compare (EContact *contact1, EContact *contact2)
{
- int phone_ids[2] = { E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2 };
+ int phone_ids[2] = { E_CONTACT_PHONE_BUSINESS, E_CONTACT_PHONE_BUSINESS_2 };
const char *phone1, *phone2;
int i;
for (i = 0; i < 2; i ++) {
gboolean equal;
- phone1 = e_card_simple_get (ecard1, phone_ids[i]);
- phone2 = e_card_simple_get (ecard2, phone_ids[i]);
+ phone1 = e_contact_get (contact1, phone_ids[i]);
+ phone2 = e_contact_get (contact2, phone_ids[i]);
if (phone1 && phone2)
equal = !strcmp (phone1, phone2);
@@ -2150,30 +1871,26 @@ business_compare (ECardSimple *ecard1, ECardSimple *ecard2)
}
static void
-anniversary_populate (ECardSimple *card, char **values)
+anniversary_populate (EContact *contact, char **values)
{
if (values[0]) {
- ECardDate dt = e_card_date_from_string (values[0]);
- g_object_set (card->card,
- "anniversary", &dt,
- NULL);
+ EContactDate *dt = e_contact_date_from_string (values[0]);
+ e_contact_set (contact, E_CONTACT_ANNIVERSARY, &dt);
}
}
struct berval**
-anniversary_ber (ECardSimple *card)
+anniversary_ber (EContact *contact)
{
- ECardDate *dt;
+ EContactDate *dt;
struct berval** result = NULL;
- g_object_get (card->card,
- "anniversary", &dt,
- NULL);
+ dt = e_contact_get (contact, E_CONTACT_ANNIVERSARY);
if (dt) {
char *anniversary;
- anniversary = e_card_date_to_string (dt);
+ anniversary = e_contact_date_to_string (dt);
result = g_new (struct berval*, 2);
result[0] = g_new (struct berval, 1);
@@ -2181,29 +1898,31 @@ anniversary_ber (ECardSimple *card)
result[0]->bv_len = strlen (anniversary);
result[1] = NULL;
+
+ e_contact_date_free (dt);
}
return result;
}
static gboolean
-anniversary_compare (ECardSimple *ecard1, ECardSimple *ecard2)
+anniversary_compare (EContact *contact1, EContact *contact2)
{
- ECardDate *dt;
+ EContactDate *dt;
char *date1 = NULL, *date2 = NULL;
gboolean equal;
- g_object_get (ecard1->card,
- "anniversary", &dt,
- NULL);
- if (dt)
- date1 = e_card_date_to_string (dt);
-
- g_object_get (ecard2->card,
- "anniversary", &dt,
- NULL);
- if (dt)
- date2 = e_card_date_to_string (dt);
+ dt = e_contact_get (contact1, E_CONTACT_ANNIVERSARY);
+ if (dt) {
+ date1 = e_contact_date_to_string (dt);
+ e_contact_date_free (dt);
+ }
+
+ dt = e_contact_get (contact2, E_CONTACT_ANNIVERSARY);
+ if (dt) {
+ date2 = e_contact_date_to_string (dt);
+ e_contact_date_free (dt);
+ }
if (date1 && date2)
equal = !strcmp (date1, date2);
@@ -2217,30 +1936,26 @@ anniversary_compare (ECardSimple *ecard1, ECardSimple *ecard2)
}
static void
-birthday_populate (ECardSimple *card, char **values)
+birthday_populate (EContact *contact, char **values)
{
if (values[0]) {
- ECardDate dt = e_card_date_from_string (values[0]);
- g_object_set (card->card,
- "birth_date", &dt,
- NULL);
+ EContactDate *dt = e_contact_date_from_string (values[0]);
+ e_contact_set (contact, E_CONTACT_BIRTH_DATE, dt);
+ e_contact_date_free (dt);
}
}
struct berval**
-birthday_ber (ECardSimple *card)
+birthday_ber (EContact *contact)
{
- ECardDate *dt;
+ EContactDate *dt;
struct berval** result = NULL;
- g_object_get (card->card,
- "birth_date", &dt,
- NULL);
-
+ dt = e_contact_get (contact, E_CONTACT_BIRTH_DATE);
if (dt) {
char *birthday;
- birthday = e_card_date_to_string (dt);
+ birthday = e_contact_date_to_string (dt);
result = g_new (struct berval*, 2);
result[0] = g_new (struct berval, 1);
@@ -2248,29 +1963,31 @@ birthday_ber (ECardSimple *card)
result[0]->bv_len = strlen (birthday);
result[1] = NULL;
+
+ e_contact_date_free (dt);
}
return result;
}
static gboolean
-birthday_compare (ECardSimple *ecard1, ECardSimple *ecard2)
+birthday_compare (EContact *contact1, EContact *contact2)
{
- ECardDate *dt;
+ EContactDate *dt;
char *date1 = NULL, *date2 = NULL;
gboolean equal;
- g_object_get (ecard1->card,
- "birth_date", &dt,
- NULL);
- if (dt)
- date1 = e_card_date_to_string (dt);
+ dt = e_contact_get (contact1, E_CONTACT_BIRTH_DATE);
+ if (dt) {
+ date1 = e_contact_date_to_string (dt);
+ e_contact_date_free (dt);
+ }
- g_object_get (ecard2->card,
- "birth_date", &dt,
- NULL);
- if (dt)
- date2 = e_card_date_to_string (dt);
+ dt = e_contact_get (contact2, E_CONTACT_BIRTH_DATE);
+ if (dt) {
+ date2 = e_contact_date_to_string (dt);
+ e_contact_date_free (dt);
+ }
if (date1 && date2)
equal = !strcmp (date1, date2);
@@ -2284,10 +2001,11 @@ birthday_compare (ECardSimple *ecard1, ECardSimple *ecard2)
}
static void
-category_populate (ECardSimple *card, char **values)
+category_populate (EContact *contact, char **values)
{
+#if notyet
int i;
- ECard *ecard;
+ EContact *ecard;
EList *categories;
g_object_get (card,
@@ -2309,15 +2027,17 @@ category_populate (ECardSimple *card, char **values)
e_card_simple_sync_card (card);
g_object_unref (ecard);
+#endif
}
struct berval**
-category_ber (ECardSimple *card)
+category_ber (EContact *contact)
{
+#if notyet
struct berval** result = NULL;
EList *categories;
EIterator *iterator;
- ECard *ecard;
+ EContact *ecard;
int i;
g_object_get (card,
@@ -2346,16 +2066,18 @@ category_ber (ECardSimple *card)
g_object_unref (categories);
g_object_unref (ecard);
return result;
+#endif
}
static gboolean
-category_compare (ECardSimple *ecard1, ECardSimple *ecard2)
+category_compare (EContact *contact1, EContact *contact2)
{
+#if notyet
char *categories1, *categories2;
gboolean equal;
- categories1 = e_card_simple_get (ecard1, E_CARD_SIMPLE_FIELD_CATEGORIES);
- categories2 = e_card_simple_get (ecard2, E_CARD_SIMPLE_FIELD_CATEGORIES);
+ categories1 = e_card_simple_get (ecard1, E_CONTACT_CATEGORIES);
+ categories2 = e_card_simple_get (ecard2, E_CONTACT_CATEGORIES);
equal = !strcmp (categories1, categories2);
@@ -2363,6 +2085,19 @@ category_compare (ECardSimple *ecard1, ECardSimple *ecard2)
g_free (categories2);
return equal;
+#endif
+}
+
+static void
+photo_populate (EContact *contact, struct berval **ber_values)
+{
+ if (ber_values && ber_values[0]) {
+ EContactPhoto photo;
+ photo.data = ber_values[0]->bv_val;
+ photo.length = ber_values[0]->bv_len;
+
+ e_contact_set (contact, E_CONTACT_PHOTO, &photo);
+ }
}
typedef struct {
@@ -2670,6 +2405,58 @@ func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data
return r;
}
+static ESExpResult *
+func_exists(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
+{
+ PASBackendLDAPSExpData *ldap_data = data;
+ ESExpResult *r;
+
+ if (argc == 1
+ && argv[0]->type == ESEXP_RES_STRING) {
+ char *propname = argv[0]->value.string;
+
+ if (!strcmp (propname, "x-evolution-any-field")) {
+ int i;
+ int query_length;
+ char *big_query;
+ char *match_str;
+
+ match_str = g_strdup("=*)");
+
+ query_length = 3; /* strlen ("(|") + strlen (")") */
+
+ for (i = 0; i < num_prop_infos; i ++) {
+ query_length += 1 /* strlen ("(") */ + strlen(prop_info[i].ldap_attr) + strlen (match_str);
+ }
+
+ big_query = g_malloc0(query_length + 1);
+ strcat (big_query, "(|");
+ for (i = 0; i < num_prop_infos; i ++) {
+ strcat (big_query, "(");
+ strcat (big_query, prop_info[i].ldap_attr);
+ strcat (big_query, match_str);
+ }
+ strcat (big_query, ")");
+
+ ldap_data->list = g_list_prepend(ldap_data->list, big_query);
+
+ g_free (match_str);
+ }
+ else {
+ char *ldap_attr = query_prop_to_ldap(propname);
+
+ if (ldap_attr)
+ ldap_data->list = g_list_prepend(ldap_data->list,
+ g_strdup_printf("(%s=*)", ldap_attr));
+ }
+ }
+
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
+ r->value.bool = FALSE;
+
+ return r;
+}
+
/* 'builtin' functions */
static struct {
char *name;
@@ -2684,10 +2471,11 @@ static struct {
{ "is", func_is, 0 },
{ "beginswith", func_beginswith, 0 },
{ "endswith", func_endswith, 0 },
+ { "exists", func_exists, 0 },
};
static gchar *
-pas_backend_ldap_build_query (PASBackendLDAP *bl, gchar *query)
+pas_backend_ldap_build_query (PASBackendLDAP *bl, const char *query)
{
ESExp *sexp;
ESExpResult *r;
@@ -2743,7 +2531,7 @@ query_prop_to_ldap(gchar *query_prop)
int i;
for (i = 0; i < num_prop_infos; i ++)
- if (!strcmp (query_prop, prop_info[i].query_prop))
+ if (!strcmp (query_prop, e_contact_field_name (prop_info[i].field_id)))
return prop_info[i].ldap_attr;
return NULL;
@@ -2752,31 +2540,22 @@ query_prop_to_ldap(gchar *query_prop)
typedef struct {
LDAPOp op;
- PASBackendLDAPBookView *view;
-
- /* grouping stuff */
- GList *pending_adds; /* the cards we're sending */
- int num_pending_adds; /* the number waiting to be sent */
- int target_pending_adds; /* the cutoff that forces a flush to the client, if it happens before the timeout */
- int num_sent_this_time; /* the number of cards we sent to the client before the most recent timeout */
- int num_sent_last_time; /* the number of cards we sent to the client before the previous timeout */
- glong grouping_time_start;
-
+ PASBookView *view;
+
/* used by search_handler to only send the status messages once */
gboolean notified_receiving_results;
} LDAPSearchOp;
-static ECardSimple *
-build_card_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasses)
+static EContact *
+build_contact_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasses)
{
- ECard *ecard = e_card_new ("");
- ECardSimple *card = e_card_simple_new (ecard);
+ EContact *contact = e_contact_new ();
char *dn;
char *attr;
BerElement *ber = NULL;
dn = ldap_get_dn(ldap, e);
- e_card_simple_set_id (card, dn);
+ e_contact_set (contact, E_CONTACT_UID, dn);
ldap_memfree (dn);
for (attr = ldap_first_attribute (ldap, e, &ber); attr;
@@ -2799,24 +2578,41 @@ build_card_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasse
break;
}
+ printf ("attr = %s, ", attr);
+ printf ("info = %p\n", info);
+
if (info) {
- values = ldap_get_values (ldap, e, attr);
+ if (info->prop_type & PROP_WRITE_ONLY)
+ continue;
+
+ if (info->prop_type & PROP_TYPE_BINARY) {
+ struct berval **ber_values = ldap_get_values_len (ldap, e, attr);
- if (values) {
- if (info->prop_type & PROP_TYPE_STRING) {
- /* if it's a normal property just set the string */
- if (values[0])
- e_card_simple_set (card, info->field_id, values[0]);
+ if (ber_values) {
+ info->binary_populate_contact_func (contact, ber_values);
+ ldap_value_free_len (ber_values);
}
- else if (info->prop_type & PROP_TYPE_COMPLEX) {
- /* if it's a list call the ecard-populate function,
- which calls g_object_set to set the property */
- info->populate_ecard_func(card,
- values);
+ }
+ else {
+ values = ldap_get_values (ldap, e, attr);
+
+ if (values) {
+ if (info->prop_type & PROP_TYPE_STRING) {
+ printf ("value = %s\n", values[0]);
+ /* if it's a normal property just set the string */
+ if (values[0])
+ e_contact_set (contact, info->field_id, values[0]);
+ }
+ else if (info->prop_type & PROP_TYPE_COMPLEX) {
+ /* if it's a list call the contact-populate function,
+ which calls g_object_set to set the property */
+ info->populate_contact_func(contact,
+ values);
+ }
+
+ ldap_value_free (values);
}
-
- ldap_value_free (values);
}
}
}
@@ -2827,11 +2623,7 @@ build_card_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasse
if (ber)
ber_free (ber, 0);
- e_card_simple_sync_card (card);
-
- g_object_unref (ecard);
-
- return card;
+ return contact;
}
static gboolean
@@ -2840,10 +2632,7 @@ poll_ldap (PASBackendLDAP *bl)
LDAP *ldap = bl->priv->ldap;
int rc;
LDAPMessage *res;
- GTimeVal cur_time;
- glong cur_millis;
struct timeval timeout;
- EIterator *iter;
if (!bl->priv->active_ops) {
g_warning ("poll_ldap being called for backend with no active operations");
@@ -2880,81 +2669,20 @@ poll_ldap (PASBackendLDAP *bl)
}
}
- g_get_current_time (&cur_time);
- cur_millis = TV_TO_MILLIS (cur_time);
-
- iter = e_list_get_iterator (bl->priv->book_views);
- while (e_iterator_is_valid (iter)) {
- PASBackendLDAPBookView *view = (PASBackendLDAPBookView *)e_iterator_get (iter);
- if (view->search_op) {
- bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), NULL);
-
- ldap_search_op_timeout (view->search_op, cur_millis);
-
- bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), NULL);
- }
- e_iterator_next (iter);
- }
- g_object_unref (iter);
-
return TRUE;
}
static void
-send_pending_adds (LDAPSearchOp *search_op)
-{
- search_op->num_sent_this_time += search_op->num_pending_adds;
- pas_book_view_notify_add (search_op->op.view, search_op->pending_adds);
- g_list_foreach (search_op->pending_adds, (GFunc)g_free, NULL);
- g_list_free (search_op->pending_adds);
- search_op->pending_adds = NULL;
- search_op->num_pending_adds = 0;
-}
-
-static void
-ldap_search_op_timeout (LDAPOp *op, glong cur_millis)
-{
- LDAPSearchOp *search_op = (LDAPSearchOp*)op;
-
- if (cur_millis - search_op->grouping_time_start > GROUPING_MINIMUM_WAIT) {
-
- if (search_op->num_pending_adds >= search_op->target_pending_adds)
- send_pending_adds (search_op);
-
- if (cur_millis - search_op->grouping_time_start > GROUPING_MAXIMUM_WAIT) {
- GTimeVal new_start;
-
- if (search_op->num_pending_adds)
- send_pending_adds (search_op);
- search_op->target_pending_adds = MIN (GROUPING_MAXIMUM_SIZE,
- (search_op->num_sent_this_time + search_op->num_sent_last_time) / 2);
- search_op->target_pending_adds = MAX (search_op->target_pending_adds, 1);
-
-#ifdef PERFORMANCE_SPEW
- printf ("num sent this time %d, last time %d, target pending adds set to %d\n",
- search_op->num_sent_this_time,
- search_op->num_sent_last_time,
- search_op->target_pending_adds);
-#endif
- g_get_current_time (&new_start);
- search_op->grouping_time_start = TV_TO_MILLIS (new_start);
- search_op->num_sent_last_time = search_op->num_sent_this_time;
- search_op->num_sent_this_time = 0;
- }
- }
-}
-
-static void
ldap_search_handler (LDAPOp *op, LDAPMessage *res)
{
LDAPSearchOp *search_op = (LDAPSearchOp*)op;
- PASBackendLDAPBookView *view = search_op->view;
+ PASBookView *view = search_op->view;
PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
LDAP *ldap = bl->priv->ldap;
LDAPMessage *e;
int msg_type;
- bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), NULL);
+ bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view)), NULL);
if (!search_op->notified_receiving_results) {
search_op->notified_receiving_results = TRUE;
@@ -2966,13 +2694,11 @@ ldap_search_handler (LDAPOp *op, LDAPMessage *res)
e = ldap_first_entry(ldap, res);
while (NULL != e) {
- ECardSimple *card = build_card_from_entry (ldap, e, NULL);
+ EContact *contact = build_contact_from_entry (ldap, e, NULL);
- search_op->pending_adds = g_list_append (search_op->pending_adds,
- e_card_simple_get_vcard_assume_utf8 (card));
- search_op->num_pending_adds ++;
+ pas_book_view_notify_update (view, contact);
- g_object_unref (card);
+ g_object_unref (contact);
e = ldap_next_entry(ldap, e);
}
@@ -2985,31 +2711,25 @@ ldap_search_handler (LDAPOp *op, LDAPMessage *res)
g_warning ("search returned %d\n", ldap_error);
- /* the entry that marks the end of our search */
- if (search_op->num_pending_adds)
- send_pending_adds (search_op);
-
if (ldap_error == LDAP_TIMELIMIT_EXCEEDED)
- pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_SearchTimeLimitExceeded);
+ pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_SearchTimeLimitExceeded);
else if (ldap_error == LDAP_SIZELIMIT_EXCEEDED)
- pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_SearchSizeLimitExceeded);
+ pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_SearchSizeLimitExceeded);
else if (ldap_error == LDAP_SUCCESS)
- pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_Success);
+ pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_Success);
else
- pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_OtherError);
+ pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_OtherError);
ldap_op_finished (op);
}
else {
g_warning ("unhandled search result type %d returned", msg_type);
- if (search_op->num_pending_adds)
- send_pending_adds (search_op);
- pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_OtherError);
+ pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_OtherError);
ldap_op_finished (op);
}
- bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), NULL);
+ bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view)), NULL);
}
static void
@@ -3017,14 +2737,11 @@ ldap_search_dtor (LDAPOp *op)
{
LDAPSearchOp *search_op = (LDAPSearchOp*) op;
+#if notyet
/* unhook us from our PASBackendLDAPBookView */
if (search_op->view)
search_op->view->search_op = NULL;
-
- g_list_foreach (search_op->pending_adds, (GFunc)g_free, NULL);
- g_list_free (search_op->pending_adds);
- search_op->pending_adds = NULL;
- search_op->num_pending_adds = 0;
+#endif
g_free (search_op);
}
@@ -3032,22 +2749,21 @@ ldap_search_dtor (LDAPOp *op)
static void
pas_backend_ldap_search (PASBackendLDAP *bl,
PASBook *book,
- PASBackendLDAPBookView *view)
+ PASBookView *view)
{
char *ldap_query;
- ldap_query = pas_backend_ldap_build_query(bl, view->search);
+ ldap_query = pas_backend_ldap_build_query (bl, pas_book_view_get_card_query (view));
if (ldap_query != NULL) {
LDAP *ldap = bl->priv->ldap;
int ldap_err;
- GTimeVal search_start;
int search_msgid;
printf ("searching server using filter: %s\n", ldap_query);
do {
- book_view_notify_status (view->book_view, _("Searching..."));
+ book_view_notify_status (view, _("Searching..."));
ldap_err = ldap_search_ext (ldap, bl->priv->ldap_rootdn,
bl->priv->ldap_scope,
@@ -3056,33 +2772,30 @@ pas_backend_ldap_search (PASBackendLDAP *bl,
NULL, /* XXX */
NULL, /* XXX */
NULL, /* XXX timeout */
- view->limit, &search_msgid);
- } while (pas_backend_ldap_reconnect (bl, view->book_view, ldap_err));
+ 0 /* XXX we need this back in view->limit*/, &search_msgid);
+ } while (pas_backend_ldap_reconnect (bl, view, ldap_err));
g_free (ldap_query);
if (ldap_err != LDAP_SUCCESS) {
- book_view_notify_status (view->book_view, ldap_err2string(ldap_err));
+ book_view_notify_status (view, ldap_err2string(ldap_err));
return;
}
else if (search_msgid == -1) {
- book_view_notify_status (view->book_view,
+ book_view_notify_status (view,
_("Error performing search"));
return;
}
else {
LDAPSearchOp *op = g_new0 (LDAPSearchOp, 1);
- op->target_pending_adds = GROUPING_INITIAL_SIZE;
-
- g_get_current_time (&search_start);
- op->grouping_time_start = TV_TO_MILLIS (search_start);
-
op->view = view;
+#if notyet
view->search_op = (LDAPOp*)op;
+#endif
- ldap_op_add ((LDAPOp*)op, PAS_BACKEND(bl), book, view->book_view,
+ ldap_op_add ((LDAPOp*)op, PAS_BACKEND(bl), book, view,
search_msgid,
ldap_search_handler, ldap_search_dtor);
@@ -3090,106 +2803,49 @@ pas_backend_ldap_search (PASBackendLDAP *bl,
return;
}
else {
- pas_book_view_notify_complete (view->book_view,
- GNOME_Evolution_Addressbook_BookViewListener_InvalidQuery);
+ pas_book_view_notify_complete (view,
+ GNOME_Evolution_Addressbook_InvalidQuery);
return;
}
}
static void
-ldap_get_view (PASBackend *backend,
- PASBook *book,
- const char *search,
- GNOME_Evolution_Addressbook_BookViewListener listener,
- int limit)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- PASBookView *book_view;
- PASBackendLDAPBookView *view;
-
- book_view = pas_book_view_new (listener);
-
- bonobo_object_ref(BONOBO_OBJECT(book));
- g_object_weak_ref (G_OBJECT (book_view), view_destroy, book);
-
- view = g_new0(PASBackendLDAPBookView, 1);
- view->book_view = book_view;
- view->search = g_strdup(search);
- view->card_sexp = pas_backend_card_sexp_new (view->search);
- view->blpriv = bl->priv;
- view->limit = limit;
-
- e_list_append(bl->priv->book_views, view);
-
- pas_book_respond_get_book_view (book,
- (book_view != NULL
- ? GNOME_Evolution_Addressbook_BookListener_Success
- : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */),
- book_view);
-
- pas_backend_ldap_search (bl, book, view);
-
- bonobo_object_unref (BONOBO_OBJECT (book_view));
-}
-
-static void
-pas_backend_ldap_process_get_book_view (PASBackend *backend,
- PASBook *book,
- PASGetBookViewRequest *req)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
-
- ldap_get_view (backend, book, req->search, req->listener,
- bl->priv->ldap_limit);
-}
-
-static void
-pas_backend_ldap_process_get_completion_view (PASBackend *backend,
- PASBook *book,
- PASGetCompletionViewRequest *req)
+pas_backend_ldap_process_start_book_view (PASBackend *backend,
+ PASBookView *view)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- ldap_get_view (backend, book, req->search, req->listener,
- MIN (bl->priv->ldap_limit, 100));
+ pas_backend_ldap_search (bl, NULL /* XXX ugh */, view);
}
static void
pas_backend_ldap_process_get_changes (PASBackend *backend,
PASBook *book,
- PASGetChangesRequest *req)
+ const char *change_id)
{
/* FIXME: implement */
}
-static void
-pas_backend_ldap_process_check_connection (PASBackend *backend,
- PASBook *book,
- PASCheckConnectionRequest *req)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
-
- pas_book_report_connection (book, bl->priv->connected);
-}
-
#define LDAP_SIMPLE_PREFIX "ldap/simple-"
#define SASL_PREFIX "sasl/"
static void
pas_backend_ldap_process_authenticate_user (PASBackend *backend,
PASBook *book,
- PASAuthenticateUserRequest *req)
+ const char *user,
+ const char *passwd,
+ const char *auth_method)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
int ldap_error;
char *dn = NULL;
- if (!strncasecmp (req->auth_method, LDAP_SIMPLE_PREFIX, strlen (LDAP_SIMPLE_PREFIX))) {
+ if (!strncasecmp (auth_method, LDAP_SIMPLE_PREFIX, strlen (LDAP_SIMPLE_PREFIX))) {
- if (!strcmp (req->auth_method, "ldap/simple-email")) {
+ if (!strcmp (auth_method, "ldap/simple-email")) {
LDAPMessage *res, *e;
- char *query = g_strdup_printf ("(mail=%s)", req->user);
+ char *query = g_strdup_printf ("(mail=%s)", user);
ldap_error = ldap_search_s (bl->priv->ldap,
bl->priv->ldap_rootdn,
@@ -3211,37 +2867,37 @@ pas_backend_ldap_process_authenticate_user (PASBackend *backend,
}
else {
pas_book_respond_authenticate_user (book,
- GNOME_Evolution_Addressbook_BookListener_PermissionDenied);
+ GNOME_Evolution_Addressbook_PermissionDenied);
return;
}
}
- else if (!strcmp (req->auth_method, "ldap/simple-binddn")) {
- dn = g_strdup (req->user);
+ else if (!strcmp (auth_method, "ldap/simple-binddn")) {
+ dn = g_strdup (user);
}
/* now authenticate against the DN we were either supplied or queried for */
printf ("simple auth as %s\n", dn);
ldap_error = ldap_simple_bind_s(bl->priv->ldap,
dn,
- req->passwd);
+ passwd);
pas_book_respond_authenticate_user (book,
ldap_error_to_response (ldap_error));
}
#ifdef ENABLE_SASL_BINDS
- else if (!strncasecmp (req->auth_method, SASL_PREFIX, strlen (SASL_PREFIX))) {
- g_print ("sasl bind (mech = %s) as %s", req->auth_method + strlen (SASL_PREFIX), req->user);
+ else if (!strncasecmp (auth_method, SASL_PREFIX, strlen (SASL_PREFIX))) {
+ g_print ("sasl bind (mech = %s) as %s", auth_method + strlen (SASL_PREFIX), user);
ldap_error = ldap_sasl_bind_s (bl->priv->ldap,
NULL,
- req->auth_method + strlen (SASL_PREFIX),
- req->passwd,
+ auth_method + strlen (SASL_PREFIX),
+ passwd,
NULL,
NULL,
NULL);
if (ldap_error == LDAP_NOT_SUPPORTED)
pas_book_respond_authenticate_user (book,
- GNOME_Evolution_Addressbook_BookListener_UnsupportedAuthenticationMethod);
+ GNOME_Evolution_Addressbook_UnsupportedAuthenticationMethod);
else
pas_book_respond_authenticate_user (book,
ldap_error_to_response (ldap_error));
@@ -3249,13 +2905,13 @@ pas_backend_ldap_process_authenticate_user (PASBackend *backend,
#endif
else {
pas_book_respond_authenticate_user (book,
- GNOME_Evolution_Addressbook_BookListener_UnsupportedAuthenticationMethod);
+ GNOME_Evolution_Addressbook_UnsupportedAuthenticationMethod);
return;
}
if (ldap_error == LDAP_SUCCESS) {
bl->priv->auth_dn = dn;
- bl->priv->auth_passwd = g_strdup (req->passwd);
+ bl->priv->auth_passwd = g_strdup (passwd);
pas_backend_set_is_writable (backend, TRUE);
@@ -3281,33 +2937,32 @@ pas_backend_ldap_process_authenticate_user (PASBackend *backend,
static void
pas_backend_ldap_process_get_supported_fields (PASBackend *backend,
- PASBook *book,
- PASGetSupportedFieldsRequest *req)
+ PASBook *book)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
pas_book_respond_get_supported_fields (book,
- GNOME_Evolution_Addressbook_BookListener_Success,
+ GNOME_Evolution_Addressbook_Success,
bl->priv->supported_fields);
}
static void
pas_backend_ldap_process_get_supported_auth_methods (PASBackend *backend,
- PASBook *book,
- PASGetSupportedAuthMethodsRequest *req)
+ PASBook *book)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
pas_book_respond_get_supported_auth_methods (book,
- GNOME_Evolution_Addressbook_BookListener_Success,
+ GNOME_Evolution_Addressbook_Success,
bl->priv->supported_auth_methods);
}
-static GNOME_Evolution_Addressbook_BookListener_CallStatus
+static GNOME_Evolution_Addressbook_CallStatus
pas_backend_ldap_load_uri (PASBackend *backend,
- const char *uri)
+ const char *uri,
+ gboolean only_if_exists)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
LDAPURLDesc *lud;
@@ -3383,17 +3038,7 @@ pas_backend_ldap_load_uri (PASBackend *backend,
return pas_backend_ldap_connect (bl);
} else
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
-}
-
-/* Get_uri handler for the addressbook LDAP backend */
-static const char *
-pas_backend_ldap_get_uri (PASBackend *backend)
-{
- PASBackendLDAP *bl;
-
- bl = PAS_BACKEND_LDAP (backend);
- return bl->priv->uri;
+ return GNOME_Evolution_Addressbook_OtherError;
}
static char*
@@ -3459,13 +3104,15 @@ pas_backend_ldap_dispose (GObject *object)
g_source_remove (bl->priv->poll_timeout);
}
- g_object_unref (bl->priv->book_views);
-
- if (bl->priv->supported_fields)
- g_object_unref (bl->priv->supported_fields);
+ if (bl->priv->supported_fields) {
+ g_list_foreach (bl->priv->supported_fields, (GFunc)g_free, NULL);
+ g_list_free (bl->priv->supported_fields);
+ }
- if (bl->priv->supported_auth_methods)
- g_object_unref (bl->priv->supported_auth_methods);
+ if (bl->priv->supported_auth_methods) {
+ g_list_foreach (bl->priv->supported_auth_methods, (GFunc)g_free, NULL);
+ g_list_free (bl->priv->supported_auth_methods);
+ }
g_free (bl->priv->uri);
@@ -3492,17 +3139,13 @@ pas_backend_ldap_class_init (PASBackendLDAPClass *klass)
/* Set the virtual methods. */
parent_class->load_uri = pas_backend_ldap_load_uri;
- parent_class->get_uri = pas_backend_ldap_get_uri;
parent_class->get_static_capabilities = pas_backend_ldap_get_static_capabilities;
- parent_class->create_card = pas_backend_ldap_process_create_card;
- parent_class->remove_cards = pas_backend_ldap_process_remove_cards;
- parent_class->modify_card = pas_backend_ldap_process_modify_card;
- parent_class->check_connection = pas_backend_ldap_process_check_connection;
- parent_class->get_vcard = pas_backend_ldap_process_get_vcard;
- parent_class->get_cursor = pas_backend_ldap_process_get_cursor;
- parent_class->get_book_view = pas_backend_ldap_process_get_book_view;
- parent_class->get_completion_view = pas_backend_ldap_process_get_completion_view;
+ parent_class->create_contact = pas_backend_ldap_process_create_contact;
+ parent_class->remove_contacts = pas_backend_ldap_process_remove_contacts;
+ parent_class->modify_contact = pas_backend_ldap_process_modify_contact;
+ parent_class->get_contact = pas_backend_ldap_process_get_contact;
+ parent_class->start_book_view = pas_backend_ldap_process_start_book_view;
parent_class->get_changes = pas_backend_ldap_process_get_changes;
parent_class->authenticate_user = pas_backend_ldap_process_authenticate_user;
parent_class->get_supported_fields = pas_backend_ldap_process_get_supported_fields;
@@ -3518,11 +3161,11 @@ pas_backend_ldap_init (PASBackendLDAP *backend)
priv = g_new0 (PASBackendLDAPPrivate, 1);
- priv->supported_fields = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL);
- priv->ldap_limit = 100;
- priv->id_to_op = g_hash_table_new (g_int_hash, g_int_equal);
- priv->poll_timeout = -1;
- priv->book_views = e_list_new (NULL, NULL, NULL);
+ priv->supported_fields = NULL;
+ priv->supported_auth_methods = NULL;
+ priv->ldap_limit = 100;
+ priv->id_to_op = g_hash_table_new (g_int_hash, g_int_equal);
+ priv->poll_timeout = -1;
backend->priv = priv;
}
diff --git a/addressbook/backend/pas/pas-backend-summary.c b/addressbook/backend/pas/pas-backend-summary.c
index 6c2c9a45c8..15f12cebc1 100644
--- a/addressbook/backend/pas/pas-backend-summary.c
+++ b/addressbook/backend/pas/pas-backend-summary.c
@@ -33,7 +33,7 @@
#include <gal/widgets/e-unicode.h>
-#include "ebook/e-card-simple.h"
+#include "ebook/e-contact.h"
#include "pas-backend-summary.h"
#include "e-util/e-sexp.h"
@@ -689,36 +689,29 @@ pas_backend_summary_save (PASBackendSummary *summary)
}
void
-pas_backend_summary_add_card (PASBackendSummary *summary, const char *vcard)
+pas_backend_summary_add_contact (PASBackendSummary *summary, EContact *contact)
{
- ECard *card;
- ECardSimple *simple;
PASBackendSummaryItem *new_item;
- card = e_card_new ((char*)vcard);
- simple = e_card_simple_new (card);
-
- new_item = g_new (PASBackendSummaryItem, 1);
-
- new_item->id = g_strdup (e_card_simple_get_id (simple));
- new_item->nickname = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_NICKNAME);
- new_item->full_name = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_FULL_NAME);
- new_item->given_name = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_GIVEN_NAME);
- new_item->surname = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_FAMILY_NAME);
- new_item->file_as = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_FILE_AS);
- new_item->email_1 = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_EMAIL);
- new_item->email_2 = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_EMAIL_2);
- new_item->email_3 = e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_EMAIL_3);
- new_item->list = e_card_evolution_list (card);
- new_item->list_show_addresses = e_card_evolution_list_show_addresses (card);
- new_item->wants_html = card->wants_html;
- new_item->wants_html_set = card->wants_html_set;
+ new_item = g_new0 (PASBackendSummaryItem, 1);
+
+ new_item->id = e_contact_get (contact, E_CONTACT_UID);
+ new_item->nickname = e_contact_get (contact, E_CONTACT_NICKNAME);
+ new_item->full_name = e_contact_get (contact, E_CONTACT_FULL_NAME);
+ new_item->given_name = e_contact_get (contact, E_CONTACT_GIVEN_NAME);
+ new_item->surname = e_contact_get (contact, E_CONTACT_FAMILY_NAME);
+ new_item->file_as = e_contact_get (contact, E_CONTACT_FILE_AS);
+ new_item->email_1 = e_contact_get (contact, E_CONTACT_EMAIL_1);
+ new_item->email_2 = e_contact_get (contact, E_CONTACT_EMAIL_2);
+ new_item->email_3 = e_contact_get (contact, E_CONTACT_EMAIL_3);
+ new_item->list = GPOINTER_TO_INT (e_contact_get (contact, E_CONTACT_IS_LIST));
+ new_item->list_show_addresses = GPOINTER_TO_INT (e_contact_get (contact, E_CONTACT_LIST_SHOW_ADDRESSES));
+ new_item->wants_html = GPOINTER_TO_INT (e_contact_get (contact, E_CONTACT_WANTS_HTML));
g_ptr_array_add (summary->priv->items, new_item);
g_hash_table_insert (summary->priv->id_to_item, new_item->id, new_item);
- g_object_unref (simple);
- g_object_unref (card);
+ g_object_unref (contact);
#ifdef SUMMARY_STATS
summary->priv->size += sizeof (PASBackendSummaryItem);
@@ -736,7 +729,7 @@ pas_backend_summary_add_card (PASBackendSummary *summary, const char *vcard)
}
void
-pas_backend_summary_remove_card (PASBackendSummary *summary, const char *id)
+pas_backend_summary_remove_contact (PASBackendSummary *summary, const char *id)
{
PASBackendSummaryItem *item = g_hash_table_lookup (summary->priv->id_to_item, id);
@@ -748,7 +741,7 @@ pas_backend_summary_remove_card (PASBackendSummary *summary, const char *id)
return;
}
- g_warning ("pas_backend_summary_remove_card: unable to locate id `%s'", id);
+ g_warning ("pas_backend_summary_remove_contact: unable to locate id `%s'", id);
}
static gboolean
@@ -1056,31 +1049,26 @@ pas_backend_summary_get_summary_vcard(PASBackendSummary *summary, const char *id
PASBackendSummaryItem *item = g_hash_table_lookup (summary->priv->id_to_item, id);
if (item) {
- ECard *card = e_card_new ("");
- ECardSimple *simple = e_card_simple_new (card);
+ EContact *contact = e_contact_new ();
char *vcard;
- e_card_simple_set_id (simple, item->id);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FILE_AS, item->file_as);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_GIVEN_NAME, item->given_name);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FAMILY_NAME, item->surname);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_NICKNAME, item->nickname);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FULL_NAME, item->full_name);
- e_card_simple_set_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL, item->email_1);
- e_card_simple_set_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL_2, item->email_2);
- e_card_simple_set_email (simple, E_CARD_SIMPLE_EMAIL_ID_EMAIL_3, item->email_3);
+ e_contact_set (contact, E_CONTACT_UID, item->id);
+ e_contact_set (contact, E_CONTACT_FILE_AS, item->file_as);
+ e_contact_set (contact, E_CONTACT_GIVEN_NAME, item->given_name);
+ e_contact_set (contact, E_CONTACT_FAMILY_NAME, item->surname);
+ e_contact_set (contact, E_CONTACT_NICKNAME, item->nickname);
+ e_contact_set (contact, E_CONTACT_FULL_NAME, item->full_name);
+ e_contact_set (contact, E_CONTACT_EMAIL_1, item->email_1);
+ e_contact_set (contact, E_CONTACT_EMAIL_2, item->email_2);
+ e_contact_set (contact, E_CONTACT_EMAIL_3, item->email_3);
- e_card_simple_sync_card (simple);
+ e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (item->list));
+ e_contact_set (contact, E_CONTACT_LIST_SHOW_ADDRESSES, GINT_TO_POINTER (item->list_show_addresses));
+ e_contact_set (contact, E_CONTACT_WANTS_HTML, GINT_TO_POINTER (item->wants_html));
- card->list = item->list;
- card->wants_html = item->wants_html;
- card->wants_html_set = item->wants_html_set;
- card->list_show_addresses = item->list_show_addresses;
+ vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- vcard = e_card_simple_get_vcard (simple);
-
- g_object_unref (simple);
- g_object_unref (card);
+ g_object_unref (contact);
return vcard;
}
diff --git a/addressbook/backend/pas/pas-backend-summary.h b/addressbook/backend/pas/pas-backend-summary.h
index 54083855d5..bb07e0fb27 100644
--- a/addressbook/backend/pas/pas-backend-summary.h
+++ b/addressbook/backend/pas/pas-backend-summary.h
@@ -26,6 +26,8 @@
#include <glib.h>
#include <glib-object.h>
+#include <pas/pas-types.h>
+#include <ebook/e-contact.h>
#define PAS_TYPE_BACKEND_SUMMARY (pas_backend_summary_get_type ())
#define PAS_BACKEND_SUMMARY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_SUMMARY, PASBackendSummary))
@@ -36,14 +38,14 @@
typedef struct _PASBackendSummaryPrivate PASBackendSummaryPrivate;
-typedef struct {
+struct _PASBackendSummary{
GObject parent_object;
PASBackendSummaryPrivate *priv;
-} PASBackendSummary;
+};
-typedef struct {
+struct _PASBackendSummaryClass{
GObjectClass parent_class;
-} PASBackendSummaryClass;
+};
PASBackendSummary* pas_backend_summary_new (const char *summary_path,
int flush_timeout_millis);
@@ -55,8 +57,8 @@ gboolean pas_backend_summary_load (PASBackendSummary *summ
/* returns FALSE if the save fails, TRUE if it succeeds (or isn't required due to no changes) */
gboolean pas_backend_summary_save (PASBackendSummary *summary);
-void pas_backend_summary_add_card (PASBackendSummary *summary, const char *vcard);
-void pas_backend_summary_remove_card (PASBackendSummary *summary, const char *id);
+void pas_backend_summary_add_contact (PASBackendSummary *summary, EContact *contact);
+void pas_backend_summary_remove_contact (PASBackendSummary *summary, const char *id);
void pas_backend_summary_touch (PASBackendSummary *summary);
diff --git a/addressbook/backend/pas/pas-backend-sync.c b/addressbook/backend/pas/pas-backend-sync.c
new file mode 100644
index 0000000000..45063eddc6
--- /dev/null
+++ b/addressbook/backend/pas/pas-backend-sync.c
@@ -0,0 +1,395 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Author:
+ * Chris Toshok (toshok@ximian.com)
+ *
+ * Copyright (C) 2003, Ximian, Inc.
+ */
+
+#include <config.h>
+#include "pas-backend-sync.h"
+#include "pas-marshal.h"
+
+struct _PASBackendSyncPrivate {
+ int mumble;
+};
+
+static GObjectClass *parent_class;
+
+gboolean
+pas_backend_sync_construct (PASBackendSync *backend)
+{
+ return TRUE;
+}
+
+PASBackendSyncStatus
+pas_backend_sync_create_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *vcard,
+ EContact **contact)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (vcard, GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (contact, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->create_contact_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->create_contact_sync) (backend, book, vcard, contact);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_remove (PASBackendSync *backend,
+ PASBook *book)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->remove_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->remove_sync) (backend, book);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_remove_contacts (PASBackendSync *backend,
+ PASBook *book,
+ GList *id_list,
+ GList **removed_ids)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (id_list, GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (removed_ids, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->remove_contacts_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->remove_contacts_sync) (backend, book, id_list, removed_ids);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_modify_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *vcard,
+ EContact **contact)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (vcard, GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (contact, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->modify_contact_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->modify_contact_sync) (backend, book, vcard, contact);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_get_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *id,
+ char **vcard)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (id, GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (vcard, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_contact_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_contact_sync) (backend, book, id, vcard);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_get_contact_list (PASBackendSync *backend,
+ PASBook *book,
+ const char *query,
+ GList **contacts)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (query, GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (contacts, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_contact_list_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_contact_list_sync) (backend, book, query, contacts);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_get_changes (PASBackendSync *backend,
+ PASBook *book,
+ const char *change_id,
+ GList **changes)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (change_id, GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (changes, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_changes_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_changes_sync) (backend, book, change_id, changes);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_authenticate_user (PASBackendSync *backend,
+ PASBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (user && passwd && auth_method, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->authenticate_user_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->authenticate_user_sync) (backend, book, user, passwd, auth_method);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_get_supported_fields (PASBackendSync *backend,
+ PASBook *book,
+ GList **fields)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (fields, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_supported_fields_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_supported_fields_sync) (backend, book, fields);
+}
+
+PASBackendSyncStatus
+pas_backend_sync_get_supported_auth_methods (PASBackendSync *backend,
+ PASBook *book,
+ GList **methods)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (methods, GNOME_Evolution_Addressbook_OtherError);
+
+ g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_supported_auth_methods_sync);
+
+ return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_supported_auth_methods_sync) (backend, book, methods);
+}
+
+static void
+_pas_backend_remove (PASBackend *backend,
+ PASBook *book)
+{
+ PASBackendSyncStatus status;
+
+ status = pas_backend_sync_remove (PAS_BACKEND_SYNC (backend), book);
+
+ pas_book_respond_remove (book, status);
+}
+
+static void
+_pas_backend_create_contact (PASBackend *backend,
+ PASBook *book,
+ const char *vcard)
+{
+ PASBackendSyncStatus status;
+ EContact *contact;
+
+ status = pas_backend_sync_create_contact (PAS_BACKEND_SYNC (backend), book, vcard, &contact);
+
+ pas_book_respond_create (book, status, contact);
+
+ g_object_unref (contact);
+}
+
+static void
+_pas_backend_remove_contacts (PASBackend *backend,
+ PASBook *book,
+ GList *id_list)
+{
+ PASBackendSyncStatus status;
+ GList *ids = NULL;
+
+ status = pas_backend_sync_remove_contacts (PAS_BACKEND_SYNC (backend), book, id_list, &ids);
+
+ pas_book_respond_remove_contacts (book, status, ids);
+
+ g_list_free (ids);
+}
+
+static void
+_pas_backend_modify_contact (PASBackend *backend,
+ PASBook *book,
+ const char *vcard)
+{
+ PASBackendSyncStatus status;
+ EContact *contact;
+
+ status = pas_backend_sync_modify_contact (PAS_BACKEND_SYNC (backend), book, vcard, &contact);
+
+ pas_book_respond_modify (book, status, contact);
+
+ g_object_unref (contact);
+}
+
+static void
+_pas_backend_get_contact (PASBackend *backend,
+ PASBook *book,
+ const char *id)
+{
+ PASBackendSyncStatus status;
+ char *vcard;
+
+ status = pas_backend_sync_get_contact (PAS_BACKEND_SYNC (backend), book, id, &vcard);
+
+ pas_book_respond_get_contact (book, status, vcard);
+
+ g_free (vcard);
+}
+
+static void
+_pas_backend_get_contact_list (PASBackend *backend,
+ PASBook *book,
+ const char *query)
+{
+ PASBackendSyncStatus status;
+ GList *cards = NULL;
+
+ status = pas_backend_sync_get_contact_list (PAS_BACKEND_SYNC (backend), book, query, &cards);
+
+ pas_book_respond_get_contact_list (book, status, cards);
+}
+
+static void
+_pas_backend_get_changes (PASBackend *backend,
+ PASBook *book,
+ const char *change_id)
+{
+ PASBackendSyncStatus status;
+ GList *changes = NULL;
+
+ status = pas_backend_sync_get_changes (PAS_BACKEND_SYNC (backend), book, change_id, &changes);
+
+ pas_book_respond_get_changes (book, status, changes);
+
+ /* XXX free view? */
+}
+
+static void
+_pas_backend_authenticate_user (PASBackend *backend,
+ PASBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method)
+{
+ PASBackendSyncStatus status;
+
+ status = pas_backend_sync_authenticate_user (PAS_BACKEND_SYNC (backend), book, user, passwd, auth_method);
+
+ pas_book_respond_authenticate_user (book, status);
+}
+
+static void
+_pas_backend_get_supported_fields (PASBackend *backend,
+ PASBook *book)
+{
+ PASBackendSyncStatus status;
+ GList *fields = NULL;
+
+ status = pas_backend_sync_get_supported_fields (PAS_BACKEND_SYNC (backend), book, &fields);
+
+ pas_book_respond_get_supported_fields (book, status, fields);
+
+ g_list_foreach (fields, (GFunc)g_free, NULL);
+ g_list_free (fields);
+}
+
+static void
+_pas_backend_get_supported_auth_methods (PASBackend *backend,
+ PASBook *book)
+{
+ PASBackendSyncStatus status;
+ GList *methods = NULL;
+
+ status = pas_backend_sync_get_supported_auth_methods (PAS_BACKEND_SYNC (backend), book, &methods);
+
+ pas_book_respond_get_supported_auth_methods (book, status, methods);
+
+ g_list_foreach (methods, (GFunc)g_free, NULL);
+ g_list_free (methods);
+}
+
+static void
+pas_backend_sync_init (PASBackendSync *backend)
+{
+ PASBackendSyncPrivate *priv;
+
+ priv = g_new0 (PASBackendSyncPrivate, 1);
+
+ backend->priv = priv;
+}
+
+static void
+pas_backend_sync_dispose (GObject *object)
+{
+ PASBackendSync *backend;
+
+ backend = PAS_BACKEND_SYNC (object);
+
+ if (backend->priv) {
+ g_free (backend->priv);
+
+ backend->priv = NULL;
+ }
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+pas_backend_sync_class_init (PASBackendSyncClass *klass)
+{
+ GObjectClass *object_class;
+ PASBackendClass *backend_class = PAS_BACKEND_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class = (GObjectClass *) klass;
+
+ backend_class->remove = _pas_backend_remove;
+ backend_class->create_contact = _pas_backend_create_contact;
+ backend_class->remove_contacts = _pas_backend_remove_contacts;
+ backend_class->modify_contact = _pas_backend_modify_contact;
+ backend_class->get_contact = _pas_backend_get_contact;
+ backend_class->get_contact_list = _pas_backend_get_contact_list;
+ backend_class->get_changes = _pas_backend_get_changes;
+ backend_class->authenticate_user = _pas_backend_authenticate_user;
+ backend_class->get_supported_fields = _pas_backend_get_supported_fields;
+ backend_class->get_supported_auth_methods = _pas_backend_get_supported_auth_methods;
+
+ object_class->dispose = pas_backend_sync_dispose;
+}
+
+/**
+ * pas_backend_get_type:
+ */
+GType
+pas_backend_sync_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo info = {
+ sizeof (PASBackendSyncClass),
+ NULL, /* base_class_init */
+ NULL, /* base_class_finalize */
+ (GClassInitFunc) pas_backend_sync_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PASBackendSync),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) pas_backend_sync_init
+ };
+
+ type = g_type_register_static (PAS_TYPE_BACKEND, "PASBackendSync", &info, 0);
+ }
+
+ return type;
+}
diff --git a/addressbook/backend/pas/pas-backend-sync.h b/addressbook/backend/pas/pas-backend-sync.h
new file mode 100644
index 0000000000..2e176d9f5d
--- /dev/null
+++ b/addressbook/backend/pas/pas-backend-sync.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ */
+
+#ifndef __PAS_BACKEND_SYNC_H__
+#define __PAS_BACKEND_SYNC_H__
+
+#include <glib.h>
+#include <pas/pas-types.h>
+#include <pas/pas-backend.h>
+#include <pas/addressbook.h>
+
+#define PAS_TYPE_BACKEND_SYNC (pas_backend_sync_get_type ())
+#define PAS_BACKEND_SYNC(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_SYNC, PASBackendSync))
+#define PAS_BACKEND_SYNC_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_TYPE_BACKEND_SYNC, PASBackendSyncClass))
+#define PAS_IS_BACKEND_SYNC(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_SYNC))
+#define PAS_IS_BACKEND_SYNC_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_SYNC))
+#define PAS_BACKEND_SYNC_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((k), PAS_TYPE_BACKEND_SYNC, PASBackendSyncClass))
+
+typedef struct _PASBackendSyncPrivate PASBackendSyncPrivate;
+
+typedef GNOME_Evolution_Addressbook_CallStatus PASBackendSyncStatus;
+
+struct _PASBackendSync {
+ PASBackend parent_object;
+ PASBackendSyncPrivate *priv;
+};
+
+struct _PASBackendSyncClass {
+ PASBackendClass parent_class;
+
+ /* Virtual methods */
+ PASBackendSyncStatus (*remove_sync) (PASBackendSync *backend, PASBook *book);
+ PASBackendSyncStatus (*create_contact_sync) (PASBackendSync *backend, PASBook *book,
+ const char *vcard, EContact **contact);
+ PASBackendSyncStatus (*remove_contacts_sync) (PASBackendSync *backend, PASBook *book,
+ GList *id_list, GList **removed_ids);
+ PASBackendSyncStatus (*modify_contact_sync) (PASBackendSync *backend, PASBook *book,
+ const char *vcard, EContact **contact);
+ PASBackendSyncStatus (*get_contact_sync) (PASBackendSync *backend, PASBook *book,
+ const char *id, char **vcard);
+ PASBackendSyncStatus (*get_contact_list_sync) (PASBackendSync *backend, PASBook *book,
+ const char *query, GList **contacts);
+ PASBackendSyncStatus (*get_changes_sync) (PASBackendSync *backend, PASBook *book,
+ const char *change_id, GList **changes);
+ PASBackendSyncStatus (*authenticate_user_sync) (PASBackendSync *backend, PASBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method);
+ PASBackendSyncStatus (*get_supported_fields_sync) (PASBackendSync *backend, PASBook *book,
+ GList **fields);
+ PASBackendSyncStatus (*get_supported_auth_methods_sync) (PASBackendSync *backend, PASBook *book,
+ GList **methods);
+
+ /* Padding for future expansion */
+ void (*_pas_reserved0) (void);
+ void (*_pas_reserved1) (void);
+ void (*_pas_reserved2) (void);
+ void (*_pas_reserved3) (void);
+ void (*_pas_reserved4) (void);
+
+};
+
+typedef PASBackendSync * (*PASBackendSyncFactoryFn) (void);
+
+gboolean pas_backend_sync_construct (PASBackendSync *backend);
+
+GType pas_backend_sync_get_type (void);
+
+PASBackendSyncStatus pas_backend_sync_remove (PASBackendSync *backend, PASBook *book);
+PASBackendSyncStatus pas_backend_sync_create_contact (PASBackendSync *backend, PASBook *book, const char *vcard, EContact **contact);
+PASBackendSyncStatus pas_backend_sync_remove_contacts (PASBackendSync *backend, PASBook *book, GList *id_list, GList **removed_ids);
+PASBackendSyncStatus pas_backend_sync_modify_contact (PASBackendSync *backend, PASBook *book, const char *vcard, EContact **contact);
+PASBackendSyncStatus pas_backend_sync_get_contact (PASBackendSync *backend, PASBook *book, const char *id, char **vcard);
+PASBackendSyncStatus pas_backend_sync_get_contact_list (PASBackendSync *backend, PASBook *book, const char *query, GList **contacts);
+PASBackendSyncStatus pas_backend_sync_get_changes (PASBackendSync *backend, PASBook *book, const char *change_id, GList **changes);
+PASBackendSyncStatus pas_backend_sync_authenticate_user (PASBackendSync *backend, PASBook *book, const char *user, const char *passwd, const char *auth_method);
+PASBackendSyncStatus pas_backend_sync_get_supported_fields (PASBackendSync *backend, PASBook *book, GList **fields);
+PASBackendSyncStatus pas_backend_sync_get_supported_auth_methods (PASBackendSync *backend, PASBook *book, GList **methods);
+
+#endif /* ! __PAS_BACKEND_SYNC_H__ */
diff --git a/addressbook/backend/pas/pas-backend-vcf.c b/addressbook/backend/pas/pas-backend-vcf.c
new file mode 100644
index 0000000000..3765fd978e
--- /dev/null
+++ b/addressbook/backend/pas/pas-backend-vcf.c
@@ -0,0 +1,632 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Author:
+ * Chris Toshok (toshok@ximian.com)
+ *
+ * Copyright (C) 2003, Ximian, Inc.
+ */
+
+#include "config.h"
+#include "pas-backend-vcf.h"
+#include "pas-backend-card-sexp.h"
+#include "pas-book.h"
+#include "pas-book-view.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/stat.h>
+
+#include <gal/util/e-util.h>
+#include <gal/widgets/e-unicode.h>
+
+#include <ebook/e-contact.h>
+#include <libgnome/gnome-i18n.h>
+
+#define PAS_ID_PREFIX "pas-id-"
+#define FILE_FLUSH_TIMEOUT 5000
+
+static PASBackendSyncClass *pas_backend_vcf_parent_class;
+typedef struct _PASBackendVCFBookView PASBackendVCFBookView;
+typedef struct _PASBackendVCFSearchContext PASBackendVCFSearchContext;
+
+struct _PASBackendVCFPrivate {
+ char *uri;
+ char *filename;
+ GHashTable *contacts;
+ gboolean dirty;
+ int flush_timeout_tag;
+};
+
+static char *
+pas_backend_vcf_create_unique_id ()
+{
+ /* use a 32 counter and the 32 bit timestamp to make an id.
+ it's doubtful 2^32 id's will be created in a second, so we
+ should be okay. */
+ static guint c = 0;
+ return g_strdup_printf (PAS_ID_PREFIX "%08lX%08X", time(NULL), c++);
+}
+
+typedef struct {
+ PASBackendVCF *bvcf;
+ PASBook *book;
+ PASBookView *view;
+} VCFBackendSearchClosure;
+
+static void
+free_search_closure (VCFBackendSearchClosure *closure)
+{
+ g_free (closure);
+}
+
+static void
+foreach_search_compare (char *id, char *vcard_string, VCFBackendSearchClosure *closure)
+{
+ EContact *contact;
+
+ contact = e_contact_new_from_vcard (vcard_string);
+ pas_book_view_notify_update (closure->view, contact);
+ g_object_unref (contact);
+}
+
+static gboolean
+pas_backend_vcf_search_timeout (gpointer data)
+{
+ VCFBackendSearchClosure *closure = data;
+
+ g_hash_table_foreach (closure->bvcf->priv->contacts,
+ (GHFunc)foreach_search_compare,
+ closure);
+
+ pas_book_view_notify_complete (closure->view, GNOME_Evolution_Addressbook_Success);
+
+ free_search_closure (closure);
+
+ return FALSE;
+}
+
+
+static void
+pas_backend_vcf_search (PASBackendVCF *bvcf,
+ PASBookView *book_view)
+{
+ const char *query = pas_book_view_get_card_query (book_view);
+ VCFBackendSearchClosure *closure = g_new0 (VCFBackendSearchClosure, 1);
+
+ if ( ! strcmp (query, "(contains \"x-evolution-any-field\" \"\")"))
+ pas_book_view_notify_status_message (book_view, _("Loading..."));
+ else
+ pas_book_view_notify_status_message (book_view, _("Searching..."));
+
+ closure->view = book_view;
+ closure->bvcf = bvcf;
+
+ g_idle_add (pas_backend_vcf_search_timeout, closure);
+}
+
+static void
+insert_contact (PASBackendVCF *vcf, char *vcard)
+{
+ EContact *contact = e_contact_new_from_vcard (vcard);
+ char *id;
+
+ id = e_contact_get (contact, E_CONTACT_UID);
+ if (id)
+ g_hash_table_insert (vcf->priv->contacts,
+ id,
+ e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30));
+}
+
+static void
+load_file (PASBackendVCF *vcf)
+{
+ FILE *fp;
+ GString *str;
+ char buf[1024];
+
+ fp = fopen (vcf->priv->filename, "r");
+ if (!fp) {
+ g_warning ("failed to open `%s' for reading", vcf->priv->filename);
+ return;
+ }
+
+ str = g_string_new ("");
+
+ while (fgets (buf, sizeof (buf), fp)) {
+ if (!strcmp (buf, "\r\n")) {
+ /* if the string has accumulated some stuff, create a contact for it and start over */
+ if (str->len) {
+ insert_contact (vcf, str->str);
+ g_string_assign (str, "");
+ }
+ }
+ else {
+ g_string_append (str, buf);
+ }
+ }
+ if (str->len) {
+ insert_contact (vcf, str->str);
+ }
+
+ g_string_free (str, TRUE);
+
+ fclose (fp);
+}
+
+static void
+foreach_build_list (char *id, char *vcard_string, GList **list)
+{
+ *list = g_list_append (*list, e_contact_new_from_vcard (vcard_string));
+}
+
+static gboolean
+save_file (PASBackendVCF *vcf)
+{
+ GList *contacts = NULL;
+ GList *l;
+ char *new_path;
+ int fd, rv;
+
+ g_hash_table_foreach (vcf->priv->contacts, (GHFunc)foreach_build_list, &contacts);
+
+ new_path = g_strdup_printf ("%s.new", vcf->priv->filename);
+
+ fd = open (new_path, O_CREAT | O_TRUNC | O_WRONLY, 0666);
+
+ for (l = contacts; l; l = l->next) {
+ EContact *contact = l->data;
+ char *vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ int len = strlen (vcard_str);
+
+ rv = write (fd, vcard_str, len);
+ g_free (vcard_str);
+ if (rv < len) {
+ /* XXX */
+ g_warning ("write failed. we need to handle short writes\n");
+ close (fd);
+ unlink (new_path);
+ return FALSE;
+ }
+
+ rv = write (fd, "\r\n", 2);
+ if (rv < 2) {
+ /* XXX */
+ g_warning ("write failed. we need to handle short writes\n");
+ close (fd);
+ unlink (new_path);
+ return FALSE;
+ }
+ }
+
+ if (0 > rename (new_path, vcf->priv->filename)) {
+ g_warning ("Failed to rename %s: %s\n", vcf->priv->filename, strerror(errno));
+ unlink (new_path);
+ return FALSE;
+ }
+
+ g_list_foreach (contacts, (GFunc)g_object_unref, NULL);
+ g_list_free (contacts);
+ g_free (new_path);
+
+ vcf->priv->dirty = FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+vcf_flush_file (gpointer data)
+{
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (data);
+
+ if (!bvcf->priv->dirty) {
+ bvcf->priv->flush_timeout_tag = 0;
+ return FALSE;
+ }
+
+ if (!save_file (bvcf)) {
+ g_warning ("failed to flush the .vcf file to disk, will try again next timeout");
+ return TRUE;
+ }
+
+ bvcf->priv->flush_timeout_tag = 0;
+ return FALSE;
+}
+
+static EContact *
+do_create(PASBackendVCF *bvcf,
+ const char *vcard_req,
+ gboolean dirty_the_file)
+{
+ char *id;
+ EContact *contact;
+ char *vcard;
+
+ id = pas_backend_vcf_create_unique_id ();
+
+ contact = e_contact_new_from_vcard (vcard_req);
+ e_contact_set(contact, E_CONTACT_UID, id);
+ vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+
+ g_hash_table_insert (bvcf->priv->contacts, id, vcard);
+
+ if (dirty_the_file) {
+ bvcf->priv->dirty = TRUE;
+
+ if (!bvcf->priv->flush_timeout_tag)
+ bvcf->priv->flush_timeout_tag = g_timeout_add (FILE_FLUSH_TIMEOUT,
+ vcf_flush_file, bvcf);
+ }
+
+ return contact;
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_create_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *vcard,
+ EContact **contact)
+{
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
+
+ *contact = do_create(bvcf, vcard, TRUE);
+ if (*contact) {
+ return GNOME_Evolution_Addressbook_Success;
+ }
+ else {
+ /* XXX need a different call status for this case, i
+ think */
+ return GNOME_Evolution_Addressbook_ContactNotFound;
+ }
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_remove_contacts (PASBackendSync *backend,
+ PASBook *book,
+ GList *id_list,
+ GList **ids)
+{
+ /* FIXME: make this handle bulk deletes like the file backend does */
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
+ char *id = id_list->data;
+
+ if (!g_hash_table_remove (bvcf->priv->contacts, id)) {
+ return GNOME_Evolution_Addressbook_ContactNotFound;
+ }
+ else {
+ bvcf->priv->dirty = TRUE;
+ if (!bvcf->priv->flush_timeout_tag)
+ bvcf->priv->flush_timeout_tag = g_timeout_add (FILE_FLUSH_TIMEOUT,
+ vcf_flush_file, bvcf);
+
+ *ids = g_list_append (*ids, id);
+
+ return GNOME_Evolution_Addressbook_Success;
+ }
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_modify_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *vcard,
+ EContact **contact)
+{
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
+ char *old_id, *old_vcard_string;
+ const char *id;
+
+ /* create a new ecard from the request data */
+ *contact = e_contact_new_from_vcard (vcard);
+ id = e_contact_get_const (*contact, E_CONTACT_UID);
+
+ if (!g_hash_table_lookup_extended (bvcf->priv->contacts, id, (gpointer)&old_id, (gpointer)&old_vcard_string)) {
+ return GNOME_Evolution_Addressbook_ContactNotFound;
+ }
+ else {
+ g_hash_table_insert (bvcf->priv->contacts, old_id, g_strdup (vcard));
+
+ g_free (old_vcard_string);
+
+ return GNOME_Evolution_Addressbook_Success;
+ }
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_get_contact (PASBackendSync *backend,
+ PASBook *book,
+ const char *id,
+ char **vcard)
+{
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
+ char *v;
+
+ v = g_hash_table_lookup (bvcf->priv->contacts, id);
+
+ if (v) {
+ *vcard = g_strdup (v);
+ return GNOME_Evolution_Addressbook_Success;
+ } else {
+ *vcard = g_strdup ("");
+ return GNOME_Evolution_Addressbook_ContactNotFound;
+ }
+}
+
+
+typedef struct {
+ PASBackendVCF *bvcf;
+ gboolean search_needed;
+ PASBackendCardSExp *card_sexp;
+ GList *list;
+} GetContactListClosure;
+
+static void
+foreach_get_contact_compare (char *id, char *vcard_string, GetContactListClosure *closure)
+{
+ if ((!closure->search_needed) || pas_backend_card_sexp_match_vcard (closure->card_sexp, vcard_string)) {
+ closure->list = g_list_append (closure->list, g_strdup (vcard_string));
+ }
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_get_contact_list (PASBackendSync *backend,
+ PASBook *book,
+ const char *query,
+ GList **contacts)
+{
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
+ const char *search = query;
+ GetContactListClosure closure;
+
+ closure.bvcf = bvcf;
+ closure.search_needed = strcmp (search, "(contains \"x-evolution-any-field\" \"\")");
+ closure.card_sexp = pas_backend_card_sexp_new (search);
+ closure.list = NULL;
+
+ g_hash_table_foreach (bvcf->priv->contacts, (GHFunc)foreach_get_contact_compare, &closure);
+
+ g_object_unref (closure.card_sexp);
+
+ *contacts = closure.list;
+ return GNOME_Evolution_Addressbook_Success;
+}
+
+static void
+pas_backend_vcf_start_book_view (PASBackend *backend,
+ PASBookView *book_view)
+{
+ pas_backend_vcf_search (PAS_BACKEND_VCF (backend), book_view);
+}
+
+static char *
+pas_backend_vcf_extract_path_from_uri (const char *uri)
+{
+ g_assert (strncasecmp (uri, "vcf://", 6) == 0);
+
+ return g_strdup (uri + 6);
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_authenticate_user (PASBackendSync *backend,
+ PASBook *book,
+ const char *user,
+ const char *passwd,
+ const char *auth_method)
+{
+ return GNOME_Evolution_Addressbook_Success;
+}
+
+static PASBackendSyncStatus
+pas_backend_vcf_process_get_supported_fields (PASBackendSync *backend,
+ PASBook *book,
+ GList **fields_out)
+{
+ GList *fields = NULL;
+ int i;
+
+ /* XXX we need a way to say "we support everything", since the
+ vcf backend does */
+ for (i = 0; i < E_CONTACT_FIELD_LAST; i ++)
+ fields = g_list_append (fields, (char*)e_contact_field_name (i));
+
+ *fields_out = fields;
+ return GNOME_Evolution_Addressbook_Success;
+}
+
+#include "ximian-vcard.h"
+
+static GNOME_Evolution_Addressbook_CallStatus
+pas_backend_vcf_load_uri (PASBackend *backend,
+ const char *uri,
+ gboolean only_if_exists)
+{
+ PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
+ char *filename;
+ gboolean writable = FALSE;
+ int fd;
+
+ g_free(bvcf->priv->uri);
+ bvcf->priv->uri = g_strdup (uri);
+
+ bvcf->priv->filename = filename = pas_backend_vcf_extract_path_from_uri (uri);
+
+ fd = open (filename, O_RDWR);
+
+ bvcf->priv->contacts = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_free);
+
+ if (fd != -1) {
+ writable = TRUE;
+ } else {
+ fd = open (filename, O_RDONLY);
+
+ if (fd == -1) {
+ fd = open (filename, O_CREAT, 0666);
+
+ if (fd != -1 && !only_if_exists) {
+ EContact *contact;
+
+ contact = do_create(bvcf, XIMIAN_VCARD, FALSE);
+ save_file (bvcf);
+
+ /* XXX check errors here */
+ g_object_unref (contact);
+
+ writable = TRUE;
+ }
+ }
+ }
+
+ if (fd == -1) {
+ g_warning ("Failed to open addressbook at uri `%s'", uri);
+ g_warning ("error == %s", strerror(errno));
+ return GNOME_Evolution_Addressbook_OtherError;
+ }
+
+ close (fd); /* XXX ugh */
+ load_file (bvcf);
+
+ pas_backend_set_is_loaded (backend, TRUE);
+ pas_backend_set_is_writable (backend, writable);
+
+ return GNOME_Evolution_Addressbook_Success;
+}
+
+static char *
+pas_backend_vcf_get_static_capabilities (PASBackend *backend)
+{
+ return g_strdup("local,do-initial-query");
+}
+
+static GNOME_Evolution_Addressbook_CallStatus
+pas_backend_vcf_cancel_operation (PASBackend *backend, PASBook *book)
+{
+ return GNOME_Evolution_Addressbook_CouldNotCancel;
+}
+
+static gboolean
+pas_backend_vcf_construct (PASBackendVCF *backend)
+{
+ g_assert (backend != NULL);
+ g_assert (PAS_IS_BACKEND_VCF (backend));
+
+ if (! pas_backend_construct (PAS_BACKEND (backend)))
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * pas_backend_vcf_new:
+ */
+PASBackend *
+pas_backend_vcf_new (void)
+{
+ PASBackendVCF *backend;
+
+ backend = g_object_new (PAS_TYPE_BACKEND_VCF, NULL);
+
+ if (! pas_backend_vcf_construct (backend)) {
+ g_object_unref (backend);
+
+ return NULL;
+ }
+
+ return PAS_BACKEND (backend);
+}
+
+static void
+pas_backend_vcf_dispose (GObject *object)
+{
+ PASBackendVCF *bvcf;
+
+ bvcf = PAS_BACKEND_VCF (object);
+
+ if (bvcf->priv) {
+
+ if (bvcf->priv->dirty)
+ save_file (bvcf);
+
+ if (bvcf->priv->flush_timeout_tag) {
+ g_source_remove (bvcf->priv->flush_timeout_tag);
+ bvcf->priv->flush_timeout_tag = 0;
+ }
+
+ g_free (bvcf->priv->uri);
+ g_free (bvcf->priv->filename);
+
+ g_free (bvcf->priv);
+ bvcf->priv = NULL;
+ }
+
+ G_OBJECT_CLASS (pas_backend_vcf_parent_class)->dispose (object);
+}
+
+static void
+pas_backend_vcf_class_init (PASBackendVCFClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ PASBackendSyncClass *sync_class;
+ PASBackendClass *backend_class;
+
+ pas_backend_vcf_parent_class = g_type_class_peek_parent (klass);
+
+ sync_class = PAS_BACKEND_SYNC_CLASS (klass);
+ backend_class = PAS_BACKEND_CLASS (klass);
+
+ /* Set the virtual methods. */
+ backend_class->load_uri = pas_backend_vcf_load_uri;
+ backend_class->get_static_capabilities = pas_backend_vcf_get_static_capabilities;
+ backend_class->start_book_view = pas_backend_vcf_start_book_view;
+ backend_class->cancel_operation = pas_backend_vcf_cancel_operation;
+
+ sync_class->create_contact_sync = pas_backend_vcf_process_create_contact;
+ sync_class->remove_contacts_sync = pas_backend_vcf_process_remove_contacts;
+ sync_class->modify_contact_sync = pas_backend_vcf_process_modify_contact;
+ sync_class->get_contact_sync = pas_backend_vcf_process_get_contact;
+ sync_class->get_contact_list_sync = pas_backend_vcf_process_get_contact_list;
+ sync_class->authenticate_user_sync = pas_backend_vcf_process_authenticate_user;
+ sync_class->get_supported_fields_sync = pas_backend_vcf_process_get_supported_fields;
+
+ object_class->dispose = pas_backend_vcf_dispose;
+}
+
+static void
+pas_backend_vcf_init (PASBackendVCF *backend)
+{
+ PASBackendVCFPrivate *priv;
+
+ priv = g_new0 (PASBackendVCFPrivate, 1);
+ priv->uri = NULL;
+
+ backend->priv = priv;
+}
+
+/**
+ * pas_backend_vcf_get_type:
+ */
+GType
+pas_backend_vcf_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo info = {
+ sizeof (PASBackendVCFClass),
+ NULL, /* base_class_init */
+ NULL, /* base_class_finalize */
+ (GClassInitFunc) pas_backend_vcf_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PASBackendVCF),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) pas_backend_vcf_init
+ };
+
+ type = g_type_register_static (PAS_TYPE_BACKEND_SYNC, "PASBackendVCF", &info, 0);
+ }
+
+ return type;
+}
diff --git a/addressbook/backend/pas/pas-backend-vcf.h b/addressbook/backend/pas/pas-backend-vcf.h
new file mode 100644
index 0000000000..81c872dcf1
--- /dev/null
+++ b/addressbook/backend/pas/pas-backend-vcf.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Author:
+ * Chris Toshok (toshok@ximian.com)
+ * Copyright (C) 2003, Ximian, Inc.
+ */
+
+#ifndef __PAS_BACKEND_VCF_H__
+#define __PAS_BACKEND_VCF_H__
+
+#include "pas-backend-sync.h"
+
+#define PAS_TYPE_BACKEND_VCF (pas_backend_vcf_get_type ())
+#define PAS_BACKEND_VCF(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_VCF, PASBackendVCF))
+#define PAS_BACKEND_VCF_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendVCFClass))
+#define PAS_IS_BACKEND_VCF(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_VCF))
+#define PAS_IS_BACKEND_VCF_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_VCF))
+#define PAS_BACKEND_VCF_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BACKEND_VCF, PASBackendVCFClass))
+
+typedef struct _PASBackendVCFPrivate PASBackendVCFPrivate;
+
+typedef struct {
+ PASBackendSync parent_object;
+ PASBackendVCFPrivate *priv;
+} PASBackendVCF;
+
+typedef struct {
+ PASBackendSyncClass parent_class;
+} PASBackendVCFClass;
+
+PASBackend *pas_backend_vcf_new (void);
+GType pas_backend_vcf_get_type (void);
+
+#endif /* ! __PAS_BACKEND_VCF_H__ */
+
diff --git a/addressbook/backend/pas/pas-backend.c b/addressbook/backend/pas/pas-backend.c
index acc6ed2a2c..076565de07 100644
--- a/addressbook/backend/pas/pas-backend.c
+++ b/addressbook/backend/pas/pas-backend.c
@@ -7,12 +7,22 @@
*/
#include <config.h>
+#include <pthread.h>
+#include "pas-book-view.h"
#include "pas-backend.h"
#include "pas-marshal.h"
struct _PASBackendPrivate {
+ GMutex *open_mutex;
+
+ GMutex *clients_mutex;
GList *clients;
- gboolean loaded, writable;
+
+ char *uri;
+ gboolean loaded, writable, removed;
+
+ GMutex *views_mutex;
+ EList *views;
};
/* Signal IDs */
@@ -31,18 +41,25 @@ pas_backend_construct (PASBackend *backend)
return TRUE;
}
-GNOME_Evolution_Addressbook_BookListener_CallStatus
+GNOME_Evolution_Addressbook_CallStatus
pas_backend_load_uri (PASBackend *backend,
- const char *uri)
+ const char *uri,
+ gboolean only_if_exists)
{
- g_return_val_if_fail (backend != NULL, FALSE);
- g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE);
- g_return_val_if_fail (uri != NULL, FALSE);
+ GNOME_Evolution_Addressbook_CallStatus status;
+
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE);
+ g_return_val_if_fail (uri, FALSE);
g_return_val_if_fail (backend->priv->loaded == FALSE, FALSE);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->load_uri != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->load_uri);
+
+ status = (* PAS_BACKEND_GET_CLASS (backend)->load_uri) (backend, uri, only_if_exists);
+
+ if (status == GNOME_Evolution_Addressbook_Success)
+ backend->priv->uri = g_strdup (uri);
- return (* PAS_BACKEND_GET_CLASS (backend)->load_uri) (backend, uri);
+ return status;
}
/**
@@ -56,246 +73,198 @@ pas_backend_load_uri (PASBackend *backend,
const char *
pas_backend_get_uri (PASBackend *backend)
{
- g_return_val_if_fail (backend != NULL, NULL);
- g_return_val_if_fail (PAS_IS_BACKEND (backend), NULL);
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), NULL);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_uri != NULL);
-
- return (* PAS_BACKEND_GET_CLASS (backend)->get_uri) (backend);
+ return backend->priv->uri;
}
-
void
-pas_backend_create_card (PASBackend *backend,
- PASBook *book,
- PASCreateCardRequest *req)
+pas_backend_open (PASBackend *backend,
+ PASBook *book,
+ gboolean only_if_exists)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->vcard != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+
+ g_mutex_lock (backend->priv->open_mutex);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->create_card != NULL);
+ if (backend->priv->loaded) {
+ pas_book_respond_open (
+ book, GNOME_Evolution_Addressbook_Success);
- (* PAS_BACKEND_GET_CLASS (backend)->create_card) (backend, book, req);
+ pas_book_report_writable (book, backend->priv->writable);
+ } else {
+ GNOME_Evolution_Addressbook_CallStatus status =
+ pas_backend_load_uri (backend, pas_book_get_uri (book), only_if_exists);
+
+ pas_book_respond_open (book, status);
+
+ if (status == GNOME_Evolution_Addressbook_Success)
+ pas_book_report_writable (book, backend->priv->writable);
+ }
+
+ g_mutex_unlock (backend->priv->open_mutex);
}
void
-pas_backend_remove_cards (PASBackend *backend,
- PASBook *book,
- PASRemoveCardsRequest *req)
+pas_backend_remove (PASBackend *backend,
+ PASBook *book)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->ids != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
- g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_cards != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->remove);
- (* PAS_BACKEND_GET_CLASS (backend)->remove_cards) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->remove) (backend, book);
}
void
-pas_backend_modify_card (PASBackend *backend,
- PASBook *book,
- PASModifyCardRequest *req)
+pas_backend_create_contact (PASBackend *backend,
+ PASBook *book,
+ const char *vcard)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->vcard != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (vcard);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->modify_card != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->create_contact);
- (* PAS_BACKEND_GET_CLASS (backend)->modify_card) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->create_contact) (backend, book, vcard);
}
void
-pas_backend_check_connection (PASBackend *backend,
- PASBook *book,
- PASCheckConnectionRequest *req)
+pas_backend_remove_contacts (PASBackend *backend,
+ PASBook *book,
+ GList *id_list)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (id_list);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->check_connection != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_contacts);
- (* PAS_BACKEND_GET_CLASS (backend)->check_connection) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->remove_contacts) (backend, book, id_list);
}
void
-pas_backend_get_vcard (PASBackend *backend,
- PASBook *book,
- PASGetVCardRequest *req)
+pas_backend_modify_contact (PASBackend *backend,
+ PASBook *book,
+ const char *vcard)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->id != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (vcard);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_vcard != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->modify_contact);
- (* PAS_BACKEND_GET_CLASS (backend)->get_vcard) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->modify_contact) (backend, book, vcard);
}
void
-pas_backend_get_cursor (PASBackend *backend,
- PASBook *book,
- PASGetCursorRequest *req)
+pas_backend_get_contact (PASBackend *backend,
+ PASBook *book,
+ const char *id)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->search != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (id);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_cursor != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_contact);
- (* PAS_BACKEND_GET_CLASS (backend)->get_cursor) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->get_contact) (backend, book, id);
}
void
-pas_backend_get_book_view (PASBackend *backend,
- PASBook *book,
- PASGetBookViewRequest *req)
+pas_backend_get_contact_list (PASBackend *backend,
+ PASBook *book,
+ const char *query)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->search != NULL && req->listener != CORBA_OBJECT_NIL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (query);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_book_view != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_contact_list);
- (* PAS_BACKEND_GET_CLASS (backend)->get_book_view) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->get_contact_list) (backend, book, query);
}
void
-pas_backend_get_completion_view (PASBackend *backend,
- PASBook *book,
- PASGetCompletionViewRequest *req)
+pas_backend_start_book_view (PASBackend *backend,
+ PASBookView *book_view)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->search != NULL && req->listener != CORBA_OBJECT_NIL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book_view && PAS_IS_BOOK_VIEW (book_view));
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_completion_view != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->start_book_view);
- (* PAS_BACKEND_GET_CLASS (backend)->get_completion_view) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->start_book_view) (backend, book_view);
}
void
pas_backend_get_changes (PASBackend *backend,
PASBook *book,
- PASGetChangesRequest *req)
+ const char *change_id)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL && req->change_id != NULL && req->listener != CORBA_OBJECT_NIL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (change_id);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_changes != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_changes);
- (* PAS_BACKEND_GET_CLASS (backend)->get_changes) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->get_changes) (backend, book, change_id);
}
void
pas_backend_authenticate_user (PASBackend *backend,
PASBook *book,
- PASAuthenticateUserRequest *req)
+ const char *user,
+ const char *passwd,
+ const char *auth_method)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+ g_return_if_fail (user && passwd && auth_method);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->authenticate_user != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->authenticate_user);
- (* PAS_BACKEND_GET_CLASS (backend)->authenticate_user) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->authenticate_user) (backend, book, user, passwd, auth_method);
}
void
pas_backend_get_supported_fields (PASBackend *backend,
- PASBook *book,
- PASGetSupportedFieldsRequest *req)
+ PASBook *book)
+
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_fields != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_fields);
- (* PAS_BACKEND_GET_CLASS (backend)->get_supported_fields) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->get_supported_fields) (backend, book);
}
void
pas_backend_get_supported_auth_methods (PASBackend *backend,
- PASBook *book,
- PASGetSupportedAuthMethodsRequest *req)
+ PASBook *book)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
- g_return_if_fail (req != NULL);
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_auth_methods != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_auth_methods);
- (* PAS_BACKEND_GET_CLASS (backend)->get_supported_auth_methods) (backend, book, req);
+ (* PAS_BACKEND_GET_CLASS (backend)->get_supported_auth_methods) (backend, book);
}
-static void
-process_client_requests (PASBook *book, gpointer user_data)
+GNOME_Evolution_Addressbook_CallStatus
+pas_backend_cancel_operation (PASBackend *backend,
+ PASBook *book)
{
- PASBackend *backend;
- PASRequest *req;
-
- backend = PAS_BACKEND (user_data);
-
- req = pas_book_pop_request (book);
- if (req == NULL)
- return;
-
- switch (req->op) {
- case CreateCard:
- pas_backend_create_card (backend, book, &req->create);
- break;
-
- case RemoveCards:
- pas_backend_remove_cards (backend, book, &req->remove);
- break;
-
- case ModifyCard:
- pas_backend_modify_card (backend, book, &req->modify);
- break;
-
- case CheckConnection:
- pas_backend_check_connection (backend, book, &req->check_connection);
- break;
-
- case GetVCard:
- pas_backend_get_vcard (backend, book, &req->get_vcard);
- break;
-
- case GetCursor:
- pas_backend_get_cursor (backend, book, &req->get_cursor);
- break;
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), GNOME_Evolution_Addressbook_OtherError);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError);
- case GetBookView:
- pas_backend_get_book_view (backend, book, &req->get_book_view);
- break;
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->cancel_operation);
- case GetCompletionView:
- pas_backend_get_completion_view (backend, book, &req->get_completion_view);
- break;
-
- case GetChanges:
- pas_backend_get_changes (backend, book, &req->get_changes);
- break;
-
- case AuthenticateUser:
- pas_backend_authenticate_user (backend, book, &req->auth_user);
- break;
-
- case GetSupportedFields:
- pas_backend_get_supported_fields (backend, book, &req->get_supported_fields);
- break;
-
- case GetSupportedAuthMethods:
- pas_backend_get_supported_auth_methods (backend, book, &req->get_supported_auth_methods);
- break;
- }
-
- pas_book_free_request (req);
+ return (* PAS_BACKEND_GET_CLASS (backend)->cancel_operation) (backend, book);
}
static void
@@ -307,74 +276,82 @@ book_destroy_cb (gpointer data, GObject *where_book_was)
}
static void
+listener_died_cb (gpointer cnx, gpointer user_data)
+{
+ PASBook *book = PAS_BOOK (user_data);
+
+ pas_backend_remove_client (pas_book_get_backend (book), book);
+}
+
+static void
last_client_gone (PASBackend *backend)
{
g_signal_emit (backend, pas_backend_signals[LAST_CLIENT_GONE], 0);
}
-static gboolean
-add_client (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener)
+EList*
+pas_backend_get_book_views (PASBackend *backend)
{
- PASBook *book;
-
- book = pas_book_new (backend, listener);
- if (!book) {
- if (!backend->priv->clients)
- last_client_gone (backend);
-
- return FALSE;
- }
-
- g_object_weak_ref (G_OBJECT (book), book_destroy_cb, backend);
-
- g_signal_connect (book, "requests_queued",
- G_CALLBACK (process_client_requests), backend);
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE);
- backend->priv->clients = g_list_prepend (backend->priv->clients, book);
-
- if (backend->priv->loaded) {
- pas_book_respond_open (
- book, GNOME_Evolution_Addressbook_BookListener_Success);
- } else {
- pas_book_respond_open (
- book, GNOME_Evolution_Addressbook_BookListener_OtherError);
- }
+ return g_object_ref (backend->priv->views);
+}
- pas_book_report_writable (book, backend->priv->writable);
+void
+pas_backend_add_book_view (PASBackend *backend,
+ PASBookView *view)
+{
+ g_mutex_lock (backend->priv->views_mutex);
- bonobo_object_unref (BONOBO_OBJECT (book));
+ e_list_append (backend->priv->views, view);
- return TRUE;
+ g_mutex_unlock (backend->priv->views_mutex);
}
/**
* pas_backend_add_client:
* @backend: An addressbook backend.
- * @listener: Listener for notification to the client.
+ * @book: the corba object representing the client connection.
*
* Adds a client to an addressbook backend.
*
* Return value: TRUE on success, FALSE on failure to add the client.
*/
gboolean
-pas_backend_add_client (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener)
+pas_backend_add_client (PASBackend *backend,
+ PASBook *book)
{
- g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE);
- g_return_val_if_fail (listener != CORBA_OBJECT_NIL, FALSE);
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), FALSE);
+
+ bonobo_object_set_immortal (BONOBO_OBJECT (book), TRUE);
+
+ g_object_weak_ref (G_OBJECT (book), book_destroy_cb, backend);
+
+ ORBit_small_listen_for_broken (pas_book_get_listener (book), G_CALLBACK (listener_died_cb), book);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->add_client != NULL);
+ g_mutex_lock (backend->priv->clients_mutex);
+ backend->priv->clients = g_list_prepend (backend->priv->clients, book);
+ g_mutex_unlock (backend->priv->clients_mutex);
- return PAS_BACKEND_GET_CLASS (backend)->add_client (backend, listener);
+ return TRUE;
}
-static void
-remove_client (PASBackend *backend,
- PASBook *book)
+void
+pas_backend_remove_client (PASBackend *backend,
+ PASBook *book)
{
+ /* XXX this needs a bit more thinking wrt the mutex - we
+ should be holding it when we check to see if clients is
+ NULL */
+
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book && PAS_IS_BOOK (book));
+
/* Disconnect */
+ g_mutex_lock (backend->priv->clients_mutex);
backend->priv->clients = g_list_remove (backend->priv->clients, book);
+ g_mutex_unlock (backend->priv->clients_mutex);
/* When all clients go away, notify the parent factory about it so that
* it may decide whether to kill the backend or not.
@@ -383,25 +360,12 @@ remove_client (PASBackend *backend,
last_client_gone (backend);
}
-void
-pas_backend_remove_client (PASBackend *backend,
- PASBook *book)
-{
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (PAS_IS_BOOK (book));
-
- g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_client != NULL);
-
- PAS_BACKEND_GET_CLASS (backend)->remove_client (backend, book);
-}
-
char *
pas_backend_get_static_capabilities (PASBackend *backend)
{
- g_return_val_if_fail (backend != NULL, NULL);
- g_return_val_if_fail (PAS_IS_BACKEND (backend), NULL);
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), NULL);
- g_assert (PAS_BACKEND_GET_CLASS (backend)->get_static_capabilities != NULL);
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_static_capabilities);
return PAS_BACKEND_GET_CLASS (backend)->get_static_capabilities (backend);
}
@@ -409,7 +373,7 @@ pas_backend_get_static_capabilities (PASBackend *backend)
gboolean
pas_backend_is_loaded (PASBackend *backend)
{
- g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE);
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE);
return backend->priv->loaded;
}
@@ -417,7 +381,7 @@ pas_backend_is_loaded (PASBackend *backend)
void
pas_backend_set_is_loaded (PASBackend *backend, gboolean is_loaded)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
backend->priv->loaded = is_loaded;
}
@@ -425,7 +389,7 @@ pas_backend_set_is_loaded (PASBackend *backend, gboolean is_loaded)
gboolean
pas_backend_is_writable (PASBackend *backend)
{
- g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE);
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE);
return backend->priv->writable;
}
@@ -433,18 +397,175 @@ pas_backend_is_writable (PASBackend *backend)
void
pas_backend_set_is_writable (PASBackend *backend, gboolean is_writable)
{
- g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
backend->priv->writable = is_writable;
}
+gboolean
+pas_backend_is_removed (PASBackend *backend)
+{
+ g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE);
+
+ return backend->priv->removed;
+}
+
+void
+pas_backend_set_is_removed (PASBackend *backend, gboolean is_removed)
+{
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+
+ backend->priv->removed = is_removed;
+}
+
+
+
+GNOME_Evolution_Addressbook_BookChangeItem*
+pas_backend_change_add_new (const char *vcard)
+{
+ GNOME_Evolution_Addressbook_BookChangeItem* new_change = GNOME_Evolution_Addressbook_BookChangeItem__alloc();
+
+ new_change->_d = GNOME_Evolution_Addressbook_ContactAdded;
+ new_change->_u.add_vcard = CORBA_string_dup (vcard);
+
+ return new_change;
+}
+
+GNOME_Evolution_Addressbook_BookChangeItem*
+pas_backend_change_modify_new (const char *vcard)
+{
+ GNOME_Evolution_Addressbook_BookChangeItem* new_change = GNOME_Evolution_Addressbook_BookChangeItem__alloc();
+
+ new_change->_d = GNOME_Evolution_Addressbook_ContactModified;
+ new_change->_u.mod_vcard = CORBA_string_dup (vcard);
+
+ return new_change;
+}
+
+GNOME_Evolution_Addressbook_BookChangeItem*
+pas_backend_change_delete_new (const char *id)
+{
+ GNOME_Evolution_Addressbook_BookChangeItem* new_change = GNOME_Evolution_Addressbook_BookChangeItem__alloc();
+
+ new_change->_d = GNOME_Evolution_Addressbook_ContactDeleted;
+ new_change->_u.del_id = CORBA_string_dup (id);
+
+ return new_change;
+}
+
+
+
+static void
+pas_backend_foreach_view (PASBackend *backend,
+ void (*callback) (PASBookView *, gpointer),
+ gpointer user_data)
+{
+ EList *views;
+ PASBookView *view;
+ EIterator *iter;
+
+ views = pas_backend_get_book_views (backend);
+ iter = e_list_get_iterator (views);
+
+ while (e_iterator_is_valid (iter)) {
+ view = (PASBookView*)e_iterator_get (iter);
+
+ bonobo_object_ref (view);
+ callback (view, user_data);
+ bonobo_object_unref (view);
+
+ e_iterator_next (iter);
+ }
+
+ g_object_unref (iter);
+ g_object_unref (views);
+}
+
+
+static void
+view_notify_update (PASBookView *view, gpointer contact)
+{
+ pas_book_view_notify_update (view, contact);
+}
+
+/**
+ * pas_backend_notify_update:
+ * @backend: an addressbook backend
+ * @contact: a new or modified contact
+ *
+ * Notifies all of @backend's book views about the new or modified
+ * contacts @contact.
+ *
+ * pas_book_respond_create() and pas_book_respond_modify() call this
+ * function for you. You only need to call this from your backend if
+ * contacts are created or modified by another (non-PAS-using) client.
+ **/
+void
+pas_backend_notify_update (PASBackend *backend, EContact *contact)
+{
+ pas_backend_foreach_view (backend, view_notify_update, contact);
+}
+
+
+static void
+view_notify_remove (PASBookView *view, gpointer id)
+{
+ pas_book_view_notify_remove (view, id);
+}
+
+/**
+ * pas_backend_notify_remove:
+ * @backend: an addressbook backend
+ * @id: a contact id
+ *
+ * Notifies all of @backend's book views that the contact with UID
+ * @id has been removed.
+ *
+ * pas_book_respond_remove_contacts() calls this function for you. You
+ * only need to call this from your backend if contacts are removed by
+ * another (non-PAS-using) client.
+ **/
+void
+pas_backend_notify_remove (PASBackend *backend, const char *id)
+{
+ pas_backend_foreach_view (backend, view_notify_remove, (gpointer)id);
+}
+
+
+static void
+view_notify_complete (PASBookView *view, gpointer unused)
+{
+ pas_book_view_notify_complete (view, GNOME_Evolution_Addressbook_Success);
+}
+
+/**
+ * pas_backend_notify_complete:
+ * @backend: an addressbook backend
+ *
+ * Notifies all of @backend's book views that the current set of
+ * notifications is complete; use this after a series of
+ * pas_backend_notify_update() and pas_backend_notify_remove() calls.
+ **/
+void
+pas_backend_notify_complete (PASBackend *backend)
+{
+ pas_backend_foreach_view (backend, view_notify_complete, NULL);
+}
+
+
+
static void
pas_backend_init (PASBackend *backend)
{
PASBackendPrivate *priv;
priv = g_new0 (PASBackendPrivate, 1);
+ priv->uri = NULL;
priv->clients = NULL;
+ priv->views = e_list_new((EListCopyFunc) g_object_ref, (EListFreeFunc) g_object_unref, NULL);
+ priv->open_mutex = g_mutex_new ();
+ priv->clients_mutex = g_mutex_new ();
+ priv->views_mutex = g_mutex_new ();
backend->priv = priv;
}
@@ -458,8 +579,20 @@ pas_backend_dispose (GObject *object)
if (backend->priv) {
g_list_free (backend->priv->clients);
- g_free (backend->priv);
+ if (backend->priv->uri)
+ g_free (backend->priv->uri);
+
+ if (backend->priv->views) {
+ g_object_unref (backend->priv->views);
+ backend->priv->views = NULL;
+ }
+
+ g_mutex_free (backend->priv->open_mutex);
+ g_mutex_free (backend->priv->clients_mutex);
+ g_mutex_free (backend->priv->views_mutex);
+
+ g_free (backend->priv);
backend->priv = NULL;
}
@@ -475,9 +608,6 @@ pas_backend_class_init (PASBackendClass *klass)
object_class = (GObjectClass *) klass;
- klass->add_client = add_client;
- klass->remove_client = remove_client;
-
object_class->dispose = pas_backend_dispose;
pas_backend_signals[LAST_CLIENT_GONE] =
diff --git a/addressbook/backend/pas/pas-backend.h b/addressbook/backend/pas/pas-backend.h
index b33518116e..41f6542213 100644
--- a/addressbook/backend/pas/pas-backend.h
+++ b/addressbook/backend/pas/pas-backend.h
@@ -25,6 +25,8 @@
#include <glib.h>
#include <glib-object.h>
#include <pas/addressbook.h>
+#include <pas/pas-types.h>
+#include <ebook/e-contact.h>
#define PAS_TYPE_BACKEND (pas_backend_get_type ())
#define PAS_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND, PASBackend))
@@ -33,7 +35,6 @@
#define PAS_IS_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND))
#define PAS_BACKEND_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((k), PAS_TYPE_BACKEND, PASBackendClass))
-typedef struct _PASBackend PASBackend;
typedef struct _PASBackendPrivate PASBackendPrivate;
#include <pas/pas-book.h>
@@ -43,44 +44,49 @@ struct _PASBackend {
PASBackendPrivate *priv;
};
-typedef struct {
+struct _PASBackendClass {
GObjectClass parent_class;
/* Virtual methods */
- GNOME_Evolution_Addressbook_BookListener_CallStatus (*load_uri) (PASBackend *backend, const char *uri);
- const char *(* get_uri) (PASBackend *backend);
- gboolean (*add_client) (PASBackend *backend, GNOME_Evolution_Addressbook_BookListener listener);
- void (*remove_client) (PASBackend *backend, PASBook *book);
+ GNOME_Evolution_Addressbook_CallStatus (*load_uri) (PASBackend *backend, const char *uri, gboolean only_if_exists);
+ void (*remove) (PASBackend *backend, PASBook *book);
char *(*get_static_capabilities) (PASBackend *backend);
- void (*create_card) (PASBackend *backend, PASBook *book, PASCreateCardRequest *req);
- void (*remove_cards) (PASBackend *backend, PASBook *book, PASRemoveCardsRequest *req);
- void (*modify_card) (PASBackend *backend, PASBook *book, PASModifyCardRequest *req);
- void (*check_connection) (PASBackend *backend, PASBook *book, PASCheckConnectionRequest *req);
- void (*get_vcard) (PASBackend *backend, PASBook *book, PASGetVCardRequest *req);
- void (*get_cursor) (PASBackend *backend, PASBook *book, PASGetCursorRequest *req);
- void (*get_book_view) (PASBackend *backend, PASBook *book, PASGetBookViewRequest *req);
- void (*get_completion_view) (PASBackend *backend, PASBook *book, PASGetCompletionViewRequest *req);
- void (*get_changes) (PASBackend *backend, PASBook *book, PASGetChangesRequest *req);
- void (*authenticate_user) (PASBackend *backend, PASBook *book, PASAuthenticateUserRequest *req);
- void (*get_supported_fields) (PASBackend *backend, PASBook *book, PASGetSupportedFieldsRequest *req);
- void (*get_supported_auth_methods) (PASBackend *backend, PASBook *book, PASGetSupportedAuthMethodsRequest *req);
+ void (*create_contact) (PASBackend *backend, PASBook *book, const char *vcard);
+ void (*remove_contacts) (PASBackend *backend, PASBook *book, GList *id_list);
+ void (*modify_contact) (PASBackend *backend, PASBook *book, const char *vcard);
+ void (*get_contact) (PASBackend *backend, PASBook *book, const char *id);
+ void (*get_contact_list) (PASBackend *backend, PASBook *book, const char *query);
+ void (*start_book_view) (PASBackend *backend, PASBookView *book_view);
+ void (*get_changes) (PASBackend *backend, PASBook *book, const char *change_id);
+ void (*authenticate_user) (PASBackend *backend, PASBook *book, const char *user, const char *passwd, const char *auth_method);
+ void (*get_supported_fields) (PASBackend *backend, PASBook *book);
+ void (*get_supported_auth_methods) (PASBackend *backend, PASBook *book);
+ GNOME_Evolution_Addressbook_CallStatus (*cancel_operation) (PASBackend *backend, PASBook *book);
/* Notification signals */
void (* last_client_gone) (PASBackend *backend);
-} PASBackendClass;
+
+ /* Padding for future expansion */
+ void (*_pas_reserved0) (void);
+ void (*_pas_reserved1) (void);
+ void (*_pas_reserved2) (void);
+ void (*_pas_reserved3) (void);
+ void (*_pas_reserved4) (void);
+};
typedef PASBackend * (*PASBackendFactoryFn) (void);
gboolean pas_backend_construct (PASBackend *backend);
-GNOME_Evolution_Addressbook_BookListener_CallStatus
+GNOME_Evolution_Addressbook_CallStatus
pas_backend_load_uri (PASBackend *backend,
- const char *uri);
+ const char *uri,
+ gboolean only_if_exists);
const char *pas_backend_get_uri (PASBackend *backend);
gboolean pas_backend_add_client (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener);
+ PASBook *book);
void pas_backend_remove_client (PASBackend *backend,
PASBook *book);
char *pas_backend_get_static_capabilities (PASBackend *backend);
@@ -89,42 +95,56 @@ gboolean pas_backend_is_loaded (PASBackend *backen
gboolean pas_backend_is_writable (PASBackend *backend);
-void pas_backend_create_card (PASBackend *backend,
- PASBook *book,
- PASCreateCardRequest *req);
-void pas_backend_remove_cards (PASBackend *backend,
- PASBook *book,
- PASRemoveCardsRequest *req);
-void pas_backend_modify_card (PASBackend *backend,
+gboolean pas_backend_is_removed (PASBackend *backend);
+
+void pas_backend_open (PASBackend *backend,
PASBook *book,
- PASModifyCardRequest *req);
-void pas_backend_check_connection (PASBackend *backend,
+ gboolean only_if_exists);
+void pas_backend_remove (PASBackend *backend,
+ PASBook *book);
+void pas_backend_create_contact (PASBackend *backend,
PASBook *book,
- PASCheckConnectionRequest *req);
-void pas_backend_get_vcard (PASBackend *backend,
+ const char *vcard);
+void pas_backend_remove_contacts (PASBackend *backend,
PASBook *book,
- PASGetVCardRequest *req);
-void pas_backend_get_cursor (PASBackend *backend,
+ GList *id_list);
+void pas_backend_modify_contact (PASBackend *backend,
PASBook *book,
- PASGetCursorRequest *req);
-void pas_backend_get_book_view (PASBackend *backend,
+ const char *vcard);
+void pas_backend_get_contact (PASBackend *backend,
PASBook *book,
- PASGetBookViewRequest *req);
-void pas_backend_get_completion_view (PASBackend *backend,
+ const char *id);
+void pas_backend_get_contact_list (PASBackend *backend,
PASBook *book,
- PASGetCompletionViewRequest *req);
+ const char *query);
void pas_backend_get_changes (PASBackend *backend,
PASBook *book,
- PASGetChangesRequest *req);
+ const char *change_id);
void pas_backend_authenticate_user (PASBackend *backend,
PASBook *book,
- PASAuthenticateUserRequest *req);
+ const char *user,
+ const char *passwd,
+ const char *auth_method);
void pas_backend_get_supported_fields (PASBackend *backend,
- PASBook *book,
- PASGetSupportedFieldsRequest *req);
+ PASBook *book);
void pas_backend_get_supported_auth_methods (PASBackend *backend,
- PASBook *book,
- PASGetSupportedAuthMethodsRequest *req);
+ PASBook *book);
+GNOME_Evolution_Addressbook_CallStatus pas_backend_cancel_operation (PASBackend *backend,
+ PASBook *book);
+
+void pas_backend_start_book_view (PASBackend *backend,
+ PASBookView *view);
+
+void pas_backend_add_book_view (PASBackend *backend,
+ PASBookView *view);
+
+EList *pas_backend_get_book_views (PASBackend *backend);
+
+void pas_backend_notify_update (PASBackend *backend,
+ EContact *contact);
+void pas_backend_notify_remove (PASBackend *backend,
+ const char *id);
+void pas_backend_notify_complete (PASBackend *backend);
GType pas_backend_get_type (void);
@@ -135,6 +155,13 @@ void pas_backend_set_is_loaded (PASBackend *backen
gboolean is_loaded);
void pas_backend_set_is_writable (PASBackend *backend,
gboolean is_writable);
+void pas_backend_set_is_removed (PASBackend *backend,
+ gboolean is_removed);
+
+/* useful for implementing _get_changes in backends */
+GNOME_Evolution_Addressbook_BookChangeItem* pas_backend_change_add_new (const char *vcard);
+GNOME_Evolution_Addressbook_BookChangeItem* pas_backend_change_modify_new (const char *vcard);
+GNOME_Evolution_Addressbook_BookChangeItem* pas_backend_change_delete_new (const char *id);
#endif /* ! __PAS_BACKEND_H__ */
diff --git a/addressbook/backend/pas/pas-book-factory.c b/addressbook/backend/pas/pas-book-factory.c
index 2d6ed1e65b..34e97aa780 100644
--- a/addressbook/backend/pas/pas-book-factory.c
+++ b/addressbook/backend/pas/pas-book-factory.c
@@ -8,6 +8,7 @@
*/
#include <config.h>
+#include <pthread.h>
#include <string.h>
#include "addressbook.h"
@@ -15,21 +16,22 @@
#include "pas-marshal.h"
#include <bonobo-activation/bonobo-activation.h>
#include <bonobo/bonobo-main.h>
+#include <bonobo/bonobo-arg.h>
#define DEFAULT_PAS_BOOK_FACTORY_OAF_ID "OAFIID:GNOME_Evolution_Wombat_ServerFactory"
static BonoboObjectClass *pas_book_factory_parent_class;
typedef struct {
- char *uri;
- GNOME_Evolution_Addressbook_BookListener listener;
+ char *uri;
+ GNOME_Evolution_Addressbook_BookListener listener;
} PASBookFactoryQueuedRequest;
struct _PASBookFactoryPrivate {
- gint idle_id;
+ GMutex *map_mutex;
+
GHashTable *backends;
GHashTable *active_server_map;
- GList *queued_requests;
/* OAFIID of the factory */
char *iid;
@@ -108,10 +110,16 @@ pas_book_factory_register_backend (PASBookFactory *factory,
int
pas_book_factory_get_n_backends (PASBookFactory *factory)
{
+ int n_backends;
+
g_return_val_if_fail (factory != NULL, -1);
g_return_val_if_fail (PAS_IS_BOOK_FACTORY (factory), -1);
- return g_hash_table_size (factory->priv->active_server_map);
+ g_mutex_lock (factory->priv->map_mutex);
+ n_backends = g_hash_table_size (factory->priv->active_server_map);
+ g_mutex_unlock (factory->priv->map_mutex);
+
+ return n_backends;
}
static void
@@ -131,10 +139,11 @@ pas_book_factory_dump_active_backends (PASBookFactory *factory)
{
g_message ("Active PAS backends");
+ g_mutex_lock (factory->priv->map_mutex);
g_hash_table_foreach (factory->priv->active_server_map,
dump_active_server_map_entry,
NULL);
-
+ g_mutex_unlock (factory->priv->map_mutex);
}
/* Callback used when a backend loses its last connected client */
@@ -154,6 +163,8 @@ backend_last_client_gone_cb (PASBackend *backend, gpointer data)
gboolean result;
char *orig_uri;
+ g_mutex_lock (factory->priv->map_mutex);
+
result = g_hash_table_lookup_extended (factory->priv->active_server_map, uri,
&orig_key, NULL);
g_assert (result != FALSE);
@@ -165,13 +176,17 @@ backend_last_client_gone_cb (PASBackend *backend, gpointer data)
g_object_unref (backend);
- /* Notify upstream if there are no more backends */
+ g_mutex_unlock (factory->priv->map_mutex);
}
- if (g_hash_table_size (factory->priv->active_server_map) == 0)
+ if (g_hash_table_size (factory->priv->active_server_map) == 0) {
+ /* Notify upstream if there are no more backends */
g_signal_emit (G_OBJECT (factory), factory_signals[LAST_BOOK_GONE], 0);
+ }
}
+
+
static PASBackendFactoryFn
pas_book_factory_lookup_backend_factory (PASBookFactory *factory,
const char *uri)
@@ -203,52 +218,16 @@ pas_book_factory_lookup_backend_factory (PASBookFactory *factory,
}
static PASBackend *
-pas_book_factory_launch_backend (PASBookFactory *factory,
- GNOME_Evolution_Addressbook_BookListener listener,
- const char *uri)
+pas_book_factory_launch_backend (PASBookFactory *factory,
+ PASBackendFactoryFn backend_factory,
+ GNOME_Evolution_Addressbook_BookListener listener,
+ const char *uri)
{
- PASBackendFactoryFn backend_factory;
PASBackend *backend;
- backend_factory = pas_book_factory_lookup_backend_factory (
- factory, uri);
-
- if (!backend_factory) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (
- listener,
- GNOME_Evolution_Addressbook_BookListener_ProtocolNotSupported,
- CORBA_OBJECT_NIL,
- &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_factory_launch_backend(): could not notify "
- "the listener");
-
- CORBA_exception_free (&ev);
- return NULL;
- }
-
backend = (* backend_factory) ();
- if (!backend) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (
- listener,
- GNOME_Evolution_Addressbook_BookListener_OtherError,
- CORBA_OBJECT_NIL,
- &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_factory_launch_backend(): could not notify "
- "the listener");
-
- CORBA_exception_free (&ev);
+ if (!backend)
return NULL;
- }
g_hash_table_insert (factory->priv->active_server_map,
g_strdup (uri),
@@ -261,154 +240,63 @@ pas_book_factory_launch_backend (PASBookFactory *factory,
return backend;
}
-static void
-pas_book_factory_process_request (PASBookFactory *factory,
- PASBookFactoryQueuedRequest *request)
+static GNOME_Evolution_Addressbook_Book
+impl_GNOME_Evolution_Addressbook_BookFactory_getBook (PortableServer_Servant servant,
+ const CORBA_char *uri,
+ const GNOME_Evolution_Addressbook_BookListener listener,
+ CORBA_Environment *ev)
{
+ PASBookFactory *factory = PAS_BOOK_FACTORY (bonobo_object (servant));
PASBackend *backend;
- char *uri;
- GNOME_Evolution_Addressbook_BookListener listener;
- CORBA_Environment ev;
+ PASBook *book;
- uri = request->uri;
- listener = request->listener;
- g_free (request);
+ printf ("impl_GNOME_Evolution_Addressbook_BookFactory_getBook\n");
/* Look up the backend and create one if needed */
+ g_mutex_lock (factory->priv->map_mutex);
backend = g_hash_table_lookup (factory->priv->active_server_map, uri);
if (!backend) {
- GNOME_Evolution_Addressbook_BookListener_CallStatus status;
-
- backend = pas_book_factory_launch_backend (factory, listener, uri);
- if (!backend)
- goto out;
+ PASBackendFactoryFn backend_factory;
- status = pas_backend_load_uri (backend, uri);
- if (status != GNOME_Evolution_Addressbook_BookListener_Success) {
- /* tell the listener that we failed to open the book */
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (
- listener, status,
- CORBA_OBJECT_NIL,
- &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_open: Exception "
- "responding to BookListener!\n");
- }
+ backend_factory = pas_book_factory_lookup_backend_factory (factory, uri);
+
+ if (backend_factory == NULL) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_GNOME_Evolution_Addressbook_BookFactory_ProtocolNotSupported,
+ NULL);
- CORBA_exception_free (&ev);
-
- backend_last_client_gone_cb (backend, factory);
+ g_mutex_unlock (factory->priv->map_mutex);
- goto out;
+ return CORBA_OBJECT_NIL;
}
- pas_backend_add_client (backend, listener);
-
- goto out;
+ backend = pas_book_factory_launch_backend (factory, backend_factory, listener, uri);
}
- pas_backend_add_client (backend, listener);
+ if (backend) {
+ GNOME_Evolution_Addressbook_BookListener listener_copy;
- out:
- g_free (uri);
-
- CORBA_exception_init (&ev);
- CORBA_Object_release (listener, &ev);
+ listener_copy = bonobo_object_dup_ref (listener, NULL);
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_factory_process_request(): could not release the listener");
+ g_mutex_unlock (factory->priv->map_mutex);
- CORBA_exception_free (&ev);
-}
+ book = pas_book_new (backend, uri, listener);
-static gboolean
-pas_book_factory_process_queue (PASBookFactory *factory)
-{
- /* Process pending Book-creation requests. */
- if (factory->priv->queued_requests != NULL) {
- PASBookFactoryQueuedRequest *request;
- GList *l;
+ pas_backend_add_client (backend, book);
- l = factory->priv->queued_requests;
- request = l->data;
-
- pas_book_factory_process_request (factory, request);
-
- factory->priv->queued_requests = g_list_remove_link (
- factory->priv->queued_requests, l);
- g_list_free_1 (l);
- }
-
- if (factory->priv->queued_requests == NULL) {
-
- factory->priv->idle_id = 0;
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-pas_book_factory_queue_request (PASBookFactory *factory,
- const char *uri,
- const GNOME_Evolution_Addressbook_BookListener listener)
-{
- PASBookFactoryQueuedRequest *request;
- GNOME_Evolution_Addressbook_BookListener listener_copy;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- listener_copy = CORBA_Object_duplicate (listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("PASBookFactory: Could not duplicate BookListener!\n");
- CORBA_exception_free (&ev);
- return;
- }
-
- CORBA_exception_free (&ev);
-
- request = g_new0 (PASBookFactoryQueuedRequest, 1);
- request->listener = listener_copy;
- request->uri = g_strdup (uri);
-
- factory->priv->queued_requests =
- g_list_prepend (factory->priv->queued_requests, request);
-
- if (! factory->priv->idle_id) {
- factory->priv->idle_id =
- g_idle_add ((GSourceFunc) pas_book_factory_process_queue, factory);
+ return bonobo_object_corba_objref (BONOBO_OBJECT (book));
}
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_BookFactory_openBook (PortableServer_Servant servant,
- const CORBA_char *uri,
- const GNOME_Evolution_Addressbook_BookListener listener,
- CORBA_Environment *ev)
-{
- PASBookFactory *factory = PAS_BOOK_FACTORY (bonobo_object (servant));
- PASBackendFactoryFn backend_factory;
-
- backend_factory = pas_book_factory_lookup_backend_factory (factory, uri);
-
- if (backend_factory == NULL) {
- GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (
- listener,
- GNOME_Evolution_Addressbook_BookListener_ProtocolNotSupported,
- CORBA_OBJECT_NIL,
- ev);
-
- return;
+ else {
+ /* probably need a more descriptive exception here */
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_GNOME_Evolution_Addressbook_BookFactory_ProtocolNotSupported,
+ NULL);
+ g_mutex_unlock (factory->priv->map_mutex);
+
+ return CORBA_OBJECT_NIL;
}
-
- pas_book_factory_queue_request (factory, uri, listener);
}
static void
@@ -425,7 +313,9 @@ pas_book_factory_new (void)
{
PASBookFactory *factory;
- factory = g_object_new (PAS_TYPE_BOOK_FACTORY, NULL);
+ factory = g_object_new (PAS_TYPE_BOOK_FACTORY,
+ "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL),
+ NULL);
pas_book_factory_construct (factory);
@@ -483,9 +373,9 @@ pas_book_factory_init (PASBookFactory *factory)
{
factory->priv = g_new0 (PASBookFactoryPrivate, 1);
+ factory->priv->map_mutex = g_mutex_new();
factory->priv->active_server_map = g_hash_table_new (g_str_hash, g_str_equal);
factory->priv->backends = g_hash_table_new (g_str_hash, g_str_equal);
- factory->priv->queued_requests = NULL;
factory->priv->registered = FALSE;
}
@@ -518,22 +408,8 @@ pas_book_factory_dispose (GObject *object)
if (factory->priv) {
PASBookFactoryPrivate *priv = factory->priv;
- GList *l;
- for (l = priv->queued_requests; l != NULL; l = l->next) {
- PASBookFactoryQueuedRequest *request = l->data;
- CORBA_Environment ev;
-
- g_free (request->uri);
-
- CORBA_exception_init (&ev);
- CORBA_Object_release (request->listener, &ev);
- CORBA_exception_free (&ev);
-
- g_free (request);
- }
- g_list_free (priv->queued_requests);
- priv->queued_requests = NULL;
+ g_mutex_free (priv->map_mutex);
g_hash_table_foreach (priv->active_server_map,
free_active_server_map_entry,
@@ -585,7 +461,7 @@ pas_book_factory_class_init (PASBookFactoryClass *klass)
epv = &klass->epv;
- epv->openBook = impl_GNOME_Evolution_Addressbook_BookFactory_openBook;
+ epv->getBook = impl_GNOME_Evolution_Addressbook_BookFactory_getBook;
}
BONOBO_TYPE_FUNC_FULL (
diff --git a/addressbook/backend/pas/pas-book-view.c b/addressbook/backend/pas/pas-book-view.c
index fce4173f0f..712997d258 100644
--- a/addressbook/backend/pas/pas-book-view.c
+++ b/addressbook/backend/pas/pas-book-view.c
@@ -6,158 +6,266 @@
*/
#include <config.h>
+#include <string.h>
#include <glib.h>
#include <bonobo/bonobo-main.h>
+#include "pas-backend.h"
+#include "pas-backend-card-sexp.h"
#include "pas-book-view.h"
static BonoboObjectClass *pas_book_view_parent_class;
struct _PASBookViewPrivate {
GNOME_Evolution_Addressbook_BookViewListener listener;
+
+#define INITIAL_THRESHOLD 20
+ GMutex *pending_mutex;
+
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard adds;
+ int next_threshold;
+ int threshold_max;
+
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard changes;
+ CORBA_sequence_GNOME_Evolution_Addressbook_ContactId removes;
+
+ PASBackend *backend;
+ char *card_query;
+ PASBackendCardSExp *card_sexp;
+ GHashTable *ids;
};
-/**
- * pas_book_view_notify_change:
- */
-void
-pas_book_view_notify_change (PASBookView *book_view,
- const GList *cards)
+static void
+send_pending_adds (PASBookView *book_view, gboolean reset)
{
CORBA_Environment ev;
- gint i, length;
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard card_sequence;
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *adds;
+
+ adds = &book_view->priv->adds;
+ if (adds->_length == 0)
+ return;
- length = g_list_length((GList *) cards);
+ CORBA_exception_init (&ev);
- card_sequence._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf(length);
- card_sequence._maximum = length;
- card_sequence._length = length;
+ GNOME_Evolution_Addressbook_BookViewListener_notifyContactsAdded (
+ book_view->priv->listener, adds, &ev);
- for ( i = 0; cards; cards = g_list_next(cards), i++ ) {
- card_sequence._buffer[i] = CORBA_string_dup((char *) cards->data);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("send_pending_adds: Exception signaling BookViewListener!\n");
}
+ CORBA_exception_free (&ev);
+
+ CORBA_free (adds->_buffer);
+ adds->_buffer = NULL;
+ adds->_maximum = 0;
+ adds->_length = 0;
+
+ if (reset)
+ book_view->priv->next_threshold = INITIAL_THRESHOLD;
+}
+
+static void
+send_pending_changes (PASBookView *book_view)
+{
+ CORBA_Environment ev;
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *changes;
+
+ changes = &book_view->priv->changes;
+ if (changes->_length == 0)
+ return;
+
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookViewListener_notifyCardChanged (
- book_view->priv->listener, &card_sequence, &ev);
+ GNOME_Evolution_Addressbook_BookViewListener_notifyContactsChanged (
+ book_view->priv->listener, changes, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_change: Exception signaling BookViewListener!\n");
+ g_warning ("send_pending_changes: Exception signaling BookViewListener!\n");
}
CORBA_exception_free (&ev);
- CORBA_free(card_sequence._buffer);
+ CORBA_free (changes->_buffer);
+ changes->_buffer = NULL;
+ changes->_maximum = 0;
+ changes->_length = 0;
}
-void
-pas_book_view_notify_change_1 (PASBookView *book_view,
- const char *card)
+static void
+send_pending_removes (PASBookView *book_view)
{
- GList *list = g_list_append(NULL, (char *) card);
- pas_book_view_notify_change(book_view, list);
- g_list_free(list);
+ CORBA_Environment ev;
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *removes;
+
+ removes = &book_view->priv->removes;
+ if (removes->_length == 0)
+ return;
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Addressbook_BookViewListener_notifyContactsRemoved (
+ book_view->priv->listener, removes, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("send_pending_removes: Exception signaling BookViewListener!\n");
+ }
+
+ CORBA_exception_free (&ev);
+
+ CORBA_free (removes->_buffer);
+ removes->_buffer = NULL;
+ removes->_maximum = 0;
+ removes->_length = 0;
}
-/**
- * pas_book_view_notify_remove:
- */
-void
-pas_book_view_notify_remove_1 (PASBookView *book_view,
- const char *id)
+#define MAKE_REALLOC(type) \
+static void \
+CORBA_sequence_ ## type ## _realloc (CORBA_sequence_ ## type *seq, \
+ CORBA_unsigned_long new_max) \
+{ \
+ type *new_buf; \
+ \
+ new_buf = CORBA_sequence_ ## type ## _allocbuf (new_max); \
+ memcpy (new_buf, seq->_buffer, seq->_maximum * sizeof (type)); \
+ CORBA_free (seq->_buffer); \
+ seq->_buffer = new_buf; \
+ seq->_maximum = new_max; \
+}
+
+MAKE_REALLOC (GNOME_Evolution_Addressbook_VCard)
+MAKE_REALLOC (GNOME_Evolution_Addressbook_ContactId)
+
+static void
+notify_change (PASBookView *book_view, const char *vcard)
{
- GList *ids = NULL;
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *changes;
+
+ send_pending_adds (book_view, TRUE);
+ send_pending_removes (book_view);
- ids = g_list_prepend (ids, (char*)id);
+ changes = &book_view->priv->changes;
- pas_book_view_notify_remove (book_view, ids);
+ if (changes->_length == changes->_maximum) {
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard_realloc (
+ changes, 2 * (changes->_maximum + 1));
+ }
- g_list_free (ids);
+ changes->_buffer[changes->_length++] = CORBA_string_dup (vcard);
}
-void
-pas_book_view_notify_remove (PASBookView *book_view,
- const GList *ids)
+static void
+notify_remove (PASBookView *book_view, const char *id)
{
- GNOME_Evolution_Addressbook_CardIdList idlist;
- CORBA_Environment ev;
- const GList *l;
- int num_ids, i;
+ CORBA_sequence_GNOME_Evolution_Addressbook_ContactId *removes;
- CORBA_exception_init (&ev);
+ send_pending_adds (book_view, TRUE);
+ send_pending_changes (book_view);
- num_ids = g_list_length ((GList*)ids);
- idlist._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_CardId_allocbuf (num_ids);
- idlist._maximum = num_ids;
- idlist._length = num_ids;
+ removes = &book_view->priv->removes;
- for (l = ids, i = 0; l; l=l->next, i ++) {
- idlist._buffer[i] = CORBA_string_dup (l->data);
+ if (removes->_length == removes->_maximum) {
+ CORBA_sequence_GNOME_Evolution_Addressbook_ContactId_realloc (
+ removes, 2 * (removes->_maximum + 1));
}
- GNOME_Evolution_Addressbook_BookViewListener_notifyCardsRemoved (
- book_view->priv->listener, &idlist, &ev);
+ removes->_buffer[removes->_length++] = CORBA_string_dup (id);
+ g_hash_table_remove (book_view->priv->ids, id);
+}
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_remove: Exception signaling BookViewListener!\n");
- }
+static void
+notify_add (PASBookView *book_view, const char *id, const char *vcard)
+{
+ CORBA_sequence_GNOME_Evolution_Addressbook_VCard *adds;
+ PASBookViewPrivate *priv = book_view->priv;
- CORBA_free(idlist._buffer);
+ send_pending_changes (book_view);
+ send_pending_removes (book_view);
- CORBA_exception_free (&ev);
+ adds = &priv->adds;
+
+ if (adds->_length == adds->_maximum) {
+ send_pending_adds (book_view, FALSE);
+
+ adds->_buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf (priv->next_threshold);
+ adds->_maximum = priv->next_threshold;
+
+ if (priv->next_threshold < priv->threshold_max) {
+ priv->next_threshold = MIN (2 * priv->next_threshold,
+ priv->threshold_max);
+ }
+ }
+
+ adds->_buffer[adds->_length++] = CORBA_string_dup (vcard);
+ g_hash_table_insert (book_view->priv->ids, g_strdup (id),
+ GUINT_TO_POINTER (1));
}
/**
- * pas_book_view_notify_add:
+ * pas_book_view_notify_update:
*/
void
-pas_book_view_notify_add (PASBookView *book_view,
- const GList *cards)
+pas_book_view_notify_update (PASBookView *book_view,
+ EContact *contact)
{
- CORBA_Environment ev;
- gint i, length;
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard card_sequence;
+ gboolean currently_in_view, want_in_view;
+ const char *id;
+ char *vcard;
- length = g_list_length((GList *)cards);
+ g_mutex_lock (book_view->priv->pending_mutex);
- card_sequence._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf(length);
- card_sequence._maximum = length;
- card_sequence._length = length;
+ id = e_contact_get_const (contact, E_CONTACT_UID);
- for ( i = 0; cards; cards = g_list_next(cards), i++ ) {
- card_sequence._buffer[i] = CORBA_string_dup((char *) cards->data);
- }
+ currently_in_view =
+ g_hash_table_lookup (book_view->priv->ids, id) != NULL;
+ want_in_view = pas_backend_card_sexp_match_contact (
+ book_view->priv->card_sexp, contact);
- CORBA_exception_init (&ev);
+ if (want_in_view) {
+ vcard = e_vcard_to_string (E_VCARD (contact),
+ EVC_FORMAT_VCARD_30);
- GNOME_Evolution_Addressbook_BookViewListener_notifyCardAdded (
- book_view->priv->listener, &card_sequence, &ev);
+ if (currently_in_view)
+ notify_change (book_view, vcard);
+ else
+ notify_add (book_view, id, vcard);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_add: Exception signaling BookViewListener!\n");
+ g_free (vcard);
+ } else {
+ if (currently_in_view)
+ pas_book_view_notify_remove (book_view, id);
+ /* else nothing; we're removing a card that wasn't there */
}
- CORBA_exception_free (&ev);
-
- CORBA_free(card_sequence._buffer);
+ g_mutex_unlock (book_view->priv->pending_mutex);
}
+/**
+ * pas_book_view_notify_remove:
+ */
void
-pas_book_view_notify_add_1 (PASBookView *book_view,
- const char *card)
+pas_book_view_notify_remove (PASBookView *book_view,
+ const char *id)
{
- GList *list = g_list_append(NULL, (char *) card);
- pas_book_view_notify_add(book_view, list);
- g_list_free(list);
+ g_mutex_lock (book_view->priv->pending_mutex);
+ notify_remove (book_view, id);
+ g_mutex_unlock (book_view->priv->pending_mutex);
}
+
void
pas_book_view_notify_complete (PASBookView *book_view,
- GNOME_Evolution_Addressbook_BookViewListener_CallStatus status)
+ GNOME_Evolution_Addressbook_CallStatus status)
{
CORBA_Environment ev;
+ g_mutex_lock (book_view->priv->pending_mutex);
+
+ send_pending_adds (book_view, TRUE);
+ send_pending_changes (book_view);
+ send_pending_removes (book_view);
+
+ g_mutex_unlock (book_view->priv->pending_mutex);
+
CORBA_exception_init (&ev);
GNOME_Evolution_Addressbook_BookViewListener_notifySequenceComplete (
@@ -178,8 +286,8 @@ pas_book_view_notify_status_message (PASBookView *book_view,
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookViewListener_notifyStatusMessage (
- book_view->priv->listener, message, &ev);
+ GNOME_Evolution_Addressbook_BookViewListener_notifyProgress (
+ book_view->priv->listener, message, 0, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
g_warning ("pas_book_view_notify_status_message: Exception signaling BookViewListener!\n");
@@ -190,7 +298,10 @@ pas_book_view_notify_status_message (PASBookView *book_view,
static void
pas_book_view_construct (PASBookView *book_view,
- GNOME_Evolution_Addressbook_BookViewListener listener)
+ PASBackend *backend,
+ GNOME_Evolution_Addressbook_BookViewListener listener,
+ const char *card_query,
+ PASBackendCardSExp *card_sexp)
{
PASBookViewPrivate *priv;
CORBA_Environment ev;
@@ -202,29 +313,70 @@ pas_book_view_construct (PASBookView *book_view,
CORBA_exception_init (&ev);
- bonobo_object_dup_ref (listener, &ev);
+ priv->listener = CORBA_Object_duplicate (listener, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("Unable to duplicate & ref listener object in pas-book-view.c\n");
+ g_warning("Unable to duplicate listener object in pas-book-view.c\n");
CORBA_exception_free (&ev);
return;
}
CORBA_exception_free (&ev);
- priv->listener = listener;
+ priv->backend = backend;
+ priv->card_query = g_strdup (card_query);
+ priv->card_sexp = card_sexp;
+}
+
+/**
+ * pas_book_view_new:
+ */
+static void
+impl_GNOME_Evolution_Addressbook_BookView_start (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ PASBookView *view = PAS_BOOK_VIEW (bonobo_object (servant));
+
+ pas_backend_start_book_view (pas_book_view_get_backend (view), view);
+}
+
+/**
+ * pas_book_view_get_card_query
+ */
+const char*
+pas_book_view_get_card_query (PASBookView *book_view)
+{
+ return book_view->priv->card_query;
+}
+
+/**
+ * pas_book_view_get_card_sexp
+ */
+PASBackendCardSExp*
+pas_book_view_get_card_sexp (PASBookView *book_view)
+{
+ return book_view->priv->card_sexp;
+}
+
+PASBackend*
+pas_book_view_get_backend (PASBookView *book_view)
+{
+ return book_view->priv->backend;
}
/**
* pas_book_view_new:
*/
PASBookView *
-pas_book_view_new (GNOME_Evolution_Addressbook_BookViewListener listener)
+pas_book_view_new (PASBackend *backend,
+ GNOME_Evolution_Addressbook_BookViewListener listener,
+ const char *card_query,
+ PASBackendCardSExp *card_sexp)
{
PASBookView *book_view;
book_view = g_object_new (PAS_TYPE_BOOK_VIEW, NULL);
- pas_book_view_construct (book_view, listener);
+ pas_book_view_construct (book_view, backend, listener, card_query, card_sexp);
return book_view;
}
@@ -237,6 +389,19 @@ pas_book_view_dispose (GObject *object)
if (book_view->priv) {
bonobo_object_release_unref (book_view->priv->listener, NULL);
+ if (book_view->priv->adds._buffer)
+ CORBA_free (book_view->priv->adds._buffer);
+ if (book_view->priv->changes._buffer)
+ CORBA_free (book_view->priv->changes._buffer);
+ if (book_view->priv->removes._buffer)
+ CORBA_free (book_view->priv->removes._buffer);
+
+ g_free (book_view->priv->card_query);
+ g_object_unref (book_view->priv->card_sexp);
+
+ g_mutex_free (book_view->priv->pending_mutex);
+ book_view->priv->pending_mutex = NULL;
+
g_free (book_view->priv);
book_view->priv = NULL;
}
@@ -249,17 +414,30 @@ static void
pas_book_view_class_init (PASBookViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ POA_GNOME_Evolution_Addressbook_BookView__epv *epv;
pas_book_view_parent_class = g_type_class_peek_parent (klass);
object_class->dispose = pas_book_view_dispose;
+
+ epv = &klass->epv;
+
+ epv->start = impl_GNOME_Evolution_Addressbook_BookView_start;
+
}
static void
pas_book_view_init (PASBookView *book_view)
{
- book_view->priv = g_new0 (PASBookViewPrivate, 1);
- book_view->priv->listener = CORBA_OBJECT_NIL;
+ book_view->priv = g_new0 (PASBookViewPrivate, 1);
+
+ book_view->priv->pending_mutex = g_mutex_new();
+
+ book_view->priv->next_threshold = INITIAL_THRESHOLD;
+ book_view->priv->threshold_max = 3000;
+
+ book_view->priv->ids = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
}
BONOBO_TYPE_FUNC_FULL (
diff --git a/addressbook/backend/pas/pas-book-view.h b/addressbook/backend/pas/pas-book-view.h
index dd6c74c596..0cacab6bf0 100644
--- a/addressbook/backend/pas/pas-book-view.h
+++ b/addressbook/backend/pas/pas-book-view.h
@@ -16,6 +16,8 @@
#include <pas/addressbook.h>
#include <glib.h>
#include <glib-object.h>
+#include <pas/pas-types.h>
+#include <ebook/e-contact.h>
#define PAS_TYPE_BOOK_VIEW (pas_book_view_get_type ())
#define PAS_BOOK_VIEW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BOOK_VIEW, PASBookView))
@@ -24,8 +26,6 @@
#define PAS_IS_BOOK_VIEW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BOOK_VIEW))
#define PAS_BOOK_VIEW_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BOOK_VIEW, PASBookView))
-typedef struct _PASBookView PASBookView;
-typedef struct _PASBookViewClass PASBookViewClass;
typedef struct _PASBookViewPrivate PASBookViewPrivate;
struct _PASBookView {
@@ -40,25 +40,24 @@ struct _PASBookViewClass {
};
-PASBookView *pas_book_view_new (GNOME_Evolution_Addressbook_BookViewListener listener);
+PASBookView *pas_book_view_new (PASBackend *backend,
+ GNOME_Evolution_Addressbook_BookViewListener listener,
+ const char *card_query,
+ PASBackendCardSExp *card_sexp);
-void pas_book_view_notify_change (PASBookView *book_view,
- const GList *cards);
-void pas_book_view_notify_change_1 (PASBookView *book_view,
- const char *card);
+const char* pas_book_view_get_card_query (PASBookView *book_view);
+PASBackendCardSExp* pas_book_view_get_card_sexp (PASBookView *book_view);
+PASBackend* pas_book_view_get_backend (PASBookView *book_view);
+
+void pas_book_view_notify_update (PASBookView *book_view,
+ EContact *contact);
void pas_book_view_notify_remove (PASBookView *book_view,
- const GList *ids);
-void pas_book_view_notify_remove_1 (PASBookView *book_view,
const char *id);
-void pas_book_view_notify_add (PASBookView *book_view,
- const GList *cards);
-void pas_book_view_notify_add_1 (PASBookView *book_view,
- const char *card);
void pas_book_view_notify_complete (PASBookView *book_view,
- GNOME_Evolution_Addressbook_BookViewListener_CallStatus);
+ GNOME_Evolution_Addressbook_CallStatus);
void pas_book_view_notify_status_message (PASBookView *book_view,
const char *message);
-GType pas_book_view_get_type (void);
+GType pas_book_view_get_type (void);
#endif /* ! __PAS_BOOK_VIEW_H__ */
diff --git a/addressbook/backend/pas/pas-book.c b/addressbook/backend/pas/pas-book.c
index dc626e59e1..7b6e0c9a2b 100644
--- a/addressbook/backend/pas/pas-book.c
+++ b/addressbook/backend/pas/pas-book.c
@@ -7,261 +7,68 @@
#include <config.h>
#include <bonobo/bonobo-main.h>
+#include <bonobo/bonobo-arg.h>
#include "e-util/e-list.h"
+#include "ebook/e-contact.h"
+#include "pas-book-view.h"
#include "pas-backend.h"
+#include "pas-backend-card-sexp.h"
#include "pas-marshal.h"
static BonoboObjectClass *pas_book_parent_class;
POA_GNOME_Evolution_Addressbook_Book__vepv pas_book_vepv;
-enum {
- REQUESTS_QUEUED,
- LAST_SIGNAL
-};
-
-static guint pas_book_signals [LAST_SIGNAL];
-
struct _PASBookPrivate {
- PASBackend *backend;
+ PASBackend *backend;
GNOME_Evolution_Addressbook_BookListener listener;
-
- GList *request_queue;
- gint timeout_id;
-
- guint timeout_lock : 1;
+ char *uri;
};
-static gboolean
-pas_book_check_queue (PASBook *book)
-{
- if (book->priv->timeout_lock)
- return TRUE;
-
- book->priv->timeout_lock = TRUE;
-
- if (book->priv->request_queue != NULL) {
- g_signal_emit (book, pas_book_signals [REQUESTS_QUEUED], 0);
- }
-
- if (book->priv->request_queue == NULL) {
- book->priv->timeout_id = 0;
- book->priv->timeout_lock = FALSE;
- bonobo_object_unref (BONOBO_OBJECT (book));
- return FALSE;
- }
-
- book->priv->timeout_lock = FALSE;
-
- return TRUE;
-}
-
-static void
-pas_book_queue_request (PASBook *book, PASRequest *req)
-{
- book->priv->request_queue =
- g_list_append (book->priv->request_queue, req);
-
- if (book->priv->timeout_id == 0) {
- bonobo_object_ref (BONOBO_OBJECT (book));
- book->priv->timeout_id = g_timeout_add (20, (GSourceFunc) pas_book_check_queue, book);
- }
-}
-
-static void
-pas_book_queue_create_card (PASBook *book, const char *vcard)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = CreateCard;
- req->create.vcard = g_strdup (vcard);
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_remove_cards (PASBook *book,
- const GNOME_Evolution_Addressbook_CardIdList *ids)
-{
- PASRequest *req;
- int i;
-
- req = g_new0 (PASRequest, 1);
- req->op = RemoveCards;
- req->remove.ids = NULL;
-
- for (i = 0; i < ids->_length; i ++) {
- req->remove.ids = g_list_append (req->remove.ids, g_strdup (ids->_buffer[i]));
- }
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_modify_card (PASBook *book, const char *vcard)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = ModifyCard;
- req->modify.vcard = g_strdup (vcard);
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_get_cursor (PASBook *book, const char *search)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetCursor;
- req->get_cursor.search = g_strdup(search);
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_get_vcard (PASBook *book, const char *id)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetVCard;
- req->get_vcard.id = g_strdup(id);
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_authenticate_user (PASBook *book,
- const char *user, const char *passwd, const char *auth_method)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = AuthenticateUser;
- req->auth_user.user = g_strdup(user);
- req->auth_user.passwd = g_strdup(passwd);
- req->auth_user.auth_method = g_strdup(auth_method);
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_get_supported_fields (PASBook *book)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetSupportedFields;
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_get_supported_auth_methods (PASBook *book)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetSupportedAuthMethods;
-
- pas_book_queue_request (book, req);
-}
-
-
static void
-pas_book_queue_get_book_view (PASBook *book, const GNOME_Evolution_Addressbook_BookViewListener listener, const char *search)
+impl_GNOME_Evolution_Addressbook_Book_open (PortableServer_Servant servant,
+ const CORBA_boolean only_if_exists,
+ CORBA_Environment *ev)
{
- PASRequest *req;
- CORBA_Environment ev;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetBookView;
- req->get_book_view.search = g_strdup(search);
-
- CORBA_exception_init (&ev);
-
- req->get_book_view.listener = bonobo_object_dup_ref(listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_queue_get_book_view: Exception "
- "duplicating BookViewListener!\n");
- }
+ PASBook *book = PAS_BOOK (bonobo_object (servant));
- CORBA_exception_free (&ev);
+ printf ("impl_GNOME_Evolution_Addressbook_Book_open\n");
- pas_book_queue_request (book, req);
+ pas_backend_open (pas_book_get_backend (book), book, only_if_exists);
}
static void
-pas_book_queue_get_completion_view (PASBook *book, const GNOME_Evolution_Addressbook_BookViewListener listener, const char *search)
+impl_GNOME_Evolution_Addressbook_Book_remove (PortableServer_Servant servant,
+ CORBA_Environment *ev)
{
- PASRequest *req;
- CORBA_Environment ev;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetCompletionView;
- req->get_book_view.search = g_strdup(search);
-
- CORBA_exception_init (&ev);
-
- req->get_book_view.listener = bonobo_object_dup_ref(listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_queue_get_completion_view: Exception "
- "duplicating BookViewListener!\n");
- }
+ PASBook *book = PAS_BOOK (bonobo_object (servant));
- CORBA_exception_free (&ev);
+ printf ("impl_GNOME_Evolution_Addressbook_Book_open\n");
- pas_book_queue_request (book, req);
+ pas_backend_remove (pas_book_get_backend (book), book);
}
static void
-pas_book_queue_get_changes (PASBook *book, const GNOME_Evolution_Addressbook_BookViewListener listener, const char *change_id)
-{
- PASRequest *req;
- CORBA_Environment ev;
-
- req = g_new0 (PASRequest, 1);
- req->op = GetChanges;
- req->get_changes.change_id= g_strdup(change_id);
-
- CORBA_exception_init (&ev);
-
- req->get_changes.listener = bonobo_object_dup_ref(listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_queue_get_changes: Exception "
- "duplicating BookViewListener!\n");
- }
-
- CORBA_exception_free (&ev);
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_check_connection (PASBook *book)
+impl_GNOME_Evolution_Addressbook_Book_getContact (PortableServer_Servant servant,
+ const CORBA_char *id,
+ CORBA_Environment *ev)
{
- PASRequest *req;
+ PASBook *book = PAS_BOOK (bonobo_object (servant));
- req = g_new0 (PASRequest, 1);
- req->op = CheckConnection;
+ printf ("impl_GNOME_Evolution_Addressbook_Book_getContact\n");
- pas_book_queue_request (book, req);
+ pas_backend_get_contact (pas_book_get_backend (book), book, id);
}
static void
-impl_GNOME_Evolution_Addressbook_Book_getVCard (PortableServer_Servant servant,
- const CORBA_char *id,
- CORBA_Environment *ev)
+impl_GNOME_Evolution_Addressbook_Book_getContactList (PortableServer_Servant servant,
+ const CORBA_char *query,
+ CORBA_Environment *ev)
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_get_vcard (book, id);
+ printf ("impl_GNOME_Evolution_Addressbook_Book_getContactList\n");
+
+ pas_backend_get_contact_list (pas_book_get_backend (book), book, query);
}
static void
@@ -273,90 +80,97 @@ impl_GNOME_Evolution_Addressbook_Book_authenticateUser (PortableServer_Servant s
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_authenticate_user (book, user, passwd, auth_method);
+ pas_backend_authenticate_user (pas_book_get_backend (book), book,
+ user, passwd, auth_method);
}
static void
-impl_GNOME_Evolution_Addressbook_Book_addCard (PortableServer_Servant servant,
- const CORBA_char *vcard,
- CORBA_Environment *ev)
+impl_GNOME_Evolution_Addressbook_Book_addContact (PortableServer_Servant servant,
+ const CORBA_char *vcard,
+ CORBA_Environment *ev)
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_create_card (book, (const char *) vcard);
+ pas_backend_create_contact (pas_book_get_backend (book), book, vcard);
}
static void
-impl_GNOME_Evolution_Addressbook_Book_removeCards (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_CardIdList *ids,
- CORBA_Environment *ev)
+impl_GNOME_Evolution_Addressbook_Book_removeContacts (PortableServer_Servant servant,
+ const GNOME_Evolution_Addressbook_ContactIdList *ids,
+ CORBA_Environment *ev)
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
+ int i;
+ GList *id_list = NULL;
+
+ for (i = 0; i < ids->_length; i ++)
+ id_list = g_list_append (id_list, ids->_buffer[i]);
- pas_book_queue_remove_cards (book, ids);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_modifyCard (PortableServer_Servant servant,
- const CORBA_char *vcard,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object (servant));
+ pas_backend_remove_contacts (pas_book_get_backend (book), book, id_list);
- pas_book_queue_modify_card (book, (const char *) vcard);
+ g_list_free (id_list);
}
static void
-impl_GNOME_Evolution_Addressbook_Book_getCursor (PortableServer_Servant servant,
- const CORBA_char *search,
- CORBA_Environment *ev)
+impl_GNOME_Evolution_Addressbook_Book_modifyContact (PortableServer_Servant servant,
+ const CORBA_char *vcard,
+ CORBA_Environment *ev)
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_get_cursor (book, search);
+ pas_backend_modify_contact (pas_book_get_backend (book), book, vcard);
}
static void
impl_GNOME_Evolution_Addressbook_Book_getBookView (PortableServer_Servant servant,
const GNOME_Evolution_Addressbook_BookViewListener listener,
const CORBA_char *search,
+ const GNOME_Evolution_Addressbook_stringlist* requested_fields,
+ const CORBA_long max_results,
CORBA_Environment *ev)
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
+ PASBackend *backend = pas_book_get_backend (book);
+ PASBackendCardSExp *card_sexp;
+ PASBookView *view;
- pas_book_queue_get_book_view (book, listener, search);
-}
+ g_warning ("impl_GNOME_Evolution_Addressbook_Book_getBookView (%s)\n", search);
+ /* we handle this entirely here, since it doesn't require any
+ backend involvement now that we have pas_book_view_start to
+ actually kick off the search. */
-static void
-impl_GNOME_Evolution_Addressbook_Book_getCompletionView (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookViewListener listener,
- const CORBA_char *search,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object (servant));
+ card_sexp = pas_backend_card_sexp_new (search);
+ if (!card_sexp) {
+ pas_book_respond_get_book_view (book, GNOME_Evolution_Addressbook_InvalidQuery, NULL);
+ return;
+ }
+
+ view = pas_book_view_new (backend, listener, search, card_sexp);
- pas_book_queue_get_completion_view (book, listener, search);
+ if (!view) {
+ g_object_unref (card_sexp);
+ pas_book_respond_get_book_view (book, GNOME_Evolution_Addressbook_OtherError, NULL);
+ return;
+ }
+
+
+ pas_backend_add_book_view (backend, view);
+
+ pas_book_respond_get_book_view (book, GNOME_Evolution_Addressbook_Success, view);
+
+ g_object_unref (view);
}
+
static void
impl_GNOME_Evolution_Addressbook_Book_getChanges (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookViewListener listener,
const CORBA_char *change_id,
CORBA_Environment *ev)
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_get_changes (book, listener, change_id);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_checkConnection (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object (servant));
-
- pas_book_queue_check_connection (book);
+ pas_backend_get_changes (pas_book_get_backend (book), book, change_id);
}
static char *
@@ -379,7 +193,7 @@ impl_GNOME_Evolution_Addressbook_Book_getSupportedFields (PortableServer_Servant
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_get_supported_fields (book);
+ pas_backend_get_supported_fields (pas_book_get_backend (book), book);
}
static void
@@ -388,7 +202,16 @@ impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods (PortableServer_Se
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- pas_book_queue_get_supported_auth_methods (book);
+ pas_backend_get_supported_auth_methods (pas_book_get_backend (book), book);
+}
+
+static GNOME_Evolution_Addressbook_CallStatus
+impl_GNOME_Evolution_Addressbook_Book_cancelOperation (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ PASBook *book = PAS_BOOK (bonobo_object (servant));
+
+ return pas_backend_cancel_operation (pas_book_get_backend (book), book);
}
/**
@@ -397,87 +220,59 @@ impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods (PortableServer_Se
PASBackend *
pas_book_get_backend (PASBook *book)
{
- g_return_val_if_fail (book != NULL, NULL);
- g_return_val_if_fail (PAS_IS_BOOK (book), NULL);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), NULL);
return book->priv->backend;
}
-/**
- * pas_book_get_listener:
- */
GNOME_Evolution_Addressbook_BookListener
pas_book_get_listener (PASBook *book)
{
- g_return_val_if_fail (book != NULL, CORBA_OBJECT_NIL);
- g_return_val_if_fail (PAS_IS_BOOK (book), CORBA_OBJECT_NIL);
+ g_return_val_if_fail (book && PAS_IS_BOOK (book), CORBA_OBJECT_NIL);
return book->priv->listener;
}
-/**
- * pas_book_check_pending
- */
-gint
-pas_book_check_pending (PASBook *book)
+const char*
+pas_book_get_uri (PASBook *book)
{
- g_return_val_if_fail (book != NULL, -1);
- g_return_val_if_fail (PAS_IS_BOOK (book), -1);
-
- return g_list_length (book->priv->request_queue);
+ return book->priv->uri;
}
/**
- * pas_book_pop_request:
+ * pas_book_respond_open:
*/
-PASRequest *
-pas_book_pop_request (PASBook *book)
+void
+pas_book_respond_open (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status)
{
- GList *popped;
- PASRequest *req;
-
- g_return_val_if_fail (book != NULL, NULL);
- g_return_val_if_fail (PAS_IS_BOOK (book), NULL);
-
- if (book->priv->request_queue == NULL)
- return NULL;
-
- req = book->priv->request_queue->data;
+ CORBA_Environment ev;
- popped = book->priv->request_queue;
- book->priv->request_queue =
- g_list_remove_link (book->priv->request_queue, popped);
+ CORBA_exception_init (&ev);
+ GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (book->priv->listener, status, &ev);
- g_list_free_1 (popped);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("pas_book_respond_open: Exception "
+ "responding to BookListener!\n");
+ }
- return req;
+ CORBA_exception_free (&ev);
}
/**
- * pas_book_respond_open:
+ * pas_book_respond_remove:
*/
void
-pas_book_respond_open (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status)
+pas_book_respond_remove (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status)
{
CORBA_Environment ev;
CORBA_exception_init (&ev);
-
- if (status == GNOME_Evolution_Addressbook_BookListener_Success) {
- GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (
- book->priv->listener, status,
- bonobo_object_corba_objref (BONOBO_OBJECT (book)),
- &ev);
- } else {
- GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (
- book->priv->listener, status,
- CORBA_OBJECT_NIL, &ev);
- }
-
+ GNOME_Evolution_Addressbook_BookListener_notifyBookRemoved (book->priv->listener, status, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_open: Exception "
+ g_warning ("pas_book_respond_remove: Exception "
"responding to BookListener!\n");
}
@@ -488,16 +283,22 @@ pas_book_respond_open (PASBook *book,
* pas_book_respond_create:
*/
void
-pas_book_respond_create (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const char *id)
+pas_book_respond_create (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ EContact *contact)
{
CORBA_Environment ev;
+ if (status == GNOME_Evolution_Addressbook_Success) {
+ pas_backend_notify_update (book->priv->backend, contact);
+ pas_backend_notify_complete (book->priv->backend);
+ }
+
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyCardCreated (
- book->priv->listener, status, (char *)id, &ev);
+ GNOME_Evolution_Addressbook_BookListener_notifyContactCreated (
+ book->priv->listener, status,
+ e_contact_get (contact, E_CONTACT_UID), &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
g_warning ("pas_book_respond_create: Exception "
@@ -508,17 +309,25 @@ pas_book_respond_create (PASBook *book,
}
/**
- * pas_book_respond_remove:
+ * pas_book_respond_remove_contacts:
*/
void
-pas_book_respond_remove (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status)
+pas_book_respond_remove_contacts (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *ids)
{
CORBA_Environment ev;
+ GList *i;
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyCardsRemoved (
+ if (ids) {
+ for (i = ids; i; i = i->next)
+ pas_backend_notify_remove (book->priv->backend, i->data);
+ pas_backend_notify_complete (book->priv->backend);
+ }
+
+ GNOME_Evolution_Addressbook_BookListener_notifyContactsRemoved (
book->priv->listener, status, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
@@ -533,14 +342,20 @@ pas_book_respond_remove (PASBook *book,
* pas_book_respond_modify:
*/
void
-pas_book_respond_modify (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status)
+pas_book_respond_modify (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ EContact *contact)
{
CORBA_Environment ev;
+ if (status == GNOME_Evolution_Addressbook_Success) {
+ pas_backend_notify_update (book->priv->backend, contact);
+ pas_backend_notify_complete (book->priv->backend);
+ }
+
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyCardModified (
+ GNOME_Evolution_Addressbook_BookListener_notifyContactModified (
book->priv->listener, status, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
@@ -556,7 +371,7 @@ pas_book_respond_modify (PASBook *book,
*/
void
pas_book_respond_authenticate_user (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status)
+ GNOME_Evolution_Addressbook_CallStatus status)
{
CORBA_Environment ev;
@@ -575,30 +390,28 @@ pas_book_respond_authenticate_user (PASBook *book,
void
pas_book_respond_get_supported_fields (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- EList *fields)
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *fields)
{
CORBA_Environment ev;
GNOME_Evolution_Addressbook_stringlist stringlist;
int num_fields;
- EIterator *iter;
int i;
+ GList *iter;
CORBA_exception_init (&ev);
- num_fields = e_list_length (fields);
+ num_fields = g_list_length (fields);
stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_fields);
stringlist._maximum = num_fields;
stringlist._length = num_fields;
- iter = e_list_get_iterator (fields);
-
- for (i = 0; e_iterator_is_valid (iter); e_iterator_next (iter), i ++) {
- stringlist._buffer[i] = CORBA_string_dup (e_iterator_get(iter));
+ for (i = 0, iter = fields; iter; iter = iter->next, i ++) {
+ stringlist._buffer[i] = CORBA_string_dup ((char*)iter->data);
}
- g_object_unref (fields);
+ printf ("calling GNOME_Evolution_Addressbook_BookListener_notifySupportedFields\n");
GNOME_Evolution_Addressbook_BookListener_notifySupportedFields (
book->priv->listener, status,
@@ -612,31 +425,27 @@ pas_book_respond_get_supported_fields (PASBook *book,
void
pas_book_respond_get_supported_auth_methods (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- EList *auth_methods)
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *auth_methods)
{
CORBA_Environment ev;
GNOME_Evolution_Addressbook_stringlist stringlist;
int num_auth_methods;
- EIterator *iter;
+ GList *iter;
int i;
CORBA_exception_init (&ev);
- num_auth_methods = e_list_length (auth_methods);
+ num_auth_methods = g_list_length (auth_methods);
stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_auth_methods);
stringlist._maximum = num_auth_methods;
stringlist._length = num_auth_methods;
- iter = e_list_get_iterator (auth_methods);
-
- for (i = 0; e_iterator_is_valid (iter); e_iterator_next (iter), i ++) {
- stringlist._buffer[i] = CORBA_string_dup (e_iterator_get(iter));
+ for (i = 0, iter = auth_methods; iter; iter = iter->next, i ++) {
+ stringlist._buffer[i] = CORBA_string_dup ((char*)iter->data);
}
- g_object_unref (auth_methods);
-
GNOME_Evolution_Addressbook_BookListener_notifySupportedAuthMethods (
book->priv->listener, status,
&stringlist,
@@ -647,30 +456,28 @@ pas_book_respond_get_supported_auth_methods (PASBook *book,
CORBA_free(stringlist._buffer);
}
-/**
- * pas_book_respond_get_cursor:
- */
-void
-pas_book_respond_get_cursor (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASCardCursor *cursor)
-{
- CORBA_Environment ev;
- CORBA_Object object;
-
- CORBA_exception_init (&ev);
-
- object = bonobo_object_corba_objref(BONOBO_OBJECT(cursor));
-
- GNOME_Evolution_Addressbook_BookListener_notifyCursorRequested (
- book->priv->listener, status, object, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_get_cursor: Exception "
- "responding to BookListener!\n");
+static void
+view_destroy(gpointer data, GObject *where_object_was)
+{
+ PASBook *book = (PASBook *)data;
+ EIterator *iterator;
+ gboolean success = FALSE;
+ EList *views = pas_backend_get_book_views (book->priv->backend);
+
+ for (iterator = e_list_get_iterator(views);
+ e_iterator_is_valid(iterator);
+ e_iterator_next(iterator)) {
+ const PASBookView *view = e_iterator_get(iterator);
+ if (view == (PASBookView*)where_object_was) {
+ e_iterator_delete(iterator);
+ success = TRUE;
+ break;
+ }
}
-
- CORBA_exception_free (&ev);
+ if (!success)
+ g_warning ("Failed to remove from book_views list");
+ g_object_unref(iterator);
+ g_object_unref(views);
}
/**
@@ -678,15 +485,21 @@ pas_book_respond_get_cursor (PASBook *book,
*/
void
pas_book_respond_get_book_view (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
+ GNOME_Evolution_Addressbook_CallStatus status,
PASBookView *book_view)
{
CORBA_Environment ev;
- CORBA_Object object;
+ CORBA_Object object = CORBA_OBJECT_NIL;
+
+ printf ("pas_book_respond_get_book_view\n");
CORBA_exception_init (&ev);
-
- object = bonobo_object_corba_objref(BONOBO_OBJECT(book_view));
+
+ if (book_view) {
+ object = bonobo_object_corba_objref(BONOBO_OBJECT(book_view));
+
+ g_object_weak_ref (G_OBJECT (book_view), view_destroy, book);
+ }
GNOME_Evolution_Addressbook_BookListener_notifyViewRequested (
book->priv->listener, status, object, &ev);
@@ -700,100 +513,122 @@ pas_book_respond_get_book_view (PASBook *book,
}
/**
- * pas_book_respond_get_book_view:
+ * pas_book_respond_get_contact:
*/
void
-pas_book_respond_get_completion_view (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASBookView *completion_view)
+pas_book_respond_get_contact (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ char *vcard)
{
CORBA_Environment ev;
- CORBA_Object object;
CORBA_exception_init (&ev);
-
- object = bonobo_object_corba_objref(BONOBO_OBJECT(completion_view));
- GNOME_Evolution_Addressbook_BookListener_notifyViewRequested (
- book->priv->listener, status, object, &ev);
+ GNOME_Evolution_Addressbook_BookListener_notifyContactRequested (book->priv->listener,
+ status,
+ vcard,
+ &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_get_completion_view: Exception "
- "responding to BookListener!\n");
- }
+ if (ev._major != CORBA_NO_EXCEPTION)
+ g_message ("could not notify listener of get-contact response");
CORBA_exception_free (&ev);
}
/**
- * pas_book_respond_get_changes:
+ * pas_book_respond_get_contact_list:
*/
void
-pas_book_respond_get_vcard (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- char *vcard)
+pas_book_respond_get_contact_list (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *card_list)
{
CORBA_Environment ev;
+ GNOME_Evolution_Addressbook_stringlist stringlist;
+ int num_cards;
+ int i;
+ GList *l;
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyCardRequested (
- book->priv->listener, status, vcard, &ev);
+ num_cards = g_list_length (card_list);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_get_card: Exception "
- "responding to BookListener!\n");
- }
+ stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_cards);
+ stringlist._maximum = num_cards;
+ stringlist._length = num_cards;
- CORBA_exception_free (&ev);
-}
+ for (i = 0, l = card_list; l; l = l->next, i ++)
+ stringlist._buffer[i] = CORBA_string_dup (l->data);
-/**
- * pas_book_respond_get_changes:
- */
-void
-pas_book_respond_get_changes (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASBookView *book_view)
-{
- CORBA_Environment ev;
- CORBA_Object object;
+ g_list_foreach (card_list, (GFunc)g_free, NULL);
+ g_list_free (card_list);
- CORBA_exception_init (&ev);
-
- object = bonobo_object_corba_objref(BONOBO_OBJECT(book_view));
- GNOME_Evolution_Addressbook_BookListener_notifyChangesRequested (
- book->priv->listener, status, object, &ev);
+ GNOME_Evolution_Addressbook_BookListener_notifyContactListRequested (book->priv->listener,
+ status,
+ &stringlist,
+ &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_get_changes: Exception "
- "responding to BookListener!\n");
- }
+ if (ev._major != CORBA_NO_EXCEPTION)
+ g_message ("could not notify listener of get-contact-list response");
CORBA_exception_free (&ev);
+
+ CORBA_free(stringlist._buffer);
}
/**
- * pas_book_report_connection:
+ * pas_book_respond_get_changes:
*/
void
-pas_book_report_connection (PASBook *book,
- gboolean connected)
+pas_book_respond_get_changes (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *changes)
{
CORBA_Environment ev;
+ GNOME_Evolution_Addressbook_BookChangeList changelist;
+ int num_changes;
+ int i;
+ GList *l;
CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_BookListener_notifyConnectionStatus (
- book->priv->listener, (CORBA_boolean) connected, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_report_connection: Exception "
- "responding to BookListener!\n");
+ num_changes = g_list_length (changes);
+
+ changelist._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_BookChangeItem_allocbuf (num_changes);
+ changelist._maximum = num_changes;
+ changelist._length = num_changes;
+
+ for (i = 0, l = changes; l; l = l->next, i ++) {
+ GNOME_Evolution_Addressbook_BookChangeItem *change = (GNOME_Evolution_Addressbook_BookChangeItem*)l->data;
+ changelist._buffer[i] = *change;
+ switch (change->_d) {
+ case GNOME_Evolution_Addressbook_ContactAdded:
+ changelist._buffer[i]._u.add_vcard = CORBA_string_dup (change->_u.add_vcard);
+ break;
+ case GNOME_Evolution_Addressbook_ContactModified:
+ changelist._buffer[i]._u.mod_vcard = CORBA_string_dup (change->_u.mod_vcard);
+ break;
+ case GNOME_Evolution_Addressbook_ContactDeleted:
+ changelist._buffer[i]._u.del_id = CORBA_string_dup (change->_u.del_id);
+ break;
+ }
}
+ g_list_foreach (changes, (GFunc)CORBA_free, NULL);
+ g_list_free (changes);
+
+ GNOME_Evolution_Addressbook_BookListener_notifyChangesRequested (book->priv->listener,
+ status,
+ &changelist,
+ &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION)
+ g_message ("could not notify listener of get-changes response");
+
CORBA_exception_free (&ev);
+
+ CORBA_free(changelist._buffer);
}
/**
@@ -821,7 +656,8 @@ pas_book_report_writable (PASBook *book,
static void
pas_book_construct (PASBook *book,
PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener)
+ const char *uri,
+ GNOME_Evolution_Addressbook_BookListener listener)
{
PASBookPrivate *priv;
CORBA_Environment ev;
@@ -830,8 +666,6 @@ pas_book_construct (PASBook *book,
priv = book->priv;
- priv->backend = backend;
-
CORBA_exception_init (&ev);
book->priv->listener = CORBA_Object_duplicate (listener, &ev);
@@ -843,94 +677,31 @@ pas_book_construct (PASBook *book,
CORBA_exception_free (&ev);
- priv->listener = listener;
+ priv->backend = backend;
+ priv->uri = g_strdup (uri);
+
}
/**
* pas_book_new:
*/
PASBook *
-pas_book_new (PASBackend *backend,
+pas_book_new (PASBackend *backend,
+ const char *uri,
GNOME_Evolution_Addressbook_BookListener listener)
{
PASBook *book;
+ char *caps = pas_backend_get_static_capabilities (backend);
- book = g_object_new (PAS_TYPE_BOOK, NULL);
-
- pas_book_construct (book, backend, listener);
+ book = g_object_new (PAS_TYPE_BOOK,
+ "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL),
+ NULL);
- return book;
-}
+ pas_book_construct (book, backend, uri, listener);
-void
-pas_book_free_request (PASRequest *req)
-{
- CORBA_Environment ev;
- switch (req->op) {
- case CreateCard:
- g_free (req->create.id);
- g_free (req->create.vcard);
- break;
- case RemoveCards:
- g_list_foreach (req->remove.ids, (GFunc)g_free, NULL);
- g_list_free (req->remove.ids);
- break;
- case ModifyCard:
- g_free (req->modify.vcard);
- break;
- case GetVCard:
- g_free (req->get_vcard.id);
- break;
- case GetCursor:
- g_free (req->get_cursor.search);
- break;
- case GetBookView:
- g_free (req->get_book_view.search);
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (req->get_book_view.listener, &ev);
+ g_free (caps);
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_free_request(GetBookView): could not release the listener");
-
- CORBA_exception_free (&ev);
- break;
- case GetCompletionView:
- g_free (req->get_completion_view.search);
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (req->get_completion_view.listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_free_request(GetCompletionView): could not release the listener");
-
- CORBA_exception_free (&ev);
- break;
- case GetChanges:
- g_free (req->get_changes.change_id);
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (req->get_changes.listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_free_request(GetChanges): could not release the listener");
-
- CORBA_exception_free (&ev);
- break;
- case CheckConnection:
- /* nothing to free */
- break;
- case AuthenticateUser:
- g_free (req->auth_user.user);
- g_free (req->auth_user.passwd);
- g_free (req->auth_user.auth_method);
- break;
- case GetSupportedFields:
- /* nothing to free */
- break;
- case GetSupportedAuthMethods:
- /* nothing to free */
- break;
- }
-
- g_free (req);
+ return book;
}
static void
@@ -939,24 +710,8 @@ pas_book_dispose (GObject *object)
PASBook *book = PAS_BOOK (object);
if (book->priv) {
- GList *l;
CORBA_Environment ev;
- for (l = book->priv->request_queue; l != NULL; l = l->next) {
- pas_book_free_request ((PASRequest *)l->data);
- }
- g_list_free (book->priv->request_queue);
-
- /* We should never ever have timeout_id == 0 when we
- get destroyed, unless there is some sort of
- reference counting bug. Still, we do this to try
- to avoid horrible crashes in those situations. */
- if (book->priv->timeout_id) {
- g_warning ("PASBook destroyed with non-zero timeout_id. This shouldn't happen.");
- g_source_remove (book->priv->timeout_id);
- book->priv->timeout_id = 0;
- }
-
CORBA_exception_init (&ev);
CORBA_Object_release (book->priv->listener, &ev);
@@ -965,6 +720,7 @@ pas_book_dispose (GObject *object)
CORBA_exception_free (&ev);
+ g_free (book->priv->uri);
g_free (book->priv);
book->priv = NULL;
}
@@ -981,42 +737,30 @@ pas_book_class_init (PASBookClass *klass)
pas_book_parent_class = g_type_class_peek_parent (klass);
- pas_book_signals [REQUESTS_QUEUED] =
- g_signal_new ("requests_queued",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (PASBookClass, requests_queued),
- NULL, NULL,
- pas_marshal_NONE__NONE,
- G_TYPE_NONE, 0);
-
object_class->dispose = pas_book_dispose;
epv = &klass->epv;
- epv->getVCard = impl_GNOME_Evolution_Addressbook_Book_getVCard;
+ epv->open = impl_GNOME_Evolution_Addressbook_Book_open;
+ epv->remove = impl_GNOME_Evolution_Addressbook_Book_remove;
+ epv->getContact = impl_GNOME_Evolution_Addressbook_Book_getContact;
+ epv->getContactList = impl_GNOME_Evolution_Addressbook_Book_getContactList;
epv->authenticateUser = impl_GNOME_Evolution_Addressbook_Book_authenticateUser;
- epv->addCard = impl_GNOME_Evolution_Addressbook_Book_addCard;
- epv->removeCards = impl_GNOME_Evolution_Addressbook_Book_removeCards;
- epv->modifyCard = impl_GNOME_Evolution_Addressbook_Book_modifyCard;
- epv->checkConnection = impl_GNOME_Evolution_Addressbook_Book_checkConnection;
+ epv->addContact = impl_GNOME_Evolution_Addressbook_Book_addContact;
+ epv->removeContacts = impl_GNOME_Evolution_Addressbook_Book_removeContacts;
+ epv->modifyContact = impl_GNOME_Evolution_Addressbook_Book_modifyContact;
epv->getStaticCapabilities = impl_GNOME_Evolution_Addressbook_Book_getStaticCapabilities;
epv->getSupportedFields = impl_GNOME_Evolution_Addressbook_Book_getSupportedFields;
epv->getSupportedAuthMethods = impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods;
- epv->getCursor = impl_GNOME_Evolution_Addressbook_Book_getCursor;
epv->getBookView = impl_GNOME_Evolution_Addressbook_Book_getBookView;
- epv->getCompletionView = impl_GNOME_Evolution_Addressbook_Book_getCompletionView;
epv->getChanges = impl_GNOME_Evolution_Addressbook_Book_getChanges;
+ epv->cancelOperation = impl_GNOME_Evolution_Addressbook_Book_cancelOperation;
}
static void
pas_book_init (PASBook *book)
{
book->priv = g_new0 (PASBookPrivate, 1);
- book->priv->timeout_id = 0;
- book->priv->request_queue = NULL;
- book->priv->timeout_id = 0;
- book->priv->timeout_lock = FALSE;
}
BONOBO_TYPE_FUNC_FULL (
diff --git a/addressbook/backend/pas/pas-book.h b/addressbook/backend/pas/pas-book.h
index 761f906437..2cb84569c2 100644
--- a/addressbook/backend/pas/pas-book.h
+++ b/addressbook/backend/pas/pas-book.h
@@ -12,13 +12,11 @@
#ifndef __PAS_BOOK_H__
#define __PAS_BOOK_H__
-#include <bonobo/bonobo-object.h>
#include <pas/addressbook.h>
-#include <pas/pas-book-view.h>
+#include <bonobo/bonobo-object.h>
#include "e-util/e-list.h"
-#include <pas/pas-backend.h>
-#include <pas/pas-card-cursor.h>
+#include <pas/pas-types.h>
#define PAS_TYPE_BOOK (pas_book_get_type ())
#define PAS_BOOK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BOOK, PASBook))
@@ -27,164 +25,68 @@
#define PAS_IS_BOOK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BOOK))
#define PAS_BOOK_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BOOK, PASBookClass))
-typedef struct _PASBook PASBook;
typedef struct _PASBookPrivate PASBookPrivate;
-typedef enum {
- CreateCard,
- RemoveCards,
- ModifyCard,
- GetVCard,
- GetCursor,
- GetBookView,
- GetCompletionView,
- GetChanges,
- CheckConnection,
- AuthenticateUser,
- GetSupportedFields,
- GetSupportedAuthMethods
-} PASOperation;
-
-typedef struct {
- PASOperation op;
- char *id;
- char *vcard;
-} PASCreateCardRequest;
-
-typedef struct {
- PASOperation op;
- GList *ids;
-} PASRemoveCardsRequest;
-
-typedef struct {
- PASOperation op;
- char *vcard;
-} PASModifyCardRequest;
-
-typedef struct {
- PASOperation op;
- char *id;
-} PASGetVCardRequest;
-
-typedef struct {
- PASOperation op;
- char *search;
-} PASGetCursorRequest;
-
-typedef struct {
- PASOperation op;
- char *search;
- GNOME_Evolution_Addressbook_BookViewListener listener;
-} PASGetBookViewRequest;
-
-typedef struct {
- PASOperation op;
- char *search;
- GNOME_Evolution_Addressbook_BookViewListener listener;
-} PASGetCompletionViewRequest;
-
-typedef struct {
- PASOperation op;
- char *change_id;
- GNOME_Evolution_Addressbook_BookViewListener listener;
-} PASGetChangesRequest;
-
-typedef struct {
- PASOperation op;
-} PASCheckConnectionRequest;
-
-typedef struct {
- PASOperation op;
- char *user;
- char *passwd;
- char *auth_method;
-} PASAuthenticateUserRequest;
-
-typedef struct {
- PASOperation op;
-} PASGetSupportedFieldsRequest;
-
-typedef struct {
- PASOperation op;
-} PASGetSupportedAuthMethodsRequest;
-
-typedef union {
- PASOperation op;
-
- PASCreateCardRequest create;
- PASRemoveCardsRequest remove;
- PASModifyCardRequest modify;
- PASGetVCardRequest get_vcard;
- PASGetCursorRequest get_cursor;
- PASGetBookViewRequest get_book_view;
- PASGetCompletionViewRequest get_completion_view;
- PASGetChangesRequest get_changes;
- PASCheckConnectionRequest check_connection;
- PASAuthenticateUserRequest auth_user;
- PASGetSupportedFieldsRequest get_supported_fields;
- PASGetSupportedAuthMethodsRequest get_supported_auth_methods;
-} PASRequest;
-
struct _PASBook {
- BonoboObject parent_object;
- PASBookPrivate *priv;
+ BonoboObject parent_object;
+ PASBookPrivate *priv;
};
-typedef struct {
+struct _PASBookClass {
BonoboObjectClass parent_class;
POA_GNOME_Evolution_Addressbook_Book__epv epv;
- /* Signals */
- void (*requests_queued) (void);
-} PASBookClass;
-
-
-typedef gboolean (*PASBookCanWriteFn) (PASBook *book);
-typedef gboolean (*PASBookCanWriteCardFn) (PASBook *book, const char *id);
-
-PASBook *pas_book_new (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener);
-PASBackend *pas_book_get_backend (PASBook *book);
-GNOME_Evolution_Addressbook_BookListener pas_book_get_listener (PASBook *book);
-int pas_book_check_pending (PASBook *book);
-PASRequest *pas_book_pop_request (PASBook *book);
-void pas_book_free_request (PASRequest *request);
-void pas_book_respond_open (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status);
-void pas_book_respond_create (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const char *id);
-void pas_book_respond_remove (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status);
-void pas_book_respond_modify (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status);
-void pas_book_respond_authenticate_user (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status);
-void pas_book_respond_get_supported_fields (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- EList *fields);
-void pas_book_respond_get_supported_auth_methods (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- EList *fields);
-
-void pas_book_respond_get_cursor (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASCardCursor *cursor);
+ /* Padding for future expansion */
+ void (*_pas_reserved0) (void);
+ void (*_pas_reserved1) (void);
+ void (*_pas_reserved2) (void);
+ void (*_pas_reserved3) (void);
+ void (*_pas_reserved4) (void);
+};
+
+
+PASBook *pas_book_new (PASBackend *backend,
+ const char *uri,
+ GNOME_Evolution_Addressbook_BookListener listener);
+GNOME_Evolution_Addressbook_BookListener pas_book_get_listener (PASBook *book);
+PASBackend *pas_book_get_backend (PASBook *book);
+const char *pas_book_get_uri (PASBook *book);
+
+void pas_book_respond_open (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status);
+void pas_book_respond_remove (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status);
+void pas_book_respond_create (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ EContact *contact);
+void pas_book_respond_remove_contacts (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *ids);
+void pas_book_respond_modify (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ EContact *contact);
+void pas_book_respond_authenticate_user (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status);
+void pas_book_respond_get_supported_fields (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *fields);
+void pas_book_respond_get_supported_auth_methods (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *fields);
+
void pas_book_respond_get_book_view (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
+ GNOME_Evolution_Addressbook_CallStatus status,
PASBookView *book_view);
-void pas_book_respond_get_completion_view (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASBookView *completion_view);
-void pas_book_respond_get_vcard (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
+void pas_book_respond_get_contact (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
char *vcard);
-void pas_book_respond_get_changes (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASBookView *book_view);
-void pas_book_report_connection (PASBook *book,
- gboolean connected);
+void pas_book_respond_get_contact_list (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *cards);
+void pas_book_respond_get_changes (PASBook *book,
+ GNOME_Evolution_Addressbook_CallStatus status,
+ GList *changes);
void pas_book_report_writable (PASBook *book,
gboolean writable);
diff --git a/addressbook/backend/pas/pas-card-cursor.c b/addressbook/backend/pas/pas-card-cursor.c
deleted file mode 100644
index 9637bb1fb7..0000000000
--- a/addressbook/backend/pas/pas-card-cursor.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * pas-card-cursor.c: Implements card cursors.
- *
- * Author:
- * Christopher James Lahey <clahey@ximian.com.
- */
-
-#include <config.h>
-#include <bonobo/bonobo-main.h>
-#include "addressbook.h"
-#include "pas-card-cursor.h"
-
-struct _PASCardCursorPrivate {
- long (*get_length) (PASCardCursor *cursor, gpointer data);
- char * (*get_nth) (PASCardCursor *cursor, long n, gpointer data);
- gpointer data;
-};
-
-/*
- * A pointer to our parent object class
- */
-static BonoboObjectClass *parent_class;
-
-/*
- * Implemented GObject::dispose
- */
-static void
-pas_card_cursor_dispose (GObject *object)
-{
- PASCardCursor *cursor = PAS_CARD_CURSOR (object);
-
- if ( cursor->priv ) {
- g_free ( cursor->priv );
- cursor->priv = NULL;
- }
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-/*
- * CORBA Demo::Echo::echo method implementation
- */
-static CORBA_long
-impl_pas_card_cursor_get_length (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- PASCardCursor *cursor = PAS_CARD_CURSOR (bonobo_object (servant));
- if ( cursor->priv->get_length )
- return cursor->priv->get_length( cursor, cursor->priv->data );
- else
- return 0;
-}
-
-/*
- * CORBA Demo::Echo::echo method implementation
- */
-static char *
-impl_pas_card_cursor_get_nth (PortableServer_Servant servant,
- const CORBA_long n,
- CORBA_Environment *ev)
-{
- PASCardCursor *cursor = PAS_CARD_CURSOR (bonobo_object (servant));
- if ( cursor->priv->get_nth ) {
- char *vcard = cursor->priv->get_nth( cursor, n, cursor->priv->data );
- char *retval = CORBA_string_dup (vcard);
- g_free (vcard);
- return retval;
- } else
- return CORBA_string_dup ("");
-}
-
-static void
-pas_card_cursor_class_init (PASCardCursorClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- POA_GNOME_Evolution_Addressbook_CardCursor__epv *epv;
-
- parent_class = g_type_class_peek_parent (klass);
-
- object_class->dispose = pas_card_cursor_dispose;
-
-
- epv = &klass->epv;
-
- epv->count = impl_pas_card_cursor_get_length;
- epv->getNth = impl_pas_card_cursor_get_nth;
-}
-
-static void
-pas_card_cursor_init (PASCardCursor *cursor)
-{
- cursor->priv = g_new0(PASCardCursorPrivate, 1);
- cursor->priv->get_length = NULL;
- cursor->priv->get_nth = NULL;
- cursor->priv->data = NULL;
-}
-
-static void
-pas_card_cursor_construct (PASCardCursor *cursor,
- PASCardCursorLengthFunc get_length,
- PASCardCursorNthFunc get_nth,
- gpointer data)
-{
- PASCardCursorPrivate *priv;
-
- g_return_if_fail (cursor != NULL);
- g_return_if_fail (PAS_IS_CARD_CURSOR (cursor));
-
- priv = cursor->priv;
-
- priv->get_length = get_length;
- priv->get_nth = get_nth;
- priv->data = data;
-}
-
-PASCardCursor *
-pas_card_cursor_new (PASCardCursorLengthFunc get_length,
- PASCardCursorNthFunc get_nth,
- gpointer data)
-{
- PASCardCursor *cursor;
-
- cursor = g_object_new (PAS_TYPE_CARD_CURSOR, NULL);
-
- pas_card_cursor_construct (cursor,
- get_length,
- get_nth,
- data);
-
- return cursor;
-}
-
-BONOBO_TYPE_FUNC_FULL (
- PASCardCursor,
- GNOME_Evolution_Addressbook_CardCursor,
- BONOBO_TYPE_OBJECT,
- pas_card_cursor);
diff --git a/addressbook/backend/pas/pas-card-cursor.h b/addressbook/backend/pas/pas-card-cursor.h
deleted file mode 100644
index db5b05c0c2..0000000000
--- a/addressbook/backend/pas/pas-card-cursor.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- *
- * Author:
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#ifndef __PAS_CARD_CURSOR_H__
-#define __PAS_CARD_CURSOR_H__
-
-#include <bonobo/bonobo-object.h>
-#include <pas/addressbook.h>
-
-G_BEGIN_DECLS
-
-#define PAS_TYPE_CARD_CURSOR (pas_card_cursor_get_type ())
-#define PAS_CARD_CURSOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_CARD_CURSOR, PASCardCursor))
-#define PAS_CARD_CURSOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_TYPE_CARD_CURSOR, PASCardCursorClass))
-#define PAS_IS_CARD_CURSOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_CARD_CURSOR))
-#define PAS_IS_CARD_CURSOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_CARD_CURSOR))
-#define PAS_CARD_CURSOR_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_CARD_CURSOR, PASCardCursorClass))
-
-typedef struct _PASCardCursor PASCardCursor;
-typedef struct _PASCardCursorPrivate PASCardCursorPrivate;
-typedef struct _PASCardCursorClass PASCardCursorClass;
-
-typedef long (*PASCardCursorLengthFunc) (PASCardCursor *cursor, gpointer data);
-typedef char * (*PASCardCursorNthFunc) (PASCardCursor *cursor, long n, gpointer data);
-
-struct _PASCardCursor {
- BonoboObject parent;
- PASCardCursorPrivate *priv;
-};
-
-struct _PASCardCursorClass {
- BonoboObjectClass parent;
-
- POA_GNOME_Evolution_Addressbook_CardCursor__epv epv;
-};
-
-
-
-/* Creating a new addressbook. */
-PASCardCursor *pas_card_cursor_new (PASCardCursorLengthFunc get_length,
- PASCardCursorNthFunc get_nth,
- gpointer data);
-
-GType pas_card_cursor_get_type (void);
-POA_GNOME_Evolution_Addressbook_CardCursor__epv *
- pas_card_cursor_get_epv (void);
-
-G_END_DECLS
-
-#endif /* ! __PAS_CARD_CURSOR_H__ */
diff --git a/addressbook/backend/pas/pas-marshal.list b/addressbook/backend/pas/pas-marshal.list
index fa33740eaa..9d6744db44 100644
--- a/addressbook/backend/pas/pas-marshal.list
+++ b/addressbook/backend/pas/pas-marshal.list
@@ -1 +1,2 @@
NONE:NONE
+NONE:POINTER
diff --git a/addressbook/backend/pas/pas-types.h b/addressbook/backend/pas/pas-types.h
new file mode 100644
index 0000000000..19611a4e23
--- /dev/null
+++ b/addressbook/backend/pas/pas-types.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Blanket header containing the typedefs for object types used in the
+ * PAS stuff, so we can disentangle the #includes.
+ *
+ * Author: Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright 2003, Ximian, Inc.
+ */
+
+#ifndef __PAS_TYPES_H__
+#define __PAS_TYPES_H__
+
+typedef struct _PASBookView PASBookView;
+typedef struct _PASBookViewClass PASBookViewClass;
+
+typedef struct _PASBackendCardSExp PASBackendCardSExp;
+typedef struct _PASBackendCardSExpClass PASBackendCardSExpClass;
+
+typedef struct _PASBackend PASBackend;
+typedef struct _PASBackendClass PASBackendClass;
+
+typedef struct _PASBackendSummary PASBackendSummary;
+typedef struct _PASBackendSummaryClass PASBackendSummaryClass;
+
+typedef struct _PASBackendSync PASBackendSync;
+typedef struct _PASBackendSyncClass PASBackendSyncClass;
+
+typedef struct _PASBook PASBook;
+typedef struct _PASBookClass PASBookClass;
+
+#endif /* __PAS_TYPES_H__ */
diff --git a/addressbook/backend/pas/ximian-vcard.h b/addressbook/backend/pas/ximian-vcard.h
new file mode 100644
index 0000000000..961a5cadb4
--- /dev/null
+++ b/addressbook/backend/pas/ximian-vcard.h
@@ -0,0 +1,81 @@
+#define XIMIAN_VCARD \
+"BEGIN:VCARD\n" \
+"X-EVOLUTION-FILE-AS:Ximian\\, Inc.\n" \
+"ADR;TYPE=WORK:;Suite 3 West;401 Park Drive;Boston;MA;02215;USA\n" \
+"LABEL;TYPE=WORK:401 Park Drive\\nSuite 3 West\\nBoston\\, MA\\n02215\\nUSA\n" \
+"TEL;WORK;VOICE:(617) 375-3800\n" \
+"TEL;WORK;FAX:(617) 236-8630\n" \
+"EMAIL;INTERNET:hello@ximian.com\n" \
+"URL:http://www.ximian.com/\n" \
+"ORG:Ximian\\, Inc.;\n" \
+"NOTE:Welcome to the Ximian Addressbook.\n" \
+"PHOTO;ENCODING=b;TYPE=JPEG:/9j/4AAQSkZJRgABAQEARwBHAAD//gAXQ3JlYXRlZCB3aXRo\n" \
+" IFRoZSBHSU1Q/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLCM\n" \
+" cHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sAQwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMj\n" \
+" IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAbgBkAwEiAAIRAQMRAf/EA\n" \
+" BwAAAIDAQEBAQAAAAAAAAAAAAAHBQYIBAMBAv/EAEYQAAEDAwEFBgMEBgQPAAAAAAECAwQABREG\n" \
+" BxIhMWETIkFRcYEUkaEIMkLBFSNSsbLRFmJydRgkMzY3Q0RGgpKTosLh8P/EABsBAQACAwEBAAA\n" \
+" AAAAAAAAAAAAEBQIDBgEH/8QALREAAQMCAwYGAgMAAAAAAAAAAQACAwQREiFRBRMiMUFhMnGBkb\n" \
+" HRBsEUofD/2gAMAwEAAhEDEQA/AH/RRRREVwXe9W2wwFzbpNZixkc1uqwPQeZ6CoHXevLfom1ds\n" \
+" 9h6a6D8PGCsFZHMk+CR4n86yzdbrqfaZqYBSnp0hRPZMoG62ynoOSR1Pua8Lg0XPJegX5Jv6k+0\n" \
+" bBjrWxp22LlkcBIlHs0HqEjiR64peT9umupqyWrhHhpP4WI6eHureNW7Tmw+DGaTI1FJVJdxksM\n" \
+" qKG09CrmfbFMCHpCw2xATDs8JrH4gykq+Z4mqifbMUZsxpd/QUllK53M2SCb2xa+bXvf0gcV0Uw\n" \
+" 0R/DVktH2hdUwlpFxjQrg1490tLPuOH0pvv2qE4jdchx1p8lNAj91Va87OtM3RCt+2Nx3Dyci/q\n" \
+" yPYcD7g1EZ+RR4rSMI9b/S2mhdbhKsmkdtWmNTuNxnXVW2cvgGZRASo+SV8j74PSmOlQUMpORWP\n" \
+" NU7MrjY0rlQFmdDTxOE4cQOo8R1Hyqe2Z7ZJ2m32bXfHnJVpJCUuqO8uP7+Kenh4eVXkFRFUMxx\n" \
+" G4UOSN0Zs4LU1FeEOWxOityYzqHWXEhSFoOQoHkQa963rBFFFFERUdfr1E09Y5d1mr3Y8ZsrV5n\n" \
+" yA6k4A6mpGkL9ojUym0W/TrLmAsGU+AeYBwgfPJ/4RREqrrcb1tJ1oUpBXLmObqUZ7rSByT0SkZ\n" \
+" J8zk1pHQmiLXo+zpbabC3SAp55Q7zyvM9PIUudiGmURbS7fpCMvzFFton8LSTxx6qH0FM7VV9VY\n" \
+" 9MzZ7aQt5tASw3+26ohKB/zEVSVFVvZzGMw02tqe/kpbI8LMR6/C/Xxq9QagfbbP+IW1QQ4Rycf\n" \
+" xncHRAIJ/rEfsmu2a9Fgsl2XIZjtj8bqwgfM1+9L2VFksESAV9o6hG886ebjqjvLWepUSarutdn\n" \
+" MXV+obRcZks/CwCQ5DKMpeBOTxzwzgA9KwfTtfxPOSB5GQUXc9pOjoC+zXe2HV5xiOC6PmkEfWp\n" \
+" xe6tAWghSVDIIOQRXxekNOx4b0WPZYLLTram19mwlJKSMHjjNUzQd2dZM7SNxczcLOsttqVzdYz\n" \
+" 3FewI9iKpK2mjMZdFe7ed9NfT9qZDI4OAd1Vkko50ndoui22kuXq2NBOO9JZSOH9sD9/z86c8gc\n" \
+" DUJNQlaFJUkKSoYII4EVGoKp9PIHt9e6lyRNlZhcqlsJ2guQpydL3F4mO7kw1KP3Fcyj0PEjrnz\n" \
+" rSAIIyOVYfvsJ3TGqlCKpTfYuJfjLHMDOR8jw9q2Foy+o1FpWBckY/XMpUoeRxxHsciu/jeJGB7\n" \
+" eRXPvaWuLT0U/RRRWaxQeVY82x3BVw2oXbJyhgoZR0AQM/UmthK+6fSsWbRQW9pV73x/tZPtwNE\n" \
+" Wj9Nw0WuwwIKQAGI6G/cAZ+tRW0lx5nTEW4Ntqdat9xjy5CEjJLSFZP5H2qaYdCkpUk5BGQa7Ap\n" \
+" DrSm3EpWhYKVJUMgg8wRXz+kqyyTG7VXUsV22Clrfc48+CzMiPIejvIC23EHIUDXNe79b7HbXbh\n" \
+" c5SI8ZvmtZ5nyA5k9BS7d0nfdMPuSdD3JtEZaitdom5Uznx3DzT6cPWkvq/V1611fGW5nZtBCgy\n" \
+" zFbXhtCycE5JxknxPhXR07RUeB3D11H+9lAfwcxmrrqLbxcHpikWGAw1FScByUkqWvrgEBPpxqi\n" \
+" ztdXWdqmNqIIjx7gykJUphJCXAM/eBJ5g4PQCmBZNiDKWEu364uF0jJYh4AT6qUDn2FVu6bPIkT\n" \
+" aTB08xKeMOU2H99eCtKRvZGQMZ7hwceNZxVGzsbmMzIBv5dfNeOjnsCdUwbTtKsV8nJgIccZkqw\n" \
+" lJcThDqvJJz8s4zUtLVzpc2vZZKt+qBIkyUKt0V0ONKSe+7g5SCPDr9Kv0tznXP1cNMyQfxnXBC\n" \
+" tqUyuB3gslftPjJLkGWB3u82o/Ij86bf2e7iqRoxyIpWfhpC0JHQ4V/5GlVtJcBt0RPiXif+00w\n" \
+" Ps5BQtNxP4TJP8Ka6rZZJpW37/Kq68ATlPeiiirBQ0HlWR9t9qVbtpEp/dwiY0h5J8Mgbp/h+ta\n" \
+" 4pM7fdKLumn2rxGbKn4BKl4HEtn73ywD7GiL7o28JuulLbKCsqLKUL/tJ7p+oqyIe4c6RGyzU4g\n" \
+" THLNJc3WpCt9gk8A54j3GPcdaZuoosy82V23QpaYpkEIdeIJKUeIAHieXPkTXA11DuassJsCefY\n" \
+" /SvYZN5FiGZU9edRwLDAXJny2mRukoStQBWQOQHjSjg7PYE7ZmzcZb7cG6KK5CZD6txOCcJQvPg\n" \
+" QAQfAn2q6RNOWi1D9J3R5dwlR2xmZPVv9mlI8ByTj59ar09Lm0jUIQl5Y0zAUMrQSPiXfHHpyz4\n" \
+" D1qTRvMQIieQAQXOtllfIDre/X2WqVmI8Qz6D9q0bP9SO37SrSpW8ZUVXw7q+YcKeSgeRyMZ65q\n" \
+" qammvWTalEv1yjOJtaWfh25CBvBOUkHPlxUeHlyq/MiPCitxorSGWG07qG0DASK45xZlx3GJDaH\n" \
+" WljCkLGQR6VGinY2ofIG8Lri2gOi37hxYG3zC+uT2HY6ZDbyFMrAUlwK7pB5HNRcp7nxqpzdN3G\n" \
+" CFQ7NObTa3nApcaSN/suOe4SDw6VK3O4swojsp9WGmxk9fIDrW4UzWkbt2K/v691vjec8YtZUTa\n" \
+" BL+IuMaIjiWWytXQn/wBD608tgtrVC0W2+tOFSFqd9icD6AVnmFFl6n1AhoAmRPdwcfgR4n2H7q\n" \
+" 2Ppi1N2exRojaQlKEBIHkAK7Gmi3MTWaLn6iTeSF+qmaKKK3rSiuedEanQ3I7qQpC0kEEZzXRRR\n" \
+" FjnaRoSVoq/KcYQv9HOr3mHB/qzz3SenhVi0ftAbnNNwLo6G5iQEodUcJd9fJX760ZqLTkHUdsd\n" \
+" hTWEOtuJwQoVl/XGyS7aakOPwGnJcDORujK0DqPH2qJV0cdUzC/0Oi3QTuhddqY84IuFukwnFFK\n" \
+" JDSmlEcwFDGR86ISI1tgtQ4jYaYaTuoSP/udJS1azvFoAZLnbsp4dm/klPQHmKs0faVEWkfEw32\n" \
+" 1f1CFj8q56XZNSwYG5t7fSt46yB5ucimM5L4c643pXWqU5tCteMpRKUfIIH86ipmvnnAUwoQSf2\n" \
+" 3lZ+g/nWEey5yfCtrquBo8Su0+4sQ46pEp1LTSeZUfoPOlnfr67fZKQlK0QkK/VtficV5nrXOkX\n" \
+" XUk9KQHp0gnghI7qPyAp1bOdkCmH2rneQHHxxQjHdb9OvWr2j2c2Didm74VZVVplGFuQXRsc2fO\n" \
+" Qgb1cmsSXQN1JH+TT4D+dPEAAADkK848duMylppISkDGBXrVkoCKKKKIiiqrrbX9m0JARIua1re\n" \
+" dJDMdoArcI58+AA8zVLsO26RqiS9Gsukpct5lHaKbTLaSrd8wFEZ9s0RN6vGRGZktlDqAoHzFKq\n" \
+" JtomzrPOuzGjZvwEBRTJfckttpbUOae9jJ5cBk8R514Wrbo7e489+3aTlvtQGTIkqElsdm2Mkq4\n" \
+" 4zyPKiKf1Hsj09flKdXEQh4/jR3VfMUvJ/2et1ZMOe8keSgFfyqz2LbfJ1M9IZs2kJsx2O0XnEN\n" \
+" yEAhA4ZwcZ58hxr7ZdtkvUS5SbTo2fJMRsuPkPoSG0jzKsDPPhz4HyoipDewC47+FXFWOjYH51Y\n" \
+" bTsAgtrSqc88/jwWrA+QxUlYtujupZ6oNo0nLlSUtqdKEyW04SMZOVYHiKjP8ACUt5/wB3pX/XT\n" \
+" /KiJnWLQ1nsTSURorad39lIFWZKUoThIAHSlNqDbLP0siKu96MnQ0ygSyVyGzvYxnlnB4jga87F\n" \
+" ttlamXJbs2j50xcZvtXUtyEZCfPB5+gyaIm9RSetm3J68RbhJgaSmPM25vtZaviW09knjxIOM8j\n" \
+" y8q7LHtzstwv/AOhrlBftkkudkFOLS43v5xgqSeHHx5daImrRX5QtK0hSTkGiiLMP2ho8wa1iSn\n" \
+" QoxVRQ20fAKClFQ9eIqq7LLJe7vreG7ZZCoZhqD8iZjustjnnwORkY8c+Wa1ZqbStt1PBMa4MId\n" \
+" Rz7wzg+dL8bEbA1vpa7RtK+CkpdWAfXjRFB7UpCNe6Kdm6NnJft1qluKuUJlvdKznPbYH3hzPXJ\n" \
+" PMGqZsk/zc2gf3G5/Cumc3sRsTO92Rcb3uB3XVjP1r4jYfYGwoN76QsYUEurGR5HjREudhUt2BP\n" \
+" 1TMYID0eyuuoJGRvJII+oq96I2iwtVz7rb7ZZWbalyzyJ9wKUjLsrKEkjH4cE8+Jz049bew+wNb\n" \
+" 3Z76N4YO66sZHlzob2H2Bkktb6CRglLqxkeXOiJZbAv9IMj+7X/wB6ag9lGnEaj17CRJA+BhZmy\n" \
+" lK+6EI44PQq3R6E06W9h9gZVvNb6FYxlLqwcfOhvYhYWt7s99G8MK3XVjI68aIo7UxgbR9IajhQ\n" \
+" 7/Du9yiSF3S3tMNrStlkAAt94DPDI4eJFUvYfNetqNYz4xAfjWZx5skZAUnJHD1FMVrYhYWVbzW\n" \
+" +2ojGUOrBx86EbD7A0FBvfRvDCt11YyPI8aIo23zdP6i2e621TaUJiXCfa1IucFPJt5KVnfHRWS\n" \
+" euPPNZ2YadfkNsspUp1aglCU8yTyrTSNh9gbCgjfSFjCgl1YyPI8al9PbItP2WamUywkuJ5KOVE\n" \
+" emeVEVw02ZH9H4YkEqdDYCifE4oqXbaS02lCRhIGBRRF//Z\n" \
+"END:VCARD"