aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/backend
diff options
context:
space:
mode:
Diffstat (limited to 'addressbook/backend')
-rw-r--r--addressbook/backend/ebook/e-book-util.c128
-rw-r--r--addressbook/backend/ebook/e-book-util.h10
-rw-r--r--addressbook/backend/ebook/e-destination.c246
-rw-r--r--addressbook/backend/ebook/e-destination.h41
4 files changed, 409 insertions, 16 deletions
diff --git a/addressbook/backend/ebook/e-book-util.c b/addressbook/backend/ebook/e-book-util.c
index aa7ead900f..d10c5612f1 100644
--- a/addressbook/backend/ebook/e-book-util.c
+++ b/addressbook/backend/ebook/e-book-util.c
@@ -48,12 +48,77 @@ e_book_load_local_address_book (EBook *book, EBookCallback open_response, gpoint
rv = e_book_load_uri (book, uri, open_response, closure);
+ if (!rv) {
+ g_warning ("Couldn't load local addressbook %s", uri);
+ }
+
g_free (filename);
g_free (uri);
return rv;
}
+static EBook *common_local_book = NULL;
+
+typedef struct _CommonBookInfo CommonBookInfo;
+struct _CommonBookInfo {
+ EBookCommonCallback cb;
+ gpointer closure;
+};
+
+static void
+got_local_book_cb (EBook *book, EBookStatus status, gpointer closure)
+{
+ CommonBookInfo *info = (CommonBookInfo *) closure;
+
+ if (status == E_BOOK_STATUS_SUCCESS) {
+
+ /* We try not to leak in a race condition where the
+ local book got loaded twice. */
+
+ if (common_local_book) {
+ gtk_object_unref (GTK_OBJECT (book));
+ book = common_local_book;
+ }
+
+ info->cb (book, info->closure);
+
+ if (common_local_book == NULL) {
+ common_local_book = book;
+ }
+
+ } else {
+
+ info->cb (NULL, info->closure);
+
+ }
+ g_free (info);
+}
+
+void
+e_book_use_local_address_book (EBookCommonCallback cb, gpointer closure)
+{
+ EBook *book;
+ CommonBookInfo *info;
+
+ g_return_if_fail (cb != NULL);
+
+ if (common_local_book != NULL) {
+ cb (common_local_book, closure);
+ return;
+ }
+
+ info = g_new0 (CommonBookInfo, 1);
+ info->cb = cb;
+ info->closure = closure;
+
+ book = e_book_new ();
+ if (! e_book_load_local_address_book (book, got_local_book_cb, info)) {
+ gtk_object_unref (GTK_OBJECT (book));
+ g_free (info);
+ }
+}
+
/*
*
* Simple Query Stuff
@@ -441,3 +506,66 @@ e_book_name_and_email_query (EBook *book,
return tag;
}
+
+/*
+ * Convenience routine to check for addresses in the local address book.
+ */
+
+typedef struct _HaveAddressInfo HaveAddressInfo;
+struct _HaveAddressInfo {
+ gchar *email;
+ EBookHaveAddressCallback cb;
+ gpointer closure;
+};
+
+static void
+have_address_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
+{
+ HaveAddressInfo *info = (HaveAddressInfo *) closure;
+
+
+ info->cb (book,
+ info->email,
+ cards && (status == E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS) ? E_CARD (cards->data) : NULL,
+ info->closure);
+
+ g_free (info->email);
+ g_free (info);
+}
+
+static void
+have_address_book_open_cb (EBook *book, gpointer closure)
+{
+ HaveAddressInfo *info = (HaveAddressInfo *) closure;
+
+ if (book) {
+
+ e_book_name_and_email_query (book, NULL, info->email, have_address_query_cb, info);
+
+ } else {
+
+ info->cb (NULL, info->email, NULL, info->closure);
+
+ g_free (info->email);
+ g_free (info);
+
+ }
+}
+
+void
+e_book_query_address_locally (const gchar *email,
+ EBookHaveAddressCallback cb,
+ gpointer closure)
+{
+ HaveAddressInfo *info;
+
+ g_return_if_fail (email != NULL);
+ g_return_if_fail (cb != NULL);
+
+ info = g_new0 (HaveAddressInfo, 1);
+ info->email = g_strdup (email);
+ info->cb = cb;
+ info->closure = closure;
+
+ e_book_use_local_address_book (have_address_book_open_cb, info);
+}
diff --git a/addressbook/backend/ebook/e-book-util.h b/addressbook/backend/ebook/e-book-util.h
index cf0103bfea..0988887324 100644
--- a/addressbook/backend/ebook/e-book-util.h
+++ b/addressbook/backend/ebook/e-book-util.h
@@ -34,12 +34,16 @@
BEGIN_GNOME_DECLS
/* Callbacks for asynchronous functions. */
+typedef void (*EBookCommonCallback) (EBook *book, gpointer closure);
typedef void (*EBookSimpleQueryCallback) (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure);
+typedef void (*EBookHaveAddressCallback) (EBook *book, const gchar *addr, ECard *card, gpointer closure);
gboolean e_book_load_local_address_book (EBook *book,
EBookCallback open_response,
gpointer closure);
+void e_book_use_local_address_book (EBookCommonCallback cb, gpointer closure);
+
/* Simple Query Interface. */
guint e_book_simple_query (EBook *book,
@@ -57,6 +61,12 @@ guint e_book_name_and_email_query (EBook *book,
EBookSimpleQueryCallback cb,
gpointer closure);
+/* Returns the ECard associated to email in the callback,
+ or NULL if no match is found in the local address book. */
+void e_book_query_address_locally (const gchar *email,
+ EBookHaveAddressCallback cb,
+ gpointer closure);
+
END_GNOME_DECLS
diff --git a/addressbook/backend/ebook/e-destination.c b/addressbook/backend/ebook/e-destination.c
index e6fdb3ee43..83bd96a7d1 100644
--- a/addressbook/backend/ebook/e-destination.c
+++ b/addressbook/backend/ebook/e-destination.c
@@ -40,6 +40,9 @@ struct _EDestinationPrivate {
gchar *string;
gchar *string_email;
gchar *string_email_verbose;
+
+ gboolean html_mail_override;
+ gboolean wants_html_mail;
};
static void e_destination_clear_card (EDestination *);
@@ -187,6 +190,15 @@ e_destination_set_string (EDestination *dest, const gchar *string)
dest->priv->string = g_strdup (string);
}
+void
+e_destination_set_html_mail_pref (EDestination *dest, gboolean x)
+{
+ g_return_if_fail (dest && E_IS_DESTINATION (dest));
+
+ dest->priv->html_mail_override = TRUE;
+ dest->priv->wants_html_mail = x;
+}
+
ECard *
e_destination_get_card (const EDestination *dest)
{
@@ -319,11 +331,11 @@ e_destination_get_email_verbose (const EDestination *dest)
if (priv->string_email_verbose == NULL) {
const gchar *email = e_destination_get_email (dest);
+ const gchar *name = e_destination_get_name (dest);
- if (priv->card) {
- gchar *n = e_card_name_to_string (priv->card->name);
- priv->string_email_verbose = g_strdup_printf ("%s <%s>", n, email);
- g_free (n);
+ if (name) {
+
+ priv->string_email_verbose = g_strdup_printf ("%s <%s>", name, email);
} else {
@@ -335,4 +347,230 @@ e_destination_get_email_verbose (const EDestination *dest)
return priv->string_email_verbose;
}
+gboolean
+e_destination_get_html_mail_pref (const EDestination *dest)
+{
+ g_return_val_if_fail (dest && E_IS_DESTINATION (dest), FALSE);
+
+ if (dest->priv->html_mail_override || dest->priv->card == NULL)
+ return dest->priv->wants_html_mail;
+
+ return dest->priv->card->wants_html;
+}
+
+gchar *
+e_destination_get_address_textv (EDestination **destv)
+{
+ gint i, j, len = 0;
+ gchar **strv;
+ gchar *str;
+ g_return_val_if_fail (destv, NULL);
+
+ while (destv[len]) {
+ g_return_val_if_fail (E_IS_DESTINATION (destv[len]), NULL);
+ ++len;
+ }
+
+ strv = g_new0 (gchar *, len+1);
+ for (i = 0, j = 0; destv[i]; ++i) {
+ const gchar *addr = e_destination_get_email_verbose (destv[i]);
+
+ strv[j++] = addr ? (gchar *) addr : "";
+ }
+
+ str = g_strjoinv (", ", strv);
+
+ g_free (strv);
+
+ return str;
+}
+
+/*
+ *
+ * Serialization code
+ *
+ */
+
+#define DESTINATION_TAG "DEST"
+#define DESTINATION_SEPARATOR "|"
+
+static gchar *
+join_strings (gchar **strv)
+{
+ /* FIXME: Should also quote any |'s that occur in any of the strings. */
+ return g_strjoinv (DESTINATION_SEPARATOR, strv);
+}
+
+static gchar **
+unjoin_string (const gchar *str)
+{
+ /* FIXME: Should properly handle quoteded |'s in the string. */
+ return g_strsplit (str, DESTINATION_SEPARATOR, 0);
+}
+
+static gchar *
+build_field (const gchar *key, const gchar *value)
+{
+ return g_strdup_printf ("%s=%s", key, value);
+}
+
+/* Modifies string in place, \0-terminates after the key, returns pointer to "value",
+ or NULL if the field is malformed. */
+static gchar *
+extract_field (gchar *field)
+{
+ gchar *s = strchr (field, '=');
+ if (s == NULL)
+ return NULL;
+ *s = '\0';
+ return s+1;
+}
+
+
+gchar *
+e_destination_export (const EDestination *dest)
+{
+ gchar **fields;
+ gchar *str;
+ gint i;
+
+ g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
+
+ fields = g_new (gchar *, 5);
+ fields[0] = g_strdup (DESTINATION_TAG);
+ fields[1] = build_field ("addr", e_destination_get_email (dest));
+
+ i = 2;
+
+ if (e_destination_get_name (dest))
+ fields[i++] = build_field ("name", e_destination_get_name (dest));
+
+ fields[i++] = build_field ("html",
+ e_destination_get_html_mail_pref (dest) ? "Y" : "N");
+
+ fields[i] = NULL;
+
+
+ str = join_strings (fields);
+ g_strfreev (fields);
+
+ return str;
+}
+
+EDestination *
+e_destination_import (const gchar *str)
+{
+ EDestination *dest;
+ gchar **fields;
+ gint i;
+
+ gchar *addr = NULL, *name = NULL;
+ gboolean want_html = FALSE;
+
+ g_return_val_if_fail (str, NULL);
+
+ fields = unjoin_string (str);
+ g_return_val_if_fail (fields && fields[0], NULL);
+ g_return_val_if_fail (!strcmp (fields[0], DESTINATION_TAG), NULL);
+
+ for (i = 1; fields[i]; ++i) {
+ gchar *key = fields[i];
+ gchar *value = extract_field (fields[i]);
+
+ if (value) {
+
+ if (!strcmp ("addr", key)) {
+
+ if (addr) {
+ g_warning ("addr redefined: \"%s\" => \"%s\"", addr, value);
+ }
+
+ addr = g_strdup (value);
+
+ } else if (!strcmp ("name", key)) {
+
+ if (name) {
+ g_warning ("name redefined: \"%s\" => \"%s\"", name, value);
+ }
+
+ name = g_strdup (name);
+
+ } else if (!strcmp ("html", key)) {
+
+ want_html = (*value == 'Y');
+
+ }
+
+ }
+
+ }
+ dest = e_destination_new ();
+
+ /* We construct this part of the object in a rather abusive way. */
+ dest->priv->string_email = addr;
+ dest->priv->name = name;
+
+ e_destination_set_html_mail_pref (dest, want_html);
+
+ g_strfreev (fields);
+
+ return dest;
+}
+
+#define VEC_SEPARATOR "\1"
+
+gchar *
+e_destination_exportv (EDestination **destv)
+{
+ gint i, len = 0;
+ gchar **strv;
+ gchar *str;
+
+ g_return_val_if_fail (destv, NULL);
+
+ while (destv[len]) {
+ g_return_val_if_fail (E_IS_DESTINATION (destv[len]), NULL);
+ ++len;
+ }
+
+ strv = g_new0 (gchar *, len+1);
+ for (i = 0; i < len; ++i)
+ strv[i] = e_destination_export (destv[i]);
+
+ str = g_strjoinv (VEC_SEPARATOR, strv);
+
+ for (i = 0; i < len; ++i)
+ g_free (strv[i]);
+ g_free (strv);
+
+ return str;
+}
+
+EDestination **
+e_destination_importv (const gchar *str)
+{
+ gchar** strv;
+ EDestination **destv;
+ gint i = 0, j = 0, len = 0;
+
+ if (!(str && *str))
+ return NULL;
+
+ strv = g_strsplit (str, VEC_SEPARATOR, 0);
+ while (strv[len])
+ ++len;
+
+ destv = g_new0 (EDestination *, len+1);
+
+ while (strv[i]) {
+ EDestination *dest = e_destination_import (strv[i]);
+ if (dest) {
+ destv[j++] = dest;
+ }
+ ++i;
+ }
+
+ g_strfreev (strv);
+ return destv;
+}
diff --git a/addressbook/backend/ebook/e-destination.h b/addressbook/backend/ebook/e-destination.h
index 3c6de6e316..bb3c77d475 100644
--- a/addressbook/backend/ebook/e-destination.h
+++ b/addressbook/backend/ebook/e-destination.h
@@ -54,23 +54,40 @@ struct _EDestinationClass {
GtkType e_destination_get_type (void);
-EDestination *e_destination_new (void);
-EDestination *e_destination_copy (EDestination *);
-gboolean e_destination_is_empty (EDestination *);
+EDestination *e_destination_new (void);
+EDestination *e_destination_copy (EDestination *);
-void e_destination_set_card (EDestination *, ECard *card, gint email_num);
-void e_destination_set_string (EDestination *, const gchar *string);
+gboolean e_destination_is_empty (EDestination *);
-ECard *e_destination_get_card (const EDestination *);
-gint e_destination_get_email_num (const EDestination *);
-const gchar *e_destination_get_string (const EDestination *);
-gint e_destination_get_strlen (const EDestination *); /* a convenience function... */
+void e_destination_set_card (EDestination *, ECard *card, gint email_num);
+void e_destination_set_string (EDestination *, const gchar *string);
+void e_destination_set_html_mail_pref (EDestination *, gboolean);
+
+ECard *e_destination_get_card (const EDestination *);
+gint e_destination_get_email_num (const EDestination *);
+const gchar *e_destination_get_string (const EDestination *);
+gint e_destination_get_strlen (const EDestination *); /* a convenience function... */
+
+const gchar *e_destination_get_name (const EDestination *);
+
+const gchar *e_destination_get_email (const EDestination *);
+const gchar *e_destination_get_email_verbose (const EDestination *);
+
+/* If true, they want HTML mail. */
+gboolean e_destination_get_html_mail_pref (const EDestination *);
+
+gchar *e_destination_get_address_textv (EDestination **);
+
+
+gchar *e_destination_export (const EDestination *);
+EDestination *e_destination_import (const gchar *str);
+
+gchar *e_destination_exportv (EDestination **);
+EDestination **e_destination_importv (const gchar *str);
+
-const gchar *e_destination_get_name (const EDestination *);
-const gchar *e_destination_get_email (const EDestination *);
-const gchar *e_destination_get_email_verbose (const EDestination *);