diff options
Diffstat (limited to 'addressbook/backend')
-rw-r--r-- | addressbook/backend/ebook/e-book-util.c | 128 | ||||
-rw-r--r-- | addressbook/backend/ebook/e-book-util.h | 10 | ||||
-rw-r--r-- | addressbook/backend/ebook/e-destination.c | 246 | ||||
-rw-r--r-- | addressbook/backend/ebook/e-destination.h | 41 |
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 *); |