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 "e-gdbus-marshallers.h"
32 #include "e-client-private.h"
34 struct _EClientPrivate
36 GStaticRecMutex prop_mutex;
43 gboolean capabilities_retrieved;
46 GHashTable *backend_property_cache;
48 GStaticRecMutex ops_mutex;
50 GHashTable *ops; /* opid to GCancellable */
67 BACKEND_PROPERTY_CHANGED,
71 static guint signals[LAST_SIGNAL];
73 G_DEFINE_ABSTRACT_TYPE (EClient, e_client, G_TYPE_OBJECT)
76 * Well-known client backend properties, which are common for each #EClient:
77 * @CLIENT_BACKEND_PROPERTY_OPENED: Is set to "TRUE" or "FALSE" depending
78 * whether the backend is fully opened.
79 * @CLIENT_BACKEND_PROPERTY_OPENING: Is set to "TRUE" or "FALSE" depending
80 * whether the backend is processing its opening phase.
81 * @CLIENT_BACKEND_PROPERTY_ONLINE: Is set to "TRUE" or "FALSE" depending
82 * on the backend's loaded state. See also e_client_is_online().
83 * @CLIENT_BACKEND_PROPERTY_READONLY: Is set to "TRUE" or "FALSE" depending
84 * on the backend's readonly state. See also e_client_is_readonly().
85 * @CLIENT_BACKEND_PROPERTY_CACHE_DIR: Local folder with cached data used
87 * @CLIENT_BACKEND_PROPERTY_CAPABILITIES: Retrieves comma-separated list
88 * of capabilities supported by the backend. Preferred method of retreiving
89 * and working with capabilities is e_client_get_capabilities() and
90 * e_client_check_capability().
94 e_client_error_quark (void)
99 q = g_quark_from_static_string ("e-client-error-quark");
105 e_client_error_to_string (EClientError code)
108 case E_CLIENT_ERROR_INVALID_ARG:
109 return _("Invalid argument");
110 case E_CLIENT_ERROR_BUSY:
111 return _("Backend is busy");
112 case E_CLIENT_ERROR_SOURCE_NOT_LOADED:
113 return _("Source not loaded");
114 case E_CLIENT_ERROR_SOURCE_ALREADY_LOADED:
115 return _("Source already loaded");
116 case E_CLIENT_ERROR_AUTHENTICATION_FAILED:
117 return _("Authentication failed");
118 case E_CLIENT_ERROR_AUTHENTICATION_REQUIRED:
119 return _("Authentication required");
120 case E_CLIENT_ERROR_REPOSITORY_OFFLINE:
121 return _("Repository offline");
122 case E_CLIENT_ERROR_OFFLINE_UNAVAILABLE:
123 return _("Offline unavailable");
124 case E_CLIENT_ERROR_PERMISSION_DENIED:
125 return _("Permission denied");
126 case E_CLIENT_ERROR_CANCELLED:
127 return _("Cancelled");
128 case E_CLIENT_ERROR_COULD_NOT_CANCEL:
129 return _("Could not cancel");
130 case E_CLIENT_ERROR_NOT_SUPPORTED:
131 return _("Not supported");
132 case E_CLIENT_ERROR_UNSUPPORTED_AUTHENTICATION_METHOD:
133 return _("Unsupported authentication method");
134 case E_CLIENT_ERROR_TLS_NOT_AVAILABLE:
135 return _("TLS not available");
136 case E_CLIENT_ERROR_SEARCH_SIZE_LIMIT_EXCEEDED:
137 return _("Search size limit exceeded");
138 case E_CLIENT_ERROR_SEARCH_TIME_LIMIT_EXCEEDED:
139 return _("Search time limit exceeded");
140 case E_CLIENT_ERROR_INVALID_QUERY:
141 return _("Invalid query");
142 case E_CLIENT_ERROR_QUERY_REFUSED:
143 return _("Query refused");
144 case E_CLIENT_ERROR_DBUS_ERROR:
145 return _("D-Bus error");
146 case E_CLIENT_ERROR_OTHER_ERROR:
147 return _("Other error");
148 case E_CLIENT_ERROR_NOT_OPENED:
149 return _("Backend is not opened yet");
152 return _("Unknown error");
156 * e_client_error_create:
157 * @code: an #EClientError code to create
158 * @custom_msg: custom message to use for the error; can be %NULL
160 * Returns: a new #GError containing an E_CLIENT_ERROR of the given
161 * @code. If the @custom_msg is NULL, then the error message is
162 * the one returned from e_client_error_to_string() for the @code,
163 * otherwise the given message is used.
165 * Returned pointer should be freed with g_error_free().
168 e_client_error_create (EClientError code, const gchar *custom_msg)
170 return g_error_new_literal (E_CLIENT_ERROR, code, custom_msg ? custom_msg : e_client_error_to_string (code));
173 static void client_set_source (EClient *client, ESource *source);
174 static void client_handle_authentication (EClient *client, const ECredentials *credentials);
177 e_client_init (EClient *client)
179 client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client, E_TYPE_CLIENT, EClientPrivate);
181 client->priv->readonly = TRUE;
183 g_static_rec_mutex_init (&client->priv->prop_mutex);
184 client->priv->backend_property_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
186 g_static_rec_mutex_init (&client->priv->ops_mutex);
187 client->priv->last_opid = 0;
188 client->priv->ops = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
192 client_dispose (GObject *object)
196 client = E_CLIENT (object);
197 g_return_if_fail (client != NULL);
198 g_return_if_fail (client->priv != NULL);
200 e_client_cancel_all (client);
202 /* Chain up to parent's dispose() method. */
203 G_OBJECT_CLASS (e_client_parent_class)->dispose (object);
207 client_finalize (GObject *object)
210 EClientPrivate *priv;
212 client = E_CLIENT (object);
213 g_return_if_fail (client != NULL);
214 g_return_if_fail (client->priv != NULL);
218 g_static_rec_mutex_lock (&priv->prop_mutex);
221 g_object_unref (priv->source);
230 if (priv->capabilities) {
231 g_slist_foreach (priv->capabilities, (GFunc) g_free, NULL);
232 g_slist_free (priv->capabilities);
233 priv->capabilities = NULL;
236 if (priv->backend_property_cache) {
237 g_hash_table_destroy (priv->backend_property_cache);
238 priv->backend_property_cache = NULL;
242 g_hash_table_destroy (priv->ops);
246 g_static_rec_mutex_unlock (&priv->prop_mutex);
247 g_static_rec_mutex_free (&priv->prop_mutex);
248 g_static_rec_mutex_free (&priv->ops_mutex);
250 /* Chain up to parent's finalize() method. */
251 G_OBJECT_CLASS (e_client_parent_class)->finalize (object);
255 client_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
257 switch (property_id) {
259 client_set_source (E_CLIENT (object), g_value_get_object (value));
263 e_client_set_online (E_CLIENT (object), g_value_get_boolean (value));
267 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
271 client_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
273 switch (property_id) {
275 g_value_set_object (value, e_client_get_source (E_CLIENT (object)));
278 case PROP_CAPABILITIES:
279 g_value_set_pointer (value, (gpointer) e_client_get_capabilities (E_CLIENT (object)));
283 g_value_set_boolean (value, e_client_is_readonly (E_CLIENT (object)));
287 g_value_set_boolean (value, e_client_is_online (E_CLIENT (object)));
291 g_value_set_boolean (value, e_client_is_opened (E_CLIENT (object)));
295 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
299 e_client_class_init (EClientClass *klass)
301 GObjectClass *object_class;
303 g_type_class_add_private (klass, sizeof (EClientPrivate));
305 object_class = G_OBJECT_CLASS (klass);
306 object_class->set_property = client_set_property;
307 object_class->get_property = client_get_property;
308 object_class->dispose = client_dispose;
309 object_class->finalize = client_finalize;
311 g_object_class_install_property (
314 g_param_spec_object (
319 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
321 g_object_class_install_property (
324 g_param_spec_pointer (
330 g_object_class_install_property (
333 g_param_spec_boolean (
340 g_object_class_install_property (
343 g_param_spec_boolean (
350 g_object_class_install_property (
353 g_param_spec_boolean (
360 signals[AUTHENTICATE] = g_signal_new (
362 G_OBJECT_CLASS_TYPE (klass),
364 G_STRUCT_OFFSET (EClientClass, authenticate),
366 e_gdbus_marshallers_BOOLEAN__POINTER,
370 signals[OPENED] = g_signal_new (
372 G_OBJECT_CLASS_TYPE (klass),
374 G_STRUCT_OFFSET (EClientClass, opened),
376 g_cclosure_marshal_VOID__BOXED,
380 signals[BACKEND_ERROR] = g_signal_new (
382 G_OBJECT_CLASS_TYPE (klass),
384 G_STRUCT_OFFSET (EClientClass, backend_error),
386 g_cclosure_marshal_VOID__STRING,
390 signals[BACKEND_DIED] = g_signal_new (
392 G_OBJECT_CLASS_TYPE (klass),
394 G_STRUCT_OFFSET (EClientClass, backend_died),
396 g_cclosure_marshal_VOID__VOID,
399 signals[BACKEND_PROPERTY_CHANGED] = g_signal_new (
400 "backend-property-changed",
401 G_OBJECT_CLASS_TYPE (klass),
403 G_STRUCT_OFFSET (EClientClass, backend_property_changed),
405 e_gdbus_marshallers_VOID__STRING_STRING,
406 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
410 client_set_source (EClient *client, ESource *source)
412 g_return_if_fail (client != NULL);
413 g_return_if_fail (E_IS_CLIENT (client));
414 g_return_if_fail (client->priv != NULL);
415 g_return_if_fail (source != NULL);
416 g_return_if_fail (E_IS_SOURCE (source));
418 g_object_ref (source);
420 if (client->priv->source)
421 g_object_unref (client->priv->source);
423 client->priv->source = source;
427 * e_client_get_source:
428 * @client: an #EClient
430 * Get the #ESource that this client has assigned.
432 * Returns: (transfer none): The source.
437 e_client_get_source (EClient *client)
439 g_return_val_if_fail (client != NULL, NULL);
440 g_return_val_if_fail (E_IS_CLIENT (client), NULL);
441 g_return_val_if_fail (client->priv != NULL, NULL);
443 return client->priv->source;
448 * @client: an #EClient
450 * Get the URI that this client has assigned. This string should not be freed.
457 e_client_get_uri (EClient *client)
459 g_return_val_if_fail (client != NULL, NULL);
460 g_return_val_if_fail (E_IS_CLIENT (client), NULL);
461 g_return_val_if_fail (client->priv != NULL, NULL);
463 if (!client->priv->uri)
464 client->priv->uri = e_source_get_uri (e_client_get_source (client));
466 return client->priv->uri;
470 client_ensure_capabilities (EClient *client)
474 g_return_if_fail (client != NULL);
475 g_return_if_fail (E_IS_CLIENT (client));
476 g_return_if_fail (client->priv != NULL);
478 if (client->priv->capabilities_retrieved || client->priv->capabilities)
481 g_static_rec_mutex_lock (&client->priv->prop_mutex);
484 e_client_retrieve_capabilities_sync (client, &capabilities, NULL, NULL);
485 /* e_client_set_capabilities is called inside the previous function */
486 g_free (capabilities);
488 client->priv->capabilities_retrieved = TRUE;
490 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
494 * e_client_get_capabilities:
495 * @client: an #EClient
497 * Get list of strings with capabilities advertised by a backend.
498 * This list, together with inner strings, is owned by the @client.
499 * To check for individual capabilities use e_client_check_capability().
501 * Returns: (element-type utf8) (transfer none): #GSList of const strings of capabilities
506 e_client_get_capabilities (EClient *client)
508 g_return_val_if_fail (client != NULL, NULL);
509 g_return_val_if_fail (E_IS_CLIENT (client), NULL);
510 g_return_val_if_fail (client->priv != NULL, NULL);
512 client_ensure_capabilities (client);
514 return client->priv->capabilities;
518 * e_client_check_capability:
519 * @client: an #EClient
520 * @capability: a capability
522 * Check if backend supports particular capability.
523 * To get all capabilities use e_client_get_capabilities().
525 * Returns: #GSList of const strings of capabilities
530 e_client_check_capability (EClient *client, const gchar *capability)
534 g_return_val_if_fail (client != NULL, FALSE);
535 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
536 g_return_val_if_fail (client->priv != NULL, FALSE);
537 g_return_val_if_fail (capability, FALSE);
539 g_static_rec_mutex_lock (&client->priv->prop_mutex);
541 client_ensure_capabilities (client);
543 for (iter = client->priv->capabilities; iter; iter = g_slist_next (iter)) {
544 const gchar *cap = iter->data;
546 if (cap && g_ascii_strcasecmp (cap, capability) == 0) {
547 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
552 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
558 * e_client_check_refresh_supported:
561 * Checks whether a client supports explicit refreshing (see e_client_refresh()).
563 * Returns: TRUE if the client supports refreshing, FALSE otherwise.
568 e_client_check_refresh_supported (EClient *client)
570 g_return_val_if_fail (client != NULL, FALSE);
571 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
573 return e_client_check_capability (client, "refresh-supported");
576 /* capabilities - comma-separated list of capabilities; can be NULL to unset */
578 e_client_set_capabilities (EClient *client, const gchar *capabilities)
580 g_return_if_fail (client != NULL);
581 g_return_if_fail (E_IS_CLIENT (client));
582 g_return_if_fail (client->priv != NULL);
584 g_static_rec_mutex_lock (&client->priv->prop_mutex);
587 client->priv->capabilities_retrieved = FALSE;
589 g_slist_foreach (client->priv->capabilities, (GFunc) g_free, NULL);
590 g_slist_free (client->priv->capabilities);
591 client->priv->capabilities = e_client_util_parse_comma_strings (capabilities);
593 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
595 g_object_notify (G_OBJECT (client), "capabilities");
599 * e_client_is_readonly:
600 * @client: an #EClient
602 * Check if this @client is read-only.
604 * Returns: %TRUE if this @client is read-only, otherwise %FALSE.
609 e_client_is_readonly (EClient *client)
611 g_return_val_if_fail (client != NULL, TRUE);
612 g_return_val_if_fail (E_IS_CLIENT (client), TRUE);
613 g_return_val_if_fail (client->priv != NULL, TRUE);
615 return client->priv->readonly;
619 e_client_set_readonly (EClient *client, gboolean readonly)
621 g_return_if_fail (client != NULL);
622 g_return_if_fail (E_IS_CLIENT (client));
623 g_return_if_fail (client->priv != NULL);
625 g_static_rec_mutex_lock (&client->priv->prop_mutex);
626 if ((readonly ? 1 : 0) == (client->priv->readonly ? 1 : 0)) {
627 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
631 client->priv->readonly = readonly;
633 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
635 g_object_notify (G_OBJECT (client), "readonly");
639 * e_client_is_online:
640 * @client: an #EClient
642 * Check if this @client is connected.
644 * Returns: %TRUE if this @client is connected, otherwise %FALSE.
649 e_client_is_online (EClient *client)
651 g_return_val_if_fail (client != NULL, FALSE);
652 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
653 g_return_val_if_fail (client->priv != NULL, FALSE);
655 return client->priv->online;
659 e_client_set_online (EClient *client, gboolean is_online)
661 g_return_if_fail (client != NULL);
662 g_return_if_fail (E_IS_CLIENT (client));
663 g_return_if_fail (client->priv != NULL);
665 /* newly connected/disconnected => make sure capabilities will be correct */
666 e_client_set_capabilities (client, NULL);
668 g_static_rec_mutex_lock (&client->priv->prop_mutex);
669 if ((is_online ? 1: 0) == (client->priv->online ? 1 : 0)) {
670 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
674 client->priv->online = is_online;
676 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
678 g_object_notify (G_OBJECT (client), "online");
682 * e_client_is_opened:
683 * @client: an #EClient
685 * Check if this @client is fully opened. This includes
686 * everything from e_client_open() call up to the authentication,
687 * if required by a backend. Client cannot do any other operation
688 * during the opening phase except of authenticate or cancel it.
689 * Every other operation results in an %E_CLIENT_ERROR_BUSY error.
691 * Returns: %TRUE if this @client is fully opened, otherwise %FALSE.
696 e_client_is_opened (EClient *client)
698 g_return_val_if_fail (client != NULL, FALSE);
699 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
700 g_return_val_if_fail (client->priv != NULL, 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, guint32 opid)
719 GCancellable *cancellable;
721 g_return_if_fail (client != NULL);
722 g_return_if_fail (E_IS_CLIENT (client));
723 g_return_if_fail (client->priv != NULL);
724 g_return_if_fail (client->priv->ops != NULL);
726 g_static_rec_mutex_lock (&client->priv->ops_mutex);
728 cancellable = g_hash_table_lookup (client->priv->ops, GINT_TO_POINTER (opid));
730 g_cancellable_cancel (cancellable);
732 g_static_rec_mutex_unlock (&client->priv->ops_mutex);
736 gather_opids_cb (gpointer opid, gpointer cancellable, gpointer ids_list)
738 GSList **ids = ids_list;
740 g_return_if_fail (ids_list != NULL);
742 *ids = g_slist_prepend (*ids, opid);
746 cancel_op_cb (gpointer opid, gpointer client)
748 client_cancel_op (client, GPOINTER_TO_INT (opid));
752 * e_client_cancel_all:
753 * @client: an #EClient
755 * Cancels all pending operations started on @client.
760 e_client_cancel_all (EClient *client)
762 GSList *opids = NULL;
764 g_return_if_fail (client != NULL);
765 g_return_if_fail (E_IS_CLIENT (client));
766 g_return_if_fail (client->priv != NULL);
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, GCancellable *cancellable)
784 g_return_val_if_fail (client != NULL, 0);
785 g_return_val_if_fail (E_IS_CLIENT (client), 0);
786 g_return_val_if_fail (client->priv != NULL, 0);
787 g_return_val_if_fail (client->priv->ops != NULL, 0);
788 g_return_val_if_fail (cancellable != NULL, 0);
790 g_static_rec_mutex_lock (&client->priv->ops_mutex);
792 client->priv->last_opid++;
793 if (!client->priv->last_opid)
794 client->priv->last_opid++;
796 while (g_hash_table_lookup (client->priv->ops, GINT_TO_POINTER (client->priv->last_opid)))
797 client->priv->last_opid++;
799 g_return_val_if_fail (client->priv->last_opid != 0, 0);
801 opid = client->priv->last_opid;
802 g_hash_table_insert (client->priv->ops, GINT_TO_POINTER (opid), g_object_ref (cancellable));
804 g_static_rec_mutex_unlock (&client->priv->ops_mutex);
810 e_client_unregister_op (EClient *client, guint32 opid)
812 g_return_if_fail (client != NULL);
813 g_return_if_fail (E_IS_CLIENT (client));
814 g_return_if_fail (client->priv != NULL);
815 g_return_if_fail (client->priv->ops != NULL);
817 g_static_rec_mutex_lock (&client->priv->ops_mutex);
818 g_hash_table_remove (client->priv->ops, GINT_TO_POINTER (opid));
819 g_static_rec_mutex_unlock (&client->priv->ops_mutex);
823 client_handle_authentication (EClient *client, const ECredentials *credentials)
827 g_return_if_fail (client != NULL);
828 g_return_if_fail (E_IS_CLIENT (client));
829 g_return_if_fail (credentials != NULL);
831 klass = E_CLIENT_GET_CLASS (client);
832 g_return_if_fail (klass != NULL);
833 g_return_if_fail (klass->handle_authentication != NULL);
835 return klass->handle_authentication (client, credentials);
838 struct EClientAuthData {
840 ECredentials *credentials;
844 client_process_authentication_idle_cb (gpointer user_data)
846 struct EClientAuthData *auth_data = user_data;
848 g_return_val_if_fail (auth_data != NULL, FALSE);
850 if (e_client_emit_authenticate (auth_data->client, auth_data->credentials)) {
851 client_handle_authentication (auth_data->client, auth_data->credentials);
855 error = e_client_error_create (E_CLIENT_ERROR_AUTHENTICATION_REQUIRED, NULL);
856 e_client_emit_opened (auth_data->client, error);
857 g_error_free (error);
860 e_credentials_free (auth_data->credentials);
861 g_object_unref (auth_data->client);
867 /* Processes authentication request in idle callback. Usual steps are:
868 a) backend sends an auth-required signal
869 b) EClient implementation calls this function
870 c) a new idle callback is run which emits authenticate signal by e_client_emit_authenticate ()
871 d) if anyone responds (returns true), the EClient::handle_authentication
872 is called from the same idle callback with new credentials
873 e) EClient implementation passes results to backend in the EClient::handle_authentication
876 e_client_process_authentication (EClient *client, const ECredentials *credentials)
878 struct EClientAuthData *auth_data;
880 g_return_if_fail (client != NULL);
881 g_return_if_fail (E_IS_CLIENT (client));
883 auth_data = g_new0 (struct EClientAuthData, 1);
884 auth_data->client = g_object_ref (client);
885 auth_data->credentials = credentials ? e_credentials_new_clone (credentials) : e_credentials_new ();
887 g_idle_add (client_process_authentication_idle_cb, auth_data);
891 e_client_emit_authenticate (EClient *client, ECredentials *credentials)
893 gboolean handled = FALSE;
895 g_return_val_if_fail (client != NULL, FALSE);
896 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
897 g_return_val_if_fail (credentials != NULL, FALSE);
899 g_signal_emit (client, signals[AUTHENTICATE], 0, credentials, &handled);
905 e_client_emit_opened (EClient *client, const GError *dbus_error)
907 GError *local_error = NULL;
909 g_return_if_fail (client != NULL);
910 g_return_if_fail (E_IS_CLIENT (client));
911 g_return_if_fail (client->priv != NULL);
913 client->priv->opened = dbus_error == NULL;
916 local_error = g_error_copy (dbus_error);
917 e_client_unwrap_dbus_error (client, local_error, &local_error);
920 g_object_notify (G_OBJECT (client), "opened");
921 g_signal_emit (client, signals[OPENED], 0, local_error);
924 g_error_free (local_error);
928 e_client_emit_backend_error (EClient *client, const gchar *error_msg)
930 g_return_if_fail (client != NULL);
931 g_return_if_fail (E_IS_CLIENT (client));
932 g_return_if_fail (error_msg != NULL);
934 g_signal_emit (client, signals[BACKEND_ERROR], 0, error_msg);
938 e_client_emit_backend_died (EClient *client)
940 g_return_if_fail (client != NULL);
941 g_return_if_fail (E_IS_CLIENT (client));
943 g_signal_emit (client, signals[BACKEND_DIED], 0);
947 e_client_emit_backend_property_changed (EClient *client, const gchar *prop_name, const gchar *prop_value)
949 g_return_if_fail (client != NULL);
950 g_return_if_fail (E_IS_CLIENT (client));
951 g_return_if_fail (client->priv != NULL);
952 g_return_if_fail (prop_name != NULL);
953 g_return_if_fail (*prop_name);
954 g_return_if_fail (prop_value != NULL);
956 e_client_update_backend_property_cache (client, prop_name, prop_value);
958 g_signal_emit (client, signals[BACKEND_PROPERTY_CHANGED], 0, prop_name, prop_value);
962 e_client_update_backend_property_cache (EClient *client, const gchar *prop_name, const gchar *prop_value)
964 g_return_if_fail (client != NULL);
965 g_return_if_fail (E_IS_CLIENT (client));
966 g_return_if_fail (client->priv != NULL);
967 g_return_if_fail (prop_name != NULL);
968 g_return_if_fail (*prop_name);
969 g_return_if_fail (prop_value != NULL);
971 g_static_rec_mutex_lock (&client->priv->prop_mutex);
973 if (client->priv->backend_property_cache)
974 g_hash_table_insert (client->priv->backend_property_cache, g_strdup (prop_name), g_strdup (prop_value));
976 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
980 e_client_get_backend_property_from_cache (EClient *client, const gchar *prop_name)
982 gchar *prop_value = NULL;
984 g_return_val_if_fail (client != NULL, NULL);
985 g_return_val_if_fail (E_IS_CLIENT (client), NULL);
986 g_return_val_if_fail (client->priv != NULL, NULL);
987 g_return_val_if_fail (prop_name != NULL, NULL);
988 g_return_val_if_fail (*prop_name, NULL);
990 g_static_rec_mutex_lock (&client->priv->prop_mutex);
992 if (client->priv->backend_property_cache)
993 prop_value = g_strdup (g_hash_table_lookup (client->priv->backend_property_cache, prop_name));
995 g_static_rec_mutex_unlock (&client->priv->prop_mutex);
1001 * e_client_retrieve_capabilities:
1002 * @client: an #EClient
1003 * @cancellable: a #GCancellable; can be %NULL
1004 * @callback: callback to call when a result is ready
1005 * @user_data: user data for the @callback
1007 * Initiates retrieval of capabilities on the @client. This is usually
1008 * required only once, after the @client is opened. The returned value
1009 * is cached and any subsequent call of e_client_get_capabilities() and
1010 * e_client_check_capability() is using the cached value.
1011 * The call is finished by e_client_retrieve_capabilities_finish()
1012 * from the @callback.
1017 e_client_retrieve_capabilities (EClient *client, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
1019 EClientClass *klass;
1021 g_return_if_fail (client != NULL);
1022 g_return_if_fail (E_IS_CLIENT (client));
1023 g_return_if_fail (client->priv != NULL);
1024 g_return_if_fail (callback != NULL);
1026 klass = E_CLIENT_GET_CLASS (client);
1027 g_return_if_fail (klass != NULL);
1028 g_return_if_fail (klass->retrieve_capabilities != NULL);
1030 klass->retrieve_capabilities (client, cancellable, callback, user_data);
1034 * e_client_retrieve_capabilities_finish:
1035 * @client: an #EClient
1036 * @result: a #GAsyncResult
1037 * @capabilities: (out): Comma-separated list of capabilities of the @client
1038 * @error: (out): a #GError to set an error, if any
1040 * Finishes previous call of e_client_retrieve_capabilities().
1041 * Returned value of @capabilities should be freed with g_free(),
1042 * when no longer needed.
1044 * Returns: %TRUE if successful, %FALSE otherwise.
1049 e_client_retrieve_capabilities_finish (EClient *client, GAsyncResult *result, gchar **capabilities, GError **error)
1051 EClientClass *klass;
1054 g_return_val_if_fail (client != NULL, FALSE);
1055 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1056 g_return_val_if_fail (client->priv != NULL, FALSE);
1057 g_return_val_if_fail (capabilities != NULL, FALSE);
1059 klass = E_CLIENT_GET_CLASS (client);
1060 g_return_val_if_fail (klass != NULL, FALSE);
1061 g_return_val_if_fail (klass->retrieve_capabilities_finish != NULL, FALSE);
1063 *capabilities = NULL;
1064 res = klass->retrieve_capabilities_finish (client, result, capabilities, error);
1066 e_client_set_capabilities (client, res ? *capabilities : NULL);
1072 * e_client_retrieve_capabilities_sync:
1073 * @client: an #EClient
1074 * @capabilities: (out): Comma-separated list of capabilities of the @client
1075 * @cancellable: a #GCancellable; can be %NULL
1076 * @error: (out): a #GError to set an error, if any
1078 * Initiates retrieval of capabilities on the @client. This is usually
1079 * required only once, after the @client is opened. The returned value
1080 * is cached and any subsequent call of e_client_get_capabilities() and
1081 * e_client_check_capability() is using the cached value. Returned value
1082 * of @capabilities should be freed with g_free(), when no longer needed.
1084 * Returns: %TRUE if successful, %FALSE otherwise.
1089 e_client_retrieve_capabilities_sync (EClient *client, gchar **capabilities, GCancellable *cancellable, GError **error)
1091 EClientClass *klass;
1092 gboolean res = FALSE;
1094 g_return_val_if_fail (client != NULL, FALSE);
1095 g_return_val_if_fail (capabilities != NULL, FALSE);
1097 klass = E_CLIENT_GET_CLASS (client);
1098 g_return_val_if_fail (klass != NULL, FALSE);
1099 g_return_val_if_fail (klass->retrieve_capabilities_sync != NULL, FALSE);
1101 *capabilities = NULL;
1102 res = klass->retrieve_capabilities_sync (client, capabilities, cancellable, error);
1104 e_client_set_capabilities (client, res ? *capabilities : NULL);
1110 * e_client_get_backend_property:
1111 * @client: an #EClient
1112 * @prop_name: property name, whose value to retrieve; cannot be %NULL
1113 * @cancellable: a #GCancellable; can be %NULL
1114 * @callback: callback to call when a result is ready
1115 * @user_data: user data for the @callback
1117 * Queries @client's backend for a property of name @prop_name.
1118 * The call is finished by e_client_get_backend_property_finish()
1119 * from the @callback.
1124 e_client_get_backend_property (EClient *client, const gchar *prop_name, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
1126 EClientClass *klass;
1128 g_return_if_fail (callback != NULL);
1129 g_return_if_fail (client != NULL);
1130 g_return_if_fail (E_IS_CLIENT (client));
1131 g_return_if_fail (client->priv != NULL);
1132 g_return_if_fail (prop_name != NULL);
1134 klass = E_CLIENT_GET_CLASS (client);
1135 g_return_if_fail (klass != NULL);
1136 g_return_if_fail (klass->get_backend_property != NULL);
1138 klass->get_backend_property (client, prop_name, cancellable, callback, user_data);
1142 * e_client_get_backend_property_finish:
1143 * @client: an #EClient
1144 * @result: a #GAsyncResult
1145 * @prop_value: (out): Retrieved backend property value; cannot be %NULL
1146 * @error: (out): a #GError to set an error, if any
1148 * Finishes previous call of e_client_get_backend_property().
1150 * Returns: %TRUE if successful, %FALSE otherwise.
1155 e_client_get_backend_property_finish (EClient *client, GAsyncResult *result, gchar **prop_value, GError **error)
1157 EClientClass *klass;
1159 g_return_val_if_fail (client != NULL, FALSE);
1160 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1161 g_return_val_if_fail (client->priv != NULL, FALSE);
1162 g_return_val_if_fail (prop_value != NULL, FALSE);
1164 klass = E_CLIENT_GET_CLASS (client);
1165 g_return_val_if_fail (klass != NULL, FALSE);
1166 g_return_val_if_fail (klass->get_backend_property_finish != NULL, FALSE);
1168 return klass->get_backend_property_finish (client, result, prop_value, error);
1172 * e_client_get_backend_property_sync:
1173 * @client: an #EClient
1174 * @prop_name: property name, whose value to retrieve; cannot be %NULL
1175 * @prop_value: (out): Retrieved backend property value; cannot be %NULL
1176 * @cancellable: a #GCancellable; can be %NULL
1177 * @error: (out): a #GError to set an error, if any
1179 * Queries @client's backend for a property of name @prop_name.
1181 * Returns: %TRUE if successful, %FALSE otherwise.
1186 e_client_get_backend_property_sync (EClient *client, const gchar *prop_name, gchar **prop_value, GCancellable *cancellable, GError **error)
1188 EClientClass *klass;
1190 g_return_val_if_fail (client != NULL, FALSE);
1191 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1192 g_return_val_if_fail (client->priv != NULL, FALSE);
1193 g_return_val_if_fail (prop_name != NULL, FALSE);
1194 g_return_val_if_fail (prop_value != NULL, FALSE);
1196 klass = E_CLIENT_GET_CLASS (client);
1197 g_return_val_if_fail (klass != NULL, FALSE);
1198 g_return_val_if_fail (klass->get_backend_property_sync != NULL, FALSE);
1200 return klass->get_backend_property_sync (client, prop_name, prop_value, cancellable, error);
1204 * e_client_set_backend_property:
1205 * @client: an #EClient
1206 * @prop_name: property name, whose value to change; cannot be %NULL
1207 * @prop_value: property value, to set; cannot be %NULL
1208 * @cancellable: a #GCancellable; can be %NULL
1209 * @callback: callback to call when a result is ready
1210 * @user_data: user data for the @callback
1212 * Sets @client's backend property of name @prop_name
1213 * to value @prop_value. The call is finished
1214 * by e_client_set_backend_property_finish() from the @callback.
1219 e_client_set_backend_property (EClient *client, const gchar *prop_name, const gchar *prop_value, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
1221 EClientClass *klass;
1223 g_return_if_fail (callback != NULL);
1224 g_return_if_fail (client != NULL);
1225 g_return_if_fail (E_IS_CLIENT (client));
1226 g_return_if_fail (client->priv != NULL);
1227 g_return_if_fail (prop_name != NULL);
1228 g_return_if_fail (prop_value != NULL);
1230 klass = E_CLIENT_GET_CLASS (client);
1231 g_return_if_fail (klass != NULL);
1232 g_return_if_fail (klass->set_backend_property != NULL);
1234 klass->set_backend_property (client, prop_name, prop_value, cancellable, callback, user_data);
1238 * e_client_set_backend_property_finish:
1239 * @client: an #EClient
1240 * @result: a #GAsyncResult
1241 * @error: (out): a #GError to set an error, if any
1243 * Finishes previous call of e_client_set_backend_property().
1245 * Returns: %TRUE if successful, %FALSE otherwise.
1250 e_client_set_backend_property_finish (EClient *client, GAsyncResult *result, GError **error)
1252 EClientClass *klass;
1254 g_return_val_if_fail (client != NULL, FALSE);
1255 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1256 g_return_val_if_fail (client->priv != NULL, FALSE);
1258 klass = E_CLIENT_GET_CLASS (client);
1259 g_return_val_if_fail (klass != NULL, FALSE);
1260 g_return_val_if_fail (klass->set_backend_property_finish != NULL, FALSE);
1262 return klass->set_backend_property_finish (client, result, error);
1266 * e_client_set_backend_property_sync:
1267 * @client: an #EClient
1268 * @prop_name: property name, whose value to change; cannot be %NULL
1269 * @prop_value: property value, to set; cannot be %NULL
1270 * @cancellable: a #GCancellable; can be %NULL
1271 * @error: (out): a #GError to set an error, if any
1273 * Sets @client's backend property of name @prop_name
1274 * to value @prop_value.
1276 * Returns: %TRUE if successful, %FALSE otherwise.
1281 e_client_set_backend_property_sync (EClient *client, const gchar *prop_name, const gchar *prop_value, GCancellable *cancellable, GError **error)
1283 EClientClass *klass;
1285 g_return_val_if_fail (client != NULL, FALSE);
1286 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1287 g_return_val_if_fail (client->priv != NULL, FALSE);
1288 g_return_val_if_fail (prop_name != NULL, FALSE);
1289 g_return_val_if_fail (prop_value != NULL, FALSE);
1291 klass = E_CLIENT_GET_CLASS (client);
1292 g_return_val_if_fail (klass != NULL, FALSE);
1293 g_return_val_if_fail (klass->set_backend_property_sync != NULL, FALSE);
1295 return klass->set_backend_property_sync (client, prop_name, prop_value, cancellable, error);
1300 * @client: an #EClient
1301 * @only_if_exists: if %TRUE, fail if this book doesn't already exist, otherwise create it first
1302 * @cancellable: a #GCancellable; can be %NULL
1303 * @callback: callback to call when a result is ready
1304 * @user_data: user data for the @callback
1306 * Opens the @client, making it ready for queries and other operations.
1307 * The call is finished by e_client_open_finish() from the @callback.
1312 e_client_open (EClient *client, gboolean only_if_exists, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
1314 EClientClass *klass;
1316 g_return_if_fail (callback != NULL);
1317 g_return_if_fail (client != NULL);
1318 g_return_if_fail (E_IS_CLIENT (client));
1319 g_return_if_fail (client->priv != NULL);
1321 klass = E_CLIENT_GET_CLASS (client);
1322 g_return_if_fail (klass != NULL);
1323 g_return_if_fail (klass->open != NULL);
1325 klass->open (client, only_if_exists, cancellable, callback, user_data);
1329 * e_client_open_finish:
1330 * @client: an #EClient
1331 * @result: a #GAsyncResult
1332 * @error: (out): a #GError to set an error, if any
1334 * Finishes previous call of e_client_open().
1336 * Returns: %TRUE if successful, %FALSE otherwise.
1341 e_client_open_finish (EClient *client, GAsyncResult *result, GError **error)
1343 EClientClass *klass;
1345 g_return_val_if_fail (client != NULL, FALSE);
1346 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1347 g_return_val_if_fail (client->priv != NULL, FALSE);
1349 klass = E_CLIENT_GET_CLASS (client);
1350 g_return_val_if_fail (klass != NULL, FALSE);
1351 g_return_val_if_fail (klass->open_finish != NULL, FALSE);
1353 return klass->open_finish (client, result, error);
1357 * e_client_open_sync:
1358 * @client: an #EClient
1359 * @only_if_exists: if %TRUE, fail if this book doesn't already exist, otherwise create it first
1360 * @cancellable: a #GCancellable; can be %NULL
1361 * @error: (out): a #GError to set an error, if any
1363 * Opens the @client, making it ready for queries and other operations.
1365 * Returns: %TRUE if successful, %FALSE otherwise.
1370 e_client_open_sync (EClient *client, gboolean only_if_exists, GCancellable *cancellable, GError **error)
1372 EClientClass *klass;
1374 klass = E_CLIENT_GET_CLASS (client);
1375 g_return_val_if_fail (klass != NULL, FALSE);
1376 g_return_val_if_fail (klass->open_sync != NULL, FALSE);
1378 return klass->open_sync (client, only_if_exists, cancellable, error);
1383 * @client: an #EClient
1384 * @cancellable: a #GCancellable; can be %NULL
1385 * @callback: callback to call when a result is ready
1386 * @user_data: user data for the @callback
1388 * Removes the backing data for this #EClient. For example, with the file backend this
1389 * deletes the database file. You cannot get it back!
1390 * The call is finished by e_client_remove_finish() from the @callback.
1395 e_client_remove (EClient *client, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
1397 EClientClass *klass;
1399 g_return_if_fail (client != NULL);
1400 g_return_if_fail (E_IS_CLIENT (client));
1401 g_return_if_fail (client->priv != NULL);
1402 g_return_if_fail (callback != NULL);
1404 klass = E_CLIENT_GET_CLASS (client);
1405 g_return_if_fail (klass != NULL);
1406 g_return_if_fail (klass->remove != NULL);
1408 klass->remove (client, cancellable, callback, user_data);
1412 * e_client_remove_finish:
1413 * @client: an #EClient
1414 * @result: a #GAsyncResult
1415 * @error: (out): a #GError to set an error, if any
1417 * Finishes previous call of e_client_remove().
1419 * Returns: %TRUE if successful, %FALSE otherwise.
1424 e_client_remove_finish (EClient *client, GAsyncResult *result, GError **error)
1426 EClientClass *klass;
1428 g_return_val_if_fail (client != NULL, FALSE);
1429 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1430 g_return_val_if_fail (client->priv != NULL, FALSE);
1432 klass = E_CLIENT_GET_CLASS (client);
1433 g_return_val_if_fail (klass != NULL, FALSE);
1434 g_return_val_if_fail (klass->remove_finish != NULL, FALSE);
1436 return klass->remove_finish (client, result, error);
1440 * e_client_remove_sync:
1441 * @client: an #EClient
1442 * @cancellable: a #GCancellable; can be %NULL
1443 * @error: (out): a #GError to set an error, if any
1445 * Removes the backing data for this #EClient. For example, with the file backend this
1446 * deletes the database file. You cannot get it back!
1448 * Returns: %TRUE if successful, %FALSE otherwise.
1453 e_client_remove_sync (EClient *client, GCancellable *cancellable, GError **error)
1455 EClientClass *klass;
1457 klass = E_CLIENT_GET_CLASS (client);
1458 g_return_val_if_fail (klass != NULL, FALSE);
1459 g_return_val_if_fail (klass->remove_sync != NULL, FALSE);
1461 return klass->remove_sync (client, cancellable, error);
1466 * @client: an #EClient
1467 * @cancellable: a #GCancellable; can be %NULL
1468 * @callback: callback to call when a result is ready
1469 * @user_data: user data for the @callback
1471 * Initiates refresh on the @client. Finishing the method doesn't mean
1472 * that the refresh is done, backend only notifies whether it started
1473 * refreshing or not. Use e_client_check_refresh_supported() to check
1474 * whether the backend supports this method.
1475 * The call is finished by e_client_refresh_finish() from the @callback.
1480 e_client_refresh (EClient *client, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
1482 EClientClass *klass;
1484 g_return_if_fail (client != NULL);
1485 g_return_if_fail (E_IS_CLIENT (client));
1486 g_return_if_fail (client->priv != NULL);
1487 g_return_if_fail (callback != NULL);
1489 klass = E_CLIENT_GET_CLASS (client);
1490 g_return_if_fail (klass != NULL);
1491 g_return_if_fail (klass->refresh != NULL);
1493 klass->refresh (client, cancellable, callback, user_data);
1497 * e_client_refresh_finish:
1498 * @client: an #EClient
1499 * @result: a #GAsyncResult
1500 * @error: (out): a #GError to set an error, if any
1502 * Finishes previous call of e_client_refresh().
1504 * Returns: %TRUE if successful, %FALSE otherwise.
1509 e_client_refresh_finish (EClient *client, GAsyncResult *result, GError **error)
1511 EClientClass *klass;
1513 g_return_val_if_fail (client != NULL, FALSE);
1514 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
1515 g_return_val_if_fail (client->priv != NULL, FALSE);
1517 klass = E_CLIENT_GET_CLASS (client);
1518 g_return_val_if_fail (klass != NULL, FALSE);
1519 g_return_val_if_fail (klass->refresh_finish != NULL, FALSE);
1521 return klass->refresh_finish (client, result, error);
1525 * e_client_refresh_sync:
1526 * @client: an #EClient
1527 * @cancellable: a #GCancellable; can be %NULL
1528 * @error: (out): a #GError to set an error, if any
1530 * Initiates refresh on the @client. Finishing the method doesn't mean
1531 * that the refresh is done, backend only notifies whether it started
1532 * refreshing or not. Use e_client_check_refresh_supported() to check
1533 * whether the backend supports this method.
1535 * Returns: %TRUE if successful, %FALSE otherwise.
1540 e_client_refresh_sync (EClient *client, GCancellable *cancellable, GError **error)
1542 EClientClass *klass;
1544 klass = E_CLIENT_GET_CLASS (client);
1545 g_return_val_if_fail (klass != NULL, FALSE);
1546 g_return_val_if_fail (klass->refresh_sync != NULL, FALSE);
1548 return klass->refresh_sync (client, cancellable, error);
1552 * e_client_util_slist_to_strv:
1553 * @strings: a #GSList of strings (const gchar *)
1555 * Convert list of strings into NULL-terminates array of strings.
1557 * Returns: (transfer full): Newly allocated NULL-terminated array of strings.
1558 * Returned pointer should be freed with g_strfreev().
1560 * Note: Pair function for this is e_client_util_strv_to_slist().
1565 e_client_util_slist_to_strv (const GSList *strings)
1570 array = g_ptr_array_sized_new (g_slist_length ((GSList *) strings) + 1);
1572 for (iter = strings; iter; iter = iter->next) {
1573 const gchar *str = iter->data;
1576 g_ptr_array_add (array, g_strdup (str));
1579 /* NULL-terminated */
1580 g_ptr_array_add (array, NULL);
1582 return (gchar **) g_ptr_array_free (array, FALSE);
1586 * e_client_util_strv_to_slist:
1587 * @strv: a NULL-terminated array of strings (const gchar *)
1589 * Convert NULL-terminated array of strings to a list of strings.
1591 * Returns: (transfer full): Newly allocated #GSList of newly allocated strings.
1592 * Returned pointer should be freed with e_client_util_free_string_slist().
1594 * Note: Pair function for this is e_client_util_slist_to_strv().
1599 e_client_util_strv_to_slist (const gchar * const *strv)
1601 GSList *slist = NULL;
1607 for (ii = 0; strv[ii]; ii++) {
1608 slist = g_slist_prepend (slist, g_strdup (strv[ii]));
1611 return g_slist_reverse (slist);
1615 * e_client_util_copy_string_slist:
1616 * @copy_to: Where to copy; can be NULL
1617 * @strings: GSList of strings to be copied
1619 * Copies GSList of strings at the end of @copy_to.
1621 * Returns: (transfer full): New head of @copy_to.
1622 * Returned pointer can be freed with e_client_util_free_string_slist().
1627 e_client_util_copy_string_slist (GSList *copy_to, const GSList *strings)
1629 GSList *res = copy_to;
1632 for (iter = strings; iter; iter = iter->next) {
1633 res = g_slist_append (res, g_strdup (iter->data));
1640 * e_client_util_copy_object_slist:
1641 * @copy_to: Where to copy; can be NULL
1642 * @objects: GSList of GObject-s to be copied
1644 * Copies GSList of GObject-s at the end of @copy_to.
1646 * Returns: (transfer full): New head of @copy_to.
1647 * Returned pointer can be freed with e_client_util_free_object_slist().
1652 e_client_util_copy_object_slist (GSList *copy_to, const GSList *objects)
1654 GSList *res = copy_to;
1657 for (iter = objects; iter; iter = iter->next) {
1658 res = g_slist_append (res, g_object_ref (iter->data));
1665 * e_client_util_free_string_slist:
1666 * @strings: a #GSList of strings (gchar *)
1668 * Frees memory previously allocated by e_client_util_strv_to_slist().
1673 e_client_util_free_string_slist (GSList *strings)
1678 g_slist_foreach (strings, (GFunc) g_free, NULL);
1679 g_slist_free (strings);
1683 * e_client_util_free_object_slist:
1684 * @objects: a #GSList of #GObject-s
1686 * Calls g_object_unref() on each member of @objects and then frees
1687 * also @objects itself.
1692 e_client_util_free_object_slist (GSList *objects)
1697 g_slist_foreach (objects, (GFunc) g_object_unref, NULL);
1698 g_slist_free (objects);
1702 * e_client_util_parse_comma_strings:
1703 * @strings: string of comma-separated values
1705 * Parses comma-separated list of values into #GSList.
1707 * Returns: (transfer full): Newly allocated #GSList of newly allocated strings
1708 * corresponding to values parsed from @strings.
1709 * Free returned pointer with e_client_util_free_string_slist().
1714 e_client_util_parse_comma_strings (const gchar *strings)
1716 GSList *strs_slist = NULL;
1717 gchar **strs_strv = NULL;
1720 if (!strings || !*strings)
1723 strs_strv = g_strsplit (strings, ",", -1);
1724 g_return_val_if_fail (strs_strv != NULL, NULL);
1726 for (ii = 0; strs_strv && strs_strv[ii]; ii++) {
1727 gchar *str = g_strstrip (strs_strv[ii]);
1730 strs_slist = g_slist_prepend (strs_slist, g_strdup (str));
1733 g_strfreev (strs_strv);
1735 return g_slist_reverse (strs_slist);
1738 /* for each known source calls check_func, which should return TRUE if the required
1739 source have been found. Function returns NULL or the source on which was returned
1740 TRUE by the check_func. Non-NULL pointer should be unreffed by g_object_unref. */
1742 search_known_sources (ESourceList *sources, gboolean (*check_func)(ESource *source, gpointer user_data), gpointer user_data)
1744 ESource *res = NULL;
1747 g_return_val_if_fail (check_func != NULL, NULL);
1748 g_return_val_if_fail (sources != NULL, NULL);
1750 for (g = e_source_list_peek_groups (sources); g; g = g->next) {
1751 ESourceGroup *group = E_SOURCE_GROUP (g->data);
1754 for (s = e_source_group_peek_sources (group); s; s = s->next) {
1755 ESource *source = E_SOURCE (s->data);
1757 if (check_func (source, user_data)) {
1758 res = g_object_ref (source);
1771 check_uri (ESource *source, gpointer uri)
1777 g_return_val_if_fail (source != NULL, FALSE);
1778 g_return_val_if_fail (uri != NULL, FALSE);
1780 suri = e_source_peek_absolute_uri (source);
1783 return g_ascii_strcasecmp (suri, uri) == 0;
1785 suri2 = e_source_get_uri (source);
1786 res = suri2 && g_ascii_strcasecmp (suri2, uri) == 0;
1792 struct check_system_data
1795 ESource *uri_source;
1799 check_system (ESource *source, gpointer data)
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, ESource *source)
1872 g_return_val_if_fail (source_list != NULL, FALSE);
1873 g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), FALSE);
1874 g_return_val_if_fail (source != NULL, FALSE);
1875 g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
1877 uid = e_source_peek_uid (source);
1879 /* make sure the source is actually in the ESourceList. If
1880 it's not we don't bother adding it, just return an error */
1881 source = e_source_list_peek_source_by_uid (source_list, uid);
1885 /* loop over all the sources clearing out any "default"
1886 properties we find */
1887 for (g = e_source_list_peek_groups (source_list); g; g = g->next) {
1889 for (s = e_source_group_peek_sources (E_SOURCE_GROUP (g->data));
1891 e_source_set_property (E_SOURCE (s->data), "default", NULL);
1895 /* set the "default" property on the source */
1896 e_source_set_property (source, "default", "true");
1902 e_client_util_get_source_for_uri (ESourceList *source_list, const gchar *uri)
1906 g_return_val_if_fail (source_list != NULL, NULL);
1907 g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL);
1908 g_return_val_if_fail (uri != NULL, NULL);
1910 source = search_known_sources (source_list, check_uri, (gpointer) uri);
1912 source = e_source_new_with_absolute_uri ("", uri);
1918 e_client_finish_async_without_dbus (EClient *client, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data, gpointer source_tag, gpointer op_res, GDestroyNotify destroy_op_res)
1920 GCancellable *use_cancellable;
1921 GSimpleAsyncResult *simple;
1924 g_return_if_fail (client != NULL);
1925 g_return_if_fail (E_IS_CLIENT (client));
1926 g_return_if_fail (callback != NULL);
1927 g_return_if_fail (source_tag != NULL);
1929 use_cancellable = cancellable;
1930 if (!use_cancellable)
1931 use_cancellable = g_cancellable_new ();
1933 opid = e_client_register_op (client, use_cancellable);
1934 g_return_if_fail (opid > 0);
1936 simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, source_tag);
1937 g_simple_async_result_set_op_res_gpointer (simple, op_res, destroy_op_res);
1938 g_simple_async_result_complete_in_idle (simple);
1939 g_object_unref (simple);
1941 if (use_cancellable != cancellable)
1942 g_object_unref (use_cancellable);
1946 e_client_get_dbus_proxy (EClient *client)
1948 EClientClass *klass;
1950 g_return_val_if_fail (client != NULL, NULL);
1951 g_return_val_if_fail (E_IS_CLIENT (client), NULL);
1953 klass = E_CLIENT_GET_CLASS (client);
1954 g_return_val_if_fail (klass != NULL, NULL);
1955 g_return_val_if_fail (klass->get_dbus_proxy != NULL, NULL);
1957 return klass->get_dbus_proxy (client);
1961 * e_client_unwrap_dbus_error:
1962 * @client: an #EClient
1963 * @dbus_error: a #GError returned bu D-Bus
1964 * @out_error: a #GError variable where to store the result
1966 * Unwraps D-Bus error to local error. @dbus_error is automatically freed.
1967 * @dbus_erorr and @out_error can point to the same variable.
1970 e_client_unwrap_dbus_error (EClient *client, GError *dbus_error, GError **out_error)
1972 EClientClass *klass;
1974 g_return_if_fail (client != NULL);
1975 g_return_if_fail (E_IS_CLIENT (client));
1977 klass = E_CLIENT_GET_CLASS (client);
1978 g_return_if_fail (klass != NULL);
1979 g_return_if_fail (klass->unwrap_dbus_error != NULL);
1981 if (!dbus_error || !out_error) {
1983 g_error_free (dbus_error);
1985 klass->unwrap_dbus_error (client, dbus_error, out_error);
1990 * e_client_util_unwrap_dbus_error:
1991 * @dbus_error: DBus #GError to unwrap
1992 * @client_error: (out): Resulting #GError; can be %NULL
1993 * @known_errors: List of known errors against which try to match
1994 * @known_errors_count: How many items are stored in @known_errors
1995 * @known_errors_domain: Error domain for @known_errors
1996 * @fail_when_none_matched: Whether to fail when none of @known_errors matches
1998 * The function takes a @dbus_error and tries to find a match in @known_errors for it,
1999 * if it is a G_IO_ERROR, G_IO_ERROR_DBUS_ERROR. If it is anything else then the @dbus_error
2000 * is moved to @client_error.
2002 * The @fail_when_none_matched influences behaviour. If it's %TRUE, and none of @known_errors matches,
2003 * or this is not a G_IO_ERROR_DBUS_ERROR, then %FALSE is returned and the @client_error
2004 * is left without change. Otherwise, the @fail_when_none_matched is %FALSE, the error is always
2005 * processed and will result in E_CLIENT_ERROR, E_CLIENT_ERROR_OTHER_ERROR if none of @known_error matches.
2007 * Returns: Whether was @dbus_error processed into @client_error.
2009 * Note: The @dbus_error is automatically freed if returned %TRUE.
2012 e_client_util_unwrap_dbus_error (GError *dbus_error, GError **client_error, const EClientErrorsList *known_errors, guint known_errors_count, GQuark known_errors_domain, gboolean fail_when_none_matched)
2014 if (!client_error) {
2016 g_error_free (dbus_error);
2021 *client_error = NULL;
2025 if (dbus_error->domain == known_errors_domain) {
2026 *client_error = dbus_error;
2031 if (g_error_matches (dbus_error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR)) {
2035 name = g_dbus_error_get_remote_error (dbus_error);
2037 for (ii = 0; ii < known_errors_count; ii++) {
2038 if (g_ascii_strcasecmp (known_errors[ii].name, name) == 0) {
2041 g_dbus_error_strip_remote_error (dbus_error);
2042 *client_error = g_error_new_literal (known_errors_domain, known_errors[ii].err_code, dbus_error->message);
2043 g_error_free (dbus_error);
2052 if (fail_when_none_matched)
2055 if (g_error_matches (dbus_error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR)) {
2056 g_dbus_error_strip_remote_error (dbus_error);
2057 *client_error = g_error_new_literal (E_CLIENT_ERROR, E_CLIENT_ERROR_OTHER_ERROR, dbus_error->message);
2058 g_error_free (dbus_error);
2060 if (dbus_error->domain == G_DBUS_ERROR)
2061 g_dbus_error_strip_remote_error (dbus_error);
2062 *client_error = dbus_error;
2068 typedef struct _EClientAsyncOpData
2073 gpointer source_tag;
2074 gchar *res_op_data; /* optional string to set on a GAsyncResult object as "res-op-data" user data */
2075 GAsyncReadyCallback callback;
2078 gboolean result; /* result of the finish function call */
2080 /* only one can be non-NULL, and the type is telling which 'out' value is valid */
2081 EClientProxyFinishVoidFunc finish_void;
2082 EClientProxyFinishBooleanFunc finish_boolean;
2083 EClientProxyFinishStringFunc finish_string;
2084 EClientProxyFinishStrvFunc finish_strv;
2085 EClientProxyFinishUintFunc finish_uint;
2088 gboolean val_boolean;
2093 } EClientAsyncOpData;
2096 async_data_free (EClientAsyncOpData *async_data)
2098 g_return_if_fail (async_data != NULL);
2099 g_return_if_fail (async_data->client != NULL);
2101 e_client_unregister_op (async_data->client, async_data->opid);
2103 if (async_data->finish_string)
2104 g_free (async_data->out.val_string);
2105 else if (async_data->finish_strv)
2106 g_strfreev (async_data->out.val_strv);
2108 g_object_unref (async_data->client);
2109 g_free (async_data->res_op_data);
2110 g_free (async_data);
2114 complete_async_op_in_idle_cb (gpointer user_data)
2116 GSimpleAsyncResult *simple = user_data;
2117 gint run_main_depth;
2119 g_return_val_if_fail (simple != NULL, FALSE);
2121 run_main_depth = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (simple), "run-main-depth"));
2122 if (run_main_depth < 1)
2125 /* do not receive in higher level than was initially run */
2126 if (g_main_depth () > run_main_depth) {
2130 g_simple_async_result_complete (simple);
2131 g_object_unref (simple);
2137 finish_async_op (EClientAsyncOpData *async_data, const GError *error, gboolean in_idle)
2139 GSimpleAsyncResult *simple;
2141 g_return_if_fail (async_data != NULL);
2142 g_return_if_fail (async_data->source_tag != NULL);
2143 g_return_if_fail (async_data->client != NULL);
2145 simple = g_simple_async_result_new (G_OBJECT (async_data->client), async_data->callback, async_data->user_data, async_data->source_tag);
2146 g_simple_async_result_set_op_res_gpointer (simple, async_data, (GDestroyNotify) async_data_free);
2148 if (async_data->res_op_data)
2149 g_object_set_data_full (G_OBJECT (simple), "res-op-data", g_strdup (async_data->res_op_data), g_free);
2152 g_simple_async_result_set_from_error (simple, error);
2155 g_object_set_data (G_OBJECT (simple), "run-main-depth", GINT_TO_POINTER (g_main_depth ()));
2156 g_idle_add (complete_async_op_in_idle_cb, simple);
2158 g_simple_async_result_complete (simple);
2159 g_object_unref (simple);
2164 async_result_ready_cb (GObject *source_object, GAsyncResult *result, gpointer user_data)
2166 GError *error = NULL;
2167 EClientAsyncOpData *async_data;
2170 g_return_if_fail (result != NULL);
2171 g_return_if_fail (source_object != NULL);
2173 async_data = user_data;
2174 g_return_if_fail (async_data != NULL);
2175 g_return_if_fail (async_data->client != NULL);
2177 client = async_data->client;
2178 g_return_if_fail (e_client_get_dbus_proxy (client) == G_DBUS_PROXY (source_object));
2180 if (async_data->finish_void)
2181 async_data->result = async_data->finish_void (G_DBUS_PROXY (source_object), result, &error);
2182 else if (async_data->finish_boolean)
2183 async_data->result = async_data->finish_boolean (G_DBUS_PROXY (source_object), result, &async_data->out.val_boolean, &error);
2184 else if (async_data->finish_string)
2185 async_data->result = async_data->finish_string (G_DBUS_PROXY (source_object), result, &async_data->out.val_string, &error);
2186 else if (async_data->finish_strv)
2187 async_data->result = async_data->finish_strv (G_DBUS_PROXY (source_object), result, &async_data->out.val_strv, &error);
2188 else if (async_data->finish_uint)
2189 async_data->result = async_data->finish_uint (G_DBUS_PROXY (source_object), result, &async_data->out.val_uint, &error);
2191 g_warning ("%s: Do not know how to finish async operation", G_STRFUNC);
2193 finish_async_op (async_data, error, FALSE);
2196 g_error_free (error);
2199 static EClientAsyncOpData *
2200 prepare_async_data (EClient *client, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data, gpointer source_tag, gboolean error_report_only, EClientProxyFinishVoidFunc finish_void, EClientProxyFinishBooleanFunc finish_boolean, EClientProxyFinishStringFunc finish_string, EClientProxyFinishStrvFunc finish_strv, EClientProxyFinishUintFunc finish_uint, GDBusProxy **proxy, GCancellable **out_cancellable)
2202 EClientAsyncOpData *async_data;
2203 GCancellable *use_cancellable;
2206 g_return_val_if_fail (client != NULL, NULL);
2207 g_return_val_if_fail (callback != NULL, NULL);
2208 g_return_val_if_fail (source_tag != NULL, NULL);
2210 if (!error_report_only) {
2211 g_return_val_if_fail (proxy != NULL, NULL);
2212 g_return_val_if_fail (out_cancellable != NULL, NULL);
2213 g_return_val_if_fail (finish_void || finish_boolean || finish_string || finish_strv || finish_uint, NULL);
2216 g_return_val_if_fail (finish_boolean == NULL, NULL);
2217 g_return_val_if_fail (finish_string == NULL, NULL);
2218 g_return_val_if_fail (finish_strv == NULL, NULL);
2219 g_return_val_if_fail (finish_uint == NULL, NULL);
2222 if (finish_boolean) {
2223 g_return_val_if_fail (finish_void == NULL, NULL);
2224 g_return_val_if_fail (finish_string == NULL, NULL);
2225 g_return_val_if_fail (finish_strv == NULL, NULL);
2226 g_return_val_if_fail (finish_uint == NULL, NULL);
2229 if (finish_string) {
2230 g_return_val_if_fail (finish_void == NULL, NULL);
2231 g_return_val_if_fail (finish_boolean == NULL, NULL);
2232 g_return_val_if_fail (finish_strv == NULL, NULL);
2233 g_return_val_if_fail (finish_uint == NULL, NULL);
2237 g_return_val_if_fail (finish_void == NULL, NULL);
2238 g_return_val_if_fail (finish_boolean == NULL, NULL);
2239 g_return_val_if_fail (finish_string == NULL, NULL);
2240 g_return_val_if_fail (finish_uint == NULL, NULL);
2244 g_return_val_if_fail (finish_void == NULL, NULL);
2245 g_return_val_if_fail (finish_boolean == NULL, NULL);
2246 g_return_val_if_fail (finish_string == NULL, NULL);
2247 g_return_val_if_fail (finish_strv == NULL, NULL);
2250 *proxy = e_client_get_dbus_proxy (client);
2255 use_cancellable = cancellable;
2256 if (!use_cancellable)
2257 use_cancellable = g_cancellable_new ();
2259 opid = e_client_register_op (client, use_cancellable);
2260 async_data = g_new0 (EClientAsyncOpData, 1);
2261 async_data->client = g_object_ref (client);
2262 async_data->opid = opid;
2263 async_data->source_tag = source_tag;
2264 async_data->callback = callback;
2265 async_data->user_data = user_data;
2266 async_data->finish_void = finish_void;
2267 async_data->finish_boolean = finish_boolean;
2268 async_data->finish_string = finish_string;
2269 async_data->finish_strv = finish_strv;
2270 async_data->finish_uint = finish_uint;
2272 /* EClient from e_client_register_op() took ownership of the use_cancellable */
2273 if (use_cancellable != cancellable)
2274 g_object_unref (use_cancellable);
2276 if (out_cancellable)
2277 *out_cancellable = use_cancellable;
2283 e_client_proxy_return_async_error (EClient *client, const GError *error, GAsyncReadyCallback callback, gpointer user_data, gpointer source_tag)
2285 EClientAsyncOpData *async_data;
2287 g_return_if_fail (client != NULL);
2288 g_return_if_fail (E_IS_CLIENT (client));
2289 g_return_if_fail (error != NULL);
2290 g_return_if_fail (callback != NULL);
2292 async_data = prepare_async_data (client, NULL, callback, user_data, source_tag, TRUE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
2293 g_return_if_fail (async_data != NULL);
2295 finish_async_op (async_data, error, TRUE);
2299 e_client_proxy_call_void (EClient *client, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data, gpointer source_tag, void (*func) (GDBusProxy *proxy, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data), EClientProxyFinishVoidFunc finish_void, EClientProxyFinishBooleanFunc finish_boolean, EClientProxyFinishStringFunc finish_string, EClientProxyFinishStrvFunc finish_strv, EClientProxyFinishUintFunc finish_uint)
2301 EClientAsyncOpData *async_data;
2302 GDBusProxy *proxy = NULL;
2304 g_return_if_fail (client != NULL);
2305 g_return_if_fail (E_IS_CLIENT (client));
2306 g_return_if_fail (callback != NULL);
2307 g_return_if_fail (source_tag != NULL);
2308 e_client_return_async_if_fail (func != NULL, client, callback, user_data, source_tag);
2310 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);
2311 e_client_return_async_if_fail (async_data != NULL, client, callback, user_data, source_tag);
2313 func (proxy, cancellable, async_result_ready_cb, async_data);
2317 e_client_proxy_call_boolean (EClient *client, gboolean in_boolean, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data, gpointer source_tag, void (*func) (GDBusProxy *proxy, gboolean in_boolean, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data), EClientProxyFinishVoidFunc finish_void, EClientProxyFinishBooleanFunc finish_boolean, EClientProxyFinishStringFunc finish_string, EClientProxyFinishStrvFunc finish_strv, EClientProxyFinishUintFunc finish_uint)
2319 EClientAsyncOpData *async_data;
2320 GDBusProxy *proxy = NULL;
2322 g_return_if_fail (client != NULL);
2323 g_return_if_fail (E_IS_CLIENT (client));
2324 g_return_if_fail (callback != NULL);
2325 g_return_if_fail (source_tag != NULL);
2326 e_client_return_async_if_fail (func != NULL, client, callback, user_data, source_tag);
2328 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);
2329 e_client_return_async_if_fail (async_data != NULL, client, callback, user_data, source_tag);
2331 func (proxy, in_boolean, cancellable, async_result_ready_cb, async_data);
2335 e_client_proxy_call_string (EClient *client, const gchar *in_string, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data, gpointer source_tag, void (*func) (GDBusProxy *proxy, const gchar * in_string, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data), EClientProxyFinishVoidFunc finish_void, EClientProxyFinishBooleanFunc finish_boolean, EClientProxyFinishStringFunc finish_string, EClientProxyFinishStrvFunc finish_strv, EClientProxyFinishUintFunc finish_uint)
2337 EClientAsyncOpData *async_data;
2338 GDBusProxy *proxy = NULL;
2340 g_return_if_fail (client != NULL);
2341 g_return_if_fail (E_IS_CLIENT (client));
2342 g_return_if_fail (callback != NULL);
2343 g_return_if_fail (source_tag != NULL);
2344 e_client_return_async_if_fail (func != NULL, client, callback, user_data, source_tag);
2345 e_client_return_async_if_fail (in_string != NULL, client, callback, user_data, source_tag);
2347 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);
2348 e_client_return_async_if_fail (async_data != NULL, client, callback, user_data, source_tag);
2350 func (proxy, in_string, cancellable, async_result_ready_cb, async_data);
2354 e_client_proxy_call_string_with_res_op_data (EClient *client, const gchar *in_string, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data, gpointer source_tag, const gchar *res_op_data, void (*func) (GDBusProxy *proxy, const gchar * in_string, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data), EClientProxyFinishVoidFunc finish_void, EClientProxyFinishBooleanFunc finish_boolean, EClientProxyFinishStringFunc finish_string, EClientProxyFinishStrvFunc finish_strv, EClientProxyFinishUintFunc finish_uint)
2356 EClientAsyncOpData *async_data;
2357 GDBusProxy *proxy = NULL;
2359 g_return_if_fail (client != NULL);
2360 g_return_if_fail (E_IS_CLIENT (client));
2361 g_return_if_fail (callback != NULL);
2362 g_return_if_fail (source_tag != NULL);
2363 e_client_return_async_if_fail (func != NULL, client, callback, user_data, source_tag);
2364 e_client_return_async_if_fail (in_string != NULL, client, callback, user_data, source_tag);
2366 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);
2367 e_client_return_async_if_fail (async_data != NULL, client, callback, user_data, source_tag);
2369 async_data->res_op_data = g_strdup (res_op_data);
2371 func (proxy, in_string, cancellable, async_result_ready_cb, async_data);
2375 e_client_proxy_call_strv (EClient *client, const gchar * const *in_strv, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data, gpointer source_tag, void (*func) (GDBusProxy *proxy, const gchar * const * in_strv, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data), EClientProxyFinishVoidFunc finish_void, EClientProxyFinishBooleanFunc finish_boolean, EClientProxyFinishStringFunc finish_string, EClientProxyFinishStrvFunc finish_strv, EClientProxyFinishUintFunc finish_uint)
2377 EClientAsyncOpData *async_data;
2378 GDBusProxy *proxy = NULL;
2380 g_return_if_fail (client != NULL);
2381 g_return_if_fail (E_IS_CLIENT (client));
2382 g_return_if_fail (callback != NULL);
2383 g_return_if_fail (source_tag != NULL);
2384 e_client_return_async_if_fail (func != NULL, client, callback, user_data, source_tag);
2385 e_client_return_async_if_fail (in_strv != NULL, client, callback, user_data, source_tag);
2387 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);
2388 e_client_return_async_if_fail (async_data != NULL, client, callback, user_data, source_tag);
2390 func (proxy, in_strv, cancellable, async_result_ready_cb, async_data);
2394 e_client_proxy_call_uint (EClient *client, guint in_uint, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data, gpointer source_tag, void (*func) (GDBusProxy *proxy, guint in_uint, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data), EClientProxyFinishVoidFunc finish_void, EClientProxyFinishBooleanFunc finish_boolean, EClientProxyFinishStringFunc finish_string, EClientProxyFinishStrvFunc finish_strv, EClientProxyFinishUintFunc finish_uint)
2396 EClientAsyncOpData *async_data;
2397 GDBusProxy *proxy = NULL;
2399 g_return_if_fail (client != NULL);
2400 g_return_if_fail (E_IS_CLIENT (client));
2401 g_return_if_fail (callback != NULL);
2402 g_return_if_fail (source_tag != NULL);
2403 e_client_return_async_if_fail (func != NULL, client, callback, user_data, source_tag);
2405 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);
2406 e_client_return_async_if_fail (async_data != NULL, client, callback, user_data, source_tag);
2408 func (proxy, in_uint, cancellable, async_result_ready_cb, async_data);
2412 e_client_proxy_call_finish_void (EClient *client, GAsyncResult *result, GError **error, gpointer source_tag)
2414 GSimpleAsyncResult *simple;
2415 GError *local_error = NULL;
2416 EClientAsyncOpData *async_data;
2418 g_return_val_if_fail (client != NULL, FALSE);
2419 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
2420 g_return_val_if_fail (result != NULL, FALSE);
2421 g_return_val_if_fail (source_tag != NULL, FALSE);
2422 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), source_tag), FALSE);
2424 simple = G_SIMPLE_ASYNC_RESULT (result);
2426 if (g_simple_async_result_propagate_error (simple, &local_error)) {
2427 e_client_unwrap_dbus_error (client, local_error, error);
2431 async_data = g_simple_async_result_get_op_res_gpointer (simple);
2432 g_return_val_if_fail (async_data != NULL, FALSE);
2434 return async_data->result;
2438 e_client_proxy_call_finish_boolean (EClient *client, GAsyncResult *result, gboolean *out_boolean, GError **error, gpointer source_tag)
2440 GSimpleAsyncResult *simple;
2441 GError *local_error = NULL;
2442 EClientAsyncOpData *async_data;
2444 g_return_val_if_fail (client != NULL, FALSE);
2445 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
2446 g_return_val_if_fail (result != NULL, FALSE);
2447 g_return_val_if_fail (source_tag != NULL, FALSE);
2448 g_return_val_if_fail (out_boolean != NULL, FALSE);
2449 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), source_tag), FALSE);
2451 simple = G_SIMPLE_ASYNC_RESULT (result);
2453 if (g_simple_async_result_propagate_error (simple, &local_error)) {
2454 e_client_unwrap_dbus_error (client, local_error, error);
2458 async_data = g_simple_async_result_get_op_res_gpointer (simple);
2459 g_return_val_if_fail (async_data != NULL, FALSE);
2461 *out_boolean = async_data->out.val_boolean;
2463 return async_data->result;
2467 e_client_proxy_call_finish_string (EClient *client, GAsyncResult *result, gchar **out_string, GError **error, gpointer source_tag)
2469 GSimpleAsyncResult *simple;
2470 GError *local_error = NULL;
2471 EClientAsyncOpData *async_data;
2473 g_return_val_if_fail (client != NULL, FALSE);
2474 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
2475 g_return_val_if_fail (result != NULL, FALSE);
2476 g_return_val_if_fail (source_tag != NULL, FALSE);
2477 g_return_val_if_fail (out_string != NULL, FALSE);
2478 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), source_tag), FALSE);
2480 simple = G_SIMPLE_ASYNC_RESULT (result);
2482 if (g_simple_async_result_propagate_error (simple, &local_error)) {
2483 e_client_unwrap_dbus_error (client, local_error, error);
2487 async_data = g_simple_async_result_get_op_res_gpointer (simple);
2488 g_return_val_if_fail (async_data != NULL, FALSE);
2490 *out_string = async_data->out.val_string;
2491 async_data->out.val_string = NULL;
2493 return async_data->result;
2497 e_client_proxy_call_finish_strv (EClient *client, GAsyncResult *result, gchar ***out_strv, GError **error, gpointer source_tag)
2499 GSimpleAsyncResult *simple;
2500 GError *local_error = NULL;
2501 EClientAsyncOpData *async_data;
2503 g_return_val_if_fail (client != NULL, FALSE);
2504 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
2505 g_return_val_if_fail (result != NULL, FALSE);
2506 g_return_val_if_fail (source_tag != NULL, FALSE);
2507 g_return_val_if_fail (out_strv != NULL, FALSE);
2508 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), source_tag), FALSE);
2510 simple = G_SIMPLE_ASYNC_RESULT (result);
2512 if (g_simple_async_result_propagate_error (simple, &local_error)) {
2513 e_client_unwrap_dbus_error (client, local_error, error);
2517 async_data = g_simple_async_result_get_op_res_gpointer (simple);
2518 g_return_val_if_fail (async_data != NULL, FALSE);
2520 *out_strv = async_data->out.val_strv;
2521 async_data->out.val_strv = NULL;
2523 return async_data->result;
2527 e_client_proxy_call_finish_uint (EClient *client, GAsyncResult *result, guint *out_uint, GError **error, gpointer source_tag)
2529 GSimpleAsyncResult *simple;
2530 GError *local_error = NULL;
2531 EClientAsyncOpData *async_data;
2533 g_return_val_if_fail (client != NULL, FALSE);
2534 g_return_val_if_fail (E_IS_CLIENT (client), FALSE);
2535 g_return_val_if_fail (result != NULL, FALSE);
2536 g_return_val_if_fail (source_tag != NULL, FALSE);
2537 g_return_val_if_fail (out_uint != NULL, FALSE);
2538 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), source_tag), FALSE);
2540 simple = G_SIMPLE_ASYNC_RESULT (result);
2542 if (g_simple_async_result_propagate_error (simple, &local_error)) {
2543 e_client_unwrap_dbus_error (client, local_error, error);
2547 async_data = g_simple_async_result_get_op_res_gpointer (simple);
2548 g_return_val_if_fail (async_data != NULL, FALSE);
2550 *out_uint = async_data->out.val_uint;
2552 return async_data->result;
2555 #define SYNC_CALL_TEMPLATE(_out_test,_the_call) \
2556 GDBusProxy *proxy; \
2557 GCancellable *use_cancellable; \
2560 GError *local_error = NULL; \
2562 g_return_val_if_fail (client != NULL, FALSE); \
2563 g_return_val_if_fail (E_IS_CLIENT (client), FALSE); \
2564 g_return_val_if_fail (func != NULL, FALSE); \
2565 g_return_val_if_fail (_out_test != NULL, FALSE); \
2567 proxy = e_client_get_dbus_proxy (client); \
2568 g_return_val_if_fail (proxy != NULL, FALSE); \
2570 use_cancellable = cancellable; \
2571 if (!use_cancellable) \
2572 use_cancellable = g_cancellable_new (); \
2574 g_object_ref (client); \
2575 opid = e_client_register_op (client, use_cancellable); \
2577 result = func _the_call; \
2579 e_client_unregister_op (client, opid); \
2580 g_object_unref (client); \
2582 if (use_cancellable != cancellable) \
2583 g_object_unref (use_cancellable); \
2585 e_client_unwrap_dbus_error (client, local_error, error);\
2590 e_client_proxy_call_sync_void__void (EClient *client, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, GCancellable *cancellable, GError **error))
2592 SYNC_CALL_TEMPLATE (client, (proxy, use_cancellable, &local_error))
2596 e_client_proxy_call_sync_void__boolean (EClient *client, gboolean *out_boolean, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, gboolean *out_boolean, GCancellable *cancellable, GError **error))
2598 SYNC_CALL_TEMPLATE (out_boolean, (proxy, out_boolean, use_cancellable, &local_error))
2602 e_client_proxy_call_sync_void__string (EClient *client, gchar **out_string, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, gchar **out_string, GCancellable *cancellable, GError **error))
2604 SYNC_CALL_TEMPLATE (out_string, (proxy, out_string, use_cancellable, &local_error))
2608 e_client_proxy_call_sync_void__strv (EClient *client, gchar ***out_strv, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, gchar ***out_strv, GCancellable *cancellable, GError **error))
2610 SYNC_CALL_TEMPLATE (out_strv, (proxy, out_strv, use_cancellable, &local_error))
2614 e_client_proxy_call_sync_void__uint (EClient *client, guint *out_uint, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, guint *out_uint, GCancellable *cancellable, GError **error))
2616 SYNC_CALL_TEMPLATE (out_uint, (proxy, out_uint, use_cancellable, &local_error))
2620 e_client_proxy_call_sync_boolean__void (EClient *client, gboolean in_boolean, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, gboolean in_boolean, GCancellable *cancellable, GError **error))
2622 SYNC_CALL_TEMPLATE (client, (proxy, in_boolean, use_cancellable, &local_error))
2626 e_client_proxy_call_sync_boolean__boolean (EClient *client, gboolean in_boolean, gboolean *out_boolean, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, gboolean in_boolean, gboolean *out_boolean, GCancellable *cancellable, GError **error))
2628 SYNC_CALL_TEMPLATE (out_boolean, (proxy, in_boolean, out_boolean, use_cancellable, &local_error))
2632 e_client_proxy_call_sync_boolean__string (EClient *client, gboolean in_boolean, gchar **out_string, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, gboolean in_boolean, gchar **out_string, GCancellable *cancellable, GError **error))
2634 SYNC_CALL_TEMPLATE (out_string, (proxy, in_boolean, out_string, use_cancellable, &local_error))
2638 e_client_proxy_call_sync_boolean__strv (EClient *client, gboolean in_boolean, gchar ***out_strv, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, gboolean in_boolean, gchar ***out_strv, GCancellable *cancellable, GError **error))
2640 SYNC_CALL_TEMPLATE (out_strv, (proxy, in_boolean, out_strv, use_cancellable, &local_error))
2644 e_client_proxy_call_sync_boolean__uint (EClient *client, gboolean in_boolean, guint *out_uint, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, gboolean in_boolean, guint *out_uint, GCancellable *cancellable, GError **error))
2646 SYNC_CALL_TEMPLATE (out_uint, (proxy, in_boolean, out_uint, use_cancellable, &local_error))
2650 e_client_proxy_call_sync_string__void (EClient *client, const gchar *in_string, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, const gchar *in_string, GCancellable *cancellable, GError **error))
2652 SYNC_CALL_TEMPLATE (client, (proxy, in_string, use_cancellable, &local_error))
2656 e_client_proxy_call_sync_string__boolean (EClient *client, const gchar *in_string, gboolean *out_boolean, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, const gchar *in_string, gboolean *out_boolean, GCancellable *cancellable, GError **error))
2658 SYNC_CALL_TEMPLATE (out_boolean, (proxy, in_string, out_boolean, use_cancellable, &local_error))
2662 e_client_proxy_call_sync_string__string (EClient *client, const gchar *in_string, gchar **out_string, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, const gchar *in_string, gchar **out_string, GCancellable *cancellable, GError **error))
2664 SYNC_CALL_TEMPLATE (out_string, (proxy, in_string, out_string, use_cancellable, &local_error))
2668 e_client_proxy_call_sync_string__strv (EClient *client, const gchar *in_string, gchar ***out_strv, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, const gchar *in_string, gchar ***out_strv, GCancellable *cancellable, GError **error))
2670 SYNC_CALL_TEMPLATE (out_strv, (proxy, in_string, out_strv, use_cancellable, &local_error))
2674 e_client_proxy_call_sync_string__uint (EClient *client, const gchar *in_string, guint *out_uint, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, const gchar *in_string, guint *out_uint, GCancellable *cancellable, GError **error))
2676 SYNC_CALL_TEMPLATE (out_uint, (proxy, in_string, out_uint, use_cancellable, &local_error))
2680 e_client_proxy_call_sync_strv__void (EClient *client, const gchar * const *in_strv, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, const gchar * const *in_strv, GCancellable *cancellable, GError **error))
2682 SYNC_CALL_TEMPLATE (client, (proxy, in_strv, use_cancellable, &local_error))
2686 e_client_proxy_call_sync_strv__boolean (EClient *client, const gchar * const *in_strv, gboolean *out_boolean, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, const gchar * const *in_strv, gboolean *out_boolean, GCancellable *cancellable, GError **error))
2688 SYNC_CALL_TEMPLATE (out_boolean, (proxy, in_strv, out_boolean, use_cancellable, &local_error))
2692 e_client_proxy_call_sync_strv__string (EClient *client, const gchar * const *in_strv, gchar **out_string, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, const gchar * const *in_strv, gchar **out_string, GCancellable *cancellable, GError **error))
2694 SYNC_CALL_TEMPLATE (out_string, (proxy, in_strv, out_string, use_cancellable, &local_error))
2698 e_client_proxy_call_sync_strv__strv (EClient *client, const gchar * const *in_strv, gchar ***out_strv, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, const gchar * const *in_strv, gchar ***out_strv, GCancellable *cancellable, GError **error))
2700 SYNC_CALL_TEMPLATE (out_strv, (proxy, in_strv, out_strv, use_cancellable, &local_error))
2704 e_client_proxy_call_sync_strv__uint (EClient *client, const gchar * const *in_strv, guint *out_uint, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, const gchar * const *in_strv, guint *out_uint, GCancellable *cancellable, GError **error))
2706 SYNC_CALL_TEMPLATE (out_uint, (proxy, in_strv, out_uint, use_cancellable, &local_error))
2710 e_client_proxy_call_sync_uint__void (EClient *client, guint in_uint, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, guint in_uint, GCancellable *cancellable, GError **error))
2712 SYNC_CALL_TEMPLATE (client, (proxy, in_uint, use_cancellable, &local_error))
2716 e_client_proxy_call_sync_uint__boolean (EClient *client, guint in_uint, gboolean *out_boolean, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, guint in_uint, gboolean *out_boolean, GCancellable *cancellable, GError **error))
2718 SYNC_CALL_TEMPLATE (out_boolean, (proxy, in_uint, out_boolean, use_cancellable, &local_error))
2722 e_client_proxy_call_sync_uint__string (EClient *client, guint in_uint, gchar **out_string, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, guint in_uint, gchar **out_string, GCancellable *cancellable, GError **error))
2724 SYNC_CALL_TEMPLATE (out_string, (proxy, in_uint, out_string, use_cancellable, &local_error))
2728 e_client_proxy_call_sync_uint__strv (EClient *client, guint in_uint, gchar ***out_strv, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, guint in_uint, gchar ***out_strv, GCancellable *cancellable, GError **error))
2730 SYNC_CALL_TEMPLATE (out_strv, (proxy, in_uint, out_strv, use_cancellable, &local_error))
2734 e_client_proxy_call_sync_uint__uint (EClient *client, guint in_uint, guint *out_uint, GCancellable *cancellable, GError **error, gboolean (*func) (GDBusProxy *proxy, guint in_uint, guint *out_uint, GCancellable *cancellable, GError **error))
2736 SYNC_CALL_TEMPLATE (out_uint, (proxy, in_uint, out_uint, use_cancellable, &local_error))
2739 #undef SYNC_CALL_TEMPLATE