[evolution-data-server] Replace EGdbusBook with EDBusAddressBook.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Replace EGdbusBook with EDBusAddressBook.
- Date: Tue, 29 Jan 2013 22:20:05 +0000 (UTC)
commit aa424cd9b26e35f6f68aeeb18c4ed72a7d14b979
Author: Matthew Barnes <mbarnes redhat com>
Date: Thu Jan 24 20:04:14 2013 -0500
Replace EGdbusBook with EDBusAddressBook.
addressbook/libebook/e-book-client.c | 2339 ++++++++++++--------
addressbook/libebook/e-book-client.h | 26 +-
addressbook/libedata-book/e-book-backend.c | 41 +-
addressbook/libedata-book/e-book-backend.h | 8 +-
addressbook/libedata-book/e-data-book.c | 741 ++++---
addressbook/libedata-book/e-data-book.h | 8 +-
addressbook/libegdbus/Makefile.am | 2 -
addressbook/libegdbus/e-gdbus-book.c | 1462 ------------
addressbook/libegdbus/e-gdbus-book.h | 259 ---
.../libedata-book/libedata-book-sections.txt | 8 +-
10 files changed, 1959 insertions(+), 2935 deletions(-)
---
diff --git a/addressbook/libebook/e-book-client.c b/addressbook/libebook/e-book-client.c
index 4767464..c2e4130 100644
--- a/addressbook/libebook/e-book-client.c
+++ b/addressbook/libebook/e-book-client.c
@@ -27,6 +27,7 @@
#include <gio/gio.h>
/* Private D-Bus classes. */
+#include <e-dbus-address-book.h>
#include <e-dbus-address-book-factory.h>
#include <libedataserver/libedataserver.h>
@@ -36,18 +37,110 @@
#include "e-contact.h"
#include "e-name-western.h"
-#include "e-gdbus-book.h"
-
#define E_BOOK_CLIENT_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_BOOK_CLIENT, EBookClientPrivate))
+/* Set this to a sufficiently large value
+ * to cover most long-running operations. */
+#define DBUS_PROXY_TIMEOUT_MS (3 * 60 * 1000) /* 3 minutes */
+
+typedef struct _AsyncContext AsyncContext;
+typedef struct _SignalClosure SignalClosure;
+typedef struct _RunInThreadClosure RunInThreadClosure;
+
struct _EBookClientPrivate {
- GDBusProxy *dbus_proxy;
+ EDBusAddressBook *dbus_proxy;
+ GMainContext *main_context;
guint gone_signal_id;
+
+ gulong dbus_proxy_error_handler_id;
+ gulong dbus_proxy_notify_handler_id;
+};
+
+struct _AsyncContext {
+ EContact *contact;
+ EBookClientView *client_view;
+ GSList *object_list;
+ GSList *string_list;
+ gchar *sexp;
+ gchar *uid;
+};
+
+struct _SignalClosure {
+ EClient *client;
+ gchar *property_name;
+ gchar *error_message;
+};
+
+struct _RunInThreadClosure {
+ GSimpleAsyncThreadFunc func;
+ GSimpleAsyncResult *simple;
+ GCancellable *cancellable;
};
-G_DEFINE_TYPE (EBookClient, e_book_client, E_TYPE_CLIENT)
+/* Forward Declarations */
+static void e_book_client_initable_init
+ (GInitableIface *interface);
+static void e_book_client_async_initable_init
+ (GAsyncInitableIface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EBookClient,
+ e_book_client,
+ E_TYPE_CLIENT,
+ G_IMPLEMENT_INTERFACE (
+ G_TYPE_INITABLE,
+ e_book_client_initable_init)
+ G_IMPLEMENT_INTERFACE (
+ G_TYPE_ASYNC_INITABLE,
+ e_book_client_async_initable_init))
+
+static void
+async_context_free (AsyncContext *async_context)
+{
+ if (async_context->contact != NULL)
+ g_object_unref (async_context->contact);
+
+ if (async_context->client_view != NULL)
+ g_object_unref (async_context->client_view);
+
+ g_slist_free_full (
+ async_context->object_list,
+ (GDestroyNotify) g_object_unref);
+
+ g_slist_free_full (
+ async_context->string_list,
+ (GDestroyNotify) g_free);
+
+ g_free (async_context->sexp);
+ g_free (async_context->uid);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
+static void
+signal_closure_free (SignalClosure *signal_closure)
+{
+ g_object_unref (signal_closure->client);
+
+ g_free (signal_closure->property_name);
+ g_free (signal_closure->error_message);
+
+ g_slice_free (SignalClosure, signal_closure);
+}
+
+static void
+run_in_thread_closure_free (RunInThreadClosure *run_in_thread_closure)
+{
+ if (run_in_thread_closure->simple != NULL)
+ g_object_unref (run_in_thread_closure->simple);
+
+ if (run_in_thread_closure->cancellable != NULL)
+ g_object_unref (run_in_thread_closure->cancellable);
+
+ g_slice_free (RunInThreadClosure, run_in_thread_closure);
+}
/*
* Well-known book backend properties:
@@ -285,6 +378,107 @@ gdbus_book_factory_activate (GCancellable *cancellable,
return TRUE;
}
+static gpointer
+book_client_dbus_thread (gpointer user_data)
+{
+ GMainContext *main_context = user_data;
+ GMainLoop *main_loop;
+
+ g_main_context_push_thread_default (main_context);
+
+ main_loop = g_main_loop_new (main_context, FALSE);
+ g_main_loop_run (main_loop);
+ g_main_loop_unref (main_loop);
+
+ g_main_context_pop_thread_default (main_context);
+
+ g_main_context_unref (main_context);
+
+ return NULL;
+}
+
+static gpointer
+book_client_dbus_thread_init (gpointer unused)
+{
+ GMainContext *main_context;
+
+ main_context = g_main_context_new ();
+
+ /* This thread terminates when the process itself terminates, so
+ * no need to worry about unreferencing the returned GThread. */
+ g_thread_new (
+ "book-client-dbus-thread",
+ book_client_dbus_thread,
+ g_main_context_ref (main_context));
+
+ return main_context;
+}
+
+static GMainContext *
+book_client_ref_dbus_main_context (void)
+{
+ static GOnce book_client_dbus_thread_once = G_ONCE_INIT;
+
+ g_once (
+ &book_client_dbus_thread_once,
+ book_client_dbus_thread_init, NULL);
+
+ return g_main_context_ref (book_client_dbus_thread_once.retval);
+}
+
+static gboolean
+book_client_run_in_dbus_thread_idle_cb (gpointer user_data)
+{
+ RunInThreadClosure *closure = user_data;
+ GObject *source_object;
+ GAsyncResult *result;
+
+ result = G_ASYNC_RESULT (closure->simple);
+ source_object = g_async_result_get_source_object (result);
+
+ closure->func (
+ closure->simple,
+ source_object,
+ closure->cancellable);
+
+ if (source_object != NULL)
+ g_object_unref (source_object);
+
+ g_simple_async_result_complete_in_idle (closure->simple);
+
+ return FALSE;
+}
+
+static void
+book_client_run_in_dbus_thread (GSimpleAsyncResult *simple,
+ GSimpleAsyncThreadFunc func,
+ gint io_priority,
+ GCancellable *cancellable)
+{
+ RunInThreadClosure *closure;
+ GMainContext *main_context;
+ GSource *idle_source;
+
+ main_context = book_client_ref_dbus_main_context ();
+
+ closure = g_slice_new0 (RunInThreadClosure);
+ closure->func = func;
+ closure->simple = g_object_ref (simple);
+
+ if (G_IS_CANCELLABLE (cancellable))
+ closure->cancellable = g_object_ref (cancellable);
+
+ idle_source = g_idle_source_new ();
+ g_source_set_priority (idle_source, io_priority);
+ g_source_set_callback (
+ idle_source, book_client_run_in_dbus_thread_idle_cb,
+ closure, (GDestroyNotify) run_in_thread_closure_free);
+ g_source_attach (idle_source, main_context);
+ g_source_unref (idle_source);
+
+ g_main_context_unref (main_context);
+}
+
static void gdbus_book_client_disconnect (EBookClient *client);
/*
@@ -344,7 +538,7 @@ gdbus_book_client_disconnect (EBookClient *client)
g_dbus_connection_signal_unsubscribe (connection, client->priv->gone_signal_id);
client->priv->gone_signal_id = 0;
- e_gdbus_book_call_close_sync (
+ e_dbus_address_book_call_close_sync (
client->priv->dbus_proxy, NULL, NULL);
g_object_unref (client->priv->dbus_proxy);
client->priv->dbus_proxy = NULL;
@@ -353,131 +547,167 @@ gdbus_book_client_disconnect (EBookClient *client)
UNLOCK_FACTORY ();
}
-static void
-backend_error_cb (EGdbusBook *dbus_proxy,
- const gchar *message,
- EBookClient *client)
+static gboolean
+book_client_emit_backend_error_idle_cb (gpointer user_data)
{
- g_return_if_fail (E_IS_BOOK_CLIENT (client));
- g_return_if_fail (message != NULL);
+ SignalClosure *signal_closure = user_data;
+
+ g_signal_emit_by_name (
+ signal_closure->client,
+ "backend-error",
+ signal_closure->error_message);
- e_client_emit_backend_error (E_CLIENT (client), message);
+ return FALSE;
}
-static void
-readonly_cb (EGdbusBook *dbus_proxy,
- gboolean readonly,
- EBookClient *client)
-{
- g_return_if_fail (E_IS_BOOK_CLIENT (client));
+static gboolean
+book_client_emit_backend_property_changed_idle_cb (gpointer user_data)
+{
+ SignalClosure *signal_closure = user_data;
+ gchar *prop_value = NULL;
+
+ /* XXX Despite appearances, this function does not block. */
+ e_client_get_backend_property_sync (
+ signal_closure->client,
+ signal_closure->property_name,
+ &prop_value, NULL, NULL);
+
+ if (prop_value != NULL) {
+ g_signal_emit_by_name (
+ signal_closure->client,
+ "backend-property-changed",
+ signal_closure->property_name,
+ prop_value);
+ g_free (prop_value);
+ }
- e_client_set_readonly (E_CLIENT (client), readonly);
+ return FALSE;
}
static void
-online_cb (EGdbusBook *dbus_proxy,
- gboolean is_online,
- EBookClient *client)
+book_client_dbus_proxy_error_cb (EDBusAddressBook *dbus_proxy,
+ const gchar *error_message,
+ EBookClient *book_client)
{
- g_return_if_fail (E_IS_BOOK_CLIENT (client));
+ GSource *idle_source;
+ SignalClosure *signal_closure;
+
+ signal_closure = g_slice_new0 (SignalClosure);
+ signal_closure->client = g_object_ref (book_client);
+ signal_closure->error_message = g_strdup (error_message);
- e_client_set_online (E_CLIENT (client), is_online);
+ idle_source = g_idle_source_new ();
+ g_source_set_callback (
+ idle_source,
+ book_client_emit_backend_error_idle_cb,
+ signal_closure,
+ (GDestroyNotify) signal_closure_free);
+ g_source_attach (idle_source, book_client->priv->main_context);
+ g_source_unref (idle_source);
}
static void
-opened_cb (EGdbusBook *dbus_proxy,
- const gchar * const *error_strv,
- EBookClient *client)
+book_client_dbus_proxy_notify_cb (EDBusAddressBook *dbus_proxy,
+ GParamSpec *pspec,
+ EBookClient *book_client)
{
- GError *error = NULL;
+ const gchar *backend_prop_name = NULL;
- g_return_if_fail (E_IS_BOOK_CLIENT (client));
- g_return_if_fail (error_strv != NULL);
- g_return_if_fail (e_gdbus_templates_decode_error (error_strv, &error));
-
- e_client_emit_opened (E_CLIENT (client), error);
+ if (g_str_equal (pspec->name, "cache-dir")) {
+ backend_prop_name = CLIENT_BACKEND_PROPERTY_CACHE_DIR;
+ }
- if (error)
- g_error_free (error);
-}
+ if (g_str_equal (pspec->name, "capabilities")) {
+ gchar **strv;
+ gchar *csv;
-static void
-backend_property_changed_cb (EGdbusBook *dbus_proxy,
- const gchar * const *name_value_strv,
- EBookClient *client)
-{
- gchar *prop_name = NULL, *prop_value = NULL;
+ backend_prop_name = CLIENT_BACKEND_PROPERTY_CAPABILITIES;
- g_return_if_fail (E_IS_BOOK_CLIENT (client));
- g_return_if_fail (name_value_strv != NULL);
- g_return_if_fail (e_gdbus_templates_decode_two_strings (name_value_strv, &prop_name, &prop_value));
- g_return_if_fail (prop_name != NULL);
- g_return_if_fail (*prop_name);
- g_return_if_fail (prop_value != NULL);
+ strv = e_dbus_address_book_dup_capabilities (dbus_proxy);
+ csv = g_strjoinv (",", strv);
+ e_client_set_capabilities (E_CLIENT (book_client), csv);
+ g_free (csv);
+ g_free (strv);
+ }
- e_client_emit_backend_property_changed (E_CLIENT (client), prop_name, prop_value);
+ if (g_str_equal (pspec->name, "online")) {
+ gboolean online;
- g_free (prop_name);
- g_free (prop_value);
-}
+ backend_prop_name = CLIENT_BACKEND_PROPERTY_ONLINE;
-/*
- * Converts a GSList of EContact objects into a NULL-terminated array of
- * valid UTF-8 vcard strings, suitable for sending over DBus.
- */
-static gchar **
-contact_slist_to_utf8_vcard_array (GSList *contacts)
-{
- gchar **array;
- const GSList *l;
- gint i = 0;
+ online = e_dbus_address_book_get_online (dbus_proxy);
+ e_client_set_online (E_CLIENT (book_client), online);
+ }
- array = g_new0 (gchar *, g_slist_length (contacts) + 1);
- for (l = contacts; l != NULL; l = l->next) {
- gchar *vcard = e_vcard_to_string (E_VCARD (l->data), EVC_FORMAT_VCARD_30);
- array[i++] = e_util_utf8_make_valid (vcard);
- g_free (vcard);
+ if (g_str_equal (pspec->name, "required-fields")) {
+ backend_prop_name = BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS;
}
- return array;
-}
+ if (g_str_equal (pspec->name, "revision")) {
+ backend_prop_name = CLIENT_BACKEND_PROPERTY_REVISION;
+ }
-static gboolean
-book_client_get_backend_property_from_cache_finish (EClient *client,
- GAsyncResult *result,
- gchar **prop_value,
- GError **error)
-{
- GSimpleAsyncResult *simple;
- GError *local_error = NULL;
+ if (g_str_equal (pspec->name, "supported-fields")) {
+ backend_prop_name = BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS;
+ }
- g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
- g_return_val_if_fail (result != NULL, FALSE);
- g_return_val_if_fail (prop_value != NULL, FALSE);
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), book_client_get_backend_property_from_cache_finish), FALSE);
+ if (g_str_equal (pspec->name, "writable")) {
+ gboolean writable;
- simple = G_SIMPLE_ASYNC_RESULT (result);
+ backend_prop_name = CLIENT_BACKEND_PROPERTY_READONLY;
- if (g_simple_async_result_propagate_error (simple, &local_error)) {
- e_client_unwrap_dbus_error (client, local_error, error);
- return FALSE;
+ writable = e_dbus_address_book_get_writable (dbus_proxy);
+ e_client_set_readonly (E_CLIENT (book_client), !writable);
}
- *prop_value = g_strdup (g_simple_async_result_get_op_res_gpointer (simple));
-
- return *prop_value != NULL;
+ if (backend_prop_name != NULL) {
+ GSource *idle_source;
+ SignalClosure *signal_closure;
+
+ signal_closure = g_slice_new0 (SignalClosure);
+ signal_closure->client = g_object_ref (book_client);
+ signal_closure->property_name = g_strdup (backend_prop_name);
+
+ idle_source = g_idle_source_new ();
+ g_source_set_callback (
+ idle_source,
+ book_client_emit_backend_property_changed_idle_cb,
+ signal_closure,
+ (GDestroyNotify) signal_closure_free);
+ g_source_attach (idle_source, book_client->priv->main_context);
+ g_source_unref (idle_source);
+ }
}
static void
book_client_dispose (GObject *object)
{
- EClient *client;
+ EBookClientPrivate *priv;
+
+ priv = E_BOOK_CLIENT_GET_PRIVATE (object);
+
+ e_client_cancel_all (E_CLIENT (object));
+
+ if (priv->dbus_proxy_error_handler_id > 0) {
+ g_signal_handler_disconnect (
+ priv->dbus_proxy,
+ priv->dbus_proxy_error_handler_id);
+ priv->dbus_proxy_error_handler_id = 0;
+ }
- client = E_CLIENT (object);
+ if (priv->dbus_proxy_notify_handler_id > 0) {
+ g_signal_handler_disconnect (
+ priv->dbus_proxy,
+ priv->dbus_proxy_notify_handler_id);
+ priv->dbus_proxy_notify_handler_id = 0;
+ }
- e_client_cancel_all (client);
+ gdbus_book_client_disconnect (E_BOOK_CLIENT (object));
- gdbus_book_client_disconnect (E_BOOK_CLIENT (client));
+ if (priv->main_context != NULL) {
+ g_main_context_unref (priv->main_context);
+ priv->main_context = NULL;
+ }
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_book_client_parent_class)->dispose (object);
@@ -514,94 +744,15 @@ book_client_unwrap_dbus_error (EClient *client,
unwrap_dbus_error (dbus_error, out_error);
}
-static void
-book_client_retrieve_capabilities (EClient *client,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_return_if_fail (E_IS_BOOK_CLIENT (client));
-
- e_client_get_backend_property (client, CLIENT_BACKEND_PROPERTY_CAPABILITIES, cancellable, callback, user_data);
-}
-
-static gboolean
-book_client_retrieve_capabilities_finish (EClient *client,
- GAsyncResult *result,
- gchar **capabilities,
- GError **error)
-{
- g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
-
- return e_client_get_backend_property_finish (client, result, capabilities, error);
-}
-
static gboolean
book_client_retrieve_capabilities_sync (EClient *client,
gchar **capabilities,
GCancellable *cancellable,
GError **error)
{
- g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
-
- return e_client_get_backend_property_sync (client, CLIENT_BACKEND_PROPERTY_CAPABILITIES, capabilities, cancellable, error);
-}
-
-static void
-book_client_get_backend_property (EClient *client,
- const gchar *prop_name,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- gchar *prop_value;
-
- prop_value = e_client_get_backend_property_from_cache (client, prop_name);
- if (prop_value) {
- e_client_finish_async_without_dbus (
- client, cancellable, callback, user_data,
- book_client_get_backend_property_from_cache_finish,
- prop_value, g_free);
- } else {
- e_client_proxy_call_string_with_res_op_data (
- client, prop_name,
- cancellable, callback, user_data,
- book_client_get_backend_property, prop_name,
- e_gdbus_book_call_get_backend_property,
- NULL, NULL,
- e_gdbus_book_call_get_backend_property_finish,
- NULL, NULL);
- }
-}
-
-static gboolean
-book_client_get_backend_property_finish (EClient *client,
- GAsyncResult *result,
- gchar **prop_value,
- GError **error)
-{
- gchar *str = NULL;
- gboolean res;
-
- g_return_val_if_fail (prop_value != NULL, FALSE);
-
- if (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (result)) == book_client_get_backend_property_from_cache_finish) {
- res = book_client_get_backend_property_from_cache_finish (client, result, &str, error);
- } else {
- res = e_client_proxy_call_finish_string (
- client, result, &str, error,
- book_client_get_backend_property);
- if (res && str) {
- const gchar *prop_name = g_object_get_data (G_OBJECT (result), "res-op-data");
-
- if (prop_name && *prop_name)
- e_client_update_backend_property_cache (client, prop_name, str);
- }
- }
-
- *prop_value = str;
-
- return res;
+ return e_client_get_backend_property_sync (
+ client, CLIENT_BACKEND_PROPERTY_CAPABILITIES,
+ capabilities, cancellable, error);
}
static gboolean
@@ -612,36 +763,74 @@ book_client_get_backend_property_sync (EClient *client,
GError **error)
{
EBookClient *book_client;
- gchar *prop_val;
- gboolean res;
-
- g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
+ EDBusAddressBook *dbus_proxy;
+ gchar **strv;
book_client = E_BOOK_CLIENT (client);
+ dbus_proxy = book_client->priv->dbus_proxy;
- if (book_client->priv->dbus_proxy == NULL) {
- set_proxy_gone_error (error);
- return FALSE;
+ if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_OPENED)) {
+ *prop_value = g_strdup ("TRUE");
+ return TRUE;
}
- prop_val = e_client_get_backend_property_from_cache (client, prop_name);
- if (prop_val) {
- g_return_val_if_fail (prop_value != NULL, FALSE);
+ if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_OPENING)) {
+ *prop_value = g_strdup ("FALSE");
+ return TRUE;
+ }
- *prop_value = prop_val;
+ if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_ONLINE)) {
+ if (e_dbus_address_book_get_online (dbus_proxy))
+ *prop_value = g_strdup ("TRUE");
+ else
+ *prop_value = g_strdup ("FALSE");
+ return TRUE;
+ }
+ if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_READONLY)) {
+ if (e_dbus_address_book_get_writable (dbus_proxy))
+ *prop_value = g_strdup ("FALSE");
+ else
+ *prop_value = g_strdup ("TRUE");
return TRUE;
}
- res = e_client_proxy_call_sync_string__string (
- client, prop_name, prop_value, cancellable, error,
- e_gdbus_book_call_get_backend_property_sync);
+ if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CACHE_DIR)) {
+ *prop_value = e_dbus_address_book_dup_cache_dir (dbus_proxy);
+ return TRUE;
+ }
- if (res && prop_value)
- e_client_update_backend_property_cache (
- client, prop_name, *prop_value);
+ if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_REVISION)) {
+ *prop_value = e_dbus_address_book_dup_revision (dbus_proxy);
+ return TRUE;
+ }
+
+ if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
+ strv = e_dbus_address_book_dup_capabilities (dbus_proxy);
+ *prop_value = g_strjoinv (",", strv);
+ g_strfreev (strv);
+ return TRUE;
+ }
+
+ if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS)) {
+ strv = e_dbus_address_book_dup_required_fields (dbus_proxy);
+ *prop_value = g_strjoinv (",", strv);
+ g_strfreev (strv);
+ return TRUE;
+ }
- return res;
+ if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS)) {
+ strv = e_dbus_address_book_dup_supported_fields (dbus_proxy);
+ *prop_value = g_strjoinv (",", strv);
+ g_strfreev (strv);
+ return TRUE;
+ }
+
+ g_set_error (
+ error, E_CLIENT_ERROR, E_CLIENT_ERROR_NOT_SUPPORTED,
+ _("Unknown book property '%s'"), prop_name);
+
+ return TRUE;
}
static gboolean
@@ -660,31 +849,6 @@ book_client_set_backend_property_sync (EClient *client,
return FALSE;
}
-static void
-book_client_open (EClient *client,
- gboolean only_if_exists,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- e_client_proxy_call_boolean (
- client, only_if_exists,
- cancellable, callback, user_data,
- book_client_open,
- e_gdbus_book_call_open,
- e_gdbus_book_call_open_finish,
- NULL, NULL, NULL, NULL);
-}
-
-static gboolean
-book_client_open_finish (EClient *client,
- GAsyncResult *result,
- GError **error)
-{
- return e_client_proxy_call_finish_void (
- client, result, error, book_client_open);
-}
-
static gboolean
book_client_open_sync (EClient *client,
gboolean only_if_exists,
@@ -702,32 +866,8 @@ book_client_open_sync (EClient *client,
return FALSE;
}
- return e_client_proxy_call_sync_boolean__void (
- client, only_if_exists, cancellable, error,
- e_gdbus_book_call_open_sync);
-}
-
-static void
-book_client_refresh (EClient *client,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- e_client_proxy_call_void (
- client, cancellable, callback, user_data,
- book_client_refresh,
- e_gdbus_book_call_refresh,
- e_gdbus_book_call_refresh_finish,
- NULL, NULL, NULL, NULL);
-}
-
-static gboolean
-book_client_refresh_finish (EClient *client,
- GAsyncResult *result,
- GError **error)
-{
- return e_client_proxy_call_finish_void (
- client, result, error, book_client_refresh);
+ return e_dbus_address_book_call_open_sync (
+ book_client->priv->dbus_proxy, cancellable, error);
}
static gboolean
@@ -746,9 +886,168 @@ book_client_refresh_sync (EClient *client,
return FALSE;
}
- return e_client_proxy_call_sync_void__void (
- client, cancellable, error,
- e_gdbus_book_call_refresh_sync);
+ return e_dbus_address_book_call_refresh_sync (
+ book_client->priv->dbus_proxy, cancellable, error);
+}
+
+static void
+book_client_init_in_dbus_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ EBookClientPrivate *priv;
+ EClient *client;
+ ESource *source;
+ GDBusConnection *connection;
+ const gchar *uid;
+ gchar *object_path = NULL;
+ gulong handler_id;
+ GError *error = NULL;
+
+ priv = E_BOOK_CLIENT_GET_PRIVATE (source_object);
+
+ client = E_CLIENT (source_object);
+ source = e_client_get_source (client);
+ uid = e_source_get_uid (source);
+
+ LOCK_FACTORY ();
+ gdbus_book_factory_activate (cancellable, &error);
+ UNLOCK_FACTORY ();
+
+ if (error != NULL) {
+ unwrap_dbus_error (error, &error);
+ g_simple_async_result_take_error (simple, error);
+ return;
+ }
+
+ e_dbus_address_book_factory_call_open_address_book_sync (
+ book_factory, uid, &object_path, cancellable, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((object_path != NULL) && (error == NULL)) ||
+ ((object_path == NULL) && (error != NULL)));
+
+ if (object_path == NULL) {
+ unwrap_dbus_error (error, &error);
+ g_simple_async_result_take_error (simple, error);
+ return;
+ }
+
+ connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (book_factory));
+
+ priv->dbus_proxy = e_dbus_address_book_proxy_new_sync (
+ connection,
+ G_DBUS_PROXY_FLAGS_NONE,
+ ADDRESS_BOOK_DBUS_SERVICE_NAME,
+ object_path,
+ cancellable, &error);
+
+ g_free (object_path);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((priv->dbus_proxy != NULL) && (error == NULL)) ||
+ ((priv->dbus_proxy == NULL) && (error != NULL)));
+
+ if (error != NULL) {
+ unwrap_dbus_error (error, &error);
+ g_simple_async_result_take_error (simple, error);
+ return;
+ }
+
+ g_dbus_proxy_set_default_timeout (
+ G_DBUS_PROXY (priv->dbus_proxy), DBUS_PROXY_TIMEOUT_MS);
+
+ priv->gone_signal_id = g_dbus_connection_signal_subscribe (
+ connection,
+ "org.freedesktop.DBus", /* sender */
+ "org.freedesktop.DBus", /* interface */
+ "NameOwnerChanged", /* member */
+ "/org/freedesktop/DBus", /* object_path */
+ "org.gnome.evolution.dataserver.AddressBook", /* arg0 */
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ gdbus_book_client_connection_gone_cb, client, NULL);
+
+ g_signal_connect (
+ connection, "closed",
+ G_CALLBACK (gdbus_book_client_closed_cb), client);
+
+ handler_id = g_signal_connect (
+ priv->dbus_proxy, "error",
+ G_CALLBACK (book_client_dbus_proxy_error_cb), client);
+ priv->dbus_proxy_error_handler_id = handler_id;
+
+ handler_id = g_signal_connect (
+ priv->dbus_proxy, "notify",
+ G_CALLBACK (book_client_dbus_proxy_notify_cb), client);
+ priv->dbus_proxy_notify_handler_id = handler_id;
+}
+
+static gboolean
+book_client_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EAsyncClosure *closure;
+ GAsyncResult *result;
+ gboolean success;
+
+ closure = e_async_closure_new ();
+
+ g_async_initable_init_async (
+ G_ASYNC_INITABLE (initable),
+ G_PRIORITY_DEFAULT, cancellable,
+ e_async_closure_callback, closure);
+
+ result = e_async_closure_wait (closure);
+
+ success = g_async_initable_init_finish (
+ G_ASYNC_INITABLE (initable), result, error);
+
+ e_async_closure_free (closure);
+
+ return success;
+}
+
+static void
+book_client_initable_init_async (GAsyncInitable *initable,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (initable), callback, user_data,
+ book_client_initable_init_async);
+
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+ book_client_run_in_dbus_thread (
+ simple, book_client_init_in_dbus_thread,
+ io_priority, cancellable);
+
+ g_object_unref (simple);
+}
+
+static gboolean
+book_client_initable_init_finish (GAsyncInitable *initable,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (initable),
+ book_client_initable_init_async), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
}
static void
@@ -764,21 +1063,26 @@ e_book_client_class_init (EBookClientClass *class)
object_class->finalize = book_client_finalize;
client_class = E_CLIENT_CLASS (class);
- client_class->get_dbus_proxy = book_client_get_dbus_proxy;
- client_class->unwrap_dbus_error = book_client_unwrap_dbus_error;
- client_class->retrieve_capabilities = book_client_retrieve_capabilities;
- client_class->retrieve_capabilities_finish = book_client_retrieve_capabilities_finish;
- client_class->retrieve_capabilities_sync = book_client_retrieve_capabilities_sync;
- client_class->get_backend_property = book_client_get_backend_property;
- client_class->get_backend_property_finish = book_client_get_backend_property_finish;
- client_class->get_backend_property_sync = book_client_get_backend_property_sync;
- client_class->set_backend_property_sync = book_client_set_backend_property_sync;
- client_class->open = book_client_open;
- client_class->open_finish = book_client_open_finish;
- client_class->open_sync = book_client_open_sync;
- client_class->refresh = book_client_refresh;
- client_class->refresh_finish = book_client_refresh_finish;
- client_class->refresh_sync = book_client_refresh_sync;
+ client_class->get_dbus_proxy = book_client_get_dbus_proxy;
+ client_class->unwrap_dbus_error = book_client_unwrap_dbus_error;
+ client_class->retrieve_capabilities_sync = book_client_retrieve_capabilities_sync;
+ client_class->get_backend_property_sync = book_client_get_backend_property_sync;
+ client_class->set_backend_property_sync = book_client_set_backend_property_sync;
+ client_class->open_sync = book_client_open_sync;
+ client_class->refresh_sync = book_client_refresh_sync;
+}
+
+static void
+e_book_client_initable_init (GInitableIface *interface)
+{
+ interface->init = book_client_initable_init;
+}
+
+static void
+e_book_client_async_initable_init (GAsyncInitableIface *interface)
+{
+ interface->init_async = book_client_initable_init_async;
+ interface->init_finish = book_client_initable_init_finish;
}
static void
@@ -789,6 +1093,10 @@ e_book_client_init (EBookClient *client)
UNLOCK_FACTORY ();
client->priv = E_BOOK_CLIENT_GET_PRIVATE (client);
+
+ /* This is so the D-Bus thread can schedule signal emissions
+ * on the thread-default context for this thread. */
+ client->priv->main_context = g_main_context_ref_thread_default ();
}
/**
@@ -808,105 +1116,11 @@ EBookClient *
e_book_client_new (ESource *source,
GError **error)
{
- EBookClient *client;
- GError *err = NULL;
- GDBusConnection *connection;
- const gchar *uid;
- gchar *object_path = NULL;
-
- g_return_val_if_fail (source != NULL, NULL);
g_return_val_if_fail (E_IS_SOURCE (source), NULL);
- LOCK_FACTORY ();
- /* XXX Oops, e_book_client_new() forgot to take a GCancellable. */
- if (!gdbus_book_factory_activate (NULL, &err)) {
- UNLOCK_FACTORY ();
- if (err) {
- unwrap_dbus_error (err, &err);
- g_warning ("%s: Failed to run book factory: %s", G_STRFUNC, err->message);
- g_propagate_error (error, err);
- } else {
- g_warning ("%s: Failed to run book factory: Unknown error", G_STRFUNC);
- g_set_error_literal (error, E_CLIENT_ERROR, E_CLIENT_ERROR_DBUS_ERROR, _("Failed to run book factory"));
- }
-
- return NULL;
- }
-
- uid = e_source_get_uid (source);
-
- client = g_object_new (E_TYPE_BOOK_CLIENT, "source", source, NULL);
- UNLOCK_FACTORY ();
-
- e_dbus_address_book_factory_call_open_address_book_sync (
- book_factory, uid, &object_path, NULL, &err);
-
- /* Sanity check. */
- g_return_val_if_fail (
- ((object_path != NULL) && (err == NULL)) ||
- ((object_path == NULL) && (err != NULL)), NULL);
-
- if (err != NULL) {
- unwrap_dbus_error (err, &err);
- g_propagate_error (error, err);
- g_object_unref (client);
- return NULL;
- }
-
- connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (book_factory));
-
- client->priv->dbus_proxy = G_DBUS_PROXY (e_gdbus_book_proxy_new_sync (
- connection,
- G_DBUS_PROXY_FLAGS_NONE,
- ADDRESS_BOOK_DBUS_SERVICE_NAME,
- object_path,
- NULL, &err));
-
- g_free (object_path);
-
- /* Sanity check. */
- g_return_val_if_fail (
- ((client->priv->dbus_proxy != NULL) && (err == NULL)) ||
- ((client->priv->dbus_proxy == NULL) && (err != NULL)), NULL);
-
- if (err != NULL) {
- unwrap_dbus_error (err, &err);
- g_propagate_error (error, err);
- g_object_unref (client);
- return NULL;
- }
-
- client->priv->gone_signal_id = g_dbus_connection_signal_subscribe (
- connection,
- "org.freedesktop.DBus", /* sender */
- "org.freedesktop.DBus", /* interface */
- "NameOwnerChanged", /* member */
- "/org/freedesktop/DBus", /* object_path */
- "org.gnome.evolution.dataserver.AddressBook", /* arg0 */
- G_DBUS_SIGNAL_FLAGS_NONE,
- gdbus_book_client_connection_gone_cb, client, NULL);
-
- g_signal_connect (
- connection, "closed",
- G_CALLBACK (gdbus_book_client_closed_cb), client);
-
- g_signal_connect (
- client->priv->dbus_proxy, "backend_error",
- G_CALLBACK (backend_error_cb), client);
- g_signal_connect (
- client->priv->dbus_proxy, "readonly",
- G_CALLBACK (readonly_cb), client);
- g_signal_connect (
- client->priv->dbus_proxy, "online",
- G_CALLBACK (online_cb), client);
- g_signal_connect (
- client->priv->dbus_proxy, "opened",
- G_CALLBACK (opened_cb), client);
- g_signal_connect (
- client->priv->dbus_proxy, "backend-property-changed",
- G_CALLBACK (backend_property_changed_cb), client);
-
- return client;
+ return g_initable_new (
+ E_TYPE_BOOK_CLIENT, NULL, error,
+ "source", source, NULL);
}
#define SELF_UID_PATH_ID "org.gnome.evolution-data-server.addressbook"
@@ -953,12 +1167,12 @@ make_me_card (void)
/**
* e_book_client_get_self:
* @registry: an #ESourceRegistry
- * @contact: (out): an #EContact pointer to set
- * @client: (out): an #EBookClient pointer to set
+ * @out_contact: (out): an #EContact pointer to set
+ * @out_client: (out): an #EBookClient pointer to set
* @error: a #GError to set on failure
*
* Get the #EContact referring to the user of the address book
- * and set it in @contact and @client.
+ * and set it in @out_contact and @out_client.
*
* Returns: %TRUE if successful, otherwise %FALSE.
*
@@ -966,67 +1180,74 @@ make_me_card (void)
**/
gboolean
e_book_client_get_self (ESourceRegistry *registry,
- EContact **contact,
- EBookClient **client,
+ EContact **out_contact,
+ EBookClient **out_client,
GError **error)
{
+ EBookClient *book_client;
ESource *source;
- GError *local_error = NULL;
+ EContact *contact = NULL;
GSettings *settings;
gchar *uid;
+ gboolean success;
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
- g_return_val_if_fail (contact != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
+ g_return_val_if_fail (out_contact != NULL, FALSE);
+ g_return_val_if_fail (out_client != NULL, FALSE);
source = e_source_registry_ref_builtin_address_book (registry);
- *client = e_book_client_new (source, &local_error);
+ book_client = e_book_client_new (source, error);
g_object_unref (source);
- if (!*client) {
- g_propagate_error (error, local_error);
+ if (book_client == NULL)
return FALSE;
- }
-
- if (!e_client_open_sync (E_CLIENT (*client), FALSE, NULL, &local_error)) {
- g_object_unref (*client);
- *client = NULL;
- g_propagate_error (error, local_error);
+ success = e_client_open_sync (
+ E_CLIENT (book_client), FALSE, NULL, error);
+ if (!success) {
+ g_object_unref (book_client);
return FALSE;
}
+ *out_client = book_client;
+
settings = g_settings_new (SELF_UID_PATH_ID);
uid = g_settings_get_string (settings, SELF_UID_KEY);
g_object_unref (settings);
if (uid) {
- gboolean got;
-
- /* Don't care about errors because we'll create a new card on failure */
- got = e_book_client_get_contact_sync (*client, uid, contact, NULL, NULL);
+ /* Don't care about errors because
+ * we'll create a new card on failure. */
+ e_book_client_get_contact_sync (
+ book_client, uid, &contact, NULL, NULL);
g_free (uid);
- if (got)
+
+ if (contact != NULL) {
+ *out_client = book_client;
+ *out_contact = contact;
return TRUE;
+ }
}
uid = NULL;
- *contact = make_me_card ();
- if (!e_book_client_add_contact_sync (*client, *contact, &uid, NULL, &local_error)) {
- g_object_unref (*client);
- *client = NULL;
- g_object_unref (*contact);
- *contact = NULL;
- g_propagate_error (error, local_error);
+ contact = make_me_card ();
+ success = e_book_client_add_contact_sync (
+ book_client, contact, &uid, NULL, error);
+ if (!success) {
+ g_object_unref (book_client);
+ g_object_unref (contact);
return FALSE;
}
- if (uid) {
- e_contact_set (*contact, E_CONTACT_UID, uid);
+ if (uid != NULL) {
+ e_contact_set (contact, E_CONTACT_UID, uid);
g_free (uid);
}
- e_book_client_set_self (*client, *contact, NULL);
+ e_book_client_set_self (book_client, contact, NULL);
+
+ *out_client = book_client;
+ *out_contact = contact;
return TRUE;
}
@@ -1092,6 +1313,27 @@ e_book_client_is_self (EContact *contact)
return is_self;
}
+/* Helper for e_book_client_add_contact() */
+static void
+book_client_add_contact_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ e_book_client_add_contact_sync (
+ E_BOOK_CLIENT (source_object),
+ async_context->contact,
+ &async_context->uid,
+ cancellable, &error);
+
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
+}
+
/**
* e_book_client_add_contact:
* @client: an #EBookClient
@@ -1108,45 +1350,45 @@ e_book_client_is_self (EContact *contact)
**/
void
e_book_client_add_contact (EBookClient *client,
- /* const */ EContact *contact,
+ EContact *contact,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- gchar *vcard, *gdbus_vcard = NULL;
- const gchar *strv[2];
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- g_return_if_fail (contact != NULL);
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
g_return_if_fail (E_IS_CONTACT (contact));
- vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
- strv[1] = NULL;
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->contact = g_object_ref (contact);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (client), callback, user_data,
+ e_book_client_add_contact);
+
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
- g_return_if_fail (strv[0] != NULL);
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- e_client_proxy_call_strv (
- E_CLIENT (client),
- strv, cancellable, callback, user_data,
- e_book_client_add_contact,
- e_gdbus_book_call_add_contacts,
- NULL, NULL, NULL,
- e_gdbus_book_call_add_contacts_finish,
- NULL);
+ g_simple_async_result_run_in_thread (
+ simple, book_client_add_contact_thread,
+ G_PRIORITY_DEFAULT, cancellable);
- g_free (vcard);
- g_free (gdbus_vcard);
+ g_object_unref (simple);
}
/**
* e_book_client_add_contact_finish:
* @client: an #EBookClient
* @result: a #GAsyncResult
- * @added_uid: (out): UID of a newly added contact; can be %NULL
+ * @out_added_uid: (out): UID of a newly added contact; can be %NULL
* @error: (out): a #GError to set an error, if any
*
* Finishes previous call of e_book_client_add_contact() and
- * sets @added_uid to a UID of a newly added contact.
+ * sets @out_added_uid to a UID of a newly added contact.
* This string should be freed with g_free().
*
* Note: This is not modifying original #EContact.
@@ -1158,37 +1400,43 @@ e_book_client_add_contact (EBookClient *client,
gboolean
e_book_client_add_contact_finish (EBookClient *client,
GAsyncResult *result,
- gchar **added_uid,
+ gchar **out_added_uid,
GError **error)
{
- gboolean res;
- gchar **out_uids = NULL;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- res = e_client_proxy_call_finish_strv (
- E_CLIENT (client), result, &out_uids, error,
- e_book_client_add_contact);
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (client),
+ e_book_client_add_contact), FALSE);
- if (res && out_uids && added_uid) {
- *added_uid = g_strdup (out_uids[0]);
- } else {
- if (added_uid)
- *added_uid = NULL;
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+
+ g_return_val_if_fail (async_context->uid != NULL, FALSE);
+
+ if (out_added_uid != NULL) {
+ *out_added_uid = async_context->uid;
+ async_context->uid = NULL;
}
- g_strfreev (out_uids);
- return res;
+ return TRUE;
}
/**
* e_book_client_add_contact_sync:
* @client: an #EBookClient
* @contact: an #EContact
- * @added_uid: (out): UID of a newly added contact; can be %NULL
+ * @out_added_uid: (out): UID of a newly added contact; can be %NULL
* @cancellable: a #GCancellable; can be %NULL
* @error: (out): a #GError to set an error, if any
*
* Adds @contact to @client and
- * sets @added_uid to a UID of a newly added contact.
+ * sets @out_added_uid to a UID of a newly added contact.
* This string should be freed with g_free().
*
* Note: This is not modifying original @contact, thus if it's needed,
@@ -1200,44 +1448,60 @@ e_book_client_add_contact_finish (EBookClient *client,
**/
gboolean
e_book_client_add_contact_sync (EBookClient *client,
- /* const */ EContact *contact,
- gchar **added_uid,
+ EContact *contact,
+ gchar **out_added_uid,
GCancellable *cancellable,
GError **error)
{
- gboolean res;
- gchar *vcard, *gdbus_vcard = NULL, **out_uids = NULL;
- const gchar *strv[2];
+ GSList link = { contact, NULL };
+ GSList *uids = NULL;
+ gboolean success;
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
+ g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
if (client->priv->dbus_proxy == NULL) {
set_proxy_gone_error (error);
return FALSE;
}
- vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
- strv[1] = NULL;
+ success = e_book_client_add_contacts_sync (
+ client, &link, &uids, cancellable, error);
- g_return_val_if_fail (strv[0] != NULL, FALSE);
+ /* Sanity check. */
+ g_return_val_if_fail (
+ (success && (uids != NULL)) ||
+ (!success && (uids == NULL)), FALSE);
- res = e_client_proxy_call_sync_strv__strv (
- E_CLIENT (client), strv, &out_uids, cancellable, error,
- e_gdbus_book_call_add_contacts_sync);
+ if (uids != NULL) {
+ if (out_added_uid != NULL)
+ *out_added_uid = g_strdup (uids->data);
- if (res && out_uids && added_uid) {
- *added_uid = g_strdup (out_uids[0]);
- } else {
- if (added_uid)
- *added_uid = NULL;
+ g_slist_free_full (uids, (GDestroyNotify) g_free);
}
- g_strfreev (out_uids);
- g_free (vcard);
- g_free (gdbus_vcard);
+ return success;
+}
+
+/* Helper for e_book_client_add_contacts() */
+static void
+book_client_add_contacts_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- return res;
+ e_book_client_add_contacts_sync (
+ E_BOOK_CLIENT (source_object),
+ async_context->object_list,
+ &async_context->string_list,
+ cancellable, &error);
+
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
}
/**
@@ -1256,40 +1520,47 @@ e_book_client_add_contact_sync (EBookClient *client,
**/
void
e_book_client_add_contacts (EBookClient *client,
- /* const */ GSList *contacts,
+ GSList *contacts,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- gchar **array;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
g_return_if_fail (contacts != NULL);
- array = contact_slist_to_utf8_vcard_array (contacts);
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->object_list = g_slist_copy_deep (
+ contacts, (GCopyFunc) g_object_ref, NULL);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (client), callback, user_data,
+ e_book_client_add_contacts);
+
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- e_client_proxy_call_strv (
- E_CLIENT (client),
- (const gchar * const *) array,
- cancellable, callback, user_data,
- e_book_client_add_contacts,
- e_gdbus_book_call_add_contacts,
- NULL, NULL, NULL,
- e_gdbus_book_call_add_contacts_finish,
- NULL);
+ g_simple_async_result_run_in_thread (
+ simple, book_client_add_contacts_thread,
+ G_PRIORITY_DEFAULT, cancellable);
- g_strfreev (array);
+ g_object_unref (simple);
}
/**
* e_book_client_add_contacts_finish:
* @client: an #EBookClient
* @result: a #GAsyncResult
- * @added_uids: (out) (element-type utf8) (allow-none): UIDs of newly added
- * contacts; can be %NULL
+ * @out_added_uids: (out) (element-type utf8) (allow-none): UIDs of
+ * newly added contacts; can be %NULL
* @error: (out): a #GError to set an error, if any
*
* Finishes previous call of e_book_client_add_contacts() and
- * sets @added_uids to the UIDs of newly added contacts if successful.
+ * sets @out_added_uids to the UIDs of newly added contacts if successful.
* This #GSList should be freed with e_client_util_free_string_slist().
*
* If any of the contacts cannot be inserted, all of the insertions will be
@@ -1304,39 +1575,42 @@ e_book_client_add_contacts (EBookClient *client,
gboolean
e_book_client_add_contacts_finish (EBookClient *client,
GAsyncResult *result,
- GSList **added_uids,
+ GSList **out_added_uids,
GError **error)
{
- gboolean res;
- gchar **out_uids = NULL;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- res = e_client_proxy_call_finish_strv (
- E_CLIENT (client), result, &out_uids, error,
- e_book_client_add_contacts);
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (client),
+ e_book_client_add_contacts), FALSE);
- if (res && out_uids && added_uids) {
- *added_uids = e_client_util_strv_to_slist ((const gchar * const*) out_uids);
- } else {
- if (added_uids)
- *added_uids = NULL;
- }
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
- g_strfreev (out_uids);
+ if (out_added_uids != NULL) {
+ *out_added_uids = async_context->string_list;
+ async_context->string_list = NULL;
+ }
- return res;
+ return TRUE;
}
/**
* e_book_client_add_contacts_sync:
* @client: an #EBookClient
* @contacts: (element-type EContact): a #GSList of #EContact objects to add
- * @added_uids: (out) (element-type utf8) (allow-none): UIDs of newly added
- * contacts; can be %NULL
+ * @out_added_uids: (out) (element-type utf8) (allow-none): UIDs of newly
+ * added contacts; can be %NULL
* @cancellable: a #GCancellable; can be %NULL
* @error: (out): a #GError to set an error, if any
*
* Adds @contacts to @client and
- * sets @added_uids to the UIDs of newly added contacts if successful.
+ * sets @out_added_uids to the UIDs of newly added contacts if successful.
* This #GSList should be freed with e_client_util_free_string_slist().
*
* If any of the contacts cannot be inserted, all of the insertions will be
@@ -1351,40 +1625,91 @@ e_book_client_add_contacts_finish (EBookClient *client,
**/
gboolean
e_book_client_add_contacts_sync (EBookClient *client,
- /* const */ GSList *contacts,
- GSList **added_uids,
+ GSList *contacts,
+ GSList **out_added_uids,
GCancellable *cancellable,
GError **error)
{
- gboolean res;
- gchar **array, **out_uids = NULL;
+ GSList *link;
+ gchar **strv;
+ gchar **uids = NULL;
+ gboolean success;
+ gint ii = 0;
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
+ g_return_val_if_fail (contacts != NULL, FALSE);
if (client->priv->dbus_proxy == NULL) {
set_proxy_gone_error (error);
return FALSE;
}
- array = contact_slist_to_utf8_vcard_array (contacts);
+ /* Build a string array, ensuring each element is valid UTF-8. */
+ strv = g_new0 (gchar *, g_slist_length (contacts) + 1);
+ for (link = contacts; link != NULL; link = g_slist_next (link)) {
+ EVCard *vcard;
+ gchar *string;
+
+ vcard = E_VCARD (link->data);
+ string = e_vcard_to_string (vcard, EVC_FORMAT_VCARD_30);
+ strv[ii++] = e_util_utf8_make_valid (string);
+ g_free (string);
+ }
+
+ success = e_dbus_address_book_call_create_contacts_sync (
+ client->priv->dbus_proxy,
+ (const gchar * const *) strv,
+ &uids, cancellable, error);
- res = e_client_proxy_call_sync_strv__strv (
- E_CLIENT (client),
- (const gchar * const *) array,
- &out_uids, cancellable, error,
- e_gdbus_book_call_add_contacts_sync);
+ g_strfreev (strv);
- if (res && out_uids && added_uids) {
- *added_uids = e_client_util_strv_to_slist ((const gchar * const*) out_uids);
- } else {
- if (added_uids)
- *added_uids = NULL;
+ /* Sanity check. */
+ g_return_val_if_fail (
+ (success && (uids != NULL)) ||
+ (!success && (uids == NULL)), FALSE);
+
+ if (!success)
+ return FALSE;
+
+ /* XXX We should have passed the string array directly
+ * back to the caller instead of building a linked
+ * list. This is unnecessary work. */
+ if (out_added_uids != NULL) {
+ GSList *tmp = NULL;
+ gint ii;
+
+ /* Take ownership of the string array elements. */
+ for (ii = 0; uids[ii] != NULL; ii++) {
+ tmp = g_slist_prepend (tmp, uids[ii]);
+ uids[ii] = NULL;
+ }
+
+ *out_added_uids = g_slist_reverse (tmp);
}
- g_strfreev (out_uids);
- g_strfreev (array);
+ g_strfreev (uids);
- return res;
+ return TRUE;
+}
+
+/* Helper for e_book_client_modify_contact() */
+static void
+book_client_modify_contact_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ e_book_client_modify_contact_sync (
+ E_BOOK_CLIENT (source_object),
+ async_context->contact,
+ cancellable, &error);
+
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
}
/**
@@ -1403,33 +1728,34 @@ e_book_client_add_contacts_sync (EBookClient *client,
**/
void
e_book_client_modify_contact (EBookClient *client,
- /* const */ EContact *contact,
+ EContact *contact,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- gchar *vcard, *gdbus_vcard = NULL;
- const gchar *strv[2];
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- g_return_if_fail (contact != NULL);
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
g_return_if_fail (E_IS_CONTACT (contact));
- vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
- strv[1] = NULL;
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->contact = g_object_ref (contact);
- g_return_if_fail (strv[0] != NULL);
+ simple = g_simple_async_result_new (
+ G_OBJECT (client), callback, user_data,
+ e_book_client_modify_contact);
- e_client_proxy_call_strv (
- E_CLIENT (client),
- strv, cancellable, callback, user_data,
- e_book_client_modify_contact,
- e_gdbus_book_call_modify_contacts,
- e_gdbus_book_call_modify_contacts_finish,
- NULL, NULL, NULL, NULL);
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
- g_free (vcard);
- g_free (gdbus_vcard);
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, book_client_modify_contact_thread,
+ G_PRIORITY_DEFAULT, cancellable);
+
+ g_object_unref (simple);
}
/**
@@ -1449,9 +1775,17 @@ e_book_client_modify_contact_finish (EBookClient *client,
GAsyncResult *result,
GError **error)
{
- return e_client_proxy_call_finish_void (
- E_CLIENT (client), result, error,
- e_book_client_modify_contact);
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (client),
+ e_book_client_modify_contact), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
}
/**
@@ -1469,36 +1803,37 @@ e_book_client_modify_contact_finish (EBookClient *client,
**/
gboolean
e_book_client_modify_contact_sync (EBookClient *client,
- /* const */ EContact *contact,
+ EContact *contact,
GCancellable *cancellable,
GError **error)
{
- gboolean res;
- gchar *vcard, *gdbus_vcard = NULL;
- const gchar *strv[2];
+ GSList link = { contact, NULL };
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
+ g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
- if (client->priv->dbus_proxy == NULL) {
- set_proxy_gone_error (error);
- return FALSE;
- }
-
- vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
- strv[1] = NULL;
+ return e_book_client_modify_contacts_sync (
+ client, &link, cancellable, error);
+}
- g_return_val_if_fail (strv[0] != NULL, FALSE);
+/* Helper for e_book_client_modify_contacts() */
+static void
+book_client_modify_contacts_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
- res = e_client_proxy_call_sync_strv__void (
- E_CLIENT (client),
- strv, cancellable, error,
- e_gdbus_book_call_modify_contacts_sync);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- g_free (vcard);
- g_free (gdbus_vcard);
+ e_book_client_modify_contacts_sync (
+ E_BOOK_CLIENT (source_object),
+ async_context->object_list,
+ cancellable, &error);
- return res;
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
}
/**
@@ -1517,27 +1852,35 @@ e_book_client_modify_contact_sync (EBookClient *client,
**/
void
e_book_client_modify_contacts (EBookClient *client,
- /* const */ GSList *contacts,
+ GSList *contacts,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- gchar **array;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
g_return_if_fail (contacts != NULL);
- array = contact_slist_to_utf8_vcard_array (contacts);
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->object_list = g_slist_copy_deep (
+ contacts, (GCopyFunc) g_object_ref, NULL);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (client), callback, user_data,
+ e_book_client_modify_contacts);
+
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
- e_client_proxy_call_strv (
- E_CLIENT (client),
- (const gchar * const *) array,
- cancellable, callback, user_data,
- e_book_client_modify_contacts,
- e_gdbus_book_call_modify_contacts,
- e_gdbus_book_call_modify_contacts_finish,
- NULL, NULL, NULL, NULL);
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- g_strfreev (array);
+ g_simple_async_result_run_in_thread (
+ simple, book_client_modify_contacts_thread,
+ G_PRIORITY_DEFAULT, cancellable);
+
+ g_object_unref (simple);
}
/**
@@ -1557,9 +1900,17 @@ e_book_client_modify_contacts_finish (EBookClient *client,
GAsyncResult *result,
GError **error)
{
- return e_client_proxy_call_finish_void (
- E_CLIENT (client), result, error,
- e_book_client_modify_contacts);
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (client),
+ e_book_client_modify_contacts), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
}
/**
@@ -1577,12 +1928,14 @@ e_book_client_modify_contacts_finish (EBookClient *client,
**/
gboolean
e_book_client_modify_contacts_sync (EBookClient *client,
- /* const */ GSList *contacts,
+ GSList *contacts,
GCancellable *cancellable,
GError **error)
{
- gboolean res;
- gchar **array;
+ GSList *link;
+ gchar **strv;
+ gboolean success;
+ gint ii = 0;
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
g_return_val_if_fail (contacts != NULL, FALSE);
@@ -1592,17 +1945,46 @@ e_book_client_modify_contacts_sync (EBookClient *client,
return FALSE;
}
- array = contact_slist_to_utf8_vcard_array (contacts);
+ /* Build a string array, ensuring each element is valid UTF-8. */
+ strv = g_new0 (gchar *, g_slist_length (contacts) + 1);
+ for (link = contacts; link != NULL; link = g_slist_next (link)) {
+ EVCard *vcard;
+ gchar *string;
+
+ vcard = E_VCARD (link->data);
+ string = e_vcard_to_string (vcard, EVC_FORMAT_VCARD_30);
+ strv[ii++] = e_util_utf8_make_valid (string);
+ g_free (string);
+ }
+
+ success = e_dbus_address_book_call_modify_contacts_sync (
+ client->priv->dbus_proxy,
+ (const gchar * const *) strv,
+ cancellable, error);
+
+ g_strfreev (strv);
+
+ return success;
+}
+
+/* Helper for e_book_client_remove_contact() */
+static void
+book_client_remove_contact_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
- res = e_client_proxy_call_sync_strv__void (
- E_CLIENT (client),
- (const gchar * const *) array,
- cancellable, error,
- e_gdbus_book_call_modify_contacts_sync);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- g_strfreev (array);
+ e_book_client_remove_contact_sync (
+ E_BOOK_CLIENT (source_object),
+ async_context->contact,
+ cancellable, &error);
- return res;
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
}
/**
@@ -1626,31 +2008,29 @@ e_book_client_remove_contact (EBookClient *client,
GAsyncReadyCallback callback,
gpointer user_data)
{
- const gchar *uid, *safe_uid;
- const gchar *strv[2];
- gchar *gdbus_uid = NULL;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- g_return_if_fail (contact != NULL);
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
g_return_if_fail (E_IS_CONTACT (contact));
- uid = e_contact_get_const ( E_CONTACT (contact), E_CONTACT_UID);
- g_return_if_fail (uid != NULL);
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->contact = g_object_ref (contact);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (client), callback, user_data,
+ e_book_client_remove_contact);
- safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
- g_return_if_fail (safe_uid != NULL);
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
- strv[0] = safe_uid;
- strv[1] = NULL;
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- e_client_proxy_call_strv (
- E_CLIENT (client),
- strv, cancellable, callback, user_data,
- e_book_client_remove_contact,
- e_gdbus_book_call_remove_contacts,
- e_gdbus_book_call_remove_contacts_finish,
- NULL, NULL, NULL, NULL);
+ g_simple_async_result_run_in_thread (
+ simple, book_client_remove_contact_thread,
+ G_PRIORITY_DEFAULT, cancellable);
- g_free (gdbus_uid);
+ g_object_unref (simple);
}
/**
@@ -1670,9 +2050,17 @@ e_book_client_remove_contact_finish (EBookClient *client,
GAsyncResult *result,
GError **error)
{
- return e_client_proxy_call_finish_void (
- E_CLIENT (client), result, error,
- e_book_client_remove_contact);
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (client),
+ e_book_client_remove_contact), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
}
/**
@@ -1690,40 +2078,40 @@ e_book_client_remove_contact_finish (EBookClient *client,
**/
gboolean
e_book_client_remove_contact_sync (EBookClient *client,
- /* const */ EContact *contact,
+ EContact *contact,
GCancellable *cancellable,
GError **error)
{
- gboolean res;
- const gchar *strv[2];
- const gchar *uid, *safe_uid;
- gchar *gdbus_uid = NULL;
+ const gchar *uid;
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
- if (client->priv->dbus_proxy == NULL) {
- set_proxy_gone_error (error);
- return FALSE;
- }
-
- uid = e_contact_get_const (E_CONTACT (contact), E_CONTACT_UID);
+ uid = e_contact_get_const (contact, E_CONTACT_UID);
g_return_val_if_fail (uid != NULL, FALSE);
- safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
- g_return_val_if_fail (safe_uid != NULL, FALSE);
+ return e_book_client_remove_contact_by_uid_sync (
+ client, uid, cancellable, error);
+}
- strv[0] = safe_uid;
- strv[1] = NULL;
+/* Helper for e_book_client_remove_contact_by_uid() */
+static void
+book_client_remove_contact_by_uid_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
- res = e_client_proxy_call_sync_strv__void (
- E_CLIENT (client),
- strv, cancellable, error,
- e_gdbus_book_call_remove_contacts_sync);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- g_free (gdbus_uid);
+ e_book_client_remove_contact_by_uid_sync (
+ E_BOOK_CLIENT (source_object),
+ async_context->uid,
+ cancellable, &error);
- return res;
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
}
/**
@@ -1747,27 +2135,29 @@ e_book_client_remove_contact_by_uid (EBookClient *client,
GAsyncReadyCallback callback,
gpointer user_data)
{
- const gchar *safe_uid;
- gchar *gdbus_uid = NULL;
- const gchar *strv[2];
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
g_return_if_fail (uid != NULL);
- safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
- g_return_if_fail (safe_uid != NULL);
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->uid = g_strdup (uid);
- strv[0] = safe_uid;
- strv[1] = NULL;
+ simple = g_simple_async_result_new (
+ G_OBJECT (client), callback, user_data,
+ e_book_client_remove_contact_by_uid);
+
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
- e_client_proxy_call_strv (
- E_CLIENT (client),
- strv, cancellable, callback, user_data,
- e_book_client_remove_contact_by_uid,
- e_gdbus_book_call_remove_contacts,
- e_gdbus_book_call_remove_contacts_finish,
- NULL, NULL, NULL, NULL);
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- g_free (gdbus_uid);
+ g_simple_async_result_run_in_thread (
+ simple, book_client_remove_contact_by_uid_thread,
+ G_PRIORITY_DEFAULT, cancellable);
+
+ g_object_unref (simple);
}
/**
@@ -1787,9 +2177,17 @@ e_book_client_remove_contact_by_uid_finish (EBookClient *client,
GAsyncResult *result,
GError **error)
{
- return e_client_proxy_call_finish_void (
- E_CLIENT (client), result, error,
- e_book_client_remove_contact_by_uid);
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (client),
+ e_book_client_remove_contact_by_uid), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
}
/**
@@ -1811,32 +2209,33 @@ e_book_client_remove_contact_by_uid_sync (EBookClient *client,
GCancellable *cancellable,
GError **error)
{
- gboolean res;
- const gchar *safe_uid;
- gchar *gdbus_uid = NULL;
- const gchar *strv[2];
+ GSList link = { (gpointer) uid, NULL };
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
g_return_val_if_fail (uid != NULL, FALSE);
- if (client->priv->dbus_proxy == NULL) {
- set_proxy_gone_error (error);
- return FALSE;
- }
-
- safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
- g_return_val_if_fail (safe_uid != NULL, FALSE);
+ return e_book_client_remove_contacts_sync (
+ client, &link, cancellable, error);
+}
- strv[0] = safe_uid;
- strv[1] = NULL;
+/* Helper for e_book_client_remove_contacts() */
+static void
+book_client_remove_contacts_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
- res = e_client_proxy_call_sync_strv__void (
- E_CLIENT (client), strv, cancellable, error,
- e_gdbus_book_call_remove_contacts_sync);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- g_free (gdbus_uid);
+ e_book_client_remove_contacts_sync (
+ E_BOOK_CLIENT (source_object),
+ async_context->string_list,
+ cancellable, &error);
- return res;
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
}
/**
@@ -1863,23 +2262,30 @@ e_book_client_remove_contacts (EBookClient *client,
GAsyncReadyCallback callback,
gpointer user_data)
{
- gchar **strv;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
g_return_if_fail (uids != NULL);
- strv = e_client_util_slist_to_strv (uids);
- g_return_if_fail (strv != NULL);
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->string_list = g_slist_copy_deep (
+ (GSList *) uids, (GCopyFunc) g_strdup, NULL);
- e_client_proxy_call_strv (
- E_CLIENT (client),
- (const gchar * const *) strv,
- cancellable, callback, user_data,
- e_book_client_remove_contacts,
- e_gdbus_book_call_remove_contacts,
- e_gdbus_book_call_remove_contacts_finish,
- NULL, NULL, NULL, NULL);
+ simple = g_simple_async_result_new (
+ G_OBJECT (client), callback, user_data,
+ e_book_client_remove_contacts);
- g_strfreev (strv);
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, book_client_remove_contacts_thread,
+ G_PRIORITY_DEFAULT, cancellable);
+
+ g_object_unref (simple);
}
/**
@@ -1899,9 +2305,17 @@ e_book_client_remove_contacts_finish (EBookClient *client,
GAsyncResult *result,
GError **error)
{
- return e_client_proxy_call_finish_void (
- E_CLIENT (client), result, error,
- e_book_client_remove_contacts);
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (client),
+ e_book_client_remove_contacts), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
}
/**
@@ -1926,8 +2340,9 @@ e_book_client_remove_contacts_sync (EBookClient *client,
GCancellable *cancellable,
GError **error)
{
- gboolean res;
gchar **strv;
+ gboolean success;
+ gint ii = 0;
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
g_return_val_if_fail (uids != NULL, FALSE);
@@ -1937,17 +2352,41 @@ e_book_client_remove_contacts_sync (EBookClient *client,
return FALSE;
}
- strv = e_client_util_slist_to_strv (uids);
- g_return_val_if_fail (strv != NULL, FALSE);
+ strv = g_new0 (gchar *, g_slist_length ((GSList *) uids) + 1);
+ while (uids != NULL) {
+ strv[ii++] = e_util_utf8_make_valid (uids->data);
+ uids = g_slist_next (uids);
+ }
- res = e_client_proxy_call_sync_strv__void (
- E_CLIENT (client), (const gchar * const *) strv,
- cancellable, error,
- e_gdbus_book_call_remove_contacts_sync);
+ success = e_dbus_address_book_call_remove_contacts_sync (
+ client->priv->dbus_proxy,
+ (const gchar * const *) strv,
+ cancellable, error);
g_strfreev (strv);
- return res;
+ return success;
+}
+
+/* Helper for e_book_client_get_contact() */
+static void
+book_client_get_contact_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ e_book_client_get_contact_sync (
+ E_BOOK_CLIENT (source_object),
+ async_context->uid,
+ &async_context->contact,
+ cancellable, &error);
+
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
}
/**
@@ -1971,35 +2410,40 @@ e_book_client_get_contact (EBookClient *client,
GAsyncReadyCallback callback,
gpointer user_data)
{
- const gchar *safe_uid;
- gchar *gdbus_uid = NULL;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
g_return_if_fail (uid != NULL);
- safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
- g_return_if_fail (safe_uid != NULL);
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->uid = g_strdup (uid);
- e_client_proxy_call_string (
- E_CLIENT (client),
- safe_uid, cancellable, callback, user_data,
- e_book_client_get_contact,
- e_gdbus_book_call_get_contact,
- NULL, NULL,
- e_gdbus_book_call_get_contact_finish,
- NULL, NULL);
+ simple = g_simple_async_result_new (
+ G_OBJECT (client), callback, user_data,
+ e_book_client_get_contact);
+
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, book_client_get_contact_thread,
+ G_PRIORITY_DEFAULT, cancellable);
- g_free (gdbus_uid);
+ g_object_unref (simple);
}
/**
* e_book_client_get_contact_finish:
* @client: an #EBookClient
* @result: a #GAsyncResult
- * @contact: (out): an #EContact for previously given uid
+ * @out_contact: (out): an #EContact for previously given uid
* @error: (out): a #GError to set an error, if any
*
* Finishes previous call of e_book_client_get_contact().
- * If successful, then the @contact is set to newly allocated
+ * If successful, then the @out_contact is set to newly allocated
* #EContact, which should be freed with g_object_unref().
*
* Returns: %TRUE if successful, %FALSE otherwise.
@@ -2009,39 +2453,41 @@ e_book_client_get_contact (EBookClient *client,
gboolean
e_book_client_get_contact_finish (EBookClient *client,
GAsyncResult *result,
- EContact **contact,
+ EContact **out_contact,
GError **error)
{
- gboolean res;
- gchar *vcard = NULL;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- g_return_val_if_fail (contact != NULL, FALSE);
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (client),
+ e_book_client_get_contact), FALSE);
- res = e_client_proxy_call_finish_string (
- E_CLIENT (client),
- result, &vcard, error,
- e_book_client_get_contact);
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
- if (vcard && res)
- *contact = e_contact_new_from_vcard (vcard);
- else
- *contact = NULL;
+ g_return_val_if_fail (async_context->contact != NULL, FALSE);
- g_free (vcard);
+ if (out_contact != NULL)
+ *out_contact = g_object_ref (async_context->contact);
- return res;
+ return TRUE;
}
/**
* e_book_client_get_contact_sync:
* @client: an #EBookClient
* @uid: a unique string ID specifying the contact
- * @contact: (out): an #EContact for given @uid
+ * @out_contact: (out): an #EContact for given @uid
* @cancellable: a #GCancellable; can be %NULL
* @error: (out): a #GError to set an error, if any
*
* Receive #EContact from the @client for the gived @uid.
- * If successful, then the @contact is set to newly allocated
+ * If successful, then the @out_contact is set to newly allocated
* #EContact, which should be freed with g_object_unref().
*
* Returns: %TRUE if successful, %FALSE otherwise.
@@ -2051,40 +2497,64 @@ e_book_client_get_contact_finish (EBookClient *client,
gboolean
e_book_client_get_contact_sync (EBookClient *client,
const gchar *uid,
- EContact **contact,
+ EContact **out_contact,
GCancellable *cancellable,
GError **error)
{
- gboolean res;
- const gchar *safe_uid;
- gchar *vcard = NULL, *gdbus_uid = NULL;
+ gchar *utf8_uid;
+ gchar *vcard = NULL;
+ gboolean success;
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
g_return_val_if_fail (uid != NULL, FALSE);
- g_return_val_if_fail (contact != NULL, FALSE);
+ g_return_val_if_fail (out_contact != NULL, FALSE);
if (client->priv->dbus_proxy == NULL) {
set_proxy_gone_error (error);
return FALSE;
}
- safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
- g_return_val_if_fail (safe_uid != NULL, FALSE);
+ utf8_uid = e_util_utf8_make_valid (uid);
+
+ success = e_dbus_address_book_call_get_contact_sync (
+ client->priv->dbus_proxy,
+ utf8_uid, &vcard, cancellable, error);
+
+ /* Sanity check. */
+ g_return_val_if_fail (
+ (success && (vcard != NULL)) ||
+ (!success && (vcard == NULL)), FALSE);
+
+ if (vcard != NULL) {
+ *out_contact =
+ e_contact_new_from_vcard_with_uid (vcard, utf8_uid);
+ g_free (vcard);
+ }
+
+ g_free (utf8_uid);
+
+ return success;
+}
- res = e_client_proxy_call_sync_string__string (
- E_CLIENT (client),
- safe_uid, &vcard, cancellable, error,
- e_gdbus_book_call_get_contact_sync);
+/* Helper for e_book_client_get_contacts() */
+static void
+book_client_get_contacts_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
- if (vcard && res)
- *contact = e_contact_new_from_vcard_with_uid (vcard, safe_uid);
- else
- *contact = NULL;
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- g_free (gdbus_uid);
- g_free (vcard);
+ e_book_client_get_contacts_sync (
+ E_BOOK_CLIENT (source_object),
+ async_context->sexp,
+ &async_context->object_list,
+ cancellable, &error);
- return res;
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
}
/**
@@ -2111,33 +2581,42 @@ e_book_client_get_contacts (EBookClient *client,
GAsyncReadyCallback callback,
gpointer user_data)
{
- gchar *gdbus_sexp = NULL;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
g_return_if_fail (sexp != NULL);
- e_client_proxy_call_string (
- E_CLIENT (client),
- e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
- cancellable, callback, user_data,
- e_book_client_get_contacts,
- e_gdbus_book_call_get_contact_list,
- NULL, NULL, NULL,
- e_gdbus_book_call_get_contact_list_finish,
- NULL);
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->sexp = g_strdup (sexp);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (client), callback, user_data,
+ e_book_client_get_contacts);
+
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- g_free (gdbus_sexp);
+ g_simple_async_result_run_in_thread (
+ simple, book_client_get_contacts_thread,
+ G_PRIORITY_DEFAULT, cancellable);
+
+ g_object_unref (simple);
}
/**
* e_book_client_get_contacts_finish:
* @client: an #EBookClient
* @result: a #GAsyncResult
- * @contacts: (element-type EContact) (out): a #GSList of matched #EContact-s
+ * @out_contacts: (element-type EContact) (out): a #GSList of matched
+ * #EContact-s
* @error: (out): a #GError to set an error, if any
*
* Finishes previous call of e_book_client_get_contacts().
- * If successful, then the @contacts is set to newly allocated list of #EContact-s,
- * which should be freed with e_client_util_free_object_slist().
+ * If successful, then the @out_contacts is set to newly allocated list of
+ * #EContact-s, which should be freed with e_client_util_free_object_slist().
*
* Returns: %TRUE if successful, %FALSE otherwise.
*
@@ -2146,47 +2625,42 @@ e_book_client_get_contacts (EBookClient *client,
gboolean
e_book_client_get_contacts_finish (EBookClient *client,
GAsyncResult *result,
- GSList **contacts,
+ GSList **out_contacts,
GError **error)
{
- gboolean res;
- gchar **vcards = NULL;
-
- g_return_val_if_fail (contacts != NULL, FALSE);
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- res = e_client_proxy_call_finish_strv (
- E_CLIENT (client),
- result, &vcards, error,
- e_book_client_get_contacts);
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (client),
+ e_book_client_get_contacts), FALSE);
- if (vcards && res) {
- gint ii;
- GSList *slist = NULL;
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- for (ii = 0; vcards[ii]; ii++) {
- slist = g_slist_prepend (slist, e_contact_new_from_vcard (vcards[ii]));
- }
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
- *contacts = g_slist_reverse (slist);
- } else {
- *contacts = NULL;
+ if (out_contacts != NULL) {
+ *out_contacts = async_context->object_list;
+ async_context->object_list = NULL;
}
- g_strfreev (vcards);
-
- return res;
+ return TRUE;
}
/**
* e_book_client_get_contacts_sync:
* @client: an #EBookClient
* @sexp: an S-expression representing the query
- * @contacts: (element-type EContact) (out): a #GSList of matched #EContact-s
+ * @out_contacts: (element-type EContact) (out): a #GSList of matched
+ * #EContact-s
* @cancellable: a #GCancellable; can be %NULL
* @error: (out): a #GError to set an error, if any
*
* Query @client with @sexp, receiving a list of contacts which matched.
- * If successful, then the @contacts is set to newly allocated #GSList of
+ * If successful, then the @out_contacts is set to newly allocated #GSList of
* #EContact-s, which should be freed with e_client_util_free_object_slist().
*
* Note: @sexp can be obtained through #EBookQuery, by converting it
@@ -2199,46 +2673,73 @@ e_book_client_get_contacts_finish (EBookClient *client,
gboolean
e_book_client_get_contacts_sync (EBookClient *client,
const gchar *sexp,
- GSList **contacts,
+ GSList **out_contacts,
GCancellable *cancellable,
GError **error)
{
- gboolean res;
- gchar *gdbus_sexp = NULL;
+ gchar *utf8_sexp;
gchar **vcards = NULL;
+ gboolean success;
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
g_return_val_if_fail (sexp != NULL, FALSE);
- g_return_val_if_fail (contacts != NULL, FALSE);
+ g_return_val_if_fail (out_contacts != NULL, FALSE);
if (client->priv->dbus_proxy == NULL) {
set_proxy_gone_error (error);
return FALSE;
}
- res = e_client_proxy_call_sync_string__strv (
- E_CLIENT (client),
- e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
- &vcards, cancellable, error,
- e_gdbus_book_call_get_contact_list_sync);
+ utf8_sexp = e_util_utf8_make_valid (sexp);
+
+ success = e_dbus_address_book_call_get_contact_list_sync (
+ client->priv->dbus_proxy,
+ utf8_sexp, &vcards, cancellable, error);
+
+ g_free (utf8_sexp);
- if (vcards && res) {
+ /* Sanity check. */
+ g_return_val_if_fail (
+ (success && (vcards != NULL)) ||
+ (!success && (vcards == NULL)), FALSE);
+
+ if (vcards != NULL) {
+ EContact *contact;
+ GSList *tmp = NULL;
gint ii;
- GSList *slist = NULL;
- for (ii = 0; vcards[ii]; ii++) {
- slist = g_slist_prepend (slist, e_contact_new_from_vcard (vcards[ii]));
+ for (ii = 0; vcards[ii] != NULL; ii++) {
+ contact = e_contact_new_from_vcard (vcards[ii]);
+ tmp = g_slist_prepend (tmp, contact);
}
- *contacts = g_slist_reverse (slist);
- } else {
- *contacts = NULL;
+ *out_contacts = g_slist_reverse (tmp);
+
+ g_strfreev (vcards);
}
- g_free (gdbus_sexp);
- g_strfreev (vcards);
+ return success;
+}
+
+/* Helper for e_book_client_get_contacts_uids() */
+static void
+book_client_get_contacts_uids_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
+
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ e_book_client_get_contacts_uids_sync (
+ E_BOOK_CLIENT (source_object),
+ async_context->sexp,
+ &async_context->string_list,
+ cancellable, &error);
- return res;
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
}
/**
@@ -2265,32 +2766,41 @@ e_book_client_get_contacts_uids (EBookClient *client,
GAsyncReadyCallback callback,
gpointer user_data)
{
- gchar *gdbus_sexp = NULL;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
g_return_if_fail (sexp != NULL);
- e_client_proxy_call_string (
- E_CLIENT (client),
- e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
- cancellable, callback, user_data,
- e_book_client_get_contacts_uids,
- e_gdbus_book_call_get_contact_list_uids,
- NULL, NULL, NULL,
- e_gdbus_book_call_get_contact_list_uids_finish,
- NULL);
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->sexp = g_strdup (sexp);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (client), callback, user_data,
+ e_book_client_get_contacts_uids);
+
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- g_free (gdbus_sexp);
+ g_simple_async_result_run_in_thread (
+ simple, book_client_get_contacts_uids_thread,
+ G_PRIORITY_DEFAULT, cancellable);
+
+ g_object_unref (simple);
}
/**
* e_book_client_get_contacts_uids_finish:
* @client: an #EBookClient
* @result: a #GAsyncResult
- * @contacts_uids: (element-type utf8) (out): a #GSList of matched contacts UIDs stored as strings
+ * @out_contact_uids: (element-type utf8) (out): a #GSList of matched
+ * contact UIDs stored as strings
* @error: (out): a #GError to set an error, if any
*
* Finishes previous call of e_book_client_get_contacts_uids().
- * If successful, then the @contacts_uids is set to newly allocated list
+ * If successful, then the @out_contact_uids is set to newly allocated list
* of UID strings, which should be freed with e_client_util_free_string_slist().
*
* Returns: %TRUE if successful, %FALSE otherwise.
@@ -2300,47 +2810,42 @@ e_book_client_get_contacts_uids (EBookClient *client,
gboolean
e_book_client_get_contacts_uids_finish (EBookClient *client,
GAsyncResult *result,
- GSList **contacts_uids,
+ GSList **out_contact_uids,
GError **error)
{
- gboolean res;
- gchar **uids = NULL;
-
- g_return_val_if_fail (contacts_uids != NULL, FALSE);
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
- res = e_client_proxy_call_finish_strv (
- E_CLIENT (client),
- result, &uids, error,
- e_book_client_get_contacts_uids);
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (client),
+ e_book_client_get_contacts_uids), FALSE);
- if (uids && res) {
- gint ii;
- GSList *slist = NULL;
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- for (ii = 0; uids[ii]; ii++) {
- slist = g_slist_prepend (slist, g_strdup (uids[ii]));
- }
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
- *contacts_uids = g_slist_reverse (slist);
- } else {
- *contacts_uids = NULL;
+ if (out_contact_uids != NULL) {
+ *out_contact_uids = async_context->string_list;
+ async_context->string_list = NULL;
}
- g_strfreev (uids);
-
- return res;
+ return TRUE;
}
/**
* e_book_client_get_contacts_uids_sync:
* @client: an #EBookClient
* @sexp: an S-expression representing the query
- * @contacts_uids: (element-type utf8) (out): a #GSList of matched contacts UIDs stored as strings
+ * @out_contact_uids: (element-type utf8) (out): a #GSList of matched
+ * contacts UIDs stored as strings
* @cancellable: a #GCancellable; can be %NULL
* @error: (out): a #GError to set an error, if any
*
* Query @client with @sexp, receiving a list of contacts UIDs which matched.
- * If successful, then the @contacts_uids is set to newly allocated list
+ * If successful, then the @out_contact_uids is set to newly allocated list
* of UID strings, which should be freed with e_client_util_free_string_slist().
*
* Note: @sexp can be obtained through #EBookQuery, by converting it
@@ -2353,46 +2858,76 @@ e_book_client_get_contacts_uids_finish (EBookClient *client,
gboolean
e_book_client_get_contacts_uids_sync (EBookClient *client,
const gchar *sexp,
- GSList **contacts_uids,
+ GSList **out_contact_uids,
GCancellable *cancellable,
GError **error)
{
- gboolean res;
- gchar *gdbus_sexp = NULL;
+ gchar *utf8_sexp;
gchar **uids = NULL;
+ gboolean success;
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
g_return_val_if_fail (sexp != NULL, FALSE);
- g_return_val_if_fail (contacts_uids != NULL, FALSE);
+ g_return_val_if_fail (out_contact_uids != NULL, FALSE);
if (client->priv->dbus_proxy == NULL) {
set_proxy_gone_error (error);
return FALSE;
}
- res = e_client_proxy_call_sync_string__strv (
- E_CLIENT (client),
- e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
- &uids, cancellable, error,
- e_gdbus_book_call_get_contact_list_uids_sync);
+ utf8_sexp = e_util_utf8_make_valid (sexp);
- if (uids && res) {
+ success = e_dbus_address_book_call_get_contact_list_uids_sync (
+ client->priv->dbus_proxy,
+ utf8_sexp, &uids, cancellable, error);
+
+ g_free (utf8_sexp);
+
+ /* Sanity check. */
+ g_return_val_if_fail (
+ (success && (uids != NULL)) ||
+ (!success && (uids == NULL)), FALSE);
+
+ /* XXX We should have passed the string array directly
+ * back to the caller instead of building a linked
+ * list. This is unnecessary work. */
+ if (uids != NULL) {
+ GSList *tmp = NULL;
gint ii;
- GSList *slist = NULL;
- for (ii = 0; uids[ii]; ii++) {
- slist = g_slist_prepend (slist, g_strdup (uids[ii]));
+ /* Take ownership of the string array elements. */
+ for (ii = 0; uids[ii] != NULL; ii++) {
+ tmp = g_slist_prepend (tmp, uids[ii]);
+ uids[ii] = NULL;
}
- *contacts_uids = g_slist_reverse (slist);
- } else {
- *contacts_uids = NULL;
+ *out_contact_uids = g_slist_reverse (tmp);
+
+ g_free (uids);
}
- g_free (gdbus_sexp);
- g_strfreev (uids);
+ return success;
+}
+
+/* Helper for e_book_client_get_view() */
+static void
+book_client_get_view_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
+{
+ AsyncContext *async_context;
+ GError *error = NULL;
- return res;
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ e_book_client_get_view_sync (
+ E_BOOK_CLIENT (source_object),
+ async_context->sexp,
+ &async_context->client_view,
+ cancellable, &error);
+
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
}
/**
@@ -2419,73 +2954,41 @@ e_book_client_get_view (EBookClient *client,
GAsyncReadyCallback callback,
gpointer user_data)
{
- gchar *gdbus_sexp = NULL;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ g_return_if_fail (E_IS_BOOK_CLIENT (client));
g_return_if_fail (sexp != NULL);
- e_client_proxy_call_string (
- E_CLIENT (client),
- e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
- cancellable, callback, user_data,
- e_book_client_get_view,
- e_gdbus_book_call_get_view,
- NULL, NULL,
- e_gdbus_book_call_get_view_finish, NULL, NULL);
-
- g_free (gdbus_sexp);
-}
-
-static gboolean
-complete_get_view (EBookClient *client,
- gboolean res,
- gchar *view_path,
- EBookClientView **view,
- GError **error)
-{
- g_return_val_if_fail (view != NULL, FALSE);
-
- if (view_path && res && book_factory) {
- GDBusConnection *connection;
- GError *local_error = NULL;
-
- connection = g_dbus_proxy_get_connection (
- G_DBUS_PROXY (book_factory));
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->sexp = g_strdup (sexp);
- *view = g_initable_new (
- E_TYPE_BOOK_CLIENT_VIEW,
- NULL, &local_error,
- "client", client,
- "connection", connection,
- "object-path", view_path,
- NULL);
+ simple = g_simple_async_result_new (
+ G_OBJECT (client), callback, user_data,
+ e_book_client_get_view);
- if (local_error != NULL) {
- unwrap_dbus_error (local_error, error);
- res = FALSE;
- }
- } else {
- *view = NULL;
- res = FALSE;
- }
+ g_simple_async_result_set_check_cancellable (simple, cancellable);
- if (!*view && error && !*error)
- g_set_error_literal (error, E_CLIENT_ERROR, E_CLIENT_ERROR_DBUS_ERROR, _("Cannot get connection to view"));
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
- g_free (view_path);
+ g_simple_async_result_run_in_thread (
+ simple, book_client_get_view_thread,
+ G_PRIORITY_DEFAULT, cancellable);
- return res;
+ g_object_unref (simple);
}
/**
* e_book_client_get_view_finish:
* @client: an #EBookClient
* @result: a #GAsyncResult
- * @view: (out): an #EBookClientView
+ * @out_view: (out): an #EBookClientView
* @error: (out): a #GError to set an error, if any
*
* Finishes previous call of e_book_client_get_view().
- * If successful, then the @view is set to newly allocated #EBookClientView,
- * which should be freed with g_object_unref().
+ * If successful, then the @out_view is set to newly allocated
+ * #EBookClientView, which should be freed with g_object_unref().
*
* Returns: %TRUE if successful, %FALSE otherwise.
*
@@ -2494,33 +2997,42 @@ complete_get_view (EBookClient *client,
gboolean
e_book_client_get_view_finish (EBookClient *client,
GAsyncResult *result,
- EBookClientView **view,
+ EBookClientView **out_view,
GError **error)
{
- gboolean res;
- gchar *view_path = NULL;
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (client),
+ e_book_client_get_view), FALSE);
- g_return_val_if_fail (view != NULL, FALSE);
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
- res = e_client_proxy_call_finish_string (
- E_CLIENT (client),
- result, &view_path, error,
- e_book_client_get_view);
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
- return complete_get_view (client, res, view_path, view, error);
+ g_return_val_if_fail (async_context->client_view != NULL, FALSE);
+
+ if (out_view != NULL)
+ *out_view = g_object_ref (async_context->client_view);
+
+ return TRUE;
}
/**
* e_book_client_get_view_sync:
* @client: an #EBookClient
* @sexp: an S-expression representing the query
- * @view: (out) an #EBookClientView
+ * @out_view: (out) an #EBookClientView
* @cancellable: a #GCancellable; can be %NULL
* @error: (out): a #GError to set an error, if any
*
* Query @client with @sexp, creating an #EBookClientView.
- * If successful, then the @view is set to newly allocated #EBookClientView,
- * which should be freed with g_object_unref().
+ * If successful, then the @out_view is set to newly allocated
+ * #EBookClientView, which should be freed with g_object_unref().
*
* Note: @sexp can be obtained through #EBookQuery, by converting it
* to a string with e_book_query_to_string().
@@ -2532,31 +3044,62 @@ e_book_client_get_view_finish (EBookClient *client,
gboolean
e_book_client_get_view_sync (EBookClient *client,
const gchar *sexp,
- EBookClientView **view,
+ EBookClientView **out_view,
GCancellable *cancellable,
GError **error)
{
- gboolean res;
- gchar *gdbus_sexp = NULL;
- gchar *view_path = NULL;
+ gchar *utf8_sexp;
+ gchar *object_path = NULL;
+ gboolean success;
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
g_return_val_if_fail (sexp != NULL, FALSE);
- g_return_val_if_fail (view != NULL, FALSE);
+ g_return_val_if_fail (out_view != NULL, FALSE);
if (client->priv->dbus_proxy == NULL) {
set_proxy_gone_error (error);
return FALSE;
}
- res = e_client_proxy_call_sync_string__string (
- E_CLIENT (client),
- e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
- &view_path, cancellable, error,
- e_gdbus_book_call_get_view_sync);
+ utf8_sexp = e_util_utf8_make_valid (sexp);
- g_free (gdbus_sexp);
+ success = e_dbus_address_book_call_get_view_sync (
+ client->priv->dbus_proxy, utf8_sexp,
+ &object_path, cancellable, error);
+
+ g_free (utf8_sexp);
+
+ /* Sanity check. */
+ g_return_val_if_fail (
+ (success && (object_path != NULL)) ||
+ (!success && (object_path == NULL)), FALSE);
+
+ if (object_path != NULL) {
+ GDBusConnection *connection;
+ EBookClientView *client_view;
+
+ connection = g_dbus_proxy_get_connection (
+ G_DBUS_PROXY (client->priv->dbus_proxy));
+
+ client_view = g_initable_new (
+ E_TYPE_BOOK_CLIENT_VIEW,
+ cancellable, error,
+ "client", client,
+ "connection", connection,
+ "object-path", object_path,
+ NULL);
+
+ /* XXX Would have been easier to return the
+ * EBookClientView directly rather than
+ * through an "out" parameter. */
+ if (client_view != NULL)
+ *out_view = client_view;
+ else
+ success = FALSE;
+
+ g_free (object_path);
+ }
- return complete_get_view (client, res, view_path, view, error);
+ return success;
}
diff --git a/addressbook/libebook/e-book-client.h b/addressbook/libebook/e-book-client.h
index 26da1d6..1e782ab 100644
--- a/addressbook/libebook/e-book-client.h
+++ b/addressbook/libebook/e-book-client.h
@@ -124,8 +124,8 @@ GType e_book_client_get_type (void) G_GNUC_CONST;
EBookClient * e_book_client_new (ESource *source,
GError **error);
gboolean e_book_client_get_self (ESourceRegistry *registry,
- EContact **contact,
- EBookClient **client,
+ EContact **out_contact,
+ EBookClient **out_client,
GError **error);
gboolean e_book_client_set_self (EBookClient *client,
EContact *contact,
@@ -139,11 +139,11 @@ void e_book_client_add_contact (EBookClient *client,
gboolean e_book_client_add_contact_finish
(EBookClient *client,
GAsyncResult *result,
- gchar **added_uid,
+ gchar **out_added_uid,
GError **error);
gboolean e_book_client_add_contact_sync (EBookClient *client,
EContact *contact,
- gchar **added_uid,
+ gchar **out_added_uid,
GCancellable *cancellable,
GError **error);
void e_book_client_add_contacts (EBookClient *client,
@@ -154,11 +154,11 @@ void e_book_client_add_contacts (EBookClient *client,
gboolean e_book_client_add_contacts_finish
(EBookClient *client,
GAsyncResult *result,
- GSList **added_uids,
+ GSList **out_added_uids,
GError **error);
gboolean e_book_client_add_contacts_sync (EBookClient *client,
GSList *contacts,
- GSList **added_uids,
+ GSList **out_added_uids,
GCancellable *cancellable,
GError **error);
void e_book_client_modify_contact (EBookClient *client,
@@ -240,11 +240,11 @@ void e_book_client_get_contact (EBookClient *client,
gboolean e_book_client_get_contact_finish
(EBookClient *client,
GAsyncResult *result,
- EContact **contact,
+ EContact **out_contact,
GError **error);
gboolean e_book_client_get_contact_sync (EBookClient *client,
const gchar *uid,
- EContact **contact,
+ EContact **out_contact,
GCancellable *cancellable,
GError **error);
void e_book_client_get_contacts (EBookClient *client,
@@ -259,7 +259,7 @@ gboolean e_book_client_get_contacts_finish
GError **error);
gboolean e_book_client_get_contacts_sync (EBookClient *client,
const gchar *sexp,
- GSList **contacts,
+ GSList **out_contacts,
GCancellable *cancellable,
GError **error);
void e_book_client_get_contacts_uids (EBookClient *client,
@@ -270,12 +270,12 @@ void e_book_client_get_contacts_uids (EBookClient *client,
gboolean e_book_client_get_contacts_uids_finish
(EBookClient *client,
GAsyncResult *result,
- GSList **contacts_uids,
+ GSList **out_contact_uids,
GError **error);
gboolean e_book_client_get_contacts_uids_sync
(EBookClient *client,
const gchar *sexp,
- GSList **contacts_uids,
+ GSList **out_contact_uids,
GCancellable *cancellable,
GError **error);
void e_book_client_get_view (EBookClient *client,
@@ -285,11 +285,11 @@ void e_book_client_get_view (EBookClient *client,
gpointer user_data);
gboolean e_book_client_get_view_finish (EBookClient *client,
GAsyncResult *result,
- EBookClientView **view,
+ EBookClientView **out_view,
GError **error);
gboolean e_book_client_get_view_sync (EBookClient *client,
const gchar *sexp,
- EBookClientView **view,
+ EBookClientView **out_view,
GCancellable *cancellable,
GError **error);
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index 948dca1..200d8e2 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -81,6 +81,8 @@ book_backend_get_backend_property (EBookBackend *backend,
e_data_book_respond_get_backend_property (book, opid, NULL, "TRUE");
} else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_OPENING)) {
e_data_book_respond_get_backend_property (book, opid, NULL, "FALSE");
+ } else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_REVISION)) {
+ e_data_book_respond_get_backend_property (book, opid, NULL, "0");
} else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_ONLINE)) {
e_data_book_respond_get_backend_property (book, opid, NULL, e_backend_get_online (E_BACKEND (backend)) ? "TRUE" : "FALSE");
} else if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_READONLY)) {
@@ -497,17 +499,8 @@ e_book_backend_open (EBookBackend *backend,
g_mutex_lock (&backend->priv->clients_mutex);
if (e_book_backend_is_opened (backend)) {
- gboolean online;
- gboolean writable;
-
g_mutex_unlock (&backend->priv->clients_mutex);
- online = e_backend_get_online (E_BACKEND (backend));
- writable = e_book_backend_get_writable (backend);
-
- e_data_book_report_online (book, online);
- e_data_book_report_readonly (book, !writable);
-
e_data_book_respond_open (book, opid, NULL);
} else {
g_mutex_unlock (&backend->priv->clients_mutex);
@@ -1246,23 +1239,16 @@ e_book_backend_notify_error (EBookBackend *backend,
* Notifies all backend's clients about the current readonly state.
*
* Since: 3.2
+ *
+ * Deprecated: 3.8: Use e_book_backend_set_writable() instead.
**/
void
e_book_backend_notify_readonly (EBookBackend *backend,
gboolean is_readonly)
{
- EBookBackendPrivate *priv;
- GList *clients;
+ g_return_if_fail (E_IS_BOOK_BACKEND (backend));
- priv = backend->priv;
e_book_backend_set_writable (backend, !is_readonly);
- g_mutex_lock (&priv->clients_mutex);
-
- for (clients = priv->clients; clients != NULL; clients = g_list_next (clients))
- e_data_book_report_readonly (E_DATA_BOOK (clients->data), is_readonly);
-
- g_mutex_unlock (&priv->clients_mutex);
-
}
/**
@@ -1274,25 +1260,16 @@ e_book_backend_notify_readonly (EBookBackend *backend,
* Meant to be used by backend implementations.
*
* Since: 3.2
+ *
+ * Deprecated: 3.8: Use e_backend_set_online() instead.
**/
void
e_book_backend_notify_online (EBookBackend *backend,
gboolean is_online)
{
- EBookBackendPrivate *priv;
- GList *clients;
-
- /* XXX Disregard the argument.
- * EBackend determines this for itself. */
- is_online = e_backend_get_online (E_BACKEND (backend));
-
- priv = backend->priv;
- g_mutex_lock (&priv->clients_mutex);
-
- for (clients = priv->clients; clients != NULL; clients = g_list_next (clients))
- e_data_book_report_online (E_DATA_BOOK (clients->data), is_online);
+ g_return_if_fail (E_IS_BOOK_BACKEND (backend));
- g_mutex_unlock (&priv->clients_mutex);
+ e_backend_set_online (E_BACKEND (backend), is_online);
}
/**
diff --git a/addressbook/libedata-book/e-book-backend.h b/addressbook/libedata-book/e-book-backend.h
index 890e0a6..6358805 100644
--- a/addressbook/libedata-book/e-book-backend.h
+++ b/addressbook/libedata-book/e-book-backend.h
@@ -285,10 +285,6 @@ void e_book_backend_notify_complete (EBookBackend *backend);
void e_book_backend_notify_error (EBookBackend *backend,
const gchar *message);
-void e_book_backend_notify_readonly (EBookBackend *backend,
- gboolean is_readonly);
-void e_book_backend_notify_online (EBookBackend *backend,
- gboolean is_online);
void e_book_backend_notify_property_changed
(EBookBackend *backend,
const gchar *prop_name,
@@ -348,6 +344,10 @@ void e_book_backend_foreach_view (EBookBackend *backend,
gpointer user_data);
void e_book_backend_notify_opened (EBookBackend *backend,
GError *error);
+void e_book_backend_notify_readonly (EBookBackend *backend,
+ gboolean is_readonly);
+void e_book_backend_notify_online (EBookBackend *backend,
+ gboolean is_online);
void e_book_backend_respond_opened (EBookBackend *backend,
EDataBook *book,
guint32 opid,
diff --git a/addressbook/libedata-book/e-data-book.c b/addressbook/libedata-book/e-data-book.c
index 372647f..6591716 100644
--- a/addressbook/libedata-book/e-data-book.c
+++ b/addressbook/libedata-book/e-data-book.c
@@ -25,6 +25,9 @@
#include <glib/gi18n.h>
#include <gio/gio.h>
+/* Private D-Bus classes. */
+#include <e-dbus-address-book.h>
+
#include <libebook/libebook.h>
#include "e-data-book-factory.h"
@@ -33,15 +36,13 @@
#include "e-book-backend.h"
#include "e-book-backend-sexp.h"
-#include "e-gdbus-book.h"
-
#define E_DATA_BOOK_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_DATA_BOOK, EDataBookPrivate))
struct _EDataBookPrivate {
GDBusConnection *connection;
- EGdbusBook *dbus_interface;
+ EDBusAddressBook *dbus_interface;
EBookBackend *backend;
gchar *object_path;
@@ -89,8 +90,6 @@ typedef struct {
guint watcher_id;
union {
- /* OP_OPEN */
- gboolean only_if_exists;
/* OP_GET_CONTACT */
gchar *uid;
/* OP_REMOVE_CONTACTS */
@@ -103,7 +102,7 @@ typedef struct {
/* OP_GET_CONTACTS_UIDS */
gchar *query;
/* OP_GET_BACKEND_PROPERTY */
- gchar *prop_name;
+ const gchar *prop_name;
/* OP_REFRESH */
/* OP_CLOSE */
@@ -166,6 +165,7 @@ op_new (OperationID op,
data->book = g_object_ref (book);
data->cancellable = g_cancellable_new ();
+ /* This is optional so we can fake client requests. */
if (invocation != NULL) {
GDBusConnection *connection;
const gchar *sender;
@@ -222,9 +222,6 @@ op_unref (OperationData *data)
case OP_GET_CONTACTS_UIDS:
g_free (data->d.query);
break;
- case OP_GET_BACKEND_PROPERTY:
- g_free (data->d.prop_name);
- break;
default:
break;
}
@@ -261,11 +258,36 @@ op_dispatch (EDataBook *book,
g_mutex_unlock (&book->priv->open_lock);
}
+static OperationData *
+op_claim (EDataBook *book,
+ guint32 opid)
+{
+ OperationData *data;
+
+ g_return_val_if_fail (E_IS_DATA_BOOK (book), NULL);
+
+ e_operation_pool_release_opid (ops_pool, opid);
+
+ g_rec_mutex_lock (&book->priv->pending_ops_lock);
+ data = g_hash_table_lookup (
+ book->priv->pending_ops,
+ GUINT_TO_POINTER (opid));
+ if (data != NULL) {
+ /* Steal the hash table's reference. */
+ g_hash_table_steal (
+ book->priv->pending_ops,
+ GUINT_TO_POINTER (opid));
+ }
+ g_rec_mutex_unlock (&book->priv->pending_ops_lock);
+
+ return data;
+}
+
static void
op_complete (EDataBook *book,
guint32 opid)
{
- g_return_if_fail (book != NULL);
+ g_return_if_fail (E_IS_DATA_BOOK (book));
e_operation_pool_release_opid (ops_pool, opid);
@@ -277,11 +299,126 @@ op_complete (EDataBook *book,
}
static void
+data_book_convert_to_client_error (GError *error)
+{
+ g_return_if_fail (error != NULL);
+
+ if (error->domain != E_DATA_BOOK_ERROR)
+ return;
+
+ switch (error->code) {
+ case E_DATA_BOOK_STATUS_REPOSITORY_OFFLINE:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_REPOSITORY_OFFLINE;
+ break;
+
+ case E_DATA_BOOK_STATUS_PERMISSION_DENIED:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_PERMISSION_DENIED;
+ break;
+
+ case E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND:
+ error->domain = E_BOOK_CLIENT_ERROR;
+ error->code = E_BOOK_CLIENT_ERROR_CONTACT_NOT_FOUND;
+ break;
+
+ case E_DATA_BOOK_STATUS_CONTACTID_ALREADY_EXISTS:
+ error->domain = E_BOOK_CLIENT_ERROR;
+ error->code = E_BOOK_CLIENT_ERROR_CONTACT_ID_ALREADY_EXISTS;
+ break;
+
+ case E_DATA_BOOK_STATUS_AUTHENTICATION_FAILED:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_AUTHENTICATION_FAILED;
+ break;
+
+ case E_DATA_BOOK_STATUS_UNSUPPORTED_AUTHENTICATION_METHOD:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_UNSUPPORTED_AUTHENTICATION_METHOD;
+ break;
+
+ case E_DATA_BOOK_STATUS_TLS_NOT_AVAILABLE:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_TLS_NOT_AVAILABLE;
+ break;
+
+ case E_DATA_BOOK_STATUS_NO_SUCH_BOOK:
+ error->domain = E_BOOK_CLIENT_ERROR;
+ error->code = E_BOOK_CLIENT_ERROR_NO_SUCH_BOOK;
+ break;
+
+ case E_DATA_BOOK_STATUS_BOOK_REMOVED:
+ error->domain = E_BOOK_CLIENT_ERROR;
+ error->code = E_BOOK_CLIENT_ERROR_NO_SUCH_SOURCE;
+ break;
+
+ case E_DATA_BOOK_STATUS_OFFLINE_UNAVAILABLE:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_OFFLINE_UNAVAILABLE;
+ break;
+
+ case E_DATA_BOOK_STATUS_SEARCH_SIZE_LIMIT_EXCEEDED:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_SEARCH_SIZE_LIMIT_EXCEEDED;
+ break;
+
+ case E_DATA_BOOK_STATUS_SEARCH_TIME_LIMIT_EXCEEDED:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_SEARCH_TIME_LIMIT_EXCEEDED;
+ break;
+
+ case E_DATA_BOOK_STATUS_INVALID_QUERY:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_INVALID_QUERY;
+ break;
+
+ case E_DATA_BOOK_STATUS_QUERY_REFUSED:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_QUERY_REFUSED;
+ break;
+
+ case E_DATA_BOOK_STATUS_COULD_NOT_CANCEL:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_COULD_NOT_CANCEL;
+ break;
+
+ case E_DATA_BOOK_STATUS_NO_SPACE:
+ error->domain = E_BOOK_CLIENT_ERROR;
+ error->code = E_BOOK_CLIENT_ERROR_NO_SPACE;
+ break;
+
+ case E_DATA_BOOK_STATUS_INVALID_ARG:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_INVALID_ARG;
+ break;
+
+ case E_DATA_BOOK_STATUS_NOT_SUPPORTED:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_NOT_SUPPORTED;
+ break;
+
+ case E_DATA_BOOK_STATUS_NOT_OPENED:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_NOT_OPENED;
+ break;
+
+ case E_DATA_BOOK_STATUS_UNSUPPORTED_FIELD:
+ case E_DATA_BOOK_STATUS_OTHER_ERROR:
+ case E_DATA_BOOK_STATUS_INVALID_SERVER_VERSION:
+ error->domain = E_CLIENT_ERROR;
+ error->code = E_CLIENT_ERROR_OTHER_ERROR;
+ break;
+
+ default:
+ g_warn_if_reached ();
+ }
+}
+
+static void
operation_thread (gpointer data,
gpointer user_data)
{
OperationData *op = data;
- OperationData *cancel_op;
EBookBackend *backend;
GHashTableIter iter;
gpointer value;
@@ -292,7 +429,7 @@ operation_thread (gpointer data,
case OP_OPEN:
e_book_backend_open (
backend, op->book, op->id,
- op->cancellable, op->d.only_if_exists);
+ op->cancellable, FALSE);
break;
case OP_ADD_CONTACTS:
@@ -352,11 +489,13 @@ operation_thread (gpointer data,
card_sexp = e_book_backend_sexp_new (op->d.query);
if (!card_sexp) {
- error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_QUERY, NULL);
- /* Translators: This is prefix to a detailed error message */
- g_prefix_error (&error, "%s", _("Invalid query: "));
- e_gdbus_book_emit_get_view_done (op->book->priv->dbus_interface, op->id, error, NULL);
- g_error_free (error);
+ g_dbus_method_invocation_return_error_literal (
+ op->invocation,
+ E_CLIENT_ERROR,
+ E_CLIENT_ERROR_INVALID_QUERY,
+ _("Invalid query"));
+
+ op_complete (op->book, op->id);
break;
}
@@ -377,16 +516,23 @@ operation_thread (gpointer data,
if (error != NULL) {
/* Translators: This is prefix to a detailed error message */
g_prefix_error (&error, "%s", _("Invalid query: "));
- e_gdbus_book_emit_get_view_done (op->book->priv->dbus_interface, op->id, error, NULL);
- g_error_free (error);
+ data_book_convert_to_client_error (error);
+ g_dbus_method_invocation_take_error (
+ op->invocation, error);
+
+ op_complete (op->book, op->id);
g_free (object_path);
break;
}
e_book_backend_add_view (backend, view);
- e_gdbus_book_emit_get_view_done (op->book->priv->dbus_interface, op->id, NULL, object_path);
+ e_dbus_address_book_complete_get_view (
+ op->book->priv->dbus_interface,
+ op->invocation,
+ object_path);
+ op_complete (op->book, op->id);
g_free (object_path);
}
break;
@@ -399,11 +545,17 @@ operation_thread (gpointer data,
g_hash_table_iter_init (&iter, op->book->priv->pending_ops);
while (g_hash_table_iter_next (&iter, NULL, &value)) {
- cancel_op = (OperationData *) value;
+ OperationData *cancel_op = value;
g_cancellable_cancel (cancel_op->cancellable);
}
g_rec_mutex_unlock (&op->book->priv->pending_ops_lock);
+
+ e_dbus_address_book_complete_close (
+ op->book->priv->dbus_interface,
+ op->invocation);
+
+ op_complete (op->book, op->id);
break;
}
@@ -547,25 +699,6 @@ e_data_book_create_error_fmt (EDataBookStatus status,
return error;
}
-static void
-data_book_return_error (GDBusMethodInvocation *invocation,
- const GError *perror,
- const gchar *error_prefix)
-{
- GError *error;
-
- if (perror == NULL)
- error = g_error_new (E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_OTHER_ERROR, "%s", _("Unknown error"));
- else
- error = g_error_new (E_DATA_BOOK_ERROR, perror->code, "%s", perror->message);
-
- g_prefix_error (&error, "%s", error_prefix);
-
- g_dbus_method_invocation_return_gerror (invocation, error);
-
- g_error_free (error);
-}
-
/**
* e_data_book_string_slist_to_comma_string:
*
@@ -606,17 +739,13 @@ e_data_book_string_slist_to_comma_string (const GSList *strings)
}
static gboolean
-data_book_handle_open_cb (EGdbusBook *interface,
+data_book_handle_open_cb (EDBusAddressBook *interface,
GDBusMethodInvocation *invocation,
- gboolean only_if_exists,
EDataBook *book)
{
OperationData *op;
op = op_new (OP_OPEN, book, invocation);
- op->d.only_if_exists = only_if_exists;
-
- e_gdbus_book_complete_open (interface, invocation, op->id);
op_dispatch (book, op);
@@ -624,7 +753,7 @@ data_book_handle_open_cb (EGdbusBook *interface,
}
static gboolean
-data_book_handle_refresh_cb (EGdbusBook *interface,
+data_book_handle_refresh_cb (EDBusAddressBook *interface,
GDBusMethodInvocation *invocation,
EDataBook *book)
{
@@ -632,147 +761,93 @@ data_book_handle_refresh_cb (EGdbusBook *interface,
op = op_new (OP_REFRESH, book, invocation);
- e_gdbus_book_complete_refresh (interface, invocation, op->id);
-
op_dispatch (book, op);
return TRUE;
}
static gboolean
-data_book_handle_get_contact_cb (EGdbusBook *interface,
+data_book_handle_get_contact_cb (EDBusAddressBook *interface,
GDBusMethodInvocation *invocation,
const gchar *in_uid,
EDataBook *book)
{
OperationData *op;
- if (in_uid == NULL) {
- GError *error;
-
- error = e_data_book_create_error (E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND, NULL);
- /* Translators: This is prefix to a detailed error message */
- data_book_return_error (invocation, error, _("Cannot get contact: "));
- g_error_free (error);
- return TRUE;
- }
-
op = op_new (OP_GET_CONTACT, book, invocation);
op->d.uid = g_strdup (in_uid);
- e_gdbus_book_complete_get_contact (interface, invocation, op->id);
-
op_dispatch (book, op);
return TRUE;
}
static gboolean
-data_book_handle_get_contact_list_cb (EGdbusBook *interface,
+data_book_handle_get_contact_list_cb (EDBusAddressBook *interface,
GDBusMethodInvocation *invocation,
const gchar *in_query,
EDataBook *book)
{
OperationData *op;
- if (in_query == NULL || !*in_query) {
- GError *error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_QUERY, NULL);
- /* Translators: This is prefix to a detailed error message */
- data_book_return_error (invocation, error, _("Empty query: "));
- g_error_free (error);
- return TRUE;
- }
-
op = op_new (OP_GET_CONTACTS, book, invocation);
op->d.query = g_strdup (in_query);
- e_gdbus_book_complete_get_contact_list (interface, invocation, op->id);
-
op_dispatch (book, op);
return TRUE;
}
static gboolean
-data_book_handle_get_contact_list_uids_cb (EGdbusBook *interface,
+data_book_handle_get_contact_list_uids_cb (EDBusAddressBook *interface,
GDBusMethodInvocation *invocation,
const gchar *in_query,
EDataBook *book)
{
OperationData *op;
- if (in_query == NULL || !*in_query) {
- GError *error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_QUERY, NULL);
- /* Translators: This is prefix to a detailed error message */
- data_book_return_error (invocation, error, _("Empty query: "));
- g_error_free (error);
- return TRUE;
- }
-
op = op_new (OP_GET_CONTACTS_UIDS, book, invocation);
op->d.query = g_strdup (in_query);
- e_gdbus_book_complete_get_contact_list_uids (interface, invocation, op->id);
-
op_dispatch (book, op);
return TRUE;
}
static gboolean
-data_book_handle_add_contacts_cb (EGdbusBook *interface,
- GDBusMethodInvocation *invocation,
- const gchar * const *in_vcards,
- EDataBook *book)
+data_book_handle_create_contacts_cb (EDBusAddressBook *interface,
+ GDBusMethodInvocation *invocation,
+ const gchar * const *in_vcards,
+ EDataBook *book)
{
OperationData *op;
- if (in_vcards == NULL || !*in_vcards) {
- GError *error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_QUERY, NULL);
- /* Translators: This is prefix to a detailed error message */
- data_book_return_error (invocation, error, _("Cannot add contact: "));
- g_error_free (error);
- return TRUE;
- }
-
op = op_new (OP_ADD_CONTACTS, book, invocation);
op->d.vcards = e_util_strv_to_slist (in_vcards);
- e_gdbus_book_complete_add_contacts (interface, invocation, op->id);
-
op_dispatch (book, op);
return TRUE;
}
static gboolean
-data_book_handle_modify_contacts_cb (EGdbusBook *interface,
+data_book_handle_modify_contacts_cb (EDBusAddressBook *interface,
GDBusMethodInvocation *invocation,
const gchar * const *in_vcards,
EDataBook *book)
{
OperationData *op;
- if (in_vcards == NULL || !*in_vcards) {
- GError *error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_QUERY, NULL);
- /* Translators: This is prefix to a detailed error message */
- data_book_return_error (invocation, error, _("Cannot modify contacts: "));
- g_error_free (error);
- return TRUE;
- }
-
op = op_new (OP_MODIFY_CONTACTS, book, invocation);
op->d.vcards = e_util_strv_to_slist (in_vcards);
- e_gdbus_book_complete_modify_contacts (interface, invocation, op->id);
-
op_dispatch (book, op);
return TRUE;
}
static gboolean
-data_book_handle_remove_contacts_cb (EGdbusBook *interface,
+data_book_handle_remove_contacts_cb (EDBusAddressBook *interface,
GDBusMethodInvocation *invocation,
const gchar * const *in_uids,
EDataBook *book)
@@ -786,56 +861,22 @@ data_book_handle_remove_contacts_cb (EGdbusBook *interface,
op->d.ids = g_slist_prepend (op->d.ids, g_strdup (*in_uids));
}
- e_gdbus_book_complete_remove_contacts (interface, invocation, op->id);
-
op_dispatch (book, op);
return TRUE;
}
static gboolean
-data_book_handle_get_backend_property_cb (EGdbusBook *interface,
- GDBusMethodInvocation *invocation,
- const gchar *in_prop_name,
- EDataBook *book)
-{
- OperationData *op;
-
- op = op_new (OP_GET_BACKEND_PROPERTY, book, invocation);
- op->d.prop_name = g_strdup (in_prop_name);
-
- e_gdbus_book_complete_get_backend_property (interface, invocation, op->id);
-
- /* This operation is never queued. */
- e_operation_pool_push (ops_pool, op);
-
- return TRUE;
-}
-
-static gboolean
-data_book_handle_get_view_cb (EGdbusBook *interface,
+data_book_handle_get_view_cb (EDBusAddressBook *interface,
GDBusMethodInvocation *invocation,
const gchar *in_query,
EDataBook *book)
{
OperationData *op;
- if (!in_query || !*in_query) {
- GError *error;
-
- error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_QUERY, NULL);
- /* Translators: This is prefix to a detailed error message */
- data_book_return_error (invocation, error, _("Invalid query: "));
- g_error_free (error);
-
- return TRUE;
- }
-
op = op_new (OP_GET_VIEW, book, invocation);
op->d.query = g_strdup (in_query);
- e_gdbus_book_complete_get_view (interface, invocation, op->id);
-
/* This operation is never queued. */
e_operation_pool_push (ops_pool, op);
@@ -843,7 +884,7 @@ data_book_handle_get_view_cb (EGdbusBook *interface,
}
static gboolean
-data_book_handle_close_cb (EGdbusBook *interface,
+data_book_handle_close_cb (EDBusAddressBook *interface,
GDBusMethodInvocation *invocation,
EDataBook *book)
{
@@ -853,8 +894,6 @@ data_book_handle_close_cb (EGdbusBook *interface,
/* unref here makes sure the book is freed in a separate thread */
g_object_unref (book);
- e_gdbus_book_complete_close (interface, invocation, NULL);
-
/* This operation is never queued. */
e_operation_pool_push (ops_pool, op);
@@ -866,11 +905,13 @@ e_data_book_respond_open (EDataBook *book,
guint opid,
GError *error)
{
+ OperationData *data;
GError *copy = NULL;
g_return_if_fail (E_IS_DATA_BOOK (book));
- op_complete (book, opid);
+ data = op_claim (book, opid);
+ g_return_if_fail (data != NULL);
/* Translators: This is prefix to a detailed error message */
g_prefix_error (&error, "%s", _("Cannot open book: "));
@@ -882,10 +923,17 @@ e_data_book_respond_open (EDataBook *book,
copy = g_error_copy (error);
e_book_backend_notify_opened (book->priv->backend, copy);
- e_gdbus_book_emit_open_done (book->priv->dbus_interface, opid, error);
+ if (error == NULL) {
+ e_dbus_address_book_complete_open (
+ book->priv->dbus_interface,
+ data->invocation);
+ } else {
+ data_book_convert_to_client_error (error);
+ g_dbus_method_invocation_take_error (
+ data->invocation, error);
+ }
- if (error != NULL)
- g_error_free (error);
+ op_unref (data);
/* Dispatch any pending operations. */
@@ -919,17 +967,27 @@ e_data_book_respond_refresh (EDataBook *book,
guint32 opid,
GError *error)
{
+ OperationData *data;
+
g_return_if_fail (E_IS_DATA_BOOK (book));
- op_complete (book, opid);
+ data = op_claim (book, opid);
+ g_return_if_fail (data != NULL);
/* Translators: This is prefix to a detailed error message */
g_prefix_error (&error, "%s", _("Cannot refresh address book: "));
- e_gdbus_book_emit_refresh_done (book->priv->dbus_interface, opid, error);
+ if (error == NULL) {
+ e_dbus_address_book_complete_refresh (
+ book->priv->dbus_interface,
+ data->invocation);
+ } else {
+ data_book_convert_to_client_error (error);
+ g_dbus_method_invocation_take_error (
+ data->invocation, error);
+ }
- if (error)
- g_error_free (error);
+ op_unref (data);
}
/**
@@ -945,21 +1003,24 @@ e_data_book_respond_get_backend_property (EDataBook *book,
GError *error,
const gchar *prop_value)
{
- gchar *gdbus_prop_value = NULL;
+ OperationData *data;
g_return_if_fail (E_IS_DATA_BOOK (book));
- op_complete (book, opid);
-
- /* Translators: This is prefix to a detailed error message */
- g_prefix_error (&error, "%s", _("Cannot get backend property: "));
-
- e_gdbus_book_emit_get_backend_property_done (book->priv->dbus_interface, opid, error, e_util_ensure_gdbus_string (prop_value, &gdbus_prop_value));
+ data = op_claim (book, opid);
+ g_return_if_fail (data != NULL);
- if (error)
+ if (error == NULL) {
+ e_data_book_report_backend_property_changed (
+ book, data->d.prop_name, prop_value);
+ } else {
+ /* This should never happen, since all backend property
+ * requests now originate from our constructed() method. */
+ g_warning ("%s: %s", G_STRFUNC, error->message);
g_error_free (error);
+ }
- g_free (gdbus_prop_value);
+ op_unref (data);
}
/**
@@ -985,21 +1046,34 @@ e_data_book_respond_get_contact (EDataBook *book,
GError *error,
const gchar *vcard)
{
- gchar *gdbus_vcard = NULL;
+ OperationData *data;
g_return_if_fail (E_IS_DATA_BOOK (book));
- op_complete (book, opid);
+ data = op_claim (book, opid);
+ g_return_if_fail (data != NULL);
/* Translators: This is prefix to a detailed error message */
g_prefix_error (&error, "%s", _("Cannot get contact: "));
- e_gdbus_book_emit_get_contact_done (book->priv->dbus_interface, opid, error, e_util_ensure_gdbus_string (vcard, &gdbus_vcard));
+ if (error == NULL) {
+ gchar *utf8_vcard;
- if (error)
- g_error_free (error);
+ utf8_vcard = e_util_utf8_make_valid (vcard);
- g_free (gdbus_vcard);
+ e_dbus_address_book_complete_get_contact (
+ book->priv->dbus_interface,
+ data->invocation,
+ utf8_vcard);
+
+ g_free (utf8_vcard);
+ } else {
+ data_book_convert_to_client_error (error);
+ g_dbus_method_invocation_take_error (
+ data->invocation, error);
+ }
+
+ op_unref (data);
}
void
@@ -1008,27 +1082,42 @@ e_data_book_respond_get_contact_list (EDataBook *book,
GError *error,
const GSList *cards)
{
+ OperationData *data;
+
g_return_if_fail (E_IS_DATA_BOOK (book));
- if (error) {
- /* Translators: This is prefix to a detailed error message */
- g_prefix_error (&error, "%s", _("Cannot get contact list: "));
- e_gdbus_book_emit_get_contact_list_done (book->priv->dbus_interface, opid, error, NULL);
- g_error_free (error);
- } else {
- gchar **array;
- const GSList *l;
- gint i = 0;
+ data = op_claim (book, opid);
+ g_return_if_fail (data != NULL);
+
+ /* Translators: This is prefix to a detailed error message */
+ g_prefix_error (&error, "%s", _("Cannot get contact list: "));
+
+ if (error == NULL) {
+ gchar **strv;
+ guint length;
+ gint ii = 0;
- array = g_new0 (gchar *, g_slist_length ((GSList *) cards) + 1);
- for (l = cards; l != NULL; l = l->next) {
- array[i++] = e_util_utf8_make_valid (l->data);
+ length = g_slist_length ((GSList *) cards);
+ strv = g_new0 (gchar *, length + 1);
+
+ while (cards != NULL) {
+ strv[ii++] = e_util_utf8_make_valid (cards->data);
+ cards = g_slist_next ((GSList *) cards);
}
- e_gdbus_book_emit_get_contact_list_done (book->priv->dbus_interface, opid, NULL, (const gchar * const *) array);
+ e_dbus_address_book_complete_get_contact_list (
+ book->priv->dbus_interface,
+ data->invocation,
+ (const gchar * const *) strv);
- g_strfreev (array);
+ g_strfreev (strv);
+ } else {
+ data_book_convert_to_client_error (error);
+ g_dbus_method_invocation_take_error (
+ data->invocation, error);
}
+
+ op_unref (data);
}
/**
@@ -1044,27 +1133,42 @@ e_data_book_respond_get_contact_list_uids (EDataBook *book,
GError *error,
const GSList *uids)
{
+ OperationData *data;
+
g_return_if_fail (E_IS_DATA_BOOK (book));
- if (error) {
- /* Translators: This is prefix to a detailed error message */
- g_prefix_error (&error, "%s", _("Cannot get contact list uids: "));
- e_gdbus_book_emit_get_contact_list_uids_done (book->priv->dbus_interface, opid, error, NULL);
- g_error_free (error);
- } else {
- gchar **array;
- const GSList *l;
- gint i = 0;
+ data = op_claim (book, opid);
+ g_return_if_fail (data != NULL);
+
+ /* Translators: This is prefix to a detailed error message */
+ g_prefix_error (&error, "%s", _("Cannot get contact list uids: "));
+
+ if (error == NULL) {
+ gchar **strv;
+ guint length;
+ gint ii = 0;
+
+ length = g_slist_length ((GSList *) uids);
+ strv = g_new0 (gchar *, length + 1);
- array = g_new0 (gchar *, g_slist_length ((GSList *) uids) + 1);
- for (l = uids; l != NULL; l = l->next) {
- array[i++] = e_util_utf8_make_valid (l->data);
+ while (uids != NULL) {
+ strv[ii++] = e_util_utf8_make_valid (uids->data);
+ uids = g_slist_next ((GSList *) uids);
}
- e_gdbus_book_emit_get_contact_list_uids_done (book->priv->dbus_interface, opid, NULL, (const gchar * const *) array);
+ e_dbus_address_book_complete_get_contact_list_uids (
+ book->priv->dbus_interface,
+ data->invocation,
+ (const gchar * const *) strv);
- g_strfreev (array);
+ g_strfreev (strv);
+ } else {
+ data_book_convert_to_client_error (error);
+ g_dbus_method_invocation_take_error (
+ data->invocation, error);
}
+
+ op_unref (data);
}
/**
@@ -1080,38 +1184,54 @@ e_data_book_respond_create_contacts (EDataBook *book,
GError *error,
const GSList *contacts)
{
- gchar **array = NULL;
- const GSList *l;
- gint i = 0;
+ OperationData *data;
g_return_if_fail (E_IS_DATA_BOOK (book));
- op_complete (book, opid);
-
- array = g_new0 (gchar *, g_slist_length ((GSList *) contacts) + 1);
- for (l = contacts; l != NULL; l = l->next) {
- EContact *contact = E_CONTACT (l->data);
-
- array[i++] = e_util_utf8_make_valid (e_contact_get_const (contact, E_CONTACT_UID));
- }
+ data = op_claim (book, opid);
+ g_return_if_fail (data != NULL);
/* Translators: This is prefix to a detailed error message */
g_prefix_error (&error, "%s", _("Cannot add contact: "));
- e_gdbus_book_emit_add_contacts_done (book->priv->dbus_interface, opid, error, (const gchar * const *) array);
+ if (error == NULL) {
+ EBookBackend *backend;
+ gchar **strv;
+ guint length;
+ gint ii = 0;
- g_strfreev (array);
- if (error) {
- g_error_free (error);
- } else {
- for (l = contacts; l != NULL; l = l->next) {
- EContact *contact = E_CONTACT (l->data);
+ backend = e_data_book_get_backend (book);
+
+ length = g_slist_length ((GSList *) contacts);
+ strv = g_new0 (gchar *, length + 1);
+
+ while (contacts != NULL) {
+ EContact *contact = E_CONTACT (contacts->data);
+ const gchar *uid;
- e_book_backend_notify_update (e_data_book_get_backend (book), contact);
+ uid = e_contact_get_const (contact, E_CONTACT_UID);
+ strv[ii++] = e_util_utf8_make_valid (uid);
+
+ e_book_backend_notify_update (backend, contact);
+
+ contacts = g_slist_next ((GSList *) contacts);
}
- e_book_backend_notify_complete (e_data_book_get_backend (book));
+ e_dbus_address_book_complete_create_contacts (
+ book->priv->dbus_interface,
+ data->invocation,
+ (const gchar * const *) strv);
+
+ e_book_backend_notify_complete (backend);
+
+ g_strfreev (strv);
+ } else {
+ data_book_convert_to_client_error (error);
+ g_dbus_method_invocation_take_error (
+ data->invocation, error);
}
+
+ op_unref (data);
}
/**
@@ -1127,25 +1247,39 @@ e_data_book_respond_modify_contacts (EDataBook *book,
GError *error,
const GSList *contacts)
{
+ OperationData *data;
+
g_return_if_fail (E_IS_DATA_BOOK (book));
- op_complete (book, opid);
+ data = op_claim (book, opid);
+ g_return_if_fail (data != NULL);
/* Translators: This is prefix to a detailed error message */
g_prefix_error (&error, "%s", _("Cannot modify contacts: "));
- e_gdbus_book_emit_modify_contacts_done (book->priv->dbus_interface, opid, error);
+ if (error == NULL) {
+ EBookBackend *backend;
- if (error) {
- g_error_free (error);
- } else {
- const GSList *l;
+ backend = e_data_book_get_backend (book);
+
+ e_dbus_address_book_complete_modify_contacts (
+ book->priv->dbus_interface,
+ data->invocation);
- for (l = contacts; l != NULL; l = l->next)
- e_book_backend_notify_update (e_data_book_get_backend (book), l->data);
+ while (contacts != NULL) {
+ EContact *contact = E_CONTACT (contacts->data);
+ e_book_backend_notify_update (backend, contact);
+ contacts = g_slist_next ((GSList *) contacts);
+ }
- e_book_backend_notify_complete (e_data_book_get_backend (book));
+ e_book_backend_notify_complete (backend);
+ } else {
+ data_book_convert_to_client_error (error);
+ g_dbus_method_invocation_take_error (
+ data->invocation, error);
}
+
+ op_unref (data);
}
void
@@ -1154,26 +1288,38 @@ e_data_book_respond_remove_contacts (EDataBook *book,
GError *error,
const GSList *ids)
{
+ OperationData *data;
+
g_return_if_fail (E_IS_DATA_BOOK (book));
- op_complete (book, opid);
+ data = op_claim (book, opid);
+ g_return_if_fail (data != NULL);
/* Translators: This is prefix to a detailed error message */
g_prefix_error (&error, "%s", _("Cannot remove contacts: "));
- e_gdbus_book_emit_remove_contacts_done (book->priv->dbus_interface, opid, error);
+ if (error == NULL) {
+ EBookBackend *backend;
- if (error) {
- g_error_free (error);
- } else {
- const GSList *ii;
+ backend = e_data_book_get_backend (book);
+
+ e_dbus_address_book_complete_remove_contacts (
+ book->priv->dbus_interface,
+ data->invocation);
- for (ii = ids; ii; ii = ii->next)
- e_book_backend_notify_remove (e_data_book_get_backend (book), ii->data);
+ while (ids != NULL) {
+ e_book_backend_notify_remove (backend, ids->data);
+ ids = g_slist_next ((GSList *) ids);
+ }
- e_book_backend_notify_complete (e_data_book_get_backend (book));
+ e_book_backend_notify_complete (backend);
+ } else {
+ data_book_convert_to_client_error (error);
+ g_dbus_method_invocation_take_error (
+ data->invocation, error);
}
+ op_unref (data);
}
/**
@@ -1190,7 +1336,7 @@ e_data_book_report_error (EDataBook *book,
g_return_if_fail (E_IS_DATA_BOOK (book));
g_return_if_fail (message != NULL);
- e_gdbus_book_emit_backend_error (book->priv->dbus_interface, message);
+ e_dbus_address_book_emit_error (book->priv->dbus_interface, message);
}
/**
@@ -1199,6 +1345,8 @@ e_data_book_report_error (EDataBook *book,
* FIXME: Document me.
*
* Since: 3.2
+ *
+ * Deprecated: 3.8: Use e_book_backend_set_writable() instead.
**/
void
e_data_book_report_readonly (EDataBook *book,
@@ -1206,7 +1354,7 @@ e_data_book_report_readonly (EDataBook *book,
{
g_return_if_fail (E_IS_DATA_BOOK (book));
- e_gdbus_book_emit_readonly (book->priv->dbus_interface, readonly);
+ e_book_backend_set_writable (book->priv->backend, !readonly);
}
/**
@@ -1215,6 +1363,8 @@ e_data_book_report_readonly (EDataBook *book,
* FIXME: Document me.
*
* Since: 3.2
+ *
+ * Deprecated: 3.8: Use e_backend_set_online() instead.
**/
void
e_data_book_report_online (EDataBook *book,
@@ -1222,7 +1372,7 @@ e_data_book_report_online (EDataBook *book,
{
g_return_if_fail (E_IS_DATA_BOOK (book));
- e_gdbus_book_emit_online (book->priv->dbus_interface, is_online);
+ e_backend_set_online (E_BACKEND (book->priv->backend), is_online);
}
/**
@@ -1256,21 +1406,42 @@ e_data_book_report_backend_property_changed (EDataBook *book,
const gchar *prop_name,
const gchar *prop_value)
{
+ EDBusAddressBook *dbus_interface;
gchar **strv;
- /* Notifies client about certain property value change */
-
g_return_if_fail (E_IS_DATA_BOOK (book));
g_return_if_fail (prop_name != NULL);
- g_return_if_fail (*prop_name != '\0');
- g_return_if_fail (prop_value != NULL);
- strv = e_gdbus_templates_encode_two_strings (prop_name, prop_value);
- g_return_if_fail (strv != NULL);
+ if (prop_value == NULL)
+ prop_value = "";
+
+ dbus_interface = book->priv->dbus_interface;
+
+ if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
+ strv = g_strsplit (prop_value, ",", -1);
+ e_dbus_address_book_set_capabilities (
+ dbus_interface, (const gchar * const *) strv);
+ g_strfreev (strv);
+ }
+
+ if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_REVISION))
+ e_dbus_address_book_set_revision (dbus_interface, prop_value);
- e_gdbus_book_emit_backend_property_changed (book->priv->dbus_interface, (const gchar * const *) strv);
+ if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS)) {
+ strv = g_strsplit (prop_value, ",", -1);
+ e_dbus_address_book_set_required_fields (
+ dbus_interface, (const gchar * const *) strv);
+ g_strfreev (strv);
+ }
+
+ if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS)) {
+ strv = g_strsplit (prop_value, ",", -1);
+ e_dbus_address_book_set_supported_fields (
+ dbus_interface, (const gchar * const *) strv);
+ g_strfreev (strv);
+ }
- g_strfreev (strv);
+ /* Disregard anything else. */
}
static void
@@ -1415,6 +1586,63 @@ data_book_finalize (GObject *object)
G_OBJECT_CLASS (e_data_book_parent_class)->finalize (object);
}
+static void
+data_book_constructed (GObject *object)
+{
+ EDataBook *book = E_DATA_BOOK (object);
+ OperationData *op;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_data_book_parent_class)->constructed (object);
+
+ g_object_bind_property (
+ book->priv->backend, "cache-dir",
+ book->priv->dbus_interface, "cache-dir",
+ G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property (
+ book->priv->backend, "online",
+ book->priv->dbus_interface, "online",
+ G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property (
+ book->priv->backend, "writable",
+ book->priv->dbus_interface, "writable",
+ G_BINDING_SYNC_CREATE);
+
+ /* XXX Initialize the rest of the properties by faking client
+ * requests. At present it's the only way to fish values
+ * from EBookBackend's antiquated API. */
+
+ op = op_new (OP_GET_BACKEND_PROPERTY, book, NULL);
+ op->d.prop_name = CLIENT_BACKEND_PROPERTY_CAPABILITIES;
+ e_book_backend_get_backend_property (
+ book->priv->backend, book, op->id,
+ op->cancellable, op->d.prop_name);
+ op_unref (op);
+
+ op = op_new (OP_GET_BACKEND_PROPERTY, book, NULL);
+ op->d.prop_name = CLIENT_BACKEND_PROPERTY_REVISION;
+ e_book_backend_get_backend_property (
+ book->priv->backend, book, op->id,
+ op->cancellable, op->d.prop_name);
+ op_unref (op);
+
+ op = op_new (OP_GET_BACKEND_PROPERTY, book, NULL);
+ op->d.prop_name = BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS;
+ e_book_backend_get_backend_property (
+ book->priv->backend, book, op->id,
+ op->cancellable, op->d.prop_name);
+ op_unref (op);
+
+ op = op_new (OP_GET_BACKEND_PROPERTY, book, NULL);
+ op->d.prop_name = BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS;
+ e_book_backend_get_backend_property (
+ book->priv->backend, book, op->id,
+ op->cancellable, op->d.prop_name);
+ op_unref (op);
+}
+
static gboolean
data_book_initable_init (GInitable *initable,
GCancellable *cancellable,
@@ -1424,8 +1652,8 @@ data_book_initable_init (GInitable *initable,
book = E_DATA_BOOK (initable);
- return e_gdbus_book_register_object (
- book->priv->dbus_interface,
+ return g_dbus_interface_skeleton_export (
+ G_DBUS_INTERFACE_SKELETON (book->priv->dbus_interface),
book->priv->connection,
book->priv->object_path,
error);
@@ -1443,6 +1671,7 @@ e_data_book_class_init (EDataBookClass *class)
object_class->get_property = data_book_get_property;
object_class->dispose = data_book_dispose;
object_class->finalize = data_book_finalize;
+ object_class->constructed = data_book_constructed;
g_object_class_install_property (
object_class,
@@ -1495,11 +1724,13 @@ e_data_book_initable_init (GInitableIface *interface)
static void
e_data_book_init (EDataBook *ebook)
{
- EGdbusBook *dbus_interface;
+ EDBusAddressBook *dbus_interface;
ebook->priv = E_DATA_BOOK_GET_PRIVATE (ebook);
- ebook->priv->dbus_interface = e_gdbus_book_stub_new ();
+ dbus_interface = e_dbus_address_book_skeleton_new ();
+ ebook->priv->dbus_interface = dbus_interface;
+
ebook->priv->pending_ops = g_hash_table_new_full (
(GHashFunc) g_direct_hash,
(GEqualFunc) g_direct_equal,
@@ -1509,7 +1740,6 @@ e_data_book_init (EDataBook *ebook)
g_mutex_init (&ebook->priv->open_lock);
- dbus_interface = ebook->priv->dbus_interface;
g_signal_connect (
dbus_interface, "handle-open",
G_CALLBACK (data_book_handle_open_cb), ebook);
@@ -1526,8 +1756,8 @@ e_data_book_init (EDataBook *ebook)
dbus_interface, "handle-get-contact-list-uids",
G_CALLBACK (data_book_handle_get_contact_list_uids_cb), ebook);
g_signal_connect (
- dbus_interface, "handle-add-contacts",
- G_CALLBACK (data_book_handle_add_contacts_cb), ebook);
+ dbus_interface, "handle-create-contacts",
+ G_CALLBACK (data_book_handle_create_contacts_cb), ebook);
g_signal_connect (
dbus_interface, "handle-modify-contacts",
G_CALLBACK (data_book_handle_modify_contacts_cb), ebook);
@@ -1535,9 +1765,6 @@ e_data_book_init (EDataBook *ebook)
dbus_interface, "handle-remove-contacts",
G_CALLBACK (data_book_handle_remove_contacts_cb), ebook);
g_signal_connect (
- dbus_interface, "handle-get-backend-property",
- G_CALLBACK (data_book_handle_get_backend_property_cb), ebook);
- g_signal_connect (
dbus_interface, "handle-get-view",
G_CALLBACK (data_book_handle_get_view_cb), ebook);
g_signal_connect (
diff --git a/addressbook/libedata-book/e-data-book.h b/addressbook/libedata-book/e-data-book.h
index a1b7b7a..7417a9f 100644
--- a/addressbook/libedata-book/e-data-book.h
+++ b/addressbook/libedata-book/e-data-book.h
@@ -195,10 +195,6 @@ void e_data_book_respond_get_contact_list_uids
void e_data_book_report_error (EDataBook *book,
const gchar *message);
-void e_data_book_report_readonly (EDataBook *book,
- gboolean readonly);
-void e_data_book_report_online (EDataBook *book,
- gboolean is_online);
void e_data_book_report_backend_property_changed
(EDataBook *book,
const gchar *prop_name,
@@ -214,6 +210,10 @@ void e_data_book_respond_set_backend_property
GError *error);
void e_data_book_report_opened (EDataBook *book,
const GError *error);
+void e_data_book_report_readonly (EDataBook *book,
+ gboolean readonly);
+void e_data_book_report_online (EDataBook *book,
+ gboolean is_online);
#endif /* EDS_DISABLE_DEPRECATED */
G_END_DECLS
diff --git a/addressbook/libegdbus/Makefile.am b/addressbook/libegdbus/Makefile.am
index 7584a27..6f75cfe 100644
--- a/addressbook/libegdbus/Makefile.am
+++ b/addressbook/libegdbus/Makefile.am
@@ -11,8 +11,6 @@ libegdbus_book_la_CPPFLAGS = \
$(NULL)
libegdbus_book_la_SOURCES = \
- e-gdbus-book.h \
- e-gdbus-book.c \
e-gdbus-book-view.h \
e-gdbus-book-view.c
diff --git a/docs/reference/addressbook/libedata-book/libedata-book-sections.txt b/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
index 387d5b7..854a7a9 100644
--- a/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
+++ b/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
@@ -37,8 +37,6 @@ e_book_backend_notify_update
e_book_backend_notify_remove
e_book_backend_notify_complete
e_book_backend_notify_error
-e_book_backend_notify_readonly
-e_book_backend_notify_online
e_book_backend_notify_property_changed
e_book_backend_sync
e_book_backend_set_is_removed
@@ -50,6 +48,8 @@ e_book_backend_is_opening
e_book_backend_set_backend_property
e_book_backend_foreach_view
e_book_backend_notify_opened
+e_book_backend_notify_readonly
+e_book_backend_notify_online
e_book_backend_respond_opened
<SUBSECTION Standard>
E_BOOK_BACKEND
@@ -281,13 +281,13 @@ e_data_book_respond_get_contact
e_data_book_respond_get_contact_list
e_data_book_respond_get_contact_list_uids
e_data_book_report_error
-e_data_book_report_readonly
-e_data_book_report_online
e_data_book_report_backend_property_changed
e_data_book_string_slist_to_comma_string
<SUBSECTION Deprecated>
e_data_book_respond_set_backend_property
e_data_book_report_opened
+e_data_book_report_readonly
+e_data_book_report_online
<SUBSECTION Standard>
E_DATA_BOOK
E_IS_DATA_BOOK
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]