diff options
Diffstat (limited to 'addressbook/backend/ebook/e-book-util.c')
-rw-r--r-- | addressbook/backend/ebook/e-book-util.c | 759 |
1 files changed, 0 insertions, 759 deletions
diff --git a/addressbook/backend/ebook/e-book-util.c b/addressbook/backend/ebook/e-book-util.c deleted file mode 100644 index d3de9840f8..0000000000 --- a/addressbook/backend/ebook/e-book-util.c +++ /dev/null @@ -1,759 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * e-book-util.c - * - * Copyright (C) 2001 Ximian, Inc. - * - * Developed by Jon Trowbridge <trow@ximian.com> - */ - -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ - -#include <config.h> -#include "e-book-util.h" - -#include <gtk/gtkobject.h> -#include <gtk/gtksignal.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-util.h> -#include "e-card-compare.h" - -typedef struct _CommonBookInfo CommonBookInfo; -struct _CommonBookInfo { - EBookCommonCallback cb; - gpointer closure; -}; - -char * -e_book_expand_uri (const char *uri) -{ - char *new_uri; - - if (!strncmp (uri, "file:", 5)) { - if (strlen (uri + 7) > 3 - && !strcmp (uri + strlen(uri) - 3, ".db")) { - /* it's a .db file */ - new_uri = g_strdup (uri); - } - else { - char *file_name; - /* we assume it's a dir and glom addressbook.db onto the end. */ - file_name = g_concat_dir_and_file(uri + 7, "addressbook.db"); - new_uri = g_strdup_printf("file://%s", file_name); - g_free(file_name); - } - } - else { - new_uri = g_strdup (uri); - } - - return new_uri; -} - -static void -got_uri_book_cb (EBook *book, EBookStatus status, gpointer closure) -{ - CommonBookInfo *info = (CommonBookInfo *) closure; - - if (status == E_BOOK_STATUS_SUCCESS) { - info->cb (book, info->closure); - } else { - info->cb (NULL, info->closure); - } - g_free (info); -} - -gboolean -e_book_load_address_book_by_uri (EBook *book, const char *uri, EBookCallback open_response, gpointer closure) -{ - gboolean rv; - char *real_uri; - - g_return_val_if_fail (book != NULL, FALSE); - g_return_val_if_fail (E_IS_BOOK (book), FALSE); - g_return_val_if_fail (open_response != NULL, FALSE); - - real_uri = e_book_expand_uri (uri); - - rv = e_book_load_uri (book, real_uri, open_response, closure); - - if (!rv) { - g_warning ("Couldn't load addressbook %s", real_uri); - } - - g_free (real_uri); - - return rv; -} - -void -e_book_use_address_book_by_uri (const char *uri, EBookCommonCallback cb, gpointer closure) -{ - EBook *book; - CommonBookInfo *info; - - g_return_if_fail (cb != NULL); - - info = g_new0 (CommonBookInfo, 1); - info->cb = cb; - info->closure = closure; - - book = e_book_new (); - if (! e_book_load_address_book_by_uri (book, uri, got_uri_book_cb, info)) { - gtk_object_unref (GTK_OBJECT (book)); - g_free (info); - } -} - -Bonobo_ConfigDatabase -e_book_get_config_database (CORBA_Environment *ev) -{ - static Bonobo_ConfigDatabase config_db; - - if (config_db == NULL) - config_db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", ev); - - return config_db; -} - -gboolean -e_book_load_local_address_book (EBook *book, EBookCallback open_response, gpointer closure) -{ - gchar *filename; - gchar *uri; - gboolean rv; - - g_return_val_if_fail (book != NULL, FALSE); - g_return_val_if_fail (E_IS_BOOK (book), FALSE); - g_return_val_if_fail (open_response != NULL, FALSE); - - filename = gnome_util_prepend_user_home ("evolution/local/Contacts/addressbook.db"); - uri = g_strdup_printf ("file://%s", filename); - - 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; - -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); - } -} - -typedef struct { - gpointer closure; - EBookCallback open_response; -} DefaultBookClosure; - -static void -e_book_default_book_open (EBook *book, EBookStatus status, gpointer closure) -{ - DefaultBookClosure *default_book_closure = closure; - gpointer user_closure = default_book_closure->closure; - EBookCallback user_response = default_book_closure->open_response; - - g_free (default_book_closure); - - /* special case the protocol not supported error, since we - really only want to failover to the local book in the case - where there's no installed backend for that protocol. all - other errors (failure to connect, etc.) should get reported - to the caller as normal. */ - if (status == E_BOOK_STATUS_PROTOCOL_NOT_SUPPORTED) { - e_book_load_local_address_book (book, user_response, user_closure); - } - else { - user_response (book, status, user_closure); - } -} - -gboolean -e_book_load_default_book (EBook *book, EBookCallback open_response, gpointer closure) -{ - char *val, *uri; - gboolean rv; - CORBA_Environment ev; - Bonobo_ConfigDatabase config_db; - - g_return_val_if_fail (book != NULL, FALSE); - g_return_val_if_fail (E_IS_BOOK (book), FALSE); - g_return_val_if_fail (open_response != NULL, FALSE); - - CORBA_exception_init (&ev); - config_db = e_book_get_config_database (&ev); - val = bonobo_config_get_string (config_db, "/DefaultFolders/contacts_uri", &ev); - CORBA_exception_free (&ev); - - if (val) { - DefaultBookClosure *default_book_closure = g_new (DefaultBookClosure, 1); - default_book_closure->closure = closure; - default_book_closure->open_response = open_response; - - /* Sigh. FIXME. */ - if (!strncmp (val, "file:", 5)) - uri = g_strconcat (val, "/addressbook.db", NULL); - else - uri = g_strdup (val); - rv = e_book_load_uri (book, uri, - e_book_default_book_open, default_book_closure); - g_free (uri); - g_free (val); - } - else { - rv = e_book_load_local_address_book (book, open_response, closure); - } - - if (!rv) { - g_warning ("Couldn't load default addressbook"); - } - - return rv; -} - -/* - * - * Simple Query Stuff - * - */ - -typedef struct _SimpleQueryInfo SimpleQueryInfo; -struct _SimpleQueryInfo { - guint tag; - EBook *book; - gchar *query; - EBookSimpleQueryCallback cb; - gpointer closure; - EBookView *view; - guint add_tag; - guint seq_complete_tag; - GList *cards; - gboolean cancelled; -}; - -static void -book_add_simple_query (EBook *book, SimpleQueryInfo *info) -{ - GList *pending = gtk_object_get_data (GTK_OBJECT (book), "sq_pending"); - pending = g_list_prepend (pending, info); - gtk_object_set_data (GTK_OBJECT (book), "sq_pending", pending); -} - -static SimpleQueryInfo * -book_lookup_simple_query (EBook *book, guint tag) -{ - GList *pending = gtk_object_get_data (GTK_OBJECT (book), "sq_pending"); - while (pending) { - SimpleQueryInfo *sq = pending->data; - if (sq->tag == tag) - return sq; - pending = g_list_next (pending); - } - return NULL; -} - -static void -book_remove_simple_query (EBook *book, SimpleQueryInfo *info) -{ - GList *pending = gtk_object_get_data (GTK_OBJECT (book), "sq_pending"); - GList *i; - - for (i=pending; i != NULL; i = g_list_next (i)) { - if (i->data == info) { - pending = g_list_remove_link (pending, i); - g_list_free_1 (i); - break; - } - } - gtk_object_set_data (GTK_OBJECT (book), "sq_pending", pending); -} - -static guint -book_issue_tag (EBook *book) -{ - gpointer ptr = gtk_object_get_data (GTK_OBJECT (book), "sq_tag"); - guint tag = GPOINTER_TO_UINT (ptr); - if (tag == 0) - tag = 1; - gtk_object_set_data (GTK_OBJECT (book), "sq_tag", GUINT_TO_POINTER (tag+1)); - return tag; -} - -static SimpleQueryInfo * -simple_query_new (EBook *book, const char *query, EBookSimpleQueryCallback cb, gpointer closure) -{ - SimpleQueryInfo *sq = g_new0 (SimpleQueryInfo, 1); - - sq->tag = book_issue_tag (book); - sq->book = book; - gtk_object_ref (GTK_OBJECT (book)); - sq->query = g_strdup (query); - sq->cb = cb; - sq->closure = closure; - sq->cancelled = FALSE; - - /* Automatically add ourselves to the EBook's pending list. */ - book_add_simple_query (book, sq); - - return sq; -} - -static void -simple_query_disconnect (SimpleQueryInfo *sq) -{ - if (sq->add_tag) { - gtk_signal_disconnect (GTK_OBJECT (sq->view), sq->add_tag); - sq->add_tag = 0; - } - - if (sq->seq_complete_tag) { - gtk_signal_disconnect (GTK_OBJECT (sq->view), sq->seq_complete_tag); - sq->seq_complete_tag = 0; - } - - if (sq->view) { - gtk_object_unref (GTK_OBJECT (sq->view)); - sq->view = NULL; - } -} - -static void -simple_query_free (SimpleQueryInfo *sq) -{ - simple_query_disconnect (sq); - - /* Remove ourselves from the EBook's pending list. */ - book_remove_simple_query (sq->book, sq); - - g_free (sq->query); - - if (sq->book) - gtk_object_unref (GTK_OBJECT (sq->book)); - - g_list_foreach (sq->cards, (GFunc) gtk_object_unref, NULL); - g_list_free (sq->cards); - - g_free (sq); -} - -static void -simple_query_card_added_cb (EBookView *view, const GList *cards, gpointer closure) -{ - SimpleQueryInfo *sq = closure; - - if (sq->cancelled) - return; - - sq->cards = g_list_concat (sq->cards, g_list_copy ((GList *) cards)); - g_list_foreach ((GList *) cards, (GFunc) gtk_object_ref, NULL); -} - -static void -simple_query_sequence_complete_cb (EBookView *view, gpointer closure) -{ - SimpleQueryInfo *sq = closure; - - /* Disconnect signals, so that we don't pick up any changes to the book that occur - in our callback */ - simple_query_disconnect (sq); - if (! sq->cancelled) - sq->cb (sq->book, E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS, sq->cards, sq->closure); - simple_query_free (sq); -} - -static void -simple_query_book_view_cb (EBook *book, EBookStatus status, EBookView *book_view, gpointer closure) -{ - SimpleQueryInfo *sq = closure; - - if (sq->cancelled) { - simple_query_free (sq); - return; - } - - if (status != E_BOOK_STATUS_SUCCESS) { - simple_query_disconnect (sq); - sq->cb (sq->book, E_BOOK_SIMPLE_QUERY_STATUS_OTHER_ERROR, NULL, sq->closure); - simple_query_free (sq); - return; - } - - sq->view = book_view; - gtk_object_ref (GTK_OBJECT (book_view)); - - sq->add_tag = gtk_signal_connect (GTK_OBJECT (sq->view), - "card_added", - GTK_SIGNAL_FUNC (simple_query_card_added_cb), - sq); - sq->seq_complete_tag = gtk_signal_connect (GTK_OBJECT (sq->view), - "sequence_complete", - GTK_SIGNAL_FUNC (simple_query_sequence_complete_cb), - sq); -} - -guint -e_book_simple_query (EBook *book, const char *query, EBookSimpleQueryCallback cb, gpointer closure) -{ - SimpleQueryInfo *sq; - - g_return_val_if_fail (book && E_IS_BOOK (book), 0); - g_return_val_if_fail (query, 0); - g_return_val_if_fail (cb, 0); - - sq = simple_query_new (book, query, cb, closure); - e_book_get_book_view (book, (gchar *) query, simple_query_book_view_cb, sq); - - return sq->tag; -} - -void -e_book_simple_query_cancel (EBook *book, guint tag) -{ - SimpleQueryInfo *sq; - - g_return_if_fail (book && E_IS_BOOK (book)); - - sq = book_lookup_simple_query (book, tag); - - if (sq) { - sq->cancelled = TRUE; - sq->cb (sq->book, E_BOOK_SIMPLE_QUERY_STATUS_CANCELLED, NULL, sq->closure); - } else { - g_warning ("Simple query tag %d is unknown", tag); - } -} - -/* - * - * Specialized Queries - * - */ - -typedef struct _NameEmailQueryInfo NameEmailQueryInfo; -struct _NameEmailQueryInfo { - gchar *name; - gchar *email; - EBookSimpleQueryCallback cb; - gpointer closure; -}; - -static void -name_email_query_info_free (NameEmailQueryInfo *info) -{ - if (info) { - g_free (info->name); - g_free (info->email); - g_free (info); - } -} - -static void -name_and_email_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure) -{ - NameEmailQueryInfo *info = closure; - GList *filtered_cards = NULL; - - while (cards) { - ECard *card = E_CARD (cards->data); - if ((info->name == NULL || e_card_compare_name_to_string (card, info->name) >= E_CARD_MATCH_VAGUE) - && (info->email == NULL || e_card_email_match_string (card, info->email))) { - filtered_cards = g_list_append (filtered_cards, card); - } - cards = g_list_next (cards); - } - - info->cb (book, status, filtered_cards, info->closure); - - g_list_free (filtered_cards); - - name_email_query_info_free (info); -} - -guint -e_book_name_and_email_query (EBook *book, - const gchar *name, - const gchar *email, - EBookSimpleQueryCallback cb, - gpointer closure) -{ - NameEmailQueryInfo *info; - gchar *email_query=NULL, *name_query=NULL, *query; - guint tag; - - g_return_val_if_fail (book && E_IS_BOOK (book), 0); - g_return_val_if_fail (cb != NULL, 0); - - if (name && !*name) - name = NULL; - if (email && !*email) - email = NULL; - - if (name == NULL && email == NULL) - return 0; - - /* Build our e-mail query. - * We only query against the username part of the address, to avoid not matching - * fred@foo.com and fred@mail.foo.com. While their may be namespace collisions - * in the usernames of everyone out there, it shouldn't be that bad. (Famous last words.) - */ - if (email) { - const gchar *t = email; - while (*t && *t != '@') - ++t; - if (*t == '@') { - email_query = g_strdup_printf ("(beginswith \"email\" \"%.*s@\")", t-email, email); - - } else { - email_query = g_strdup_printf ("(beginswith \"email\" \"%s\")", email); - } - } - - /* Build our name query. - * We only do name-query stuff if we don't have an e-mail address. Our basic assumption - * is that the username part of the email is good enough to keep the amount of stuff returned - * in the query relatively small. - */ - if (name && !email) { - gchar *name_cpy = g_strdup (name), *qjoined; - gchar **namev; - gint i, count=0; - - g_strstrip (name_cpy); - namev = g_strsplit (name_cpy, " ", 0); - for (i=0; namev[i]; ++i) { - if (*namev[i]) { - char *str = namev[i]; - - namev[i] = g_strdup_printf ("(contains \"file_as\" \"%s\")", namev[i]); - ++count; - - g_free (str); - } - } - - qjoined = g_strjoinv (" ", namev); - if (count > 1) { - name_query = g_strdup_printf ("(or %s)", qjoined); - } else { - name_query = qjoined; - qjoined = NULL; - } - - g_free (name_cpy); - g_strfreev (namev); - g_free (qjoined); - } - - /* Assemble our e-mail & name queries */ - if (email_query && name_query) { - query = g_strdup_printf ("(and %s %s)", email_query, name_query); - } else if (email_query) { - query = email_query; - email_query = NULL; - } else if (name_query) { - query = name_query; - name_query = NULL; - } else - return 0; - - info = g_new0 (NameEmailQueryInfo, 1); - info->name = g_strdup (name); - info->email = g_strdup (email); - info->cb = cb; - info->closure = closure; - - tag = e_book_simple_query (book, query, name_and_email_cb, info); - - g_free (email_query); - g_free (name_query); - g_free (query); - - return tag; -} - -/* - * Simple nickname query - */ - -typedef struct _NicknameQueryInfo NicknameQueryInfo; -struct _NicknameQueryInfo { - gchar *nickname; - EBookSimpleQueryCallback cb; - gpointer closure; -}; - -static void -nickname_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure) -{ - NicknameQueryInfo *info = closure; - - if (info->cb) - info->cb (book, status, cards, info->closure); - - g_free (info->nickname); - g_free (info); -} - -guint -e_book_nickname_query (EBook *book, - const char *nickname, - EBookSimpleQueryCallback cb, - gpointer closure) -{ - NicknameQueryInfo *info; - gchar *query; - guint retval; - - g_return_val_if_fail (E_IS_BOOK (book), 0); - g_return_val_if_fail (nickname != NULL, 0); - - /* The empty-string case shouldn't generate a warning. */ - if (! *nickname) - return 0; - - info = g_new0 (NicknameQueryInfo, 1); - info->nickname = g_strdup (nickname); - info->cb = cb; - info->closure = closure; - - query = g_strdup_printf ("(is \"nickname\" \"%s\")", info->nickname); - - retval = e_book_simple_query (book, query, nickname_cb, info); - - g_free (query); - - return retval; -} - -/* - * 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); -} |