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/e-data-server-util.h>
31 #include "e-gdbus-marshallers.h"
34 #include "e-client-private.h"
36 #define E_CLIENT_GET_PRIVATE(obj) \
37 (G_TYPE_INSTANCE_GET_PRIVATE \
38 ((obj), E_TYPE_CLIENT, EClientPrivate))
40 struct _EClientPrivate {
41 GStaticRecMutex prop_mutex;
48 gboolean capabilities_retrieved;
51 GHashTable *backend_property_cache;
53 GStaticRecMutex ops_mutex;
55 GHashTable *ops; /* opid to GCancellable */
72 BACKEND_PROPERTY_CHANGED,
76 static guint signals[LAST_SIGNAL];
78 G_DEFINE_ABSTRACT_TYPE (EClient, e_client, G_TYPE_OBJECT)
81 * Well-known client backend properties, which are common for each #EClient:
82 * @CLIENT_BACKEND_PROPERTY_OPENED: Is set to "TRUE" or "FALSE" depending
83 * whether the backend is fully opened.
84 * @CLIENT_BACKEND_PROPERTY_OPENING: Is set to "TRUE" or "FALSE" depending
85 * whether the backend is processing its opening phase.
86 * @CLIENT_BACKEND_PROPERTY_ONLINE: Is set to "TRUE" or "FALSE" depending
87 * on the backend's loaded state. See also e_client_is_online().
88 * @CLIENT_BACKEND_PROPERTY_READONLY: Is set to "TRUE" or "FALSE" depending
89 * on the backend's readonly state. See also e_client_is_readonly().
90 * @CLIENT_BACKEND_PROPERTY_CACHE_DIR: Local folder with cached data used
92 * @CLIENT_BACKEND_PROPERTY_CAPABILITIES: Retrieves comma-separated list
93 * of capabilities supported by the backend. Preferred method of retreiving
94 * and working with capabilities is e_client_get_capabilities() and
95 * e_client_check_capability().
99 e_client_error_quark (void)
104 q = g_quark_from_static_string ("e-client-error-quark");
110 * e_client_error_to_string:
112 * FIXME: Document me.
117 e_client_error_to_string (EClientError code)
120 case E_CLIENT_ERROR_INVALID_ARG:
121 return _("Invalid argument");
122 case E_CLIENT_ERROR_BUSY:
123 return _("Backend is busy");
124 case E_CLIENT_ERROR_SOURCE_NOT_LOADED:
125 return _("Source not loaded");
126 case E_CLIENT_ERROR_SOURCE_ALREADY_LOADED:
127 return _("Source already loaded");
128 case E_CLIENT_ERROR_AUTHENTICATION_FAILED:
129 return _("Authentication failed");
130 case E_CLIENT_ERROR_AUTHENTICATION_REQUIRED:
131 return _("Authentication required");
132 case E_CLIENT_ERROR_REPOSITORY_OFFLINE:
133 return _("Repository offline");
134 case E_CLIENT_ERROR_OFFLINE_UNAVAILABLE:
135 /* Translators: This means that the EClient does not support offline mode, or
136 * it's not set to by a user, thus it is unavailable while user is not connected. */
137 return _("Offline unavailable");
138 case E_CLIENT_ERROR_PERMISSION_DENIED:
139 return _("Permission denied");
140 case E_CLIENT_ERROR_CANCELLED:
141 return _("Cancelled");
142 case E_CLIENT_ERROR_COULD_NOT_CANCEL:
143 return _("Could not cancel");
144 case E_CLIENT_ERROR_NOT_SUPPORTED:
145 return _("Not supported");
146 case E_CLIENT_ERROR_UNSUPPORTED_AUTHENTICATION_METHOD:
147 return _("Unsupported authentication method");
148 case E_CLIENT_ERROR_TLS_NOT_AVAILABLE:
149 return _("TLS not available");
150 case E_CLIENT_ERROR_SEARCH_SIZE_LIMIT_EXCEEDED:
151 return _("Search size limit exceeded");
152 case E_CLIENT_ERROR_SEARCH_TIME_LIMIT_EXCEEDED:
153 return _("Search time limit exceeded");
154 case E_CLIENT_ERROR_INVALID_QUERY:
155 return _("Invalid query");
156 case E_CLIENT_ERROR_QUERY_REFUSED:
157 return _("Query refused");
158 case E_CLIENT_ERROR_DBUS_ERROR:
159 return _("D-Bus error");
160 case E_CLIENT_ERROR_OTHER_ERROR:
161 return _("Other error");
162 case E_CLIENT_ERROR_NOT_OPENED:
163 return _("Backend is not opened yet");
166 return _("Unknown error");
170 * e_client_error_create:
171 * @code: an #EClientError code to create
172 * @custom_msg: custom message to use for the error; can be %NULL
174 * Returns: a new #GError containing an E_CLIENT_ERROR of the given
175 * @code. If the @custom_msg is NULL, then the error message is
176 * the one returned from e_client_error_to_string() for the @code,
177 * otherwise the given message is used.
179 * Returned pointer should be freed with g_error_free().
184 e_client_error_create (EClientError code,
185 const gchar *custom_msg)
187 return g_error_new_literal (E_CLIENT_ERROR, code, custom_msg ? custom_msg : e_client_error_to_string (code));
190 static void client_set_source (EClient *client, ESource *source);
191 static void client_handle_authentication (EClient *client, const ECredentials *credentials);
194 e_client_init (EClient *client)
196 client->priv = E_CLIENT_GET_PRIVATE (client);
198 client->priv->readonly = TRUE;
200 g_static_rec_mutex_init (&client->priv->prop_mutex);
201 client->priv->backend_property_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
203 g_static_rec_mutex_init (&client->priv->ops_mutex);
204 client->priv->last_opid = 0;
205 client->priv->ops = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
209 client_dispose (GObject *object)
213 client = E_CLIENT (object);
215 e_client_cancel_all (client);
217 /* Chain up to parent's dispose() method. */
218 G_OBJECT_CLASS (e_client_parent_class)->dispose (object);
222 client_finalize (GObject *object)
225 EClientPrivate *priv;
227 client = E_CLIENT (object);
231 g_static_rec_mutex_lock (&priv->prop_mutex);
234 g_object_unref (priv->source);
243 if (priv->capabilities) {
244 g_slist_foreach (priv->capabilities, (GFunc) g_free, NULL);
245 g_slist_free (priv->capabilities);
246 priv->capabilities = NULL;
249 if (priv->backend_property_cache) {
250 g_hash_table_destroy (priv->backend_property_cache);
251 priv->backend_property_cache = NULL;
255 g_hash_table_destroy (priv->ops);
259 g_static_rec_mutex_unlock (&priv->prop_mutex);
260 g_static_rec_mutex_free (&priv->prop_mutex);
261 g_static_rec_mutex_free (&priv->ops_mutex);
263 /* Chain up to parent's finalize() method. */
264 G_OBJECT_CLASS (e_client_parent_class)->finalize (object);
268 client_set_property (GObject *object,
273 switch (property_id) {
275 client_set_source (E_CLIENT (object), g_value_get_object (value));
279 e_client_set_online (E_CLIENT (object), g_value_get_boolean (value));
283 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
287 client_get_property (GObject *object,
292 switch (property_id) {
294 g_value_set_object (value, e_client_get_source (E_CLIENT (object)));
297 case PROP_CAPABILITIES:
298 g_value_set_pointer (value, (gpointer) e_client_get_capabilities (E_CLIENT (object)));
302 g_value_set_boolean (value, e_client_is_readonly (E_CLIENT (object)));
306 g_value_set_boolean (value, e_client_is_online (E_CLIENT (object)));
310 g_value_set_boolean (value, e_client_is_opened (E_CLIENT (object)));
314 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
318 e_client_class_init (EClientClass *class)
320 GObjectClass *object_class;
322 g_type_class_add_private (class, sizeof (EClientPrivate));
324 object_class = G_OBJECT_CLASS (class);
325 object_class->set_property = client_set_property;
326 object_class->get_property = client_get_property;
327 object_class->dispose = client_dispose;
328 object_class->finalize = client_finalize;
330 g_object_class_install_property (
333 g_param_spec_object (
338 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
340 g_object_class_install_property (
343 g_param_spec_pointer (
349 g_object_class_install_property (
352 g_param_spec_boolean (
359 g_object_class_install_property (
362 g_param_spec_boolean (
369 g_object_class_install_property (
372 g_param_spec_boolean (
379 signals[AUTHENTICATE] = g_signal_new (
381 G_OBJECT_CLASS_TYPE (class),
383 G_STRUCT_OFFSET (EClientClass, authenticate),
385 e_gdbus_marshallers_BOOLEAN__POINTER,
389 signals[OPENED] = g_signal_new (
391 G_OBJECT_CLASS_TYPE (class),
393 G_STRUCT_OFFSET (EClientClass, opened),
395 g_cclosure_marshal_VOID__BOXED,
399 signals[BACKEND_ERROR] = g_signal_new (
401 G_OBJECT_CLASS_TYPE (class),
403 G_STRUCT_OFFSET (EClientClass, backend_error),
405 g_cclosure_marshal_VOID__STRING,
409 signals[BACKEND_DIED] = g_signal_new (
411 G_OBJECT_CLASS_TYPE (class),
413 G_STRUCT_OFFSET (EClientClass, backend_died),
415 g_cclosure_marshal_VOID__VOID,
418 signals[BACKEND_PROPERTY_CHANGED] = g_signal_new (
419 "backend-property-changed",
420 G_OBJECT_CLASS_TYPE (class),
422 G_STRUCT_OFFSET (EClientClass, backend_property_changed),
424 e_gdbus_marshallers_VOID__STRING_STRING,
425 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
429 client_set_source (EClient *client,
432 g_return_if_fail (E_IS_CLIENT (client));
433 g_return_if_fail (E_IS_SOURCE (source));
435 g_object_ref (source);
437 if (client->priv->source)
438 g_object_unref (client->priv->source);
440 client->priv->source = source;
444 * e_client_get_source:
445 * @client: an #EClient
447 * Get the #ESource that this client has assigned.
449 * Returns: (transfer none): The source.
454 e_client_get_source (EClient *client)
456 g_return_val_if_fail (E_IS_CLIENT (client), NULL);
458 return client->priv->source;
463 * @client: an #EClient
465 * Get the URI that this client has assigned. This string should not be freed.
472 e_client_get_uri (EClient *client)
474 g_return_val_if_fail (E_IS_CLIENT (client), NULL);
476 if (!client->priv->uri)
477 client->priv->uri = e_source_get_uri (e_client_get_source (client));
479 return client->priv->uri;
483 client_ensure_capabilities (EClient *client)
487 g_return_if_fail (E_IS_CLIENT (client));
489 if (client->priv->capabilities_retrieved || client->priv->capabilities)
492 g_static_rec_mutex_lock (&client->priv->prop_mutex);
495 e_client_retrieve_capabilities_sync (client, &capabilities, NULL, NULL);
496 /* e_client_set_capabilities is called inside the previous function */
497 g_free (capabilities);
499 client->priv->capabilities_retrieved = TRUE;
501 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
505 * e_client_get_capabilities:
506 * @client: an #EClient
508 * Get list of strings with capabilities advertised by a backend.
509 * This list, together with inner strings, is owned by the @client.
510 * To check for individual capabilities use e_client_check_capability().
512 * Returns: (element-type utf8) (transfer none): #GSList of const strings
518 e_client_get_capabilities (EClient *client)
520 g_return_val_if_fail (E_IS_CLIENT (client), NULL);
522 client_ensure_capabilities (client);
524 return client->priv->capabilities;
528 * e_client_check_capability:
529 * @client: an #EClient
530 * @capability: a capability
532 * Check if backend supports particular capability.
533 * To get all capabilities use e_client_get_capabilities().
535 * Returns: #GSList of const strings of capabilities
540 e_client_check_capability (EClient *client,
541 const gchar *capability)
545 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
546 g_return_val_if_fail (capability, FALSE);
548 g_static_rec_mutex_lock (&client->priv->prop_mutex);
550 client_ensure_capabilities (client);
552 for (iter = client->priv->capabilities; iter; iter = g_slist_next (iter)) {
553 const gchar *cap = iter->data;
555 if (cap && g_ascii_strcasecmp (cap, capability) == 0) {
556 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
561 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
567 * e_client_check_refresh_supported:
570 * Checks whether a client supports explicit refreshing
571 * (see e_client_refresh()).
573 * Returns: TRUE if the client supports refreshing, FALSE otherwise.
578 e_client_check_refresh_supported (EClient *client)
580 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
582 return e_client_check_capability (client, "refresh-supported");
585 /* capabilities - comma-separated list of capabilities; can be NULL to unset */
587 e_client_set_capabilities (EClient *client,
588 const gchar *capabilities)
590 g_return_if_fail (E_IS_CLIENT (client));
592 g_static_rec_mutex_lock (&client->priv->prop_mutex);
595 client->priv->capabilities_retrieved = FALSE;
597 g_slist_foreach (client->priv->capabilities, (GFunc) g_free, NULL);
598 g_slist_free (client->priv->capabilities);
599 client->priv->capabilities = e_client_util_parse_comma_strings (capabilities);
601 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
603 g_object_notify (G_OBJECT (client), "capabilities");
607 * e_client_is_readonly:
608 * @client: an #EClient
610 * Check if this @client is read-only.
612 * Returns: %TRUE if this @client is read-only, otherwise %FALSE.
617 e_client_is_readonly (EClient *client)
619 g_return_val_if_fail (E_IS_CLIENT (client), TRUE);
621 return client->priv->readonly;
625 e_client_set_readonly (EClient *client,
628 g_return_if_fail (E_IS_CLIENT (client));
630 g_static_rec_mutex_lock (&client->priv->prop_mutex);
631 if ((readonly ? 1 : 0) == (client->priv->readonly ? 1 : 0)) {
632 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
636 client->priv->readonly = readonly;
638 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
640 g_object_notify (G_OBJECT (client), "readonly");
644 * e_client_is_online:
645 * @client: an #EClient
647 * Check if this @client is connected.
649 * Returns: %TRUE if this @client is connected, otherwise %FALSE.
654 e_client_is_online (EClient *client)
656 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
658 return client->priv->online;
662 e_client_set_online (EClient *client,
665 g_return_if_fail (E_IS_CLIENT (client));
667 /* newly connected/disconnected => make sure capabilities will be correct */
668 e_client_set_capabilities (client, NULL);
670 g_static_rec_mutex_lock (&client->priv->prop_mutex);
671 if ((is_online ? 1: 0) == (client->priv->online ? 1 : 0)) {
672 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
676 client->priv->online = is_online;
678 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
680 g_object_notify (G_OBJECT (client), "online");
684 * e_client_is_opened:
685 * @client: an #EClient
687 * Check if this @client is fully opened. This includes
688 * everything from e_client_open() call up to the authentication,
689 * if required by a backend. Client cannot do any other operation
690 * during the opening phase except of authenticate or cancel it.
691 * Every other operation results in an %E_CLIENT_ERROR_BUSY error.
693 * Returns: %TRUE if this @client is fully opened, otherwise %FALSE.
698 e_client_is_opened (EClient *client)
700 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
702 return client->priv->opened;
707 * @client: an #EClient
708 * @opid: asynchronous operation ID
710 * Cancels particular asynchronous operation. The @opid is returned from
711 * an e_client_register_op(). The function does nothing if the asynchronous
712 * operation doesn't exist any more.
717 client_cancel_op (EClient *client,
720 GCancellable *cancellable;
722 g_return_if_fail (E_IS_CLIENT (client));
723 g_return_if_fail (client->priv->ops != NULL);
725 g_static_rec_mutex_lock (&client->priv->ops_mutex);
727 cancellable = g_hash_table_lookup (client->priv->ops, GINT_TO_POINTER (opid));
729 g_cancellable_cancel (cancellable);
731 g_static_rec_mutex_unlock (&client->priv->ops_mutex);
735 gather_opids_cb (gpointer opid,
736 gpointer cancellable,
739 GSList **ids = ids_list;
741 g_return_if_fail (ids_list != NULL);
743 *ids = g_slist_prepend (*ids, opid);
747 cancel_op_cb (gpointer opid,
750 client_cancel_op (client, GPOINTER_TO_INT (opid));
754 * e_client_cancel_all:
755 * @client: an #EClient
757 * Cancels all pending operations started on @client.
762 e_client_cancel_all (EClient *client)
764 GSList *opids = NULL;
766 g_return_if_fail (E_IS_CLIENT (client));
767 g_return_if_fail (client->priv->ops != NULL);
769 g_static_rec_mutex_lock (&client->priv->ops_mutex);
771 g_hash_table_foreach (client->priv->ops, gather_opids_cb, &opids);
773 g_slist_foreach (opids, cancel_op_cb, client);
774 g_slist_free (opids);
776 g_static_rec_mutex_unlock (&client->priv->ops_mutex);
780 e_client_register_op (EClient *client,
781 GCancellable *cancellable)
785 g_return_val_if_fail (E_IS_CLIENT (client), 0);
786 g_return_val_if_fail (client->priv->ops != NULL, 0);
787 g_return_val_if_fail (cancellable != NULL, 0);
789 g_static_rec_mutex_lock (&client->priv->ops_mutex);
791 client->priv->last_opid++;
792 if (!client->priv->last_opid)
793 client->priv->last_opid++;
795 while (g_hash_table_lookup (client->priv->ops, GINT_TO_POINTER (client->priv->last_opid)))
796 client->priv->last_opid++;
798 g_return_val_if_fail (client->priv->last_opid != 0, 0);
800 opid = client->priv->last_opid;
801 g_hash_table_insert (client->priv->ops, GINT_TO_POINTER (opid), g_object_ref (cancellable));
803 g_static_rec_mutex_unlock (&client->priv->ops_mutex);
809 e_client_unregister_op (EClient *client,
812 g_return_if_fail (E_IS_CLIENT (client));
813 g_return_if_fail (client->priv->ops != NULL);
815 g_static_rec_mutex_lock (&client->priv->ops_mutex);
816 g_hash_table_remove (client->priv->ops, GINT_TO_POINTER (opid));
817 g_static_rec_mutex_unlock (&client->priv->ops_mutex);
821 client_handle_authentication (EClient *client,
822 const ECredentials *credentials)
826 g_return_if_fail (E_IS_CLIENT (client));
827 g_return_if_fail (credentials != NULL);
829 class = E_CLIENT_GET_CLASS (client);
830 g_return_if_fail (class != NULL);
831 g_return_if_fail (class->handle_authentication != NULL);
833 return class->handle_authentication (client, credentials);
836 struct EClientAuthData {
838 ECredentials *credentials;
842 client_process_authentication_idle_cb (gpointer user_data)
844 static gboolean processing_one = FALSE;
845 struct EClientAuthData *auth_data = user_data;
847 g_return_val_if_fail (auth_data != NULL, FALSE);
849 /* there is one currently processing, postpone this request for later */
853 /* no need for locking, this is always main-thread's idle */
854 processing_one = TRUE;
856 if (e_client_emit_authenticate (auth_data->client, auth_data->credentials)) {
857 client_handle_authentication (auth_data->client, auth_data->credentials);
859 /* Always pass credentials to backend to finish opening phase.
860 * Empty username indicates that either user cancelled password prompt
861 * or there was no authentication callback set.
863 e_credentials_set (auth_data->credentials, E_CREDENTIALS_KEY_USERNAME, NULL);
864 client_handle_authentication (auth_data->client, auth_data->credentials);
866 if (g_strcmp0 (e_credentials_peek (auth_data->credentials, E_CREDENTIALS_KEY_FOREIGN_REQUEST), "1") != 0) {
869 error = e_client_error_create (E_CLIENT_ERROR_AUTHENTICATION_REQUIRED, NULL);
870 e_client_emit_opened (auth_data->client, error);
871 g_error_free (error);
875 e_credentials_free (auth_data->credentials);
876 g_object_unref (auth_data->client);
879 processing_one = FALSE;
884 /* Processes authentication request in idle callback. Usual steps are:
885 * a) backend sends an auth - required signal
886 * b) EClient implementation calls this function
887 * c) a new idle callback is run which emits authenticate signal by e_client_emit_authenticate ()
888 * d) if anyone responds (returns true), the EClient::handle_authentication
889 * is called from the same idle callback with new credentials
890 * e) EClient implementation passes results to backend in the EClient::handle_authentication
893 e_client_process_authentication (EClient *client,
894 const ECredentials *credentials)
896 struct EClientAuthData *auth_data;
898 g_return_if_fail (E_IS_CLIENT (client));
900 auth_data = g_new0 (struct EClientAuthData, 1);
901 auth_data->client = g_object_ref (client);
902 auth_data->credentials = credentials ? e_credentials_new_clone (credentials) : e_credentials_new ();
904 g_idle_add (client_process_authentication_idle_cb, auth_data);
908 e_client_emit_authenticate (EClient *client,
909 ECredentials *credentials)
911 gboolean handled = FALSE;
913 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
914 g_return_val_if_fail (credentials != NULL, FALSE);
916 g_signal_emit (client, signals[AUTHENTICATE], 0, credentials, &handled);
922 e_client_emit_opened (EClient *client,
923 const GError *dbus_error)
925 GError *local_error = NULL;
927 g_return_if_fail (E_IS_CLIENT (client));
929 client->priv->opened = dbus_error == NULL;
932 local_error = g_error_copy (dbus_error);
933 e_client_unwrap_dbus_error (client, local_error, &local_error);
936 g_object_notify (G_OBJECT (client), "opened");
937 g_signal_emit (client, signals[OPENED], 0, local_error);
940 g_error_free (local_error);
944 e_client_emit_backend_error (EClient *client,
945 const gchar *error_msg)
947 g_return_if_fail (E_IS_CLIENT (client));
948 g_return_if_fail (error_msg != NULL);
950 g_signal_emit (client, signals[BACKEND_ERROR], 0, error_msg);
954 e_client_emit_backend_died (EClient *client)
956 g_return_if_fail (E_IS_CLIENT (client));
958 g_signal_emit (client, signals[BACKEND_DIED], 0);
962 e_client_emit_backend_property_changed (EClient *client,
963 const gchar *prop_name,
964 const gchar *prop_value)
966 g_return_if_fail (E_IS_CLIENT (client));
967 g_return_if_fail (prop_name != NULL);
968 g_return_if_fail (*prop_name);
969 g_return_if_fail (prop_value != NULL);
971 e_client_update_backend_property_cache (client, prop_name, prop_value);
973 g_signal_emit (client, signals[BACKEND_PROPERTY_CHANGED], 0, prop_name, prop_value);
977 e_client_update_backend_property_cache (EClient *client,
978 const gchar *prop_name,
979 const gchar *prop_value)
981 g_return_if_fail (E_IS_CLIENT (client));
982 g_return_if_fail (prop_name != NULL);
983 g_return_if_fail (*prop_name);
984 g_return_if_fail (prop_value != NULL);
986 g_static_rec_mutex_lock (&client->priv->prop_mutex);
988 if (client->priv->backend_property_cache)
989 g_hash_table_insert (client->priv->backend_property_cache, g_strdup (prop_name), g_strdup (prop_value));
991 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
995 e_client_get_backend_property_from_cache (EClient *client,
996 const gchar *prop_name)
998 gchar *prop_value = NULL;
1000 g_return_val_if_fail (E_IS_CLIENT (client), NULL);
1001 g_return_val_if_fail (prop_name != NULL, NULL);
1002 g_return_val_if_fail (*prop_name, NULL);
1004 g_static_rec_mutex_lock (&client->priv->prop_mutex);
1006 if (client->priv->backend_property_cache)
1007 prop_value = g_strdup (g_hash_table_lookup (client->priv->backend_property_cache, prop_name));
1009 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
1015 * e_client_retrieve_capabilities:
1016 * @client: an #EClient
1017 * @cancellable: a #GCancellable; can be %NULL
1018 * @callback: callback to call when a result is ready
1019 * @user_data: user data for the @callback
1021 * Initiates retrieval of capabilities on the @client. This is usually
1022 * required only once, after the @client is opened. The returned value
1023 * is cached and any subsequent call of e_client_get_capabilities() and
1024 * e_client_check_capability() is using the cached value.
1025 * The call is finished by e_client_retrieve_capabilities_finish()
1026 * from the @callback.
1031 e_client_retrieve_capabilities (EClient *client,
1032 GCancellable *cancellable,
1033 GAsyncReadyCallback callback,
1036 EClientClass *class;
1038 g_return_if_fail (E_IS_CLIENT (client));
1039 g_return_if_fail (callback != NULL);
1041 class = E_CLIENT_GET_CLASS (client);
1042 g_return_if_fail (class != NULL);
1043 g_return_if_fail (class->retrieve_capabilities != NULL);
1045 class->retrieve_capabilities (client, cancellable, callback, user_data);
1049 * e_client_retrieve_capabilities_finish:
1050 * @client: an #EClient
1051 * @result: a #GAsyncResult
1052 * @capabilities: (out): Comma-separated list of capabilities of the @client
1053 * @error: (out): a #GError to set an error, if any
1055 * Finishes previous call of e_client_retrieve_capabilities().
1056 * Returned value of @capabilities should be freed with g_free(),
1057 * when no longer needed.
1059 * Returns: %TRUE if successful, %FALSE otherwise.
1064 e_client_retrieve_capabilities_finish (EClient *client,
1065 GAsyncResult *result,
1066 gchar **capabilities,
1069 EClientClass *class;
1072 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1073 g_return_val_if_fail (capabilities != NULL, FALSE);
1075 class = E_CLIENT_GET_CLASS (client);
1076 g_return_val_if_fail (class != NULL, FALSE);
1077 g_return_val_if_fail (class->retrieve_capabilities_finish != NULL, FALSE);
1079 *capabilities = NULL;
1080 res = class->retrieve_capabilities_finish (client, result, capabilities, error);
1082 e_client_set_capabilities (client, res ? *capabilities : NULL);
1088 * e_client_retrieve_capabilities_sync:
1089 * @client: an #EClient
1090 * @capabilities: (out): Comma-separated list of capabilities of the @client
1091 * @cancellable: a #GCancellable; can be %NULL
1092 * @error: (out): a #GError to set an error, if any
1094 * Initiates retrieval of capabilities on the @client. This is usually
1095 * required only once, after the @client is opened. The returned value
1096 * is cached and any subsequent call of e_client_get_capabilities() and
1097 * e_client_check_capability() is using the cached value. Returned value
1098 * of @capabilities should be freed with g_free(), when no longer needed.
1100 * Returns: %TRUE if successful, %FALSE otherwise.
1105 e_client_retrieve_capabilities_sync (EClient *client,
1106 gchar **capabilities,
1107 GCancellable *cancellable,
1110 EClientClass *class;
1111 gboolean res = FALSE;
1113 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1114 g_return_val_if_fail (capabilities != NULL, FALSE);
1116 class = E_CLIENT_GET_CLASS (client);
1117 g_return_val_if_fail (class != NULL, FALSE);
1118 g_return_val_if_fail (class->retrieve_capabilities_sync != NULL, FALSE);
1120 *capabilities = NULL;
1121 res = class->retrieve_capabilities_sync (client, capabilities, cancellable, error);
1123 e_client_set_capabilities (client, res ? *capabilities : NULL);
1129 * e_client_get_backend_property:
1130 * @client: an #EClient
1131 * @prop_name: property name, whose value to retrieve; cannot be %NULL
1132 * @cancellable: a #GCancellable; can be %NULL
1133 * @callback: callback to call when a result is ready
1134 * @user_data: user data for the @callback
1136 * Queries @client's backend for a property of name @prop_name.
1137 * The call is finished by e_client_get_backend_property_finish()
1138 * from the @callback.
1143 e_client_get_backend_property (EClient *client,
1144 const gchar *prop_name,
1145 GCancellable *cancellable,
1146 GAsyncReadyCallback callback,
1149 EClientClass *class;
1151 g_return_if_fail (callback != NULL);
1152 g_return_if_fail (E_IS_CLIENT (client));
1153 g_return_if_fail (prop_name != NULL);
1155 class = E_CLIENT_GET_CLASS (client);
1156 g_return_if_fail (class != NULL);
1157 g_return_if_fail (class->get_backend_property != NULL);
1159 class->get_backend_property (client, prop_name, cancellable, callback, user_data);
1163 * e_client_get_backend_property_finish:
1164 * @client: an #EClient
1165 * @result: a #GAsyncResult
1166 * @prop_value: (out): Retrieved backend property value; cannot be %NULL
1167 * @error: (out): a #GError to set an error, if any
1169 * Finishes previous call of e_client_get_backend_property().
1171 * Returns: %TRUE if successful, %FALSE otherwise.
1176 e_client_get_backend_property_finish (EClient *client,
1177 GAsyncResult *result,
1181 EClientClass *class;
1183 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1184 g_return_val_if_fail (prop_value != NULL, FALSE);
1186 class = E_CLIENT_GET_CLASS (client);
1187 g_return_val_if_fail (class != NULL, FALSE);
1188 g_return_val_if_fail (class->get_backend_property_finish != NULL, FALSE);
1190 return class->get_backend_property_finish (client, result, prop_value, error);
1194 * e_client_get_backend_property_sync:
1195 * @client: an #EClient
1196 * @prop_name: property name, whose value to retrieve; cannot be %NULL
1197 * @prop_value: (out): Retrieved backend property value; cannot be %NULL
1198 * @cancellable: a #GCancellable; can be %NULL
1199 * @error: (out): a #GError to set an error, if any
1201 * Queries @client's backend for a property of name @prop_name.
1203 * Returns: %TRUE if successful, %FALSE otherwise.
1208 e_client_get_backend_property_sync (EClient *client,
1209 const gchar *prop_name,
1211 GCancellable *cancellable,
1214 EClientClass *class;
1216 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1217 g_return_val_if_fail (prop_name != NULL, FALSE);
1218 g_return_val_if_fail (prop_value != NULL, FALSE);
1220 class = E_CLIENT_GET_CLASS (client);
1221 g_return_val_if_fail (class != NULL, FALSE);
1222 g_return_val_if_fail (class->get_backend_property_sync != NULL, FALSE);
1224 return class->get_backend_property_sync (client, prop_name, prop_value, cancellable, error);
1228 * e_client_set_backend_property:
1229 * @client: an #EClient
1230 * @prop_name: property name, whose value to change; cannot be %NULL
1231 * @prop_value: property value, to set; cannot be %NULL
1232 * @cancellable: a #GCancellable; can be %NULL
1233 * @callback: callback to call when a result is ready
1234 * @user_data: user data for the @callback
1236 * Sets @client's backend property of name @prop_name
1237 * to value @prop_value. The call is finished
1238 * by e_client_set_backend_property_finish() from the @callback.
1243 e_client_set_backend_property (EClient *client,
1244 const gchar *prop_name,
1245 const gchar *prop_value,
1246 GCancellable *cancellable,
1247 GAsyncReadyCallback callback,
1250 EClientClass *class;
1252 g_return_if_fail (callback != NULL);
1253 g_return_if_fail (E_IS_CLIENT (client));
1254 g_return_if_fail (prop_name != NULL);
1255 g_return_if_fail (prop_value != NULL);
1257 class = E_CLIENT_GET_CLASS (client);
1258 g_return_if_fail (class != NULL);
1259 g_return_if_fail (class->set_backend_property != NULL);
1261 class->set_backend_property (client, prop_name, prop_value, cancellable, callback, user_data);
1265 * e_client_set_backend_property_finish:
1266 * @client: an #EClient
1267 * @result: a #GAsyncResult
1268 * @error: (out): a #GError to set an error, if any
1270 * Finishes previous call of e_client_set_backend_property().
1272 * Returns: %TRUE if successful, %FALSE otherwise.
1277 e_client_set_backend_property_finish (EClient *client,
1278 GAsyncResult *result,
1281 EClientClass *class;
1283 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1285 class = E_CLIENT_GET_CLASS (client);
1286 g_return_val_if_fail (class != NULL, FALSE);
1287 g_return_val_if_fail (class->set_backend_property_finish != NULL, FALSE);
1289 return class->set_backend_property_finish (client, result, error);
1293 * e_client_set_backend_property_sync:
1294 * @client: an #EClient
1295 * @prop_name: property name, whose value to change; cannot be %NULL
1296 * @prop_value: property value, to set; cannot be %NULL
1297 * @cancellable: a #GCancellable; can be %NULL
1298 * @error: (out): a #GError to set an error, if any
1300 * Sets @client's backend property of name @prop_name
1301 * to value @prop_value.
1303 * Returns: %TRUE if successful, %FALSE otherwise.
1308 e_client_set_backend_property_sync (EClient *client,
1309 const gchar *prop_name,
1310 const gchar *prop_value,
1311 GCancellable *cancellable,
1314 EClientClass *class;
1316 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1317 g_return_val_if_fail (prop_name != NULL, FALSE);
1318 g_return_val_if_fail (prop_value != NULL, FALSE);
1320 class = E_CLIENT_GET_CLASS (client);
1321 g_return_val_if_fail (class != NULL, FALSE);
1322 g_return_val_if_fail (class->set_backend_property_sync != NULL, FALSE);
1324 return class->set_backend_property_sync (client, prop_name, prop_value, cancellable, error);
1329 * @client: an #EClient
1330 * @only_if_exists: if %TRUE, fail if this book doesn't already exist, otherwise create it first
1331 * @cancellable: a #GCancellable; can be %NULL
1332 * @callback: callback to call when a result is ready
1333 * @user_data: user data for the @callback
1335 * Opens the @client, making it ready for queries and other operations.
1336 * The call is finished by e_client_open_finish() from the @callback.
1341 e_client_open (EClient *client,
1342 gboolean only_if_exists,
1343 GCancellable *cancellable,
1344 GAsyncReadyCallback callback,
1347 EClientClass *class;
1349 g_return_if_fail (callback != NULL);
1350 g_return_if_fail (E_IS_CLIENT (client));
1352 class = E_CLIENT_GET_CLASS (client);
1353 g_return_if_fail (class != NULL);
1354 g_return_if_fail (class->open != NULL);
1356 class->open (client, only_if_exists, cancellable, callback, user_data);
1360 * e_client_open_finish:
1361 * @client: an #EClient
1362 * @result: a #GAsyncResult
1363 * @error: (out): a #GError to set an error, if any
1365 * Finishes previous call of e_client_open().
1367 * Returns: %TRUE if successful, %FALSE otherwise.
1372 e_client_open_finish (EClient *client,
1373 GAsyncResult *result,
1376 EClientClass *class;
1378 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1380 class = E_CLIENT_GET_CLASS (client);
1381 g_return_val_if_fail (class != NULL, FALSE);
1382 g_return_val_if_fail (class->open_finish != NULL, FALSE);
1384 return class->open_finish (client, result, error);
1388 * e_client_open_sync:
1389 * @client: an #EClient
1390 * @only_if_exists: if %TRUE, fail if this book doesn't already exist, otherwise create it first
1391 * @cancellable: a #GCancellable; can be %NULL
1392 * @error: (out): a #GError to set an error, if any
1394 * Opens the @client, making it ready for queries and other operations.
1396 * Returns: %TRUE if successful, %FALSE otherwise.
1401 e_client_open_sync (EClient *client,
1402 gboolean only_if_exists,
1403 GCancellable *cancellable,
1406 EClientClass *class;
1408 class = E_CLIENT_GET_CLASS (client);
1409 g_return_val_if_fail (class != NULL, FALSE);
1410 g_return_val_if_fail (class->open_sync != NULL, FALSE);
1412 return class->open_sync (client, only_if_exists, cancellable, error);
1417 * @client: an #EClient
1418 * @cancellable: a #GCancellable; can be %NULL
1419 * @callback: callback to call when a result is ready
1420 * @user_data: user data for the @callback
1422 * Removes the backing data for this #EClient. For example, with the file
1423 * backend this deletes the database file. You cannot get it back!
1424 * The call is finished by e_client_remove_finish() from the @callback.
1429 e_client_remove (EClient *client,
1430 GCancellable *cancellable,
1431 GAsyncReadyCallback callback,
1434 EClientClass *class;
1436 g_return_if_fail (E_IS_CLIENT (client));
1437 g_return_if_fail (callback != NULL);
1439 class = E_CLIENT_GET_CLASS (client);
1440 g_return_if_fail (class != NULL);
1441 g_return_if_fail (class->remove != NULL);
1443 class->remove (client, cancellable, callback, user_data);
1447 * e_client_remove_finish:
1448 * @client: an #EClient
1449 * @result: a #GAsyncResult
1450 * @error: (out): a #GError to set an error, if any
1452 * Finishes previous call of e_client_remove().
1454 * Returns: %TRUE if successful, %FALSE otherwise.
1459 e_client_remove_finish (EClient *client,
1460 GAsyncResult *result,
1463 EClientClass *class;
1465 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1467 class = E_CLIENT_GET_CLASS (client);
1468 g_return_val_if_fail (class != NULL, FALSE);
1469 g_return_val_if_fail (class->remove_finish != NULL, FALSE);
1471 return class->remove_finish (client, result, error);
1475 * e_client_remove_sync:
1476 * @client: an #EClient
1477 * @cancellable: a #GCancellable; can be %NULL
1478 * @error: (out): a #GError to set an error, if any
1480 * Removes the backing data for this #EClient. For example, with the file
1481 * backend this deletes the database file. You cannot get it back!
1483 * Returns: %TRUE if successful, %FALSE otherwise.
1488 e_client_remove_sync (EClient *client,
1489 GCancellable *cancellable,
1492 EClientClass *class;
1494 class = E_CLIENT_GET_CLASS (client);
1495 g_return_val_if_fail (class != NULL, FALSE);
1496 g_return_val_if_fail (class->remove_sync != NULL, FALSE);
1498 return class->remove_sync (client, cancellable, error);
1503 * @client: an #EClient
1504 * @cancellable: a #GCancellable; can be %NULL
1505 * @callback: callback to call when a result is ready
1506 * @user_data: user data for the @callback
1508 * Initiates refresh on the @client. Finishing the method doesn't mean
1509 * that the refresh is done, backend only notifies whether it started
1510 * refreshing or not. Use e_client_check_refresh_supported() to check
1511 * whether the backend supports this method.
1512 * The call is finished by e_client_refresh_finish() from the @callback.
1517 e_client_refresh (EClient *client,
1518 GCancellable *cancellable,
1519 GAsyncReadyCallback callback,
1522 EClientClass *class;
1524 g_return_if_fail (E_IS_CLIENT (client));
1525 g_return_if_fail (callback != NULL);
1527 class = E_CLIENT_GET_CLASS (client);
1528 g_return_if_fail (class != NULL);
1529 g_return_if_fail (class->refresh != NULL);
1531 class->refresh (client, cancellable, callback, user_data);
1535 * e_client_refresh_finish:
1536 * @client: an #EClient
1537 * @result: a #GAsyncResult
1538 * @error: (out): a #GError to set an error, if any
1540 * Finishes previous call of e_client_refresh().
1542 * Returns: %TRUE if successful, %FALSE otherwise.
1547 e_client_refresh_finish (EClient *client,
1548 GAsyncResult *result,
1551 EClientClass *class;
1553 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1555 class = E_CLIENT_GET_CLASS (client);
1556 g_return_val_if_fail (class != NULL, FALSE);
1557 g_return_val_if_fail (class->refresh_finish != NULL, FALSE);
1559 return class->refresh_finish (client, result, error);
1563 * e_client_refresh_sync:
1564 * @client: an #EClient
1565 * @cancellable: a #GCancellable; can be %NULL
1566 * @error: (out): a #GError to set an error, if any
1568 * Initiates refresh on the @client. Finishing the method doesn't mean
1569 * that the refresh is done, backend only notifies whether it started
1570 * refreshing or not. Use e_client_check_refresh_supported() to check
1571 * whether the backend supports this method.
1573 * Returns: %TRUE if successful, %FALSE otherwise.
1578 e_client_refresh_sync (EClient *client,
1579 GCancellable *cancellable,
1582 EClientClass *class;
1584 class = E_CLIENT_GET_CLASS (client);
1585 g_return_val_if_fail (class != NULL, FALSE);
1586 g_return_val_if_fail (class->refresh_sync != NULL, FALSE);
1588 return class->refresh_sync (client, cancellable, error);
1592 * e_client_util_slist_to_strv:
1593 * @strings: a #GSList of strings (const gchar *)
1595 * Convert list of strings into NULL-terminates array of strings.
1597 * Returns: (transfer full): Newly allocated NULL-terminated array of strings.
1598 * Returned pointer should be freed with g_strfreev().
1600 * Note: Pair function for this is e_client_util_strv_to_slist().
1605 e_client_util_slist_to_strv (const GSList *strings)
1607 return e_util_slist_to_strv (strings);
1611 * e_client_util_strv_to_slist:
1612 * @strv: a NULL-terminated array of strings (const gchar *)
1614 * Convert NULL-terminated array of strings to a list of strings.
1616 * Returns: (transfer full): Newly allocated #GSList of newly allocated strings.
1617 * Returned pointer should be freed with e_client_util_free_string_slist().
1619 * Note: Pair function for this is e_client_util_slist_to_strv().
1624 e_client_util_strv_to_slist (const gchar * const *strv)
1626 return e_util_strv_to_slist (strv);
1630 * e_client_util_copy_string_slist:
1631 * @copy_to: Where to copy; can be NULL
1632 * @strings: GSList of strings to be copied
1634 * Copies GSList of strings at the end of @copy_to.
1636 * Returns: (transfer full): New head of @copy_to.
1637 * Returned pointer can be freed with e_client_util_free_string_slist().
1642 e_client_util_copy_string_slist (GSList *copy_to,
1643 const GSList *strings)
1645 return e_util_copy_string_slist (copy_to, strings);
1649 * e_client_util_copy_object_slist:
1650 * @copy_to: Where to copy; can be NULL
1651 * @objects: GSList of GObject-s to be copied
1653 * Copies GSList of GObject-s at the end of @copy_to.
1655 * Returns: (transfer full): New head of @copy_to.
1656 * Returned pointer can be freed with e_client_util_free_object_slist().
1661 e_client_util_copy_object_slist (GSList *copy_to,
1662 const GSList *objects)
1664 return e_util_copy_object_slist (copy_to, objects);
1668 * e_client_util_free_string_slist:
1669 * @strings: a #GSList of strings (gchar *)
1671 * Frees memory previously allocated by e_client_util_strv_to_slist().
1676 e_client_util_free_string_slist (GSList *strings)
1678 e_util_free_string_slist (strings);
1682 * e_client_util_free_object_slist:
1683 * @objects: a #GSList of #GObject-s
1685 * Calls g_object_unref() on each member of @objects and then frees
1686 * also @objects itself.
1691 e_client_util_free_object_slist (GSList *objects)
1693 e_util_free_object_slist (objects);
1697 * e_client_util_parse_comma_strings:
1698 * @strings: string of comma-separated values
1700 * Parses comma-separated list of values into #GSList.
1702 * Returns: (transfer full): Newly allocated #GSList of newly allocated strings
1703 * corresponding to values parsed from @strings.
1704 * Free returned pointer with e_client_util_free_string_slist().
1709 e_client_util_parse_comma_strings (const gchar *strings)
1711 GSList *strs_slist = NULL;
1712 gchar **strs_strv = NULL;
1715 if (!strings || !*strings)
1718 strs_strv = g_strsplit (strings, ",", -1);
1719 g_return_val_if_fail (strs_strv != NULL, NULL);
1721 for (ii = 0; strs_strv && strs_strv[ii]; ii++) {
1722 gchar *str = g_strstrip (strs_strv[ii]);
1725 strs_slist = g_slist_prepend (strs_slist, g_strdup (str));
1728 g_strfreev (strs_strv);
1730 return g_slist_reverse (strs_slist);
1733 /* for each known source calls check_func, which should return TRUE if the required
1734 * source have been found. Function returns NULL or the source on which was returned
1735 * TRUE by the check_func. Non - NULL pointer should be unreffed by g_object_unref. */
1737 search_known_sources (ESourceList *sources,
1738 gboolean (*check_func) (ESource *source,
1739 gpointer user_data),
1742 ESource *res = NULL;
1745 g_return_val_if_fail (check_func != NULL, NULL);
1746 g_return_val_if_fail (sources != NULL, NULL);
1748 for (g = e_source_list_peek_groups (sources); g; g = g->next) {
1749 ESourceGroup *group = E_SOURCE_GROUP (g->data);
1752 for (s = e_source_group_peek_sources (group); s; s = s->next) {
1753 ESource *source = E_SOURCE (s->data);
1755 if (check_func (source, user_data)) {
1756 res = g_object_ref (source);
1769 check_uri (ESource *source,
1776 g_return_val_if_fail (source != NULL, FALSE);
1777 g_return_val_if_fail (uri != NULL, FALSE);
1779 suri = e_source_peek_absolute_uri (source);
1782 return g_ascii_strcasecmp (suri, uri) == 0;
1784 suri2 = e_source_get_uri (source);
1785 res = suri2 && g_ascii_strcasecmp (suri2, uri) == 0;
1791 struct check_system_data
1794 ESource *uri_source;
1798 check_system (ESource *source,
1801 struct check_system_data *csd = data;
1803 g_return_val_if_fail (source != NULL, FALSE);
1804 g_return_val_if_fail (data != NULL, FALSE);
1806 if (e_source_get_property (source, "system")) {
1810 if (check_uri (source, (gpointer) csd->uri)) {
1811 if (csd->uri_source)
1812 g_object_unref (csd->uri_source);
1813 csd->uri_source = g_object_ref (source);
1820 e_client_util_get_system_source (ESourceList *source_list)
1822 struct check_system_data csd;
1823 ESource *system_source = NULL;
1825 g_return_val_if_fail (source_list != NULL, NULL);
1826 g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL);
1828 csd.uri = "local:system";
1829 csd.uri_source = NULL;
1831 system_source = search_known_sources (source_list, check_system, &csd);
1833 if (!system_source) {
1834 system_source = csd.uri_source;
1835 csd.uri_source = NULL;
1839 g_object_unref (csd.uri_source);
1841 if (!system_source) {
1842 /* create a new one, if not found */
1843 ESourceGroup *on_this_computer;
1845 on_this_computer = e_source_list_ensure_group (source_list,
1846 _("On This Computer"),
1848 if (on_this_computer) {
1849 GError *error = NULL;
1851 system_source = e_source_new (_("Personal"), "system");
1852 e_source_set_color_spec (system_source, "#BECEDD");
1853 e_source_group_add_source (on_this_computer, system_source, -1);
1855 if (!e_source_list_sync (source_list, &error))
1856 g_warning ("Cannot add system source to GConf: %s", error ? error->message : "Unknown error");
1859 g_error_free (error);
1863 return system_source;
1867 e_client_util_set_default (ESourceList *source_list,
1873 g_return_val_if_fail (source_list != NULL, FALSE);
1874 g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), FALSE);
1875 g_return_val_if_fail (source != NULL, FALSE);
1876 g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
1878 uid = e_source_get_uid (source);
1880 /* make sure the source is actually in the ESourceList. If
1881 * it's not we don't bother adding it, just return an error */
1882 source = e_source_list_peek_source_by_uid (source_list, uid);
1886 /* loop over all the sources clearing out any "default"
1887 * properties we find */
1888 for (g = e_source_list_peek_groups (source_list); g; g = g->next) {
1890 for (s = e_source_group_peek_sources (E_SOURCE_GROUP (g->data));
1892 e_source_set_property (E_SOURCE (s->data), "default", NULL);
1896 /* set the "default" property on the source */
1897 e_source_set_property (source, "default", "true");
1903 e_client_util_get_source_for_uri (ESourceList *source_list,
1908 g_return_val_if_fail (source_list != NULL, NULL);
1909 g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL);
1910 g_return_val_if_fail (uri != NULL, NULL);
1912 source = search_known_sources (source_list, check_uri, (gpointer) uri);
1914 source = e_source_new_with_absolute_uri ("", uri);
1920 e_client_finish_async_without_dbus (EClient *client,
1921 GCancellable *cancellable,
1922 GAsyncReadyCallback callback,
1924 gpointer source_tag,
1926 GDestroyNotify destroy_op_res)
1928 GCancellable *use_cancellable;
1929 GSimpleAsyncResult *simple;
1932 g_return_if_fail (E_IS_CLIENT (client));
1933 g_return_if_fail (callback != NULL);
1934 g_return_if_fail (source_tag != NULL);
1936 use_cancellable = cancellable;
1937 if (!use_cancellable)
1938 use_cancellable = g_cancellable_new ();
1940 opid = e_client_register_op (client, use_cancellable);
1941 g_return_if_fail (opid > 0);
1943 simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, source_tag);
1944 g_simple_async_result_set_op_res_gpointer (simple, op_res, destroy_op_res);
1945 g_simple_async_result_complete_in_idle (simple);
1946 g_object_unref (simple);
1948 if (use_cancellable != cancellable)
1949 g_object_unref (use_cancellable);
1953 e_client_get_dbus_proxy (EClient *client)
1955 EClientClass *class;
1957 g_return_val_if_fail (E_IS_CLIENT (client), NULL);
1959 class = E_CLIENT_GET_CLASS (client);
1960 g_return_val_if_fail (class != NULL, NULL);
1961 g_return_val_if_fail (class->get_dbus_proxy != NULL, NULL);
1963 return class->get_dbus_proxy (client);
1967 * e_client_unwrap_dbus_error:
1968 * @client: an #EClient
1969 * @dbus_error: a #GError returned bu D-Bus
1970 * @out_error: a #GError variable where to store the result
1972 * Unwraps D-Bus error to local error. @dbus_error is automatically freed.
1973 * @dbus_erorr and @out_error can point to the same variable.
1978 e_client_unwrap_dbus_error (EClient *client,
1982 EClientClass *class;
1984 g_return_if_fail (E_IS_CLIENT (client));
1986 class = E_CLIENT_GET_CLASS (client);
1987 g_return_if_fail (class != NULL);
1988 g_return_if_fail (class->unwrap_dbus_error != NULL);
1990 if (!dbus_error || !out_error) {
1992 g_error_free (dbus_error);
1994 class->unwrap_dbus_error (client, dbus_error, out_error);
1999 * e_client_util_unwrap_dbus_error:
2000 * @dbus_error: DBus #GError to unwrap
2001 * @client_error: (out): Resulting #GError; can be %NULL
2002 * @known_errors: List of known errors against which try to match
2003 * @known_errors_count: How many items are stored in @known_errors
2004 * @known_errors_domain: Error domain for @known_errors
2005 * @fail_when_none_matched: Whether to fail when none of @known_errors matches
2007 * The function takes a @dbus_error and tries to find a match in @known_errors
2008 * for it, if it is a G_IO_ERROR, G_IO_ERROR_DBUS_ERROR. If it is anything else
2009 * then the @dbus_error is moved to @client_error.
2011 * The @fail_when_none_matched influences behaviour. If it's %TRUE, and none of
2012 * @known_errors matches, or this is not a G_IO_ERROR_DBUS_ERROR, then %FALSE
2013 * is returned and the @client_error is left without change. Otherwise, the
2014 * @fail_when_none_matched is %FALSE, the error is always processed and will
2015 * result in E_CLIENT_ERROR, E_CLIENT_ERROR_OTHER_ERROR if none of @known_error
2018 * Returns: Whether was @dbus_error processed into @client_error.
2020 * Note: The @dbus_error is automatically freed if returned %TRUE.
2025 e_client_util_unwrap_dbus_error (GError *dbus_error,
2026 GError **client_error,
2027 const EClientErrorsList *known_errors,
2028 guint known_errors_count,
2029 GQuark known_errors_domain,
2030 gboolean fail_when_none_matched)
2032 if (!client_error) {
2034 g_error_free (dbus_error);
2039 *client_error = NULL;
2043 if (dbus_error->domain == known_errors_domain) {
2044 *client_error = dbus_error;
2049 if (g_error_matches (dbus_error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR)) {
2053 name = g_dbus_error_get_remote_error (dbus_error);
2055 for (ii = 0; ii < known_errors_count; ii++) {
2056 if (g_ascii_strcasecmp (known_errors[ii].name, name) == 0) {
2059 g_dbus_error_strip_remote_error (dbus_error);
2060 *client_error = g_error_new_literal (known_errors_domain, known_errors[ii].err_code, dbus_error->message);
2061 g_error_free (dbus_error);
2070 if (fail_when_none_matched)
2073 if (g_error_matches (dbus_error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR)) {
2074 g_dbus_error_strip_remote_error (dbus_error);
2075 *client_error = g_error_new_literal (E_CLIENT_ERROR, E_CLIENT_ERROR_OTHER_ERROR, dbus_error->message);
2076 g_error_free (dbus_error);
2078 if (dbus_error->domain == G_DBUS_ERROR)
2079 g_dbus_error_strip_remote_error (dbus_error);
2080 *client_error = dbus_error;
2086 typedef struct _EClientAsyncOpData
2091 gpointer source_tag;
2092 gchar *res_op_data; /* optional string to set on a GAsyncResult object as "res-op-data" user data */
2093 GAsyncReadyCallback callback;
2096 gboolean result; /* result of the finish function call */
2098 /* only one can be non-NULL, and the type is telling which 'out' value is valid */
2099 EClientProxyFinishVoidFunc finish_void;
2100 EClientProxyFinishBooleanFunc finish_boolean;
2101 EClientProxyFinishStringFunc finish_string;
2102 EClientProxyFinishStrvFunc finish_strv;
2103 EClientProxyFinishUintFunc finish_uint;
2106 gboolean val_boolean;
2111 } EClientAsyncOpData;
2114 async_data_free (EClientAsyncOpData *async_data)
2116 g_return_if_fail (async_data != NULL);
2117 g_return_if_fail (async_data->client != NULL);
2119 e_client_unregister_op (async_data->client, async_data->opid);
2121 if (async_data->finish_string)
2122 g_free (async_data->out.val_string);
2123 else if (async_data->finish_strv)
2124 g_strfreev (async_data->out.val_strv);
2126 g_object_unref (async_data->client);
2127 g_free (async_data->res_op_data);
2128 g_free (async_data);
2132 complete_async_op_in_idle_cb (gpointer user_data)
2134 GSimpleAsyncResult *simple = user_data;
2135 gint run_main_depth;
2137 g_return_val_if_fail (simple != NULL, FALSE);
2139 run_main_depth = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (simple), "run-main-depth"));
2140 if (run_main_depth < 1)
2143 /* do not receive in higher level than was initially run */
2144 if (g_main_depth () > run_main_depth) {
2148 g_simple_async_result_complete (simple);
2149 g_object_unref (simple);
2155 finish_async_op (EClientAsyncOpData *async_data,
2156 const GError *error,
2159 GSimpleAsyncResult *simple;
2161 g_return_if_fail (async_data != NULL);
2162 g_return_if_fail (async_data->source_tag != NULL);
2163 g_return_if_fail (async_data->client != NULL);
2165 simple = g_simple_async_result_new (G_OBJECT (async_data->client), async_data->callback, async_data->user_data, async_data->source_tag);
2166 g_simple_async_result_set_op_res_gpointer (simple, async_data, (GDestroyNotify) async_data_free);
2168 if (async_data->res_op_data)
2169 g_object_set_data_full (G_OBJECT (simple), "res-op-data", g_strdup (async_data->res_op_data), g_free);
2172 g_simple_async_result_set_from_error (simple, error);
2175 g_object_set_data (G_OBJECT (simple), "run-main-depth", GINT_TO_POINTER (g_main_depth ()));
2176 g_idle_add (complete_async_op_in_idle_cb, simple);
2178 g_simple_async_result_complete (simple);
2179 g_object_unref (simple);
2184 async_result_ready_cb (GObject *source_object,
2185 GAsyncResult *result,
2188 GError *error = NULL;
2189 EClientAsyncOpData *async_data;
2192 g_return_if_fail (result != NULL);
2193 g_return_if_fail (source_object != NULL);
2195 async_data = user_data;
2196 g_return_if_fail (async_data != NULL);
2197 g_return_if_fail (async_data->client != NULL);
2199 client = async_data->client;
2200 g_return_if_fail (e_client_get_dbus_proxy (client) == G_DBUS_PROXY (source_object));
2202 if (async_data->finish_void)
2203 async_data->result = async_data->finish_void (G_DBUS_PROXY (source_object), result, &error);
2204 else if (async_data->finish_boolean)
2205 async_data->result = async_data->finish_boolean (G_DBUS_PROXY (source_object), result, &async_data->out.val_boolean, &error);
2206 else if (async_data->finish_string)
2207 async_data->result = async_data->finish_string (G_DBUS_PROXY (source_object), result, &async_data->out.val_string, &error);
2208 else if (async_data->finish_strv)
2209 async_data->result = async_data->finish_strv (G_DBUS_PROXY (source_object), result, &async_data->out.val_strv, &error);
2210 else if (async_data->finish_uint)
2211 async_data->result = async_data->finish_uint (G_DBUS_PROXY (source_object), result, &async_data->out.val_uint, &error);
2213 g_warning ("%s: Do not know how to finish async operation", G_STRFUNC);
2215 finish_async_op (async_data, error, FALSE);
2218 g_error_free (error);
2221 static EClientAsyncOpData *
2222 prepare_async_data (EClient *client,
2223 GCancellable *cancellable,
2224 GAsyncReadyCallback callback,
2226 gpointer source_tag,
2227 gboolean error_report_only,
2228 EClientProxyFinishVoidFunc finish_void,
2229 EClientProxyFinishBooleanFunc finish_boolean,
2230 EClientProxyFinishStringFunc finish_string,
2231 EClientProxyFinishStrvFunc finish_strv,
2232 EClientProxyFinishUintFunc finish_uint,
2234 GCancellable **out_cancellable)
2236 EClientAsyncOpData *async_data;
2237 GCancellable *use_cancellable;
2240 g_return_val_if_fail (client != NULL, NULL);
2241 g_return_val_if_fail (callback != NULL, NULL);
2242 g_return_val_if_fail (source_tag != NULL, NULL);
2244 if (!error_report_only) {
2245 g_return_val_if_fail (proxy != NULL, NULL);
2246 g_return_val_if_fail (out_cancellable != NULL, NULL);
2247 g_return_val_if_fail (finish_void || finish_boolean || finish_string || finish_strv || finish_uint, NULL);
2250 g_return_val_if_fail (finish_boolean == NULL, NULL);
2251 g_return_val_if_fail (finish_string == NULL, NULL);
2252 g_return_val_if_fail (finish_strv == NULL, NULL);
2253 g_return_val_if_fail (finish_uint == NULL, NULL);
2256 if (finish_boolean) {
2257 g_return_val_if_fail (finish_void == NULL, NULL);
2258 g_return_val_if_fail (finish_string == NULL, NULL);
2259 g_return_val_if_fail (finish_strv == NULL, NULL);
2260 g_return_val_if_fail (finish_uint == NULL, NULL);
2263 if (finish_string) {
2264 g_return_val_if_fail (finish_void == NULL, NULL);
2265 g_return_val_if_fail (finish_boolean == NULL, NULL);
2266 g_return_val_if_fail (finish_strv == NULL, NULL);
2267 g_return_val_if_fail (finish_uint == NULL, NULL);
2271 g_return_val_if_fail (finish_void == NULL, NULL);
2272 g_return_val_if_fail (finish_boolean == NULL, NULL);
2273 g_return_val_if_fail (finish_string == NULL, NULL);
2274 g_return_val_if_fail (finish_uint == NULL, NULL);
2278 g_return_val_if_fail (finish_void == NULL, NULL);
2279 g_return_val_if_fail (finish_boolean == NULL, NULL);
2280 g_return_val_if_fail (finish_string == NULL, NULL);
2281 g_return_val_if_fail (finish_strv == NULL, NULL);
2284 *proxy = e_client_get_dbus_proxy (client);
2289 use_cancellable = cancellable;
2290 if (!use_cancellable)
2291 use_cancellable = g_cancellable_new ();
2293 opid = e_client_register_op (client, use_cancellable);
2294 async_data = g_new0 (EClientAsyncOpData, 1);
2295 async_data->client = g_object_ref (client);
2296 async_data->opid = opid;
2297 async_data->source_tag = source_tag;
2298 async_data->callback = callback;
2299 async_data->user_data = user_data;
2300 async_data->finish_void = finish_void;
2301 async_data->finish_boolean = finish_boolean;
2302 async_data->finish_string = finish_string;
2303 async_data->finish_strv = finish_strv;
2304 async_data->finish_uint = finish_uint;
2306 /* EClient from e_client_register_op() took ownership of the use_cancellable */
2307 if (use_cancellable != cancellable)
2308 g_object_unref (use_cancellable);
2310 if (out_cancellable)
2311 *out_cancellable = use_cancellable;
2317 e_client_proxy_return_async_error (EClient *client,
2318 const GError *error,
2319 GAsyncReadyCallback callback,
2321 gpointer source_tag)
2323 EClientAsyncOpData *async_data;
2325 g_return_if_fail (E_IS_CLIENT (client));
2326 g_return_if_fail (error != NULL);
2327 g_return_if_fail (callback != NULL);
2329 async_data = prepare_async_data (client, NULL, callback, user_data, source_tag, TRUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
2330 g_return_if_fail (async_data != NULL);
2332 finish_async_op (async_data, error, TRUE);
2336 e_client_proxy_call_void (EClient *client,
2337 GCancellable *cancellable,
2338 GAsyncReadyCallback callback,
2340 gpointer source_tag,
2341 void (*func) (GDBusProxy *proxy,
2342 GCancellable *cancellable,
2343 GAsyncReadyCallback callback,
2344 gpointer user_data),
2345 EClientProxyFinishVoidFunc finish_void,
2346 EClientProxyFinishBooleanFunc finish_boolean,
2347 EClientProxyFinishStringFunc finish_string,
2348 EClientProxyFinishStrvFunc finish_strv,
2349 EClientProxyFinishUintFunc finish_uint)
2351 EClientAsyncOpData *async_data;
2352 GDBusProxy *proxy = NULL;
2354 g_return_if_fail (E_IS_CLIENT (client));
2355 g_return_if_fail (callback != NULL);
2356 g_return_if_fail (source_tag != NULL);
2357 e_client_return_async_if_fail (func != NULL, client, callback, user_data, source_tag);
2359 async_data = prepare_async_data (client, cancellable, callback, user_data, source_tag, FALSE, finish_void, finish_boolean, finish_string, finish_strv, finish_uint, &proxy, &cancellable);
2360 e_client_return_async_if_fail (async_data != NULL, client, callback, user_data, source_tag);
2362 func (proxy, cancellable, async_result_ready_cb, async_data);
2366 e_client_proxy_call_boolean (EClient *client,
2367 gboolean in_boolean,
2368 GCancellable *cancellable,
2369 GAsyncReadyCallback callback,
2371 gpointer source_tag,
2372 void (*func) (GDBusProxy *proxy,
2373 gboolean in_boolean,
2374 GCancellable *cancellable,
2375 GAsyncReadyCallback callback,
2376 gpointer user_data),
2377 EClientProxyFinishVoidFunc finish_void,
2378 EClientProxyFinishBooleanFunc finish_boolean,
2379 EClientProxyFinishStringFunc finish_string,
2380 EClientProxyFinishStrvFunc finish_strv,
2381 EClientProxyFinishUintFunc finish_uint)
2383 EClientAsyncOpData *async_data;
2384 GDBusProxy *proxy = NULL;
2386 g_return_if_fail (E_IS_CLIENT (client));
2387 g_return_if_fail (callback != NULL);
2388 g_return_if_fail (source_tag != NULL);
2389 e_client_return_async_if_fail (func != NULL, client, callback, user_data, source_tag);
2391 async_data = prepare_async_data (client, cancellable, callback, user_data, source_tag, FALSE, finish_void, finish_boolean, finish_string, finish_strv, finish_uint, &proxy, &cancellable);
2392 e_client_return_async_if_fail (async_data != NULL, client, callback, user_data, source_tag);
2394 func (proxy, in_boolean, cancellable, async_result_ready_cb, async_data);
2398 e_client_proxy_call_string (EClient *client,
2399 const gchar *in_string,
2400 GCancellable *cancellable,
2401 GAsyncReadyCallback callback,
2403 gpointer source_tag,
2404 void (*func) (GDBusProxy *proxy,
2405 const gchar *in_string,
2406 GCancellable *cancellable,
2407 GAsyncReadyCallback callback,
2408 gpointer user_data),
2409 EClientProxyFinishVoidFunc finish_void,
2410 EClientProxyFinishBooleanFunc finish_boolean,
2411 EClientProxyFinishStringFunc finish_string,
2412 EClientProxyFinishStrvFunc finish_strv,
2413 EClientProxyFinishUintFunc finish_uint)
2415 EClientAsyncOpData *async_data;
2416 GDBusProxy *proxy = NULL;
2418 g_return_if_fail (E_IS_CLIENT (client));
2419 g_return_if_fail (callback != NULL);
2420 g_return_if_fail (source_tag != NULL);
2421 e_client_return_async_if_fail (func != NULL, client, callback, user_data, source_tag);
2422 e_client_return_async_if_fail (in_string != NULL, client, callback, user_data, source_tag);
2424 async_data = prepare_async_data (client, cancellable, callback, user_data, source_tag, FALSE, finish_void, finish_boolean, finish_string, finish_strv, finish_uint, &proxy, &cancellable);
2425 e_client_return_async_if_fail (async_data != NULL, client, callback, user_data, source_tag);
2427 func (proxy, in_string, cancellable, async_result_ready_cb, async_data);
2431 e_client_proxy_call_string_with_res_op_data (EClient *client,
2432 const gchar *in_string,
2433 GCancellable *cancellable,
2434 GAsyncReadyCallback callback,
2436 gpointer source_tag,
2437 const gchar *res_op_data,
2438 void (*func) (GDBusProxy *proxy,
2439 const gchar *in_string,
2440 GCancellable *cancellable,
2441 GAsyncReadyCallback callback,
2442 gpointer user_data),
2443 EClientProxyFinishVoidFunc finish_void,
2444 EClientProxyFinishBooleanFunc finish_boolean,
2445 EClientProxyFinishStringFunc finish_string,
2446 EClientProxyFinishStrvFunc finish_strv,
2447 EClientProxyFinishUintFunc finish_uint)
2449 EClientAsyncOpData *async_data;
2450 GDBusProxy *proxy = NULL;
2452 g_return_if_fail (E_IS_CLIENT (client));
2453 g_return_if_fail (callback != NULL);
2454 g_return_if_fail (source_tag != NULL);
2455 e_client_return_async_if_fail (func != NULL, client, callback, user_data, source_tag);
2456 e_client_return_async_if_fail (in_string != NULL, client, callback, user_data, source_tag);
2458 async_data = prepare_async_data (client, cancellable, callback, user_data, source_tag, FALSE, finish_void, finish_boolean, finish_string, finish_strv, finish_uint, &proxy, &cancellable);
2459 e_client_return_async_if_fail (async_data != NULL, client, callback, user_data, source_tag);
2461 async_data->res_op_data = g_strdup (res_op_data);
2463 func (proxy, in_string, cancellable, async_result_ready_cb, async_data);
2467 e_client_proxy_call_strv (EClient *client,
2468 const gchar * const *in_strv,
2469 GCancellable *cancellable,
2470 GAsyncReadyCallback callback,
2472 gpointer source_tag,
2473 void (*func) (GDBusProxy *proxy,
2474 const gchar * const * in_strv,
2475 GCancellable *cancellable,
2476 GAsyncReadyCallback callback,
2477 gpointer user_data),
2478 EClientProxyFinishVoidFunc finish_void,
2479 EClientProxyFinishBooleanFunc finish_boolean,
2480 EClientProxyFinishStringFunc finish_string,
2481 EClientProxyFinishStrvFunc finish_strv,
2482 EClientProxyFinishUintFunc finish_uint)
2484 EClientAsyncOpData *async_data;
2485 GDBusProxy *proxy = NULL;
2487 g_return_if_fail (E_IS_CLIENT (client));
2488 g_return_if_fail (callback != NULL);
2489 g_return_if_fail (source_tag != NULL);
2490 e_client_return_async_if_fail (func != NULL, client, callback, user_data, source_tag);
2491 e_client_return_async_if_fail (in_strv != NULL, client, callback, user_data, source_tag);
2493 async_data = prepare_async_data (client, cancellable, callback, user_data, source_tag, FALSE, finish_void, finish_boolean, finish_string, finish_strv, finish_uint, &proxy, &cancellable);
2494 e_client_return_async_if_fail (async_data != NULL, client, callback, user_data, source_tag);
2496 func (proxy, in_strv, cancellable, async_result_ready_cb, async_data);
2500 e_client_proxy_call_uint (EClient *client,
2502 GCancellable *cancellable,
2503 GAsyncReadyCallback callback,
2505 gpointer source_tag,
2506 void (*func) (GDBusProxy *proxy,
2508 GCancellable *cancellable,
2509 GAsyncReadyCallback callback,
2510 gpointer user_data),
2511 EClientProxyFinishVoidFunc finish_void,
2512 EClientProxyFinishBooleanFunc finish_boolean,
2513 EClientProxyFinishStringFunc finish_string,
2514 EClientProxyFinishStrvFunc finish_strv,
2515 EClientProxyFinishUintFunc finish_uint)
2517 EClientAsyncOpData *async_data;
2518 GDBusProxy *proxy = NULL;
2520 g_return_if_fail (E_IS_CLIENT (client));
2521 g_return_if_fail (callback != NULL);
2522 g_return_if_fail (source_tag != NULL);
2523 e_client_return_async_if_fail (func != NULL, client, callback, user_data, source_tag);
2525 async_data = prepare_async_data (client, cancellable, callback, user_data, source_tag, FALSE, finish_void, finish_boolean, finish_string, finish_strv, finish_uint, &proxy, &cancellable);
2526 e_client_return_async_if_fail (async_data != NULL, client, callback, user_data, source_tag);
2528 func (proxy, in_uint, cancellable, async_result_ready_cb, async_data);
2532 e_client_proxy_call_finish_void (EClient *client,
2533 GAsyncResult *result,
2535 gpointer source_tag)
2537 GSimpleAsyncResult *simple;
2538 GError *local_error = NULL;
2539 EClientAsyncOpData *async_data;
2541 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
2542 g_return_val_if_fail (result != NULL, FALSE);
2543 g_return_val_if_fail (source_tag != NULL, FALSE);
2544 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), source_tag), FALSE);
2546 simple = G_SIMPLE_ASYNC_RESULT (result);
2548 if (g_simple_async_result_propagate_error (simple, &local_error)) {
2549 e_client_unwrap_dbus_error (client, local_error, error);
2553 async_data = g_simple_async_result_get_op_res_gpointer (simple);
2554 g_return_val_if_fail (async_data != NULL, FALSE);
2556 return async_data->result;
2560 e_client_proxy_call_finish_boolean (EClient *client,
2561 GAsyncResult *result,
2562 gboolean *out_boolean,
2564 gpointer source_tag)
2566 GSimpleAsyncResult *simple;
2567 GError *local_error = NULL;
2568 EClientAsyncOpData *async_data;
2570 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
2571 g_return_val_if_fail (result != NULL, FALSE);
2572 g_return_val_if_fail (source_tag != NULL, FALSE);
2573 g_return_val_if_fail (out_boolean != NULL, FALSE);
2574 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), source_tag), FALSE);
2576 simple = G_SIMPLE_ASYNC_RESULT (result);
2578 if (g_simple_async_result_propagate_error (simple, &local_error)) {
2579 e_client_unwrap_dbus_error (client, local_error, error);
2583 async_data = g_simple_async_result_get_op_res_gpointer (simple);
2584 g_return_val_if_fail (async_data != NULL, FALSE);
2586 *out_boolean = async_data->out.val_boolean;
2588 return async_data->result;
2592 e_client_proxy_call_finish_string (EClient *client,
2593 GAsyncResult *result,
2596 gpointer source_tag)
2598 GSimpleAsyncResult *simple;
2599 GError *local_error = NULL;
2600 EClientAsyncOpData *async_data;
2602 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
2603 g_return_val_if_fail (result != NULL, FALSE);
2604 g_return_val_if_fail (source_tag != NULL, FALSE);
2605 g_return_val_if_fail (out_string != NULL, FALSE);
2606 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), source_tag), FALSE);
2608 simple = G_SIMPLE_ASYNC_RESULT (result);
2610 if (g_simple_async_result_propagate_error (simple, &local_error)) {
2611 e_client_unwrap_dbus_error (client, local_error, error);
2615 async_data = g_simple_async_result_get_op_res_gpointer (simple);
2616 g_return_val_if_fail (async_data != NULL, FALSE);
2618 *out_string = async_data->out.val_string;
2619 async_data->out.val_string = NULL;
2621 return async_data->result;
2625 e_client_proxy_call_finish_strv (EClient *client,
2626 GAsyncResult *result,
2629 gpointer source_tag)
2631 GSimpleAsyncResult *simple;
2632 GError *local_error = NULL;
2633 EClientAsyncOpData *async_data;
2635 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
2636 g_return_val_if_fail (result != NULL, FALSE);
2637 g_return_val_if_fail (source_tag != NULL, FALSE);
2638 g_return_val_if_fail (out_strv != NULL, FALSE);
2639 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), source_tag), FALSE);
2641 simple = G_SIMPLE_ASYNC_RESULT (result);
2643 if (g_simple_async_result_propagate_error (simple, &local_error)) {
2644 e_client_unwrap_dbus_error (client, local_error, error);
2648 async_data = g_simple_async_result_get_op_res_gpointer (simple);
2649 g_return_val_if_fail (async_data != NULL, FALSE);
2651 *out_strv = async_data->out.val_strv;
2652 async_data->out.val_strv = NULL;
2654 return async_data->result;
2658 e_client_proxy_call_finish_uint (EClient *client,
2659 GAsyncResult *result,
2662 gpointer source_tag)
2664 GSimpleAsyncResult *simple;
2665 GError *local_error = NULL;
2666 EClientAsyncOpData *async_data;
2668 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
2669 g_return_val_if_fail (result != NULL, FALSE);
2670 g_return_val_if_fail (source_tag != NULL, FALSE);
2671 g_return_val_if_fail (out_uint != NULL, FALSE);
2672 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), source_tag), FALSE);
2674 simple = G_SIMPLE_ASYNC_RESULT (result);
2676 if (g_simple_async_result_propagate_error (simple, &local_error)) {
2677 e_client_unwrap_dbus_error (client, local_error, error);
2681 async_data = g_simple_async_result_get_op_res_gpointer (simple);
2682 g_return_val_if_fail (async_data != NULL, FALSE);
2684 *out_uint = async_data->out.val_uint;
2686 return async_data->result;
2689 #define SYNC_CALL_TEMPLATE(_out_test,_the_call) \
2690 GDBusProxy *proxy; \
2691 GCancellable *use_cancellable; \
2694 GError *local_error = NULL; \
2696 g_return_val_if_fail (E_IS_CLIENT (client), FALSE); \
2697 g_return_val_if_fail (func != NULL, FALSE); \
2698 g_return_val_if_fail (_out_test != NULL, FALSE); \
2700 proxy = e_client_get_dbus_proxy (client); \
2701 g_return_val_if_fail (proxy != NULL, FALSE); \
2703 use_cancellable = cancellable; \
2704 if (!use_cancellable) \
2705 use_cancellable = g_cancellable_new (); \
2707 g_object_ref (client); \
2708 opid = e_client_register_op (client, use_cancellable); \
2710 result = func _the_call; \
2712 e_client_unregister_op (client, opid); \
2713 g_object_unref (client); \
2715 if (use_cancellable != cancellable) \
2716 g_object_unref (use_cancellable); \
2718 e_client_unwrap_dbus_error (client, local_error, error);\
2723 e_client_proxy_call_sync_void__void (EClient *client,
2724 GCancellable *cancellable,
2726 gboolean (*func) (GDBusProxy *proxy,
2727 GCancellable *cancellable,
2730 SYNC_CALL_TEMPLATE (client, (proxy, use_cancellable, &local_error))
2734 e_client_proxy_call_sync_void__boolean (EClient *client,
2735 gboolean *out_boolean,
2736 GCancellable *cancellable,
2738 gboolean (*func) (GDBusProxy *proxy,
2739 gboolean *out_boolean,
2740 GCancellable *cancellable,
2743 SYNC_CALL_TEMPLATE (out_boolean, (proxy, out_boolean, use_cancellable, &local_error))
2747 e_client_proxy_call_sync_void__string (EClient *client,
2749 GCancellable *cancellable,
2751 gboolean (*func) (GDBusProxy *proxy,
2753 GCancellable *cancellable,
2756 SYNC_CALL_TEMPLATE (out_string, (proxy, out_string, use_cancellable, &local_error))
2760 e_client_proxy_call_sync_void__strv (EClient *client,
2762 GCancellable *cancellable,
2764 gboolean (*func) (GDBusProxy *proxy,
2766 GCancellable *cancellable,
2769 SYNC_CALL_TEMPLATE (out_strv, (proxy, out_strv, use_cancellable, &local_error))
2773 e_client_proxy_call_sync_void__uint (EClient *client,
2775 GCancellable *cancellable,
2777 gboolean (*func) (GDBusProxy *proxy,
2779 GCancellable *cancellable,
2782 SYNC_CALL_TEMPLATE (out_uint, (proxy, out_uint, use_cancellable, &local_error))
2786 e_client_proxy_call_sync_boolean__void (EClient *client,
2787 gboolean in_boolean,
2788 GCancellable *cancellable,
2790 gboolean (*func) (GDBusProxy *proxy,
2791 gboolean in_boolean,
2792 GCancellable *cancellable,
2795 SYNC_CALL_TEMPLATE (client, (proxy, in_boolean, use_cancellable, &local_error))
2799 e_client_proxy_call_sync_boolean__boolean (EClient *client,
2800 gboolean in_boolean,
2801 gboolean *out_boolean,
2802 GCancellable *cancellable,
2804 gboolean (*func) (GDBusProxy *proxy,
2805 gboolean in_boolean,
2806 gboolean *out_boolean,
2807 GCancellable *cancellable,
2810 SYNC_CALL_TEMPLATE (out_boolean, (proxy, in_boolean, out_boolean, use_cancellable, &local_error))
2814 e_client_proxy_call_sync_boolean__string (EClient *client,
2815 gboolean in_boolean,
2817 GCancellable *cancellable,
2819 gboolean (*func) (GDBusProxy *proxy,
2820 gboolean in_boolean,
2822 GCancellable *cancellable,
2825 SYNC_CALL_TEMPLATE (out_string, (proxy, in_boolean, out_string, use_cancellable, &local_error))
2829 e_client_proxy_call_sync_boolean__strv (EClient *client,
2830 gboolean in_boolean,
2832 GCancellable *cancellable,
2834 gboolean (*func) (GDBusProxy *proxy,
2835 gboolean in_boolean,
2837 GCancellable *cancellable,
2840 SYNC_CALL_TEMPLATE (out_strv, (proxy, in_boolean, out_strv, use_cancellable, &local_error))
2844 e_client_proxy_call_sync_boolean__uint (EClient *client,
2845 gboolean in_boolean,
2847 GCancellable *cancellable,
2849 gboolean (*func) (GDBusProxy *proxy,
2850 gboolean in_boolean,
2852 GCancellable *cancellable,
2855 SYNC_CALL_TEMPLATE (out_uint, (proxy, in_boolean, out_uint, use_cancellable, &local_error))
2859 e_client_proxy_call_sync_string__void (EClient *client,
2860 const gchar *in_string,
2861 GCancellable *cancellable,
2863 gboolean (*func) (GDBusProxy *proxy,
2864 const gchar *in_string,
2865 GCancellable *cancellable,
2868 SYNC_CALL_TEMPLATE (client, (proxy, in_string, use_cancellable, &local_error))
2872 e_client_proxy_call_sync_string__boolean (EClient *client,
2873 const gchar *in_string,
2874 gboolean *out_boolean,
2875 GCancellable *cancellable,
2877 gboolean (*func) (GDBusProxy *proxy,
2878 const gchar *in_string,
2879 gboolean *out_boolean,
2880 GCancellable *cancellable,
2883 SYNC_CALL_TEMPLATE (out_boolean, (proxy, in_string, out_boolean, use_cancellable, &local_error))
2887 e_client_proxy_call_sync_string__string (EClient *client,
2888 const gchar *in_string,
2890 GCancellable *cancellable,
2892 gboolean (*func) (GDBusProxy *proxy,
2893 const gchar *in_string,
2895 GCancellable *cancellable,
2898 SYNC_CALL_TEMPLATE (out_string, (proxy, in_string, out_string, use_cancellable, &local_error))
2902 e_client_proxy_call_sync_string__strv (EClient *client,
2903 const gchar *in_string,
2905 GCancellable *cancellable,
2907 gboolean (*func) (GDBusProxy *proxy,
2908 const gchar *in_string,
2910 GCancellable *cancellable,
2913 SYNC_CALL_TEMPLATE (out_strv, (proxy, in_string, out_strv, use_cancellable, &local_error))
2917 e_client_proxy_call_sync_string__uint (EClient *client,
2918 const gchar *in_string,
2920 GCancellable *cancellable,
2922 gboolean (*func) (GDBusProxy *proxy,
2923 const gchar *in_string,
2925 GCancellable *cancellable,
2928 SYNC_CALL_TEMPLATE (out_uint, (proxy, in_string, out_uint, use_cancellable, &local_error))
2932 e_client_proxy_call_sync_strv__void (EClient *client,
2933 const gchar * const *in_strv,
2934 GCancellable *cancellable,
2936 gboolean (*func) (GDBusProxy *proxy,
2937 const gchar * const *in_strv,
2938 GCancellable *cancellable,
2941 SYNC_CALL_TEMPLATE (client, (proxy, in_strv, use_cancellable, &local_error))
2945 e_client_proxy_call_sync_strv__boolean (EClient *client,
2946 const gchar * const *in_strv,
2947 gboolean *out_boolean,
2948 GCancellable *cancellable,
2950 gboolean (*func) (GDBusProxy *proxy,
2951 const gchar * const *in_strv,
2952 gboolean *out_boolean,
2953 GCancellable *cancellable,
2956 SYNC_CALL_TEMPLATE (out_boolean, (proxy, in_strv, out_boolean, use_cancellable, &local_error))
2960 e_client_proxy_call_sync_strv__string (EClient *client,
2961 const gchar * const *in_strv,
2963 GCancellable *cancellable,
2965 gboolean (*func) (GDBusProxy *proxy,
2966 const gchar * const *in_strv,
2968 GCancellable *cancellable,
2971 SYNC_CALL_TEMPLATE (out_string, (proxy, in_strv, out_string, use_cancellable, &local_error))
2975 e_client_proxy_call_sync_strv__strv (EClient *client,
2976 const gchar * const *in_strv,
2978 GCancellable *cancellable,
2980 gboolean (*func) (GDBusProxy *proxy,
2981 const gchar * const *in_strv,
2983 GCancellable *cancellable,
2986 SYNC_CALL_TEMPLATE (out_strv, (proxy, in_strv, out_strv, use_cancellable, &local_error))
2990 e_client_proxy_call_sync_strv__uint (EClient *client,
2991 const gchar * const *in_strv,
2993 GCancellable *cancellable,
2995 gboolean (*func) (GDBusProxy *proxy,
2996 const gchar * const *in_strv,
2998 GCancellable *cancellable,
3001 SYNC_CALL_TEMPLATE (out_uint, (proxy, in_strv, out_uint, use_cancellable, &local_error))
3005 e_client_proxy_call_sync_uint__void (EClient *client,
3007 GCancellable *cancellable,
3009 gboolean (*func) (GDBusProxy *proxy,
3011 GCancellable *cancellable,
3014 SYNC_CALL_TEMPLATE (client, (proxy, in_uint, use_cancellable, &local_error))
3018 e_client_proxy_call_sync_uint__boolean (EClient *client,
3020 gboolean *out_boolean,
3021 GCancellable *cancellable,
3023 gboolean (*func) (GDBusProxy *proxy,
3025 gboolean *out_boolean,
3026 GCancellable *cancellable,
3029 SYNC_CALL_TEMPLATE (out_boolean, (proxy, in_uint, out_boolean, use_cancellable, &local_error))
3033 e_client_proxy_call_sync_uint__string (EClient *client,
3036 GCancellable *cancellable,
3038 gboolean (*func) (GDBusProxy *proxy,
3041 GCancellable *cancellable,
3044 SYNC_CALL_TEMPLATE (out_string, (proxy, in_uint, out_string, use_cancellable, &local_error))
3048 e_client_proxy_call_sync_uint__strv (EClient *client,
3051 GCancellable *cancellable,
3053 gboolean (*func) (GDBusProxy *proxy,
3056 GCancellable *cancellable,
3059 SYNC_CALL_TEMPLATE (out_strv, (proxy, in_uint, out_strv, use_cancellable, &local_error))
3063 e_client_proxy_call_sync_uint__uint (EClient *client,
3066 GCancellable *cancellable,
3068 gboolean (*func) (GDBusProxy *proxy,
3071 GCancellable *cancellable,
3074 SYNC_CALL_TEMPLATE (out_uint, (proxy, in_uint, out_uint, use_cancellable, &local_error))
3077 #undef SYNC_CALL_TEMPLATE