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/>
21 * @include: libedataserver/e-source.h
22 * @short_description: Hierarchical data sources
24 * An #ESource (or "data source") is a description of a file or network
25 * location where data can be obtained (such as a mail account), or a
26 * description of a resource at that location (such as a mail folder).
28 * In more concrete terms, it's an interface for a key file. All such
29 * key files have a main group named [Data Source]. The keys in a
30 * [Data Source] group map to #GObject properties in an #ESource.
32 * Additional groups in the key file are referred to as "extensions".
33 * #ESourceExtension serves as the base class for writing interfaces
34 * for these additional key file groups. The keys in one of these
35 * key file groups map to #GObject properties in some custom subclass
36 * of #ESourceExtension which was written specifically for that key
37 * file group. For example, a key file might include a group named
38 * [Calendar], whose keys map to #GObject properties in an extension
39 * class named #ESourceCalendar.
41 * Each #ESource contains an internal dictionary of extension objects,
42 * accessible by their key file group name. e_source_get_extension()
43 * can look up extension objects by name.
45 * An #ESource is identified by a unique identifier string, or "UID",
46 * which is also the basename of the corresponding key file. Additional
47 * files related to the #ESource, such as cache files, are usually kept
48 * in a directory named after the UID of the #ESource. Similarly, the
49 * password for an account described by an #ESource is kept in GNOME
50 * Keyring under the UID of the #ESource. This makes finding these
51 * additional resources simple.
53 * Several extensions for common information such as authentication
54 * details are built into libedataserver (#ESourceAuthentication, for
55 * example). Backend modules may also define their own extensions for
56 * information and settings unique to the backend. #ESourceExtension
57 * subclasses written for specific backends are generally not available
58 * to applications and shared libraries. This is by design, to try and
59 * keep backend-specific knowledge from creeping into places it doesn't
67 #include <glib/gi18n-lib.h>
69 /* Private D-Bus classes. */
70 #include <e-dbus-source.h>
72 #include "e-data-server-util.h"
73 #include "e-source-extension.h"
76 /* built-in extension types */
77 #include "e-source-address-book.h"
78 #include "e-source-alarms.h"
79 #include "e-source-authentication.h"
80 #include "e-source-autocomplete.h"
81 #include "e-source-calendar.h"
82 #include "e-source-camel.h"
83 #include "e-source-collection.h"
84 #include "e-source-goa.h"
85 #include "e-source-mail-account.h"
86 #include "e-source-mail-composition.h"
87 #include "e-source-mail-identity.h"
88 #include "e-source-mail-signature.h"
89 #include "e-source-mail-submission.h"
90 #include "e-source-mail-transport.h"
91 #include "e-source-mdn.h"
92 #include "e-source-offline.h"
93 #include "e-source-openpgp.h"
94 #include "e-source-refresh.h"
95 #include "e-source-security.h"
96 #include "e-source-selectable.h"
97 #include "e-source-smime.h"
98 #include "e-source-webdav.h"
100 #define E_SOURCE_GET_PRIVATE(obj) \
101 (G_TYPE_INSTANCE_GET_PRIVATE \
102 ((obj), E_TYPE_SOURCE, ESourcePrivate))
104 /* This forces the GType to be registered in a way that
105 * avoids a "statement with no effect" compiler warning. */
106 #define REGISTER_TYPE(type) \
107 (g_type_class_unref (g_type_class_ref (type)))
109 #define PRIMARY_GROUP_NAME "Data Source"
111 struct _ESourcePrivate {
112 GDBusObject *dbus_object;
113 GMainContext *main_context;
116 GMutex *changed_lock;
118 GMutex *property_lock;
123 /* The lock guards the key file and hash table. */
126 GStaticRecMutex lock;
127 GHashTable *extensions;
149 static guint signals[LAST_SIGNAL];
151 /* Forward Declarations */
152 static void e_source_initable_init (GInitableIface *interface);
154 G_DEFINE_TYPE_WITH_CODE (
158 G_IMPLEMENT_INTERFACE (
160 e_source_initable_init))
163 source_find_extension_classes_rec (GType parent_type,
164 GHashTable *hash_table)
167 guint n_children, ii;
169 children = g_type_children (parent_type, &n_children);
171 for (ii = 0; ii < n_children; ii++) {
172 GType type = children[ii];
173 ESourceExtensionClass *class;
176 /* Recurse over the child's children. */
177 source_find_extension_classes_rec (type, hash_table);
179 /* Skip abstract types. */
180 if (G_TYPE_IS_ABSTRACT (type))
183 class = g_type_class_ref (type);
184 key = (gpointer) class->name;
187 g_hash_table_insert (hash_table, key, class);
189 g_type_class_unref (class);
196 source_find_extension_classes (void)
198 GHashTable *hash_table;
200 hash_table = g_hash_table_new_full (
201 (GHashFunc) g_str_hash,
202 (GEqualFunc) g_str_equal,
203 (GDestroyNotify) NULL,
204 (GDestroyNotify) g_type_class_unref);
206 source_find_extension_classes_rec (
207 E_TYPE_SOURCE_EXTENSION, hash_table);
213 source_localized_hack (GKeyFile *key_file,
214 const gchar *group_name,
216 const gchar *new_value)
218 const gchar * const *language_names;
219 gchar *localized_key;
221 /* XXX If we're changing a string key that has translations,
222 * set both "key" and "key[$CURRENT_LOCALE]" to the new
223 * value so g_key_file_get_locale_string() will pick it
224 * up. This is not a perfect solution however. When a
225 * different locale is used the value may revert to its
226 * original localized string. Good enough for now. */
228 language_names = g_get_language_names ();
229 localized_key = g_strdup_printf ("%s[%s]", key, language_names[0]);
231 if (g_key_file_has_key (key_file, group_name, localized_key, NULL))
232 g_key_file_set_string (
233 key_file, group_name, localized_key, new_value);
235 g_free (localized_key);
239 source_set_key_file_from_property (GObject *object,
242 const gchar *group_name)
248 pvalue = g_slice_new0 (GValue);
249 g_value_init (pvalue, pspec->value_type);
250 g_object_get_property (object, pspec->name, pvalue);
252 svalue = g_slice_new0 (GValue);
253 g_value_init (svalue, G_TYPE_STRING);
255 key = e_source_parameter_to_key (pspec->name);
257 /* For the most part we can just transform any supported
258 * property type to a string, with a couple exceptions. */
260 /* Transforming a boolean GValue to a string results in
261 * "TRUE" or "FALSE" (all uppercase), but GKeyFile only
262 * recognizes "true" or "false" (all lowercase). So we
263 * have to use g_key_file_set_boolean(). */
264 if (G_VALUE_HOLDS_BOOLEAN (pvalue)) {
265 gboolean v_boolean = g_value_get_boolean (pvalue);
266 g_key_file_set_boolean (key_file, group_name, key, v_boolean);
268 /* String GValues may contain characters that need escaping. */
269 } else if (G_VALUE_HOLDS_STRING (pvalue)) {
270 const gchar *v_string = g_value_get_string (pvalue);
272 if (v_string == NULL)
275 /* Special case for localized "DisplayName" keys. */
276 source_localized_hack (key_file, group_name, key, v_string);
277 g_key_file_set_string (key_file, group_name, key, v_string);
279 /* Transforming an enum GValue to a string results in
280 * the GEnumValue name. We want the shorter nickname. */
281 } else if (G_VALUE_HOLDS_ENUM (pvalue)) {
282 GParamSpecEnum *enum_pspec;
283 GEnumClass *enum_class;
284 GEnumValue *enum_value;
287 enum_pspec = G_PARAM_SPEC_ENUM (pspec);
288 enum_class = enum_pspec->enum_class;
290 value = g_value_get_enum (pvalue);
291 enum_value = g_enum_get_value (enum_class, value);
293 if (enum_value == NULL) {
294 value = enum_pspec->default_value;
295 enum_value = g_enum_get_value (enum_class, value);
298 if (enum_value != NULL)
299 g_key_file_set_string (
300 key_file, group_name, key,
301 enum_value->value_nick);
303 } else if (G_VALUE_HOLDS (pvalue, G_TYPE_STRV)) {
304 const gchar **strv = g_value_get_boxed (pvalue);
308 length = g_strv_length ((gchar **) strv);
309 g_key_file_set_string_list (
310 key_file, group_name, key, strv, length);
312 /* For GValues holding a GFile object we save the URI. */
313 } else if (G_VALUE_HOLDS (pvalue, G_TYPE_FILE)) {
314 GFile *file = g_value_get_object (pvalue);
318 uri = g_file_get_uri (file);
319 g_key_file_set_string (
320 key_file, group_name, key,
321 (uri != NULL) ? uri : "");
324 } else if (g_value_transform (pvalue, svalue)) {
325 const gchar *value = g_value_get_string (svalue);
326 g_key_file_set_value (key_file, group_name, key, value);
330 g_value_unset (pvalue);
331 g_value_unset (svalue);
332 g_slice_free (GValue, pvalue);
333 g_slice_free (GValue, svalue);
337 source_set_property_from_key_file (GObject *object,
340 const gchar *group_name)
344 GError *error = NULL;
346 value = g_slice_new0 (GValue);
347 key = e_source_parameter_to_key (pspec->name);
349 if (G_IS_PARAM_SPEC_CHAR (pspec) ||
350 G_IS_PARAM_SPEC_UCHAR (pspec) ||
351 G_IS_PARAM_SPEC_INT (pspec) ||
352 G_IS_PARAM_SPEC_UINT (pspec) ||
353 G_IS_PARAM_SPEC_LONG (pspec) ||
354 G_IS_PARAM_SPEC_ULONG (pspec)) {
357 v_int = g_key_file_get_integer (
358 key_file, group_name, key, &error);
360 g_value_init (value, G_TYPE_INT);
361 g_value_set_int (value, v_int);
364 } else if (G_IS_PARAM_SPEC_BOOLEAN (pspec)) {
367 v_boolean = g_key_file_get_boolean (
368 key_file, group_name, key, &error);
370 g_value_init (value, G_TYPE_BOOLEAN);
371 g_value_set_boolean (value, v_boolean);
374 } else if (G_IS_PARAM_SPEC_ENUM (pspec)) {
377 nick = g_key_file_get_string (
378 key_file, group_name, key, &error);
380 GParamSpecEnum *enum_pspec;
381 GEnumValue *enum_value;
383 enum_pspec = G_PARAM_SPEC_ENUM (pspec);
384 enum_value = g_enum_get_value_by_nick (
385 enum_pspec->enum_class, nick);
386 if (enum_value != NULL) {
387 g_value_init (value, pspec->value_type);
388 g_value_set_enum (value, enum_value->value);
393 } else if (G_IS_PARAM_SPEC_FLOAT (pspec) ||
394 G_IS_PARAM_SPEC_DOUBLE (pspec)) {
397 v_double = g_key_file_get_double (
398 key_file, group_name, key, &error);
400 g_value_init (value, G_TYPE_DOUBLE);
401 g_value_set_double (value, v_double);
404 } else if (G_IS_PARAM_SPEC_STRING (pspec)) {
407 /* Get the localized string if present. */
408 v_string = g_key_file_get_locale_string (
409 key_file, group_name, key, NULL, &error);
411 g_value_init (value, G_TYPE_STRING);
412 g_value_take_string (value, v_string);
415 } else if (g_type_is_a (pspec->value_type, G_TYPE_STRV)) {
418 strv = g_key_file_get_string_list (
419 key_file, group_name, key, NULL, &error);
421 g_value_init (value, G_TYPE_STRV);
422 g_value_take_boxed (value, strv);
425 } else if (g_type_is_a (pspec->value_type, G_TYPE_FILE)) {
428 /* Create the GFile from the URI string. */
429 uri = g_key_file_get_locale_string (
430 key_file, group_name, key, NULL, &error);
433 if (uri != NULL && *uri != '\0')
434 file = g_file_new_for_uri (uri);
435 g_value_init (value, pspec->value_type);
436 g_value_take_object (value, file);
442 "No GKeyFile-to-GValue converter defined "
443 "for type '%s'", G_VALUE_TYPE_NAME (value));
446 /* If a value could not be retrieved from the key
447 * file, restore the property to its default value. */
449 g_value_init (value, pspec->value_type);
450 g_param_value_set_default (pspec, value);
451 g_error_free (error);
454 if (G_IS_VALUE (value)) {
455 g_object_set_property (object, pspec->name, value);
456 g_value_unset (value);
459 g_slice_free (GValue, value);
464 source_load_from_key_file (GObject *object,
466 const gchar *group_name)
469 GParamSpec **properties;
470 guint n_properties, ii;
472 class = G_OBJECT_GET_CLASS (object);
473 properties = g_object_class_list_properties (class, &n_properties);
475 g_object_freeze_notify (object);
477 for (ii = 0; ii < n_properties; ii++) {
478 if (properties[ii]->flags & E_SOURCE_PARAM_SETTING) {
479 source_set_property_from_key_file (
480 object, properties[ii], key_file, group_name);
484 g_object_thaw_notify (object);
490 source_save_to_key_file (GObject *object,
492 const gchar *group_name)
495 GParamSpec **properties;
496 guint n_properties, ii;
498 class = G_OBJECT_GET_CLASS (object);
499 properties = g_object_class_list_properties (class, &n_properties);
501 for (ii = 0; ii < n_properties; ii++) {
502 if (properties[ii]->flags & E_SOURCE_PARAM_SETTING) {
503 source_set_key_file_from_property (
504 object, properties[ii], key_file, group_name);
512 source_parse_dbus_data (ESource *source,
516 EDBusObject *dbus_object;
517 EDBusSource *dbus_source;
524 dbus_object = E_DBUS_OBJECT (source->priv->dbus_object);
526 dbus_source = e_dbus_object_get_source (dbus_object);
527 data = e_dbus_source_dup_data (dbus_source);
528 g_object_unref (dbus_source);
530 g_return_val_if_fail (data != NULL, FALSE);
532 key_file = source->priv->key_file;
534 success = g_key_file_load_from_data (
535 key_file, data, strlen (data),
536 G_KEY_FILE_KEEP_COMMENTS |
537 G_KEY_FILE_KEEP_TRANSLATIONS,
546 /* Make sure the key file has a [Data Source] group. */
547 if (!g_key_file_has_group (key_file, PRIMARY_GROUP_NAME)) {
549 error, G_KEY_FILE_ERROR,
550 G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
551 _("Source file is missing a [%s] group"),
556 /* Load key file values from the [Data Source] group and from
557 * any other groups for which an extension object has already
558 * been created. Note that not all the extension classes may
559 * be registered at this point, so avoid attempting to create
560 * new extension objects here. Extension objects are created
561 * on-demand in e_source_get_extension(). */
563 source_load_from_key_file (
564 G_OBJECT (source), key_file, PRIMARY_GROUP_NAME);
566 g_hash_table_iter_init (&iter, source->priv->extensions);
567 while (g_hash_table_iter_next (&iter, &group_name, &extension))
568 source_load_from_key_file (extension, key_file, group_name);
574 source_notify_dbus_data_cb (EDBusSource *dbus_source,
578 GError *error = NULL;
580 g_static_rec_mutex_lock (&source->priv->lock);
582 /* Since the source data came from a GKeyFile structure on the
583 * server-side, this should never fail. But we'll print error
584 * messages to the terminal just in case. */
585 if (!source_parse_dbus_data (source, &error)) {
586 g_return_if_fail (error != NULL);
587 g_warning ("%s", error->message);
588 g_error_free (error);
591 g_static_rec_mutex_unlock (&source->priv->lock);
595 source_idle_changed_cb (gpointer user_data)
597 ESource *source = E_SOURCE (user_data);
599 g_mutex_lock (source->priv->changed_lock);
600 g_source_unref (source->priv->changed);
601 source->priv->changed = NULL;
602 g_mutex_unlock (source->priv->changed_lock);
604 g_signal_emit (source, signals[CHANGED], 0);
610 source_set_dbus_object (ESource *source,
611 EDBusObject *dbus_object)
613 /* D-Bus object will be NULL when configuring a new source. */
614 if (dbus_object == NULL)
617 g_return_if_fail (E_DBUS_IS_OBJECT (dbus_object));
618 g_return_if_fail (source->priv->dbus_object == NULL);
620 source->priv->dbus_object = g_object_ref (dbus_object);
624 source_set_main_context (ESource *source,
625 GMainContext *main_context)
627 g_return_if_fail (source->priv->main_context == NULL);
629 source->priv->main_context =
630 (main_context != NULL) ?
631 g_main_context_ref (main_context) :
632 g_main_context_ref_thread_default ();
636 source_set_property (GObject *object,
641 switch (property_id) {
642 case PROP_DBUS_OBJECT:
643 source_set_dbus_object (
645 g_value_get_object (value));
648 case PROP_DISPLAY_NAME:
649 e_source_set_display_name (
651 g_value_get_string (value));
655 e_source_set_enabled (
657 g_value_get_boolean (value));
660 case PROP_MAIN_CONTEXT:
661 source_set_main_context (
663 g_value_get_boxed (value));
667 e_source_set_parent (
669 g_value_get_string (value));
673 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
677 source_get_property (GObject *object,
682 switch (property_id) {
683 case PROP_DBUS_OBJECT:
684 g_value_take_object (
685 value, e_source_ref_dbus_object (
689 case PROP_DISPLAY_NAME:
690 g_value_take_string (
691 value, e_source_dup_display_name (
696 g_value_set_boolean (
697 value, e_source_get_enabled (
701 case PROP_MAIN_CONTEXT:
703 value, e_source_ref_main_context (
708 g_value_take_string (
709 value, e_source_dup_parent (
714 g_value_set_boolean (
715 value, e_source_get_removable (
720 g_value_take_string (
721 value, e_source_dup_uid (
726 g_value_set_boolean (
727 value, e_source_get_writable (
732 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
736 source_dispose (GObject *object)
738 ESourcePrivate *priv;
740 priv = E_SOURCE_GET_PRIVATE (object);
742 if (priv->dbus_object != NULL) {
743 EDBusObject *dbus_object;
744 EDBusSource *dbus_source;
746 dbus_object = E_DBUS_OBJECT (priv->dbus_object);
748 dbus_source = e_dbus_object_get_source (dbus_object);
749 if (dbus_source != NULL) {
750 g_signal_handlers_disconnect_matched (
751 dbus_source, G_SIGNAL_MATCH_DATA,
752 0, 0, NULL, NULL, object);
753 g_object_unref (dbus_source);
756 g_object_unref (priv->dbus_object);
757 priv->dbus_object = NULL;
760 if (priv->main_context != NULL) {
761 g_main_context_unref (priv->main_context);
762 priv->main_context = NULL;
765 /* XXX Maybe not necessary to acquire the lock? */
766 g_mutex_lock (priv->changed_lock);
767 if (priv->changed != NULL) {
768 g_source_destroy (priv->changed);
769 g_source_unref (priv->changed);
770 priv->changed = NULL;
772 g_mutex_unlock (priv->changed_lock);
774 g_hash_table_remove_all (priv->extensions);
776 /* Chain up to parent's dispose() method. */
777 G_OBJECT_CLASS (e_source_parent_class)->dispose (object);
781 source_finalize (GObject *object)
783 ESourcePrivate *priv;
785 priv = E_SOURCE_GET_PRIVATE (object);
787 g_mutex_free (priv->changed_lock);
788 g_mutex_free (priv->property_lock);
790 g_free (priv->display_name);
791 g_free (priv->parent);
794 g_key_file_free (priv->key_file);
795 g_static_rec_mutex_free (&priv->lock);
796 g_hash_table_destroy (priv->extensions);
798 /* Chain up to parent's finalize() method. */
799 G_OBJECT_CLASS (e_source_parent_class)->finalize (object);
803 source_notify (GObject *object,
806 if ((pspec->flags & E_SOURCE_PARAM_SETTING) != 0)
807 e_source_changed (E_SOURCE (object));
811 source_remove_sync (ESource *source,
812 GCancellable *cancellable,
815 EDBusObject *dbus_object;
816 EDBusSourceRemovable *dbus_source;
819 dbus_object = E_DBUS_OBJECT (source->priv->dbus_object);
821 dbus_source = e_dbus_object_get_source_removable (dbus_object);
823 if (dbus_source == NULL) {
826 G_IO_ERROR_PERMISSION_DENIED,
827 _("Data source '%s' is not removable"),
828 e_source_get_display_name (source));
832 success = e_dbus_source_removable_call_remove_sync (
833 dbus_source, cancellable, error);
835 g_object_unref (dbus_source);
840 /* Helper for source_remove() */
842 source_remove_thread (GSimpleAsyncResult *simple,
844 GCancellable *cancellable)
846 GError *error = NULL;
848 e_source_remove_sync (E_SOURCE (object), cancellable, &error);
851 g_simple_async_result_take_error (simple, error);
855 source_remove (ESource *source,
856 GCancellable *cancellable,
857 GAsyncReadyCallback callback,
860 GSimpleAsyncResult *simple;
862 simple = g_simple_async_result_new (
863 G_OBJECT (source), callback, user_data, source_remove);
865 g_simple_async_result_set_check_cancellable (simple, cancellable);
867 g_simple_async_result_run_in_thread (
868 simple, source_remove_thread,
869 G_PRIORITY_DEFAULT, cancellable);
871 g_object_unref (simple);
875 source_remove_finish (ESource *source,
876 GAsyncResult *result,
879 GSimpleAsyncResult *simple;
881 g_return_val_if_fail (
882 g_simple_async_result_is_valid (
883 result, G_OBJECT (source), source_remove), FALSE);
885 simple = G_SIMPLE_ASYNC_RESULT (result);
887 /* Assume success unless a GError is set. */
888 return !g_simple_async_result_propagate_error (simple, error);
892 source_write_sync (ESource *source,
893 GCancellable *cancellable,
896 EDBusObject *dbus_object;
897 EDBusSourceWritable *dbus_source;
901 dbus_object = E_DBUS_OBJECT (source->priv->dbus_object);
903 dbus_source = e_dbus_object_get_source_writable (dbus_object);
905 if (dbus_source == NULL) {
908 G_IO_ERROR_PERMISSION_DENIED,
909 _("Data source '%s' is not writable"),
910 e_source_get_display_name (source));
914 data = e_source_to_string (source, NULL);
916 success = e_dbus_source_writable_call_write_sync (
917 dbus_source, data, cancellable, error);
921 g_object_unref (dbus_source);
926 /* Helper for source_write() */
928 source_write_thread (GSimpleAsyncResult *simple,
930 GCancellable *cancellable)
932 GError *error = NULL;
934 e_source_write_sync (E_SOURCE (object), cancellable, &error);
937 g_simple_async_result_take_error (simple, error);
941 source_write (ESource *source,
942 GCancellable *cancellable,
943 GAsyncReadyCallback callback,
946 GSimpleAsyncResult *simple;
948 simple = g_simple_async_result_new (
949 G_OBJECT (source), callback, user_data, source_write);
951 g_simple_async_result_set_check_cancellable (simple, cancellable);
953 g_simple_async_result_run_in_thread (
954 simple, source_write_thread,
955 G_PRIORITY_DEFAULT, cancellable);
957 g_object_unref (simple);
961 source_write_finish (ESource *source,
962 GAsyncResult *result,
965 GSimpleAsyncResult *simple;
967 g_return_val_if_fail (
968 g_simple_async_result_is_valid (
969 result, G_OBJECT (source), source_write), FALSE);
971 simple = G_SIMPLE_ASYNC_RESULT (result);
973 /* Assume success unless a GError is set. */
974 return !g_simple_async_result_propagate_error (simple, error);
978 source_initable_init (GInitable *initable,
979 GCancellable *cancellable,
983 gboolean success = TRUE;
985 source = E_SOURCE (initable);
987 /* The D-Bus object has the unique identifier (UID). */
988 if (source->priv->dbus_object != NULL) {
989 EDBusObject *dbus_object;
990 EDBusSource *dbus_source;
992 dbus_object = E_DBUS_OBJECT (source->priv->dbus_object);
994 /* An EDBusObject lacking an EDBusSource
995 * interface indicates a programmer error. */
996 dbus_source = e_dbus_object_get_source (dbus_object);
997 g_return_val_if_fail (E_DBUS_IS_SOURCE (dbus_source), FALSE);
999 /* Allow authentication prompts for a data source
1000 * when a new client-side proxy object is created.
1001 * The thought being if you cancel an authentication
1002 * prompt you won't be bothered again until you start
1003 * (or restart) a new E-D-S client app.
1005 * Failure here is non-fatal, ignore errors.
1007 * XXX Only GDBusProxy objects may call this. Sources
1008 * created server-side can't invoke remote methods.
1010 if (G_IS_DBUS_PROXY (dbus_source))
1011 e_dbus_source_call_allow_auth_prompt_sync (
1012 dbus_source, cancellable, NULL);
1014 /* The UID never changes, so we can cache a copy. */
1015 source->priv->uid = e_dbus_source_dup_uid (dbus_source);
1018 dbus_source, "notify::data",
1019 G_CALLBACK (source_notify_dbus_data_cb), source);
1021 success = source_parse_dbus_data (source, error);
1023 /* Avoid a spurious "changed" emission. */
1024 g_mutex_lock (source->priv->changed_lock);
1025 if (source->priv->changed != NULL) {
1026 g_source_destroy (source->priv->changed);
1027 g_source_unref (source->priv->changed);
1028 source->priv->changed = NULL;
1030 g_mutex_unlock (source->priv->changed_lock);
1032 g_object_unref (dbus_source);
1034 /* No D-Bus object implies we're configuring a new source,
1035 * so generate a new unique identifier (UID) for it. */
1037 source->priv->uid = e_uid_new ();
1044 e_source_class_init (ESourceClass *class)
1046 GObjectClass *object_class;
1048 g_type_class_add_private (class, sizeof (ESourcePrivate));
1050 object_class = G_OBJECT_CLASS (class);
1051 object_class->set_property = source_set_property;
1052 object_class->get_property = source_get_property;
1053 object_class->dispose = source_dispose;
1054 object_class->finalize = source_finalize;
1055 object_class->notify = source_notify;
1057 class->remove_sync = source_remove_sync;
1058 class->remove = source_remove;
1059 class->remove_finish = source_remove_finish;
1060 class->write_sync = source_write_sync;
1061 class->write = source_write;
1062 class->write_finish = source_write_finish;
1064 g_object_class_install_property (
1067 g_param_spec_object (
1070 "The D-Bus object for the data source",
1073 G_PARAM_CONSTRUCT_ONLY |
1074 G_PARAM_STATIC_STRINGS));
1076 g_object_class_install_property (
1079 g_param_spec_string (
1082 "The human-readable name of the data source",
1086 G_PARAM_STATIC_STRINGS |
1087 E_SOURCE_PARAM_SETTING));
1089 g_object_class_install_property (
1092 g_param_spec_boolean (
1095 "Whether the data source is enabled",
1099 G_PARAM_STATIC_STRINGS |
1100 E_SOURCE_PARAM_SETTING));
1102 g_object_class_install_property (
1105 g_param_spec_boxed (
1108 "The GMainContext used for signal emissions",
1109 G_TYPE_MAIN_CONTEXT,
1111 G_PARAM_CONSTRUCT_ONLY |
1112 G_PARAM_STATIC_STRINGS));
1114 g_object_class_install_property (
1117 g_param_spec_string (
1120 "The unique identity of the parent data source",
1123 G_PARAM_STATIC_STRINGS |
1124 E_SOURCE_PARAM_SETTING));
1126 g_object_class_install_property (
1129 g_param_spec_boolean (
1132 "Whether the data source is removable",
1135 G_PARAM_STATIC_STRINGS));
1137 g_object_class_install_property (
1140 g_param_spec_string (
1143 "The unique identity of the data source",
1146 G_PARAM_STATIC_STRINGS));
1148 g_object_class_install_property (
1151 g_param_spec_boolean (
1154 "Whether the data source is writable",
1157 G_PARAM_STATIC_STRINGS));
1161 * @source: the #ESource that received the signal
1163 * The ::changed signal is emitted when a property in @source or
1164 * one of its extension objects changes. A common use for this
1165 * signal is to notify a #GtkTreeModel containing data collected
1166 * from #ESource<!-- -->s that it needs to update a row.
1168 signals[CHANGED] = g_signal_new (
1170 G_TYPE_FROM_CLASS (class),
1171 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
1172 G_STRUCT_OFFSET (ESourceClass, changed),
1174 g_cclosure_marshal_VOID__VOID,
1177 /* Register built-in ESourceExtension types. */
1178 REGISTER_TYPE (E_TYPE_SOURCE_ADDRESS_BOOK);
1179 REGISTER_TYPE (E_TYPE_SOURCE_ALARMS);
1180 REGISTER_TYPE (E_TYPE_SOURCE_AUTHENTICATION);
1181 REGISTER_TYPE (E_TYPE_SOURCE_AUTOCOMPLETE);
1182 REGISTER_TYPE (E_TYPE_SOURCE_CALENDAR);
1183 REGISTER_TYPE (E_TYPE_SOURCE_COLLECTION);
1184 REGISTER_TYPE (E_TYPE_SOURCE_GOA);
1185 REGISTER_TYPE (E_TYPE_SOURCE_MAIL_ACCOUNT);
1186 REGISTER_TYPE (E_TYPE_SOURCE_MAIL_COMPOSITION);
1187 REGISTER_TYPE (E_TYPE_SOURCE_MAIL_IDENTITY);
1188 REGISTER_TYPE (E_TYPE_SOURCE_MAIL_SIGNATURE);
1189 REGISTER_TYPE (E_TYPE_SOURCE_MAIL_SUBMISSION);
1190 REGISTER_TYPE (E_TYPE_SOURCE_MAIL_TRANSPORT);
1191 REGISTER_TYPE (E_TYPE_SOURCE_MDN);
1192 REGISTER_TYPE (E_TYPE_SOURCE_MEMO_LIST);
1193 REGISTER_TYPE (E_TYPE_SOURCE_OFFLINE);
1194 REGISTER_TYPE (E_TYPE_SOURCE_OPENPGP);
1195 REGISTER_TYPE (E_TYPE_SOURCE_REFRESH);
1196 REGISTER_TYPE (E_TYPE_SOURCE_SECURITY);
1197 REGISTER_TYPE (E_TYPE_SOURCE_SELECTABLE);
1198 REGISTER_TYPE (E_TYPE_SOURCE_SMIME);
1199 REGISTER_TYPE (E_TYPE_SOURCE_TASK_LIST);
1200 REGISTER_TYPE (E_TYPE_SOURCE_WEBDAV);
1202 e_source_camel_register_types ();
1206 e_source_initable_init (GInitableIface *interface)
1208 interface->init = source_initable_init;
1212 e_source_init (ESource *source)
1214 GHashTable *extensions;
1216 extensions = g_hash_table_new_full (
1217 (GHashFunc) g_str_hash,
1218 (GEqualFunc) g_str_equal,
1219 (GDestroyNotify) g_free,
1220 (GDestroyNotify) g_object_unref);
1222 source->priv = E_SOURCE_GET_PRIVATE (source);
1223 source->priv->changed_lock = g_mutex_new ();
1224 source->priv->property_lock = g_mutex_new ();
1225 source->priv->key_file = g_key_file_new ();
1226 source->priv->extensions = extensions;
1228 g_static_rec_mutex_init (&source->priv->lock);
1233 * @dbus_object: (allow-none): a #GDBusObject or %NULL
1234 * @main_context: (allow-none): a #GMainContext or %NULL
1235 * @error: return location for a #GError, or %NULL
1237 * Creates a new #ESource instance.
1239 * The #ESource::changed signal will be emitted from @main_context if given,
1240 * or else from the thread-default #GMainContext at the time this function is
1243 * The only time the function should be called outside of #ESourceRegistry
1244 * is to create a so-called "scratch" #ESource for editing in a Properties
1245 * window or an account setup assistant.
1247 * FIXME: Elaborate on scratch sources.
1249 * Returns: a new #ESource, or %NULL on error
1254 e_source_new (GDBusObject *dbus_object,
1255 GMainContext *main_context,
1258 if (dbus_object != NULL)
1259 g_return_val_if_fail (E_DBUS_IS_OBJECT (dbus_object), NULL);
1261 return g_initable_new (
1262 E_TYPE_SOURCE, NULL, error,
1263 "dbus-object", dbus_object,
1264 "main-context", main_context,
1270 * @source: an #ESource
1272 * Generates a hash value for @source. This function is intended for
1273 * easily hashing an #ESource to add to a #GHashTable or similar data
1276 * Returns: a hash value for @source.
1281 e_source_hash (ESource *source)
1285 g_return_val_if_fail (E_IS_SOURCE (source), 0);
1287 uid = e_source_get_uid (source);
1289 return g_str_hash (uid);
1294 * @source1: the first #ESource
1295 * @source2: the second #ESource
1297 * Checks two #ESource instances for equality. #ESource instances are
1298 * equal if their unique identifier strings are equal.
1300 * Returns: %TRUE if @source1 and @source2 are equal
1305 e_source_equal (ESource *source1,
1308 const gchar *uid1, *uid2;
1310 g_return_val_if_fail (E_IS_SOURCE (source1), FALSE);
1311 g_return_val_if_fail (E_IS_SOURCE (source2), FALSE);
1313 if (source1 == source2)
1316 uid1 = e_source_get_uid (source1);
1317 uid2 = e_source_get_uid (source2);
1319 return g_str_equal (uid1, uid2);
1324 * @source: an #ESource
1326 * Emits the #ESource::changed signal from an idle callback in
1327 * @source's #ESource:main-context.
1329 * This function is primarily intended for use by #ESourceExtension
1330 * when emitting a #GObject::notify signal on one of its properties.
1335 e_source_changed (ESource *source)
1337 g_return_if_fail (E_IS_SOURCE (source));
1339 g_mutex_lock (source->priv->changed_lock);
1340 if (source->priv->changed == NULL) {
1341 source->priv->changed = g_idle_source_new ();
1342 g_source_set_callback (
1343 source->priv->changed,
1344 source_idle_changed_cb,
1345 source, (GDestroyNotify) NULL);
1347 source->priv->changed,
1348 source->priv->main_context);
1350 g_mutex_unlock (source->priv->changed_lock);
1355 * @source: an #ESource
1357 * Returns the unique identifier string for @source.
1359 * Returns: the UID for @source
1364 e_source_get_uid (ESource *source)
1366 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
1368 return source->priv->uid;
1373 * @source: an #ESource
1375 * Thread-safe variation of e_source_get_uid().
1376 * Use this function when accessing @source from multiple threads.
1378 * The returned string should be freed with g_free() when no longer needed.
1380 * Returns: a newly-allocated copy of #ESource:uid
1385 e_source_dup_uid (ESource *source)
1387 const gchar *protected;
1390 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
1392 /* Perhaps we don't need to lock the mutex since
1393 * this is a read-only property but it can't hurt. */
1395 g_mutex_lock (source->priv->property_lock);
1397 protected = e_source_get_uid (source);
1398 duplicate = g_strdup (protected);
1400 g_mutex_unlock (source->priv->property_lock);
1406 * e_source_get_parent:
1407 * @source: an #ESource
1409 * Returns the unique identifier string of the parent #ESource.
1411 * Returns: the UID of the parent #ESource
1416 e_source_get_parent (ESource *source)
1418 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
1420 return source->priv->parent;
1424 * e_source_dup_parent:
1425 * @source: an #ESource
1427 * Thread-safe variation of e_source_get_parent().
1428 * Use this function when accessing @source from multiple threads.
1430 * The returned string should be freed with g_free() when no longer needed.
1432 * Returns: a newly-allocated copy of #ESource:parent
1437 e_source_dup_parent (ESource *source)
1439 const gchar *protected;
1442 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
1444 g_mutex_lock (source->priv->property_lock);
1446 protected = e_source_get_parent (source);
1447 duplicate = g_strdup (protected);
1449 g_mutex_unlock (source->priv->property_lock);
1455 * e_source_set_parent:
1456 * @source: an #ESource
1457 * @parent: (allow-none): the UID of the parent #ESource, or %NULL
1459 * Identifies the parent of @source by its unique identifier string.
1460 * This can only be set prior to adding @source to an #ESourceRegistry.
1462 * The internal copy of #ESource:parent is automatically stripped of leading
1463 * and trailing whitespace. If the resulting string is empty, %NULL is set
1469 e_source_set_parent (ESource *source,
1470 const gchar *parent)
1472 g_return_if_fail (E_IS_SOURCE (source));
1474 g_mutex_lock (source->priv->property_lock);
1476 g_free (source->priv->parent);
1477 source->priv->parent = e_util_strdup_strip (parent);
1479 g_mutex_unlock (source->priv->property_lock);
1481 g_object_notify (G_OBJECT (source), "parent");
1485 * e_source_get_enabled:
1486 * @source: an #ESource
1488 * Returns %TRUE if @source is enabled.
1490 * An application should try to honor this setting if at all possible,
1491 * even if it does not provide a way to change the setting through its
1492 * user interface. Disabled data sources should generally be hidden.
1494 * Returns: whether @source is enabled
1499 e_source_get_enabled (ESource *source)
1501 g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
1503 return source->priv->enabled;
1507 * e_source_set_enabled:
1508 * @source: an #ESource
1509 * @enabled: whether to enable @source
1511 * Enables or disables @source.
1513 * An application should try to honor this setting if at all possible,
1514 * even if it does not provide a way to change the setting through its
1515 * user interface. Disabled data sources should generally be hidden.
1520 e_source_set_enabled (ESource *source,
1523 g_return_if_fail (E_IS_SOURCE (source));
1525 if (enabled == source->priv->enabled)
1528 source->priv->enabled = enabled;
1530 g_object_notify (G_OBJECT (source), "enabled");
1534 * e_source_get_writable:
1535 * @source: an #ESource
1537 * Returns whether the D-Bus service will accept changes to @source.
1538 * If @source is not writable, calls to e_source_write() will fail.
1540 * Returns: whether @source is writable
1545 e_source_get_writable (ESource *source)
1547 EDBusObject *dbus_object;
1548 EDBusSourceWritable *dbus_source;
1550 g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
1552 dbus_object = E_DBUS_OBJECT (source->priv->dbus_object);
1553 dbus_source = e_dbus_object_peek_source_writable (dbus_object);
1555 return (dbus_source != NULL);
1559 * e_source_get_removable:
1560 * @source: an #ESource
1562 * Returns whether the D-Bus service will allow @source to be removed.
1563 * If @source is not writable, calls to e_source_remove() will fail.
1565 * Returns: whether @source is removable
1570 e_source_get_removable (ESource *source)
1572 EDBusObject *dbus_object;
1573 EDBusSourceRemovable *dbus_source;
1575 g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
1577 dbus_object = E_DBUS_OBJECT (source->priv->dbus_object);
1578 dbus_source = e_dbus_object_peek_source_removable (dbus_object);
1580 return (dbus_source != NULL);
1584 * e_source_get_extension:
1585 * @source: an #ESource
1586 * @extension_name: an extension name
1588 * Returns an instance of some #ESourceExtension subclass which registered
1589 * itself under @extension_name. If no such instance exists within @source,
1590 * one will be created. It is the caller's responsibility to know which
1591 * subclass is being returned.
1593 * If you just want to test for the existence of an extension within @source
1594 * without creating it, use e_source_has_extension().
1596 * Extension instances are owned by their #ESource and should not be
1597 * referenced directly. Instead, reference the #ESource instance and
1598 * use this function to fetch the extension instance as needed.
1600 * Returns: an instance of some #ESourceExtension subclass
1605 e_source_get_extension (ESource *source,
1606 const gchar *extension_name)
1608 ESourceExtension *extension;
1609 GHashTable *hash_table;
1612 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
1613 g_return_val_if_fail (extension_name != NULL, NULL);
1615 g_static_rec_mutex_lock (&source->priv->lock);
1617 /* Check if we already have the extension. */
1618 extension = g_hash_table_lookup (
1619 source->priv->extensions, extension_name);
1620 if (extension != NULL)
1623 /* Find all subclasses of ESourceExtensionClass. */
1624 hash_table = source_find_extension_classes ();
1625 class = g_hash_table_lookup (hash_table, extension_name);
1627 /* Create a new instance of the appropriate GType. */
1628 if (class != NULL) {
1629 extension = g_object_new (
1630 G_TYPE_FROM_CLASS (class),
1631 "source", source, NULL);
1632 source_load_from_key_file (
1633 G_OBJECT (extension),
1634 source->priv->key_file,
1636 g_hash_table_insert (
1637 source->priv->extensions,
1638 g_strdup (extension_name), extension);
1640 /* XXX Tie this into a debug setting for ESources. */
1643 "No registered GType for ESource "
1644 "extension '%s'", extension_name);
1648 g_hash_table_destroy (hash_table);
1651 g_static_rec_mutex_unlock (&source->priv->lock);
1657 * e_source_has_extension:
1658 * @source: an #ESource
1659 * @extension_name: an extension name
1661 * Checks whether @source has an #ESourceExtension with the given name.
1663 * Returns: %TRUE if @source has such an extension, %FALSE if not
1668 e_source_has_extension (ESource *source,
1669 const gchar *extension_name)
1671 ESourceExtension *extension;
1673 g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
1674 g_return_val_if_fail (extension_name != NULL, FALSE);
1676 g_static_rec_mutex_lock (&source->priv->lock);
1678 /* Two cases to check for, either one is good enough:
1679 * 1) Our internal GKeyFile has a group named 'extension_name'.
1680 * 2) Our 'extensions' table has an entry for 'extension_name'.
1682 * We have to check both data structures in case a new extension
1683 * not present in the GKeyFile was instantiated, but we have not
1684 * yet updated our internal GKeyFile. A common occurrence when
1685 * editing a brand new data source.
1687 * When checking the GKeyFile we want to actually fetch the
1688 * extension with e_source_get_extension() to make sure it's
1689 * a registered extension name and not just an arbitrary key
1690 * file group name. */
1692 if (g_key_file_has_group (source->priv->key_file, extension_name)) {
1693 extension = e_source_get_extension (source, extension_name);
1695 GHashTable *hash_table = source->priv->extensions;
1696 extension = g_hash_table_lookup (hash_table, extension_name);
1699 g_static_rec_mutex_unlock (&source->priv->lock);
1701 return (extension != NULL);
1705 * e_source_ref_dbus_object:
1706 * @source: an #ESource
1708 * Returns the #GDBusObject that was passed to e_source_new().
1710 * The returned #GDBusObject is referenced for thread-safety and must be
1711 * unreferenced with g_object_unref() when finished with it.
1713 * Returns: (transfer full): the #GDBusObject for @source, or %NULL
1718 e_source_ref_dbus_object (ESource *source)
1720 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
1722 if (source->priv->dbus_object == NULL)
1725 return g_object_ref (source->priv->dbus_object);
1729 * e_source_ref_main_context:
1730 * @source: an #ESource
1732 * Returns the #GMainContext from which #ESource::changed signals are
1735 * The returned #GMainContext is referenced for thread-safety and must be
1736 * unreferenced with g_main_context_unref() when finished with it.
1738 * Returns: (transfer full): the #GMainContext for signal emissions
1743 e_source_ref_main_context (ESource *source)
1745 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
1747 return g_main_context_ref (source->priv->main_context);
1751 * e_source_get_display_name:
1752 * @source: an #ESource
1754 * Returns the display name for @source. Use the display name to
1755 * represent the #ESource in a user interface.
1757 * Returns: the display name for @source
1762 e_source_get_display_name (ESource *source)
1764 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
1766 return source->priv->display_name;
1770 * e_source_dup_display_name:
1771 * @source: an #ESource
1773 * Thread-safe variation of e_source_get_display_name().
1774 * Use this function when accessing @source from multiple threads.
1776 * The returned string should be freed with g_free() when no longer needed.
1778 * Returns: a newly-allocated copy of #ESource:display-name
1783 e_source_dup_display_name (ESource *source)
1785 const gchar *protected;
1788 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
1790 g_mutex_lock (source->priv->property_lock);
1792 protected = e_source_get_display_name (source);
1793 duplicate = g_strdup (protected);
1795 g_mutex_unlock (source->priv->property_lock);
1801 * e_source_set_display_name:
1802 * @source: an #ESource
1803 * @display_name: a display name
1805 * Sets the display name for @source. The @display_name argument must be a
1806 * valid UTF-8 string. Use the display name to represent the #ESource in a
1809 * The internal copy of @display_name is automatically stripped of leading
1810 * and trailing whitespace.
1815 e_source_set_display_name (ESource *source,
1816 const gchar *display_name)
1818 g_return_if_fail (E_IS_SOURCE (source));
1819 g_return_if_fail (display_name != NULL);
1820 g_return_if_fail (g_utf8_validate (display_name, -1, NULL));
1822 g_mutex_lock (source->priv->property_lock);
1824 g_free (source->priv->display_name);
1825 source->priv->display_name = g_strdup (display_name);
1827 /* Strip leading and trailing whitespace. */
1828 g_strstrip (source->priv->display_name);
1830 g_mutex_unlock (source->priv->property_lock);
1832 g_object_notify (G_OBJECT (source), "display-name");
1836 * e_source_compare_by_display_name:
1837 * @source1: the first #ESource
1838 * @source2: the second #ESource
1840 * Compares two #ESource instances by their display names. Useful for
1841 * ordering sources in a user interface.
1843 * Returns: a negative value if @source1 compares before @source2, zero if
1844 * they compare equal, or a positive value if @source1 compares
1850 e_source_compare_by_display_name (ESource *source1,
1853 const gchar *display_name1;
1854 const gchar *display_name2;
1856 display_name1 = e_source_get_display_name (source1);
1857 display_name2 = e_source_get_display_name (source2);
1859 return g_utf8_collate (display_name1, display_name2);
1863 * e_source_to_string:
1864 * @source: an #ESource
1865 * @length: (allow-none): return location for the length of the returned
1868 * Outputs the current contents of @source as a key file string.
1869 * Free the returned string with g_free().
1871 * Returns: a newly-allocated string
1876 e_source_to_string (ESource *source,
1879 GHashTableIter iter;
1881 gpointer group_name;
1885 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
1887 g_static_rec_mutex_lock (&source->priv->lock);
1889 key_file = source->priv->key_file;
1891 source_save_to_key_file (
1892 G_OBJECT (source), key_file, PRIMARY_GROUP_NAME);
1894 g_hash_table_iter_init (&iter, source->priv->extensions);
1895 while (g_hash_table_iter_next (&iter, &group_name, &extension))
1896 source_save_to_key_file (extension, key_file, group_name);
1898 data = g_key_file_to_data (key_file, length, NULL);
1900 g_static_rec_mutex_unlock (&source->priv->lock);
1906 * e_source_parameter_to_key:
1907 * @param_name: a #GParamSpec name
1909 * Converts a #GParamSpec name (e.g. "foo-bar" or "foo_bar")
1910 * to "CamelCase" for use as a #GKeyFile key (e.g. "FooBar").
1912 * This function is made public only to aid in account migration.
1913 * Applications should not need to use this.
1918 e_source_parameter_to_key (const gchar *param_name)
1920 gboolean uppercase = TRUE;
1924 g_return_val_if_fail (param_name != NULL, NULL);
1926 key = cp = g_malloc0 (strlen (param_name) + 1);
1928 for (ii = 0; param_name[ii] != '\0'; ii++) {
1929 if (g_ascii_isalnum (param_name[ii]) && uppercase) {
1930 *cp++ = g_ascii_toupper (param_name[ii]);
1932 } else if (param_name[ii] == '-' || param_name[ii] == '_')
1935 *cp++ = param_name[ii];
1942 * e_source_remove_sync:
1943 * @source: the #ESource to be removed
1944 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
1945 * @error: return location for a #GError, or %NULL
1947 * Requests the D-Bus service to delete the key files for @source and all of
1948 * its descendants and broadcast their removal to all clients. If an error
1949 * occurs, the functon will set @error and return %FALSE.
1951 * Returns: %TRUE on success, %FALSE on failure
1956 e_source_remove_sync (ESource *source,
1957 GCancellable *cancellable,
1960 ESourceClass *class;
1962 g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
1964 class = E_SOURCE_GET_CLASS (source);
1965 g_return_val_if_fail (class->remove_sync != NULL, FALSE);
1967 return class->remove_sync (source, cancellable, error);
1972 * @source: the #ESource to be removed
1973 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
1974 * @callback: (scope async): a #GAsyncReadyCallback to call when the request
1976 * @user_data: (closure): data to pass to the callback function
1978 * Asynchronously requests the D-Bus service to delete the key files for
1979 * @source all of its descendants and broadcast their removal to all clients.
1981 * When the operation is finished, @callback will be called. You can then
1982 * call e_source_remove_finish() to get the result of the operation.
1987 e_source_remove (ESource *source,
1988 GCancellable *cancellable,
1989 GAsyncReadyCallback callback,
1992 ESourceClass *class;
1994 g_return_if_fail (E_IS_SOURCE (source));
1996 class = E_SOURCE_GET_CLASS (source);
1997 g_return_if_fail (class->remove != NULL);
1999 class->remove (source, cancellable, callback, user_data);
2003 * e_source_remove_finish:
2004 * @source: the #ESource to be removed
2005 * @result: a #GAsyncResult
2006 * @error: return location for a #GError, or %NULL
2008 * Finishes the operation started with e_source_remove(). If an
2009 * error occured, the function will set @error and return %FALSE.
2011 * Returns: %TRUE on success, %FALSE of failure
2016 e_source_remove_finish (ESource *source,
2017 GAsyncResult *result,
2020 ESourceClass *class;
2022 g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
2023 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
2025 class = E_SOURCE_GET_CLASS (source);
2026 g_return_val_if_fail (class->remove_finish != NULL, FALSE);
2028 return class->remove_finish (source, result, error);
2032 * e_source_write_sync:
2033 * @source: a writable #ESource
2034 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
2035 * @error: return location for a #GError, or %NULL
2037 * Submits the current contents of @source to the D-Bus service to be
2038 * written to disk and broadcast to other clients. This can only be
2039 * called on #ESource:writable data sources.
2041 * Returns: %TRUE on success, %FALSE on failure
2046 e_source_write_sync (ESource *source,
2047 GCancellable *cancellable,
2050 ESourceClass *class;
2052 g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
2054 class = E_SOURCE_GET_CLASS (source);
2055 g_return_val_if_fail (class->write_sync != NULL, FALSE);
2057 return class->write_sync (source, cancellable, error);
2062 * @source: a writable #ESource
2063 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
2064 * @callback: (scope async): a #GAsyncReadyCallback to call when the request
2066 * @user_data: (closure): data to pass to the callback function
2068 * Asynchronously submits the current contents of @source to the D-Bus
2069 * service to be written to disk and broadcast to other clients. This
2070 * can only be called on #ESource:writable data sources.
2072 * When the operation is finished, @callback will be called. You can then
2073 * call e_source_write_finish() to get the result of the operation.
2078 e_source_write (ESource *source,
2079 GCancellable *cancellable,
2080 GAsyncReadyCallback callback,
2083 ESourceClass *class;
2085 g_return_if_fail (E_IS_SOURCE (source));
2087 class = E_SOURCE_GET_CLASS (source);
2088 g_return_if_fail (class->write != NULL);
2090 class->write (source, cancellable, callback, user_data);
2094 * e_source_write_finish:
2095 * @source: a writable #ESource
2096 * @result: a #GAsyncResult
2097 * @error: return location for a #GError, or %NULL
2099 * Finishes the operation started with e_source_write(). If an
2100 * error occurred, the function will set @error and return %FALSE.
2102 * Returns: %TRUE on success, %FALSE on failure
2107 e_source_write_finish (ESource *source,
2108 GAsyncResult *result,
2111 ESourceClass *class;
2113 g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
2114 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
2116 class = E_SOURCE_GET_CLASS (source);
2117 g_return_val_if_fail (class->write_finish != NULL, FALSE);
2119 return class->write_finish (source, result, error);