4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
18 * Copyright (C) 2011 Red Hat, Inc. (www.redhat.com)
26 #include <glib/gi18n-lib.h>
29 #include <libedataserver/libedataserver.h>
30 #include <libedataserver/e-client-private.h>
32 #include "e-book-client.h"
33 #include "e-contact.h"
34 #include "e-name-western.h"
36 #include "e-gdbus-book.h"
37 #include "e-gdbus-book-factory.h"
39 #define E_BOOK_CLIENT_GET_PRIVATE(obj) \
40 (G_TYPE_INSTANCE_GET_PRIVATE \
41 ((obj), E_TYPE_BOOK_CLIENT, EBookClientPrivate))
43 struct _EBookClientPrivate {
44 GDBusProxy *dbus_proxy;
48 G_DEFINE_TYPE (EBookClient, e_book_client, E_TYPE_CLIENT)
51 * Well-known book backend properties:
52 * @BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS: Retrieves comma-separated list
53 * of required fields by the backend. Use e_client_util_parse_comma_strings()
54 * to parse returned string value into a #GSList. These fields are required
55 * to be filled in for all contacts.
56 * @BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS: Retrieves comma-separated list
57 * of supported fields by the backend. Use e_client_util_parse_comma_strings()
58 * to parse returned string value into a #GSList. These fields can be
59 * stored for contacts.
61 * See also: @CLIENT_BACKEND_PROPERTY_OPENED, @CLIENT_BACKEND_PROPERTY_OPENING,
62 * @CLIENT_BACKEND_PROPERTY_ONLINE, @CLIENT_BACKEND_PROPERTY_READONLY
63 * @CLIENT_BACKEND_PROPERTY_CACHE_DIR, @CLIENT_BACKEND_PROPERTY_CAPABILITIES
67 e_book_client_error_quark (void)
71 q = g_quark_from_static_string ("e-book-client-error-quark");
77 * e_book_client_error_to_string:
84 e_book_client_error_to_string (EBookClientError code)
87 case E_BOOK_CLIENT_ERROR_NO_SUCH_BOOK:
88 return _("No such book");
89 case E_BOOK_CLIENT_ERROR_CONTACT_NOT_FOUND:
90 return _("Contact not found");
91 case E_BOOK_CLIENT_ERROR_CONTACT_ID_ALREADY_EXISTS:
92 return _("Contact ID already exists");
93 case E_BOOK_CLIENT_ERROR_NO_SUCH_SOURCE:
94 return _("No such source");
95 case E_BOOK_CLIENT_ERROR_NO_SPACE:
99 return _("Unknown error");
103 * e_book_client_error_create:
104 * @code: an #EBookClientError code to create
105 * @custom_msg: custom message to use for the error; can be %NULL
107 * Returns: a new #GError containing an E_BOOK_CLIENT_ERROR of the given
108 * @code. If the @custom_msg is NULL, then the error message is
109 * the one returned from e_book_client_error_to_string() for the @code,
110 * otherwise the given message is used.
112 * Returned pointer should be freed with g_error_free().
117 e_book_client_error_create (EBookClientError code,
118 const gchar *custom_msg)
120 return g_error_new_literal (E_BOOK_CLIENT_ERROR, code, custom_msg ? custom_msg : e_book_client_error_to_string (code));
124 * If the specified GError is a remote error, then create a new error
125 * representing the remote error. If the error is anything else, then
129 unwrap_dbus_error (GError *error,
130 GError **client_error)
132 #define err(a,b) "org.gnome.evolution.dataserver.AddressBook." a, b
133 static EClientErrorsList book_errors[] = {
134 { err ("Success", -1) },
135 { err ("ContactNotFound", E_BOOK_CLIENT_ERROR_CONTACT_NOT_FOUND) },
136 { err ("ContactIDAlreadyExists", E_BOOK_CLIENT_ERROR_CONTACT_ID_ALREADY_EXISTS) },
137 { err ("NoSuchBook", E_BOOK_CLIENT_ERROR_NO_SUCH_BOOK) },
138 { err ("BookRemoved", E_BOOK_CLIENT_ERROR_NO_SUCH_SOURCE) },
139 { err ("NoSpace", E_BOOK_CLIENT_ERROR_NO_SPACE) }
141 { err ("Busy", E_CLIENT_ERROR_BUSY) },
142 { err ("RepositoryOffline", E_CLIENT_ERROR_REPOSITORY_OFFLINE) },
143 { err ("OfflineUnavailable", E_CLIENT_ERROR_OFFLINE_UNAVAILABLE) },
144 { err ("PermissionDenied", E_CLIENT_ERROR_PERMISSION_DENIED) },
145 { err ("AuthenticationFailed", E_CLIENT_ERROR_AUTHENTICATION_FAILED) },
146 { err ("AuthenticationRequired", E_CLIENT_ERROR_AUTHENTICATION_REQUIRED) },
147 { err ("CouldNotCancel", E_CLIENT_ERROR_COULD_NOT_CANCEL) },
148 { err ("InvalidArg", E_CLIENT_ERROR_INVALID_ARG) },
149 { err ("NotSupported", E_CLIENT_ERROR_NOT_SUPPORTED) },
150 { err ("UnsupportedAuthenticationMethod", E_CLIENT_ERROR_UNSUPPORTED_AUTHENTICATION_METHOD) },
151 { err ("TLSNotAvailable", E_CLIENT_ERROR_TLS_NOT_AVAILABLE) },
152 { err ("SearchSizeLimitExceeded", E_CLIENT_ERROR_SEARCH_SIZE_LIMIT_EXCEEDED) },
153 { err ("SearchTimeLimitExceeded", E_CLIENT_ERROR_SEARCH_TIME_LIMIT_EXCEEDED) },
154 { err ("InvalidQuery", E_CLIENT_ERROR_INVALID_QUERY) },
155 { err ("QueryRefused", E_CLIENT_ERROR_QUERY_REFUSED) },
156 { err ("NotOpened", E_CLIENT_ERROR_NOT_OPENED) },
157 { err ("UnsupportedField", E_CLIENT_ERROR_OTHER_ERROR) },
158 { err ("InvalidServerVersion", E_CLIENT_ERROR_OTHER_ERROR) },
159 { err ("OtherError", E_CLIENT_ERROR_OTHER_ERROR) }
166 if (!e_client_util_unwrap_dbus_error (error, client_error, book_errors, G_N_ELEMENTS (book_errors), E_BOOK_CLIENT_ERROR, TRUE))
167 e_client_util_unwrap_dbus_error (error, client_error, cl_errors, G_N_ELEMENTS (cl_errors), E_CLIENT_ERROR, FALSE);
173 set_proxy_gone_error (GError **error)
175 /* do not translate this string, it should ideally never happen */
176 g_set_error_literal (error, E_CLIENT_ERROR, E_CLIENT_ERROR_DBUS_ERROR, "D-Bus book proxy gone");
179 static guint active_book_clients = 0, book_connection_closed_id = 0;
180 static EGdbusBookFactory *book_factory = NULL;
181 static GRecMutex book_factory_lock;
182 #define LOCK_FACTORY() g_rec_mutex_lock (&book_factory_lock)
183 #define UNLOCK_FACTORY() g_rec_mutex_unlock (&book_factory_lock)
185 static void gdbus_book_factory_closed_cb (GDBusConnection *connection, gboolean remote_peer_vanished, GError *error, gpointer user_data);
188 gdbus_book_factory_disconnect (GDBusConnection *connection)
192 if (!connection && book_factory)
193 connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (book_factory));
195 if (connection && book_connection_closed_id) {
196 g_dbus_connection_signal_unsubscribe (connection, book_connection_closed_id);
197 g_signal_handlers_disconnect_by_func (connection, gdbus_book_factory_closed_cb, NULL);
200 if (book_factory != NULL)
201 g_object_unref (book_factory);
203 book_connection_closed_id = 0;
210 gdbus_book_factory_closed_cb (GDBusConnection *connection,
211 gboolean remote_peer_vanished,
219 gdbus_book_factory_disconnect (connection);
222 unwrap_dbus_error (g_error_copy (error), &err);
225 g_debug ("GDBus connection is closed%s: %s", remote_peer_vanished ? ", remote peer vanished" : "", err->message);
227 } else if (active_book_clients) {
228 g_debug ("GDBus connection is closed%s", remote_peer_vanished ? ", remote peer vanished" : "");
235 gdbus_book_factory_connection_gone_cb (GDBusConnection *connection,
236 const gchar *sender_name,
237 const gchar *object_path,
238 const gchar *interface_name,
239 const gchar *signal_name,
240 GVariant *parameters,
243 /* signal subscription takes care of correct parameters,
244 * thus just do what is to be done here */
245 gdbus_book_factory_closed_cb (connection, TRUE, NULL, user_data);
249 gdbus_book_factory_activate (GCancellable *cancellable,
252 GDBusConnection *connection;
256 if (G_LIKELY (book_factory != NULL)) {
261 book_factory = e_gdbus_book_factory_proxy_new_for_bus_sync (
263 G_DBUS_PROXY_FLAGS_NONE,
264 ADDRESS_BOOK_DBUS_SERVICE_NAME,
265 "/org/gnome/evolution/dataserver/AddressBookFactory",
268 if (book_factory == NULL) {
273 connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (book_factory));
274 book_connection_closed_id = g_dbus_connection_signal_subscribe (
277 "org.freedesktop.DBus", /* interface */
278 "NameOwnerChanged", /* member */
279 "/org/freedesktop/DBus", /* object_path */
280 "org.gnome.evolution.dataserver.AddressBook", /* arg0 */
281 G_DBUS_SIGNAL_FLAGS_NONE,
282 gdbus_book_factory_connection_gone_cb, NULL, NULL);
285 connection, "closed",
286 G_CALLBACK (gdbus_book_factory_closed_cb), NULL);
293 static void gdbus_book_client_disconnect (EBookClient *client);
296 * Called when the addressbook server dies.
299 gdbus_book_client_closed_cb (GDBusConnection *connection,
300 gboolean remote_peer_vanished,
306 g_assert (E_IS_BOOK_CLIENT (client));
309 unwrap_dbus_error (g_error_copy (error), &err);
312 g_debug (G_STRLOC ": EBookClient GDBus connection is closed%s: %s", remote_peer_vanished ? ", remote peer vanished" : "", err->message);
315 g_debug (G_STRLOC ": EBookClient GDBus connection is closed%s", remote_peer_vanished ? ", remote peer vanished" : "");
318 gdbus_book_client_disconnect (client);
320 e_client_emit_backend_died (E_CLIENT (client));
324 gdbus_book_client_connection_gone_cb (GDBusConnection *connection,
325 const gchar *sender_name,
326 const gchar *object_path,
327 const gchar *interface_name,
328 const gchar *signal_name,
329 GVariant *parameters,
332 /* signal subscription takes care of correct parameters,
333 * thus just do what is to be done here */
334 gdbus_book_client_closed_cb (connection, TRUE, NULL, user_data);
338 gdbus_book_client_disconnect (EBookClient *client)
340 g_return_if_fail (E_IS_BOOK_CLIENT (client));
342 /* Ensure that everything relevant is NULL */
345 if (client->priv->dbus_proxy != NULL) {
346 GDBusConnection *connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (client->priv->dbus_proxy));
348 g_signal_handlers_disconnect_by_func (connection, gdbus_book_client_closed_cb, client);
349 g_dbus_connection_signal_unsubscribe (connection, client->priv->gone_signal_id);
350 client->priv->gone_signal_id = 0;
352 e_gdbus_book_call_close_sync (
353 client->priv->dbus_proxy, NULL, NULL);
354 g_object_unref (client->priv->dbus_proxy);
355 client->priv->dbus_proxy = NULL;
362 backend_error_cb (EGdbusBook *dbus_proxy,
363 const gchar *message,
366 g_return_if_fail (E_IS_BOOK_CLIENT (client));
367 g_return_if_fail (message != NULL);
369 e_client_emit_backend_error (E_CLIENT (client), message);
373 readonly_cb (EGdbusBook *dbus_proxy,
377 g_return_if_fail (E_IS_BOOK_CLIENT (client));
379 e_client_set_readonly (E_CLIENT (client), readonly);
383 online_cb (EGdbusBook *dbus_proxy,
387 g_return_if_fail (E_IS_BOOK_CLIENT (client));
389 e_client_set_online (E_CLIENT (client), is_online);
393 opened_cb (EGdbusBook *dbus_proxy,
394 const gchar * const *error_strv,
397 GError *error = NULL;
399 g_return_if_fail (E_IS_BOOK_CLIENT (client));
400 g_return_if_fail (error_strv != NULL);
401 g_return_if_fail (e_gdbus_templates_decode_error (error_strv, &error));
403 e_client_emit_opened (E_CLIENT (client), error);
406 g_error_free (error);
410 backend_property_changed_cb (EGdbusBook *dbus_proxy,
411 const gchar * const *name_value_strv,
414 gchar *prop_name = NULL, *prop_value = NULL;
416 g_return_if_fail (E_IS_BOOK_CLIENT (client));
417 g_return_if_fail (name_value_strv != NULL);
418 g_return_if_fail (e_gdbus_templates_decode_two_strings (name_value_strv, &prop_name, &prop_value));
419 g_return_if_fail (prop_name != NULL);
420 g_return_if_fail (*prop_name);
421 g_return_if_fail (prop_value != NULL);
423 e_client_emit_backend_property_changed (E_CLIENT (client), prop_name, prop_value);
430 * Converts a GSList of EContact objects into a NULL-terminated array of
431 * valid UTF-8 vcard strings, suitable for sending over DBus.
434 contact_slist_to_utf8_vcard_array (GSList *contacts)
440 array = g_new0 (gchar *, g_slist_length (contacts) + 1);
441 for (l = contacts; l != NULL; l = l->next) {
442 gchar *vcard = e_vcard_to_string (E_VCARD (l->data), EVC_FORMAT_VCARD_30);
443 array[i++] = e_util_utf8_make_valid (vcard);
451 book_client_get_backend_property_from_cache_finish (EClient *client,
452 GAsyncResult *result,
456 GSimpleAsyncResult *simple;
457 GError *local_error = NULL;
459 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
460 g_return_val_if_fail (result != NULL, FALSE);
461 g_return_val_if_fail (prop_value != NULL, FALSE);
462 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), book_client_get_backend_property_from_cache_finish), FALSE);
464 simple = G_SIMPLE_ASYNC_RESULT (result);
466 if (g_simple_async_result_propagate_error (simple, &local_error)) {
467 e_client_unwrap_dbus_error (client, local_error, error);
471 *prop_value = g_strdup (g_simple_async_result_get_op_res_gpointer (simple));
473 return *prop_value != NULL;
477 book_client_dispose (GObject *object)
481 client = E_CLIENT (object);
483 e_client_cancel_all (client);
485 gdbus_book_client_disconnect (E_BOOK_CLIENT (client));
487 /* Chain up to parent's dispose() method. */
488 G_OBJECT_CLASS (e_book_client_parent_class)->dispose (object);
492 book_client_finalize (GObject *object)
494 /* Chain up to parent's finalize() method. */
495 G_OBJECT_CLASS (e_book_client_parent_class)->finalize (object);
498 active_book_clients--;
499 if (!active_book_clients)
500 gdbus_book_factory_disconnect (NULL);
505 book_client_get_dbus_proxy (EClient *client)
507 EBookClientPrivate *priv;
509 priv = E_BOOK_CLIENT_GET_PRIVATE (client);
511 return G_DBUS_PROXY (priv->dbus_proxy);
515 book_client_unwrap_dbus_error (EClient *client,
519 unwrap_dbus_error (dbus_error, out_error);
523 book_client_retrieve_capabilities (EClient *client,
524 GCancellable *cancellable,
525 GAsyncReadyCallback callback,
528 g_return_if_fail (E_IS_BOOK_CLIENT (client));
530 e_client_get_backend_property (client, CLIENT_BACKEND_PROPERTY_CAPABILITIES, cancellable, callback, user_data);
534 book_client_retrieve_capabilities_finish (EClient *client,
535 GAsyncResult *result,
536 gchar **capabilities,
539 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
541 return e_client_get_backend_property_finish (client, result, capabilities, error);
545 book_client_retrieve_capabilities_sync (EClient *client,
546 gchar **capabilities,
547 GCancellable *cancellable,
550 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
552 return e_client_get_backend_property_sync (client, CLIENT_BACKEND_PROPERTY_CAPABILITIES, capabilities, cancellable, error);
556 book_client_get_backend_property (EClient *client,
557 const gchar *prop_name,
558 GCancellable *cancellable,
559 GAsyncReadyCallback callback,
564 prop_value = e_client_get_backend_property_from_cache (client, prop_name);
566 e_client_finish_async_without_dbus (
567 client, cancellable, callback, user_data,
568 book_client_get_backend_property_from_cache_finish,
571 e_client_proxy_call_string_with_res_op_data (
573 cancellable, callback, user_data,
574 book_client_get_backend_property, prop_name,
575 e_gdbus_book_call_get_backend_property,
577 e_gdbus_book_call_get_backend_property_finish,
583 book_client_get_backend_property_finish (EClient *client,
584 GAsyncResult *result,
591 g_return_val_if_fail (prop_value != NULL, FALSE);
593 if (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (result)) == book_client_get_backend_property_from_cache_finish) {
594 res = book_client_get_backend_property_from_cache_finish (client, result, &str, error);
596 res = e_client_proxy_call_finish_string (
597 client, result, &str, error,
598 book_client_get_backend_property);
600 const gchar *prop_name = g_object_get_data (G_OBJECT (result), "res-op-data");
602 if (prop_name && *prop_name)
603 e_client_update_backend_property_cache (client, prop_name, str);
613 book_client_get_backend_property_sync (EClient *client,
614 const gchar *prop_name,
616 GCancellable *cancellable,
619 EBookClient *book_client;
623 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
625 book_client = E_BOOK_CLIENT (client);
627 if (book_client->priv->dbus_proxy == NULL) {
628 set_proxy_gone_error (error);
632 prop_val = e_client_get_backend_property_from_cache (client, prop_name);
634 g_return_val_if_fail (prop_value != NULL, FALSE);
636 *prop_value = prop_val;
641 res = e_client_proxy_call_sync_string__string (
642 client, prop_name, prop_value, cancellable, error,
643 e_gdbus_book_call_get_backend_property_sync);
645 if (res && prop_value)
646 e_client_update_backend_property_cache (
647 client, prop_name, *prop_value);
653 book_client_set_backend_property (EClient *client,
654 const gchar *prop_name,
655 const gchar *prop_value,
656 GCancellable *cancellable,
657 GAsyncReadyCallback callback,
660 gchar **prop_name_value;
662 prop_name_value = e_gdbus_book_encode_set_backend_property (prop_name, prop_value);
664 e_client_proxy_call_strv (
665 client, (const gchar * const *) prop_name_value,
666 cancellable, callback, user_data,
667 book_client_set_backend_property,
668 e_gdbus_book_call_set_backend_property,
669 e_gdbus_book_call_set_backend_property_finish,
670 NULL, NULL, NULL, NULL);
672 g_strfreev (prop_name_value);
676 book_client_set_backend_property_finish (EClient *client,
677 GAsyncResult *result,
680 return e_client_proxy_call_finish_void (
681 client, result, error,
682 book_client_set_backend_property);
686 book_client_set_backend_property_sync (EClient *client,
687 const gchar *prop_name,
688 const gchar *prop_value,
689 GCancellable *cancellable,
692 EBookClient *book_client;
694 gchar **prop_name_value;
696 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
698 book_client = E_BOOK_CLIENT (client);
700 if (book_client->priv->dbus_proxy == NULL) {
701 set_proxy_gone_error (error);
705 prop_name_value = e_gdbus_book_encode_set_backend_property (prop_name, prop_value);
706 res = e_client_proxy_call_sync_strv__void (
707 client, (const gchar * const *) prop_name_value,
709 e_gdbus_book_call_set_backend_property_sync);
710 g_strfreev (prop_name_value);
716 book_client_open (EClient *client,
717 gboolean only_if_exists,
718 GCancellable *cancellable,
719 GAsyncReadyCallback callback,
722 e_client_proxy_call_boolean (
723 client, only_if_exists,
724 cancellable, callback, user_data,
726 e_gdbus_book_call_open,
727 e_gdbus_book_call_open_finish,
728 NULL, NULL, NULL, NULL);
732 book_client_open_finish (EClient *client,
733 GAsyncResult *result,
736 return e_client_proxy_call_finish_void (
737 client, result, error, book_client_open);
741 book_client_open_sync (EClient *client,
742 gboolean only_if_exists,
743 GCancellable *cancellable,
746 EBookClient *book_client;
748 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
750 book_client = E_BOOK_CLIENT (client);
752 if (book_client->priv->dbus_proxy == NULL) {
753 set_proxy_gone_error (error);
757 return e_client_proxy_call_sync_boolean__void (
758 client, only_if_exists, cancellable, error,
759 e_gdbus_book_call_open_sync);
763 book_client_refresh (EClient *client,
764 GCancellable *cancellable,
765 GAsyncReadyCallback callback,
768 e_client_proxy_call_void (
769 client, cancellable, callback, user_data,
771 e_gdbus_book_call_refresh,
772 e_gdbus_book_call_refresh_finish,
773 NULL, NULL, NULL, NULL);
777 book_client_refresh_finish (EClient *client,
778 GAsyncResult *result,
781 return e_client_proxy_call_finish_void (
782 client, result, error, book_client_refresh);
786 book_client_refresh_sync (EClient *client,
787 GCancellable *cancellable,
790 EBookClient *book_client;
792 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
794 book_client = E_BOOK_CLIENT (client);
796 if (book_client->priv->dbus_proxy == NULL) {
797 set_proxy_gone_error (error);
801 return e_client_proxy_call_sync_void__void (
802 client, cancellable, error,
803 e_gdbus_book_call_refresh_sync);
807 e_book_client_class_init (EBookClientClass *class)
809 GObjectClass *object_class;
810 EClientClass *client_class;
812 g_type_class_add_private (class, sizeof (EBookClientPrivate));
814 object_class = G_OBJECT_CLASS (class);
815 object_class->dispose = book_client_dispose;
816 object_class->finalize = book_client_finalize;
818 client_class = E_CLIENT_CLASS (class);
819 client_class->get_dbus_proxy = book_client_get_dbus_proxy;
820 client_class->unwrap_dbus_error = book_client_unwrap_dbus_error;
821 client_class->retrieve_capabilities = book_client_retrieve_capabilities;
822 client_class->retrieve_capabilities_finish = book_client_retrieve_capabilities_finish;
823 client_class->retrieve_capabilities_sync = book_client_retrieve_capabilities_sync;
824 client_class->get_backend_property = book_client_get_backend_property;
825 client_class->get_backend_property_finish = book_client_get_backend_property_finish;
826 client_class->get_backend_property_sync = book_client_get_backend_property_sync;
827 client_class->set_backend_property = book_client_set_backend_property;
828 client_class->set_backend_property_finish = book_client_set_backend_property_finish;
829 client_class->set_backend_property_sync = book_client_set_backend_property_sync;
830 client_class->open = book_client_open;
831 client_class->open_finish = book_client_open_finish;
832 client_class->open_sync = book_client_open_sync;
833 client_class->refresh = book_client_refresh;
834 client_class->refresh_finish = book_client_refresh_finish;
835 client_class->refresh_sync = book_client_refresh_sync;
839 e_book_client_init (EBookClient *client)
842 active_book_clients++;
845 client->priv = E_BOOK_CLIENT_GET_PRIVATE (client);
850 * @source: An #ESource pointer
851 * @error: A #GError pointer
853 * Creates a new #EBookClient corresponding to the given source. There are
854 * only two operations that are valid on this book at this point:
855 * e_client_open(), and e_client_remove().
857 * Returns: a new but unopened #EBookClient.
862 e_book_client_new (ESource *source,
867 GDBusConnection *connection;
869 gchar *object_path = NULL;
871 g_return_val_if_fail (source != NULL, NULL);
872 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
875 /* XXX Oops, e_book_client_new() forgot to take a GCancellable. */
876 if (!gdbus_book_factory_activate (NULL, &err)) {
879 unwrap_dbus_error (err, &err);
880 g_warning ("%s: Failed to run book factory: %s", G_STRFUNC, err->message);
881 g_propagate_error (error, err);
883 g_warning ("%s: Failed to run book factory: Unknown error", G_STRFUNC);
884 g_set_error_literal (error, E_CLIENT_ERROR, E_CLIENT_ERROR_DBUS_ERROR, _("Failed to run book factory"));
890 uid = e_source_get_uid (source);
892 client = g_object_new (E_TYPE_BOOK_CLIENT, "source", source, NULL);
895 e_gdbus_book_factory_call_get_book_sync (
896 G_DBUS_PROXY (book_factory), uid, &object_path, NULL, &err);
899 g_return_val_if_fail (
900 ((object_path != NULL) && (err == NULL)) ||
901 ((object_path == NULL) && (err != NULL)), NULL);
904 unwrap_dbus_error (err, &err);
905 g_propagate_error (error, err);
906 g_object_unref (client);
910 connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (book_factory));
912 client->priv->dbus_proxy = G_DBUS_PROXY (e_gdbus_book_proxy_new_sync (
914 G_DBUS_PROXY_FLAGS_NONE,
915 ADDRESS_BOOK_DBUS_SERVICE_NAME,
919 g_free (object_path);
922 g_return_val_if_fail (
923 ((client->priv->dbus_proxy != NULL) && (err == NULL)) ||
924 ((client->priv->dbus_proxy == NULL) && (err != NULL)), NULL);
927 unwrap_dbus_error (err, &err);
928 g_propagate_error (error, err);
929 g_object_unref (client);
933 client->priv->gone_signal_id = g_dbus_connection_signal_subscribe (
935 "org.freedesktop.DBus", /* sender */
936 "org.freedesktop.DBus", /* interface */
937 "NameOwnerChanged", /* member */
938 "/org/freedesktop/DBus", /* object_path */
939 "org.gnome.evolution.dataserver.AddressBook", /* arg0 */
940 G_DBUS_SIGNAL_FLAGS_NONE,
941 gdbus_book_client_connection_gone_cb, client, NULL);
944 connection, "closed",
945 G_CALLBACK (gdbus_book_client_closed_cb), client);
948 client->priv->dbus_proxy, "backend_error",
949 G_CALLBACK (backend_error_cb), client);
951 client->priv->dbus_proxy, "readonly",
952 G_CALLBACK (readonly_cb), client);
954 client->priv->dbus_proxy, "online",
955 G_CALLBACK (online_cb), client);
957 client->priv->dbus_proxy, "opened",
958 G_CALLBACK (opened_cb), client);
960 client->priv->dbus_proxy, "backend-property-changed",
961 G_CALLBACK (backend_property_changed_cb), client);
966 #define SELF_UID_PATH_ID "org.gnome.evolution-data-server.addressbook"
967 #define SELF_UID_KEY "self-contact-uid"
976 vcard = g_string_new ("BEGIN:VCARD\nVERSION:3.0\n");
978 s = g_get_user_name ();
980 g_string_append_printf (vcard, "NICKNAME:%s\n", s);
982 s = g_get_real_name ();
983 if (s && strcmp (s, "Unknown") != 0) {
984 ENameWestern *western;
986 g_string_append_printf (vcard, "FN:%s\n", s);
988 western = e_name_western_parse (s);
989 g_string_append_printf (
990 vcard, "N:%s;%s;%s;%s;%s\n",
991 western->last ? western->last : "",
992 western->first ? western->first : "",
993 western->middle ? western->middle : "",
994 western->prefix ? western->prefix : "",
995 western->suffix ? western->suffix : "");
996 e_name_western_free (western);
998 g_string_append (vcard, "END:VCARD");
1000 contact = e_contact_new_from_vcard (vcard->str);
1002 g_string_free (vcard, TRUE);
1008 * e_book_client_get_self:
1009 * @registry: an #ESourceRegistry
1010 * @contact: (out): an #EContact pointer to set
1011 * @client: (out): an #EBookClient pointer to set
1012 * @error: a #GError to set on failure
1014 * Get the #EContact referring to the user of the address book
1015 * and set it in @contact and @client.
1017 * Returns: %TRUE if successful, otherwise %FALSE.
1022 e_book_client_get_self (ESourceRegistry *registry,
1024 EBookClient **client,
1028 GError *local_error = NULL;
1029 GSettings *settings;
1032 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
1033 g_return_val_if_fail (contact != NULL, FALSE);
1034 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1036 source = e_source_registry_ref_builtin_address_book (registry);
1037 g_return_val_if_fail (source != NULL, FALSE);
1038 *client = e_book_client_new (source, &local_error);
1039 g_object_unref (source);
1042 g_propagate_error (error, local_error);
1046 if (!e_client_open_sync (E_CLIENT (*client), FALSE, NULL, &local_error)) {
1047 g_object_unref (*client);
1049 g_propagate_error (error, local_error);
1054 settings = g_settings_new (SELF_UID_PATH_ID);
1055 uid = g_settings_get_string (settings, SELF_UID_KEY);
1056 g_object_unref (settings);
1061 /* Don't care about errors because we'll create a new card on failure */
1062 got = e_book_client_get_contact_sync (*client, uid, contact, NULL, NULL);
1069 *contact = make_me_card ();
1070 if (!e_book_client_add_contact_sync (*client, *contact, &uid, NULL, &local_error)) {
1071 g_object_unref (*client);
1073 g_object_unref (*contact);
1075 g_propagate_error (error, local_error);
1080 e_contact_set (*contact, E_CONTACT_UID, uid);
1084 e_book_client_set_self (*client, *contact, NULL);
1090 * e_book_client_set_self:
1091 * @client: an #EBookClient
1092 * @contact: an #EContact
1093 * @error: a #GError to set on failure
1095 * Specify that @contact residing in @client is the #EContact that
1096 * refers to the user of the address book.
1098 * Returns: %TRUE if successful, %FALSE otherwise.
1103 e_book_client_set_self (EBookClient *client,
1107 GSettings *settings;
1109 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1110 g_return_val_if_fail (contact != NULL, FALSE);
1111 g_return_val_if_fail (e_contact_get_const (contact, E_CONTACT_UID) != NULL, FALSE);
1113 settings = g_settings_new (SELF_UID_PATH_ID);
1114 g_settings_set_string (settings, SELF_UID_KEY, e_contact_get_const (contact, E_CONTACT_UID));
1115 g_object_unref (settings);
1121 * e_book_client_is_self:
1122 * @contact: an #EContact
1124 * Check if @contact is the user of the address book.
1126 * Returns: %TRUE if @contact is the user, %FALSE otherwise.
1131 e_book_client_is_self (EContact *contact)
1133 GSettings *settings;
1137 g_return_val_if_fail (contact && E_IS_CONTACT (contact), FALSE);
1139 settings = g_settings_new (SELF_UID_PATH_ID);
1140 uid = g_settings_get_string (settings, SELF_UID_KEY);
1141 g_object_unref (settings);
1143 is_self = uid && !g_strcmp0 (uid, e_contact_get_const (contact, E_CONTACT_UID));
1151 * e_book_client_add_contact:
1152 * @client: an #EBookClient
1153 * @contact: an #EContact
1154 * @cancellable: a #GCancellable; can be %NULL
1155 * @callback: callback to call when a result is ready
1156 * @user_data: user data for the @callback
1158 * Adds @contact to @client.
1159 * The call is finished by e_book_client_add_contact_finish()
1160 * from the @callback.
1165 e_book_client_add_contact (EBookClient *client,
1166 /* const */ EContact *contact,
1167 GCancellable *cancellable,
1168 GAsyncReadyCallback callback,
1171 gchar *vcard, *gdbus_vcard = NULL;
1172 const gchar *strv[2];
1174 g_return_if_fail (contact != NULL);
1175 g_return_if_fail (E_IS_CONTACT (contact));
1177 vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
1178 strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
1181 g_return_if_fail (strv[0] != NULL);
1183 e_client_proxy_call_strv (
1185 strv, cancellable, callback, user_data,
1186 e_book_client_add_contact,
1187 e_gdbus_book_call_add_contacts,
1189 e_gdbus_book_call_add_contacts_finish,
1193 g_free (gdbus_vcard);
1197 * e_book_client_add_contact_finish:
1198 * @client: an #EBookClient
1199 * @result: a #GAsyncResult
1200 * @added_uid: (out): UID of a newly added contact; can be %NULL
1201 * @error: (out): a #GError to set an error, if any
1203 * Finishes previous call of e_book_client_add_contact() and
1204 * sets @added_uid to a UID of a newly added contact.
1205 * This string should be freed with g_free().
1207 * Note: This is not modifying original #EContact.
1209 * Returns: %TRUE if successful, %FALSE otherwise.
1214 e_book_client_add_contact_finish (EBookClient *client,
1215 GAsyncResult *result,
1220 gchar **out_uids = NULL;
1222 res = e_client_proxy_call_finish_strv (
1223 E_CLIENT (client), result, &out_uids, error,
1224 e_book_client_add_contact);
1226 if (res && out_uids && added_uid) {
1227 *added_uid = g_strdup (out_uids[0]);
1232 g_strfreev (out_uids);
1238 * e_book_client_add_contact_sync:
1239 * @client: an #EBookClient
1240 * @contact: an #EContact
1241 * @added_uid: (out): UID of a newly added contact; can be %NULL
1242 * @cancellable: a #GCancellable; can be %NULL
1243 * @error: (out): a #GError to set an error, if any
1245 * Adds @contact to @client and
1246 * sets @added_uid to a UID of a newly added contact.
1247 * This string should be freed with g_free().
1249 * Note: This is not modifying original @contact, thus if it's needed,
1250 * then use e_contact_set (contact, E_CONTACT_UID, new_uid).
1252 * Returns: %TRUE if successful, %FALSE otherwise.
1257 e_book_client_add_contact_sync (EBookClient *client,
1258 /* const */ EContact *contact,
1260 GCancellable *cancellable,
1264 gchar *vcard, *gdbus_vcard = NULL, **out_uids = NULL;
1265 const gchar *strv[2];
1267 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1269 if (client->priv->dbus_proxy == NULL) {
1270 set_proxy_gone_error (error);
1274 vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
1275 strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
1278 g_return_val_if_fail (strv[0] != NULL, FALSE);
1280 res = e_client_proxy_call_sync_strv__strv (
1281 E_CLIENT (client), strv, &out_uids, cancellable, error,
1282 e_gdbus_book_call_add_contacts_sync);
1284 if (res && out_uids && added_uid) {
1285 *added_uid = g_strdup (out_uids[0]);
1291 g_strfreev (out_uids);
1293 g_free (gdbus_vcard);
1299 * e_book_client_add_contacts:
1300 * @client: an #EBookClient
1301 * @contacts: (element-type EContact): a #GSList of #EContact objects to add
1302 * @cancellable: (allow-none): a #GCancellable; can be %NULL
1303 * @callback: callback to call when a result is ready
1304 * @user_data: user data for the @callback
1306 * Adds @contacts to @client.
1307 * The call is finished by e_book_client_add_contacts_finish()
1308 * from the @callback.
1313 e_book_client_add_contacts (EBookClient *client,
1314 /* const */ GSList *contacts,
1315 GCancellable *cancellable,
1316 GAsyncReadyCallback callback,
1321 g_return_if_fail (contacts != NULL);
1323 array = contact_slist_to_utf8_vcard_array (contacts);
1325 e_client_proxy_call_strv (
1327 (const gchar * const *) array,
1328 cancellable, callback, user_data,
1329 e_book_client_add_contacts,
1330 e_gdbus_book_call_add_contacts,
1332 e_gdbus_book_call_add_contacts_finish,
1339 * e_book_client_add_contacts_finish:
1340 * @client: an #EBookClient
1341 * @result: a #GAsyncResult
1342 * @added_uids: (out) (element-type utf8) (allow-none): UIDs of newly added
1343 * contacts; can be %NULL
1344 * @error: (out): a #GError to set an error, if any
1346 * Finishes previous call of e_book_client_add_contacts() and
1347 * sets @added_uids to the UIDs of newly added contacts if successful.
1348 * This #GSList should be freed with e_client_util_free_string_slist().
1350 * If any of the contacts cannot be inserted, all of the insertions will be
1351 * reverted and this method will return %FALSE.
1353 * Note: This is not modifying original #EContact objects.
1355 * Returns: %TRUE if successful, %FALSE otherwise.
1360 e_book_client_add_contacts_finish (EBookClient *client,
1361 GAsyncResult *result,
1362 GSList **added_uids,
1366 gchar **out_uids = NULL;
1368 res = e_client_proxy_call_finish_strv (
1369 E_CLIENT (client), result, &out_uids, error,
1370 e_book_client_add_contacts);
1372 if (res && out_uids && added_uids) {
1373 *added_uids = e_client_util_strv_to_slist ((const gchar * const*) out_uids);
1379 g_strfreev (out_uids);
1385 * e_book_client_add_contacts_sync:
1386 * @client: an #EBookClient
1387 * @contacts: (element-type EContact): a #GSList of #EContact objects to add
1388 * @added_uids: (out) (element-type utf8) (allow-none): UIDs of newly added
1389 * contacts; can be %NULL
1390 * @cancellable: a #GCancellable; can be %NULL
1391 * @error: (out): a #GError to set an error, if any
1393 * Adds @contacts to @client and
1394 * sets @added_uids to the UIDs of newly added contacts if successful.
1395 * This #GSList should be freed with e_client_util_free_string_slist().
1397 * If any of the contacts cannot be inserted, all of the insertions will be
1398 * reverted and this method will return %FALSE.
1400 * Note: This is not modifying original @contacts, thus if it's needed,
1401 * then use e_contact_set (contact, E_CONTACT_UID, new_uid).
1403 * Returns: %TRUE if successful, %FALSE otherwise.
1408 e_book_client_add_contacts_sync (EBookClient *client,
1409 /* const */ GSList *contacts,
1410 GSList **added_uids,
1411 GCancellable *cancellable,
1415 gchar **array, **out_uids = NULL;
1417 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1419 if (client->priv->dbus_proxy == NULL) {
1420 set_proxy_gone_error (error);
1424 array = contact_slist_to_utf8_vcard_array (contacts);
1426 res = e_client_proxy_call_sync_strv__strv (
1428 (const gchar * const *) array,
1429 &out_uids, cancellable, error,
1430 e_gdbus_book_call_add_contacts_sync);
1432 if (res && out_uids && added_uids) {
1433 *added_uids = e_client_util_strv_to_slist ((const gchar * const*) out_uids);
1439 g_strfreev (out_uids);
1446 * e_book_client_modify_contact:
1447 * @client: an #EBookClient
1448 * @contact: an #EContact
1449 * @cancellable: a #GCancellable; can be %NULL
1450 * @callback: callback to call when a result is ready
1451 * @user_data: user data for the @callback
1453 * Applies the changes made to @contact to the stored version in @client.
1454 * The call is finished by e_book_client_modify_contact_finish()
1455 * from the @callback.
1460 e_book_client_modify_contact (EBookClient *client,
1461 /* const */ EContact *contact,
1462 GCancellable *cancellable,
1463 GAsyncReadyCallback callback,
1466 gchar *vcard, *gdbus_vcard = NULL;
1467 const gchar *strv[2];
1469 g_return_if_fail (contact != NULL);
1470 g_return_if_fail (E_IS_CONTACT (contact));
1472 vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
1473 strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
1476 g_return_if_fail (strv[0] != NULL);
1478 e_client_proxy_call_strv (
1480 strv, cancellable, callback, user_data,
1481 e_book_client_modify_contact,
1482 e_gdbus_book_call_modify_contacts,
1483 e_gdbus_book_call_modify_contacts_finish,
1484 NULL, NULL, NULL, NULL);
1487 g_free (gdbus_vcard);
1491 * e_book_client_modify_contact_finish:
1492 * @client: an #EBookClient
1493 * @result: a #GAsyncResult
1494 * @error: (out): a #GError to set an error, if any
1496 * Finishes previous call of e_book_client_modify_contact().
1498 * Returns: %TRUE if successful, %FALSE otherwise.
1503 e_book_client_modify_contact_finish (EBookClient *client,
1504 GAsyncResult *result,
1507 return e_client_proxy_call_finish_void (
1508 E_CLIENT (client), result, error,
1509 e_book_client_modify_contact);
1513 * e_book_client_modify_contact_sync:
1514 * @client: an #EBookClient
1515 * @contact: an #EContact
1516 * @cancellable: a #GCancellable; can be %NULL
1517 * @error: (out): a #GError to set an error, if any
1519 * Applies the changes made to @contact to the stored version in @client.
1521 * Returns: %TRUE if successful, %FALSE otherwise.
1526 e_book_client_modify_contact_sync (EBookClient *client,
1527 /* const */ EContact *contact,
1528 GCancellable *cancellable,
1532 gchar *vcard, *gdbus_vcard = NULL;
1533 const gchar *strv[2];
1535 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1537 if (client->priv->dbus_proxy == NULL) {
1538 set_proxy_gone_error (error);
1542 vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
1543 strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
1546 g_return_val_if_fail (strv[0] != NULL, FALSE);
1548 res = e_client_proxy_call_sync_strv__void (
1550 strv, cancellable, error,
1551 e_gdbus_book_call_modify_contacts_sync);
1554 g_free (gdbus_vcard);
1560 * e_book_client_modify_contacts:
1561 * @client: an #EBookClient
1562 * @contacts: (element-type EContact): a #GSList of #EContact objects
1563 * @cancellable: (allow-none): a #GCancellable; can be %NULL
1564 * @callback: callback to call when a result is ready
1565 * @user_data: user data for the @callback
1567 * Applies the changes made to @contacts to the stored versions in @client.
1568 * The call is finished by e_book_client_modify_contacts_finish()
1569 * from the @callback.
1574 e_book_client_modify_contacts (EBookClient *client,
1575 /* const */ GSList *contacts,
1576 GCancellable *cancellable,
1577 GAsyncReadyCallback callback,
1582 g_return_if_fail (contacts != NULL);
1584 array = contact_slist_to_utf8_vcard_array (contacts);
1586 e_client_proxy_call_strv (
1588 (const gchar * const *) array,
1589 cancellable, callback, user_data,
1590 e_book_client_modify_contacts,
1591 e_gdbus_book_call_modify_contacts,
1592 e_gdbus_book_call_modify_contacts_finish,
1593 NULL, NULL, NULL, NULL);
1599 * e_book_client_modify_contacts_finish:
1600 * @client: an #EBookClient
1601 * @result: a #GAsyncResult
1602 * @error: (out): a #GError to set an error, if any
1604 * Finishes previous call of e_book_client_modify_contacts().
1606 * Returns: %TRUE if successful, %FALSE otherwise.
1611 e_book_client_modify_contacts_finish (EBookClient *client,
1612 GAsyncResult *result,
1615 return e_client_proxy_call_finish_void (
1616 E_CLIENT (client), result, error,
1617 e_book_client_modify_contacts);
1621 * e_book_client_modify_contacts_sync:
1622 * @client: an #EBookClient
1623 * @contacts: (element-type EContact): a #GSList of #EContact objects
1624 * @cancellable: (allow-none): a #GCancellable; can be %NULL
1625 * @error: (out): a #GError to set an error, if any
1627 * Applies the changes made to @contacts to the stored versions in @client.
1629 * Returns: %TRUE if successful, %FALSE otherwise.
1634 e_book_client_modify_contacts_sync (EBookClient *client,
1635 /* const */ GSList *contacts,
1636 GCancellable *cancellable,
1642 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1643 g_return_val_if_fail (contacts != NULL, FALSE);
1645 if (client->priv->dbus_proxy == NULL) {
1646 set_proxy_gone_error (error);
1650 array = contact_slist_to_utf8_vcard_array (contacts);
1652 res = e_client_proxy_call_sync_strv__void (
1654 (const gchar * const *) array,
1656 e_gdbus_book_call_modify_contacts_sync);
1664 * e_book_client_remove_contact:
1665 * @client: an #EBookClient
1666 * @contact: an #EContact
1667 * @cancellable: a #GCancellable; can be %NULL
1668 * @callback: callback to call when a result is ready
1669 * @user_data: user data for the @callback
1671 * Removes @contact from the @client.
1672 * The call is finished by e_book_client_remove_contact_finish()
1673 * from the @callback.
1678 e_book_client_remove_contact (EBookClient *client,
1679 /* const */ EContact *contact,
1680 GCancellable *cancellable,
1681 GAsyncReadyCallback callback,
1684 const gchar *uid, *safe_uid;
1685 const gchar *strv[2];
1686 gchar *gdbus_uid = NULL;
1688 g_return_if_fail (contact != NULL);
1689 g_return_if_fail (E_IS_CONTACT (contact));
1691 uid = e_contact_get_const ( E_CONTACT (contact), E_CONTACT_UID);
1692 g_return_if_fail (uid != NULL);
1694 safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
1695 g_return_if_fail (safe_uid != NULL);
1700 e_client_proxy_call_strv (
1702 strv, cancellable, callback, user_data,
1703 e_book_client_remove_contact,
1704 e_gdbus_book_call_remove_contacts,
1705 e_gdbus_book_call_remove_contacts_finish,
1706 NULL, NULL, NULL, NULL);
1712 * e_book_client_remove_contact_finish:
1713 * @client: an #EBookClient
1714 * @result: a #GAsyncResult
1715 * @error: (out): a #GError to set an error, if any
1717 * Finishes previous call of e_book_client_remove_contact().
1719 * Returns: %TRUE if successful, %FALSE otherwise.
1724 e_book_client_remove_contact_finish (EBookClient *client,
1725 GAsyncResult *result,
1728 return e_client_proxy_call_finish_void (
1729 E_CLIENT (client), result, error,
1730 e_book_client_remove_contact);
1734 * e_book_client_remove_contact_sync:
1735 * @client: an #EBookClient
1736 * @contact: an #EContact
1737 * @cancellable: a #GCancellable; can be %NULL
1738 * @error: (out): a #GError to set an error, if any
1740 * Removes @contact from the @client.
1742 * Returns: %TRUE if successful, %FALSE otherwise.
1747 e_book_client_remove_contact_sync (EBookClient *client,
1748 /* const */ EContact *contact,
1749 GCancellable *cancellable,
1753 const gchar *strv[2];
1754 const gchar *uid, *safe_uid;
1755 gchar *gdbus_uid = NULL;
1757 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1758 g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
1760 if (client->priv->dbus_proxy == NULL) {
1761 set_proxy_gone_error (error);
1765 uid = e_contact_get_const (E_CONTACT (contact), E_CONTACT_UID);
1766 g_return_val_if_fail (uid != NULL, FALSE);
1768 safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
1769 g_return_val_if_fail (safe_uid != NULL, FALSE);
1774 res = e_client_proxy_call_sync_strv__void (
1776 strv, cancellable, error,
1777 e_gdbus_book_call_remove_contacts_sync);
1785 * e_book_client_remove_contact_by_uid:
1786 * @client: an #EBookClient
1787 * @uid: a UID of a contact to remove
1788 * @cancellable: a #GCancellable; can be %NULL
1789 * @callback: callback to call when a result is ready
1790 * @user_data: user data for the @callback
1792 * Removes contact with @uid from the @client.
1793 * The call is finished by e_book_client_remove_contact_by_uid_finish()
1794 * from the @callback.
1799 e_book_client_remove_contact_by_uid (EBookClient *client,
1801 GCancellable *cancellable,
1802 GAsyncReadyCallback callback,
1805 const gchar *safe_uid;
1806 gchar *gdbus_uid = NULL;
1807 const gchar *strv[2];
1809 g_return_if_fail (uid != NULL);
1811 safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
1812 g_return_if_fail (safe_uid != NULL);
1817 e_client_proxy_call_strv (
1819 strv, cancellable, callback, user_data,
1820 e_book_client_remove_contact_by_uid,
1821 e_gdbus_book_call_remove_contacts,
1822 e_gdbus_book_call_remove_contacts_finish,
1823 NULL, NULL, NULL, NULL);
1829 * e_book_client_remove_contact_by_uid_finish:
1830 * @client: an #EBookClient
1831 * @result: a #GAsyncResult
1832 * @error: (out): a #GError to set an error, if any
1834 * Finishes previous call of e_book_client_remove_contact_by_uid().
1836 * Returns: %TRUE if successful, %FALSE otherwise.
1841 e_book_client_remove_contact_by_uid_finish (EBookClient *client,
1842 GAsyncResult *result,
1845 return e_client_proxy_call_finish_void (
1846 E_CLIENT (client), result, error,
1847 e_book_client_remove_contact_by_uid);
1851 * e_book_client_remove_contact_by_uid_sync:
1852 * @client: an #EBookClient
1853 * @uid: a UID of a contact to remove
1854 * @cancellable: a #GCancellable; can be %NULL
1855 * @error: (out): a #GError to set an error, if any
1857 * Removes contact with @uid from the @client.
1859 * Returns: %TRUE if successful, %FALSE otherwise.
1864 e_book_client_remove_contact_by_uid_sync (EBookClient *client,
1866 GCancellable *cancellable,
1870 const gchar *safe_uid;
1871 gchar *gdbus_uid = NULL;
1872 const gchar *strv[2];
1874 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1875 g_return_val_if_fail (uid != NULL, FALSE);
1877 if (client->priv->dbus_proxy == NULL) {
1878 set_proxy_gone_error (error);
1882 safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
1883 g_return_val_if_fail (safe_uid != NULL, FALSE);
1888 res = e_client_proxy_call_sync_strv__void (
1889 E_CLIENT (client), strv, cancellable, error,
1890 e_gdbus_book_call_remove_contacts_sync);
1898 * e_book_client_remove_contacts:
1899 * @client: an #EBookClient
1900 * @uids: (element-type utf8): a #GSList of UIDs to remove
1901 * @cancellable: a #GCancellable; can be %NULL
1902 * @callback: callback to call when a result is ready
1903 * @user_data: user data for the @callback
1905 * Removes the contacts with uids from the list @uids from @client. This is
1906 * always more efficient than calling e_book_client_remove_contact() if you
1907 * have more than one uid to remove, as some backends can implement it
1908 * as a batch request.
1909 * The call is finished by e_book_client_remove_contacts_finish()
1910 * from the @callback.
1915 e_book_client_remove_contacts (EBookClient *client,
1917 GCancellable *cancellable,
1918 GAsyncReadyCallback callback,
1923 g_return_if_fail (uids != NULL);
1925 strv = e_client_util_slist_to_strv (uids);
1926 g_return_if_fail (strv != NULL);
1928 e_client_proxy_call_strv (
1930 (const gchar * const *) strv,
1931 cancellable, callback, user_data,
1932 e_book_client_remove_contacts,
1933 e_gdbus_book_call_remove_contacts,
1934 e_gdbus_book_call_remove_contacts_finish,
1935 NULL, NULL, NULL, NULL);
1941 * e_book_client_remove_contacts_finish:
1942 * @client: an #EBookClient
1943 * @result: a #GAsyncResult
1944 * @error: (out): a #GError to set an error, if any
1946 * Finishes previous call of e_book_client_remove_contacts().
1948 * Returns: %TRUE if successful, %FALSE otherwise.
1953 e_book_client_remove_contacts_finish (EBookClient *client,
1954 GAsyncResult *result,
1957 return e_client_proxy_call_finish_void (
1958 E_CLIENT (client), result, error,
1959 e_book_client_remove_contacts);
1963 * e_book_client_remove_contacts_sync:
1964 * @client: an #EBookClient
1965 * @uids: (element-type utf8): a #GSList of UIDs to remove
1966 * @cancellable: a #GCancellable; can be %NULL
1967 * @error: (out): a #GError to set an error, if any
1969 * Removes the contacts with uids from the list @uids from @client. This is
1970 * always more efficient than calling e_book_client_remove_contact() if you
1971 * have more than one uid to remove, as some backends can implement it
1972 * as a batch request.
1974 * Returns: %TRUE if successful, %FALSE otherwise.
1979 e_book_client_remove_contacts_sync (EBookClient *client,
1981 GCancellable *cancellable,
1987 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1988 g_return_val_if_fail (uids != NULL, FALSE);
1990 if (client->priv->dbus_proxy == NULL) {
1991 set_proxy_gone_error (error);
1995 strv = e_client_util_slist_to_strv (uids);
1996 g_return_val_if_fail (strv != NULL, FALSE);
1998 res = e_client_proxy_call_sync_strv__void (
1999 E_CLIENT (client), (const gchar * const *) strv,
2001 e_gdbus_book_call_remove_contacts_sync);
2009 * e_book_client_get_contact:
2010 * @client: an #EBookClient
2011 * @uid: a unique string ID specifying the contact
2012 * @cancellable: a #GCancellable; can be %NULL
2013 * @callback: callback to call when a result is ready
2014 * @user_data: user data for the @callback
2016 * Receive #EContact from the @client for the gived @uid.
2017 * The call is finished by e_book_client_get_contact_finish()
2018 * from the @callback.
2023 e_book_client_get_contact (EBookClient *client,
2025 GCancellable *cancellable,
2026 GAsyncReadyCallback callback,
2029 const gchar *safe_uid;
2030 gchar *gdbus_uid = NULL;
2032 g_return_if_fail (uid != NULL);
2034 safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
2035 g_return_if_fail (safe_uid != NULL);
2037 e_client_proxy_call_string (
2039 safe_uid, cancellable, callback, user_data,
2040 e_book_client_get_contact,
2041 e_gdbus_book_call_get_contact,
2043 e_gdbus_book_call_get_contact_finish,
2050 * e_book_client_get_contact_finish:
2051 * @client: an #EBookClient
2052 * @result: a #GAsyncResult
2053 * @contact: (out): an #EContact for previously given uid
2054 * @error: (out): a #GError to set an error, if any
2056 * Finishes previous call of e_book_client_get_contact().
2057 * If successful, then the @contact is set to newly allocated
2058 * #EContact, which should be freed with g_object_unref().
2060 * Returns: %TRUE if successful, %FALSE otherwise.
2065 e_book_client_get_contact_finish (EBookClient *client,
2066 GAsyncResult *result,
2071 gchar *vcard = NULL;
2073 g_return_val_if_fail (contact != NULL, FALSE);
2075 res = e_client_proxy_call_finish_string (
2077 result, &vcard, error,
2078 e_book_client_get_contact);
2081 *contact = e_contact_new_from_vcard (vcard);
2091 * e_book_client_get_contact_sync:
2092 * @client: an #EBookClient
2093 * @uid: a unique string ID specifying the contact
2094 * @contact: (out): an #EContact for given @uid
2095 * @cancellable: a #GCancellable; can be %NULL
2096 * @error: (out): a #GError to set an error, if any
2098 * Receive #EContact from the @client for the gived @uid.
2099 * If successful, then the @contact is set to newly allocated
2100 * #EContact, which should be freed with g_object_unref().
2102 * Returns: %TRUE if successful, %FALSE otherwise.
2107 e_book_client_get_contact_sync (EBookClient *client,
2110 GCancellable *cancellable,
2114 const gchar *safe_uid;
2115 gchar *vcard = NULL, *gdbus_uid = NULL;
2117 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
2118 g_return_val_if_fail (uid != NULL, FALSE);
2119 g_return_val_if_fail (contact != NULL, FALSE);
2121 if (client->priv->dbus_proxy == NULL) {
2122 set_proxy_gone_error (error);
2126 safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
2127 g_return_val_if_fail (safe_uid != NULL, FALSE);
2129 res = e_client_proxy_call_sync_string__string (
2131 safe_uid, &vcard, cancellable, error,
2132 e_gdbus_book_call_get_contact_sync);
2135 *contact = e_contact_new_from_vcard_with_uid (vcard, safe_uid);
2146 * e_book_client_get_contacts:
2147 * @client: an #EBookClient
2148 * @sexp: an S-expression representing the query
2149 * @cancellable: a #GCancellable; can be %NULL
2150 * @callback: callback to call when a result is ready
2151 * @user_data: user data for the @callback
2153 * Query @client with @sexp, receiving a list of contacts which
2154 * matched. The call is finished by e_book_client_get_contacts_finish()
2155 * from the @callback.
2157 * Note: @sexp can be obtained through #EBookQuery, by converting it
2158 * to a string with e_book_query_to_string().
2163 e_book_client_get_contacts (EBookClient *client,
2165 GCancellable *cancellable,
2166 GAsyncReadyCallback callback,
2169 gchar *gdbus_sexp = NULL;
2171 g_return_if_fail (sexp != NULL);
2173 e_client_proxy_call_string (
2175 e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
2176 cancellable, callback, user_data,
2177 e_book_client_get_contacts,
2178 e_gdbus_book_call_get_contact_list,
2180 e_gdbus_book_call_get_contact_list_finish,
2183 g_free (gdbus_sexp);
2187 * e_book_client_get_contacts_finish:
2188 * @client: an #EBookClient
2189 * @result: a #GAsyncResult
2190 * @contacts: (element-type EContact) (out): a #GSList of matched #EContact-s
2191 * @error: (out): a #GError to set an error, if any
2193 * Finishes previous call of e_book_client_get_contacts().
2194 * If successful, then the @contacts is set to newly allocated list of #EContact-s,
2195 * which should be freed with e_client_util_free_object_slist().
2197 * Returns: %TRUE if successful, %FALSE otherwise.
2202 e_book_client_get_contacts_finish (EBookClient *client,
2203 GAsyncResult *result,
2208 gchar **vcards = NULL;
2210 g_return_val_if_fail (contacts != NULL, FALSE);
2212 res = e_client_proxy_call_finish_strv (
2214 result, &vcards, error,
2215 e_book_client_get_contacts);
2217 if (vcards && res) {
2219 GSList *slist = NULL;
2221 for (ii = 0; vcards[ii]; ii++) {
2222 slist = g_slist_prepend (slist, e_contact_new_from_vcard (vcards[ii]));
2225 *contacts = g_slist_reverse (slist);
2230 g_strfreev (vcards);
2236 * e_book_client_get_contacts_sync:
2237 * @client: an #EBookClient
2238 * @sexp: an S-expression representing the query
2239 * @contacts: (element-type EContact) (out): a #GSList of matched #EContact-s
2240 * @cancellable: a #GCancellable; can be %NULL
2241 * @error: (out): a #GError to set an error, if any
2243 * Query @client with @sexp, receiving a list of contacts which matched.
2244 * If successful, then the @contacts is set to newly allocated #GSList of
2245 * #EContact-s, which should be freed with e_client_util_free_object_slist().
2247 * Note: @sexp can be obtained through #EBookQuery, by converting it
2248 * to a string with e_book_query_to_string().
2250 * Returns: %TRUE if successful, %FALSE otherwise.
2255 e_book_client_get_contacts_sync (EBookClient *client,
2258 GCancellable *cancellable,
2262 gchar *gdbus_sexp = NULL;
2263 gchar **vcards = NULL;
2265 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
2266 g_return_val_if_fail (sexp != NULL, FALSE);
2267 g_return_val_if_fail (contacts != NULL, FALSE);
2269 if (client->priv->dbus_proxy == NULL) {
2270 set_proxy_gone_error (error);
2274 res = e_client_proxy_call_sync_string__strv (
2276 e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
2277 &vcards, cancellable, error,
2278 e_gdbus_book_call_get_contact_list_sync);
2280 if (vcards && res) {
2282 GSList *slist = NULL;
2284 for (ii = 0; vcards[ii]; ii++) {
2285 slist = g_slist_prepend (slist, e_contact_new_from_vcard (vcards[ii]));
2288 *contacts = g_slist_reverse (slist);
2293 g_free (gdbus_sexp);
2294 g_strfreev (vcards);
2300 * e_book_client_get_contacts_uids:
2301 * @client: an #EBookClient
2302 * @sexp: an S-expression representing the query
2303 * @cancellable: a #GCancellable; can be %NULL
2304 * @callback: callback to call when a result is ready
2305 * @user_data: user data for the @callback
2307 * Query @client with @sexp, receiving a list of contacts UIDs which
2308 * matched. The call is finished by e_book_client_get_contacts_uids_finish()
2309 * from the @callback.
2311 * Note: @sexp can be obtained through #EBookQuery, by converting it
2312 * to a string with e_book_query_to_string().
2317 e_book_client_get_contacts_uids (EBookClient *client,
2319 GCancellable *cancellable,
2320 GAsyncReadyCallback callback,
2323 gchar *gdbus_sexp = NULL;
2325 g_return_if_fail (sexp != NULL);
2327 e_client_proxy_call_string (
2329 e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
2330 cancellable, callback, user_data,
2331 e_book_client_get_contacts_uids,
2332 e_gdbus_book_call_get_contact_list_uids,
2334 e_gdbus_book_call_get_contact_list_uids_finish,
2337 g_free (gdbus_sexp);
2341 * e_book_client_get_contacts_uids_finish:
2342 * @client: an #EBookClient
2343 * @result: a #GAsyncResult
2344 * @contacts_uids: (element-type utf8) (out): a #GSList of matched contacts UIDs stored as strings
2345 * @error: (out): a #GError to set an error, if any
2347 * Finishes previous call of e_book_client_get_contacts_uids().
2348 * If successful, then the @contacts_uids is set to newly allocated list
2349 * of UID strings, which should be freed with e_client_util_free_string_slist().
2351 * Returns: %TRUE if successful, %FALSE otherwise.
2356 e_book_client_get_contacts_uids_finish (EBookClient *client,
2357 GAsyncResult *result,
2358 GSList **contacts_uids,
2362 gchar **uids = NULL;
2364 g_return_val_if_fail (contacts_uids != NULL, FALSE);
2366 res = e_client_proxy_call_finish_strv (
2368 result, &uids, error,
2369 e_book_client_get_contacts_uids);
2373 GSList *slist = NULL;
2375 for (ii = 0; uids[ii]; ii++) {
2376 slist = g_slist_prepend (slist, g_strdup (uids[ii]));
2379 *contacts_uids = g_slist_reverse (slist);
2381 *contacts_uids = NULL;
2390 * e_book_client_get_contacts_uids_sync:
2391 * @client: an #EBookClient
2392 * @sexp: an S-expression representing the query
2393 * @contacts_uids: (element-type utf8) (out): a #GSList of matched contacts UIDs stored as strings
2394 * @cancellable: a #GCancellable; can be %NULL
2395 * @error: (out): a #GError to set an error, if any
2397 * Query @client with @sexp, receiving a list of contacts UIDs which matched.
2398 * If successful, then the @contacts_uids is set to newly allocated list
2399 * of UID strings, which should be freed with e_client_util_free_string_slist().
2401 * Note: @sexp can be obtained through #EBookQuery, by converting it
2402 * to a string with e_book_query_to_string().
2404 * Returns: %TRUE if successful, %FALSE otherwise.
2409 e_book_client_get_contacts_uids_sync (EBookClient *client,
2411 GSList **contacts_uids,
2412 GCancellable *cancellable,
2416 gchar *gdbus_sexp = NULL;
2417 gchar **uids = NULL;
2419 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
2420 g_return_val_if_fail (sexp != NULL, FALSE);
2421 g_return_val_if_fail (contacts_uids != NULL, FALSE);
2423 if (client->priv->dbus_proxy == NULL) {
2424 set_proxy_gone_error (error);
2428 res = e_client_proxy_call_sync_string__strv (
2430 e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
2431 &uids, cancellable, error,
2432 e_gdbus_book_call_get_contact_list_uids_sync);
2436 GSList *slist = NULL;
2438 for (ii = 0; uids[ii]; ii++) {
2439 slist = g_slist_prepend (slist, g_strdup (uids[ii]));
2442 *contacts_uids = g_slist_reverse (slist);
2444 *contacts_uids = NULL;
2447 g_free (gdbus_sexp);
2454 * e_book_client_get_view:
2455 * @client: an #EBookClient
2456 * @sexp: an S-expression representing the query
2457 * @cancellable: a #GCancellable; can be %NULL
2458 * @callback: callback to call when a result is ready
2459 * @user_data: user data for the @callback
2461 * Query @client with @sexp, creating an #EBookClientView.
2462 * The call is finished by e_book_client_get_view_finish()
2463 * from the @callback.
2465 * Note: @sexp can be obtained through #EBookQuery, by converting it
2466 * to a string with e_book_query_to_string().
2471 e_book_client_get_view (EBookClient *client,
2473 GCancellable *cancellable,
2474 GAsyncReadyCallback callback,
2477 gchar *gdbus_sexp = NULL;
2479 g_return_if_fail (sexp != NULL);
2481 e_client_proxy_call_string (
2483 e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
2484 cancellable, callback, user_data,
2485 e_book_client_get_view,
2486 e_gdbus_book_call_get_view,
2488 e_gdbus_book_call_get_view_finish, NULL, NULL);
2490 g_free (gdbus_sexp);
2494 complete_get_view (EBookClient *client,
2497 EBookClientView **view,
2500 g_return_val_if_fail (view != NULL, FALSE);
2502 if (view_path && res && book_factory) {
2503 GDBusConnection *connection;
2504 GError *local_error = NULL;
2506 connection = g_dbus_proxy_get_connection (
2507 G_DBUS_PROXY (book_factory));
2509 *view = g_initable_new (
2510 E_TYPE_BOOK_CLIENT_VIEW,
2513 "connection", connection,
2514 "object-path", view_path,
2517 if (local_error != NULL) {
2518 unwrap_dbus_error (local_error, error);
2526 if (!*view && error && !*error)
2527 g_set_error_literal (error, E_CLIENT_ERROR, E_CLIENT_ERROR_DBUS_ERROR, _("Cannot get connection to view"));
2535 * e_book_client_get_view_finish:
2536 * @client: an #EBookClient
2537 * @result: a #GAsyncResult
2538 * @view: (out): an #EBookClientView
2539 * @error: (out): a #GError to set an error, if any
2541 * Finishes previous call of e_book_client_get_view().
2542 * If successful, then the @view is set to newly allocated #EBookClientView,
2543 * which should be freed with g_object_unref().
2545 * Returns: %TRUE if successful, %FALSE otherwise.
2550 e_book_client_get_view_finish (EBookClient *client,
2551 GAsyncResult *result,
2552 EBookClientView **view,
2556 gchar *view_path = NULL;
2558 g_return_val_if_fail (view != NULL, FALSE);
2560 res = e_client_proxy_call_finish_string (
2562 result, &view_path, error,
2563 e_book_client_get_view);
2565 return complete_get_view (client, res, view_path, view, error);
2569 * e_book_client_get_view_sync:
2570 * @client: an #EBookClient
2571 * @sexp: an S-expression representing the query
2572 * @view: (out) an #EBookClientView
2573 * @cancellable: a #GCancellable; can be %NULL
2574 * @error: (out): a #GError to set an error, if any
2576 * Query @client with @sexp, creating an #EBookClientView.
2577 * If successful, then the @view is set to newly allocated #EBookClientView,
2578 * which should be freed with g_object_unref().
2580 * Note: @sexp can be obtained through #EBookQuery, by converting it
2581 * to a string with e_book_query_to_string().
2583 * Returns: %TRUE if successful, %FALSE otherwise.
2588 e_book_client_get_view_sync (EBookClient *client,
2590 EBookClientView **view,
2591 GCancellable *cancellable,
2595 gchar *gdbus_sexp = NULL;
2596 gchar *view_path = NULL;
2598 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
2599 g_return_val_if_fail (sexp != NULL, FALSE);
2600 g_return_val_if_fail (view != NULL, FALSE);
2602 if (client->priv->dbus_proxy == NULL) {
2603 set_proxy_gone_error (error);
2607 res = e_client_proxy_call_sync_string__string (
2609 e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
2610 &view_path, cancellable, error,
2611 e_gdbus_book_call_get_view_sync);
2613 g_free (gdbus_sexp);
2615 return complete_get_view (client, res, view_path, view, error);