diff options
Diffstat (limited to 'addressbook/backend/ebook/e-book.c')
-rw-r--r-- | addressbook/backend/ebook/e-book.c | 2060 |
1 files changed, 0 insertions, 2060 deletions
diff --git a/addressbook/backend/ebook/e-book.c b/addressbook/backend/ebook/e-book.c deleted file mode 100644 index b551c8727b..0000000000 --- a/addressbook/backend/ebook/e-book.c +++ /dev/null @@ -1,2060 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -#include <config.h> - -#include <pthread.h> - -#include <string.h> - -#include "e-book.h" -#include "e-vcard.h" - -#include <bonobo-activation/bonobo-activation.h> - -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-main.h> - -#include <libgnome/gnome-i18n.h> - -#include "e-book-marshal.h" -#include "e-book-listener.h" -#include "addressbook.h" -#include "e-util/e-component-listener.h" -#include "e-util/e-msgport.h" - -static GObjectClass *parent_class; - -#define CARDSERVER_OAF_ID "OAFIID:GNOME_Evolution_Wombat_ServerFactory" - -#define e_return_error_if_fail(expr,error_code) G_STMT_START{ \ - if G_LIKELY(expr) { } else \ - { \ - g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_CRITICAL, \ - "file %s: line %d (%s): assertion `%s' failed", \ - __FILE__, \ - __LINE__, \ - __PRETTY_FUNCTION__, \ - #expr); \ - g_set_error (error, E_BOOK_ERROR, (error_code), \ - "file %s: line %d (%s): assertion `%s' failed", \ - __FILE__, \ - __LINE__, \ - __PRETTY_FUNCTION__, \ - #expr); \ - return FALSE; \ - }; }G_STMT_END - -/* XXX we need a better error message here */ -#define E_BOOK_CHECK_STATUS(status,error) G_STMT_START{ \ - if ((status) == E_BOOK_ERROR_OK) { \ - return TRUE; \ - } \ - else { \ - g_set_error ((error), E_BOOK_ERROR, (status), "EBookStatus returned %d", (status)); \ - return FALSE; \ - } }G_STMT_END - -enum { - OPEN_PROGRESS, - WRITABLE_STATUS, - BACKEND_DIED, - LAST_SIGNAL -}; - -static guint e_book_signals [LAST_SIGNAL]; - -typedef struct { - EMutex *mutex; - pthread_cond_t cond; - EBookStatus status; - - char *id; - GList *list; - EContact *contact; - - EBookView *view; - EBookViewListener *listener; -} EBookOp; - -typedef enum { - E_BOOK_URI_NOT_LOADED, - E_BOOK_URI_LOADING, - E_BOOK_URI_LOADED -} EBookLoadState; - -struct _EBookPrivate { - GList *book_factories; - GList *iter; - - /* cached capabilites */ - char *cap; - gboolean cap_queried; - - /* cached writable status */ - gboolean writable; - - EBookListener *listener; - EComponentListener *comp_listener; - - GNOME_Evolution_Addressbook_Book corba_book; - - EBookLoadState load_state; - - - EBookOp *current_op; - - EMutex *mutex; - - gchar *uri; - - gulong listener_signal; - gulong died_signal; -}; - - -/* Error quark */ -GQuark -e_book_error_quark (void) -{ - static GQuark q = 0; - if (q == 0) - q = g_quark_from_static_string ("e-book-error-quark"); - - return q; -} - - - -/* EBookOp calls */ - -static EBookOp* -e_book_new_op (EBook *book) -{ - EBookOp *op = g_new0 (EBookOp, 1); - - op->mutex = e_mutex_new (E_MUTEX_SIMPLE); - pthread_cond_init (&op->cond, 0); - - book->priv->current_op = op; - - return op; -} - -static EBookOp* -e_book_get_op (EBook *book) -{ - if (!book->priv->current_op) { - g_warning ("unexpected response"); - return NULL; - } - - return book->priv->current_op; -} - -static void -e_book_op_free (EBookOp *op) -{ - /* XXX more stuff here */ - pthread_cond_destroy (&op->cond); - e_mutex_destroy (op->mutex); - g_free (op); -} - -static void -e_book_op_remove (EBook *book, - EBookOp *op) -{ - if (book->priv->current_op != op) - g_warning ("cannot remove op, it's not current"); - - book->priv->current_op = NULL; -} - -static void -e_book_clear_op (EBook *book, - EBookOp *op) -{ - e_book_op_remove (book, op); - e_mutex_unlock (op->mutex); - e_book_op_free (op); -} - - - -/** - * e_book_add_card: - * @book: an #EBook - * @contact: an #EContact - * - * adds @contact to @book. - * - * Return value: a #EBookStatus value. - **/ -gboolean -e_book_add_contact (EBook *book, - EContact *contact, - GError **error) -{ - EBookOp *our_op; - EBookStatus status; - CORBA_Environment ev; - char *vcard_str; - - printf ("e_book_add_contact\n"); - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (contact && E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG); - - e_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_URI_LOADED) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED, - _("e_book_add_contact called on book before e_book_load_uri")); - return FALSE; - } - - if (book->priv->current_op != NULL) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - return FALSE; - } - - vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); - - our_op = e_book_new_op (book); - - e_mutex_lock (our_op->mutex); - - e_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - /* will eventually end up calling e_book_response_add_contact */ - GNOME_Evolution_Addressbook_Book_addContact (book->priv->corba_book, - (const GNOME_Evolution_Addressbook_VCard) vcard_str, &ev); - - g_free (vcard_str); - - if (ev._major != CORBA_NO_EXCEPTION) { - - e_book_clear_op (book, our_op); - - CORBA_exception_free (&ev); - - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("Corba exception making Book::addContact call")); - return FALSE; - } - - CORBA_exception_free (&ev); - - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_mutex_cond_wait (&our_op->cond, our_op->mutex); - - status = our_op->status; - e_contact_set (contact, E_CONTACT_UID, our_op->id); - g_free (our_op->id); - - e_book_clear_op (book, our_op); - - E_BOOK_CHECK_STATUS (status, error); -} - -static void -e_book_response_add_contact (EBook *book, - EBookStatus status, - char *id) -{ - EBookOp *op; - - printf ("e_book_response_add_contact\n"); - - op = e_book_get_op (book); - - if (op == NULL) { - g_warning ("e_book_response_add_contact: Cannot find operation "); - return; - } - - e_mutex_lock (op->mutex); - - op->status = status; - op->id = g_strdup (id); - - pthread_cond_signal (&op->cond); - - e_mutex_unlock (op->mutex); -} - - - -/** - * e_book_commit_contact: - * @book: an #EBook - * @contact: an #EContact - * - * applies the changes made to @contact to the stored version in - * @book. - * - * Return value: a #EBookStatus value. - **/ -gboolean -e_book_commit_contact (EBook *book, - EContact *contact, - GError **error) -{ - EBookOp *our_op; - EBookStatus status; - CORBA_Environment ev; - char *vcard_str; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (contact && E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG); - - e_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_URI_LOADED) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED, - _("e_book_commit_contact called on book before e_book_load_uri")); - return FALSE; - } - - if (book->priv->current_op != NULL) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - return FALSE; - } - - vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); - - our_op = e_book_new_op (book); - - e_mutex_lock (our_op->mutex); - - e_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - /* will eventually end up calling _e_book_response_generic */ - GNOME_Evolution_Addressbook_Book_modifyContact (book->priv->corba_book, - (const GNOME_Evolution_Addressbook_VCard) vcard_str, &ev); - - g_free (vcard_str); - - if (ev._major != CORBA_NO_EXCEPTION) { - - e_book_clear_op (book, our_op); - - CORBA_exception_free (&ev); - - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("Corba exception making Book::modifyContact call")); - return FALSE; - } - - CORBA_exception_free (&ev); - - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_mutex_cond_wait (&our_op->cond, our_op->mutex); - - status = our_op->status; - e_contact_set (contact, E_CONTACT_UID, our_op->id); - g_free (our_op->id); - - /* remove the op from the book's hash of operations */ - e_book_clear_op (book, our_op); - - E_BOOK_CHECK_STATUS (status, error); -} - - -/** - * e_book_get_supported_fields: - * @book: an #EBook - * @fields: a #GList - * - * queries @book for the list of fields it supports. mostly for use - * by the contact editor so it knows what fields to sensitize. - * - * Return value: a #EBookStatus value. - **/ -gboolean -e_book_get_supported_fields (EBook *book, - GList **fields, - GError **error) -{ - EBookOp *our_op; - EBookStatus status; - CORBA_Environment ev; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (fields, E_BOOK_ERROR_INVALID_ARG); - - e_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_URI_LOADED) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED, - _("e_book_get_supported_fields on book before e_book_load_uri")); - return FALSE; - } - - if (book->priv->current_op != NULL) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - } - - our_op = e_book_new_op (book); - - e_mutex_lock (our_op->mutex); - - e_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - /* will eventually end up calling - _e_book_response_get_supported_fields */ - GNOME_Evolution_Addressbook_Book_getSupportedFields(book->priv->corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - e_book_clear_op (book, our_op); - - CORBA_exception_free (&ev); - - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("Corba exception making Book::getSupportedFields call")); - return FALSE; - } - - - CORBA_exception_free (&ev); - - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_mutex_cond_wait (&our_op->cond, our_op->mutex); - - status = our_op->status; - *fields = our_op->list; - - e_book_clear_op (book, our_op); - - E_BOOK_CHECK_STATUS (status, error); -} - -static void -e_book_response_get_supported_fields (EBook *book, - EBookStatus status, - GList *fields) -{ - EBookOp *op; - - op = e_book_get_op (book); - - if (op == NULL) { - g_warning ("e_book_response_get_supported_fields: Cannot find operation "); - return; - } - - e_mutex_lock (op->mutex); - - op->status = status; - op->list = fields; - - pthread_cond_signal (&op->cond); - - e_mutex_unlock (op->mutex); -} - - -/** - * e_book_get_supported_auth_methods: - * @book: an #EBook - * @auth_methods: a #GList - * - * queries @book for the list of authentication methods it supports. - * - * Return value: a #EBookStatus value. - **/ -gboolean -e_book_get_supported_auth_methods (EBook *book, - GList **auth_methods, - GError **error) -{ - EBookOp *our_op; - EBookStatus status; - CORBA_Environment ev; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (auth_methods, E_BOOK_ERROR_INVALID_ARG); - - e_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_URI_LOADED) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED, - _("e_book_get_supported_auth_methods on book before e_book_load_uri")); - return FALSE; - } - - if (book->priv->current_op != NULL) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - return FALSE; - } - - our_op = e_book_new_op (book); - - e_mutex_lock (our_op->mutex); - - e_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - /* will eventually end up calling - e_book_response_get_supported_fields */ - GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods(book->priv->corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - e_book_clear_op (book, our_op); - - CORBA_exception_free (&ev); - - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("Corba exception making Book::getSupportedAuthMethods call")); - return FALSE; - } - - - CORBA_exception_free (&ev); - - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_mutex_cond_wait (&our_op->cond, our_op->mutex); - - status = our_op->status; - *auth_methods = our_op->list; - - e_book_clear_op (book, our_op); - - E_BOOK_CHECK_STATUS (status, error); -} - -static void -e_book_response_get_supported_auth_methods (EBook *book, - EBookStatus status, - GList *auth_methods) -{ - EBookOp *op; - - op = e_book_get_op (book); - - if (op == NULL) { - g_warning ("e_book_response_get_supported_auth_methods: Cannot find operation "); - return; - } - - e_mutex_lock (op->mutex); - - op->status = status; - op->list = auth_methods; - - pthread_cond_signal (&op->cond); - - e_mutex_unlock (op->mutex); -} - - - -/** - * e_book_authenticate_user: - * @book: an #EBook - * @user: a string - * @passwd: a string - * @auth_method: a string - * - * authenticates @user with @passwd, using the auth method - * @auth_method. @auth_method must be one of the authentication - * methods returned using e_book_get_supported_auth_methods. - * - * Return value: a #EBookStatus value. - **/ -gboolean -e_book_authenticate_user (EBook *book, - const char *user, - const char *passwd, - const char *auth_method, - GError **error) -{ - EBookOp *our_op; - EBookStatus status; - CORBA_Environment ev; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (user, E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (passwd, E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (auth_method, E_BOOK_ERROR_INVALID_ARG); - - e_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_URI_LOADED) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED, - _("e_book_authenticate_user on book before e_book_load_uri")); - return FALSE; - } - - if (book->priv->current_op != NULL) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - return FALSE; - } - - our_op = e_book_new_op (book); - - e_mutex_lock (our_op->mutex); - - e_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - /* will eventually end up calling - e_book_response_generic */ - GNOME_Evolution_Addressbook_Book_authenticateUser (book->priv->corba_book, - user, passwd, - auth_method, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - e_book_clear_op (book, our_op); - - CORBA_exception_free (&ev); - - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("Corba exception making Book::authenticateUser call")); - return FALSE; - } - - CORBA_exception_free (&ev); - - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_mutex_cond_wait (&our_op->cond, our_op->mutex); - - status = our_op->status; - - e_book_clear_op (book, our_op); - - E_BOOK_CHECK_STATUS (status, error); -} - - -/** - * e_book_get_contact: - * @book: an #EBook - * @id: a string - * @contact: an #EContact - * - * Fills in @contact with the contents of the vcard in @book - * corresponding to @id. - * - * Return value: a #EBookStatus value. - **/ -gboolean -e_book_get_contact (EBook *book, - const char *id, - EContact **contact, - GError **error) -{ - EBookOp *our_op; - EBookStatus status; - CORBA_Environment ev; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (id, E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (contact, E_BOOK_ERROR_INVALID_ARG); - - e_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_URI_LOADED) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED, - _("e_book_get_contact on book before e_book_load_uri")); - return FALSE; - } - - if (book->priv->current_op != NULL) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - return FALSE; - } - - our_op = e_book_new_op (book); - - e_mutex_lock (our_op->mutex); - - e_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - /* will eventually end up calling e_book_response_generic */ - GNOME_Evolution_Addressbook_Book_getContact (book->priv->corba_book, - (const GNOME_Evolution_Addressbook_VCard) id, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - e_book_clear_op (book, our_op); - - CORBA_exception_free (&ev); - - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("Corba exception making Book::getContact call")); - return FALSE; - } - - CORBA_exception_free (&ev); - - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_mutex_cond_wait (&our_op->cond, our_op->mutex); - - status = our_op->status; - *contact = our_op->contact; - - e_book_clear_op (book, our_op); - - E_BOOK_CHECK_STATUS (status, error); -} - -static void -e_book_response_get_contact (EBook *book, - EBookStatus status, - EContact *contact) -{ - EBookOp *op; - - printf ("e_book_response_get_contact\n"); - - op = e_book_get_op (book); - - if (op == NULL) { - g_warning ("e_book_response_get_contact: Cannot find operation "); - return; - } - - e_mutex_lock (op->mutex); - - op->status = status; - op->contact = contact; - - pthread_cond_signal (&op->cond); - - e_mutex_unlock (op->mutex); -} - - -/** - * e_book_remove_contact: - * @book: an #EBook - * @id: a string - * - * Removes the contact with id @id from @book. - * - * Return value: a #EBookStatus value. - **/ -gboolean -e_book_remove_contact (EBook *book, - const char *id, - GError **error) -{ - GList *list; - gboolean rv; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (id, E_BOOK_ERROR_INVALID_ARG); - - e_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_URI_LOADED) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED, - _("e_book_remove_contact on book before e_book_load_uri")); - return FALSE; - } - - if (book->priv->current_op != NULL) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - return FALSE; - } - - e_mutex_lock (book->priv->mutex); - - list = g_list_append (NULL, (char*)id); - - rv = e_book_remove_contacts (book, list, error); - - return rv; -} - -/** - * e_book_remove_contacts: - * @book: an #EBook - * @ids: an #GList of const char *id's - * - * Removes the contacts with ids from the list @ids from @book. This is - * always more efficient than calling e_book_remove_contact_by_id if you - * have more than one id to remove, as some backends can implement it - * as a batch request. - * - * Return value: a #EBookStatus value. - **/ -gboolean -e_book_remove_contacts (EBook *book, - GList *ids, - GError **error) -{ - GNOME_Evolution_Addressbook_ContactIdList idlist; - CORBA_Environment ev; - GList *iter; - int num_ids, i; - EBookOp *our_op; - EBookStatus status; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (ids, E_BOOK_ERROR_INVALID_ARG); - - e_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_URI_LOADED) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED, - _("e_book_remove_contacts on book before e_book_load_uri")); - return FALSE; - } - - if (book->priv->current_op != NULL) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - return FALSE; - } - - our_op = e_book_new_op (book); - - e_mutex_lock (our_op->mutex); - - e_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - num_ids = g_list_length (ids); - idlist._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_ContactId_allocbuf (num_ids); - idlist._maximum = num_ids; - idlist._length = num_ids; - - for (iter = ids, i = 0; iter; iter = iter->next) - idlist._buffer[i++] = CORBA_string_dup (iter->data); - - /* will eventually end up calling e_book_response_generic */ - GNOME_Evolution_Addressbook_Book_removeContacts (book->priv->corba_book, &idlist, &ev); - - CORBA_free(idlist._buffer); - - if (ev._major != CORBA_NO_EXCEPTION) { - - e_book_clear_op (book, our_op); - - CORBA_exception_free (&ev); - - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("Corba exception making Book::removeContacts call")); - return FALSE; - } - - CORBA_exception_free (&ev); - - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_mutex_cond_wait (&our_op->cond, our_op->mutex); - - status = our_op->status; - - e_book_clear_op (book, our_op); - - E_BOOK_CHECK_STATUS (status, error); -} - - -/** - * e_book_get_book_view: - * @book: an #EBook - * @query: an #EBookQuery - * @requested_fields a #GList containing the names of fields to return, or NULL for all - * @max_results the maximum number of contacts to show (or 0 for all) - * - * need docs here.. - * - * Return value: a #EBookStatus value. - **/ -gboolean -e_book_get_book_view (EBook *book, - EBookQuery *query, - GList *requested_fields, - int max_results, - EBookView **book_view, - GError **error) -{ - GNOME_Evolution_Addressbook_stringlist stringlist; - CORBA_Environment ev; - EBookOp *our_op; - EBookStatus status; - int num_fields, i; - GList *iter; - char *query_string; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (query, E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (book_view, E_BOOK_ERROR_INVALID_ARG); - - e_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_URI_LOADED) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED, - _("e_book_get_book_view on book before e_book_load_uri")); - return FALSE; - } - - if (book->priv->current_op != NULL) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - return FALSE; - } - - our_op = e_book_new_op (book); - - e_mutex_lock (our_op->mutex); - - e_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - our_op->listener = e_book_view_listener_new(); - - num_fields = g_list_length (requested_fields); - - stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_fields); - stringlist._maximum = num_fields; - stringlist._length = num_fields; - - for (i = 0, iter = requested_fields; iter; iter = iter->next, i ++) { - stringlist._buffer[i] = CORBA_string_dup ((char*)iter->data); - } - - query_string = e_book_query_to_string (query); - - /* will eventually end up calling e_book_response_get_book_view */ - GNOME_Evolution_Addressbook_Book_getBookView (book->priv->corba_book, - bonobo_object_corba_objref(BONOBO_OBJECT(our_op->listener)), - query_string, - &stringlist, max_results, &ev); - - CORBA_free(stringlist._buffer); - g_free (query_string); - - if (ev._major != CORBA_NO_EXCEPTION) { - - e_book_clear_op (book, our_op); - - CORBA_exception_free (&ev); - - g_warning ("corba exception._major = %d\n", ev._major); - - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("Corba exception making Book::getBookView call")); - return FALSE; - } - - CORBA_exception_free (&ev); - - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_mutex_cond_wait (&our_op->cond, our_op->mutex); - - status = our_op->status; - *book_view = our_op->view; - - e_book_clear_op (book, our_op); - - E_BOOK_CHECK_STATUS (status, error); -} - -static void -e_book_response_get_book_view (EBook *book, - EBookStatus status, - GNOME_Evolution_Addressbook_BookView corba_book_view) -{ - - EBookOp *op; - - printf ("e_book_response_get_book_view\n"); - - op = e_book_get_op (book); - - if (op == NULL) { - g_warning ("e_book_response_get_book_view: Cannot find operation "); - return; - } - - e_mutex_lock (op->mutex); - - op->status = status; - op->view = e_book_view_new (corba_book_view, op->listener); - - bonobo_object_ref(BONOBO_OBJECT(op->listener)); - - pthread_cond_signal (&op->cond); - - e_mutex_unlock (op->mutex); -} - - - -/** - * e_book_get_contacts: - * @book: an #EBook - * @query: an #EBookQuery - * - * need docs here.. - * - * Return value: a #EBookStatus value. - **/ -gboolean -e_book_get_contacts (EBook *book, - EBookQuery *query, - GList **contacts, - GError **error) -{ - CORBA_Environment ev; - EBookOp *our_op; - EBookStatus status; - char *query_string; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (query, E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (contacts, E_BOOK_ERROR_INVALID_ARG); - - e_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_URI_LOADED) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED, - _("e_book_get_contacts on book before e_book_load_uri")); - return FALSE; - } - - if (book->priv->current_op != NULL) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - return FALSE; - } - - our_op = e_book_new_op (book); - - e_mutex_lock (our_op->mutex); - - e_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - query_string = e_book_query_to_string (query); - - /* will eventually end up calling e_book_response_get_contacts */ - GNOME_Evolution_Addressbook_Book_getContactList (book->priv->corba_book, query_string, &ev); - - g_free (query_string); - - if (ev._major != CORBA_NO_EXCEPTION) { - - e_book_clear_op (book, our_op); - - CORBA_exception_free (&ev); - - g_warning ("corba exception._major = %d\n", ev._major); - - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("Corba exception making Book::getContactList call")); - return FALSE; - } - - CORBA_exception_free (&ev); - - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_mutex_cond_wait (&our_op->cond, our_op->mutex); - - status = our_op->status; - *contacts = our_op->list; - - e_book_clear_op (book, our_op); - - E_BOOK_CHECK_STATUS (status, error); -} - -static void -e_book_response_get_contacts (EBook *book, - EBookStatus status, - GList *contact_list) -{ - - EBookOp *op; - - op = e_book_get_op (book); - - if (op == NULL) { - g_warning ("e_book_response_get_contacts: Cannot find operation "); - return; - } - - e_mutex_lock (op->mutex); - - op->status = status; - op->list = contact_list; - - pthread_cond_signal (&op->cond); - - e_mutex_unlock (op->mutex); -} - - -gboolean -e_book_get_changes (EBook *book, - char *changeid, - GList **changes, - GError **error) -{ - CORBA_Environment ev; - EBookOp *our_op; - EBookStatus status; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (changeid, E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (changes, E_BOOK_ERROR_INVALID_ARG); - - e_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_URI_LOADED) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED, - _("e_book_get_changes on book before e_book_load_uri")); - return FALSE; - } - - if (book->priv->current_op != NULL) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - return FALSE; - } - - our_op = e_book_new_op (book); - - e_mutex_lock (our_op->mutex); - - e_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - /* will eventually end up calling e_book_response_get_changes */ - GNOME_Evolution_Addressbook_Book_getChanges (book->priv->corba_book, changeid, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - e_book_clear_op (book, our_op); - - CORBA_exception_free (&ev); - - g_warning ("corba exception._major = %d\n", ev._major); - - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("Corba exception making Book::getChanges call")); - return FALSE; - } - - CORBA_exception_free (&ev); - - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_mutex_cond_wait (&our_op->cond, our_op->mutex); - - status = our_op->status; - *changes = our_op->list; - - e_book_clear_op (book, our_op); - - E_BOOK_CHECK_STATUS (status, error); -} - -static void -e_book_response_get_changes (EBook *book, - EBookStatus status, - GList *change_list) -{ - - EBookOp *op; - - op = e_book_get_op (book); - - if (op == NULL) { - g_warning ("e_book_response_get_contacts: Cannot find operation "); - return; - } - - e_mutex_lock (op->mutex); - - op->status = status; - op->list = change_list; - - pthread_cond_signal (&op->cond); - - e_mutex_unlock (op->mutex); -} - -void -e_book_free_change_list (GList *change_list) -{ - GList *l; - for (l = change_list; l; l = l->next) { - EBookChange *change = l->data; - - g_object_unref (change->contact); - g_free (change); - } - - g_list_free (change_list); -} - - - -static void -e_book_response_generic (EBook *book, - EBookStatus status) -{ - EBookOp *op; - - op = e_book_get_op (book); - - if (op == NULL) { - g_warning ("e_book_response_generic: Cannot find operation "); - return; - } - - e_mutex_lock (op->mutex); - - op->status = status; - - pthread_cond_signal (&op->cond); - - e_mutex_unlock (op->mutex); -} - -/** - * e_book_cancel: - * @book: an #EBook - * - * Used to cancel an already running operation on @book. This - * function makes a synchronous CORBA to the backend telling it to - * cancel the operation. If the operation wasn't cancellable (either - * transiently or permanently) or had already comopleted on the wombat - * side, this function will return E_BOOK_STATUS_COULD_NOT_CANCEL, and - * the operation will continue uncancelled. If the operation could be - * cancelled, this function will return E_BOOK_ERROR_OK, and the - * blocked e_book function corresponding to current operation will - * return with a status of E_BOOK_STATUS_CANCELLED. - * - * Return value: a #EBookStatus value. - **/ -gboolean -e_book_cancel (EBook *book, - GError **error) -{ - EBookOp *op; - EBookStatus status; - gboolean rv; - CORBA_Environment ev; - - e_mutex_lock (book->priv->mutex); - - if (book->priv->current_op == NULL) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_COULD_NOT_CANCEL, - _("e_book_cancel: there is no current operation")); - return FALSE; - } - - op = book->priv->current_op; - - e_mutex_lock (op->mutex); - - e_mutex_unlock (book->priv->mutex); - - status = GNOME_Evolution_Addressbook_Book_cancelOperation(book->priv->corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - e_mutex_unlock (op->mutex); - - CORBA_exception_free (&ev); - - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("Corba exception making Book::cancelOperation call")); - return FALSE; - } - - CORBA_exception_free (&ev); - - if (status == E_BOOK_ERROR_OK) { - op->status = E_BOOK_ERROR_CANCELLED; - - pthread_cond_signal (&op->cond); - - rv = TRUE; - } - else { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_COULD_NOT_CANCEL, - _("e_book_cancel: couldn't cancel")); - rv = FALSE; - } - - e_mutex_unlock (op->mutex); - - return rv; -} - -static void -e_book_response_open (EBook *book, - EBookStatus status) -{ - EBookOp *op; - - op = e_book_get_op (book); - - if (op == NULL) { - g_warning ("e_book_response_open: Cannot find operation "); - return; - } - - e_mutex_lock (op->mutex); - - op->status = status; - - pthread_cond_signal (&op->cond); - - e_mutex_unlock (op->mutex); -} - - - -gboolean -e_book_remove (EBook *book, - GError **error) -{ - CORBA_Environment ev; - EBookOp *our_op; - EBookStatus status; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - - e_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_URI_LOADED) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_URI_NOT_LOADED, - _("e_book_remove on book before e_book_load_uri")); - return FALSE; - } - - if (book->priv->current_op != NULL) { - e_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - return FALSE; - } - - our_op = e_book_new_op (book); - - e_mutex_lock (our_op->mutex); - - e_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - /* will eventually end up calling e_book_response_remove */ - GNOME_Evolution_Addressbook_Book_remove (book->priv->corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - e_book_clear_op (book, our_op); - - CORBA_exception_free (&ev); - - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("Corba exception making Book::remove call")); - return FALSE; - } - - CORBA_exception_free (&ev); - - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_mutex_cond_wait (&our_op->cond, our_op->mutex); - - status = our_op->status; - - e_book_clear_op (book, our_op); - - E_BOOK_CHECK_STATUS (status, error); -} - -static void -e_book_response_remove (EBook *book, - EBookStatus status) -{ - EBookOp *op; - - printf ("e_book_response_remove\n"); - - op = e_book_get_op (book); - - if (op == NULL) { - g_warning ("e_book_response_remove: Cannot find operation "); - return; - } - - e_mutex_lock (op->mutex); - - op->status = status; - - pthread_cond_signal (&op->cond); - - e_mutex_unlock (op->mutex); -} - - - -static void -e_book_handle_response (EBookListener *listener, EBookListenerResponse *resp, EBook *book) -{ - switch (resp->op) { - case CreateContactResponse: - e_book_response_add_contact (book, resp->status, resp->id); - break; - case RemoveContactResponse: - case ModifyContactResponse: - case AuthenticationResponse: - e_book_response_generic (book, resp->status); - break; - case GetContactResponse: { - EContact *contact = e_contact_new_from_vcard (resp->vcard); - e_book_response_get_contact (book, resp->status, contact); - break; - } - case GetContactListResponse: - e_book_response_get_contacts (book, resp->status, resp->list); - break; - case GetBookViewResponse: - e_book_response_get_book_view(book, resp->status, resp->book_view); - break; - case GetChangesResponse: - e_book_response_get_changes(book, resp->status, resp->list); - break; - case OpenBookResponse: - e_book_response_open (book, resp->status); - break; - case RemoveBookResponse: - e_book_response_remove (book, resp->status); - break; - case GetSupportedFieldsResponse: - e_book_response_get_supported_fields (book, resp->status, resp->list); - break; - case GetSupportedAuthMethodsResponse: - e_book_response_get_supported_auth_methods (book, resp->status, resp->list); - break; - case WritableStatusEvent: - book->priv->writable = resp->writable; - g_signal_emit (book, e_book_signals [WRITABLE_STATUS], 0, resp->writable); - break; - default: - g_error ("EBook: Unknown response code %d!\n", - resp->op); - } -} - - - -gboolean -e_book_unload_uri (EBook *book, - GError **error) -{ - CORBA_Environment ev; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (book->priv->load_state != E_BOOK_URI_NOT_LOADED, E_BOOK_ERROR_URI_NOT_LOADED); - - /* Release the remote GNOME_Evolution_Addressbook_Book in the PAS. */ - CORBA_exception_init (&ev); - - bonobo_object_release_unref (book->priv->corba_book, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_unload_uri: Exception releasing " - "remote book interface!\n"); - } - - CORBA_exception_free (&ev); - - e_book_listener_stop (book->priv->listener); - bonobo_object_unref (BONOBO_OBJECT (book->priv->listener)); - - book->priv->listener = NULL; - book->priv->load_state = E_BOOK_URI_NOT_LOADED; - g_free (book->priv->cap); - book->priv->cap = NULL; - book->priv->writable = FALSE; - - return TRUE; -} - - - -/** - * e_book_load_uri: - */ - -static void -backend_died_cb (EComponentListener *cl, gpointer user_data) -{ - EBook *book = user_data; - - book->priv->load_state = E_BOOK_URI_NOT_LOADED; - g_signal_emit (book, e_book_signals [BACKEND_DIED], 0); -} - -static GList * -activate_factories_for_uri (EBook *book, const char *uri) -{ - CORBA_Environment ev; - Bonobo_ServerInfoList *info_list = NULL; - int i; - char *protocol, *query, *colon; - GList *factories = NULL; - - colon = strchr (uri, ':'); - if (!colon) { - g_warning ("e_book_load_uri: Unable to determine protocol in the URI\n"); - return FALSE; - } - - protocol = g_strndup (uri, colon-uri); - query = g_strdup_printf ("repo_ids.has ('IDL:GNOME/Evolution/BookFactory:1.0')" - " AND addressbook:supported_protocols.has ('%s')", protocol - ); - - CORBA_exception_init (&ev); - - info_list = bonobo_activation_query (query, NULL, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Eeek! Cannot perform bonobo-activation query for book factories."); - CORBA_exception_free (&ev); - goto done; - return NULL; - } - - if (info_list->_length == 0) { - g_warning ("Can't find installed BookFactory that handles protocol '%s'.", protocol); - CORBA_exception_free (&ev); - goto done; - } - - CORBA_exception_free (&ev); - - for (i = 0; i < info_list->_length; i ++) { - const Bonobo_ServerInfo *info; - GNOME_Evolution_Addressbook_BookFactory factory; - - info = info_list->_buffer + i; - - factory = bonobo_activation_activate_from_id (info->iid, 0, NULL, NULL); - - if (factory == CORBA_OBJECT_NIL) - g_warning ("e_book_construct: Could not obtain a handle " - "to the Personal Addressbook Server with IID `%s'\n", info->iid); - else - factories = g_list_append (factories, factory); - } - - done: - if (info_list) - CORBA_free (info_list); - g_free (query); - g_free (protocol); - - return factories; -} - -gboolean -e_book_load_uri (EBook *book, - const char *uri, - gboolean only_if_exists, - GError **error) -{ - GList *factories; - GList *l; - gboolean rv = FALSE; - GNOME_Evolution_Addressbook_Book corba_book = CORBA_OBJECT_NIL; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); - e_return_error_if_fail (uri, E_BOOK_ERROR_INVALID_ARG); - - /* XXX this needs to happen while holding the book's lock i would think... */ - e_return_error_if_fail (book->priv->load_state == E_BOOK_URI_NOT_LOADED, E_BOOK_ERROR_URI_ALREADY_LOADED); - - /* try to find a list of factories that can handle the protocol */ - if (! (factories = activate_factories_for_uri (book, uri))) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_PROTOCOL_NOT_SUPPORTED, - _("e_book_load_uri: no factories available for uri `%s'"), uri); - return FALSE; - } - - - book->priv->load_state = E_BOOK_URI_LOADING; - - /* - * Create our local BookListener interface. - */ - book->priv->listener = e_book_listener_new (); - if (book->priv->listener == NULL) { - g_warning ("e_book_load_uri: Could not create EBookListener!\n"); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_OTHER_ERROR, - _("e_book_load_uri: Could not create EBookListener")); - return FALSE; - } - book->priv->listener_signal = g_signal_connect (book->priv->listener, "response", - G_CALLBACK (e_book_handle_response), book); - - g_free (book->priv->uri); - book->priv->uri = g_strdup (uri); - - for (l = factories; l; l = l->next) { - GNOME_Evolution_Addressbook_BookFactory factory = l->data; - EBookOp *our_op; - CORBA_Environment ev; - EBookStatus status; - - our_op = e_book_new_op (book); - - e_mutex_lock (our_op->mutex); - - CORBA_exception_init (&ev); - - corba_book = GNOME_Evolution_Addressbook_BookFactory_getBook (factory, book->priv->uri, - bonobo_object_corba_objref (BONOBO_OBJECT (book->priv->listener)), - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - e_book_clear_op (book, our_op); - - CORBA_exception_free (&ev); - continue; - } - - GNOME_Evolution_Addressbook_Book_open (corba_book, - only_if_exists, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - /* kill the listener so the book will die */ - g_signal_handler_disconnect (book->priv->listener, book->priv->listener_signal); - bonobo_object_unref (book->priv->listener); - book->priv->listener = NULL; - - e_book_clear_op (book, our_op); - - CORBA_exception_free (&ev); - continue; - } - - CORBA_exception_free (&ev); - - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_mutex_cond_wait (&our_op->cond, our_op->mutex); - - status = our_op->status; - - /* remove the op from the book's hash of operations */ - e_book_clear_op (book, our_op); - - if (status == E_BOOK_ERROR_CANCELLED - || status == E_BOOK_ERROR_OK) { - rv = TRUE; - break; - } - } - - /* free up the factories */ - for (l = factories; l; l = l->next) - CORBA_Object_release ((CORBA_Object)l->data, NULL); - - if (rv == TRUE) { - book->priv->corba_book = corba_book; - book->priv->load_state = E_BOOK_URI_LOADED; - book->priv->comp_listener = e_component_listener_new (book->priv->corba_book); - book->priv->died_signal = g_signal_connect (book->priv->comp_listener, "component_died", - G_CALLBACK (backend_died_cb), book); - return TRUE; - } - else { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_PROTOCOL_NOT_SUPPORTED, - _("e_book_load_uri: no factories available for uri `%s'"), uri); - return FALSE; - } - - return rv; -} - -gboolean -e_book_load_local_addressbook (EBook *book, - GError **error) -{ - char *filename; - char *uri; - gboolean rv; - - filename = g_build_filename (g_get_home_dir(), - "evolution/local/Contacts", - NULL); - uri = g_strdup_printf ("file://%s", filename); - - g_free (filename); - - rv = e_book_load_uri (book, uri, TRUE, error); - - g_free (uri); - - return rv; -} - -const char * -e_book_get_uri (EBook *book) -{ - return book->priv->uri; -} - -const char * -e_book_get_static_capabilities (EBook *book, - GError **error) -{ - if (!book->priv->cap_queried) { - CORBA_Environment ev; - char *temp; - - CORBA_exception_init (&ev); - - if (book->priv->load_state != E_BOOK_URI_LOADED) { - g_warning ("e_book_unload_uri: No URI is loaded!\n"); - return g_strdup(""); - } - - temp = GNOME_Evolution_Addressbook_Book_getStaticCapabilities(book->priv->corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_get_static_capabilities: Exception " - "during get_static_capabilities!\n"); - CORBA_exception_free (&ev); - return g_strdup(""); - } - - book->priv->cap = g_strdup(temp); - book->priv->cap_queried = TRUE; - - CORBA_free(temp); - - CORBA_exception_free (&ev); - } - - return book->priv->cap; -} - -gboolean -e_book_check_static_capability (EBook *book, - const char *cap) -{ - const char *caps = e_book_get_static_capabilities (book, NULL); - - /* XXX this is an inexact test but it works for our use */ - if (caps && strstr (caps, cap)) - return TRUE; - - return FALSE; -} - -gboolean -e_book_is_writable (EBook *book) -{ - return book->priv->writable; -} - - - - -gboolean -e_book_get_self (EContact **contact, EBook **book, GError **error) -{ - GError *e = NULL; - - if (!e_book_get_default_addressbook (book, &e)) { - g_propagate_error (error, e); - return FALSE; - } - -#if notyet - EBook *b; - char *self_uri, *self_uid; - - /* XXX get the setting for the self book and self uid from gconf */ - - b = e_book_new(); - if (! e_book_load_uri (b, self_uri, TRUE, error)) { - g_object_unref (b); - return FALSE; - } - - if (! e_book_get_contact (b, self_uid, - contact, error)) { - g_object_unref (b); - return FALSE; - } - - if (book) - *book = b; - else - g_object_unref (b); - return TRUE; -#endif -} - -gboolean -e_book_set_self (EBook *book, const char *id, GError **error) -{ -} - - - -gboolean -e_book_get_default_addressbook (EBook **book, GError **error) -{ - /* XXX for now just load the local ~/evolution/local/Contacts */ - char *path, *uri; - gboolean rv; - - *book = e_book_new (); - - path = g_build_filename (g_get_home_dir (), - "evolution/local/Contacts", - NULL); - uri = g_strdup_printf ("file://%s", path); - g_free (path); - - rv = e_book_load_uri (*book, uri, FALSE, error); - - g_free (uri); - - if (!rv) { - g_object_unref (*book); - *book = NULL; - } - - return rv; -#if notyet - EConfigListener *listener = e_config_listener_new (); - ESourceList *sources = ...; - ESource *default_source; - - default_source = e_source_list_peek_source_by_uid (sources, - "default_"); -#endif -} - -#if notyet -ESourceList* -e_book_get_addressbooks (GError **error) -{ -} -#endif - - -static void* -startup_mainloop (void *arg) -{ - bonobo_main(); - return NULL; -} - -/* one-time start up for libebook */ -static void -e_book_activate() -{ - static GStaticMutex e_book_lock = G_STATIC_MUTEX_INIT; - static gboolean activated = FALSE; - - g_static_mutex_lock (&e_book_lock); - if (!activated) { - pthread_t ebook_mainloop_thread; - activated = TRUE; - pthread_create(&ebook_mainloop_thread, NULL, startup_mainloop, NULL); - } - g_static_mutex_unlock (&e_book_lock); -} - - - -EBook* -e_book_new (void) -{ - e_book_activate (); - return g_object_new (E_TYPE_BOOK, NULL); -} - - -static void -e_book_init (EBook *book) -{ - book->priv = g_new0 (EBookPrivate, 1); - book->priv->load_state = E_BOOK_URI_NOT_LOADED; - book->priv->uri = NULL; - book->priv->mutex = e_mutex_new (E_MUTEX_REC); -} - -static void -e_book_dispose (GObject *object) -{ - EBook *book = E_BOOK (object); - - if (book->priv) { - CORBA_Environment ev; - GList *l; - - if (book->priv->comp_listener) { - g_signal_handler_disconnect (book->priv->comp_listener, book->priv->died_signal); - g_object_unref (book->priv->comp_listener); - book->priv->comp_listener = NULL; - } - - if (book->priv->load_state == E_BOOK_URI_LOADED) - e_book_unload_uri (book, NULL); - - CORBA_exception_init (&ev); - - for (l = book->priv->book_factories; l; l = l->next) { - CORBA_Object_release ((CORBA_Object)l->data, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("EBook: Exception while releasing BookFactory\n"); - - CORBA_exception_free (&ev); - CORBA_exception_init (&ev); - } - } - - CORBA_exception_free (&ev); - - if (book->priv->listener) { - g_signal_handler_disconnect (book->priv->listener, book->priv->listener_signal); - bonobo_object_unref (book->priv->listener); - book->priv->listener = NULL; - } - - g_free (book->priv->cap); - - g_free (book->priv->uri); - - g_free (book->priv); - book->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -e_book_class_init (EBookClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - e_book_signals [WRITABLE_STATUS] = - g_signal_new ("writable_status", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookClass, writable_status), - NULL, NULL, - e_book_marshal_NONE__BOOL, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); - - e_book_signals [BACKEND_DIED] = - g_signal_new ("backend_died", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookClass, backend_died), - NULL, NULL, - e_book_marshal_NONE__NONE, - G_TYPE_NONE, 0); - - object_class->dispose = e_book_dispose; -} - -/** - * e_book_get_type: - */ -GType -e_book_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (EBookClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) e_book_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EBook), - 0, /* n_preallocs */ - (GInstanceInitFunc) e_book_init - }; - - type = g_type_register_static (G_TYPE_OBJECT, "EBook", &info, 0); - } - - return type; -} |