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
66 G_DEFINE_QUARK (e-book-client-error-quark, e_book_client_error)
69 * e_book_client_error_to_string:
76 e_book_client_error_to_string (EBookClientError code)
79 case E_BOOK_CLIENT_ERROR_NO_SUCH_BOOK:
80 return _("No such book");
81 case E_BOOK_CLIENT_ERROR_CONTACT_NOT_FOUND:
82 return _("Contact not found");
83 case E_BOOK_CLIENT_ERROR_CONTACT_ID_ALREADY_EXISTS:
84 return _("Contact ID already exists");
85 case E_BOOK_CLIENT_ERROR_NO_SUCH_SOURCE:
86 return _("No such source");
87 case E_BOOK_CLIENT_ERROR_NO_SPACE:
91 return _("Unknown error");
95 * e_book_client_error_create:
96 * @code: an #EBookClientError code to create
97 * @custom_msg: custom message to use for the error; can be %NULL
99 * Returns: a new #GError containing an E_BOOK_CLIENT_ERROR of the given
100 * @code. If the @custom_msg is NULL, then the error message is
101 * the one returned from e_book_client_error_to_string() for the @code,
102 * otherwise the given message is used.
104 * Returned pointer should be freed with g_error_free().
109 e_book_client_error_create (EBookClientError code,
110 const gchar *custom_msg)
112 return g_error_new_literal (E_BOOK_CLIENT_ERROR, code, custom_msg ? custom_msg : e_book_client_error_to_string (code));
116 * If the specified GError is a remote error, then create a new error
117 * representing the remote error. If the error is anything else, then
121 unwrap_dbus_error (GError *error,
122 GError **client_error)
124 #define err(a,b) "org.gnome.evolution.dataserver.AddressBook." a, b
125 static EClientErrorsList book_errors[] = {
126 { err ("Success", -1) },
127 { err ("ContactNotFound", E_BOOK_CLIENT_ERROR_CONTACT_NOT_FOUND) },
128 { err ("ContactIDAlreadyExists", E_BOOK_CLIENT_ERROR_CONTACT_ID_ALREADY_EXISTS) },
129 { err ("NoSuchBook", E_BOOK_CLIENT_ERROR_NO_SUCH_BOOK) },
130 { err ("BookRemoved", E_BOOK_CLIENT_ERROR_NO_SUCH_SOURCE) },
131 { err ("NoSpace", E_BOOK_CLIENT_ERROR_NO_SPACE) }
133 { err ("Busy", E_CLIENT_ERROR_BUSY) },
134 { err ("RepositoryOffline", E_CLIENT_ERROR_REPOSITORY_OFFLINE) },
135 { err ("OfflineUnavailable", E_CLIENT_ERROR_OFFLINE_UNAVAILABLE) },
136 { err ("PermissionDenied", E_CLIENT_ERROR_PERMISSION_DENIED) },
137 { err ("AuthenticationFailed", E_CLIENT_ERROR_AUTHENTICATION_FAILED) },
138 { err ("AuthenticationRequired", E_CLIENT_ERROR_AUTHENTICATION_REQUIRED) },
139 { err ("CouldNotCancel", E_CLIENT_ERROR_COULD_NOT_CANCEL) },
140 { err ("InvalidArg", E_CLIENT_ERROR_INVALID_ARG) },
141 { err ("NotSupported", E_CLIENT_ERROR_NOT_SUPPORTED) },
142 { err ("UnsupportedAuthenticationMethod", E_CLIENT_ERROR_UNSUPPORTED_AUTHENTICATION_METHOD) },
143 { err ("TLSNotAvailable", E_CLIENT_ERROR_TLS_NOT_AVAILABLE) },
144 { err ("SearchSizeLimitExceeded", E_CLIENT_ERROR_SEARCH_SIZE_LIMIT_EXCEEDED) },
145 { err ("SearchTimeLimitExceeded", E_CLIENT_ERROR_SEARCH_TIME_LIMIT_EXCEEDED) },
146 { err ("InvalidQuery", E_CLIENT_ERROR_INVALID_QUERY) },
147 { err ("QueryRefused", E_CLIENT_ERROR_QUERY_REFUSED) },
148 { err ("NotOpened", E_CLIENT_ERROR_NOT_OPENED) },
149 { err ("UnsupportedField", E_CLIENT_ERROR_OTHER_ERROR) },
150 { err ("InvalidServerVersion", E_CLIENT_ERROR_OTHER_ERROR) },
151 { err ("OtherError", E_CLIENT_ERROR_OTHER_ERROR) }
158 if (!e_client_util_unwrap_dbus_error (error, client_error, book_errors, G_N_ELEMENTS (book_errors), E_BOOK_CLIENT_ERROR, TRUE))
159 e_client_util_unwrap_dbus_error (error, client_error, cl_errors, G_N_ELEMENTS (cl_errors), E_CLIENT_ERROR, FALSE);
165 set_proxy_gone_error (GError **error)
167 /* do not translate this string, it should ideally never happen */
168 g_set_error_literal (error, E_CLIENT_ERROR, E_CLIENT_ERROR_DBUS_ERROR, "D-Bus book proxy gone");
171 static guint active_book_clients = 0, book_connection_closed_id = 0;
172 static EGdbusBookFactory *book_factory = NULL;
173 static GRecMutex book_factory_lock;
174 #define LOCK_FACTORY() g_rec_mutex_lock (&book_factory_lock)
175 #define UNLOCK_FACTORY() g_rec_mutex_unlock (&book_factory_lock)
177 static void gdbus_book_factory_closed_cb (GDBusConnection *connection, gboolean remote_peer_vanished, GError *error, gpointer user_data);
180 gdbus_book_factory_disconnect (GDBusConnection *connection)
184 if (!connection && book_factory)
185 connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (book_factory));
187 if (connection && book_connection_closed_id) {
188 g_dbus_connection_signal_unsubscribe (connection, book_connection_closed_id);
189 g_signal_handlers_disconnect_by_func (connection, gdbus_book_factory_closed_cb, NULL);
192 if (book_factory != NULL)
193 g_object_unref (book_factory);
195 book_connection_closed_id = 0;
202 gdbus_book_factory_closed_cb (GDBusConnection *connection,
203 gboolean remote_peer_vanished,
211 gdbus_book_factory_disconnect (connection);
214 unwrap_dbus_error (g_error_copy (error), &err);
217 g_debug ("GDBus connection is closed%s: %s", remote_peer_vanished ? ", remote peer vanished" : "", err->message);
219 } else if (active_book_clients) {
220 g_debug ("GDBus connection is closed%s", remote_peer_vanished ? ", remote peer vanished" : "");
227 gdbus_book_factory_connection_gone_cb (GDBusConnection *connection,
228 const gchar *sender_name,
229 const gchar *object_path,
230 const gchar *interface_name,
231 const gchar *signal_name,
232 GVariant *parameters,
235 /* signal subscription takes care of correct parameters,
236 * thus just do what is to be done here */
237 gdbus_book_factory_closed_cb (connection, TRUE, NULL, user_data);
241 gdbus_book_factory_activate (GCancellable *cancellable,
244 GDBusConnection *connection;
248 if (G_LIKELY (book_factory != NULL)) {
253 book_factory = e_gdbus_book_factory_proxy_new_for_bus_sync (
255 G_DBUS_PROXY_FLAGS_NONE,
256 ADDRESS_BOOK_DBUS_SERVICE_NAME,
257 "/org/gnome/evolution/dataserver/AddressBookFactory",
260 if (book_factory == NULL) {
265 connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (book_factory));
266 book_connection_closed_id = g_dbus_connection_signal_subscribe (
269 "org.freedesktop.DBus", /* interface */
270 "NameOwnerChanged", /* member */
271 "/org/freedesktop/DBus", /* object_path */
272 "org.gnome.evolution.dataserver.AddressBook", /* arg0 */
273 G_DBUS_SIGNAL_FLAGS_NONE,
274 gdbus_book_factory_connection_gone_cb, NULL, NULL);
277 connection, "closed",
278 G_CALLBACK (gdbus_book_factory_closed_cb), NULL);
285 static void gdbus_book_client_disconnect (EBookClient *client);
288 * Called when the addressbook server dies.
291 gdbus_book_client_closed_cb (GDBusConnection *connection,
292 gboolean remote_peer_vanished,
298 g_assert (E_IS_BOOK_CLIENT (client));
301 unwrap_dbus_error (g_error_copy (error), &err);
304 g_debug (G_STRLOC ": EBookClient GDBus connection is closed%s: %s", remote_peer_vanished ? ", remote peer vanished" : "", err->message);
307 g_debug (G_STRLOC ": EBookClient GDBus connection is closed%s", remote_peer_vanished ? ", remote peer vanished" : "");
310 gdbus_book_client_disconnect (client);
312 e_client_emit_backend_died (E_CLIENT (client));
316 gdbus_book_client_connection_gone_cb (GDBusConnection *connection,
317 const gchar *sender_name,
318 const gchar *object_path,
319 const gchar *interface_name,
320 const gchar *signal_name,
321 GVariant *parameters,
324 /* signal subscription takes care of correct parameters,
325 * thus just do what is to be done here */
326 gdbus_book_client_closed_cb (connection, TRUE, NULL, user_data);
330 gdbus_book_client_disconnect (EBookClient *client)
332 g_return_if_fail (E_IS_BOOK_CLIENT (client));
334 /* Ensure that everything relevant is NULL */
337 if (client->priv->dbus_proxy != NULL) {
338 GDBusConnection *connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (client->priv->dbus_proxy));
340 g_signal_handlers_disconnect_by_func (connection, gdbus_book_client_closed_cb, client);
341 g_dbus_connection_signal_unsubscribe (connection, client->priv->gone_signal_id);
342 client->priv->gone_signal_id = 0;
344 e_gdbus_book_call_close_sync (
345 client->priv->dbus_proxy, NULL, NULL);
346 g_object_unref (client->priv->dbus_proxy);
347 client->priv->dbus_proxy = NULL;
354 backend_error_cb (EGdbusBook *dbus_proxy,
355 const gchar *message,
358 g_return_if_fail (E_IS_BOOK_CLIENT (client));
359 g_return_if_fail (message != NULL);
361 e_client_emit_backend_error (E_CLIENT (client), message);
365 readonly_cb (EGdbusBook *dbus_proxy,
369 g_return_if_fail (E_IS_BOOK_CLIENT (client));
371 e_client_set_readonly (E_CLIENT (client), readonly);
375 online_cb (EGdbusBook *dbus_proxy,
379 g_return_if_fail (E_IS_BOOK_CLIENT (client));
381 e_client_set_online (E_CLIENT (client), is_online);
385 opened_cb (EGdbusBook *dbus_proxy,
386 const gchar * const *error_strv,
389 GError *error = NULL;
391 g_return_if_fail (E_IS_BOOK_CLIENT (client));
392 g_return_if_fail (error_strv != NULL);
393 g_return_if_fail (e_gdbus_templates_decode_error (error_strv, &error));
395 e_client_emit_opened (E_CLIENT (client), error);
398 g_error_free (error);
402 backend_property_changed_cb (EGdbusBook *dbus_proxy,
403 const gchar * const *name_value_strv,
406 gchar *prop_name = NULL, *prop_value = NULL;
408 g_return_if_fail (E_IS_BOOK_CLIENT (client));
409 g_return_if_fail (name_value_strv != NULL);
410 g_return_if_fail (e_gdbus_templates_decode_two_strings (name_value_strv, &prop_name, &prop_value));
411 g_return_if_fail (prop_name != NULL);
412 g_return_if_fail (*prop_name);
413 g_return_if_fail (prop_value != NULL);
415 e_client_emit_backend_property_changed (E_CLIENT (client), prop_name, prop_value);
422 * Converts a GSList of EContact objects into a NULL-terminated array of
423 * valid UTF-8 vcard strings, suitable for sending over DBus.
426 contact_slist_to_utf8_vcard_array (GSList *contacts)
432 array = g_new0 (gchar *, g_slist_length (contacts) + 1);
433 for (l = contacts; l != NULL; l = l->next) {
434 gchar *vcard = e_vcard_to_string (E_VCARD (l->data), EVC_FORMAT_VCARD_30);
435 array[i++] = e_util_utf8_make_valid (vcard);
443 book_client_get_backend_property_from_cache_finish (EClient *client,
444 GAsyncResult *result,
448 GSimpleAsyncResult *simple;
449 GError *local_error = NULL;
451 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
452 g_return_val_if_fail (result != NULL, FALSE);
453 g_return_val_if_fail (prop_value != NULL, FALSE);
454 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), book_client_get_backend_property_from_cache_finish), FALSE);
456 simple = G_SIMPLE_ASYNC_RESULT (result);
458 if (g_simple_async_result_propagate_error (simple, &local_error)) {
459 e_client_unwrap_dbus_error (client, local_error, error);
463 *prop_value = g_strdup (g_simple_async_result_get_op_res_gpointer (simple));
465 return *prop_value != NULL;
469 book_client_dispose (GObject *object)
473 client = E_CLIENT (object);
475 e_client_cancel_all (client);
477 gdbus_book_client_disconnect (E_BOOK_CLIENT (client));
479 /* Chain up to parent's dispose() method. */
480 G_OBJECT_CLASS (e_book_client_parent_class)->dispose (object);
484 book_client_finalize (GObject *object)
486 /* Chain up to parent's finalize() method. */
487 G_OBJECT_CLASS (e_book_client_parent_class)->finalize (object);
490 active_book_clients--;
491 if (!active_book_clients)
492 gdbus_book_factory_disconnect (NULL);
497 book_client_get_dbus_proxy (EClient *client)
499 EBookClientPrivate *priv;
501 priv = E_BOOK_CLIENT_GET_PRIVATE (client);
503 return G_DBUS_PROXY (priv->dbus_proxy);
507 book_client_unwrap_dbus_error (EClient *client,
511 unwrap_dbus_error (dbus_error, out_error);
515 book_client_retrieve_capabilities (EClient *client,
516 GCancellable *cancellable,
517 GAsyncReadyCallback callback,
520 g_return_if_fail (E_IS_BOOK_CLIENT (client));
522 e_client_get_backend_property (client, CLIENT_BACKEND_PROPERTY_CAPABILITIES, cancellable, callback, user_data);
526 book_client_retrieve_capabilities_finish (EClient *client,
527 GAsyncResult *result,
528 gchar **capabilities,
531 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
533 return e_client_get_backend_property_finish (client, result, capabilities, error);
537 book_client_retrieve_capabilities_sync (EClient *client,
538 gchar **capabilities,
539 GCancellable *cancellable,
542 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
544 return e_client_get_backend_property_sync (client, CLIENT_BACKEND_PROPERTY_CAPABILITIES, capabilities, cancellable, error);
548 book_client_get_backend_property (EClient *client,
549 const gchar *prop_name,
550 GCancellable *cancellable,
551 GAsyncReadyCallback callback,
556 prop_value = e_client_get_backend_property_from_cache (client, prop_name);
558 e_client_finish_async_without_dbus (
559 client, cancellable, callback, user_data,
560 book_client_get_backend_property_from_cache_finish,
563 e_client_proxy_call_string_with_res_op_data (
565 cancellable, callback, user_data,
566 book_client_get_backend_property, prop_name,
567 e_gdbus_book_call_get_backend_property,
569 e_gdbus_book_call_get_backend_property_finish,
575 book_client_get_backend_property_finish (EClient *client,
576 GAsyncResult *result,
583 g_return_val_if_fail (prop_value != NULL, FALSE);
585 if (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (result)) == book_client_get_backend_property_from_cache_finish) {
586 res = book_client_get_backend_property_from_cache_finish (client, result, &str, error);
588 res = e_client_proxy_call_finish_string (
589 client, result, &str, error,
590 book_client_get_backend_property);
592 const gchar *prop_name = g_object_get_data (G_OBJECT (result), "res-op-data");
594 if (prop_name && *prop_name)
595 e_client_update_backend_property_cache (client, prop_name, str);
605 book_client_get_backend_property_sync (EClient *client,
606 const gchar *prop_name,
608 GCancellable *cancellable,
611 EBookClient *book_client;
615 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
617 book_client = E_BOOK_CLIENT (client);
619 if (book_client->priv->dbus_proxy == NULL) {
620 set_proxy_gone_error (error);
624 prop_val = e_client_get_backend_property_from_cache (client, prop_name);
626 g_return_val_if_fail (prop_value != NULL, FALSE);
628 *prop_value = prop_val;
633 res = e_client_proxy_call_sync_string__string (
634 client, prop_name, prop_value, cancellable, error,
635 e_gdbus_book_call_get_backend_property_sync);
637 if (res && prop_value)
638 e_client_update_backend_property_cache (
639 client, prop_name, *prop_value);
645 book_client_set_backend_property (EClient *client,
646 const gchar *prop_name,
647 const gchar *prop_value,
648 GCancellable *cancellable,
649 GAsyncReadyCallback callback,
652 gchar **prop_name_value;
654 prop_name_value = e_gdbus_book_encode_set_backend_property (prop_name, prop_value);
656 e_client_proxy_call_strv (
657 client, (const gchar * const *) prop_name_value,
658 cancellable, callback, user_data,
659 book_client_set_backend_property,
660 e_gdbus_book_call_set_backend_property,
661 e_gdbus_book_call_set_backend_property_finish,
662 NULL, NULL, NULL, NULL);
664 g_strfreev (prop_name_value);
668 book_client_set_backend_property_finish (EClient *client,
669 GAsyncResult *result,
672 return e_client_proxy_call_finish_void (
673 client, result, error,
674 book_client_set_backend_property);
678 book_client_set_backend_property_sync (EClient *client,
679 const gchar *prop_name,
680 const gchar *prop_value,
681 GCancellable *cancellable,
684 EBookClient *book_client;
686 gchar **prop_name_value;
688 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
690 book_client = E_BOOK_CLIENT (client);
692 if (book_client->priv->dbus_proxy == NULL) {
693 set_proxy_gone_error (error);
697 prop_name_value = e_gdbus_book_encode_set_backend_property (prop_name, prop_value);
698 res = e_client_proxy_call_sync_strv__void (
699 client, (const gchar * const *) prop_name_value,
701 e_gdbus_book_call_set_backend_property_sync);
702 g_strfreev (prop_name_value);
708 book_client_open (EClient *client,
709 gboolean only_if_exists,
710 GCancellable *cancellable,
711 GAsyncReadyCallback callback,
714 e_client_proxy_call_boolean (
715 client, only_if_exists,
716 cancellable, callback, user_data,
718 e_gdbus_book_call_open,
719 e_gdbus_book_call_open_finish,
720 NULL, NULL, NULL, NULL);
724 book_client_open_finish (EClient *client,
725 GAsyncResult *result,
728 return e_client_proxy_call_finish_void (
729 client, result, error, book_client_open);
733 book_client_open_sync (EClient *client,
734 gboolean only_if_exists,
735 GCancellable *cancellable,
738 EBookClient *book_client;
740 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
742 book_client = E_BOOK_CLIENT (client);
744 if (book_client->priv->dbus_proxy == NULL) {
745 set_proxy_gone_error (error);
749 return e_client_proxy_call_sync_boolean__void (
750 client, only_if_exists, cancellable, error,
751 e_gdbus_book_call_open_sync);
755 book_client_refresh (EClient *client,
756 GCancellable *cancellable,
757 GAsyncReadyCallback callback,
760 e_client_proxy_call_void (
761 client, cancellable, callback, user_data,
763 e_gdbus_book_call_refresh,
764 e_gdbus_book_call_refresh_finish,
765 NULL, NULL, NULL, NULL);
769 book_client_refresh_finish (EClient *client,
770 GAsyncResult *result,
773 return e_client_proxy_call_finish_void (
774 client, result, error, book_client_refresh);
778 book_client_refresh_sync (EClient *client,
779 GCancellable *cancellable,
782 EBookClient *book_client;
784 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
786 book_client = E_BOOK_CLIENT (client);
788 if (book_client->priv->dbus_proxy == NULL) {
789 set_proxy_gone_error (error);
793 return e_client_proxy_call_sync_void__void (
794 client, cancellable, error,
795 e_gdbus_book_call_refresh_sync);
799 e_book_client_class_init (EBookClientClass *class)
801 GObjectClass *object_class;
802 EClientClass *client_class;
804 g_type_class_add_private (class, sizeof (EBookClientPrivate));
806 object_class = G_OBJECT_CLASS (class);
807 object_class->dispose = book_client_dispose;
808 object_class->finalize = book_client_finalize;
810 client_class = E_CLIENT_CLASS (class);
811 client_class->get_dbus_proxy = book_client_get_dbus_proxy;
812 client_class->unwrap_dbus_error = book_client_unwrap_dbus_error;
813 client_class->retrieve_capabilities = book_client_retrieve_capabilities;
814 client_class->retrieve_capabilities_finish = book_client_retrieve_capabilities_finish;
815 client_class->retrieve_capabilities_sync = book_client_retrieve_capabilities_sync;
816 client_class->get_backend_property = book_client_get_backend_property;
817 client_class->get_backend_property_finish = book_client_get_backend_property_finish;
818 client_class->get_backend_property_sync = book_client_get_backend_property_sync;
819 client_class->set_backend_property = book_client_set_backend_property;
820 client_class->set_backend_property_finish = book_client_set_backend_property_finish;
821 client_class->set_backend_property_sync = book_client_set_backend_property_sync;
822 client_class->open = book_client_open;
823 client_class->open_finish = book_client_open_finish;
824 client_class->open_sync = book_client_open_sync;
825 client_class->refresh = book_client_refresh;
826 client_class->refresh_finish = book_client_refresh_finish;
827 client_class->refresh_sync = book_client_refresh_sync;
831 e_book_client_init (EBookClient *client)
834 active_book_clients++;
837 client->priv = E_BOOK_CLIENT_GET_PRIVATE (client);
842 * @source: An #ESource pointer
843 * @error: A #GError pointer
845 * Creates a new #EBookClient corresponding to the given source. There are
846 * only two operations that are valid on this book at this point:
847 * e_client_open(), and e_client_remove().
849 * Returns: a new but unopened #EBookClient.
854 e_book_client_new (ESource *source,
859 GDBusConnection *connection;
861 gchar *object_path = NULL;
863 g_return_val_if_fail (source != NULL, NULL);
864 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
867 /* XXX Oops, e_book_client_new() forgot to take a GCancellable. */
868 if (!gdbus_book_factory_activate (NULL, &err)) {
871 unwrap_dbus_error (err, &err);
872 g_warning ("%s: Failed to run book factory: %s", G_STRFUNC, err->message);
873 g_propagate_error (error, err);
875 g_warning ("%s: Failed to run book factory: Unknown error", G_STRFUNC);
876 g_set_error_literal (error, E_CLIENT_ERROR, E_CLIENT_ERROR_DBUS_ERROR, _("Failed to run book factory"));
882 uid = e_source_get_uid (source);
884 client = g_object_new (E_TYPE_BOOK_CLIENT, "source", source, NULL);
887 e_gdbus_book_factory_call_get_book_sync (
888 G_DBUS_PROXY (book_factory), uid, &object_path, NULL, &err);
891 g_return_val_if_fail (
892 ((object_path != NULL) && (err == NULL)) ||
893 ((object_path == NULL) && (err != NULL)), NULL);
896 unwrap_dbus_error (err, &err);
897 g_propagate_error (error, err);
898 g_object_unref (client);
902 connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (book_factory));
904 client->priv->dbus_proxy = G_DBUS_PROXY (e_gdbus_book_proxy_new_sync (
906 G_DBUS_PROXY_FLAGS_NONE,
907 ADDRESS_BOOK_DBUS_SERVICE_NAME,
911 g_free (object_path);
914 g_return_val_if_fail (
915 ((client->priv->dbus_proxy != NULL) && (err == NULL)) ||
916 ((client->priv->dbus_proxy == NULL) && (err != NULL)), NULL);
919 unwrap_dbus_error (err, &err);
920 g_propagate_error (error, err);
921 g_object_unref (client);
925 client->priv->gone_signal_id = g_dbus_connection_signal_subscribe (
927 "org.freedesktop.DBus", /* sender */
928 "org.freedesktop.DBus", /* interface */
929 "NameOwnerChanged", /* member */
930 "/org/freedesktop/DBus", /* object_path */
931 "org.gnome.evolution.dataserver.AddressBook", /* arg0 */
932 G_DBUS_SIGNAL_FLAGS_NONE,
933 gdbus_book_client_connection_gone_cb, client, NULL);
936 connection, "closed",
937 G_CALLBACK (gdbus_book_client_closed_cb), client);
940 client->priv->dbus_proxy, "backend_error",
941 G_CALLBACK (backend_error_cb), client);
943 client->priv->dbus_proxy, "readonly",
944 G_CALLBACK (readonly_cb), client);
946 client->priv->dbus_proxy, "online",
947 G_CALLBACK (online_cb), client);
949 client->priv->dbus_proxy, "opened",
950 G_CALLBACK (opened_cb), client);
952 client->priv->dbus_proxy, "backend-property-changed",
953 G_CALLBACK (backend_property_changed_cb), client);
958 #define SELF_UID_PATH_ID "org.gnome.evolution-data-server.addressbook"
959 #define SELF_UID_KEY "self-contact-uid"
968 vcard = g_string_new ("BEGIN:VCARD\nVERSION:3.0\n");
970 s = g_get_user_name ();
972 g_string_append_printf (vcard, "NICKNAME:%s\n", s);
974 s = g_get_real_name ();
975 if (s && strcmp (s, "Unknown") != 0) {
976 ENameWestern *western;
978 g_string_append_printf (vcard, "FN:%s\n", s);
980 western = e_name_western_parse (s);
981 g_string_append_printf (
982 vcard, "N:%s;%s;%s;%s;%s\n",
983 western->last ? western->last : "",
984 western->first ? western->first : "",
985 western->middle ? western->middle : "",
986 western->prefix ? western->prefix : "",
987 western->suffix ? western->suffix : "");
988 e_name_western_free (western);
990 g_string_append (vcard, "END:VCARD");
992 contact = e_contact_new_from_vcard (vcard->str);
994 g_string_free (vcard, TRUE);
1000 * e_book_client_get_self:
1001 * @registry: an #ESourceRegistry
1002 * @contact: (out): an #EContact pointer to set
1003 * @client: (out): an #EBookClient pointer to set
1004 * @error: a #GError to set on failure
1006 * Get the #EContact referring to the user of the address book
1007 * and set it in @contact and @client.
1009 * Returns: %TRUE if successful, otherwise %FALSE.
1014 e_book_client_get_self (ESourceRegistry *registry,
1016 EBookClient **client,
1020 GError *local_error = NULL;
1021 GSettings *settings;
1024 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
1025 g_return_val_if_fail (contact != NULL, FALSE);
1026 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1028 source = e_source_registry_ref_builtin_address_book (registry);
1029 *client = e_book_client_new (source, &local_error);
1030 g_object_unref (source);
1033 g_propagate_error (error, local_error);
1037 if (!e_client_open_sync (E_CLIENT (*client), FALSE, NULL, &local_error)) {
1038 g_object_unref (*client);
1040 g_propagate_error (error, local_error);
1045 settings = g_settings_new (SELF_UID_PATH_ID);
1046 uid = g_settings_get_string (settings, SELF_UID_KEY);
1047 g_object_unref (settings);
1052 /* Don't care about errors because we'll create a new card on failure */
1053 got = e_book_client_get_contact_sync (*client, uid, contact, NULL, NULL);
1060 *contact = make_me_card ();
1061 if (!e_book_client_add_contact_sync (*client, *contact, &uid, NULL, &local_error)) {
1062 g_object_unref (*client);
1064 g_object_unref (*contact);
1066 g_propagate_error (error, local_error);
1071 e_contact_set (*contact, E_CONTACT_UID, uid);
1075 e_book_client_set_self (*client, *contact, NULL);
1081 * e_book_client_set_self:
1082 * @client: an #EBookClient
1083 * @contact: an #EContact
1084 * @error: a #GError to set on failure
1086 * Specify that @contact residing in @client is the #EContact that
1087 * refers to the user of the address book.
1089 * Returns: %TRUE if successful, %FALSE otherwise.
1094 e_book_client_set_self (EBookClient *client,
1098 GSettings *settings;
1100 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1101 g_return_val_if_fail (contact != NULL, FALSE);
1102 g_return_val_if_fail (e_contact_get_const (contact, E_CONTACT_UID) != NULL, FALSE);
1104 settings = g_settings_new (SELF_UID_PATH_ID);
1105 g_settings_set_string (settings, SELF_UID_KEY, e_contact_get_const (contact, E_CONTACT_UID));
1106 g_object_unref (settings);
1112 * e_book_client_is_self:
1113 * @contact: an #EContact
1115 * Check if @contact is the user of the address book.
1117 * Returns: %TRUE if @contact is the user, %FALSE otherwise.
1122 e_book_client_is_self (EContact *contact)
1124 GSettings *settings;
1128 g_return_val_if_fail (contact && E_IS_CONTACT (contact), FALSE);
1130 settings = g_settings_new (SELF_UID_PATH_ID);
1131 uid = g_settings_get_string (settings, SELF_UID_KEY);
1132 g_object_unref (settings);
1134 is_self = uid && !g_strcmp0 (uid, e_contact_get_const (contact, E_CONTACT_UID));
1142 * e_book_client_add_contact:
1143 * @client: an #EBookClient
1144 * @contact: an #EContact
1145 * @cancellable: a #GCancellable; can be %NULL
1146 * @callback: callback to call when a result is ready
1147 * @user_data: user data for the @callback
1149 * Adds @contact to @client.
1150 * The call is finished by e_book_client_add_contact_finish()
1151 * from the @callback.
1156 e_book_client_add_contact (EBookClient *client,
1157 /* const */ EContact *contact,
1158 GCancellable *cancellable,
1159 GAsyncReadyCallback callback,
1162 gchar *vcard, *gdbus_vcard = NULL;
1163 const gchar *strv[2];
1165 g_return_if_fail (contact != NULL);
1166 g_return_if_fail (E_IS_CONTACT (contact));
1168 vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
1169 strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
1172 g_return_if_fail (strv[0] != NULL);
1174 e_client_proxy_call_strv (
1176 strv, cancellable, callback, user_data,
1177 e_book_client_add_contact,
1178 e_gdbus_book_call_add_contacts,
1180 e_gdbus_book_call_add_contacts_finish,
1184 g_free (gdbus_vcard);
1188 * e_book_client_add_contact_finish:
1189 * @client: an #EBookClient
1190 * @result: a #GAsyncResult
1191 * @added_uid: (out): UID of a newly added contact; can be %NULL
1192 * @error: (out): a #GError to set an error, if any
1194 * Finishes previous call of e_book_client_add_contact() and
1195 * sets @added_uid to a UID of a newly added contact.
1196 * This string should be freed with g_free().
1198 * Note: This is not modifying original #EContact.
1200 * Returns: %TRUE if successful, %FALSE otherwise.
1205 e_book_client_add_contact_finish (EBookClient *client,
1206 GAsyncResult *result,
1211 gchar **out_uids = NULL;
1213 res = e_client_proxy_call_finish_strv (
1214 E_CLIENT (client), result, &out_uids, error,
1215 e_book_client_add_contact);
1217 if (res && out_uids && added_uid) {
1218 *added_uid = g_strdup (out_uids[0]);
1223 g_strfreev (out_uids);
1229 * e_book_client_add_contact_sync:
1230 * @client: an #EBookClient
1231 * @contact: an #EContact
1232 * @added_uid: (out): UID of a newly added contact; can be %NULL
1233 * @cancellable: a #GCancellable; can be %NULL
1234 * @error: (out): a #GError to set an error, if any
1236 * Adds @contact to @client and
1237 * sets @added_uid to a UID of a newly added contact.
1238 * This string should be freed with g_free().
1240 * Note: This is not modifying original @contact, thus if it's needed,
1241 * then use e_contact_set (contact, E_CONTACT_UID, new_uid).
1243 * Returns: %TRUE if successful, %FALSE otherwise.
1248 e_book_client_add_contact_sync (EBookClient *client,
1249 /* const */ EContact *contact,
1251 GCancellable *cancellable,
1255 gchar *vcard, *gdbus_vcard = NULL, **out_uids = NULL;
1256 const gchar *strv[2];
1258 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1260 if (client->priv->dbus_proxy == NULL) {
1261 set_proxy_gone_error (error);
1265 vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
1266 strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
1269 g_return_val_if_fail (strv[0] != NULL, FALSE);
1271 res = e_client_proxy_call_sync_strv__strv (
1272 E_CLIENT (client), strv, &out_uids, cancellable, error,
1273 e_gdbus_book_call_add_contacts_sync);
1275 if (res && out_uids && added_uid) {
1276 *added_uid = g_strdup (out_uids[0]);
1282 g_strfreev (out_uids);
1284 g_free (gdbus_vcard);
1290 * e_book_client_add_contacts:
1291 * @client: an #EBookClient
1292 * @contacts: (element-type EContact): a #GSList of #EContact objects to add
1293 * @cancellable: (allow-none): a #GCancellable; can be %NULL
1294 * @callback: callback to call when a result is ready
1295 * @user_data: user data for the @callback
1297 * Adds @contacts to @client.
1298 * The call is finished by e_book_client_add_contacts_finish()
1299 * from the @callback.
1304 e_book_client_add_contacts (EBookClient *client,
1305 /* const */ GSList *contacts,
1306 GCancellable *cancellable,
1307 GAsyncReadyCallback callback,
1312 g_return_if_fail (contacts != NULL);
1314 array = contact_slist_to_utf8_vcard_array (contacts);
1316 e_client_proxy_call_strv (
1318 (const gchar * const *) array,
1319 cancellable, callback, user_data,
1320 e_book_client_add_contacts,
1321 e_gdbus_book_call_add_contacts,
1323 e_gdbus_book_call_add_contacts_finish,
1330 * e_book_client_add_contacts_finish:
1331 * @client: an #EBookClient
1332 * @result: a #GAsyncResult
1333 * @added_uids: (out) (element-type utf8) (allow-none): UIDs of newly added
1334 * contacts; can be %NULL
1335 * @error: (out): a #GError to set an error, if any
1337 * Finishes previous call of e_book_client_add_contacts() and
1338 * sets @added_uids to the UIDs of newly added contacts if successful.
1339 * This #GSList should be freed with e_client_util_free_string_slist().
1341 * If any of the contacts cannot be inserted, all of the insertions will be
1342 * reverted and this method will return %FALSE.
1344 * Note: This is not modifying original #EContact objects.
1346 * Returns: %TRUE if successful, %FALSE otherwise.
1351 e_book_client_add_contacts_finish (EBookClient *client,
1352 GAsyncResult *result,
1353 GSList **added_uids,
1357 gchar **out_uids = NULL;
1359 res = e_client_proxy_call_finish_strv (
1360 E_CLIENT (client), result, &out_uids, error,
1361 e_book_client_add_contacts);
1363 if (res && out_uids && added_uids) {
1364 *added_uids = e_client_util_strv_to_slist ((const gchar * const*) out_uids);
1370 g_strfreev (out_uids);
1376 * e_book_client_add_contacts_sync:
1377 * @client: an #EBookClient
1378 * @contacts: (element-type EContact): a #GSList of #EContact objects to add
1379 * @added_uids: (out) (element-type utf8) (allow-none): UIDs of newly added
1380 * contacts; can be %NULL
1381 * @cancellable: a #GCancellable; can be %NULL
1382 * @error: (out): a #GError to set an error, if any
1384 * Adds @contacts to @client and
1385 * sets @added_uids to the UIDs of newly added contacts if successful.
1386 * This #GSList should be freed with e_client_util_free_string_slist().
1388 * If any of the contacts cannot be inserted, all of the insertions will be
1389 * reverted and this method will return %FALSE.
1391 * Note: This is not modifying original @contacts, thus if it's needed,
1392 * then use e_contact_set (contact, E_CONTACT_UID, new_uid).
1394 * Returns: %TRUE if successful, %FALSE otherwise.
1399 e_book_client_add_contacts_sync (EBookClient *client,
1400 /* const */ GSList *contacts,
1401 GSList **added_uids,
1402 GCancellable *cancellable,
1406 gchar **array, **out_uids = NULL;
1408 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1410 if (client->priv->dbus_proxy == NULL) {
1411 set_proxy_gone_error (error);
1415 array = contact_slist_to_utf8_vcard_array (contacts);
1417 res = e_client_proxy_call_sync_strv__strv (
1419 (const gchar * const *) array,
1420 &out_uids, cancellable, error,
1421 e_gdbus_book_call_add_contacts_sync);
1423 if (res && out_uids && added_uids) {
1424 *added_uids = e_client_util_strv_to_slist ((const gchar * const*) out_uids);
1430 g_strfreev (out_uids);
1437 * e_book_client_modify_contact:
1438 * @client: an #EBookClient
1439 * @contact: an #EContact
1440 * @cancellable: a #GCancellable; can be %NULL
1441 * @callback: callback to call when a result is ready
1442 * @user_data: user data for the @callback
1444 * Applies the changes made to @contact to the stored version in @client.
1445 * The call is finished by e_book_client_modify_contact_finish()
1446 * from the @callback.
1451 e_book_client_modify_contact (EBookClient *client,
1452 /* const */ EContact *contact,
1453 GCancellable *cancellable,
1454 GAsyncReadyCallback callback,
1457 gchar *vcard, *gdbus_vcard = NULL;
1458 const gchar *strv[2];
1460 g_return_if_fail (contact != NULL);
1461 g_return_if_fail (E_IS_CONTACT (contact));
1463 vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
1464 strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
1467 g_return_if_fail (strv[0] != NULL);
1469 e_client_proxy_call_strv (
1471 strv, cancellable, callback, user_data,
1472 e_book_client_modify_contact,
1473 e_gdbus_book_call_modify_contacts,
1474 e_gdbus_book_call_modify_contacts_finish,
1475 NULL, NULL, NULL, NULL);
1478 g_free (gdbus_vcard);
1482 * e_book_client_modify_contact_finish:
1483 * @client: an #EBookClient
1484 * @result: a #GAsyncResult
1485 * @error: (out): a #GError to set an error, if any
1487 * Finishes previous call of e_book_client_modify_contact().
1489 * Returns: %TRUE if successful, %FALSE otherwise.
1494 e_book_client_modify_contact_finish (EBookClient *client,
1495 GAsyncResult *result,
1498 return e_client_proxy_call_finish_void (
1499 E_CLIENT (client), result, error,
1500 e_book_client_modify_contact);
1504 * e_book_client_modify_contact_sync:
1505 * @client: an #EBookClient
1506 * @contact: an #EContact
1507 * @cancellable: a #GCancellable; can be %NULL
1508 * @error: (out): a #GError to set an error, if any
1510 * Applies the changes made to @contact to the stored version in @client.
1512 * Returns: %TRUE if successful, %FALSE otherwise.
1517 e_book_client_modify_contact_sync (EBookClient *client,
1518 /* const */ EContact *contact,
1519 GCancellable *cancellable,
1523 gchar *vcard, *gdbus_vcard = NULL;
1524 const gchar *strv[2];
1526 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1528 if (client->priv->dbus_proxy == NULL) {
1529 set_proxy_gone_error (error);
1533 vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
1534 strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
1537 g_return_val_if_fail (strv[0] != NULL, FALSE);
1539 res = e_client_proxy_call_sync_strv__void (
1541 strv, cancellable, error,
1542 e_gdbus_book_call_modify_contacts_sync);
1545 g_free (gdbus_vcard);
1551 * e_book_client_modify_contacts:
1552 * @client: an #EBookClient
1553 * @contacts: (element-type EContact): a #GSList of #EContact objects
1554 * @cancellable: (allow-none): a #GCancellable; can be %NULL
1555 * @callback: callback to call when a result is ready
1556 * @user_data: user data for the @callback
1558 * Applies the changes made to @contacts to the stored versions in @client.
1559 * The call is finished by e_book_client_modify_contacts_finish()
1560 * from the @callback.
1565 e_book_client_modify_contacts (EBookClient *client,
1566 /* const */ GSList *contacts,
1567 GCancellable *cancellable,
1568 GAsyncReadyCallback callback,
1573 g_return_if_fail (contacts != NULL);
1575 array = contact_slist_to_utf8_vcard_array (contacts);
1577 e_client_proxy_call_strv (
1579 (const gchar * const *) array,
1580 cancellable, callback, user_data,
1581 e_book_client_modify_contacts,
1582 e_gdbus_book_call_modify_contacts,
1583 e_gdbus_book_call_modify_contacts_finish,
1584 NULL, NULL, NULL, NULL);
1590 * e_book_client_modify_contacts_finish:
1591 * @client: an #EBookClient
1592 * @result: a #GAsyncResult
1593 * @error: (out): a #GError to set an error, if any
1595 * Finishes previous call of e_book_client_modify_contacts().
1597 * Returns: %TRUE if successful, %FALSE otherwise.
1602 e_book_client_modify_contacts_finish (EBookClient *client,
1603 GAsyncResult *result,
1606 return e_client_proxy_call_finish_void (
1607 E_CLIENT (client), result, error,
1608 e_book_client_modify_contacts);
1612 * e_book_client_modify_contacts_sync:
1613 * @client: an #EBookClient
1614 * @contacts: (element-type EContact): a #GSList of #EContact objects
1615 * @cancellable: (allow-none): a #GCancellable; can be %NULL
1616 * @error: (out): a #GError to set an error, if any
1618 * Applies the changes made to @contacts to the stored versions in @client.
1620 * Returns: %TRUE if successful, %FALSE otherwise.
1625 e_book_client_modify_contacts_sync (EBookClient *client,
1626 /* const */ GSList *contacts,
1627 GCancellable *cancellable,
1633 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1634 g_return_val_if_fail (contacts != NULL, FALSE);
1636 if (client->priv->dbus_proxy == NULL) {
1637 set_proxy_gone_error (error);
1641 array = contact_slist_to_utf8_vcard_array (contacts);
1643 res = e_client_proxy_call_sync_strv__void (
1645 (const gchar * const *) array,
1647 e_gdbus_book_call_modify_contacts_sync);
1655 * e_book_client_remove_contact:
1656 * @client: an #EBookClient
1657 * @contact: an #EContact
1658 * @cancellable: a #GCancellable; can be %NULL
1659 * @callback: callback to call when a result is ready
1660 * @user_data: user data for the @callback
1662 * Removes @contact from the @client.
1663 * The call is finished by e_book_client_remove_contact_finish()
1664 * from the @callback.
1669 e_book_client_remove_contact (EBookClient *client,
1670 /* const */ EContact *contact,
1671 GCancellable *cancellable,
1672 GAsyncReadyCallback callback,
1675 const gchar *uid, *safe_uid;
1676 const gchar *strv[2];
1677 gchar *gdbus_uid = NULL;
1679 g_return_if_fail (contact != NULL);
1680 g_return_if_fail (E_IS_CONTACT (contact));
1682 uid = e_contact_get_const ( E_CONTACT (contact), E_CONTACT_UID);
1683 g_return_if_fail (uid != NULL);
1685 safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
1686 g_return_if_fail (safe_uid != NULL);
1691 e_client_proxy_call_strv (
1693 strv, cancellable, callback, user_data,
1694 e_book_client_remove_contact,
1695 e_gdbus_book_call_remove_contacts,
1696 e_gdbus_book_call_remove_contacts_finish,
1697 NULL, NULL, NULL, NULL);
1703 * e_book_client_remove_contact_finish:
1704 * @client: an #EBookClient
1705 * @result: a #GAsyncResult
1706 * @error: (out): a #GError to set an error, if any
1708 * Finishes previous call of e_book_client_remove_contact().
1710 * Returns: %TRUE if successful, %FALSE otherwise.
1715 e_book_client_remove_contact_finish (EBookClient *client,
1716 GAsyncResult *result,
1719 return e_client_proxy_call_finish_void (
1720 E_CLIENT (client), result, error,
1721 e_book_client_remove_contact);
1725 * e_book_client_remove_contact_sync:
1726 * @client: an #EBookClient
1727 * @contact: an #EContact
1728 * @cancellable: a #GCancellable; can be %NULL
1729 * @error: (out): a #GError to set an error, if any
1731 * Removes @contact from the @client.
1733 * Returns: %TRUE if successful, %FALSE otherwise.
1738 e_book_client_remove_contact_sync (EBookClient *client,
1739 /* const */ EContact *contact,
1740 GCancellable *cancellable,
1744 const gchar *strv[2];
1745 const gchar *uid, *safe_uid;
1746 gchar *gdbus_uid = NULL;
1748 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1749 g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
1751 if (client->priv->dbus_proxy == NULL) {
1752 set_proxy_gone_error (error);
1756 uid = e_contact_get_const (E_CONTACT (contact), E_CONTACT_UID);
1757 g_return_val_if_fail (uid != NULL, FALSE);
1759 safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
1760 g_return_val_if_fail (safe_uid != NULL, FALSE);
1765 res = e_client_proxy_call_sync_strv__void (
1767 strv, cancellable, error,
1768 e_gdbus_book_call_remove_contacts_sync);
1776 * e_book_client_remove_contact_by_uid:
1777 * @client: an #EBookClient
1778 * @uid: a UID of a contact to remove
1779 * @cancellable: a #GCancellable; can be %NULL
1780 * @callback: callback to call when a result is ready
1781 * @user_data: user data for the @callback
1783 * Removes contact with @uid from the @client.
1784 * The call is finished by e_book_client_remove_contact_by_uid_finish()
1785 * from the @callback.
1790 e_book_client_remove_contact_by_uid (EBookClient *client,
1792 GCancellable *cancellable,
1793 GAsyncReadyCallback callback,
1796 const gchar *safe_uid;
1797 gchar *gdbus_uid = NULL;
1798 const gchar *strv[2];
1800 g_return_if_fail (uid != NULL);
1802 safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
1803 g_return_if_fail (safe_uid != NULL);
1808 e_client_proxy_call_strv (
1810 strv, cancellable, callback, user_data,
1811 e_book_client_remove_contact_by_uid,
1812 e_gdbus_book_call_remove_contacts,
1813 e_gdbus_book_call_remove_contacts_finish,
1814 NULL, NULL, NULL, NULL);
1820 * e_book_client_remove_contact_by_uid_finish:
1821 * @client: an #EBookClient
1822 * @result: a #GAsyncResult
1823 * @error: (out): a #GError to set an error, if any
1825 * Finishes previous call of e_book_client_remove_contact_by_uid().
1827 * Returns: %TRUE if successful, %FALSE otherwise.
1832 e_book_client_remove_contact_by_uid_finish (EBookClient *client,
1833 GAsyncResult *result,
1836 return e_client_proxy_call_finish_void (
1837 E_CLIENT (client), result, error,
1838 e_book_client_remove_contact_by_uid);
1842 * e_book_client_remove_contact_by_uid_sync:
1843 * @client: an #EBookClient
1844 * @uid: a UID of a contact to remove
1845 * @cancellable: a #GCancellable; can be %NULL
1846 * @error: (out): a #GError to set an error, if any
1848 * Removes contact with @uid from the @client.
1850 * Returns: %TRUE if successful, %FALSE otherwise.
1855 e_book_client_remove_contact_by_uid_sync (EBookClient *client,
1857 GCancellable *cancellable,
1861 const gchar *safe_uid;
1862 gchar *gdbus_uid = NULL;
1863 const gchar *strv[2];
1865 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1866 g_return_val_if_fail (uid != NULL, FALSE);
1868 if (client->priv->dbus_proxy == NULL) {
1869 set_proxy_gone_error (error);
1873 safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
1874 g_return_val_if_fail (safe_uid != NULL, FALSE);
1879 res = e_client_proxy_call_sync_strv__void (
1880 E_CLIENT (client), strv, cancellable, error,
1881 e_gdbus_book_call_remove_contacts_sync);
1889 * e_book_client_remove_contacts:
1890 * @client: an #EBookClient
1891 * @uids: (element-type utf8): a #GSList of UIDs to remove
1892 * @cancellable: a #GCancellable; can be %NULL
1893 * @callback: callback to call when a result is ready
1894 * @user_data: user data for the @callback
1896 * Removes the contacts with uids from the list @uids from @client. This is
1897 * always more efficient than calling e_book_client_remove_contact() if you
1898 * have more than one uid to remove, as some backends can implement it
1899 * as a batch request.
1900 * The call is finished by e_book_client_remove_contacts_finish()
1901 * from the @callback.
1906 e_book_client_remove_contacts (EBookClient *client,
1908 GCancellable *cancellable,
1909 GAsyncReadyCallback callback,
1914 g_return_if_fail (uids != NULL);
1916 strv = e_client_util_slist_to_strv (uids);
1917 g_return_if_fail (strv != NULL);
1919 e_client_proxy_call_strv (
1921 (const gchar * const *) strv,
1922 cancellable, callback, user_data,
1923 e_book_client_remove_contacts,
1924 e_gdbus_book_call_remove_contacts,
1925 e_gdbus_book_call_remove_contacts_finish,
1926 NULL, NULL, NULL, NULL);
1932 * e_book_client_remove_contacts_finish:
1933 * @client: an #EBookClient
1934 * @result: a #GAsyncResult
1935 * @error: (out): a #GError to set an error, if any
1937 * Finishes previous call of e_book_client_remove_contacts().
1939 * Returns: %TRUE if successful, %FALSE otherwise.
1944 e_book_client_remove_contacts_finish (EBookClient *client,
1945 GAsyncResult *result,
1948 return e_client_proxy_call_finish_void (
1949 E_CLIENT (client), result, error,
1950 e_book_client_remove_contacts);
1954 * e_book_client_remove_contacts_sync:
1955 * @client: an #EBookClient
1956 * @uids: (element-type utf8): a #GSList of UIDs to remove
1957 * @cancellable: a #GCancellable; can be %NULL
1958 * @error: (out): a #GError to set an error, if any
1960 * Removes the contacts with uids from the list @uids from @client. This is
1961 * always more efficient than calling e_book_client_remove_contact() if you
1962 * have more than one uid to remove, as some backends can implement it
1963 * as a batch request.
1965 * Returns: %TRUE if successful, %FALSE otherwise.
1970 e_book_client_remove_contacts_sync (EBookClient *client,
1972 GCancellable *cancellable,
1978 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
1979 g_return_val_if_fail (uids != NULL, FALSE);
1981 if (client->priv->dbus_proxy == NULL) {
1982 set_proxy_gone_error (error);
1986 strv = e_client_util_slist_to_strv (uids);
1987 g_return_val_if_fail (strv != NULL, FALSE);
1989 res = e_client_proxy_call_sync_strv__void (
1990 E_CLIENT (client), (const gchar * const *) strv,
1992 e_gdbus_book_call_remove_contacts_sync);
2000 * e_book_client_get_contact:
2001 * @client: an #EBookClient
2002 * @uid: a unique string ID specifying the contact
2003 * @cancellable: a #GCancellable; can be %NULL
2004 * @callback: callback to call when a result is ready
2005 * @user_data: user data for the @callback
2007 * Receive #EContact from the @client for the gived @uid.
2008 * The call is finished by e_book_client_get_contact_finish()
2009 * from the @callback.
2014 e_book_client_get_contact (EBookClient *client,
2016 GCancellable *cancellable,
2017 GAsyncReadyCallback callback,
2020 const gchar *safe_uid;
2021 gchar *gdbus_uid = NULL;
2023 g_return_if_fail (uid != NULL);
2025 safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
2026 g_return_if_fail (safe_uid != NULL);
2028 e_client_proxy_call_string (
2030 safe_uid, cancellable, callback, user_data,
2031 e_book_client_get_contact,
2032 e_gdbus_book_call_get_contact,
2034 e_gdbus_book_call_get_contact_finish,
2041 * e_book_client_get_contact_finish:
2042 * @client: an #EBookClient
2043 * @result: a #GAsyncResult
2044 * @contact: (out): an #EContact for previously given uid
2045 * @error: (out): a #GError to set an error, if any
2047 * Finishes previous call of e_book_client_get_contact().
2048 * If successful, then the @contact is set to newly allocated
2049 * #EContact, which should be freed with g_object_unref().
2051 * Returns: %TRUE if successful, %FALSE otherwise.
2056 e_book_client_get_contact_finish (EBookClient *client,
2057 GAsyncResult *result,
2062 gchar *vcard = NULL;
2064 g_return_val_if_fail (contact != NULL, FALSE);
2066 res = e_client_proxy_call_finish_string (
2068 result, &vcard, error,
2069 e_book_client_get_contact);
2072 *contact = e_contact_new_from_vcard (vcard);
2082 * e_book_client_get_contact_sync:
2083 * @client: an #EBookClient
2084 * @uid: a unique string ID specifying the contact
2085 * @contact: (out): an #EContact for given @uid
2086 * @cancellable: a #GCancellable; can be %NULL
2087 * @error: (out): a #GError to set an error, if any
2089 * Receive #EContact from the @client for the gived @uid.
2090 * If successful, then the @contact is set to newly allocated
2091 * #EContact, which should be freed with g_object_unref().
2093 * Returns: %TRUE if successful, %FALSE otherwise.
2098 e_book_client_get_contact_sync (EBookClient *client,
2101 GCancellable *cancellable,
2105 const gchar *safe_uid;
2106 gchar *vcard = NULL, *gdbus_uid = NULL;
2108 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
2109 g_return_val_if_fail (uid != NULL, FALSE);
2110 g_return_val_if_fail (contact != NULL, FALSE);
2112 if (client->priv->dbus_proxy == NULL) {
2113 set_proxy_gone_error (error);
2117 safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
2118 g_return_val_if_fail (safe_uid != NULL, FALSE);
2120 res = e_client_proxy_call_sync_string__string (
2122 safe_uid, &vcard, cancellable, error,
2123 e_gdbus_book_call_get_contact_sync);
2126 *contact = e_contact_new_from_vcard_with_uid (vcard, safe_uid);
2137 * e_book_client_get_contacts:
2138 * @client: an #EBookClient
2139 * @sexp: an S-expression representing the query
2140 * @cancellable: a #GCancellable; can be %NULL
2141 * @callback: callback to call when a result is ready
2142 * @user_data: user data for the @callback
2144 * Query @client with @sexp, receiving a list of contacts which
2145 * matched. The call is finished by e_book_client_get_contacts_finish()
2146 * from the @callback.
2148 * Note: @sexp can be obtained through #EBookQuery, by converting it
2149 * to a string with e_book_query_to_string().
2154 e_book_client_get_contacts (EBookClient *client,
2156 GCancellable *cancellable,
2157 GAsyncReadyCallback callback,
2160 gchar *gdbus_sexp = NULL;
2162 g_return_if_fail (sexp != NULL);
2164 e_client_proxy_call_string (
2166 e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
2167 cancellable, callback, user_data,
2168 e_book_client_get_contacts,
2169 e_gdbus_book_call_get_contact_list,
2171 e_gdbus_book_call_get_contact_list_finish,
2174 g_free (gdbus_sexp);
2178 * e_book_client_get_contacts_finish:
2179 * @client: an #EBookClient
2180 * @result: a #GAsyncResult
2181 * @contacts: (element-type EContact) (out): a #GSList of matched #EContact-s
2182 * @error: (out): a #GError to set an error, if any
2184 * Finishes previous call of e_book_client_get_contacts().
2185 * If successful, then the @contacts is set to newly allocated list of #EContact-s,
2186 * which should be freed with e_client_util_free_object_slist().
2188 * Returns: %TRUE if successful, %FALSE otherwise.
2193 e_book_client_get_contacts_finish (EBookClient *client,
2194 GAsyncResult *result,
2199 gchar **vcards = NULL;
2201 g_return_val_if_fail (contacts != NULL, FALSE);
2203 res = e_client_proxy_call_finish_strv (
2205 result, &vcards, error,
2206 e_book_client_get_contacts);
2208 if (vcards && res) {
2210 GSList *slist = NULL;
2212 for (ii = 0; vcards[ii]; ii++) {
2213 slist = g_slist_prepend (slist, e_contact_new_from_vcard (vcards[ii]));
2216 *contacts = g_slist_reverse (slist);
2221 g_strfreev (vcards);
2227 * e_book_client_get_contacts_sync:
2228 * @client: an #EBookClient
2229 * @sexp: an S-expression representing the query
2230 * @contacts: (element-type EContact) (out): a #GSList of matched #EContact-s
2231 * @cancellable: a #GCancellable; can be %NULL
2232 * @error: (out): a #GError to set an error, if any
2234 * Query @client with @sexp, receiving a list of contacts which matched.
2235 * If successful, then the @contacts is set to newly allocated #GSList of
2236 * #EContact-s, which should be freed with e_client_util_free_object_slist().
2238 * Note: @sexp can be obtained through #EBookQuery, by converting it
2239 * to a string with e_book_query_to_string().
2241 * Returns: %TRUE if successful, %FALSE otherwise.
2246 e_book_client_get_contacts_sync (EBookClient *client,
2249 GCancellable *cancellable,
2253 gchar *gdbus_sexp = NULL;
2254 gchar **vcards = NULL;
2256 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
2257 g_return_val_if_fail (sexp != NULL, FALSE);
2258 g_return_val_if_fail (contacts != NULL, FALSE);
2260 if (client->priv->dbus_proxy == NULL) {
2261 set_proxy_gone_error (error);
2265 res = e_client_proxy_call_sync_string__strv (
2267 e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
2268 &vcards, cancellable, error,
2269 e_gdbus_book_call_get_contact_list_sync);
2271 if (vcards && res) {
2273 GSList *slist = NULL;
2275 for (ii = 0; vcards[ii]; ii++) {
2276 slist = g_slist_prepend (slist, e_contact_new_from_vcard (vcards[ii]));
2279 *contacts = g_slist_reverse (slist);
2284 g_free (gdbus_sexp);
2285 g_strfreev (vcards);
2291 * e_book_client_get_contacts_uids:
2292 * @client: an #EBookClient
2293 * @sexp: an S-expression representing the query
2294 * @cancellable: a #GCancellable; can be %NULL
2295 * @callback: callback to call when a result is ready
2296 * @user_data: user data for the @callback
2298 * Query @client with @sexp, receiving a list of contacts UIDs which
2299 * matched. The call is finished by e_book_client_get_contacts_uids_finish()
2300 * from the @callback.
2302 * Note: @sexp can be obtained through #EBookQuery, by converting it
2303 * to a string with e_book_query_to_string().
2308 e_book_client_get_contacts_uids (EBookClient *client,
2310 GCancellable *cancellable,
2311 GAsyncReadyCallback callback,
2314 gchar *gdbus_sexp = NULL;
2316 g_return_if_fail (sexp != NULL);
2318 e_client_proxy_call_string (
2320 e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
2321 cancellable, callback, user_data,
2322 e_book_client_get_contacts_uids,
2323 e_gdbus_book_call_get_contact_list_uids,
2325 e_gdbus_book_call_get_contact_list_uids_finish,
2328 g_free (gdbus_sexp);
2332 * e_book_client_get_contacts_uids_finish:
2333 * @client: an #EBookClient
2334 * @result: a #GAsyncResult
2335 * @contacts_uids: (element-type utf8) (out): a #GSList of matched contacts UIDs stored as strings
2336 * @error: (out): a #GError to set an error, if any
2338 * Finishes previous call of e_book_client_get_contacts_uids().
2339 * If successful, then the @contacts_uids is set to newly allocated list
2340 * of UID strings, which should be freed with e_client_util_free_string_slist().
2342 * Returns: %TRUE if successful, %FALSE otherwise.
2347 e_book_client_get_contacts_uids_finish (EBookClient *client,
2348 GAsyncResult *result,
2349 GSList **contacts_uids,
2353 gchar **uids = NULL;
2355 g_return_val_if_fail (contacts_uids != NULL, FALSE);
2357 res = e_client_proxy_call_finish_strv (
2359 result, &uids, error,
2360 e_book_client_get_contacts_uids);
2364 GSList *slist = NULL;
2366 for (ii = 0; uids[ii]; ii++) {
2367 slist = g_slist_prepend (slist, g_strdup (uids[ii]));
2370 *contacts_uids = g_slist_reverse (slist);
2372 *contacts_uids = NULL;
2381 * e_book_client_get_contacts_uids_sync:
2382 * @client: an #EBookClient
2383 * @sexp: an S-expression representing the query
2384 * @contacts_uids: (element-type utf8) (out): a #GSList of matched contacts UIDs stored as strings
2385 * @cancellable: a #GCancellable; can be %NULL
2386 * @error: (out): a #GError to set an error, if any
2388 * Query @client with @sexp, receiving a list of contacts UIDs which matched.
2389 * If successful, then the @contacts_uids is set to newly allocated list
2390 * of UID strings, which should be freed with e_client_util_free_string_slist().
2392 * Note: @sexp can be obtained through #EBookQuery, by converting it
2393 * to a string with e_book_query_to_string().
2395 * Returns: %TRUE if successful, %FALSE otherwise.
2400 e_book_client_get_contacts_uids_sync (EBookClient *client,
2402 GSList **contacts_uids,
2403 GCancellable *cancellable,
2407 gchar *gdbus_sexp = NULL;
2408 gchar **uids = NULL;
2410 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
2411 g_return_val_if_fail (sexp != NULL, FALSE);
2412 g_return_val_if_fail (contacts_uids != NULL, FALSE);
2414 if (client->priv->dbus_proxy == NULL) {
2415 set_proxy_gone_error (error);
2419 res = e_client_proxy_call_sync_string__strv (
2421 e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
2422 &uids, cancellable, error,
2423 e_gdbus_book_call_get_contact_list_uids_sync);
2427 GSList *slist = NULL;
2429 for (ii = 0; uids[ii]; ii++) {
2430 slist = g_slist_prepend (slist, g_strdup (uids[ii]));
2433 *contacts_uids = g_slist_reverse (slist);
2435 *contacts_uids = NULL;
2438 g_free (gdbus_sexp);
2445 * e_book_client_get_view:
2446 * @client: an #EBookClient
2447 * @sexp: an S-expression representing the query
2448 * @cancellable: a #GCancellable; can be %NULL
2449 * @callback: callback to call when a result is ready
2450 * @user_data: user data for the @callback
2452 * Query @client with @sexp, creating an #EBookClientView.
2453 * The call is finished by e_book_client_get_view_finish()
2454 * from the @callback.
2456 * Note: @sexp can be obtained through #EBookQuery, by converting it
2457 * to a string with e_book_query_to_string().
2462 e_book_client_get_view (EBookClient *client,
2464 GCancellable *cancellable,
2465 GAsyncReadyCallback callback,
2468 gchar *gdbus_sexp = NULL;
2470 g_return_if_fail (sexp != NULL);
2472 e_client_proxy_call_string (
2474 e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
2475 cancellable, callback, user_data,
2476 e_book_client_get_view,
2477 e_gdbus_book_call_get_view,
2479 e_gdbus_book_call_get_view_finish, NULL, NULL);
2481 g_free (gdbus_sexp);
2485 complete_get_view (EBookClient *client,
2488 EBookClientView **view,
2491 g_return_val_if_fail (view != NULL, FALSE);
2493 if (view_path && res && book_factory) {
2494 GDBusConnection *connection;
2495 GError *local_error = NULL;
2497 connection = g_dbus_proxy_get_connection (
2498 G_DBUS_PROXY (book_factory));
2500 *view = g_initable_new (
2501 E_TYPE_BOOK_CLIENT_VIEW,
2504 "connection", connection,
2505 "object-path", view_path,
2508 if (local_error != NULL) {
2509 unwrap_dbus_error (local_error, error);
2517 if (!*view && error && !*error)
2518 g_set_error_literal (error, E_CLIENT_ERROR, E_CLIENT_ERROR_DBUS_ERROR, _("Cannot get connection to view"));
2526 * e_book_client_get_view_finish:
2527 * @client: an #EBookClient
2528 * @result: a #GAsyncResult
2529 * @view: (out): an #EBookClientView
2530 * @error: (out): a #GError to set an error, if any
2532 * Finishes previous call of e_book_client_get_view().
2533 * If successful, then the @view is set to newly allocated #EBookClientView,
2534 * which should be freed with g_object_unref().
2536 * Returns: %TRUE if successful, %FALSE otherwise.
2541 e_book_client_get_view_finish (EBookClient *client,
2542 GAsyncResult *result,
2543 EBookClientView **view,
2547 gchar *view_path = NULL;
2549 g_return_val_if_fail (view != NULL, FALSE);
2551 res = e_client_proxy_call_finish_string (
2553 result, &view_path, error,
2554 e_book_client_get_view);
2556 return complete_get_view (client, res, view_path, view, error);
2560 * e_book_client_get_view_sync:
2561 * @client: an #EBookClient
2562 * @sexp: an S-expression representing the query
2563 * @view: (out) an #EBookClientView
2564 * @cancellable: a #GCancellable; can be %NULL
2565 * @error: (out): a #GError to set an error, if any
2567 * Query @client with @sexp, creating an #EBookClientView.
2568 * If successful, then the @view is set to newly allocated #EBookClientView,
2569 * which should be freed with g_object_unref().
2571 * Note: @sexp can be obtained through #EBookQuery, by converting it
2572 * to a string with e_book_query_to_string().
2574 * Returns: %TRUE if successful, %FALSE otherwise.
2579 e_book_client_get_view_sync (EBookClient *client,
2581 EBookClientView **view,
2582 GCancellable *cancellable,
2586 gchar *gdbus_sexp = NULL;
2587 gchar *view_path = NULL;
2589 g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
2590 g_return_val_if_fail (sexp != NULL, FALSE);
2591 g_return_val_if_fail (view != NULL, FALSE);
2593 if (client->priv->dbus_proxy == NULL) {
2594 set_proxy_gone_error (error);
2598 res = e_client_proxy_call_sync_string__string (
2600 e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
2601 &view_path, cancellable, error,
2602 e_gdbus_book_call_get_view_sync);
2604 g_free (gdbus_sexp);
2606 return complete_get_view (client, res, view_path, view, error);