diff options
author | Ross Burton <ross@linux.intel.com> | 2009-06-15 08:36:35 +0100 |
---|---|---|
committer | Ross Burton <ross@linux.intel.com> | 2009-08-17 13:01:35 +0100 |
commit | 84a1355a10557a912676d92a53167a070cb5dabc (patch) | |
tree | 80db795dfb5be60326b040d46fcdd7370d26275c | |
parent | 754ba318d162cefeecda294d33c4575037e20bea (diff) | |
download | evolution-data-server-84a1355a10557a912676d92a53167a070cb5dabc.tar.gz |
Port libebook to DBus
-rw-r--r-- | addressbook/libebook/Makefile.am | 41 | ||||
-rw-r--r-- | addressbook/libebook/e-book-listener.c | 494 | ||||
-rw-r--r-- | addressbook/libebook/e-book-listener.h | 119 | ||||
-rw-r--r-- | addressbook/libebook/e-book-marshal.list | 5 | ||||
-rw-r--r-- | addressbook/libebook/e-book-view-listener.c | 405 | ||||
-rw-r--r-- | addressbook/libebook/e-book-view-listener.h | 92 | ||||
-rw-r--r-- | addressbook/libebook/e-book-view-private.h | 30 | ||||
-rw-r--r-- | addressbook/libebook/e-book-view.c | 454 | ||||
-rw-r--r-- | addressbook/libebook/e-book.c | 3838 | ||||
-rw-r--r-- | addressbook/libebook/e-error.h | 40 | ||||
-rw-r--r-- | addressbook/libebook/libebook.pc.in | 5 |
11 files changed, 1268 insertions, 4255 deletions
diff --git a/addressbook/libebook/Makefile.am b/addressbook/libebook/Makefile.am index 96223381c..54f08b494 100644 --- a/addressbook/libebook/Makefile.am +++ b/addressbook/libebook/Makefile.am @@ -8,37 +8,18 @@ AM_CPPFLAGS = \ -I$(top_builddir)/addressbook/libebook \ $(EVOLUTION_ADDRESSBOOK_CFLAGS) -# The corba stubs and skels -CORBA_GENERATED_C = \ - Evolution-DataServer-Addressbook-common.c \ - Evolution-DataServer-Addressbook-skels.c \ - Evolution-DataServer-Addressbook-stubs.c -CORBA_GENERATED_H = \ - Evolution-DataServer-Addressbook.h - -CORBA_GENERATED = $(CORBA_GENERATED_C) $(CORBA_GENERATED_H) - -idls = \ - $(srcdir)/../idl/Evolution-DataServer-Addressbook.idl - -idl_flags = $(IDL_INCLUDES) - -$(CORBA_GENERATED_H): $(idls) - $(ORBIT_IDL) $(idl_flags) $(srcdir)/../idl/Evolution-DataServer-Addressbook.idl -$(CORBA_GENERATED_C): $(CORBA_GENERATED_H) +# The marshallers +MARSHAL_GENERATED = e-book-marshal.c e-book-marshal.h +@EVO_MARSHAL_RULE@ # The library lib_LTLIBRARIES = libebook-1.2.la -libebook_1_2_la_SOURCES = \ - $(CORBA_GENERATED_C) \ - $(CORBA_GENERATED_H) \ +libebook_1_2_la_SOURCES = \ + $(MARSHAL_GENERATED) \ + $(DBUS_GENERATED_H) \ e-address-western.c \ - e-book-listener.c \ - e-book-listener.h \ e-book-query.c \ - e-book-view-listener.c \ - e-book-view-listener.h \ e-book-view-private.h \ e-book-view.c \ e-book.c \ @@ -46,7 +27,8 @@ libebook_1_2_la_SOURCES = \ e-destination.c \ e-name-western.c \ e-name-western-tables.h \ - e-vcard.c + e-vcard.c \ + e-error.h libebook_1_2_la_LIBADD = \ $(top_builddir)/camel/libcamel-1.2.la \ @@ -78,11 +60,16 @@ e-name-western-tables.h: e-name-western-tables.h.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libebook-$(API_VERSION).pc -BUILT_SOURCES = $(CORBA_GENERATED) +DBUS_GENERATED_H = e-data-book-factory-bindings.h e-data-book-bindings.h e-data-book-view-bindings.h +%-bindings.h: $(top_srcdir)/addressbook/libedata-book/%.xml + dbus-binding-tool --mode=glib-client --output=$@ --prefix=$(subst -,_,$*) $^ + +BUILT_SOURCES = $(DBUS_GENERATED_H) $(MARSHAL_GENERATED) CLEANFILES = $(BUILT_SOURCES) DISTCLEANFILES = $(pkgconfig_DATA) EXTRA_DIST = \ + e-book-marshal.list \ $(pkgconfig_DATA:-$(API_VERSION).pc=.pc.in) \ e-name-western-tables.h.in \ gen-western-table.py diff --git a/addressbook/libebook/e-book-listener.c b/addressbook/libebook/e-book-listener.c deleted file mode 100644 index 3e45a02a3..000000000 --- a/addressbook/libebook/e-book-listener.c +++ /dev/null @@ -1,494 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Exports the BookListener interface. Maintains a queue of messages - * which come in on the interface. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - */ - -#include <config.h> -#include <bonobo/bonobo-main.h> -#include "e-contact.h" -#include "e-book-listener.h" - -#define d(x) - -extern GMainContext *_ebook_context; - -static EBookStatus e_book_listener_convert_status (GNOME_Evolution_Addressbook_CallStatus status); - -enum { - RESPONSE, - LAST_SIGNAL -}; - -static guint e_book_listener_signals [LAST_SIGNAL]; - -static BonoboObjectClass *parent_class; - -struct _EBookListenerPrivate { - guint stopped : 1; -}; - -static EBookStatus -e_book_listener_convert_status (const GNOME_Evolution_Addressbook_CallStatus status) -{ - switch (status) { - case GNOME_Evolution_Addressbook_Success: - return E_BOOK_ERROR_OK; - case GNOME_Evolution_Addressbook_RepositoryOffline: - return E_BOOK_ERROR_REPOSITORY_OFFLINE; - case GNOME_Evolution_Addressbook_PermissionDenied: - return E_BOOK_ERROR_PERMISSION_DENIED; - case GNOME_Evolution_Addressbook_ContactNotFound: - return E_BOOK_ERROR_CONTACT_NOT_FOUND; - case GNOME_Evolution_Addressbook_ContactIdAlreadyExists: - return E_BOOK_ERROR_CONTACT_ID_ALREADY_EXISTS; - case GNOME_Evolution_Addressbook_AuthenticationFailed: - return E_BOOK_ERROR_AUTHENTICATION_FAILED; - case GNOME_Evolution_Addressbook_AuthenticationRequired: - return E_BOOK_ERROR_AUTHENTICATION_REQUIRED; - case GNOME_Evolution_Addressbook_UnsupportedAuthenticationMethod: - return E_BOOK_ERROR_UNSUPPORTED_AUTHENTICATION_METHOD; - case GNOME_Evolution_Addressbook_TLSNotAvailable: - return E_BOOK_ERROR_TLS_NOT_AVAILABLE; - case GNOME_Evolution_Addressbook_NoSuchBook: - return E_BOOK_ERROR_NO_SUCH_BOOK; - case GNOME_Evolution_Addressbook_OfflineUnavailable: - return E_BOOK_ERROR_OFFLINE_UNAVAILABLE; - case GNOME_Evolution_Addressbook_InvalidServerVersion: - return E_BOOK_ERROR_INVALID_SERVER_VERSION; - - case GNOME_Evolution_Addressbook_OtherError: - default: - return E_BOOK_ERROR_OTHER_ERROR; - } -} - -static void -impl_BookListener_respond_create_contact (PortableServer_Servant servant, - const CORBA_long opid, - const GNOME_Evolution_Addressbook_CallStatus status, - const CORBA_char * id, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - - response.op = CreateContactResponse; - response.opid = opid; - response.status = e_book_listener_convert_status (status); - response.id = g_strdup (id); - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); - - g_free (response.id); -} - -static void -impl_BookListener_respond_remove_contacts (PortableServer_Servant servant, - const CORBA_long opid, - const GNOME_Evolution_Addressbook_CallStatus status, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - - response.op = RemoveContactResponse; - response.opid = opid; - response.status = e_book_listener_convert_status (status); - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); -} - -static void -impl_BookListener_respond_modify_contact (PortableServer_Servant servant, - const CORBA_long opid, - const GNOME_Evolution_Addressbook_CallStatus status, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - - response.op = ModifyContactResponse; - response.opid = opid; - response.status = e_book_listener_convert_status (status); - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); -} - -static void -impl_BookListener_respond_get_contact (PortableServer_Servant servant, - const CORBA_long opid, - const GNOME_Evolution_Addressbook_CallStatus status, - const CORBA_char * card, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - - response.op = GetContactResponse; - response.opid = opid; - response.status = e_book_listener_convert_status (status); - response.vcard = g_strdup (card); - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); - - g_free (response.vcard); -} - -static void -impl_BookListener_respond_get_contact_list (PortableServer_Servant servant, - const CORBA_long opid, - const GNOME_Evolution_Addressbook_CallStatus status, - const GNOME_Evolution_Addressbook_stringlist *cards, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - gint i; - - if (listener->priv->stopped) - return; - - response.op = GetContactListResponse; - response.opid = opid; - response.status = e_book_listener_convert_status (status); - response.list = NULL; - - for (i = 0; i < cards->_length; i ++) { - response.list = g_list_prepend (response.list, e_contact_new_from_vcard (cards->_buffer[i])); - } - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); - - g_list_foreach (response.list, (GFunc)g_object_unref, NULL); - g_list_free (response.list); -} - -static void -impl_BookListener_respond_get_view (PortableServer_Servant servant, - const CORBA_long opid, - const GNOME_Evolution_Addressbook_CallStatus status, - const GNOME_Evolution_Addressbook_BookView book_view, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - - d(printf ("impl_BookListener_respond_get_view\n")); - - if (listener->priv->stopped) - return; - - response.op = GetBookViewResponse; - response.opid = opid; - response.status = e_book_listener_convert_status (status); - response.book_view = book_view; - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); -} - -static void -impl_BookListener_respond_get_changes (PortableServer_Servant servant, - const CORBA_long opid, - const GNOME_Evolution_Addressbook_CallStatus status, - const GNOME_Evolution_Addressbook_BookChangeList *changes, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - gint i; - - response.op = GetChangesResponse; - response.opid = opid; - response.status = e_book_listener_convert_status (status); - response.list = NULL; - - for (i = 0; i < changes->_length; i ++) { - EBookChange *change = g_new (EBookChange, 1); - GNOME_Evolution_Addressbook_BookChangeItem corba_change = changes->_buffer[i]; - - switch (corba_change.changeType) { - case GNOME_Evolution_Addressbook_ContactAdded: - change->change_type = E_BOOK_CHANGE_CARD_ADDED; - break; - case GNOME_Evolution_Addressbook_ContactDeleted: - change->change_type = E_BOOK_CHANGE_CARD_DELETED; - break; - case GNOME_Evolution_Addressbook_ContactModified: - change->change_type = E_BOOK_CHANGE_CARD_MODIFIED; - break; - } - change->contact = e_contact_new_from_vcard (corba_change.vcard); - - response.list = g_list_prepend (response.list, change); - } - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); -} - -static void -impl_BookListener_respond_open_book (PortableServer_Servant servant, - const CORBA_long opid, - const GNOME_Evolution_Addressbook_CallStatus status, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - - response.op = OpenBookResponse; - response.opid = opid; - response.status = e_book_listener_convert_status (status); - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); -} - -static void -impl_BookListener_respond_remove_book (PortableServer_Servant servant, - const CORBA_long opid, - const GNOME_Evolution_Addressbook_CallStatus status, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - - response.op = RemoveBookResponse; - response.opid = opid; - response.status = e_book_listener_convert_status (status); - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); -} - -static void -impl_BookListener_respond_authentication_result (PortableServer_Servant servant, - const CORBA_long opid, - const GNOME_Evolution_Addressbook_CallStatus status, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - - response.op = AuthenticationResponse; - response.opid = opid; - response.status = e_book_listener_convert_status (status); - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); -} - -static void -impl_BookListener_respond_get_required_fields (PortableServer_Servant servant, - const CORBA_long opid, - const GNOME_Evolution_Addressbook_CallStatus status, - const GNOME_Evolution_Addressbook_stringlist *fields, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - gint i; - - response.op = GetRequiredFieldsResponse; - response.opid = opid; - response.status = e_book_listener_convert_status (status); - response.list = NULL; - - for (i = 0; i < fields->_length; i ++) - response.list = g_list_prepend (response.list, g_strdup (fields->_buffer[i])); - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); -} - -static void -impl_BookListener_respond_get_supported_fields (PortableServer_Servant servant, - const CORBA_long opid, - const GNOME_Evolution_Addressbook_CallStatus status, - const GNOME_Evolution_Addressbook_stringlist *fields, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - gint i; - - response.op = GetSupportedFieldsResponse; - response.opid = opid; - response.status = e_book_listener_convert_status (status); - response.list = NULL; - - for (i = 0; i < fields->_length; i ++) - response.list = g_list_prepend (response.list, g_strdup (fields->_buffer[i])); - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); -} - -static void -impl_BookListener_respond_get_supported_auth_methods (PortableServer_Servant servant, - const CORBA_long opid, - const GNOME_Evolution_Addressbook_CallStatus status, - const GNOME_Evolution_Addressbook_stringlist *auth_methods, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - gint i; - - response.op = GetSupportedAuthMethodsResponse; - response.opid = opid; - response.status = e_book_listener_convert_status (status); - response.list = NULL; - - for (i = 0; i < auth_methods->_length; i ++) - response.list = g_list_prepend (response.list, g_strdup (auth_methods->_buffer[i])); - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); -} - -static void -impl_BookListener_report_writable (PortableServer_Servant servant, - const CORBA_boolean writable, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - - response.op = WritableStatusEvent; - response.writable = writable; - - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); -} - -static void -impl_BookListener_report_link_status (PortableServer_Servant servant, - const CORBA_boolean is_online, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - - response.op = LinkStatusEvent; - response.connected = is_online; - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); -} - -static void -impl_BookListener_report_auth_required (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - EBookListener *listener = E_BOOK_LISTENER (bonobo_object (servant)); - EBookListenerResponse response; - - response.op = AuthRequiredEvent; - g_signal_emit (listener, e_book_listener_signals [RESPONSE], 0, &response); -} - -static void -impl_BookListener_respond_progress (PortableServer_Servant servant, - const CORBA_char * message, - const CORBA_short percent, - CORBA_Environment *ev) -{ -} - -/** - * e_book_listener_new: - * - * Creates and returns a new #EBookListener. - * - * Returns: a new #EBookListener - */ -EBookListener * -e_book_listener_new (void) -{ - static GStaticMutex mutex = G_STATIC_MUTEX_INIT; - static PortableServer_POA poa = NULL; - EBookListener *listener; - - g_static_mutex_lock (&mutex); - if (poa == NULL) - poa = bonobo_poa_get_threaded (ORBIT_THREAD_HINT_ON_CONTEXT, _ebook_context, NULL); - g_static_mutex_unlock (&mutex); - - listener = g_object_new (E_TYPE_BOOK_LISTENER, "poa", poa, NULL); - - return listener; -} - -static void -e_book_listener_init (EBookListener *listener) -{ - listener->priv = g_new0 (EBookListenerPrivate, 1); -} - -/** - * e_book_listener_stop: - * @listener: an #EBookListener - * - * Stops @listener from generating events. - **/ -void -e_book_listener_stop (EBookListener *listener) -{ - g_return_if_fail (E_IS_BOOK_LISTENER (listener)); - - listener->priv->stopped = TRUE; -} - -static void -e_book_listener_finalize (GObject *object) -{ - EBookListener *listener = E_BOOK_LISTENER (object); - if (listener->priv) { - g_free (listener->priv); - listener->priv = NULL; - } - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -e_book_listener_class_init (EBookListenerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - POA_GNOME_Evolution_Addressbook_BookListener__epv *epv; - - parent_class = g_type_class_ref (BONOBO_TYPE_OBJECT); - - e_book_listener_signals [RESPONSE] = - g_signal_new ("response", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookListenerClass, response), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - epv = &klass->epv; - epv->notifyProgress = impl_BookListener_respond_progress; - epv->notifyBookOpened = impl_BookListener_respond_open_book; - epv->notifyBookRemoved = impl_BookListener_respond_remove_book; - epv->notifyContactCreated = impl_BookListener_respond_create_contact; - epv->notifyContactsRemoved = impl_BookListener_respond_remove_contacts; - epv->notifyContactModified = impl_BookListener_respond_modify_contact; - epv->notifyAuthenticationResult = impl_BookListener_respond_authentication_result; - epv->notifyRequiredFields = impl_BookListener_respond_get_required_fields; - epv->notifySupportedFields = impl_BookListener_respond_get_supported_fields; - epv->notifySupportedAuthMethods = impl_BookListener_respond_get_supported_auth_methods; - epv->notifyContactRequested = impl_BookListener_respond_get_contact; - epv->notifyContactListRequested = impl_BookListener_respond_get_contact_list; - epv->notifyViewRequested = impl_BookListener_respond_get_view; - epv->notifyChangesRequested = impl_BookListener_respond_get_changes; - epv->notifyWritable = impl_BookListener_report_writable; - epv->notifyConnectionStatus = impl_BookListener_report_link_status; - epv->notifyAuthRequired = impl_BookListener_report_auth_required; - - object_class->finalize = e_book_listener_finalize; -} - -BONOBO_TYPE_FUNC_FULL ( - EBookListener, - GNOME_Evolution_Addressbook_BookListener, - BONOBO_TYPE_OBJECT, - e_book_listener) diff --git a/addressbook/libebook/e-book-listener.h b/addressbook/libebook/e-book-listener.h deleted file mode 100644 index 71e000f67..000000000 --- a/addressbook/libebook/e-book-listener.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * A client-side GObject which exposes the - * Evolution:BookListener interface. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - */ - -#ifndef __E_BOOK_LISTENER_H__ -#define __E_BOOK_LISTENER_H__ - -#include <bonobo/bonobo-object.h> -#include <libebook/e-book-types.h> - -#include "Evolution-DataServer-Addressbook.h" - -#define E_TYPE_BOOK_LISTENER (e_book_listener_get_type ()) -#define E_BOOK_LISTENER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_BOOK_LISTENER, EBookListener)) -#define E_BOOK_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_BOOK_LISTENER, EBookListenerClass)) -#define E_IS_BOOK_LISTENER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_BOOK_LISTENER)) -#define E_IS_BOOK_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_BOOK_LISTENER)) -#define E_BOOK_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_BOOK_LISTENER, EBookListenerClass)) - -G_BEGIN_DECLS - -typedef struct _EBookListener EBookListener; -typedef struct _EBookListenerClass EBookListenerClass; -typedef struct _EBookListenerPrivate EBookListenerPrivate; -typedef struct _EBookListenerResponse EBookListenerResponse; - -struct _EBookListener { - BonoboObject parent; - /*< private >*/ - EBookListenerPrivate *priv; -}; - -struct _EBookListenerClass { - BonoboObjectClass parent; - - POA_GNOME_Evolution_Addressbook_BookListener__epv epv; - - /* - * Signals - */ - - void (*response) (EBookListener *listener, EBookListenerResponse *response); - - /* Padding for future expansion */ - void (*_ebook_reserved0) (void); - void (*_ebook_reserved1) (void); - void (*_ebook_reserved2) (void); - void (*_ebook_reserved3) (void); - void (*_ebook_reserved4) (void); -}; - -typedef enum { - /* Async responses */ - OpenBookResponse, - RemoveBookResponse, - CreateContactResponse, - RemoveContactResponse, - ModifyContactResponse, - GetContactResponse, - GetContactListResponse, - GetBookViewResponse, - GetChangesResponse, - AuthenticationResponse, - GetSupportedFieldsResponse, - GetRequiredFieldsResponse, - GetSupportedAuthMethodsResponse, - - /* Async events */ - LinkStatusEvent, - WritableStatusEvent, - AuthRequiredEvent, - ProgressEvent -} EBookListenerOperation; - -struct _EBookListenerResponse { - EBookListenerOperation op; - - /* The tag that e_book_* assigned to the operation this is a - response for */ - guint32 opid; - - /* For most Response notifications */ - EBookStatus status; - - /* For GetBookViewReponse */ - GNOME_Evolution_Addressbook_BookView book_view; - - /* For GetSupportedFields/GetSupportedAuthMethods */ - GList *list; - - /* For ProgressEvent */ - gchar *msg; - short percent; - - /* For LinkStatusEvent */ - gboolean connected; - - /* For WritableStatusEvent */ - gboolean writable; - - /* For Card[Added|Removed|Modified]Event */ - gchar *id; - gchar *vcard; -}; - -EBookListener *e_book_listener_new (void); -GType e_book_listener_get_type (void); -void e_book_listener_stop (EBookListener *listener); - -G_END_DECLS - -#endif /* ! __E_BOOK_LISTENER_H__ */ diff --git a/addressbook/libebook/e-book-marshal.list b/addressbook/libebook/e-book-marshal.list new file mode 100644 index 000000000..680ea039a --- /dev/null +++ b/addressbook/libebook/e-book-marshal.list @@ -0,0 +1,5 @@ +NONE:NONE +NONE:BOOL +NONE:POINTER +NONE:STRING +NONE:INT diff --git a/addressbook/libebook/e-book-view-listener.c b/addressbook/libebook/e-book-view-listener.c deleted file mode 100644 index 75da9a071..000000000 --- a/addressbook/libebook/e-book-view-listener.c +++ /dev/null @@ -1,405 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Exports the BookViewListener interface. Maintains a queue of messages - * which come in on the interface. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - */ - -#include <config.h> -#include <bonobo/bonobo-main.h> -#include "e-book-view-listener.h" -#include "e-book-view.h" -#include "e-contact.h" - -#define d(x) - -static EBookViewStatus e_book_view_listener_convert_status (GNOME_Evolution_Addressbook_CallStatus status); - -enum { - RESPONSE, - LAST_SIGNAL -}; - -static guint e_book_view_listener_signals [LAST_SIGNAL]; - -static BonoboObjectClass *parent_class; - -#define READ_END 0 -#define WRITE_END 1 - -struct _EBookViewListenerPrivate { - guint stopped : 1; - GAsyncQueue *queue; - - GMutex *idle_mutex; - guint idle_id; -}; - -static void -free_response (EBookViewListenerResponse *response) -{ - g_return_if_fail (response != NULL); - - g_list_foreach (response->ids, (GFunc)g_free, NULL); - g_list_free (response->ids); - g_list_foreach (response->contacts, (GFunc) g_object_unref, NULL); - g_list_free (response->contacts); - g_free (response->message); - g_free (response); -} - -static gboolean -main_thread_get_response (gpointer data) -{ - EBookViewListener *listener = data; - EBookViewListenerResponse *response; - - bonobo_object_ref (listener); - - g_mutex_lock (listener->priv->idle_mutex); - - /* remove the idle call */ - - while ((response = g_async_queue_try_pop (listener->priv->queue)) != NULL) { - - g_signal_emit (listener, e_book_view_listener_signals [RESPONSE], 0, response); - - free_response (response); - } - - listener->priv->idle_id = -1; - - g_mutex_unlock (listener->priv->idle_mutex); - - bonobo_object_unref (listener); - - return FALSE; -} - -static void -e_book_view_listener_queue_response (EBookViewListener *listener, - EBookViewListenerResponse *response) -{ - if (response == NULL) - return; - - if (listener->priv->stopped) { - free_response (response); - return; - } - - g_mutex_lock (listener->priv->idle_mutex); - - g_async_queue_push (listener->priv->queue, response); - - if (listener->priv->idle_id == -1) - listener->priv->idle_id = g_idle_add (main_thread_get_response, listener); - g_mutex_unlock (listener->priv->idle_mutex); -} - -/* Add, Remove, Modify */ -static void -e_book_view_listener_queue_status_event (EBookViewListener *listener, - EBookViewListenerOperation op, - EBookViewStatus status) -{ - EBookViewListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookViewListenerResponse, 1); - - resp->op = op; - resp->status = status; - - e_book_view_listener_queue_response (listener, resp); -} - -/* Add, Remove, Modify */ -static void -e_book_view_listener_queue_idlist_event (EBookViewListener *listener, - EBookViewListenerOperation op, - const GNOME_Evolution_Addressbook_ContactIdList *ids) -{ - EBookViewListenerResponse *resp; - gint i; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookViewListenerResponse, 1); - - resp->op = op; - resp->status = E_BOOK_VIEW_STATUS_OK; - - for (i = 0; i < ids->_length; i ++) { - resp->ids = g_list_prepend (resp->ids, g_strdup (ids->_buffer[i])); - } - - e_book_view_listener_queue_response (listener, resp); -} - -/* Add, Remove, Modify */ -static void -e_book_view_listener_queue_sequence_event (EBookViewListener *listener, - EBookViewListenerOperation op, - const GNOME_Evolution_Addressbook_VCardList *vcards) -{ - EBookViewListenerResponse *resp; - gint i; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookViewListenerResponse, 1); - - resp->op = op; - resp->status = E_BOOK_VIEW_STATUS_OK; - - for ( i = 0; i < vcards->_length; i++ ) { - resp->contacts = g_list_prepend (resp->contacts, e_contact_new_from_vcard (vcards->_buffer[i])); - } - resp->contacts = g_list_reverse (resp->contacts); - - e_book_view_listener_queue_response (listener, resp); -} - -/* Status Message */ -static void -e_book_view_listener_queue_message_event (EBookViewListener *listener, - EBookViewListenerOperation op, - const gchar *message) -{ - EBookViewListenerResponse *resp; - - if (listener->priv->stopped) - return; - - resp = g_new0 (EBookViewListenerResponse, 1); - - resp->op = op; - resp->status = E_BOOK_VIEW_STATUS_OK; - resp->message = g_strdup(message); - - e_book_view_listener_queue_response (listener, resp); -} - -static void -impl_BookViewListener_notify_contacts_added (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_VCardList *vcards, - CORBA_Environment *ev) -{ - EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant)); - - d(printf ("%p: impl_BookViewListener_notify_contacts_added (%p)\n", g_thread_self(), listener)); - - e_book_view_listener_queue_sequence_event ( - listener, ContactsAddedEvent, vcards); -} - -static void -impl_BookViewListener_notify_contacts_removed (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_ContactIdList *ids, - CORBA_Environment *ev) -{ - EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant)); - - d(printf ("%p: impl_BookViewListener_notify_contacts_removed (%p)\n", g_thread_self(), listener)); - - e_book_view_listener_queue_idlist_event (listener, ContactsRemovedEvent, ids); -} - -static void -impl_BookViewListener_notify_contacts_changed (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_VCardList *vcards, - CORBA_Environment *ev) -{ - EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant)); - - d(printf ("%p: impl_BookViewListener_notify_contacts_changed (%p)\n", g_thread_self(), listener)); - - e_book_view_listener_queue_sequence_event ( - listener, ContactsModifiedEvent, vcards); -} - -static void -impl_BookViewListener_notify_sequence_complete (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_CallStatus status, - CORBA_Environment *ev) -{ - EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant)); - - d(printf ("%p: impl_BookViewListener_notify_sequence_complete (%p)\n", g_thread_self(), listener)); - - e_book_view_listener_queue_status_event (listener, SequenceCompleteEvent, - e_book_view_listener_convert_status (status)); -} - -static void -impl_BookViewListener_notify_progress (PortableServer_Servant servant, - const gchar *message, - const CORBA_short percent, - CORBA_Environment *ev) -{ - EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object (servant)); - - d(printf ("%p: impl_BookViewListener_notify_progress (%p,`%s')\n", g_thread_self(), listener, message)); - - e_book_view_listener_queue_message_event (listener, StatusMessageEvent, message); -} - -static EBookViewStatus -e_book_view_listener_convert_status (const GNOME_Evolution_Addressbook_CallStatus status) -{ - switch (status) { - case GNOME_Evolution_Addressbook_Success: - return E_BOOK_VIEW_STATUS_OK; - case GNOME_Evolution_Addressbook_SearchTimeLimitExceeded: - return E_BOOK_VIEW_STATUS_TIME_LIMIT_EXCEEDED; - case GNOME_Evolution_Addressbook_SearchSizeLimitExceeded: - return E_BOOK_VIEW_STATUS_SIZE_LIMIT_EXCEEDED; - case GNOME_Evolution_Addressbook_InvalidQuery: - return E_BOOK_VIEW_ERROR_INVALID_QUERY; - case GNOME_Evolution_Addressbook_QueryRefused: - return E_BOOK_VIEW_ERROR_QUERY_REFUSED; - case GNOME_Evolution_Addressbook_OtherError: - default: - return E_BOOK_VIEW_ERROR_OTHER_ERROR; - } -} - -/** - * e_book_view_listener_new: - * - * Creates and returns a new #EBookViewListener. - * - * Return value: a new #EBookViewListener - */ -EBookViewListener * -e_book_view_listener_new (void) -{ - static GStaticMutex mutex = G_STATIC_MUTEX_INIT; - static PortableServer_POA poa = NULL; - EBookViewListener *listener; - - g_static_mutex_lock (&mutex); - if (poa == NULL) - poa = bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_OBJECT, NULL); - g_static_mutex_unlock (&mutex); - - listener = g_object_new (E_TYPE_BOOK_VIEW_LISTENER, "poa", poa, NULL); - - listener->priv->queue = g_async_queue_new(); - listener->priv->idle_mutex = g_mutex_new(); - listener->priv->idle_id = -1; - - return listener; -} - -static void -e_book_view_listener_init (EBookViewListener *listener) -{ - listener->priv = g_new0 (EBookViewListenerPrivate, 1); - listener->priv->stopped = TRUE; -} - -/** - * e_book_view_listener_start: - * @listener: an #EBookViewListener - * - * Makes @listener start generating events. - **/ -void -e_book_view_listener_start (EBookViewListener *listener) -{ - g_return_if_fail (E_IS_BOOK_VIEW_LISTENER (listener)); - d(printf ("%p: e_book_view_listener_start (%p)\n", g_thread_self(), listener)); - listener->priv->stopped = FALSE; -} - -/** - * e_book_view_listener_stop: - * @listener: an #EBookViewListener - * - * Makes @listener stop generating events. - **/ -void -e_book_view_listener_stop (EBookViewListener *listener) -{ - g_return_if_fail (E_IS_BOOK_VIEW_LISTENER (listener)); - d(printf ("%p: e_book_view_listener_stop (%p)\n", g_thread_self(), listener)); - listener->priv->stopped = TRUE; - - if (listener->priv->idle_id != -1) { - g_source_remove (listener->priv->idle_id); - listener->priv->idle_id = -1; - } -} - -static void -e_book_view_listener_dispose (GObject *object) -{ - EBookViewListener *listener = E_BOOK_VIEW_LISTENER (object); - - d(printf ("%p: in e_book_view_listener_dispose (%p)\n", g_thread_self(), object)); - - if (listener->priv) { - EBookViewListenerResponse *response; - - if (listener->priv->idle_id != -1) - g_source_remove (listener->priv->idle_id); - - g_mutex_free (listener->priv->idle_mutex); - - /* Free pending events */ - while ((response = g_async_queue_try_pop (listener->priv->queue)) != NULL) - free_response (response); - - g_async_queue_unref (listener->priv->queue); - - g_free (listener->priv); - listener->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -e_book_view_listener_class_init (EBookViewListenerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - POA_GNOME_Evolution_Addressbook_BookViewListener__epv *epv; - - parent_class = g_type_class_ref (BONOBO_TYPE_OBJECT); - - e_book_view_listener_signals [RESPONSE] = - g_signal_new ("response", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookViewListenerClass, response), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, - 1, G_TYPE_POINTER); - - object_class->dispose = e_book_view_listener_dispose; - - epv = &klass->epv; - epv->notifyContactsChanged = impl_BookViewListener_notify_contacts_changed; - epv->notifyContactsRemoved = impl_BookViewListener_notify_contacts_removed; - epv->notifyContactsAdded = impl_BookViewListener_notify_contacts_added; - epv->notifySequenceComplete = impl_BookViewListener_notify_sequence_complete; - epv->notifyProgress = impl_BookViewListener_notify_progress; -} - -BONOBO_TYPE_FUNC_FULL ( - EBookViewListener, - GNOME_Evolution_Addressbook_BookViewListener, - BONOBO_TYPE_OBJECT, - e_book_view_listener) diff --git a/addressbook/libebook/e-book-view-listener.h b/addressbook/libebook/e-book-view-listener.h deleted file mode 100644 index 3ab121637..000000000 --- a/addressbook/libebook/e-book-view-listener.h +++ /dev/null @@ -1,92 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * A client-side GObject which exposes the - * Evolution:BookViewListener interface. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - */ - -#ifndef __E_BOOK_VIEW_LISTENER_H__ -#define __E_BOOK_VIEW_LISTENER_H__ - -#include <bonobo/bonobo-object.h> -#include <libebook/e-book-types.h> - -#include "Evolution-DataServer-Addressbook.h" - -#define E_TYPE_BOOK_VIEW_LISTENER (e_book_view_listener_get_type ()) -#define E_BOOK_VIEW_LISTENER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_BOOK_VIEW_LISTENER, EBookViewListener)) -#define E_BOOK_VIEW_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_BOOK_VIEW_LISTENER, EBookViewListenerClass)) -#define E_IS_BOOK_VIEW_LISTENER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_BOOK_VIEW_LISTENER)) -#define E_IS_BOOK_VIEW_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_BOOK_VIEW_LISTENER)) -#define E_BOOK_VIEW_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_BOOK_VIEW_LISTENER, EBookViewListenerClass)) - -G_BEGIN_DECLS - -typedef struct _EBookViewListener EBookViewListener; -typedef struct _EBookViewListenerClass EBookViewListenerClass; -typedef struct _EBookViewListenerPrivate EBookViewListenerPrivate; - -typedef struct _EBookViewListenerResponse EBookViewListenerResponse; - -struct _EBookViewListener { - BonoboObject parent; - /*< private >*/ - EBookViewListenerPrivate *priv; -}; - -struct _EBookViewListenerClass { - BonoboObjectClass parent; - - POA_GNOME_Evolution_Addressbook_BookViewListener__epv epv; - - /* - * Signals - */ - void (*response) (EBookViewListener *listener, EBookViewListenerResponse *response); - - /* Padding for future expansion */ - void (*_ebook_reserved0) (void); - void (*_ebook_reserved1) (void); - void (*_ebook_reserved2) (void); - void (*_ebook_reserved3) (void); - void (*_ebook_reserved4) (void); -}; - -typedef enum { - /* Async events */ - ContactsAddedEvent, - ContactsRemovedEvent, - ContactsModifiedEvent, - SequenceCompleteEvent, - StatusMessageEvent -} EBookViewListenerOperation; - -struct _EBookViewListenerResponse { - EBookViewListenerOperation op; - - /* For SequenceComplete */ - EBookViewStatus status; - - /* For ContactsRemovedEvent */ - GList *ids; - - /* For Contact[sAdded|Modified]Event */ - GList *contacts; /* Of type EContact. */ - - /* For StatusMessageEvent */ - gchar *message; - -}; - -EBookViewListener *e_book_view_listener_new (void); -GType e_book_view_listener_get_type (void); -void e_book_view_listener_start (EBookViewListener *listener); -void e_book_view_listener_stop (EBookViewListener *listener); - -G_END_DECLS - -#endif /* ! __E_BOOK_VIEW_LISTENER_H__ */ diff --git a/addressbook/libebook/e-book-view-private.h b/addressbook/libebook/e-book-view-private.h index a8e546a5a..8b7db453f 100644 --- a/addressbook/libebook/e-book-view-private.h +++ b/addressbook/libebook/e-book-view-private.h @@ -1,25 +1,31 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * The Evolution addressbook client object. + * Copyright (C) 2006 OpenedHand Ltd + * Copyright (C) 2009 Intel Corporation * - * Author: - * Nat Friedman (nat@ximian.com) + * This library is free software; you can redistribute it and/or modify it under + * the terms of version 2.1 of the GNU Lesser General Public License as + * published by the Free Software Foundation. * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * This library 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 Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Ross Burton <ross@linux.intel.com> */ #ifndef __E_BOOK_VIEW_PRIVATE_H__ #define __E_BOOK_VIEW_PRIVATE_H__ -#include <glib.h> -#include <glib-object.h> - -#include "Evolution-DataServer-Addressbook.h" -#include "e-book-view-listener.h" - -EBookView *e_book_view_new (GNOME_Evolution_Addressbook_BookView corba_book_view, EBookViewListener *listener); +#include "e-book.h" +#include "e-book-view.h" -void e_book_view_set_book (EBookView *book_view, struct _EBook *book); +EBookView *_e_book_view_new (EBook *book, DBusGProxy *view_proxy); G_END_DECLS diff --git a/addressbook/libebook/e-book-view.c b/addressbook/libebook/e-book-view.c index 03c232791..56e23f0bc 100644 --- a/addressbook/libebook/e-book-view.c +++ b/addressbook/libebook/e-book-view.c @@ -1,30 +1,42 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * The Evolution addressbook client object. + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * Copyright (C) 2006 OpenedHand Ltd + * Copyright (C) 2009 Intel Corporation * - * Author: - * Nat Friedman (nat@ximian.com) + * This library is free software; you can redistribute it and/or modify it under + * the terms of version 2.1 of the GNU Lesser General Public License as + * published by the Free Software Foundation. * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * This library 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 Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Ross Burton <ross@linux.intel.com> */ -#include <config.h> - -#include "e-book-view-listener.h" +#include <glib-object.h> +#include <dbus/dbus-glib.h> +#include "e-book.h" #include "e-book-view.h" #include "e-book-view-private.h" -#include "e-book.h" - -static GObjectClass *parent_class; - -struct _EBookViewPrivate { - GNOME_Evolution_Addressbook_BookView corba_book_view; +#include "e-data-book-view-bindings.h" +#include "e-book-marshal.h" - EBook *book; +G_DEFINE_TYPE(EBookView, e_book_view, G_TYPE_OBJECT); - EBookViewListener *listener; +#define E_BOOK_VIEW_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_BOOK_VIEW, EBookViewPrivate)) - gint response_id; +struct _EBookViewPrivate { + EBook *book; + DBusGProxy *view_proxy; + gboolean running; }; enum { @@ -36,156 +48,124 @@ enum { LAST_SIGNAL }; -static guint e_book_view_signals [LAST_SIGNAL]; +static guint signals [LAST_SIGNAL]; static void -e_book_view_do_added_event (EBookView *book_view, - EBookViewListenerResponse *resp) +status_message_cb (DBusGProxy *proxy, const gchar *message, EBookView *book_view) { - g_signal_emit (book_view, e_book_view_signals [CONTACTS_ADDED], 0, - resp->contacts); -} + if (!book_view->priv->running) + return; -static void -e_book_view_do_modified_event (EBookView *book_view, - EBookViewListenerResponse *resp) -{ - g_signal_emit (book_view, e_book_view_signals [CONTACTS_CHANGED], 0, - resp->contacts); + g_signal_emit (book_view, signals[STATUS_MESSAGE], 0, message); } static void -e_book_view_do_removed_event (EBookView *book_view, - EBookViewListenerResponse *resp) +contacts_added_cb (DBusGProxy *proxy, const gchar **vcards, EBookView *book_view) { - g_signal_emit (book_view, e_book_view_signals [CONTACTS_REMOVED], 0, - resp->ids); -} + const gchar **p; + GList *contacts = NULL; -static void -e_book_view_do_complete_event (EBookView *book_view, - EBookViewListenerResponse *resp) -{ - g_signal_emit (book_view, e_book_view_signals [SEQUENCE_COMPLETE], 0, - resp->status); -} + if (!book_view->priv->running) + return; -static void -e_book_view_do_status_message_event (EBookView *book_view, - EBookViewListenerResponse *resp) -{ - g_signal_emit (book_view, e_book_view_signals [STATUS_MESSAGE], 0, - resp->message); + for (p = vcards; *p; p++) { + contacts = g_list_prepend (contacts, e_contact_new_from_vcard (*p)); + } + contacts = g_list_reverse (contacts); + + g_signal_emit (book_view, signals[CONTACTS_ADDED], 0, contacts); + + g_list_foreach (contacts, (GFunc)g_object_unref, NULL); + g_list_free (contacts); } static void -e_book_view_handle_response (EBookViewListener *listener, EBookViewListenerResponse *resp, EBookView *book_view) +contacts_changed_cb (DBusGProxy *proxy, const gchar **vcards, EBookView *book_view) { - /* we shouldn't need this check. EBVL only emits the signal when resp != NULL */ - if (resp == NULL) + const gchar **p; + GList *contacts = NULL; + + if (!book_view->priv->running) return; - switch (resp->op) { - case ContactsAddedEvent: - e_book_view_do_added_event (book_view, resp); - break; - case ContactsModifiedEvent: - e_book_view_do_modified_event (book_view, resp); - break; - case ContactsRemovedEvent: - e_book_view_do_removed_event (book_view, resp); - break; - case SequenceCompleteEvent: - e_book_view_do_complete_event (book_view, resp); - break; - case StatusMessageEvent: - e_book_view_do_status_message_event (book_view, resp); - break; - default: - g_error ("EBookView: Unknown operation %d in listener queue!\n", - resp->op); - break; + for (p = vcards; *p; p++) { + contacts = g_list_prepend (contacts, e_contact_new_from_vcard (*p)); } + contacts = g_list_reverse (contacts); + + g_signal_emit (book_view, signals[CONTACTS_CHANGED], 0, contacts); + + g_list_foreach (contacts, (GFunc)g_object_unref, NULL); + g_list_free (contacts); } -static gboolean -e_book_view_construct (EBookView *book_view, GNOME_Evolution_Addressbook_BookView corba_book_view, EBookViewListener *listener) +static void +contacts_removed_cb (DBusGProxy *proxy, const gchar **ids, EBookView *book_view) { - CORBA_Environment ev; - g_return_val_if_fail (book_view != NULL, FALSE); - g_return_val_if_fail (E_IS_BOOK_VIEW (book_view), FALSE); - - /* - * Copy in the corba_book_view. - */ - CORBA_exception_init (&ev); - - book_view->priv->corba_book_view = bonobo_object_dup_ref(corba_book_view, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("e_book_view_construct: Exception duplicating corba_book_view.\n"); - CORBA_exception_free (&ev); - book_view->priv->corba_book_view = CORBA_OBJECT_NIL; - return FALSE; - } + const gchar **p; + GList *list = NULL; - CORBA_exception_free (&ev); + if (!book_view->priv->running) + return; - /* - * Create our local BookListener interface. - */ - book_view->priv->listener = listener; - book_view->priv->response_id = g_signal_connect (book_view->priv->listener, "response", - G_CALLBACK (e_book_view_handle_response), book_view); + for (p = ids; *p; p++) { + list = g_list_prepend (list, (char*)*p); + } + list = g_list_reverse (list); - bonobo_object_ref(BONOBO_OBJECT(book_view->priv->listener)); + g_signal_emit (book_view, signals[CONTACTS_REMOVED], 0, list); - return TRUE; + /* No need to free the values, our caller will */ + g_list_free (list); } -/** - * e_book_view_new: - * @corba_book_view: a CORBA BookView object - * @listener: an #EBookViewListener - * - * Creates a new #EBookView based on @corba_book_view and listening to - * @listener. This is a private function, applications should call - * #e_book_get_book_view or #e_book_async_get_book_view. - * - * Return value: A new #EBookView. - **/ -EBookView * -e_book_view_new (GNOME_Evolution_Addressbook_BookView corba_book_view, EBookViewListener *listener) +static void +complete_cb (DBusGProxy *proxy, guint status, EBookView *book_view) { - EBookView *book_view; - - book_view = g_object_new (E_TYPE_BOOK_VIEW, NULL); - - if (! e_book_view_construct (book_view, corba_book_view, listener)) { - g_object_unref (book_view); - return NULL; - } + if (!book_view->priv->running) + return; - return book_view; + g_signal_emit (book_view, signals[SEQUENCE_COMPLETE], 0, status); } -/** - * e_book_view_set_book: - * @book_view: an #EBookView +/* + * e_book_view_new: * @book: an #EBook + * @view_proxy: The #DBusGProxy to get signals from + * + * Creates a new #EBookView based on #EBook and listening to @view_proxy. This + * is a private function, applications should call #e_book_get_book_view or + * #e_book_async_get_book_view. * - * Makes @book_view listen to changes in @book. This function apparently - * has no effect for the time being. + * Return value: A new #EBookView. **/ -void -e_book_view_set_book (EBookView *book_view, EBook *book) +EBookView * +_e_book_view_new (EBook *book, DBusGProxy *view_proxy) { - g_return_if_fail (book_view && E_IS_BOOK_VIEW (book_view)); - g_return_if_fail (book && E_IS_BOOK (book)); - g_return_if_fail (book_view->priv->book == NULL); - - book_view->priv->book = book; - g_object_ref (book); + EBookView *view; + EBookViewPrivate *priv; + + view = g_object_new (E_TYPE_BOOK_VIEW, NULL); + priv = view->priv; + + priv->book = g_object_ref (book); + + /* Take ownership of the view_proxy object */ + priv->view_proxy = view_proxy; + g_object_add_weak_pointer (G_OBJECT (view_proxy), (gpointer)&priv->view_proxy); + + dbus_g_proxy_add_signal (view_proxy, "StatusMessage", G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (view_proxy, "StatusMessage", G_CALLBACK (status_message_cb), view, NULL); + dbus_g_proxy_add_signal (view_proxy, "ContactsAdded", G_TYPE_STRV, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (view_proxy, "ContactsAdded", G_CALLBACK (contacts_added_cb), view, NULL); + dbus_g_proxy_add_signal (view_proxy, "ContactsChanged", G_TYPE_STRV, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (view_proxy, "ContactsChanged", G_CALLBACK (contacts_changed_cb), view, NULL); + dbus_g_proxy_add_signal (view_proxy, "ContactsRemoved", G_TYPE_STRV, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (view_proxy, "ContactsRemoved", G_CALLBACK (contacts_removed_cb), view, NULL); + dbus_g_proxy_add_signal (view_proxy, "Complete", G_TYPE_UINT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (view_proxy, "Complete", G_CALLBACK (complete_cb), view, NULL); + + return view; } /** @@ -196,10 +176,10 @@ e_book_view_set_book (EBookView *book_view, EBook *book) * * Return value: an #EBook. **/ -EBook* +EBook * e_book_view_get_book (EBookView *book_view) { - g_return_val_if_fail (book_view && E_IS_BOOK_VIEW (book_view), NULL); + g_return_val_if_fail (E_IS_BOOK_VIEW (book_view), NULL); return book_view->priv->book; } @@ -213,18 +193,24 @@ e_book_view_get_book (EBookView *book_view) void e_book_view_start (EBookView *book_view) { - CORBA_Environment ev; + GError *error = NULL; - g_return_if_fail (book_view && E_IS_BOOK_VIEW (book_view)); + g_return_if_fail (E_IS_BOOK_VIEW (book_view)); - CORBA_exception_init (&ev); + book_view->priv->running = TRUE; - e_book_view_listener_start (book_view->priv->listener); + if (book_view->priv->view_proxy) { + org_gnome_evolution_dataserver_addressbook_BookView_start (book_view->priv->view_proxy, &error); + if (error) { + g_warning ("Cannot start book view: %s\n", error->message); - GNOME_Evolution_Addressbook_BookView_start (book_view->priv->corba_book_view, &ev); + /* Fake a sequence-complete so that the application knows this failed */ + /* TODO: use get_status_from_error */ + g_signal_emit (book_view, signals[SEQUENCE_COMPLETE], 0, + E_BOOK_ERROR_CORBA_EXCEPTION); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("corba exception._major = %d\n", ev._major); + g_error_free (error); + } } } @@ -237,69 +223,48 @@ e_book_view_start (EBookView *book_view) void e_book_view_stop (EBookView *book_view) { - CORBA_Environment ev; + GError *error = NULL; - g_return_if_fail (book_view && E_IS_BOOK_VIEW (book_view)); + g_return_if_fail (E_IS_BOOK_VIEW (book_view)); - CORBA_exception_init (&ev); + book_view->priv->running = FALSE; - e_book_view_listener_stop (book_view->priv->listener); - - GNOME_Evolution_Addressbook_BookView_stop (book_view->priv->corba_book_view, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("corba exception._major = %d\n", ev._major); + if (book_view->priv->view_proxy) { + org_gnome_evolution_dataserver_addressbook_BookView_stop (book_view->priv->view_proxy, &error); + if (error) { + g_warning ("Cannot stop book view: %s\n", error->message); + g_error_free (error); + } } } static void e_book_view_init (EBookView *book_view) { - book_view->priv = g_new0 (EBookViewPrivate, 1); - book_view->priv->book = NULL; - book_view->priv->corba_book_view = CORBA_OBJECT_NIL; - book_view->priv->listener = NULL; - book_view->priv->response_id = 0; + EBookViewPrivate *priv = E_BOOK_VIEW_GET_PRIVATE (book_view); + + priv->book = NULL; + priv->view_proxy = NULL; + priv->running = FALSE; + + book_view->priv = priv; } static void e_book_view_dispose (GObject *object) { - EBookView *book_view = E_BOOK_VIEW (object); - CORBA_Environment ev; - - if (book_view->priv) { - if (book_view->priv->book) { - g_object_unref (book_view->priv->book); - } - - if (book_view->priv->corba_book_view) { - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookView_dispose (book_view->priv->corba_book_view, &ev); + EBookView *view = E_BOOK_VIEW (object); - bonobo_object_release_unref (book_view->priv->corba_book_view, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("EBookView: Exception while releasing BookView\n"); - } - - CORBA_exception_free (&ev); - } - - if (book_view->priv->listener) { - if (book_view->priv->response_id) - g_signal_handler_disconnect(book_view->priv->listener, - book_view->priv->response_id); - e_book_view_listener_stop (book_view->priv->listener); - bonobo_object_unref (BONOBO_OBJECT(book_view->priv->listener)); - } - - g_free (book_view->priv); - book_view->priv = NULL; + if (view->priv->view_proxy) { + org_gnome_evolution_dataserver_addressbook_BookView_dispose (view->priv->view_proxy, NULL); + g_object_unref (view->priv->view_proxy); + view->priv->view_proxy = NULL; } - G_OBJECT_CLASS(parent_class)->dispose (object); + if (view->priv->book) { + g_object_unref (view->priv->book); + view->priv->book = NULL; + } } static void @@ -307,84 +272,43 @@ e_book_view_class_init (EBookViewClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - e_book_view_signals [CONTACTS_CHANGED] = - g_signal_new ("contacts_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookViewClass, contacts_changed), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - e_book_view_signals [CONTACTS_ADDED] = - g_signal_new ("contacts_added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookViewClass, contacts_added), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - e_book_view_signals [CONTACTS_REMOVED] = - g_signal_new ("contacts_removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookViewClass, contacts_removed), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - e_book_view_signals [SEQUENCE_COMPLETE] = - g_signal_new ("sequence_complete", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookViewClass, sequence_complete), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - - e_book_view_signals [STATUS_MESSAGE] = - g_signal_new ("status_message", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookViewClass, status_message), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); + g_type_class_add_private (klass, sizeof (EBookViewPrivate)); + + signals [CONTACTS_CHANGED] = g_signal_new ("contacts_changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EBookViewClass, contacts_changed), + NULL, NULL, + e_book_marshal_NONE__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + signals [CONTACTS_REMOVED] = g_signal_new ("contacts_removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EBookViewClass, contacts_removed), + NULL, NULL, + e_book_marshal_NONE__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + signals [CONTACTS_ADDED] = g_signal_new ("contacts_added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EBookViewClass, contacts_added), + NULL, NULL, + e_book_marshal_NONE__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + signals [SEQUENCE_COMPLETE] = g_signal_new ("sequence_complete", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EBookViewClass, sequence_complete), + NULL, NULL, + e_book_marshal_NONE__INT, + G_TYPE_NONE, 1, G_TYPE_INT); + signals [STATUS_MESSAGE] = g_signal_new ("status_message", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EBookViewClass, status_message), + NULL, NULL, + e_book_marshal_NONE__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); object_class->dispose = e_book_view_dispose; } - -/** - * e_book_view_get_type: - */ -GType -e_book_view_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (EBookViewClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) e_book_view_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EBookView), - 0, /* n_preallocs */ - (GInstanceInitFunc) e_book_view_init - }; - - type = g_type_register_static (G_TYPE_OBJECT, "EBookView", &info, 0); - } - - return type; -} diff --git a/addressbook/libebook/e-book.c b/addressbook/libebook/e-book.c index f604adb6c..3939b2bf5 100644 --- a/addressbook/libebook/e-book.c +++ b/addressbook/libebook/e-book.c @@ -1,81 +1,53 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * Copyright (C) 2006 OpenedHand Ltd + * Copyright (C) 2009 Intel Corporation + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of version 2.1 of the GNU Lesser General Public License as + * published by the Free Software Foundation. + * + * This library 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 Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Ross Burton <ross@linux.intel.com> + */ #include <config.h> - +#include <unistd.h> #include <string.h> - +#include <glib-object.h> +#include <glib/gi18n-lib.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> #include "e-book.h" +#include "e-error.h" +#include "e-contact.h" #include "e-book-view-private.h" -#include "e-vcard.h" +#include "e-data-book-factory-bindings.h" +#include "e-data-book-bindings.h" +#include "libedata-book/e-data-book-types.h" +#include "e-book-marshal.h" -#include <bonobo-activation/bonobo-activation.h> +#define E_DATA_BOOK_FACTORY_SERVICE_NAME "org.gnome.evolution.dataserver.AddressBook" -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-main.h> -#include <gconf/gconf-client.h> +static char** flatten_stringlist(GList *list); +static GList *array_to_stringlist (char **list); +static gboolean unwrap_gerror(GError *error, GError **client_error); +static EBookStatus get_status_from_error (GError *error); + +G_DEFINE_TYPE(EBook, e_book, G_TYPE_OBJECT) +#define E_BOOK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_BOOK, EBookPrivate)) -#include <glib/gi18n-lib.h> -#include "libedataserver/e-flag.h" -#include "libedataserver/e-component-listener.h" - -#include "e-book-listener.h" - -#define d(x) - -GMainContext *_ebook_context; - -static GObjectClass *parent_class; - -#ifdef __PRETTY_FUNCTION__ -#define e_return_error_if_fail(expr,error_code,retval) 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 (retval); \ - }; }G_STMT_END -#else -#define e_return_error_if_fail(expr,error_code,retval) G_STMT_START{ \ - if G_LIKELY(expr) { } else \ - { \ - g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_CRITICAL, \ - "file %s: line %d: assertion `%s' failed", \ - __FILE__, \ - __LINE__, \ - #expr); \ - g_set_error (error, E_BOOK_ERROR, (error_code), \ - "file %s: line %d: assertion `%s' failed", \ - __FILE__, \ - __LINE__, \ - #expr); \ - return (retval); \ - }; }G_STMT_END -#endif - -/* 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, CONNECTION_STATUS, AUTH_REQUIRED, @@ -85,279 +57,224 @@ enum { static guint e_book_signals [LAST_SIGNAL]; -typedef enum { - STATE_WAITING, - STATE_PROCESSING, - STATE_CANCELLING -} EBookOpState; - -typedef struct { - gint32 opid; - EBookOpState opstate; - gint idle_id; - gboolean synchronous; - EFlag *flag; - EBook *book; - EBookStatus status; - gchar *id; - GList *list; - EList *elist; - EContact *contact; - - EBookView *view; - EBookViewListener *listener; - - /* callbacks/closure for async calls */ - union { - EBookIdCallback id; - EBookCallback status; - EBookContactCallback contact; - EBookListCallback list; - EBookBookViewCallback book_view; - EBookEListCallback elist; - } cb; - gpointer closure; -} EBookOp; - -typedef enum { - E_BOOK_SOURCE_NOT_LOADED, - E_BOOK_SOURCE_LOADING, - E_BOOK_SOURCE_LOADED -} EBookLoadState; - struct _EBookPrivate { - /* cached capabilites */ - gchar *cap; - gboolean cap_queried; - - /* cached writable status */ + ESource *source; + char *uri; + DBusGProxy *proxy; + gboolean loaded; gboolean writable; gboolean connected; + char *cap; + gboolean cap_queried; +}; - EBookListener *listener; - EComponentListener *comp_listener; - - GNOME_Evolution_Addressbook_Book corba_book; - - EBookLoadState load_state; - - GList *pending_idles; - GHashTable *id_to_op; - guint32 current_op_id; - - GMutex *mutex; - - /* Need to keep URI around, since the getter returns const */ - gchar *uri; - ESource *source; - - gulong listener_signal; - gulong died_signal; +static DBusGConnection *connection = NULL; +static DBusGProxy *factory_proxy = NULL; - gint writable_idle_id; - gint connection_idle_id; - gint auth_idle_id; -}; +typedef struct { + EBook *book; + void *callback; /* TODO union */ + gpointer closure; + gpointer data; +} AsyncData; - -/* 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"); + static GQuark q = 0; + if (q == 0) + q = g_quark_from_static_string ("e-book-error-quark"); - return q; + return q; } - - -/* EBookOp calls */ - -static EBookOp* -e_book_new_op (EBook *book, gboolean sync) +/* + * Called when the addressbook server dies. + */ +static void +proxy_destroyed (gpointer data, GObject *object) { - EBookOp *op = g_new0 (EBookOp, 1); + EBook *book = data; - op->flag = e_flag_new (); - op->opstate = STATE_WAITING; + g_assert (E_IS_BOOK (book)); - op->synchronous = sync; - if (sync) - op->opid = 0; - else - op->opid = book->priv->current_op_id++; + g_warning (G_STRLOC ": e-d-s proxy died"); - g_hash_table_insert (book->priv->id_to_op, - &op->opid, op); + /* Ensure that everything relevant is NULL */ + factory_proxy = NULL; + book->priv->proxy = NULL; - return op; + g_signal_emit (G_OBJECT (book), e_book_signals [BACKEND_DIED], 0); } -static EBookOp* -e_book_get_op (EBook *book, gint opid) -{ - return (EBookOp*)g_hash_table_lookup (book->priv->id_to_op, - &opid); -} - -static EBookOp* -e_book_get_current_sync_op (EBook *book) -{ - return e_book_get_op (book, 0); -} - -static EBookOp * -e_book_find_op (EBook *book, guint32 opid, const gchar *func_name) +static void +e_book_dispose (GObject *object) { - EBookOp *op; + EBook *book = E_BOOK (object); - op = e_book_get_op (book, opid); + book->priv->loaded = FALSE; - if (op == NULL) { - g_warning ("%s: Cannot find operation", func_name); - } else if (op->opstate != STATE_WAITING) { - /* returns only operations, which are waiting */ - op = NULL; - } else { - /* set opstate to processing, thus it will not be canceled meanwhile */ - op->opstate = STATE_PROCESSING; + if (book->priv->proxy) { + g_object_weak_unref (G_OBJECT (book->priv->proxy), proxy_destroyed, book); + org_gnome_evolution_dataserver_addressbook_Book_close (book->priv->proxy, NULL); + } + if (book->priv->source) { + g_object_unref (book->priv->source); + book->priv->source = NULL; + } + if (book->priv->proxy) { + g_object_unref (book->priv->proxy); + book->priv->proxy = NULL; } - return op; + if (G_OBJECT_CLASS (e_book_parent_class)->dispose) + G_OBJECT_CLASS (e_book_parent_class)->dispose (object); } static void -e_book_op_free (EBookOp *op) +e_book_finalize (GObject *object) { - e_flag_free (op->flag); - g_free (op); + EBook *book = E_BOOK (object); + + if (book->priv->uri) + g_free (book->priv->uri); + + if (book->priv->cap) + g_free (book->priv->cap); + + if (G_OBJECT_CLASS (e_book_parent_class)->finalize) + G_OBJECT_CLASS (e_book_parent_class)->finalize (object); } static void -e_book_op_remove (EBook *book, - EBookOp *op) +e_book_class_init (EBookClass *e_book_class) { - g_hash_table_remove (book->priv->id_to_op, - &op->opid); - - if (op->idle_id && g_list_find (book->priv->pending_idles, GINT_TO_POINTER (op->idle_id))) { - book->priv->pending_idles = g_list_remove (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - g_source_remove (op->idle_id); - op->idle_id = 0; - } + GObjectClass *gobject_class = G_OBJECT_CLASS (e_book_class); + + e_book_signals [WRITABLE_STATUS] = + g_signal_new ("writable_status", + G_OBJECT_CLASS_TYPE (gobject_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 [CONNECTION_STATUS] = + g_signal_new ("connection_status", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EBookClass, connection_status), + NULL, NULL, + e_book_marshal_NONE__BOOL, + G_TYPE_NONE, 1, + G_TYPE_BOOLEAN); + + e_book_signals [AUTH_REQUIRED] = + g_signal_new ("auth_required", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EBookClass, auth_required), + NULL, NULL, + e_book_marshal_NONE__NONE, + G_TYPE_NONE, 0); + + e_book_signals [BACKEND_DIED] = + g_signal_new ("backend_died", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EBookClass, backend_died), + NULL, NULL, + e_book_marshal_NONE__NONE, + G_TYPE_NONE, 0); + + gobject_class->dispose = e_book_dispose; + gobject_class->finalize = e_book_finalize; + + g_type_class_add_private (e_book_class, sizeof (EBookPrivate)); } static void -e_book_clear_op (EBook *book, - EBookOp *op) +e_book_init (EBook *book) { - e_book_op_remove (book, op); - e_flag_clear (op->flag); - e_book_op_free (op); + EBookPrivate *priv = E_BOOK_GET_PRIVATE (book); + priv->source = NULL; + priv->uri = NULL; + priv->proxy = NULL; + priv->loaded = FALSE; + priv->writable = FALSE; + priv->connected = FALSE; + priv->cap = NULL; + priv->cap_queried = FALSE; + book->priv = priv; } static gboolean -do_add_contact (gboolean sync, - EBook *book, - EContact *contact, - GError **error, /* for sync case */ - EBookIdCallback cb, /* for async case */ - gpointer closure) +e_book_activate(GError **error) { - EBookOp *our_op; - EBookStatus status; - CORBA_Environment ev; - gchar *vcard_str; - - d(printf ("do_add_contact\n")); - - g_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_SOURCE_LOADED) { - g_mutex_unlock (book->priv->mutex); - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_SOURCE_NOT_LOADED, - /* translators: the placeholders will be filled by - * function names, e.g. - * "e_book_add_contact" on book before - * "e_book_open */ - _("\"%s\" on book before \"%s\""), - "e_book_add_contact", "e_book_open"); - } - else { - g_warning (_("\"%s\" on book before \"%s\""), - "e_book_add_contact", "e_book_open"); - } - return FALSE; - } + DBusError derror; - if (sync && e_book_get_current_sync_op (book) != NULL) { - g_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - return FALSE; + if (G_LIKELY (factory_proxy)) { + return TRUE; } - our_op = e_book_new_op (book, sync); - - g_mutex_unlock (book->priv->mutex); - - vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); - - CORBA_exception_init (&ev); - - our_op->cb.id = cb; - our_op->closure = closure; + if (!connection) { + connection = dbus_g_bus_get (DBUS_BUS_SESSION, error); + if (!connection) + return FALSE; + } - /* will eventually end up calling e_book_response_add_contact */ - GNOME_Evolution_Addressbook_Book_addContact (book->priv->corba_book, our_op->opid, - (const GNOME_Evolution_Addressbook_VCard) vcard_str, &ev); + dbus_error_init (&derror); + if (!dbus_bus_start_service_by_name (dbus_g_connection_get_connection (connection), + E_DATA_BOOK_FACTORY_SERVICE_NAME, + 0, NULL, &derror)) { + dbus_set_g_error (error, &derror); + dbus_error_free (&derror); + return FALSE; + } - g_free (vcard_str); + if (!factory_proxy) { + factory_proxy = dbus_g_proxy_new_for_name_owner (connection, + E_DATA_BOOK_FACTORY_SERVICE_NAME, + "/org/gnome/evolution/dataserver/addressbook/BookFactory", + "org.gnome.evolution.dataserver.addressbook.BookFactory", + error); + if (!factory_proxy) { + return FALSE; + } + g_object_add_weak_pointer (G_OBJECT (factory_proxy), (gpointer)&factory_proxy); + } - if (ev._major != CORBA_NO_EXCEPTION) { + return TRUE; +} - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); +static void +writable_cb (DBusGProxy *proxy, gboolean writable, EBook *book) +{ + g_return_if_fail (E_IS_BOOK (book)); - CORBA_exception_free (&ev); + book->priv->writable = writable; - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::addContact"); - } - else { - g_warning (_("CORBA exception making \"%s\" call"), - "Book::addContact"); - } - return FALSE; - } + g_signal_emit (G_OBJECT (book), e_book_signals [WRITABLE_STATUS], 0, writable); +} - CORBA_exception_free (&ev); +static void +connection_cb (DBusGProxy *proxy, gboolean connected, EBook *book) +{ + g_return_if_fail (E_IS_BOOK (book)); - if (sync) { - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_flag_wait (our_op->flag); + book->priv->connected = connected; - status = our_op->status; - e_contact_set (contact, E_CONTACT_UID, our_op->id); - g_free (our_op->id); + g_signal_emit (G_OBJECT (book), e_book_signals [CONNECTION_STATUS], 0, connected); +} - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); +static void +auth_required_cb (DBusGProxy *proxy, EBook *book) +{ + g_return_if_fail (E_IS_BOOK (book)); - E_BOOK_CHECK_STATUS (status, error); - } - else { - return TRUE; - } + g_signal_emit (G_OBJECT (book), e_book_signals [AUTH_REQUIRED], 0); } /** @@ -375,14 +292,42 @@ e_book_add_contact (EBook *book, EContact *contact, GError **error) { - d(printf ("e_book_add_contact\n")); + GError *err = NULL; + char *vcard, *uid = NULL; + + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + e_return_error_if_fail (E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG); + + vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); + org_gnome_evolution_dataserver_addressbook_Book_add_contact (book->priv->proxy, vcard, &uid, &err); + g_free (vcard); + if (uid) { + e_contact_set (contact, E_CONTACT_UID, uid); + g_free (uid); + } + return unwrap_gerror (err, error); +} + +static void +add_contact_reply (DBusGProxy *proxy, char *uid, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + EBookIdCallback cb = data->callback; + + /* If there is an error returned the GLib bindings currently return garbage + for the OUT values. This is bad. */ + if (error) + uid = NULL; - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (contact && E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG, FALSE); + if (cb) + cb (data->book, get_status_from_error (error), uid, data->closure); - return do_add_contact (TRUE, - book, contact, error, - NULL, NULL); + if (uid) + g_free (uid); + + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -402,170 +347,23 @@ e_book_async_add_contact (EBook *book, EBookIdCallback cb, gpointer closure) { - d(printf ("e_book_async_add_contact\n")); - - g_return_val_if_fail (book && E_IS_BOOK (book), FALSE); - g_return_val_if_fail (contact && E_IS_CONTACT (contact), FALSE); - - return !do_add_contact (FALSE, - book, contact, NULL, - cb, closure); -} - -static gboolean -emit_async_add_contact_response (gpointer data) -{ - EBookOp *op = data; - EBook *book = op->book; - - if (op->cb.id) - op->cb.id (book, op->status, op->id, op->closure); - - g_mutex_lock (book->priv->mutex); - - g_free (op->id); + gchar *vcard; + AsyncData *data; - book->priv->pending_idles = g_list_remove (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); + e_return_async_error_val_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_val_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + e_return_async_error_val_if_fail (E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG); - e_book_clear_op (book, op); + vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); - g_mutex_unlock (book->priv->mutex); - g_object_unref (book); + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; - return FALSE; -} - -static void -e_book_response_add_contact (EBook *book, - guint32 opid, - EBookStatus status, - gchar *id) -{ - EBookOp *op; - - d(printf ("e_book_response_add_contact\n")); - - g_mutex_lock (book->priv->mutex); - - op = e_book_find_op (book, opid, G_STRFUNC); - - if (op == NULL) { - g_mutex_unlock (book->priv->mutex); - return; - } - - op->id = g_strdup (id); - op->status = status; - - if (op->synchronous) - e_flag_set (op->flag); - else { - op->book = g_object_ref (book); - - op->idle_id = g_idle_add (emit_async_add_contact_response, op); - book->priv->pending_idles = g_list_prepend (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - } - - g_mutex_unlock (book->priv->mutex); -} - - - -static gboolean -do_commit_contact (gboolean sync, - EBook *book, - EContact *contact, - GError **error, - EBookCallback cb, - gpointer closure) -{ - EBookOp *our_op; - EBookStatus status; - CORBA_Environment ev; - gchar *vcard_str; - - g_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_SOURCE_LOADED) { - g_mutex_unlock (book->priv->mutex); - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_SOURCE_NOT_LOADED, - _("\"%s\" on book before \"%s\""), - "e_book_commit_contact", "e_book_open"); - } - else { - g_warning (_("\"%s\" on book before \"%s\""), - "e_book_commit_contact", "e_book_open"); - } - return FALSE; - } - - if (sync && e_book_get_current_sync_op (book) != NULL) { - g_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, sync); - - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - our_op->cb.status = cb; - our_op->closure = closure; - - /* will eventually end up calling _e_book_response_generic */ - GNOME_Evolution_Addressbook_Book_modifyContact (book->priv->corba_book, our_op->opid, - (const GNOME_Evolution_Addressbook_VCard) vcard_str, &ev); - - g_free (vcard_str); - - if (ev._major != CORBA_NO_EXCEPTION) { - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_free (&ev); - - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::modifyContact"); - } - else { - g_warning (_("CORBA exception making \"%s\" call"), - "Book::modifyContact"); - } - return FALSE; - } - - CORBA_exception_free (&ev); - - if (sync) { - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_flag_wait (our_op->flag); - - status = our_op->status; - g_free (our_op->id); - - /* remove the op from the book's hash of operations */ - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - E_BOOK_CHECK_STATUS (status, error); - } - else { - return TRUE; - } + org_gnome_evolution_dataserver_addressbook_Book_add_contact_async (book->priv->proxy, vcard, add_contact_reply, data); + g_free (vcard); + return 0; } /** @@ -584,13 +382,30 @@ e_book_commit_contact (EBook *book, EContact *contact, GError **error) { - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (contact && E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG, FALSE); + GError *err = NULL; + gchar *vcard; + + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + e_return_error_if_fail (E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG); + + vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); + org_gnome_evolution_dataserver_addressbook_Book_modify_contact (book->priv->proxy, vcard, &err); + g_free (vcard); + return unwrap_gerror (err, error); +} + +static void +modify_contact_reply (DBusGProxy *proxy, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + EBookCallback cb = data->callback; - return do_commit_contact (TRUE, - book, contact, error, - NULL, NULL); + if (cb) + cb (data->book, get_status_from_error (error), data->closure); + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -611,190 +426,25 @@ e_book_async_commit_contact (EBook *book, EBookCallback cb, gpointer closure) { - return !do_commit_contact (FALSE, - book, contact, NULL, - cb, closure); -} - -static gboolean -do_get_required_fields (gboolean sync, - EBook *book, - GList **fields, - GError **error, - EBookEListCallback cb, - gpointer closure) -{ - EBookOp *our_op; - EBookStatus status; - CORBA_Environment ev; - - g_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_SOURCE_LOADED) { - g_mutex_unlock (book->priv->mutex); - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_SOURCE_NOT_LOADED, - _("\"%s\" on book before \"%s\""), - "e_book_get_required_fields", "e_book_open"); - } - else { - g_warning (_("\"%s\" on book before \"%s\""), - "e_book_get_required_fields", "e_book_open"); - } - return FALSE; - } - - if (sync && e_book_get_current_sync_op (book) != NULL) { - g_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, sync); - - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - our_op->cb.elist = cb; - our_op->closure = closure; - - /* will eventually end up calling - _e_book_response_get_supported_fields */ - GNOME_Evolution_Addressbook_Book_getRequiredFields(book->priv->corba_book, our_op->opid, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_free (&ev); - - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::getRequiredFields"); - } - else { - g_warning (_("CORBA exception making \"%s\" call"), - "Book::getRequiredFields"); - } - - return FALSE; - } - - CORBA_exception_free (&ev); + char *vcard; + AsyncData *data; - if (sync) { - /* wait for something to happen (both cancellation and a - successful response will notify us via our cv */ - e_flag_wait (our_op->flag); + e_return_async_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + e_return_async_error_if_fail (E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG); - status = our_op->status; - *fields = our_op->list; + vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; - E_BOOK_CHECK_STATUS (status, error); - } - else { - return TRUE; - } + org_gnome_evolution_dataserver_addressbook_Book_modify_contact_async (book->priv->proxy, vcard, modify_contact_reply, data); + g_free (vcard); + return 0; } -static gboolean -do_get_supported_fields (gboolean sync, - EBook *book, - GList **fields, - GError **error, - EBookEListCallback cb, - gpointer closure) -{ - EBookOp *our_op; - EBookStatus status; - CORBA_Environment ev; - - g_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_SOURCE_LOADED) { - g_mutex_unlock (book->priv->mutex); - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_SOURCE_NOT_LOADED, - _("\"%s\" on book before \"%s\""), - "e_book_get_supported_fields", "e_book_open"); - } - else { - g_warning (_("\"%s\" on book before \"%s\""), - "e_book_get_supported_fields", "e_book_open"); - } - return FALSE; - } - - if (sync && e_book_get_current_sync_op (book) != NULL) { - g_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, sync); - - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - our_op->cb.elist = cb; - our_op->closure = closure; - - /* will eventually end up calling - _e_book_response_get_supported_fields */ - GNOME_Evolution_Addressbook_Book_getSupportedFields(book->priv->corba_book, our_op->opid, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_free (&ev); - - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::getSupportedFields"); - } - else { - g_warning (_("CORBA exception making \"%s\" call"), - "Book::getSupportedFields"); - } - - return FALSE; - } - - CORBA_exception_free (&ev); - - if (sync) { - /* wait for something to happen (both cancellation and a - successful response will notify us via our cv */ - e_flag_wait (our_op->flag); - - status = our_op->status; - *fields = our_op->list; - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - E_BOOK_CHECK_STATUS (status, error); - } - else { - return TRUE; - } -} /** * e_book_get_required_fields: @@ -814,12 +464,42 @@ e_book_get_required_fields (EBook *book, GList **fields, GError **error) { - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (fields, E_BOOK_ERROR_INVALID_ARG, FALSE); + GError *err = NULL; + char **list = NULL; + + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + + org_gnome_evolution_dataserver_addressbook_Book_get_required_fields (book->priv->proxy, &list, &err); + if (list) { + *fields = array_to_stringlist (list); + return TRUE; + } else { + return unwrap_gerror (err, error); + } +} + +static void +get_required_fields_reply(DBusGProxy *proxy, char **fields, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + EBookEListCallback cb = data->callback; + char **i = fields; + EList *efields = e_list_new (NULL, + (EListFreeFunc) g_free, + NULL); - return do_get_required_fields (TRUE, - book, fields, error, - NULL, NULL); + while (*i != NULL) { + e_list_append (efields, (*i++)); + } + + if (cb) + cb (data->book, get_status_from_error (error), efields, data->closure); + + g_object_unref (efields); + g_free (fields); + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -838,11 +518,18 @@ e_book_async_get_required_fields (EBook *book, EBookEListCallback cb, gpointer closure) { - g_return_val_if_fail (E_IS_BOOK (book), FALSE); + AsyncData *data; + + e_return_async_error_val_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_val_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); - return !do_get_required_fields (FALSE, - book, NULL, NULL, - cb, closure); + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; + + org_gnome_evolution_dataserver_addressbook_Book_get_required_fields_async (book->priv->proxy, get_required_fields_reply, data); + return 0; } /** @@ -863,12 +550,41 @@ e_book_get_supported_fields (EBook *book, GList **fields, GError **error) { - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (fields, E_BOOK_ERROR_INVALID_ARG, FALSE); + GError *err = NULL; + char **list = NULL; + + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + + org_gnome_evolution_dataserver_addressbook_Book_get_supported_fields (book->priv->proxy, &list, &err); + if (list) { + *fields = array_to_stringlist (list); + return TRUE; + } else { + return unwrap_gerror (err, error); + } +} + +static void +get_supported_fields_reply(DBusGProxy *proxy, char **fields, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + EBookEListCallback cb = data->callback; + char **i = fields; + EList *efields = e_list_new (NULL, (EListFreeFunc) g_free, NULL); + + while (*i != NULL) { + e_list_append (efields, (*i++)); + } + + if (cb) + cb (data->book, get_status_from_error (error), efields, data->closure); + + g_object_unref (efields); + g_free (fields); - return do_get_supported_fields (TRUE, - book, fields, error, - NULL, NULL); + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -888,208 +604,18 @@ e_book_async_get_supported_fields (EBook *book, EBookEListCallback cb, gpointer closure) { - g_return_val_if_fail (E_IS_BOOK (book), FALSE); - - return !do_get_supported_fields (FALSE, - book, NULL, NULL, - cb, closure); -} - -static gboolean -emit_async_elist_response (gpointer data) -{ - EBookOp *op = data; - EBook *book = op->book; - - if (op->cb.elist) - op->cb.elist (book, op->status, op->elist, op->closure); - - g_mutex_lock (book->priv->mutex); - - g_object_unref (op->elist); - - book->priv->pending_idles = g_list_remove (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); + AsyncData *data; - e_book_clear_op (book, op); + e_return_async_error_val_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_val_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); - g_mutex_unlock (book->priv->mutex); - g_object_unref (book); + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; - return FALSE; -} - -static void -e_book_response_get_required_fields (EBook *book, - guint32 opid, - EBookStatus status, - GList *fields) - -{ - EBookOp *op; - - g_mutex_lock (book->priv->mutex); - - op = e_book_find_op (book, opid, G_STRFUNC); - - if (op == NULL) { - g_mutex_unlock (book->priv->mutex); - return; - } - - op->status = status; - if (op->synchronous) { - op->list = fields; - e_flag_set (op->flag); - } else { - GList *l; - EList *efields = e_list_new ((EListCopyFunc) g_strdup, - (EListFreeFunc) g_free, - NULL); - - for (l = fields; l; l = l->next) - e_list_append (efields, l->data); - - op->book = g_object_ref (book); - op->elist = efields; - - op->idle_id = g_idle_add (emit_async_elist_response, op); - book->priv->pending_idles = g_list_prepend (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - } - - g_mutex_unlock (book->priv->mutex); -} - -static void -e_book_response_get_supported_fields (EBook *book, - guint32 opid, - EBookStatus status, - GList *fields) -{ - EBookOp *op; - - g_mutex_lock (book->priv->mutex); - - op = e_book_find_op (book, opid, G_STRFUNC); - - if (op == NULL) { - g_mutex_unlock (book->priv->mutex); - return; - } - - op->status = status; - if (op->synchronous) { - op->list = fields; - e_flag_set (op->flag); - } else { - GList *l; - EList *efields = e_list_new ((EListCopyFunc) g_strdup, - (EListFreeFunc) g_free, - NULL); - - for (l = fields; l; l = l->next) - e_list_append (efields, l->data); - - op->book = g_object_ref (book); - op->elist = efields; - - op->idle_id = g_idle_add (emit_async_elist_response, op); - book->priv->pending_idles = g_list_prepend (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - } - - g_mutex_unlock (book->priv->mutex); -} - - -static gboolean -do_get_supported_auth_methods (gboolean sync, - EBook *book, - GList **auth_methods, - GError **error, - EBookEListCallback cb, - gpointer closure) -{ - EBookOp *our_op; - EBookStatus status; - CORBA_Environment ev; - - g_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_SOURCE_LOADED) { - g_mutex_unlock (book->priv->mutex); - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_SOURCE_NOT_LOADED, - _("\"%s\" on book before \"%s\""), - "e_book_get_supported_auth_methods", - "e_book_open"); - } - else { - g_warning (_("\"%s\" on book before \"%s\""), - "e_book_get_supported_auth_methods", - "e_book_open"); - } - return FALSE; - } - - if (sync && e_book_get_current_sync_op (book) != NULL) { - g_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, sync); - - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - our_op->cb.elist = cb; - our_op->closure = closure; - - /* will eventually end up calling - e_book_response_get_supported_fields */ - GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods(book->priv->corba_book, our_op->opid, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_free (&ev); - - if (error) - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::getSupportedAuthMethods"); - else - g_warning (_("CORBA exception making \"%s\" call"), - "Book::getSupportedAuthMethods"); - return FALSE; - } - - CORBA_exception_free (&ev); - - if (sync) { - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_flag_wait (our_op->flag); - - status = our_op->status; - *auth_methods = our_op->list; - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - E_BOOK_CHECK_STATUS (status, error); - } - else { - return TRUE; - } + org_gnome_evolution_dataserver_addressbook_Book_get_supported_fields_async (book->priv->proxy, get_supported_fields_reply, data); + return 0; } /** @@ -1109,12 +635,43 @@ e_book_get_supported_auth_methods (EBook *book, GList **auth_methods, GError **error) { - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (auth_methods, E_BOOK_ERROR_INVALID_ARG, FALSE); + GError *err = NULL; + char **list = NULL; + + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); - return do_get_supported_auth_methods (TRUE, - book, auth_methods, error, - NULL, NULL); + org_gnome_evolution_dataserver_addressbook_Book_get_supported_auth_methods (book->priv->proxy, &list, &err); + if (list) { + *auth_methods = array_to_stringlist (list); + return TRUE; + } else { + return unwrap_gerror (err, error); + } +} + +static void +get_supported_auth_methods_reply(DBusGProxy *proxy, char **methods, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + EBookEListCallback cb = data->callback; + char **i = methods; + EList *emethods = e_list_new (NULL, + (EListFreeFunc) g_free, + NULL); + + while (*i != NULL) { + e_list_append (emethods, (*i++)); + } + + if (cb) + cb (data->book, get_status_from_error (error), emethods, data->closure); + + g_object_unref (emethods); + g_free (methods); + + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -1127,154 +684,25 @@ e_book_get_supported_auth_methods (EBook *book, * This function does not block. * * Return value: %TRUE if successful, %FALSE otherwise. - **/ +**/ guint e_book_async_get_supported_auth_methods (EBook *book, EBookEListCallback cb, gpointer closure) { - g_return_val_if_fail (book && E_IS_BOOK (book), TRUE); - - return !do_get_supported_auth_methods (FALSE, - book, NULL, NULL, - cb, closure); -} - -static void -e_book_response_get_supported_auth_methods (EBook *book, - guint32 opid, - EBookStatus status, - GList *auth_methods) -{ - EBookOp *op; - - g_mutex_lock (book->priv->mutex); - - op = e_book_find_op (book, opid, G_STRFUNC); - - if (op == NULL) { - g_mutex_unlock (book->priv->mutex); - return; - } - - op->status = status; - if (op->synchronous) { - op->list = auth_methods; - e_flag_set (op->flag); - } else { - GList *l; - EList *emethods = e_list_new ((EListCopyFunc) g_strdup, - (EListFreeFunc) g_free, - NULL); - - for (l = auth_methods; l; l = l->next) - e_list_append (emethods, l->data); - - op->book = g_object_ref (book); - op->elist = emethods; - - op->idle_id = g_idle_add (emit_async_elist_response, op); - book->priv->pending_idles = g_list_prepend (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - } - - g_mutex_unlock (book->priv->mutex); -} - - - -static gboolean -do_authenticate_user (gboolean sync, - EBook *book, - const gchar *user, - const gchar *passwd, - const gchar *auth_method, - GError **error, - EBookCallback cb, - gpointer closure) -{ - EBookOp *our_op; - EBookStatus status; - CORBA_Environment ev; - - g_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_SOURCE_LOADED) { - g_mutex_unlock (book->priv->mutex); - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_SOURCE_NOT_LOADED, - _("\"%s\" on book before \"%s\""), - "e_book_authenticate_user", "e_book_open"); - } - else { - g_warning (_("\"%s\" on book before \"%s\""), - "e_book_authenticate_user", "e_book_open"); - } - - return FALSE; - } - - if (sync && e_book_get_current_sync_op (book) != NULL) { - g_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, sync); - - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - our_op->cb.status = cb; - our_op->closure = closure; - - /* will eventually end up calling - e_book_response_generic */ - GNOME_Evolution_Addressbook_Book_authenticateUser (book->priv->corba_book, our_op->opid, - user, passwd, - auth_method, - &ev); + AsyncData *data; - if (ev._major != CORBA_NO_EXCEPTION) { + e_return_async_error_val_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_val_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; - CORBA_exception_free (&ev); - - if (error) - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::authenticateUser"); - else - g_warning (_("CORBA exception making \"%s\" call"), - "Book::authenticateUser"); - - return FALSE; - } - - CORBA_exception_free (&ev); - - if (sync) { - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_flag_wait (our_op->flag); - - status = our_op->status; - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - E_BOOK_CHECK_STATUS (status, error); - } - else { - return TRUE; - } -} + org_gnome_evolution_dataserver_addressbook_Book_get_supported_auth_methods_async (book->priv->proxy, get_supported_auth_methods_reply, data); + return 0; + } /** * e_book_authenticate_user: @@ -1297,14 +725,26 @@ e_book_authenticate_user (EBook *book, const gchar *auth_method, GError **error) { - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (user, E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (passwd, E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (auth_method, E_BOOK_ERROR_INVALID_ARG, FALSE); - - return do_authenticate_user (TRUE, - book, user, passwd, auth_method, error, - NULL, NULL); + GError *err = NULL; + + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + + org_gnome_evolution_dataserver_addressbook_Book_authenticate_user (book->priv->proxy, user, passwd, auth_method, &err); + return unwrap_gerror (err, error); +} + +static void +authenticate_user_reply(DBusGProxy *proxy, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + EBookCallback cb = data->callback; + + if (cb) + cb (data->book, get_status_from_error (error), data->closure); + + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -1331,107 +771,21 @@ e_book_async_authenticate_user (EBook *book, EBookCallback cb, gpointer closure) { - g_return_val_if_fail (book && E_IS_BOOK (book), TRUE); - g_return_val_if_fail (user, TRUE); - g_return_val_if_fail (passwd, TRUE); - g_return_val_if_fail (auth_method, TRUE); - - return !do_authenticate_user (FALSE, - book, user, passwd, auth_method, NULL, - cb, closure); -} - - - -static gboolean -do_get_contact (gboolean sync, - EBook *book, - const gchar *id, - EContact **contact, - GError **error, - EBookContactCallback cb, - gpointer closure) -{ - EBookOp *our_op; - EBookStatus status; - CORBA_Environment ev; - - g_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_SOURCE_LOADED) { - g_mutex_unlock (book->priv->mutex); - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_SOURCE_NOT_LOADED, - _("\"%s\" on book before \"%s\""), - "e_book_get_contact", "e_book_open"); - } - else { - g_warning (_("\"%s\" on book before \"%s\""), - "e_book_get_contact", "e_book_open"); - } - - return FALSE; - } - - if (sync && e_book_get_current_sync_op (book) != NULL) { - g_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_BUSY, - _("book busy")); - return FALSE; - } + AsyncData *data; - our_op = e_book_new_op (book, sync); + e_return_async_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + e_return_async_error_if_fail (user, E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_if_fail (passwd, E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_if_fail (auth_method, E_BOOK_ERROR_INVALID_ARG); - g_mutex_unlock (book->priv->mutex); + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; - CORBA_exception_init (&ev); - - our_op->cb.contact = cb; - our_op->closure = closure; - - /* will eventually end up calling e_book_response_generic */ - GNOME_Evolution_Addressbook_Book_getContact (book->priv->corba_book, our_op->opid, - (const GNOME_Evolution_Addressbook_VCard) id, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_free (&ev); - - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::getContact"); - } - else { - g_warning (_("CORBA exception making \"%s\" call"), - "Book::getContact"); - } - return FALSE; - } - - CORBA_exception_free (&ev); - - if (sync) { - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_flag_wait (our_op->flag); - - status = our_op->status; - *contact = our_op->contact; - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - E_BOOK_CHECK_STATUS (status, error); - } - else { - return TRUE; - } + org_gnome_evolution_dataserver_addressbook_Book_authenticate_user_async (book->priv->proxy, user, passwd, auth_method, authenticate_user_reply, data); + return 0; } /** @@ -1452,13 +806,46 @@ e_book_get_contact (EBook *book, EContact **contact, GError **error) { - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (id, E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (contact, E_BOOK_ERROR_INVALID_ARG, FALSE); + GError *err = NULL; + gchar *vcard = NULL; + + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); - return do_get_contact (TRUE, - book, id, contact, error, - NULL, NULL); + org_gnome_evolution_dataserver_addressbook_Book_get_contact (book->priv->proxy, id, &vcard, &err); + if (vcard) { + *contact = e_contact_new_from_vcard (vcard); + g_free (vcard); + } + return unwrap_gerror (err, error); +} + +static void +get_contact_reply(DBusGProxy *proxy, char *vcard, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + EBookContactCallback cb = data->callback; + EBookStatus status = get_status_from_error (error); + + /* Protect against garbage return values on error */ + if (error) + vcard = NULL; + + if (cb) { + if (error == NULL) { + cb (data->book, status, e_contact_new_from_vcard (vcard), data->closure); + } else { + cb (data->book, status, NULL, data->closure); + } + } else { + g_warning (G_STRLOC ": cannot get contact: %s", error->message); + } + + if (error) + g_error_free (error); + g_free (vcard); + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -1478,172 +865,19 @@ e_book_async_get_contact (EBook *book, EBookContactCallback cb, gpointer closure) { - g_return_val_if_fail (book && E_IS_BOOK (book), TRUE); - g_return_val_if_fail (id, TRUE); - - return !do_get_contact (FALSE, - book, id, NULL, NULL, - cb, closure); -} - -static gboolean -emit_async_get_contact_response (gpointer data) -{ - EBookOp *op = data; - EBook *book = op->book; - - if (op->cb.contact) - op->cb.contact (book, op->status, op->contact, op->closure); - - g_mutex_lock (book->priv->mutex); - - g_object_unref (op->contact); - - book->priv->pending_idles = g_list_remove (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); + AsyncData *data; - e_book_clear_op (book, op); + e_return_async_error_val_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_val_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + e_return_async_error_val_if_fail (id, E_BOOK_ERROR_INVALID_ARG); - g_mutex_unlock (book->priv->mutex); - g_object_unref (book); + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; - return FALSE; -} - -static void -e_book_response_get_contact (EBook *book, - guint32 opid, - EBookStatus status, - EContact *contact) -{ - EBookOp *op; - - d(printf ("e_book_response_get_contact\n")); - - g_mutex_lock (book->priv->mutex); - - op = e_book_find_op (book, opid, G_STRFUNC); - - if (op == NULL) { - g_mutex_unlock (book->priv->mutex); - return; - } - - op->status = status; - op->contact = contact; - - if (op->synchronous) - e_flag_set (op->flag); - else { - op->book = g_object_ref (book); - - op->idle_id = g_idle_add (emit_async_get_contact_response, op); - book->priv->pending_idles = g_list_prepend (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - } - - g_mutex_unlock (book->priv->mutex); -} - - -static gboolean -do_remove_contacts (gboolean sync, - EBook *book, - GList *ids, - GError **error, - EBookCallback cb, - gpointer closure) -{ - GNOME_Evolution_Addressbook_ContactIdList idlist; - CORBA_Environment ev; - GList *iter; - gint num_ids, i; - EBookOp *our_op; - EBookStatus status; - - g_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_SOURCE_LOADED) { - g_mutex_unlock (book->priv->mutex); - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_SOURCE_NOT_LOADED, - _("\"%s\" on book before \"%s\""), - "e_book_remove_contacts", "e_book_open"); - } - else { - g_warning (_("\"%s\" on book before \"%s\""), - "e_book_remove_contacts", "e_book_open"); - } - return FALSE; - } - - if (sync && e_book_get_current_sync_op (book) != NULL) { - g_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, sync); - - g_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); - - our_op->cb.status = cb; - our_op->closure = closure; - - /* will eventually end up calling e_book_response_generic */ - GNOME_Evolution_Addressbook_Book_removeContacts (book->priv->corba_book, our_op->opid, &idlist, &ev); - - CORBA_free(idlist._buffer); - - if (ev._major != CORBA_NO_EXCEPTION) { - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_free (&ev); - - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::removeContacts"); - } - else { - g_warning (_("CORBA exception making \"%s\" call"), - "Book::removeContacts"); - } - return FALSE; - } - - CORBA_exception_free (&ev); - - if (sync) { - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_flag_wait (our_op->flag); - - status = our_op->status; - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - E_BOOK_CHECK_STATUS (status, error); - } - else { - return TRUE; - } + org_gnome_evolution_dataserver_addressbook_Book_get_contact_async (book->priv->proxy, id, get_contact_reply, data); + return 0; } /** @@ -1661,19 +895,31 @@ e_book_remove_contact (EBook *book, const gchar *id, GError **error) { - GList *list; - gboolean rv; + GError *err = NULL; + const gchar *l[2]; - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (id, E_BOOK_ERROR_INVALID_ARG, FALSE); + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + e_return_error_if_fail (id, E_BOOK_ERROR_INVALID_ARG); - list = g_list_append (NULL, (gchar *)id); + l[0] = id; + l[1] = NULL; - rv = e_book_remove_contacts (book, list, error); + org_gnome_evolution_dataserver_addressbook_Book_remove_contacts (book->priv->proxy, l, &err); + return unwrap_gerror (err, error); +} + +static void +remove_contact_reply (DBusGProxy *proxy, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + EBookCallback cb = data->callback; - g_list_free (list); + if (cb) + cb (data->book, get_status_from_error (error), data->closure); - return rv; + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -1694,12 +940,18 @@ e_book_remove_contacts (EBook *book, GList *ids, GError **error) { - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (ids, E_BOOK_ERROR_INVALID_ARG, FALSE); + GError *err = NULL; + char **l; + + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + e_return_error_if_fail (ids, E_BOOK_ERROR_INVALID_ARG); + + l = flatten_stringlist (ids); - return do_remove_contacts (TRUE, - book, ids, error, - NULL, NULL); + org_gnome_evolution_dataserver_addressbook_Book_remove_contacts (book->priv->proxy, (const char **) l, &err); + g_free (l); + return unwrap_gerror (err, error); } /** @@ -1719,14 +971,36 @@ e_book_async_remove_contact (EBook *book, EBookCallback cb, gpointer closure) { - const gchar *id; + AsyncData *data; + const gchar *l[2]; - g_return_val_if_fail (E_IS_BOOK (book), TRUE); - g_return_val_if_fail (E_IS_CONTACT (contact), TRUE); + e_return_async_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + e_return_async_error_if_fail (E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG); + + l[0] = e_contact_get_const (contact, E_CONTACT_UID); + l[1] = NULL; + + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; + + org_gnome_evolution_dataserver_addressbook_Book_remove_contacts_async (book->priv->proxy, l, remove_contact_reply, data); + return 0; + } + +static void +remove_contact_by_id_reply (DBusGProxy *proxy, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + EBookCallback cb = data->callback; - id = e_contact_get_const (contact, E_CONTACT_UID); + if (cb) + cb (data->book, get_status_from_error (error), data->closure); - return e_book_async_remove_contact_by_id (book, id, cb, closure); + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -1746,14 +1020,36 @@ e_book_async_remove_contact_by_id (EBook *book, EBookCallback cb, gpointer closure) { - GList *list; + AsyncData *data; + const gchar *l[2]; + + e_return_async_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + e_return_async_error_if_fail (id, E_BOOK_ERROR_INVALID_ARG); + + l[0] = id; + l[1] = NULL; + + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; + + org_gnome_evolution_dataserver_addressbook_Book_remove_contacts_async (book->priv->proxy, l, remove_contact_by_id_reply, data); + return 0; +} - g_return_val_if_fail (E_IS_BOOK (book), TRUE); - g_return_val_if_fail (id != NULL, TRUE); +static void +remove_contacts_reply (DBusGProxy *proxy, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + EBookCallback cb = data->callback; - list = g_list_append (NULL, g_strdup (id)); + if (cb) + cb (data->book, get_status_from_error (error), data->closure); - return e_book_async_remove_contacts (book, list, cb, closure); + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -1776,130 +1072,28 @@ e_book_async_remove_contacts (EBook *book, EBookCallback cb, gpointer closure) { - g_return_val_if_fail (book && E_IS_BOOK (book), TRUE); - g_return_val_if_fail (ids, TRUE); - - return !do_remove_contacts (FALSE, - book, ids, NULL, - cb, closure); -} - - -static gboolean -do_get_book_view (gboolean sync, - EBook *book, - EBookQuery *query, - GList *requested_fields, - gint max_results, - EBookView **book_view, - GError **error, - EBookBookViewCallback cb, - gpointer closure) -{ - GNOME_Evolution_Addressbook_stringlist stringlist; - CORBA_Environment ev; - EBookOp *our_op; - EBookStatus status; - gint num_fields, i; - GList *iter; - gchar *query_string; - - g_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_SOURCE_LOADED) { - g_mutex_unlock (book->priv->mutex); - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_SOURCE_NOT_LOADED, - _("\"%s\" on book before \"%s\""), - "e_book_get_book_view", "e_book_open"); - } - else { - g_warning (_("\"%s\" on book before \"%s\""), - "e_book_get_book_view", "e_book_open"); - } - return FALSE; - } - - if (sync && e_book_get_current_sync_op (book) != NULL) { - g_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, sync); - - g_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 ((gchar *)iter->data); - } - - query_string = e_book_query_to_string (query); + AsyncData *data; + gchar **l; - our_op->cb.book_view = cb; - our_op->closure = closure; + e_return_async_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); - /* will eventually end up calling e_book_response_get_book_view */ - GNOME_Evolution_Addressbook_Book_getBookView (book->priv->corba_book, - our_op->opid, - 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) { - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_free (&ev); - - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::authenticateUser"); - } - else { - g_warning (_("CORBA exception making \"%s\" call"), - "Book::authenticateUser"); - } - - return FALSE; + if (ids == NULL) { + if (cb) + cb (book, E_BOOK_ERROR_OK, closure); + return 0; } - CORBA_exception_free (&ev); - - if (sync) { - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_flag_wait (our_op->flag); + l = flatten_stringlist (ids); - status = our_op->status; - *book_view = our_op->view; + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - E_BOOK_CHECK_STATUS (status, error); - } - else { - return TRUE; - } + org_gnome_evolution_dataserver_addressbook_Book_remove_contacts_async (book->priv->proxy, (const char **) l, remove_contacts_reply, data); + g_free (l); + return 0; } /** @@ -1925,13 +1119,70 @@ e_book_get_book_view (EBook *book, EBookView **book_view, GError **error) { - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (query, E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (book_view, E_BOOK_ERROR_INVALID_ARG, FALSE); + GError *err = NULL; + DBusGProxy *view_proxy; + char *sexp, *view_path; + gboolean ret = TRUE; + + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + + sexp = e_book_query_to_string (query); + + if (!org_gnome_evolution_dataserver_addressbook_Book_get_book_view (book->priv->proxy, sexp, max_results, &view_path, &err)) { + *book_view = NULL; + g_free (sexp); + return unwrap_gerror (err, error); + } + view_proxy = dbus_g_proxy_new_for_name_owner (connection, + E_DATA_BOOK_FACTORY_SERVICE_NAME, view_path, + "org.gnome.evolution.dataserver.addressbook.BookView", error); + + if (view_proxy) { + *book_view = _e_book_view_new (book, view_proxy); + } else { + *book_view = NULL; + g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, + "Cannot get connection to view"); + ret = FALSE; + } + + g_free (view_path); + g_free (sexp); + + return ret; +} + +static void +get_book_view_reply (DBusGProxy *proxy, gchar *view_path, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + GError *err = NULL; + EBookView *view = NULL; + EBookBookViewCallback cb = data->callback; + DBusGProxy *view_proxy; + EBookStatus status; + + if (view_path) { + view_proxy = dbus_g_proxy_new_for_name_owner (connection, E_DATA_BOOK_FACTORY_SERVICE_NAME, view_path, + "org.gnome.evolution.dataserver.addressbook.BookView", &err); + if (view_proxy) { + view = _e_book_view_new (data->book, view_proxy); + status = E_BOOK_ERROR_OK; + } else { + g_warning (G_STRLOC ": cannot get connection to view: %s", err->message); + g_error_free (err); + status = E_BOOK_ERROR_CORBA_EXCEPTION; + } + } else { + status = get_status_from_error (error); + } - return do_get_book_view (TRUE, - book, query, requested_fields, max_results, book_view, error, - NULL, NULL); + if (cb) + cb (data->book, status, view, data->closure); + + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -1956,173 +1207,25 @@ e_book_async_get_book_view (EBook *book, EBookBookViewCallback cb, gpointer closure) { - g_return_val_if_fail (book && E_IS_BOOK (book), TRUE); - g_return_val_if_fail (query, TRUE); - - return !do_get_book_view (FALSE, - book, query, requested_fields, max_results, NULL, NULL, - cb, closure); -} + AsyncData *data; + gchar *sexp; -static gboolean -emit_async_get_book_view_response (gpointer data) -{ - EBookOp *op = data; - EBook *book = op->book; + e_return_async_error_val_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_val_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + e_return_async_error_val_if_fail (query, E_BOOK_ERROR_INVALID_ARG); - if (op->cb.book_view) - op->cb.book_view (book, op->status, op->view, op->closure); + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; - g_mutex_lock (book->priv->mutex); + sexp = e_book_query_to_string (query); - g_object_unref (op->view); + org_gnome_evolution_dataserver_addressbook_Book_get_book_view_async (book->priv->proxy, sexp, max_results, get_book_view_reply, data); - book->priv->pending_idles = g_list_remove (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - - e_book_clear_op (book, op); - - g_mutex_unlock (book->priv->mutex); - g_object_unref (book); - - return FALSE; -} - -static void -e_book_response_get_book_view (EBook *book, - guint32 opid, - EBookStatus status, - GNOME_Evolution_Addressbook_BookView corba_book_view) -{ - - EBookOp *op; - - d(printf ("e_book_response_get_book_view\n")); - - g_mutex_lock (book->priv->mutex); - - op = e_book_find_op (book, opid, G_STRFUNC); - - if (op == NULL) { - g_mutex_unlock (book->priv->mutex); - return; - } - - op->status = status; - op->view = e_book_view_new (corba_book_view, op->listener); - e_book_view_set_book (op->view, book); - - bonobo_object_unref(BONOBO_OBJECT(op->listener)); - - if (op->synchronous) - e_flag_set (op->flag); - else { - op->book = g_object_ref (book); - - op->idle_id = g_idle_add (emit_async_get_book_view_response, op); - book->priv->pending_idles = g_list_prepend (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - } - - g_mutex_unlock (book->priv->mutex); -} - -static gboolean -do_get_contacts (gboolean sync, - EBook *book, - EBookQuery *query, - GList **contacts, - GError **error, - EBookListCallback cb, - gpointer closure) -{ - CORBA_Environment ev; - EBookOp *our_op; - EBookStatus status; - gchar *query_string; - - g_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_SOURCE_LOADED) { - g_mutex_unlock (book->priv->mutex); - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_SOURCE_NOT_LOADED, - _("\"%s\" on book before \"%s\""), - "e_book_get_contacts", "e_book_open"); - } - else { - g_warning (_("\"%s\" on book before \"%s\""), - "e_book_get_contacts", "e_book_open"); - } - - return FALSE; - } - - if (sync && e_book_get_current_sync_op (book) != NULL) { - g_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, sync); - - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - query_string = e_book_query_to_string (query); - - our_op->cb.list = cb; - our_op->closure = closure; - - /* will eventually end up calling e_book_response_get_contacts */ - GNOME_Evolution_Addressbook_Book_getContactList (book->priv->corba_book, our_op->opid, query_string, &ev); - - g_free (query_string); - - if (ev._major != CORBA_NO_EXCEPTION) { - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_free (&ev); - - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::getContactList"); - } - else { - g_warning (_("CORBA exception making \"%s\" call"), - "Book::getContactList"); - } - - return FALSE; - } - - CORBA_exception_free (&ev); - - if (sync) { - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_flag_wait (our_op->flag); - - status = our_op->status; - *contacts = our_op->list; - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - E_BOOK_CHECK_STATUS (status, error); - } - else { - return TRUE; - } + g_free (sexp); + return 0; } - /** * e_book_get_contacts: * @book: an #EBook @@ -2141,13 +1244,50 @@ e_book_get_contacts (EBook *book, GList **contacts, GError **error) { - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (query, E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (contacts, E_BOOK_ERROR_INVALID_ARG, FALSE); + GError *err = NULL; + char **list = NULL; + char *sexp; + + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + + sexp = e_book_query_to_string (query); + org_gnome_evolution_dataserver_addressbook_Book_get_contact_list (book->priv->proxy, sexp, &list, &err); + g_free (sexp); + if (!err) { + GList *l = NULL; + char **i = list; + while (*i != NULL) { + l = g_list_prepend (l, e_contact_new_from_vcard (*i++)); + } + *contacts = g_list_reverse (l); + g_strfreev (list); + return TRUE; + } else { + return unwrap_gerror (err, error); + } +} - return do_get_contacts (TRUE, - book, query, contacts, error, - NULL, NULL); +static void +get_contacts_reply(DBusGProxy *proxy, char **vcards, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + GList *list = NULL; + EBookListCallback cb = data->callback; + if (vcards) { + char **i = vcards; + while (*i != NULL) { + list = g_list_prepend (list, e_contact_new_from_vcard (*i++)); + } + } + list = g_list_reverse (list); + + if (cb) + cb (data->book, get_status_from_error (error), list, data->closure); + g_strfreev (vcards); + + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -2167,162 +1307,52 @@ e_book_async_get_contacts (EBook *book, EBookListCallback cb, gpointer closure) { - g_return_val_if_fail (book && E_IS_BOOK (book), TRUE); - g_return_val_if_fail (query, TRUE); - - return !do_get_contacts (FALSE, - book, query, NULL, NULL, - cb, closure); -} - -static gboolean -emit_async_get_contacts_response (gpointer data) -{ - EBookOp *op = data; - EBook *book = op->book; - - if (op->cb.list) - op->cb.list (book, op->status, op->list, op->closure); - - g_mutex_lock (book->priv->mutex); - - g_list_foreach (op->list, (GFunc)g_object_unref, NULL); - g_list_free (op->list); + AsyncData *data; + gchar *sexp; - book->priv->pending_idles = g_list_remove (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); + e_return_async_error_val_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_val_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + e_return_async_error_val_if_fail (query, E_BOOK_ERROR_INVALID_ARG); - e_book_clear_op (book, op); + sexp = e_book_query_to_string (query); - g_mutex_unlock (book->priv->mutex); - g_object_unref (book); + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; - return FALSE; -} - -static void -e_book_response_get_contacts (EBook *book, - guint32 opid, - EBookStatus status, - GList *contact_list) -{ - - EBookOp *op; - - g_mutex_lock (book->priv->mutex); - - op = e_book_find_op (book, opid, G_STRFUNC); - - if (op == NULL) { - g_mutex_unlock (book->priv->mutex); - return; - } - - op->list = g_list_copy (contact_list); - g_list_foreach (op->list, (GFunc)g_object_ref, NULL); - op->status = status; - - if (op->synchronous) - e_flag_set (op->flag); - else { - op->book = g_object_ref (book); - op->idle_id = g_idle_add (emit_async_get_contacts_response, op); - book->priv->pending_idles = g_list_prepend (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - } - - g_mutex_unlock (book->priv->mutex); + org_gnome_evolution_dataserver_addressbook_Book_get_contact_list_async (book->priv->proxy, sexp, get_contacts_reply, data); + g_free (sexp); + return 0; } - -static gboolean -do_get_changes (gboolean sync, - EBook *book, - const gchar *changeid, - GList **changes, - GError **error, - EBookListCallback cb, - gpointer closure) +static GList * +parse_changes_array (GPtrArray *array) { - CORBA_Environment ev; - EBookOp *our_op; - EBookStatus status; + GList *l = NULL; + int i; - g_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_SOURCE_LOADED) { - g_mutex_unlock (book->priv->mutex); - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_SOURCE_NOT_LOADED, - _("\"%s\" on book before \"%s\""), - "e_book_get_changes", "e_book_open"); - } - else { - g_warning (_("\"%s\" on book before \"%s\""), - "e_book_get_changes", "e_book_open"); - } - return FALSE; - } - - if (sync && e_book_get_current_sync_op (book) != NULL) { - g_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, sync); - - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - our_op->cb.list = cb; - our_op->closure = closure; - - /* will eventually end up calling e_book_response_get_changes */ - GNOME_Evolution_Addressbook_Book_getChanges (book->priv->corba_book, our_op->opid, changeid, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { + if (array == NULL) + return NULL; - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); + for (i = 0; i < array->len; i++) { + EBookChange *change; + GValueArray *vals; - CORBA_exception_free (&ev); + vals = g_ptr_array_index (array, i); - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::getChanges"); - } - else { - g_warning (_("CORBA exception making \"%s\" call"), - "Book::getChanges"); - } + change = g_slice_new (EBookChange); + change->change_type = g_value_get_uint (g_value_array_get_nth (vals, 0)); + change->contact = e_contact_new_from_vcard + (g_value_get_string (g_value_array_get_nth (vals, 1))); - return FALSE; + l = g_list_prepend (l, change); } - CORBA_exception_free (&ev); - - if (sync) { - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_flag_wait (our_op->flag); - - status = our_op->status; - *changes = our_op->list; + g_ptr_array_foreach (array, (GFunc)g_value_array_free, NULL); + g_ptr_array_free (array, TRUE); - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - E_BOOK_CHECK_STATUS (status, error); - } - else { - return TRUE; - } + return g_list_reverse (l); } /** @@ -2343,13 +1373,36 @@ e_book_get_changes (EBook *book, GList **changes, GError **error) { - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (changeid, E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (changes, E_BOOK_ERROR_INVALID_ARG, FALSE); + GError *err = NULL; + GPtrArray *array = NULL; + + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + + org_gnome_evolution_dataserver_addressbook_Book_get_changes (book->priv->proxy, changeid, &array, &err); + if (!err) { + *changes = parse_changes_array (array); + return TRUE; + } else { + return unwrap_gerror (err, error); + } +} + +static void +get_changes_reply (DBusGProxy *proxy, GPtrArray *changes, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + EBookListCallback cb = data->callback; + GList *list = NULL; + + if (changes) + list = parse_changes_array (changes); + + if (cb) + cb (data->book, get_status_from_error (error), list, data->closure); - return do_get_changes (TRUE, - book, changeid, changes, error, - NULL, NULL); + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -2370,69 +1423,18 @@ e_book_async_get_changes (EBook *book, EBookListCallback cb, gpointer closure) { - g_return_val_if_fail (book && E_IS_BOOK (book), TRUE); - g_return_val_if_fail (changeid, TRUE); - - return !do_get_changes (FALSE, - book, changeid, NULL, NULL, - cb, closure); -} - -static gboolean -emit_async_get_changes_response (gpointer data) -{ - EBookOp *op = data; - EBook *book = op->book; + AsyncData *data; - if (op->cb.list) - op->cb.list (book, op->status, op->list, op->closure); + e_return_async_error_val_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_val_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); - g_mutex_lock (book->priv->mutex); + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; - e_book_free_change_list (op->list); - - book->priv->pending_idles = g_list_remove (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - - e_book_clear_op (book, op); - - g_mutex_unlock (book->priv->mutex); - g_object_unref (book); - - return FALSE; -} - -static void -e_book_response_get_changes (EBook *book, - guint32 opid, - EBookStatus status, - GList *change_list) -{ - - EBookOp *op; - - g_mutex_lock (book->priv->mutex); - - op = e_book_find_op (book, opid, G_STRFUNC); - - if (op == NULL) { - g_mutex_unlock (book->priv->mutex); - return; - } - - op->status = status; - op->list = change_list; - - if (op->synchronous) - e_flag_set (op->flag); - else { - op->book = g_object_ref (book); - op->idle_id = g_idle_add (emit_async_get_changes_response, op); - book->priv->pending_idles = g_list_prepend (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - } - - g_mutex_unlock (book->priv->mutex); + org_gnome_evolution_dataserver_addressbook_Book_get_changes_async (book->priv->proxy, changeid, get_changes_reply, data); + return 0; } /** @@ -2449,117 +1451,12 @@ e_book_free_change_list (GList *change_list) EBookChange *change = l->data; g_object_unref (change->contact); - g_free (change); + g_slice_free (EBookChange, change); } g_list_free (change_list); } - - -static gboolean -emit_async_generic_response (gpointer data) -{ - EBookOp *op = data; - EBook *book = op->book; - - if (op->cb.status) - op->cb.status (book, op->status, op->closure); - - g_mutex_lock (book->priv->mutex); - - book->priv->pending_idles = g_list_remove (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - - e_book_clear_op (book, op); - - g_mutex_unlock (book->priv->mutex); - g_object_unref (book); - - return FALSE; -} - -static void -e_book_response_generic (EBook *book, - guint32 opid, - EBookStatus status) -{ - EBookOp *op; - d(printf("e_book_response_generic\n")); - g_mutex_lock (book->priv->mutex); - - op = e_book_find_op (book, opid, G_STRFUNC); - - if (op == NULL) { - g_mutex_unlock (book->priv->mutex); - return; - } - - op->status = status; - if (op->synchronous) - e_flag_set (op->flag); - else { - op->book = g_object_ref (book); - op->idle_id = g_idle_add (emit_async_generic_response, op); - book->priv->pending_idles = g_list_prepend (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - } - - g_mutex_unlock (book->priv->mutex); -} - -static gboolean -do_cancel (EBook *book, GError **error, EBookOp *op, const gchar *func_name) -{ - EBookStatus status; - gboolean rv; - CORBA_Environment ev; - - if (op == NULL) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_COULD_NOT_CANCEL, - _("%s: there is no current operation"), func_name); - return FALSE; - } - - status = GNOME_Evolution_Addressbook_Book_cancelOperation(book->priv->corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - CORBA_exception_free (&ev); - - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::cancelOperation"); - e_flag_set (op->flag); - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, op); - g_mutex_unlock (book->priv->mutex); - return FALSE; - } - - CORBA_exception_free (&ev); - - if (status == E_BOOK_ERROR_OK) { - op->status = E_BOOK_ERROR_CANCELLED; - rv = TRUE; - } - else { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_COULD_NOT_CANCEL, - _("%s: could not cancel"), func_name); - rv = FALSE; - } - /* Always trigger the operation, we cannot put it back to queue, because - the result could come just few ticks before, in the other thread. */ - e_flag_set (op->flag); - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, op); - g_mutex_unlock (book->priv->mutex); - - return rv; -} - /** * e_book_cancel: * @book: an #EBook @@ -2581,25 +1478,10 @@ gboolean e_book_cancel (EBook *book, GError **error) { - EBookOp *op; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - - g_mutex_lock (book->priv->mutex); - op = e_book_get_current_sync_op (book); - if (op) { - if (op->opstate != STATE_WAITING) { - g_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_COULD_NOT_CANCEL, - _("%s: could not cancel"), G_STRFUNC); - return FALSE; - } - - op->opstate = STATE_CANCELLING; - } - g_mutex_unlock (book->priv->mutex); + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); - return do_cancel (book, error, op, "e_book_cancel"); + return org_gnome_evolution_dataserver_addressbook_Book_cancel_operation (book->priv->proxy, error); } /** @@ -2610,140 +1492,10 @@ e_book_cancel (EBook *book, gboolean e_book_cancel_async_op (EBook *book, GError **error) { - EBookOp *op; - guint32 opid; - - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - - g_mutex_lock (book->priv->mutex); + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); - /* find nearest unfinished async op to cancel */ - op = NULL; - for (opid = book->priv->current_op_id; opid > 0 && !op; opid--) { - op = e_book_get_op (book, opid); - - if (op && op->synchronous) - op = NULL; - } - - if (op) { - if (op->opstate != STATE_WAITING) { - g_mutex_unlock (book->priv->mutex); - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_COULD_NOT_CANCEL, - _("%s: could not cancel"), G_STRFUNC); - return FALSE; - } - - op->opstate = STATE_CANCELLING; - } - - g_mutex_unlock (book->priv->mutex); - - return do_cancel (book, error, op, "e_book_cancel_async_op"); -} - - - -static gboolean -do_open (gboolean sync, - EBook *book, - gboolean only_if_exists, - GError **error, - EBookCallback cb, - gpointer closure) -{ - CORBA_Environment ev; - EBookOp *our_op; - EBookStatus status; - - g_mutex_lock (book->priv->mutex); - - if (book->priv->load_state != E_BOOK_SOURCE_NOT_LOADED) { - g_mutex_unlock (book->priv->mutex); - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_SOURCE_ALREADY_LOADED, - _("\"%s\" on book after \"%s\""), - "e_book_open", "e_book_open"); - } - else { - g_warning (_("\"%s\" on book after \"%s\""), - "e_book_open", "e_book_open"); - } - - return FALSE; - } - - if (sync && e_book_get_current_sync_op (book) != NULL) { - g_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, sync); - - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - our_op->cb.status = cb; - our_op->closure = closure; - - /* will eventually end up calling e_book_response_remove */ - GNOME_Evolution_Addressbook_Book_open (book->priv->corba_book, our_op->opid, only_if_exists, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_free (&ev); - - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::open"); - } - else { - g_warning (_("CORBA exception making \"%s\" call"), - "Book::open"); - } - - return FALSE; - } - - CORBA_exception_free (&ev); - - if (sync) { - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_flag_wait (our_op->flag); - - status = our_op->status; - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - if (status == E_BOOK_ERROR_CANCELLED) { - /* Cancelled */ - book->priv->load_state = E_BOOK_SOURCE_NOT_LOADED; - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CANCELLED, - _("%s: canceled"), "e_book_open"); - return FALSE; - } - else if (status == E_BOOK_ERROR_OK) { - book->priv->load_state = E_BOOK_SOURCE_LOADED; - return TRUE; - } - else { - E_BOOK_CHECK_STATUS (status, error); - } - } - else { - return TRUE; - } + return org_gnome_evolution_dataserver_addressbook_Book_cancel_operation (book->priv->proxy, error); } /** @@ -2761,11 +1513,44 @@ e_book_open (EBook *book, gboolean only_if_exists, GError **error) { - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); + GError *err = NULL; + EBookStatus status; + + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + + if (!org_gnome_evolution_dataserver_addressbook_Book_open (book->priv->proxy, only_if_exists, &err)) { + g_propagate_error (error, err); + return FALSE; + } + + status = get_status_from_error (err); + + if (status == E_BOOK_ERROR_OK) { + book->priv->loaded = TRUE; + return TRUE; + } else { + g_propagate_error (error, err); + return FALSE; + } +} + +static void +open_reply(DBusGProxy *proxy, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + EBookCallback cb = data->callback; + EDataBookStatus status; + + status = get_status_from_error (error); - return do_open (TRUE, - book, only_if_exists, error, - NULL, NULL); + data->book->priv->loaded = (status == E_BOOK_ERROR_OK); + + if (cb) + cb (data->book, status, data->closure); + + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -2783,152 +1568,21 @@ e_book_open (EBook *book, guint e_book_async_open (EBook *book, gboolean only_if_exists, - EBookCallback open_response, + EBookCallback cb, gpointer closure) { - g_return_val_if_fail (book && E_IS_BOOK (book), FALSE); - - return !do_open (FALSE, - book, only_if_exists, NULL, - open_response, closure); -} - -static gboolean -emit_async_open_response (gpointer data) -{ - EBookOp *op = data; - EBook *book = op->book; - - d(printf ("in async_open_response\n")); - - g_mutex_lock (book->priv->mutex); - - if (op->status == E_BOOK_ERROR_OK) - book->priv->load_state = E_BOOK_SOURCE_LOADED; - else - book->priv->load_state = E_BOOK_SOURCE_NOT_LOADED; - - g_mutex_unlock (book->priv->mutex); - - if (op->cb.status) - op->cb.status (book, op->status, op->closure); - - g_mutex_lock (book->priv->mutex); + AsyncData *data; - book->priv->pending_idles = g_list_remove (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); + e_return_async_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); - e_book_clear_op (book, op); + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; - g_mutex_unlock (book->priv->mutex); - g_object_unref (book); - - return FALSE; -} - -static void -e_book_response_open (EBook *book, - guint32 opid, - EBookStatus status) -{ - EBookOp *op; - - d(printf ("in e_book_response_open\n")); - - g_mutex_lock (book->priv->mutex); - - op = e_book_find_op (book, opid, G_STRFUNC); - - if (op == NULL) { - g_mutex_unlock (book->priv->mutex); - return; - } - - op->status = status; - if (op->synchronous) - e_flag_set (op->flag); - else { - op->book = g_object_ref (book); - op->idle_id = g_idle_add (emit_async_open_response, op); - book->priv->pending_idles = g_list_prepend (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - } - - g_mutex_unlock (book->priv->mutex); -} - - -static gboolean -do_remove (gboolean sync, - EBook *book, - GError **error, - EBookCallback cb, - gpointer closure) -{ - CORBA_Environment ev; - EBookOp *our_op; - EBookStatus status; - - g_mutex_lock (book->priv->mutex); - - if (sync && e_book_get_current_sync_op (book) != NULL) { - g_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, sync); - - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_init (&ev); - - our_op->cb.status = cb; - our_op->closure = closure; - - /* will eventually end up calling e_book_response_remove */ - GNOME_Evolution_Addressbook_Book_remove (book->priv->corba_book, our_op->opid, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - CORBA_exception_free (&ev); - - if (error) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::remove"); - } - else { - g_warning (_("CORBA exception making \"%s\" call"), - "Book::remove"); - } - - return FALSE; - } - - CORBA_exception_free (&ev); - - if (sync) { - /* wait for something to happen (both cancellation and a - successful response will notity us via our cv */ - e_flag_wait (our_op->flag); - - status = our_op->status; - - g_mutex_lock (book->priv->mutex); - e_book_clear_op (book, our_op); - g_mutex_unlock (book->priv->mutex); - - E_BOOK_CHECK_STATUS (status, error); - } - else { - return TRUE; - } + org_gnome_evolution_dataserver_addressbook_Book_open_async (book->priv->proxy, only_if_exists, open_reply, data); + return 0; } /** @@ -2945,12 +1599,25 @@ gboolean e_book_remove (EBook *book, GError **error) { - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); + GError *err = NULL; + + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); + + org_gnome_evolution_dataserver_addressbook_Book_remove (book->priv->proxy, &err); + return unwrap_gerror (err, error); +} - return do_remove (TRUE, - book, error, - NULL, NULL); +static void +remove_reply(DBusGProxy *proxy, GError *error, gpointer user_data) +{ + AsyncData *data = user_data; + EBookCallback cb = data->callback; + if (cb) + cb (data->book, get_status_from_error (error), data->closure); + g_object_unref (data->book); + g_slice_free (AsyncData, data); } /** @@ -2969,421 +1636,18 @@ e_book_async_remove (EBook *book, EBookCallback cb, gpointer closure) { - g_return_val_if_fail (book && E_IS_BOOK (book), TRUE); - - return !do_remove (FALSE, - book, NULL, - cb, closure); - -} - -static void -e_book_response_remove (EBook *book, - guint32 opid, - EBookStatus status) -{ - EBookOp *op; - - d(printf ("e_book_response_remove\n")); - - g_mutex_lock (book->priv->mutex); - - op = e_book_find_op (book, opid, G_STRFUNC); - - if (op == NULL) { - g_mutex_unlock (book->priv->mutex); - return; - } - - op->status = status; - if (op->synchronous) - e_flag_set (op->flag); - else { - op->book = g_object_ref (book); - op->idle_id = g_idle_add (emit_async_generic_response, op); - book->priv->pending_idles = g_list_prepend (book->priv->pending_idles, - GINT_TO_POINTER (op->idle_id)); - } - - g_mutex_unlock (book->priv->mutex); -} - -static gboolean -e_book_idle_writable (gpointer data) -{ - EBook *book = data; - gboolean writable; - - g_mutex_lock (book->priv->mutex); - writable = book->priv->writable; - book->priv->writable_idle_id = 0; - g_mutex_unlock (book->priv->mutex); - - g_signal_emit (G_OBJECT (book), e_book_signals [WRITABLE_STATUS], 0, writable); - - g_object_unref (book); - - return FALSE; -} - -static gboolean -e_book_idle_connection (gpointer data) -{ - EBook *book = data; - gboolean connected; - - if (!book->priv) - return FALSE; - - g_mutex_lock (book->priv->mutex); - connected = book->priv->connected; - book->priv->connection_idle_id = 0; - g_mutex_unlock (book->priv->mutex); - - g_signal_emit (G_OBJECT (book), e_book_signals [CONNECTION_STATUS], 0, connected); - - g_object_unref (book); - - return FALSE; -} - -static gboolean -e_book_idle_auth_required (gpointer data) -{ - EBook *book = data; - gboolean connected; - - if (!book->priv) - return FALSE; - - g_mutex_lock (book->priv->mutex); - connected = book->priv->connected; - book->priv->auth_idle_id = 0; - g_mutex_unlock (book->priv->mutex); - - g_signal_emit (G_OBJECT (book), e_book_signals [AUTH_REQUIRED], 0); - - g_object_unref (book); - - return FALSE; - -} - -static void -e_book_handle_response (EBookListener *listener, EBookListenerResponse *resp, EBook *book) -{ - EContact *contact; - - switch (resp->op) { - case CreateContactResponse: - e_book_response_add_contact (book, resp->opid, resp->status, resp->id); - break; - case RemoveContactResponse: - case ModifyContactResponse: - case AuthenticationResponse: - e_book_response_generic (book, resp->opid, resp->status); - break; - case GetContactResponse: - contact = e_contact_new_from_vcard (resp->vcard); - e_book_response_get_contact (book, resp->opid, resp->status, contact); - break; - case GetContactListResponse: - e_book_response_get_contacts (book, resp->opid, resp->status, resp->list); - break; - case GetBookViewResponse: - e_book_response_get_book_view(book, resp->opid, resp->status, resp->book_view); - break; - case GetChangesResponse: - e_book_response_get_changes(book, resp->opid, resp->status, resp->list); - break; - case OpenBookResponse: - e_book_response_open (book, resp->opid, resp->status); - break; - case RemoveBookResponse: - e_book_response_remove (book, resp->opid, resp->status); - break; - case GetSupportedFieldsResponse: - e_book_response_get_supported_fields (book, resp->opid, resp->status, resp->list); - break; - case GetRequiredFieldsResponse: - e_book_response_get_required_fields (book, resp->opid, resp->status, resp->list); - break; - case GetSupportedAuthMethodsResponse: - e_book_response_get_supported_auth_methods (book, resp->opid, resp->status, resp->list); - break; - case WritableStatusEvent: - book->priv->writable = resp->writable; - - g_mutex_lock (book->priv->mutex); - if (book->priv->writable_idle_id == 0) { - g_object_ref (book); - book->priv->writable_idle_id = g_idle_add (e_book_idle_writable, book); - } - g_mutex_unlock (book->priv->mutex); - - break; - case LinkStatusEvent: - book->priv->connected = resp->connected; - g_mutex_lock (book->priv->mutex); - if (book->priv->connection_idle_id == 0) { - g_object_ref (book); - book->priv->connection_idle_id = g_idle_add (e_book_idle_connection, book); - } - g_mutex_unlock (book->priv->mutex); - break; - case AuthRequiredEvent: - g_mutex_lock (book->priv->mutex); - if (book->priv->auth_idle_id == 0) { - g_object_ref (book); - book->priv->auth_idle_id = g_idle_add (e_book_idle_auth_required, book); - } - g_mutex_unlock (book->priv->mutex); - break; - - default: - g_error ("EBook: Unknown response code %d!\n", - resp->op); - } -} - - - -/** - * e_book_unload_uri: - * @book: an #EBook - * @error: an #GError to set on failure - * - * Unload the URI that this book had previously loaded. - * - * Return value: %TRUE on success, %FALSE otherwise. - */ -static 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, FALSE); - e_return_error_if_fail (book->priv->load_state != E_BOOK_SOURCE_NOT_LOADED, E_BOOK_ERROR_SOURCE_NOT_LOADED, FALSE); - - if (book->priv->load_state == E_BOOK_SOURCE_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); - - book->priv->corba_book = CORBA_OBJECT_NIL; - 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_SOURCE_NOT_LOADED; - g_free (book->priv->cap); - book->priv->cap = NULL; - book->priv->cap_queried = FALSE; - book->priv->writable = FALSE; - } - else if (book->priv->load_state == E_BOOK_SOURCE_LOADING) { - e_book_cancel (book, error); - } - - return TRUE; -} - - - -/* Set a flag for operation from the operation hash table */ -static void -find_key_value (gpointer key, gpointer value, gpointer data) -{ - EBookOp *op; - - op = value; - - if (op == NULL) { - g_warning ("find_key_value: Cannot find operation "); - return; - } - - op->status = E_BOOK_ERROR_SOURCE_NOT_LOADED; - if (op->synchronous) - e_flag_set (op->flag); -} - -/** - * e_book_load_uri: - */ - -static void -backend_died_cb (EComponentListener *cl, gpointer user_data) -{ - EBook *book = (EBook *)user_data; - - d(printf ("backend_died_cb\n")); - - g_mutex_lock (book->priv->mutex); - g_hash_table_foreach (book->priv->id_to_op, find_key_value, NULL); - g_mutex_unlock (book->priv->mutex); - - book->priv->load_state = E_BOOK_SOURCE_NOT_LOADED; - g_signal_emit (book, e_book_signals [BACKEND_DIED], 0); -} - -static GList * -activate_factories_for_uri (EBook *book, const gchar *uri) -{ - CORBA_Environment ev; - Bonobo_ServerInfoList *info_list = NULL; - gint i; - const gchar *query; - GList *factories = NULL; - - query = "repo_ids.has ('IDL:GNOME/Evolution/DataServer/BookFactory:" API_VERSION "')"; - - CORBA_exception_init (&ev); - - info_list = bonobo_activation_query (query, NULL, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - gchar *exc_text = bonobo_exception_get_text (&ev); - g_warning ("Cannot perform bonobo-activation query for book factories: %s", exc_text); - g_free (exc_text); - CORBA_exception_free (&ev); - goto done; - return NULL; - } - - if (info_list->_length == 0) { - g_warning ("Can't find installed BookFactories"); - CORBA_exception_free (&ev); - goto done; - } + AsyncData *data; - CORBA_exception_free (&ev); + e_return_async_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_async_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); - for (i = 0; i < info_list->_length; i ++) { - const Bonobo_ServerInfo *info; - GNOME_Evolution_Addressbook_BookFactory factory; + data = g_slice_new0 (AsyncData); + data->book = g_object_ref (book); + data->callback = cb; + data->closure = closure; - 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); - - return factories; -} - -/* XXX hm, should this function hold a lock on book->priv->mutex? It - doesn't seem to require it, but there are unlocked writes to - book->priv->load_state, which other functions read.. */ -static gboolean -fetch_corba_book (EBook *book, - ESource *source, - GError **error) -{ - GNOME_Evolution_Addressbook_Book corba_book = CORBA_OBJECT_NIL; - gchar *uri; - gchar *source_xml; - GList *factories; - GList *l; - gboolean rv = FALSE; - - uri = e_source_get_uri (source); - if (!uri) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_OTHER_ERROR, - _("%s: Invalid source."), "e_book_load_uri"); - return FALSE; - } - - /* try to find a list of factories that can handle the protocol */ - factories = activate_factories_for_uri (book, uri); - if (!factories) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_PROTOCOL_NOT_SUPPORTED, - _("%s: no factories available for URI `%s'"), "e_book_load_uri", uri); - return FALSE; - } - - /* - * 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, - _("%s: Could not create EBookListener"), "e_book_load_uri"); - return FALSE; - } - book->priv->listener_signal = g_signal_connect_object (book->priv->listener, "response", - G_CALLBACK (e_book_handle_response), - book, 0); - - g_free (book->priv->uri); - book->priv->uri = uri; - - g_object_ref (source); - if (book->priv->source) - g_object_unref (book->priv->source); - book->priv->source = source; - - source_xml = e_source_to_standalone_xml (source); - - for (l = factories; l; l = l->next) { - GNOME_Evolution_Addressbook_BookFactory factory = l->data; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - corba_book = GNOME_Evolution_Addressbook_BookFactory_getBook (factory, source_xml, - bonobo_object_corba_objref (BONOBO_OBJECT (book->priv->listener)), - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - CORBA_exception_free (&ev); - continue; - } - else if (corba_book != CORBA_OBJECT_NIL) { - rv = TRUE; - break; - } - } - - g_free (source_xml); - - /* free up the factories */ - for (l = factories; l; l = l->next) - CORBA_Object_release ((CORBA_Object)l->data, NULL); - - g_list_free (factories); - - if (rv == TRUE) { - book->priv->corba_book = corba_book; - 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); - } - else { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_PROTOCOL_NOT_SUPPORTED, - _("%s: no factories available for URI `%s'"), "e_book_new", uri); - } - - return rv; + org_gnome_evolution_dataserver_addressbook_Book_remove_async (book->priv->proxy, remove_reply, data); + return 0; } /** @@ -3397,7 +1661,7 @@ fetch_corba_book (EBook *book, const gchar * e_book_get_uri (EBook *book) { - g_return_val_if_fail (book && E_IS_BOOK (book), NULL); + g_return_val_if_fail (E_IS_BOOK (book), NULL); return book->priv->uri; } @@ -3413,7 +1677,7 @@ e_book_get_uri (EBook *book) ESource * e_book_get_source (EBook *book) { - g_return_val_if_fail (book && E_IS_BOOK (book), NULL); + g_return_val_if_fail (E_IS_BOOK (book), NULL); return book->priv->source; } @@ -3432,37 +1696,18 @@ const gchar * e_book_get_static_capabilities (EBook *book, GError **error) { - g_return_val_if_fail (book && E_IS_BOOK (book), NULL); + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->proxy, E_BOOK_ERROR_REPOSITORY_OFFLINE); if (!book->priv->cap_queried) { - CORBA_Environment ev; - gchar *temp; + char *cap = NULL; - CORBA_exception_init (&ev); - - if (book->priv->load_state != E_BOOK_SOURCE_LOADED) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_SOURCE_NOT_LOADED, - _("\"%s\" on book before \"%s\""), - "e_book_get_static_capabilities", "e_book_open"); - return g_strdup (""); + if (!org_gnome_evolution_dataserver_addressbook_Book_get_static_capabilities (book->priv->proxy, &cap, error)) { + return NULL; } - temp = GNOME_Evolution_Addressbook_Book_getStaticCapabilities(book->priv->corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_set_error (error, E_BOOK_ERROR, E_BOOK_ERROR_CORBA_EXCEPTION, - _("CORBA exception making \"%s\" call"), - "Book::getStaticCapabilities"); - CORBA_exception_free (&ev); - return g_strdup (""); - } - - book->priv->cap = g_strdup(temp); + book->priv->cap = cap; book->priv->cap_queried = TRUE; - - CORBA_free(temp); - - CORBA_exception_free (&ev); } return book->priv->cap; @@ -3508,10 +1753,7 @@ e_book_is_opened (EBook *book) { g_return_val_if_fail (E_IS_BOOK (book), FALSE); - if (book->priv->load_state != E_BOOK_SOURCE_LOADED) - return FALSE; - - return TRUE; + return book->priv->loaded; } /** @@ -3626,8 +1868,8 @@ e_book_set_self (EBook *book, EContact *contact, GError **error) { GConfClient *gconf; - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (contact && E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG, FALSE); + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (E_IS_CONTACT (contact), E_BOOK_ERROR_INVALID_ARG); gconf = gconf_client_get_default(); gconf_client_set_string (gconf, SELF_UID_KEY, e_contact_get_const (contact, E_CONTACT_UID), NULL); @@ -3666,8 +1908,6 @@ e_book_is_self (EContact *contact) return rv; } - - /** * e_book_set_default_addressbook: * @book: An #EBook pointer @@ -3683,8 +1923,8 @@ e_book_set_default_addressbook (EBook *book, GError **error) { ESource *source; - e_return_error_if_fail (book && E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG, FALSE); - e_return_error_if_fail (book->priv->load_state == E_BOOK_SOURCE_NOT_LOADED, E_BOOK_ERROR_SOURCE_ALREADY_LOADED, FALSE); + e_return_error_if_fail (E_IS_BOOK (book), E_BOOK_ERROR_INVALID_ARG); + e_return_error_if_fail (book->priv->loaded == FALSE, E_BOOK_ERROR_SOURCE_ALREADY_LOADED); source = e_book_get_source (book); @@ -3709,7 +1949,7 @@ e_book_set_default_source (ESource *source, GError **error) GError *err = NULL; GSList *g; - e_return_error_if_fail (source && E_IS_SOURCE (source), E_BOOK_ERROR_INVALID_ARG, FALSE); + e_return_error_if_fail (source && E_IS_SOURCE (source), E_BOOK_ERROR_INVALID_ARG); uid = e_source_peek_uid (source); @@ -3766,7 +2006,7 @@ e_book_get_addressbooks (ESourceList **addressbook_sources, GError **error) { GConfClient *gconf; - e_return_error_if_fail (addressbook_sources, E_BOOK_ERROR_INVALID_ARG, FALSE); + e_return_error_if_fail (addressbook_sources, E_BOOK_ERROR_INVALID_ARG); gconf = gconf_client_get_default(); *addressbook_sources = e_source_list_new_for_gconf (gconf, "/apps/evolution/addressbook/sources"); @@ -3775,38 +2015,6 @@ e_book_get_addressbooks (ESourceList **addressbook_sources, GError **error) return TRUE; } - -static gpointer -startup_mainloop (gpointer arg) -{ - GMainLoop *loop = g_main_loop_new (_ebook_context, FALSE); - g_main_loop_run (loop); - return NULL; -} - -/* one-time start up for libebook */ -static void -e_book_activate(void) -{ - static GStaticMutex e_book_lock = G_STATIC_MUTEX_INIT; - static gboolean activated = FALSE; - - g_static_mutex_lock (&e_book_lock); - if (!activated) { - GThread *ebook_mainloop_thread; - activated = TRUE; - - _ebook_context = g_main_context_new (); - - if (!bonobo_is_initialized ()) - bonobo_init (NULL, NULL); - - ebook_mainloop_thread = g_thread_create(startup_mainloop, NULL, FALSE, NULL); - } - g_static_mutex_unlock (&e_book_lock); -} - - /** * e_book_new: * @source: An #ESource pointer @@ -3821,21 +2029,52 @@ e_book_activate(void) EBook* e_book_new (ESource *source, GError **error) { + GError *err = NULL; EBook *book; + char *path; - e_return_error_if_fail (source && E_IS_SOURCE (source), E_BOOK_ERROR_INVALID_ARG, NULL); + e_return_error_if_fail (E_IS_SOURCE (source), E_BOOK_ERROR_INVALID_ARG); - e_book_activate (); + if (!e_book_activate (&err)) { + g_warning (G_STRLOC ": cannot activate book: %s\n", err->message); + g_propagate_error (error, err); + return NULL; + } book = g_object_new (E_TYPE_BOOK, NULL); book->priv->source = g_object_ref (source); + book->priv->uri = e_source_get_uri (source); - if (!fetch_corba_book (book, source, error)) { + if (!org_gnome_evolution_dataserver_addressbook_BookFactory_get_book (factory_proxy, book->priv->uri, &path, &err)) { + g_warning (G_STRLOC ": cannot get book from factory: %s", err ? err->message : "[no error]"); + g_propagate_error (error, err); g_object_unref (book); return NULL; } + book->priv->proxy = dbus_g_proxy_new_for_name_owner (connection, + E_DATA_BOOK_FACTORY_SERVICE_NAME, path, + "org.gnome.evolution.dataserver.addressbook.Book", + &err); + if (!book->priv->proxy) { + g_warning (G_STRLOC ": cannot get proxy for book %s: %s", path, err->message); + g_propagate_error (error, err); + g_free (path); + g_object_unref (book); + return NULL; + } + g_free (path); + + g_object_weak_ref (G_OBJECT (book->priv->proxy), proxy_destroyed, book); + + dbus_g_proxy_add_signal (book->priv->proxy, "writable", G_TYPE_BOOLEAN, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (book->priv->proxy, "writable", G_CALLBACK (writable_cb), book, NULL); + dbus_g_proxy_add_signal (book->priv->proxy, "connection", G_TYPE_BOOLEAN, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (book->priv->proxy, "connection", G_CALLBACK (connection_cb), book, NULL); + dbus_g_proxy_add_signal (book->priv->proxy, "auth_required", G_TYPE_INVALID); + dbus_g_proxy_connect_signal (book->priv->proxy, "auth_required", G_CALLBACK (auth_required_cb), book, NULL); + return book; } @@ -3852,21 +2091,16 @@ e_book_new (ESource *source, GError **error) EBook* e_book_new_from_uri (const gchar *uri, GError **error) { - ESourceGroup *group; ESource *source; EBook *book; - e_return_error_if_fail (uri, E_BOOK_ERROR_INVALID_ARG, NULL); + e_return_error_if_fail (uri, E_BOOK_ERROR_INVALID_ARG); - group = e_source_group_new ("", uri); - source = e_source_new ("", ""); - e_source_set_group (source, group); - e_source_set_relative_uri (source, NULL); + source = e_source_new_with_absolute_uri ("", uri); book = e_book_new (source, error); g_object_unref (source); - g_object_unref (group); return book; } @@ -3997,168 +2231,98 @@ e_book_new_default_addressbook (GError **error) return book; } -static void -kill_remaining_ops (gpointer key, gpointer value, gpointer user_data) -{ - EBookOp *op = value; - EBook *book = user_data; - - if (!op) - return; - - find_key_value (key, value, NULL); - e_book_clear_op (book, op); -} - -static void -e_book_init (EBook *book) -{ - book->priv = g_new0 (EBookPrivate, 1); - book->priv->load_state = E_BOOK_SOURCE_NOT_LOADED; - book->priv->uri = NULL; - book->priv->source = NULL; - book->priv->mutex = g_mutex_new (); - book->priv->id_to_op = g_hash_table_new (g_int_hash, g_int_equal); - book->priv->current_op_id = 1; -} - -static void -e_book_dispose (GObject *object) +/** + * If the specified GError is a remote error, then create a new error + * representing the remote error. If the error is anything else, then leave it + * alone. + */ +static gboolean +unwrap_gerror (GError *error, GError **client_error) { - EBook *book = E_BOOK (object); - - if (book->priv) { - 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_SOURCE_LOADED) - e_book_unload_uri (book, NULL); - - if (book->priv->corba_book) { - CORBA_Environment ev; + if (error == NULL) + return TRUE; - CORBA_exception_init (&ev); - bonobo_object_release_unref (book->priv->corba_book, &ev); - if (ev._major != CORBA_NO_EXCEPTION) - g_warning ("%s: Exception releasing remote book interface!\n", G_STRFUNC); - CORBA_exception_free (&ev); + if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION) { + GError *new; + gint code; + if (client_error) { + code = get_status_from_error (error); + new = g_error_new_literal (E_BOOK_ERROR, code, error->message); + *client_error = new; } + g_error_free (error); + } else { + if (client_error) + *client_error = error; + } + return FALSE; +} - if (book->priv->listener) { - e_book_listener_stop (book->priv->listener); - - /* GLib bug compatibility */ - if (g_signal_handler_is_connected (book->priv->listener, book->priv->listener_signal)) - g_signal_handler_disconnect (book->priv->listener, book->priv->listener_signal); - bonobo_object_unref (book->priv->listener); - book->priv->listener = NULL; +/** + * If the GError is a remote error, extract the EBookStatus embedded inside. + * Otherwise return CORBA_EXCEPTION (I know this is DBus...). + */ +static EBookStatus +get_status_from_error (GError *error) +{ + if G_LIKELY (error == NULL) + return E_BOOK_ERROR_OK; + if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION) { + const char *name; + name = dbus_g_error_get_name (error); + if (strcmp (name, "org.gnome.evolution.dataserver.addressbook.Book.contactnotfound") == 0) { + return E_BOOK_ERROR_CONTACT_NOT_FOUND; + } else if (strcmp (name, "org.gnome.evolution.dataserver.addressbook.Book.invalidquery") == 0) { + return E_BOOK_ERROR_INVALID_ARG; + } else if (strcmp (name, "org.gnome.evolution.dataserver.addressbook.Book.cancelled") == 0) { + return E_BOOK_ERROR_CANCELLED; + } else if (strcmp (name, "org.gnome.evolution.dataserver.addressbook.Book.permissiondenied") == 0) { + return E_BOOK_ERROR_PERMISSION_DENIED; + } else if (strcmp (name, "org.gnome.evolution.dataserver.addressbook.Book.nospace") == 0) { + return E_BOOK_ERROR_NO_SPACE; + } else if (strcmp (name, "org.gnome.evolution.dataserver.addressbook.Book.repositoryoffline") == 0) { + return E_BOOK_ERROR_REPOSITORY_OFFLINE; + } else if (strcmp (name, "org.gnome.evolution.dataserver.addressbook.Book.othererror") == 0) { + return E_BOOK_ERROR_OTHER_ERROR; + } else { + g_warning (G_STRLOC ": unmatched error name %s", name); + return E_BOOK_ERROR_OTHER_ERROR; } - - g_free (book->priv->cap); - - g_free (book->priv->uri); - - if (book->priv->source) - g_object_unref (book->priv->source); - - g_mutex_lock (book->priv->mutex); - g_hash_table_foreach (book->priv->id_to_op, kill_remaining_ops, book); - g_hash_table_destroy (book->priv->id_to_op); - g_mutex_unlock (book->priv->mutex); - - g_mutex_free (book->priv->mutex); - - if (book->priv->connection_idle_id) - g_source_remove (book->priv->connection_idle_id); - - if (book->priv->auth_idle_id) - g_source_remove (book->priv->auth_idle_id); - - if (book->priv->writable_idle_id) - g_source_remove (book->priv->writable_idle_id); - - g_free (book->priv); - book->priv = NULL; + } else { + /* In this case the error was caused by DBus. Dump the message to the + console as otherwise we have no idea what the problem is. */ + g_warning ("DBus error: %s", error->message); + return E_BOOK_ERROR_CORBA_EXCEPTION; } - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); } -static void -e_book_class_init (EBookClass *klass) +/** + * Turn a GList of strings into an array of strings. + */ +static char ** +flatten_stringlist (GList *list) { - 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, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); - - e_book_signals [CONNECTION_STATUS] = - g_signal_new ("connection_status", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookClass, connection_status), - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); - - e_book_signals [AUTH_REQUIRED] = - g_signal_new ("auth_required", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EBookClass, auth_required), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - 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, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - object_class->dispose = e_book_dispose; + char **array = g_new0 (char *, g_list_length (list) + 1); + GList *l = list; + int i = 0; + while (l != NULL) { + array[i++] = l->data; + l = l->next; + } + return array; } /** - * e_book_get_type: + * Turn an array of strings into a GList. */ -GType -e_book_get_type (void) +static GList * +array_to_stringlist (char **list) { - 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); + GList *l = NULL; + char **i = list; + while (*i != NULL) { + l = g_list_prepend (l, (*i++)); } - - return type; + g_free (list); + return g_list_reverse(l); } diff --git a/addressbook/libebook/e-error.h b/addressbook/libebook/e-error.h new file mode 100644 index 000000000..5d137f019 --- /dev/null +++ b/addressbook/libebook/e-error.h @@ -0,0 +1,40 @@ +#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 + + +#define e_return_async_error_if_fail(expr, error) 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); \ + cb (book, error, closure); \ + return 0; \ + } \ + } G_STMT_END \ + +#define e_return_async_error_val_if_fail(expr, error) 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); \ + cb (book, error, NULL, closure); \ + return 0; \ + } \ + } G_STMT_END \ + diff --git a/addressbook/libebook/libebook.pc.in b/addressbook/libebook/libebook.pc.in index 49a497aa8..3d098d5ee 100644 --- a/addressbook/libebook/libebook.pc.in +++ b/addressbook/libebook/libebook.pc.in @@ -5,14 +5,11 @@ includedir=@includedir@ datarootdir=@datarootdir@ datadir=@datadir@ -idldir=@idldir@ -IDL_INCLUDES=-I${idldir} @IDL_INCLUDES@ - privincludedir=@privincludedir@ Name: libebook Description: Client library for evolution address books Version: @VERSION@ -Requires: libbonobo-2.0 >= @LIBBONOBO_REQUIRED@ libedataserver-1.2 +Requires: libedataserver-1.2 dbus-glib-1 Libs: -L${libdir} -lebook-1.2 Cflags: -I${privincludedir} |