4 * This library is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library. If not, see <http://www.gnu.org/licenses/>.
19 * SECTION: e-source-registry
20 * @include: libedataserver/libedataserver.h
21 * @short_description: A central repository for data sources
23 * The #ESourceRegistry is a global singleton store for all #ESource
24 * instances. It uses file monitors to react to key file creation and
25 * deletion events, either constructing an #ESource instance from the
26 * newly created key file, or removing from the logical #ESource
27 * hierarchy the instance corresponding to the deleted key file.
29 * The #ESourceRegistry can be queried for individual #ESource instances
30 * by their unique identifier string or key file path, for collections of
31 * #ESource instances having a particular extension, or for all available
34 * The #ESourceRegistry API also provides a front-end for the
35 * "org.gnome.Evolution.DefaultSources" #GSettings schema which tracks
36 * which #ESource instances are designated to be the user's default address
37 * book, calendar, memo list and task list for desktop integration.
39 * Note: The #ESourceRegistry uses thread default main context from the time
40 * of its creation to deliver D-Bus signals, finish operations and so on,
41 * thus it requires a running main loop for its proper functionality.
44 #include "evolution-data-server-config.h"
46 #include <glib/gstdio.h>
47 #include <glib/gi18n-lib.h>
49 /* XXX Yeah, yeah... */
50 #define GCR_API_SUBJECT_TO_CHANGE
52 #include <gcr/gcr-base.h>
54 /* Private D-Bus classes. */
55 #include "e-dbus-source.h"
56 #include "e-dbus-source-manager.h"
58 #include "e-data-server-util.h"
59 #include "e-source-collection.h"
60 #include "e-source-enumtypes.h"
62 /* Needed for the defaults API. */
63 #include "e-source-address-book.h"
64 #include "e-source-calendar.h"
65 #include "e-source-mail-account.h"
66 #include "e-source-mail-identity.h"
67 #include "e-source-memo-list.h"
68 #include "e-source-task-list.h"
70 #include "e-source-registry.h"
72 #define E_SOURCE_REGISTRY_GET_PRIVATE(obj) \
73 (G_TYPE_INSTANCE_GET_PRIVATE \
74 ((obj), E_TYPE_SOURCE_REGISTRY, ESourceRegistryPrivate))
76 #define DBUS_OBJECT_PATH "/org/gnome/evolution/dataserver/SourceManager"
77 #define GSETTINGS_SCHEMA "org.gnome.Evolution.DefaultSources"
79 /* Built-in data source UIDs. */
80 #define E_SOURCE_BUILTIN_ADDRESS_BOOK_UID "system-address-book"
81 #define E_SOURCE_BUILTIN_CALENDAR_UID "system-calendar"
82 #define E_SOURCE_BUILTIN_MAIL_ACCOUNT_UID "local"
83 #define E_SOURCE_BUILTIN_MEMO_LIST_UID "system-memo-list"
84 #define E_SOURCE_BUILTIN_PROXY_UID "system-proxy"
85 #define E_SOURCE_BUILTIN_TASK_LIST_UID "system-task-list"
87 /* GSettings keys for default data sources. */
88 #define E_SETTINGS_DEFAULT_ADDRESS_BOOK_KEY "default-address-book"
89 #define E_SETTINGS_DEFAULT_CALENDAR_KEY "default-calendar"
90 #define E_SETTINGS_DEFAULT_MAIL_ACCOUNT_KEY "default-mail-account"
91 #define E_SETTINGS_DEFAULT_MAIL_IDENTITY_KEY "default-mail-identity"
92 #define E_SETTINGS_DEFAULT_MEMO_LIST_KEY "default-memo-list"
93 #define E_SETTINGS_DEFAULT_TASK_LIST_KEY "default-task-list"
95 typedef struct _AsyncContext AsyncContext
;
96 typedef struct _CreateContext CreateContext
;
97 typedef struct _SourceClosure SourceClosure
;
98 typedef struct _ThreadClosure ThreadClosure
;
99 typedef struct _CredentialsRequiredClosure CredentialsRequiredClosure
;
101 struct _ESourceRegistryPrivate
{
102 GMainContext
*main_context
;
104 GThread
*manager_thread
;
105 ThreadClosure
*thread_closure
;
107 GDBusObjectManager
*dbus_object_manager
;
108 EDBusSourceManager
*dbus_source_manager
;
110 GHashTable
*object_path_table
;
111 GMutex object_path_table_lock
;
113 GHashTable
*service_restart_table
;
114 GMutex service_restart_table_lock
;
121 gboolean initialized
;
125 EOAuth2Services
*oauth2_services
;
128 struct _AsyncContext
{
130 GList
*list_of_sources
;
133 /* Used in e_source_registry_create_sources_sync() */
134 struct _CreateContext
{
135 GHashTable
*pending_uids
;
136 GMainContext
*main_context
;
137 GMainLoop
*main_loop
;
140 struct _SourceClosure
{
145 struct _ThreadClosure
{
146 ESourceRegistry
*registry
;
147 GMainContext
*main_context
;
148 GMainLoop
*main_loop
;
149 GCond main_loop_cond
;
150 GMutex main_loop_mutex
;
154 struct _CredentialsRequiredClosure
{
157 ESourceCredentialsReason reason
;
158 gchar
*certificate_pem
;
159 GTlsCertificateFlags certificate_errors
;
165 PROP_DEFAULT_ADDRESS_BOOK
,
166 PROP_DEFAULT_CALENDAR
,
167 PROP_DEFAULT_MAIL_ACCOUNT
,
168 PROP_DEFAULT_MAIL_IDENTITY
,
169 PROP_DEFAULT_MEMO_LIST
,
170 PROP_DEFAULT_TASK_LIST
179 CREDENTIALS_REQUIRED
,
183 /* Forward Declarations */
184 static void source_registry_add_source (ESourceRegistry
*registry
,
186 static void e_source_registry_initable_init (GInitableIface
*iface
);
188 /* Private ESource function, for our use only. */
189 void __e_source_private_replace_dbus_object
191 GDBusObject
*dbus_object
);
193 static guint signals
[LAST_SIGNAL
];
195 /* By default, the GAsyncInitable interface calls GInitable.init()
196 * from a separate thread, so we only have to override GInitable. */
197 G_DEFINE_TYPE_WITH_CODE (
201 G_IMPLEMENT_INTERFACE (
202 G_TYPE_INITABLE
, e_source_registry_initable_init
)
203 G_IMPLEMENT_INTERFACE (
204 G_TYPE_ASYNC_INITABLE
, NULL
))
207 async_context_free (AsyncContext
*async_context
)
209 if (async_context
->source
!= NULL
)
210 g_object_unref (async_context
->source
);
213 async_context
->list_of_sources
,
214 (GDestroyNotify
) g_object_unref
);
216 g_slice_free (AsyncContext
, async_context
);
219 static CreateContext
*
220 create_context_new (void)
222 CreateContext
*create_context
;
224 create_context
= g_slice_new0 (CreateContext
);
226 create_context
->pending_uids
= g_hash_table_new_full (
227 (GHashFunc
) g_str_hash
,
228 (GEqualFunc
) g_str_equal
,
229 (GDestroyNotify
) g_free
,
230 (GDestroyNotify
) NULL
);
232 create_context
->main_context
= g_main_context_new ();
234 create_context
->main_loop
= g_main_loop_new (
235 create_context
->main_context
, FALSE
);
237 return create_context
;
241 create_context_free (CreateContext
*create_context
)
243 g_main_loop_unref (create_context
->main_loop
);
244 g_main_context_unref (create_context
->main_context
);
245 g_hash_table_unref (create_context
->pending_uids
);
247 g_slice_free (CreateContext
, create_context
);
251 source_closure_free (SourceClosure
*closure
)
253 g_weak_ref_clear (&closure
->registry
);
254 g_object_unref (closure
->source
);
256 g_slice_free (SourceClosure
, closure
);
260 thread_closure_free (ThreadClosure
*closure
)
262 /* The registry member is not referenced. */
264 g_warn_if_fail (!g_main_context_pending (closure
->main_context
));
266 g_main_context_unref (closure
->main_context
);
267 g_main_loop_unref (closure
->main_loop
);
268 g_cond_clear (&closure
->main_loop_cond
);
269 g_mutex_clear (&closure
->main_loop_mutex
);
271 /* The GError should be NULL at this point,
272 * regardless of whether an error occurred. */
273 g_warn_if_fail (closure
->error
== NULL
);
275 g_slice_free (ThreadClosure
, closure
);
279 credentials_required_closure_free (gpointer ptr
)
281 CredentialsRequiredClosure
*closure
= ptr
;
284 g_weak_ref_clear (&closure
->registry
);
285 g_object_unref (closure
->source
);
286 g_free (closure
->certificate_pem
);
287 g_clear_error (&closure
->op_error
);
289 g_slice_free (CredentialsRequiredClosure
, closure
);
293 G_LOCK_DEFINE_STATIC (singleton_lock
);
294 static GWeakRef singleton
;
296 static ESourceRegistry
*
297 source_registry_dup_uninitialized_singleton (void)
299 ESourceRegistry
*registry
;
301 G_LOCK (singleton_lock
);
303 registry
= g_weak_ref_get (&singleton
);
304 if (registry
== NULL
) {
305 registry
= g_object_new (E_TYPE_SOURCE_REGISTRY
, NULL
);
306 g_weak_ref_set (&singleton
, registry
);
309 G_UNLOCK (singleton_lock
);
315 source_registry_dbus_object_dup_uid (GDBusObject
*dbus_object
)
317 EDBusObject
*e_dbus_object
;
318 EDBusSource
*e_dbus_source
;
320 /* EDBusSource interface should always be present. */
321 e_dbus_object
= E_DBUS_OBJECT (dbus_object
);
322 e_dbus_source
= e_dbus_object_peek_source (e_dbus_object
);
324 return e_dbus_source_dup_uid (e_dbus_source
);
328 source_registry_object_path_table_insert (ESourceRegistry
*registry
,
329 const gchar
*object_path
,
332 GHashTable
*object_path_table
;
334 g_return_if_fail (object_path
!= NULL
);
335 g_return_if_fail (E_IS_SOURCE (source
));
337 object_path_table
= registry
->priv
->object_path_table
;
339 g_mutex_lock (®istry
->priv
->object_path_table_lock
);
341 g_hash_table_insert (
343 g_strdup (object_path
),
344 g_object_ref (source
));
346 g_mutex_unlock (®istry
->priv
->object_path_table_lock
);
350 source_registry_object_path_table_lookup (ESourceRegistry
*registry
,
351 const gchar
*object_path
)
353 GHashTable
*object_path_table
;
356 g_return_val_if_fail (object_path
!= NULL
, NULL
);
358 object_path_table
= registry
->priv
->object_path_table
;
360 g_mutex_lock (®istry
->priv
->object_path_table_lock
);
362 source
= g_hash_table_lookup (object_path_table
, object_path
);
364 g_object_ref (source
);
366 g_mutex_unlock (®istry
->priv
->object_path_table_lock
);
372 source_registry_object_path_table_remove (ESourceRegistry
*registry
,
373 const gchar
*object_path
)
375 GHashTable
*object_path_table
;
378 g_return_val_if_fail (object_path
!= NULL
, FALSE
);
380 object_path_table
= registry
->priv
->object_path_table
;
382 g_mutex_lock (®istry
->priv
->object_path_table_lock
);
384 removed
= g_hash_table_remove (object_path_table
, object_path
);
386 g_mutex_unlock (®istry
->priv
->object_path_table_lock
);
392 source_registry_service_restart_table_add (ESourceRegistry
*registry
,
395 GHashTable
*service_restart_table
;
397 g_return_if_fail (uid
!= NULL
);
399 service_restart_table
= registry
->priv
->service_restart_table
;
401 g_mutex_lock (®istry
->priv
->service_restart_table_lock
);
403 g_hash_table_add (service_restart_table
, g_strdup (uid
));
405 g_mutex_unlock (®istry
->priv
->service_restart_table_lock
);
409 source_registry_service_restart_table_remove (ESourceRegistry
*registry
,
412 GHashTable
*service_restart_table
;
415 g_return_val_if_fail (uid
!= NULL
, FALSE
);
417 service_restart_table
= registry
->priv
->service_restart_table
;
419 g_mutex_lock (®istry
->priv
->service_restart_table_lock
);
421 removed
= g_hash_table_remove (service_restart_table
, uid
);
423 g_mutex_unlock (®istry
->priv
->service_restart_table_lock
);
429 source_registry_service_restart_table_steal_all (ESourceRegistry
*registry
)
431 GHashTable
*service_restart_table
;
434 service_restart_table
= registry
->priv
->service_restart_table
;
436 g_mutex_lock (®istry
->priv
->service_restart_table_lock
);
438 list
= g_hash_table_get_keys (service_restart_table
);
439 g_hash_table_steal_all (service_restart_table
);
441 g_mutex_unlock (®istry
->priv
->service_restart_table_lock
);
447 source_registry_sources_remove (ESourceRegistry
*registry
,
453 uid
= e_source_get_uid (source
);
454 g_return_val_if_fail (uid
!= NULL
, FALSE
);
456 g_mutex_lock (®istry
->priv
->sources_lock
);
458 removed
= g_hash_table_remove (registry
->priv
->sources
, uid
);
460 g_mutex_unlock (®istry
->priv
->sources_lock
);
466 source_registry_sources_lookup (ESourceRegistry
*registry
,
471 g_return_val_if_fail (uid
!= NULL
, NULL
);
473 g_mutex_lock (®istry
->priv
->sources_lock
);
475 source
= g_hash_table_lookup (registry
->priv
->sources
, uid
);
478 g_object_ref (source
);
480 g_mutex_unlock (®istry
->priv
->sources_lock
);
486 source_registry_sources_get_values (ESourceRegistry
*registry
)
490 g_mutex_lock (®istry
->priv
->sources_lock
);
492 values
= g_hash_table_get_values (registry
->priv
->sources
);
494 g_list_foreach (values
, (GFunc
) g_object_ref
, NULL
);
496 g_mutex_unlock (®istry
->priv
->sources_lock
);
502 source_registry_sources_build_tree (ESourceRegistry
*registry
)
509 g_mutex_lock (®istry
->priv
->sources_lock
);
511 root
= g_node_new (NULL
);
512 index
= g_hash_table_new (g_str_hash
, g_str_equal
);
514 /* Add a GNode for each ESource to the index. */
515 g_hash_table_iter_init (&iter
, registry
->priv
->sources
);
516 while (g_hash_table_iter_next (&iter
, &key
, &value
)) {
517 ESource
*source
= g_object_ref (value
);
518 g_hash_table_insert (index
, key
, g_node_new (source
));
521 /* Traverse the index and link the nodes together. */
522 g_hash_table_iter_init (&iter
, index
);
523 while (g_hash_table_iter_next (&iter
, NULL
, &value
)) {
527 const gchar
*parent_uid
;
529 source_node
= (GNode
*) value
;
530 source
= E_SOURCE (source_node
->data
);
531 parent_uid
= e_source_get_parent (source
);
533 if (parent_uid
== NULL
|| *parent_uid
== '\0') {
536 parent_node
= g_hash_table_lookup (index
, parent_uid
);
537 g_warn_if_fail (parent_node
!= NULL
);
540 /* Should never be NULL, but just to be safe. */
541 if (parent_node
!= NULL
)
542 g_node_append (parent_node
, source_node
);
545 g_hash_table_destroy (index
);
547 g_mutex_unlock (®istry
->priv
->sources_lock
);
553 source_registry_settings_changed_cb (GSettings
*settings
,
555 ESourceRegistry
*registry
)
557 /* We define a property name that matches every key in
558 * the "org.gnome.Evolution.DefaultSources" schema. */
559 g_object_notify (G_OBJECT (registry
), key
);
563 source_registry_source_changed_idle_cb (gpointer user_data
)
565 SourceClosure
*closure
= user_data
;
566 ESourceRegistry
*registry
;
568 registry
= g_weak_ref_get (&closure
->registry
);
570 if (registry
!= NULL
) {
573 signals
[SOURCE_CHANGED
], 0,
575 g_object_unref (registry
);
582 source_registry_source_notify_enabled_idle_cb (gpointer user_data
)
584 SourceClosure
*closure
= user_data
;
585 ESourceRegistry
*registry
;
587 registry
= g_weak_ref_get (&closure
->registry
);
589 if (registry
!= NULL
) {
590 if (e_source_get_enabled (closure
->source
)) {
593 signals
[SOURCE_ENABLED
], 0,
598 signals
[SOURCE_DISABLED
], 0,
601 g_object_unref (registry
);
608 source_registry_source_changed_cb (ESource
*source
,
609 ESourceRegistry
*registry
)
611 GSource
*idle_source
;
612 SourceClosure
*closure
;
614 closure
= g_slice_new0 (SourceClosure
);
615 g_weak_ref_init (&closure
->registry
, registry
);
616 closure
->source
= g_object_ref (source
);
618 idle_source
= g_idle_source_new ();
619 g_source_set_callback (
621 source_registry_source_changed_idle_cb
,
622 closure
, (GDestroyNotify
) source_closure_free
);
623 g_source_attach (idle_source
, registry
->priv
->main_context
);
624 g_source_unref (idle_source
);
628 source_registry_source_notify_enabled_cb (ESource
*source
,
630 ESourceRegistry
*registry
)
632 GSource
*idle_source
;
633 SourceClosure
*closure
;
635 closure
= g_slice_new0 (SourceClosure
);
636 g_weak_ref_init (&closure
->registry
, registry
);
637 closure
->source
= g_object_ref (source
);
639 idle_source
= g_idle_source_new ();
640 g_source_set_callback (
642 source_registry_source_notify_enabled_idle_cb
,
643 closure
, (GDestroyNotify
) source_closure_free
);
644 g_source_attach (idle_source
, registry
->priv
->main_context
);
645 g_source_unref (idle_source
);
649 source_registry_source_credentials_required_idle_cb (gpointer user_data
)
651 CredentialsRequiredClosure
*closure
= user_data
;
652 ESourceRegistry
*registry
;
654 registry
= g_weak_ref_get (&closure
->registry
);
656 if (registry
!= NULL
) {
659 signals
[CREDENTIALS_REQUIRED
], 0,
660 closure
->source
, closure
->reason
, closure
->certificate_pem
,
661 closure
->certificate_errors
, closure
->op_error
);
663 g_object_unref (registry
);
670 source_registry_source_credentials_required_cb (ESource
*source
,
671 ESourceCredentialsReason reason
,
672 const gchar
*certificate_pem
,
673 GTlsCertificateFlags certificate_errors
,
674 const GError
*op_error
,
675 ESourceRegistry
*registry
)
677 GSource
*idle_source
;
678 CredentialsRequiredClosure
*closure
;
680 closure
= g_slice_new0 (CredentialsRequiredClosure
);
681 g_weak_ref_init (&closure
->registry
, registry
);
682 closure
->source
= g_object_ref (source
);
683 closure
->reason
= reason
;
684 closure
->certificate_pem
= g_strdup (certificate_pem
);
685 closure
->certificate_errors
= certificate_errors
;
686 closure
->op_error
= op_error
? g_error_copy (op_error
) : NULL
;
688 idle_source
= g_idle_source_new ();
689 g_source_set_callback (
691 source_registry_source_credentials_required_idle_cb
,
692 closure
, credentials_required_closure_free
);
693 g_source_attach (idle_source
, registry
->priv
->main_context
);
694 g_source_unref (idle_source
);
698 source_registry_new_source (ESourceRegistry
*registry
,
699 GDBusObject
*dbus_object
)
701 GMainContext
*main_context
;
703 const gchar
*object_path
;
704 GError
*local_error
= NULL
;
706 /* We don't want the ESource emitting "changed" signals from
707 * the manager thread, so we pass it the same main context the
708 * registry uses for scheduling signal emissions. */
709 main_context
= registry
->priv
->main_context
;
710 source
= e_source_new (dbus_object
, main_context
, &local_error
);
711 object_path
= g_dbus_object_get_object_path (dbus_object
);
713 /* The likelihood of an error here is slim, so it's
714 * sufficient to just print a warning if one occurs. */
715 if (local_error
!= NULL
) {
716 g_warn_if_fail (source
== NULL
);
718 "ESourceRegistry: Failed to create a "
719 "data source object for path '%s': %s",
720 object_path
, local_error
->message
);
721 g_error_free (local_error
);
725 g_return_val_if_fail (E_IS_SOURCE (source
), NULL
);
727 /* Add the ESource to the object path table immediately. */
728 source_registry_object_path_table_insert (
729 registry
, object_path
, source
);
735 source_registry_unref_source (ESource
*source
)
737 g_signal_handlers_disconnect_matched (
738 source
, G_SIGNAL_MATCH_FUNC
, 0, 0, NULL
,
739 source_registry_source_changed_cb
, NULL
);
741 g_signal_handlers_disconnect_matched (
742 source
, G_SIGNAL_MATCH_FUNC
, 0, 0, NULL
,
743 source_registry_source_notify_enabled_cb
, NULL
);
745 g_signal_handlers_disconnect_matched (
746 source
, G_SIGNAL_MATCH_FUNC
, 0, 0, NULL
,
747 source_registry_source_credentials_required_cb
, NULL
);
749 g_object_unref (source
);
753 source_registry_add_source (ESourceRegistry
*registry
,
758 /* This is called in the manager thread during initialization
759 * and in response to "object-added" signals from the manager. */
761 uid
= e_source_get_uid (source
);
762 g_return_if_fail (uid
!= NULL
);
764 g_mutex_lock (®istry
->priv
->sources_lock
);
766 /* Check if we already have this source in the registry. */
767 if (g_hash_table_lookup (registry
->priv
->sources
, uid
) != NULL
) {
768 g_mutex_unlock (®istry
->priv
->sources_lock
);
774 G_CALLBACK (source_registry_source_changed_cb
),
778 source
, "notify::enabled",
779 G_CALLBACK (source_registry_source_notify_enabled_cb
),
783 source
, "credentials-required",
784 G_CALLBACK (source_registry_source_credentials_required_cb
),
787 g_hash_table_insert (
788 registry
->priv
->sources
,
789 g_strdup (uid
), g_object_ref (source
));
791 g_mutex_unlock (®istry
->priv
->sources_lock
);
795 source_registry_object_added_idle_cb (gpointer user_data
)
797 SourceClosure
*closure
= user_data
;
798 ESourceRegistry
*registry
;
800 registry
= g_weak_ref_get (&closure
->registry
);
802 if (registry
!= NULL
) {
805 signals
[SOURCE_ADDED
], 0,
807 g_object_unref (registry
);
814 source_registry_object_added_by_owner (ESourceRegistry
*registry
,
815 GDBusObject
*dbus_object
)
817 SourceClosure
*closure
;
818 GSource
*idle_source
;
821 g_return_if_fail (E_DBUS_IS_OBJECT (dbus_object
));
823 source
= source_registry_new_source (registry
, dbus_object
);
824 g_return_if_fail (source
!= NULL
);
826 /* Add the new ESource to our internal hash table so it can be
827 * obtained through e_source_registry_ref_source() immediately. */
828 source_registry_add_source (registry
, source
);
830 /* Schedule a callback on the ESourceRegistry's GMainContext. */
832 closure
= g_slice_new0 (SourceClosure
);
833 g_weak_ref_init (&closure
->registry
, registry
);
834 closure
->source
= g_object_ref (source
);
836 idle_source
= g_idle_source_new ();
837 g_source_set_callback (
839 source_registry_object_added_idle_cb
,
840 closure
, (GDestroyNotify
) source_closure_free
);
841 g_source_attach (idle_source
, registry
->priv
->main_context
);
842 g_source_unref (idle_source
);
844 g_object_unref (source
);
848 source_registry_object_added_no_owner (ESourceRegistry
*registry
,
849 GDBusObject
*dbus_object
)
851 ESource
*source
= NULL
;
854 uid
= source_registry_dbus_object_dup_uid (dbus_object
);
856 if (source_registry_service_restart_table_remove (registry
, uid
))
857 source
= e_source_registry_ref_source (registry
, uid
);
859 if (source
!= NULL
) {
860 const gchar
*object_path
;
862 object_path
= g_dbus_object_get_object_path (dbus_object
);
864 source_registry_object_path_table_insert (
865 registry
, object_path
, source
);
867 __e_source_private_replace_dbus_object (source
, dbus_object
);
869 g_object_unref (source
);
872 source_registry_object_added_by_owner (registry
, dbus_object
);
879 source_registry_object_added_cb (GDBusObjectManager
*object_manager
,
880 GDBusObject
*dbus_object
,
881 ESourceRegistry
*registry
)
885 name_owner
= g_dbus_object_manager_client_get_name_owner (
886 G_DBUS_OBJECT_MANAGER_CLIENT (object_manager
));
888 if (name_owner
!= NULL
)
889 source_registry_object_added_by_owner (registry
, dbus_object
);
891 source_registry_object_added_no_owner (registry
, dbus_object
);
897 source_registry_object_removed_idle_cb (gpointer user_data
)
899 SourceClosure
*closure
= user_data
;
900 ESourceRegistry
*registry
;
902 registry
= g_weak_ref_get (&closure
->registry
);
904 if (registry
!= NULL
) {
907 signals
[SOURCE_REMOVED
], 0,
909 g_object_unref (registry
);
916 source_registry_object_removed_by_owner (ESourceRegistry
*registry
,
917 GDBusObject
*dbus_object
)
919 SourceClosure
*closure
;
920 GSource
*idle_source
;
922 const gchar
*object_path
;
924 /* Find the corresponding ESource in the object path table.
925 * Note that the lookup returns a new ESource reference. */
926 object_path
= g_dbus_object_get_object_path (dbus_object
);
927 source
= source_registry_object_path_table_lookup (
928 registry
, object_path
);
929 g_return_if_fail (E_IS_SOURCE (source
));
931 /* Remove the ESource from the object path table immediately. */
932 source_registry_object_path_table_remove (registry
, object_path
);
934 /* Also remove the ESource from the sources table immediately. */
935 if (!source_registry_sources_remove (registry
, source
)) {
936 g_object_unref (source
);
937 g_return_if_reached ();
940 /* Strip the ESource of its GDBusObject. */
941 __e_source_private_replace_dbus_object (source
, NULL
);
943 /* Schedule a callback on the ESourceRegistry's GMainContext. */
945 closure
= g_slice_new0 (SourceClosure
);
946 g_weak_ref_init (&closure
->registry
, registry
);
947 closure
->source
= g_object_ref (source
);
949 idle_source
= g_idle_source_new ();
950 g_source_set_callback (
952 source_registry_object_removed_idle_cb
,
953 closure
, (GDestroyNotify
) source_closure_free
);
954 g_source_attach (idle_source
, registry
->priv
->main_context
);
955 g_source_unref (idle_source
);
957 g_object_unref (source
);
961 source_registry_object_removed_no_owner (ESourceRegistry
*registry
,
962 GDBusObject
*dbus_object
)
964 const gchar
*object_path
;
966 object_path
= g_dbus_object_get_object_path (dbus_object
);
968 if (source_registry_object_path_table_remove (registry
, object_path
)) {
971 uid
= source_registry_dbus_object_dup_uid (dbus_object
);
972 source_registry_service_restart_table_add (registry
, uid
);
978 source_registry_object_removed_cb (GDBusObjectManager
*object_manager
,
979 GDBusObject
*dbus_object
,
980 ESourceRegistry
*registry
)
984 name_owner
= g_dbus_object_manager_client_get_name_owner (
985 G_DBUS_OBJECT_MANAGER_CLIENT (object_manager
));
987 if (name_owner
!= NULL
)
988 source_registry_object_removed_by_owner (registry
, dbus_object
);
990 source_registry_object_removed_no_owner (registry
, dbus_object
);
996 source_registry_name_appeared (ESourceRegistry
*registry
)
1000 /* The D-Bus service restarted, and the GDBusObjectManager has
1001 * just set its "name-owner" property having finished emitting
1002 * an "object-added" signal for each GDBusObject. */
1004 list
= source_registry_service_restart_table_steal_all (registry
);
1006 for (link
= list
; link
!= NULL
; link
= g_list_next (link
)) {
1007 SourceClosure
*closure
;
1008 GSource
*idle_source
;
1010 const gchar
*uid
= link
->data
;
1012 source
= e_source_registry_ref_source (registry
, uid
);
1016 closure
= g_slice_new0 (SourceClosure
);
1017 g_weak_ref_init (&closure
->registry
, registry
);
1018 closure
->source
= g_object_ref (source
);
1020 idle_source
= g_idle_source_new ();
1021 g_source_set_callback (
1023 source_registry_object_removed_idle_cb
,
1024 closure
, (GDestroyNotify
) source_closure_free
);
1025 g_source_attach (idle_source
, registry
->priv
->main_context
);
1026 g_source_unref (idle_source
);
1028 g_object_unref (source
);
1031 g_list_free_full (list
, (GDestroyNotify
) g_free
);
1035 source_registry_name_vanished (ESourceRegistry
*registry
)
1037 /* This function is just a convenience breakpoint. The D-Bus
1038 * service aborted, so the GDBusObjectManager has cleared its
1039 * "name-owner" property and will now emit a "object-removed"
1040 * signal for each GDBusObject. */
1044 source_registry_notify_name_owner_cb (GDBusObjectManager
*object_manager
,
1046 ESourceRegistry
*registry
)
1050 name_owner
= g_dbus_object_manager_client_get_name_owner (
1051 G_DBUS_OBJECT_MANAGER_CLIENT (object_manager
));
1053 if (name_owner
!= NULL
)
1054 source_registry_name_appeared (registry
);
1056 source_registry_name_vanished (registry
);
1058 g_free (name_owner
);
1062 source_registry_object_manager_running (gpointer data
)
1064 ThreadClosure
*closure
= data
;
1066 g_mutex_lock (&closure
->main_loop_mutex
);
1067 g_cond_broadcast (&closure
->main_loop_cond
);
1068 g_mutex_unlock (&closure
->main_loop_mutex
);
1074 source_registry_object_manager_thread (gpointer data
)
1076 GDBusObjectManager
*object_manager
;
1077 ThreadClosure
*closure
= data
;
1078 GSource
*idle_source
;
1080 gulong object_added_handler_id
= 0;
1081 gulong object_removed_handler_id
= 0;
1082 gulong notify_name_owner_handler_id
= 0;
1084 /* GDBusObjectManagerClient grabs the thread-default GMainContext
1085 * at creation time and only emits signals from that GMainContext.
1086 * Running it in a separate thread prevents its signal emissions
1087 * from being inhibited by someone overriding the thread-default
1090 /* This becomes the GMainContext that GDBusObjectManagerClient
1091 * will emit signals from. Make it the thread-default context
1092 * for this thread before creating the client. */
1093 g_main_context_push_thread_default (closure
->main_context
);
1095 object_manager
= e_dbus_object_manager_client_new_for_bus_sync (
1097 G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE
,
1098 SOURCES_DBUS_SERVICE_NAME
,
1100 NULL
, &closure
->error
);
1104 ((object_manager
!= NULL
) && (closure
->error
== NULL
)) ||
1105 ((object_manager
== NULL
) && (closure
->error
!= NULL
)));
1107 /* If we failed to create the GDBusObjectManagerClient, skip
1108 * straight to the main loop. The GError will be propagated
1109 * back to the caller, the main loop will terminate, and the
1110 * partially-initialized ESourceRegistry will be destroyed. */
1111 if (object_manager
== NULL
)
1114 /* Give the registry a handle to the object manager. */
1115 closure
->registry
->priv
->dbus_object_manager
=
1116 g_object_ref (object_manager
);
1118 /* Now populate the registry with an initial set of ESources. */
1120 list
= g_dbus_object_manager_get_objects (object_manager
);
1122 for (link
= list
; link
!= NULL
; link
= g_list_next (link
)) {
1123 GDBusObject
*dbus_object
;
1126 dbus_object
= G_DBUS_OBJECT (link
->data
);
1128 source
= source_registry_new_source (
1129 closure
->registry
, dbus_object
);
1131 if (source
!= NULL
) {
1132 source_registry_add_source (
1133 closure
->registry
, source
);
1134 g_object_unref (source
);
1138 g_list_free_full (list
, (GDestroyNotify
) g_object_unref
);
1140 /* Listen for D-Bus object additions and removals. */
1142 object_added_handler_id
= g_signal_connect (
1143 object_manager
, "object-added",
1144 G_CALLBACK (source_registry_object_added_cb
),
1147 object_removed_handler_id
= g_signal_connect (
1148 object_manager
, "object-removed",
1149 G_CALLBACK (source_registry_object_removed_cb
),
1152 notify_name_owner_handler_id
= g_signal_connect (
1153 object_manager
, "notify::name-owner",
1154 G_CALLBACK (source_registry_notify_name_owner_cb
),
1158 /* Schedule a one-time idle callback to broadcast through a
1159 * condition variable that our main loop is up and running. */
1161 idle_source
= g_idle_source_new ();
1162 g_source_set_callback (
1164 source_registry_object_manager_running
,
1165 closure
, (GDestroyNotify
) NULL
);
1166 g_source_attach (idle_source
, closure
->main_context
);
1167 g_source_unref (idle_source
);
1169 /* Now we mostly idle here for the rest of the session. */
1171 g_main_loop_run (closure
->main_loop
);
1173 /* Clean up and exit. */
1175 if (object_manager
!= NULL
) {
1176 g_signal_handler_disconnect (
1177 object_manager
, object_added_handler_id
);
1178 g_signal_handler_disconnect (
1179 object_manager
, object_removed_handler_id
);
1180 g_signal_handler_disconnect (
1181 object_manager
, notify_name_owner_handler_id
);
1182 g_object_unref (object_manager
);
1185 /* Make sure the queue is flushed, because items in it can reference
1186 the main_context, effectively causing it to leak, together with
1187 its GWakeup ([eventfd]) file descriptor. */
1188 while (g_main_context_pending (closure
->main_context
)) {
1189 g_main_context_iteration (closure
->main_context
, FALSE
);
1192 g_main_context_pop_thread_default (closure
->main_context
);
1198 source_registry_set_property (GObject
*object
,
1200 const GValue
*value
,
1203 switch (property_id
) {
1204 case PROP_DEFAULT_ADDRESS_BOOK
:
1205 e_source_registry_set_default_address_book (
1206 E_SOURCE_REGISTRY (object
),
1207 g_value_get_object (value
));
1210 case PROP_DEFAULT_CALENDAR
:
1211 e_source_registry_set_default_calendar (
1212 E_SOURCE_REGISTRY (object
),
1213 g_value_get_object (value
));
1216 case PROP_DEFAULT_MAIL_ACCOUNT
:
1217 e_source_registry_set_default_mail_account (
1218 E_SOURCE_REGISTRY (object
),
1219 g_value_get_object (value
));
1222 case PROP_DEFAULT_MAIL_IDENTITY
:
1223 e_source_registry_set_default_mail_identity (
1224 E_SOURCE_REGISTRY (object
),
1225 g_value_get_object (value
));
1228 case PROP_DEFAULT_MEMO_LIST
:
1229 e_source_registry_set_default_memo_list (
1230 E_SOURCE_REGISTRY (object
),
1231 g_value_get_object (value
));
1234 case PROP_DEFAULT_TASK_LIST
:
1235 e_source_registry_set_default_task_list (
1236 E_SOURCE_REGISTRY (object
),
1237 g_value_get_object (value
));
1241 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
1245 source_registry_get_property (GObject
*object
,
1250 switch (property_id
) {
1251 case PROP_DEFAULT_ADDRESS_BOOK
:
1252 g_value_take_object (
1254 e_source_registry_ref_default_address_book (
1255 E_SOURCE_REGISTRY (object
)));
1258 case PROP_DEFAULT_CALENDAR
:
1259 g_value_take_object (
1261 e_source_registry_ref_default_calendar (
1262 E_SOURCE_REGISTRY (object
)));
1265 case PROP_DEFAULT_MAIL_ACCOUNT
:
1266 g_value_take_object (
1268 e_source_registry_ref_default_mail_account (
1269 E_SOURCE_REGISTRY (object
)));
1272 case PROP_DEFAULT_MAIL_IDENTITY
:
1273 g_value_take_object (
1275 e_source_registry_ref_default_mail_identity (
1276 E_SOURCE_REGISTRY (object
)));
1279 case PROP_DEFAULT_MEMO_LIST
:
1280 g_value_take_object (
1282 e_source_registry_ref_default_memo_list (
1283 E_SOURCE_REGISTRY (object
)));
1286 case PROP_DEFAULT_TASK_LIST
:
1287 g_value_take_object (
1289 e_source_registry_ref_default_task_list (
1290 E_SOURCE_REGISTRY (object
)));
1294 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
1298 source_registry_dispose (GObject
*object
)
1300 ESourceRegistryPrivate
*priv
;
1302 priv
= E_SOURCE_REGISTRY_GET_PRIVATE (object
);
1304 if (priv
->dbus_object_manager
!= NULL
) {
1305 g_object_unref (priv
->dbus_object_manager
);
1306 priv
->dbus_object_manager
= NULL
;
1309 if (priv
->dbus_source_manager
!= NULL
) {
1310 g_object_unref (priv
->dbus_source_manager
);
1311 priv
->dbus_source_manager
= NULL
;
1314 /* Terminate the manager thread after GDBus objects,
1315 because they can schedule GSource-s in the main context there. */
1316 if (priv
->manager_thread
!= NULL
) {
1317 g_main_loop_quit (priv
->thread_closure
->main_loop
);
1318 g_thread_join (priv
->manager_thread
);
1319 priv
->manager_thread
= NULL
;
1322 if (priv
->thread_closure
) {
1323 thread_closure_free (priv
->thread_closure
);
1324 priv
->thread_closure
= NULL
;
1327 g_hash_table_remove_all (priv
->object_path_table
);
1329 g_hash_table_remove_all (priv
->sources
);
1331 if (priv
->main_context
!= NULL
) {
1332 while (g_main_context_pending (priv
->main_context
)) {
1333 g_main_context_iteration (priv
->main_context
, FALSE
);
1335 g_main_context_unref (priv
->main_context
);
1336 priv
->main_context
= NULL
;
1339 if (priv
->settings
!= NULL
) {
1340 g_signal_handlers_disconnect_by_data (priv
->settings
, object
);
1341 g_object_unref (priv
->settings
);
1342 priv
->settings
= NULL
;
1345 /* Chain up to parent's finalize() method. */
1346 G_OBJECT_CLASS (e_source_registry_parent_class
)->dispose (object
);
1350 source_registry_finalize (GObject
*object
)
1352 ESourceRegistryPrivate
*priv
;
1354 priv
= E_SOURCE_REGISTRY_GET_PRIVATE (object
);
1356 g_hash_table_destroy (priv
->object_path_table
);
1357 g_mutex_clear (&priv
->object_path_table_lock
);
1359 g_hash_table_destroy (priv
->service_restart_table
);
1360 g_mutex_clear (&priv
->service_restart_table_lock
);
1362 g_hash_table_destroy (priv
->sources
);
1363 g_mutex_clear (&priv
->sources_lock
);
1365 g_clear_error (&priv
->init_error
);
1366 g_mutex_clear (&priv
->init_lock
);
1368 g_clear_object (&priv
->oauth2_services
);
1370 /* Chain up to parent's finalize() method. */
1371 G_OBJECT_CLASS (e_source_registry_parent_class
)->finalize (object
);
1375 source_registry_initable_init (GInitable
*initable
,
1376 GCancellable
*cancellable
,
1379 ESourceRegistry
*registry
;
1380 ThreadClosure
*closure
;
1381 GError
*local_error
= NULL
;
1383 registry
= E_SOURCE_REGISTRY (initable
);
1385 g_mutex_lock (®istry
->priv
->init_lock
);
1387 if (registry
->priv
->initialized
)
1390 closure
= g_slice_new0 (ThreadClosure
);
1391 closure
->registry
= registry
; /* do not reference */
1392 closure
->main_context
= g_main_context_new ();
1393 /* It's important to pass 'is_running=FALSE' here because
1394 * we wait for the main loop to start running as a way of
1395 * synchronizing with the manager thread. */
1396 closure
->main_loop
= g_main_loop_new (closure
->main_context
, FALSE
);
1397 g_cond_init (&closure
->main_loop_cond
);
1398 g_mutex_init (&closure
->main_loop_mutex
);
1400 registry
->priv
->thread_closure
= closure
;
1402 registry
->priv
->manager_thread
= g_thread_new (
1404 source_registry_object_manager_thread
,
1407 /* Wait for notification that the manager
1408 * thread's main loop has been started. */
1409 g_mutex_lock (&closure
->main_loop_mutex
);
1410 while (!g_main_loop_is_running (closure
->main_loop
))
1412 &closure
->main_loop_cond
,
1413 &closure
->main_loop_mutex
);
1414 g_mutex_unlock (&closure
->main_loop_mutex
);
1416 /* Check for error in the manager thread. */
1417 if (closure
->error
!= NULL
) {
1418 g_dbus_error_strip_remote_error (closure
->error
);
1419 g_propagate_error (®istry
->priv
->init_error
, closure
->error
);
1420 closure
->error
= NULL
;
1424 /* The registry should now be populated with sources.
1426 * XXX Actually, not necessarily if the registry service was
1427 * just now activated. There may yet be a small window
1428 * while the registry service starts up before it exports
1429 * any sources, even built-in sources. This COULD create
1430 * problems if any logic that depends on those built-in
1431 * sources executes during this time window, but so far
1432 * we haven't seen any cases of that.
1434 * Attempts in the past to stop and wait for sources to
1435 * show up have proven problematic. See for example:
1436 * https://bugzilla.gnome.org/678378
1438 * Leave the runtime check disabled for the moment.
1439 * I have a feeling I'll be revisiting this again.
1441 /*g_warn_if_fail (g_hash_table_size (registry->priv->sources) > 0);*/
1443 /* The EDBusSourceManagerProxy is just another D-Bus interface
1444 * that resides at the same object path. It's unrelated to the
1445 * GDBusObjectManagerClient and doesn't need its own thread. */
1446 registry
->priv
->dbus_source_manager
=
1447 e_dbus_source_manager_proxy_new_for_bus_sync (
1449 G_DBUS_PROXY_FLAGS_NONE
,
1450 SOURCES_DBUS_SERVICE_NAME
,
1452 cancellable
, &local_error
);
1454 if (local_error
!= NULL
) {
1455 g_dbus_error_strip_remote_error (local_error
);
1456 g_propagate_error (®istry
->priv
->init_error
, local_error
);
1461 registry
->priv
->initialized
= TRUE
;
1462 g_mutex_unlock (®istry
->priv
->init_lock
);
1464 if (registry
->priv
->init_error
!= NULL
) {
1465 GError
*init_error_copy
;
1467 /* Return a copy of the same error to
1468 * all pending initialization requests. */
1469 init_error_copy
= g_error_copy (registry
->priv
->init_error
);
1470 g_propagate_error (error
, init_error_copy
);
1479 e_source_registry_class_init (ESourceRegistryClass
*class)
1481 GObjectClass
*object_class
;
1483 g_type_class_add_private (class, sizeof (ESourceRegistryPrivate
));
1485 object_class
= G_OBJECT_CLASS (class);
1486 object_class
->set_property
= source_registry_set_property
;
1487 object_class
->get_property
= source_registry_get_property
;
1488 object_class
->dispose
= source_registry_dispose
;
1489 object_class
->finalize
= source_registry_finalize
;
1491 /* The property names correspond to the key names in the
1492 * "org.gnome.Evolution.DefaultSources" GSettings schema. */
1495 * ESourceRegistry:default-address-book:
1497 * The default address book #ESource.
1499 g_object_class_install_property (
1501 PROP_DEFAULT_ADDRESS_BOOK
,
1502 g_param_spec_object (
1503 "default-address-book",
1504 "Default Address Book",
1505 "The default address book ESource",
1508 G_PARAM_STATIC_STRINGS
));
1511 * ESourceRegistry:default-calendar:
1513 * The default calendar #ESource.
1515 g_object_class_install_property (
1517 PROP_DEFAULT_CALENDAR
,
1518 g_param_spec_object (
1521 "The default calendar ESource",
1524 G_PARAM_STATIC_STRINGS
));
1527 * ESourceRegistry:default-mail-account:
1529 * The default mail account #ESource.
1531 g_object_class_install_property (
1533 PROP_DEFAULT_MAIL_ACCOUNT
,
1534 g_param_spec_object (
1535 "default-mail-account",
1536 "Default Mail Account",
1537 "The default mail account ESource",
1540 G_PARAM_STATIC_STRINGS
));
1543 * ESourceRegistry:default-mail-identity:
1545 * The default mail identity #ESource.
1547 g_object_class_install_property (
1549 PROP_DEFAULT_MAIL_IDENTITY
,
1550 g_param_spec_object (
1551 "default-mail-identity",
1552 "Default Mail Identity",
1553 "The default mail identity ESource",
1556 G_PARAM_STATIC_STRINGS
));
1559 * ESourceRegistry:default-memo-list:
1561 * The default memo list #ESource.
1563 g_object_class_install_property (
1565 PROP_DEFAULT_MEMO_LIST
,
1566 g_param_spec_object (
1567 "default-memo-list",
1568 "Default Memo List",
1569 "The default memo list ESource",
1572 G_PARAM_STATIC_STRINGS
));
1575 * ESourceRegistry:default-task-list:
1577 * The default task list #ESource.
1579 g_object_class_install_property (
1581 PROP_DEFAULT_TASK_LIST
,
1582 g_param_spec_object (
1583 "default-task-list",
1584 "Default Task List",
1585 "The default task list ESource",
1588 G_PARAM_STATIC_STRINGS
));
1591 * ESourceRegistry::source-added:
1592 * @registry: the #ESourceRegistry which emitted the signal
1593 * @source: the newly-added #ESource
1595 * Emitted when an #ESource is added to @registry.
1597 signals
[SOURCE_ADDED
] = g_signal_new (
1599 G_OBJECT_CLASS_TYPE (object_class
),
1601 G_STRUCT_OFFSET (ESourceRegistryClass
, source_added
),
1607 * ESourceRegistry::source-changed:
1608 * @registry: the #ESourceRegistry which emitted the signal
1609 * @source: the #ESource that changed
1611 * Emitted when an #ESource registered with @registry emits
1612 * its #ESource::changed signal.
1614 signals
[SOURCE_CHANGED
] = g_signal_new (
1616 G_OBJECT_CLASS_TYPE (object_class
),
1618 G_STRUCT_OFFSET (ESourceRegistryClass
, source_changed
),
1624 * ESourceRegistry::source-removed:
1625 * @registry: the #ESourceRegistry which emitted the signal
1626 * @source: the #ESource that got removed
1628 * Emitted when an #ESource is removed from @registry.
1630 signals
[SOURCE_REMOVED
] = g_signal_new (
1632 G_OBJECT_CLASS_TYPE (object_class
),
1634 G_STRUCT_OFFSET (ESourceRegistryClass
, source_removed
),
1640 * ESourceRegistry::source-enabled:
1641 * @registry: the #ESourceRegistry which emitted the signal
1642 * @source: the #ESource that got enabled
1644 * Emitted when an #ESource #ESource:enabled property becomes %TRUE.
1646 signals
[SOURCE_ENABLED
] = g_signal_new (
1648 G_OBJECT_CLASS_TYPE (object_class
),
1650 G_STRUCT_OFFSET (ESourceRegistryClass
, source_enabled
),
1656 * ESourceRegistry::source-disabled:
1657 * @registry: the #ESourceRegistry which emitted the signal
1658 * @source: the #ESource that got disabled
1660 * Emitted when an #ESource #ESource:enabled property becomes %FALSE.
1662 signals
[SOURCE_DISABLED
] = g_signal_new (
1664 G_OBJECT_CLASS_TYPE (object_class
),
1666 G_STRUCT_OFFSET (ESourceRegistryClass
, source_disabled
),
1672 * ESourceRegistry::credentials-required:
1673 * @registry: the #ESourceRegistry which emitted the signal
1674 * @source: the #ESource that requires credentials
1675 * @reason: an #ESourceCredentialsReason indicating why the credentials are requested
1676 * @certificate_pem: PEM-encoded secure connection certificate for failed SSL checks
1677 * @certificate_errors: what failed with the SSL certificate
1678 * @op_error: a #GError with a description of the error, or %NULL
1680 * The ::credentials-required signal is emitted when the @source
1681 * requires credentials to connect to (possibly remote)
1682 * data store. The credentials can be passed to the source using
1683 * e_source_authenticate() function. The signal is emitted in
1684 * the thread-default main context from the time the @registry was created.
1686 * Note: This is just a proxy signal for the ESource::credentials-required signal.
1688 signals
[CREDENTIALS_REQUIRED
] = g_signal_new (
1689 "credentials-required",
1690 G_TYPE_FROM_CLASS (class),
1691 G_SIGNAL_RUN_LAST
| G_SIGNAL_NO_RECURSE
,
1692 G_STRUCT_OFFSET (ESourceRegistryClass
, credentials_required
),
1696 E_TYPE_SOURCE_CREDENTIALS_REASON
,
1698 G_TYPE_TLS_CERTIFICATE_FLAGS
,
1703 e_source_registry_initable_init (GInitableIface
*iface
)
1705 iface
->init
= source_registry_initable_init
;
1709 e_source_registry_init (ESourceRegistry
*registry
)
1711 registry
->priv
= E_SOURCE_REGISTRY_GET_PRIVATE (registry
);
1713 /* This is so the object manager thread can schedule signal
1714 * emissions on the thread-default context for this thread. */
1715 registry
->priv
->main_context
= g_main_context_ref_thread_default ();
1717 /* D-Bus object path -> ESource */
1718 registry
->priv
->object_path_table
=
1719 g_hash_table_new_full (
1720 (GHashFunc
) g_str_hash
,
1721 (GEqualFunc
) g_str_equal
,
1722 (GDestroyNotify
) g_free
,
1723 (GDestroyNotify
) g_object_unref
);
1725 g_mutex_init (®istry
->priv
->object_path_table_lock
);
1727 /* Set of UID strings */
1728 registry
->priv
->service_restart_table
=
1729 g_hash_table_new_full (
1730 (GHashFunc
) g_str_hash
,
1731 (GEqualFunc
) g_str_equal
,
1732 (GDestroyNotify
) g_free
,
1733 (GDestroyNotify
) NULL
);
1735 g_mutex_init (®istry
->priv
->service_restart_table_lock
);
1737 /* UID string -> ESource */
1738 registry
->priv
->sources
= g_hash_table_new_full (
1739 (GHashFunc
) g_str_hash
,
1740 (GEqualFunc
) g_str_equal
,
1741 (GDestroyNotify
) g_free
,
1742 (GDestroyNotify
) source_registry_unref_source
);
1744 g_mutex_init (®istry
->priv
->sources_lock
);
1746 registry
->priv
->settings
= g_settings_new (GSETTINGS_SCHEMA
);
1749 registry
->priv
->settings
, "changed",
1750 G_CALLBACK (source_registry_settings_changed_cb
), registry
);
1752 g_mutex_init (®istry
->priv
->init_lock
);
1754 registry
->priv
->oauth2_services
= e_oauth2_services_new ();
1758 * e_source_registry_new_sync:
1759 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
1760 * @error: return location for a #GError, or %NULL
1762 * Creates a new #ESourceRegistry front-end for the registry D-Bus service.
1763 * If an error occurs in connecting to the D-Bus service, the function sets
1764 * @error and returns %NULL.
1766 * Since 3.12 a singleton will be returned. No strong reference is kept
1767 * internally, so it is the caller's responsibility to keep one.
1769 * Returns: a new #ESourceRegistry, or %NULL
1774 e_source_registry_new_sync (GCancellable
*cancellable
,
1777 ESourceRegistry
*registry
;
1779 /* XXX Work around http://bugzilla.gnome.org/show_bug.cgi?id=683519
1780 * until GObject's type initialization deadlock issue is fixed.
1781 * Apparently only the synchronous instantiation is affected. */
1782 g_type_ensure (G_TYPE_DBUS_CONNECTION
);
1783 g_type_ensure (G_TYPE_DBUS_PROXY
);
1784 g_type_ensure (G_BUS_TYPE_SESSION
);
1786 registry
= source_registry_dup_uninitialized_singleton ();
1788 if (!g_initable_init (G_INITABLE (registry
), cancellable
, error
))
1789 g_clear_object (®istry
);
1794 /* Helper for e_source_registry_new() */
1796 source_registry_init_cb (GObject
*source_object
,
1797 GAsyncResult
*result
,
1800 GTask
*task
= user_data
;
1801 GError
*local_error
= NULL
;
1803 g_async_initable_init_finish (
1804 G_ASYNC_INITABLE (source_object
), result
, &local_error
);
1806 if (local_error
== NULL
) {
1807 g_task_return_pointer (
1808 task
, g_object_ref (source_object
),
1809 (GDestroyNotify
) g_object_unref
);
1811 g_task_return_error (task
, local_error
);
1814 g_object_unref (task
);
1818 * e_source_registry_new:
1819 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
1820 * @callback: (scope async): a #GAsyncReadyCallback to call when the request
1822 * @user_data: (closure): data to pass to the callback function
1824 * Asynchronously creates a new #ESourceRegistry front-end for the registry
1827 * When the operation is finished, @callback will be called. You can then
1828 * call e_source_registry_new_finish() to get the result of the operation.
1830 * Since 3.12 a singleton will be returned. No strong reference is kept
1831 * internally, so it is the caller's responsibility to keep one.
1836 e_source_registry_new (GCancellable
*cancellable
,
1837 GAsyncReadyCallback callback
,
1840 ESourceRegistry
*registry
;
1843 task
= g_task_new (NULL
, cancellable
, callback
, user_data
);
1845 registry
= source_registry_dup_uninitialized_singleton ();
1847 g_async_initable_init_async (
1848 G_ASYNC_INITABLE (registry
),
1849 G_PRIORITY_DEFAULT
, cancellable
,
1850 source_registry_init_cb
, task
);
1852 g_object_unref (registry
);
1856 * e_source_registry_new_finish:
1857 * @result: a #GAsyncResult
1858 * @error: return location for a #GError, or %NULL
1860 * Finishes the operation started with e_source_registry_new_finish().
1861 * If an error occurs in connecting to the D-Bus service, the function
1862 * sets @error and returns %NULL.
1864 * Returns: a new #ESourceRegistry, or %NULL
1869 e_source_registry_new_finish (GAsyncResult
*result
,
1872 g_return_val_if_fail (g_task_is_valid (result
, NULL
), NULL
);
1874 return g_task_propagate_pointer (G_TASK (result
), error
);
1878 * e_source_registry_get_oauth2_services:
1879 * @registry: an #ESourceRegistry
1881 * Returns: (transfer none): an instance of #EOAuth2Services, owned by @registry
1886 e_source_registry_get_oauth2_services (ESourceRegistry
*registry
)
1888 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
1890 return registry
->priv
->oauth2_services
;
1893 /* Helper for e_source_registry_commit_source() */
1895 source_registry_commit_source_thread (GSimpleAsyncResult
*simple
,
1897 GCancellable
*cancellable
)
1899 AsyncContext
*async_context
;
1900 GError
*local_error
= NULL
;
1902 async_context
= g_simple_async_result_get_op_res_gpointer (simple
);
1904 e_source_registry_commit_source_sync (
1905 E_SOURCE_REGISTRY (object
),
1906 async_context
->source
,
1907 cancellable
, &local_error
);
1909 if (local_error
!= NULL
)
1910 g_simple_async_result_take_error (simple
, local_error
);
1914 * e_source_registry_commit_source_sync:
1915 * @registry: an #ESourceRegistry
1916 * @source: an #ESource with changes to commit
1917 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
1918 * @error: return location for #GError, or %NULL
1920 * This is a convenience function intended for use with graphical
1921 * #ESource editors. Call this function when the user is finished
1922 * making changes to @source.
1924 * If @source has a #GDBusObject, its contents are submitted to the D-Bus
1925 * service through e_source_write_sync().
1927 * If @source does NOT have a #GDBusObject (implying it's a scratch
1928 * #ESource), its contents are submitted to the D-Bus service through
1929 * either e_source_remote_create_sync() if @source is to be a collection
1930 * member, or e_source_registry_create_sources_sync() if @source to be an
1931 * independent data source.
1933 * If an error occurs, the function will set @error and return %FALSE.
1935 * Returns: %TRUE on success, %FALSE on failure
1940 e_source_registry_commit_source_sync (ESourceRegistry
*registry
,
1942 GCancellable
*cancellable
,
1945 GDBusObject
*dbus_object
;
1946 ESource
*collection_source
;
1947 gboolean collection_member
;
1950 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), FALSE
);
1951 g_return_val_if_fail (E_IS_SOURCE (source
), FALSE
);
1953 dbus_object
= e_source_ref_dbus_object (source
);
1955 collection_source
= e_source_registry_find_extension (
1956 registry
, source
, E_SOURCE_EXTENSION_COLLECTION
);
1959 (collection_source
!= NULL
) &&
1960 (collection_source
!= source
);
1962 if (dbus_object
!= NULL
) {
1963 success
= e_source_write_sync (source
, cancellable
, error
);
1964 g_object_unref (dbus_object
);
1966 } else if (collection_member
) {
1967 success
= e_source_remote_create_sync (
1968 collection_source
, source
, cancellable
, error
);
1971 GList
*list
= g_list_prepend (NULL
, source
);
1972 success
= e_source_registry_create_sources_sync (
1973 registry
, list
, cancellable
, error
);
1977 if (collection_source
!= NULL
)
1978 g_object_unref (collection_source
);
1984 * e_source_registry_commit_source:
1985 * @registry: an #ESourceRegistry
1986 * @source: an #ESource with changes to commit
1987 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
1988 * @callback: (scope async): a #GAsyncReadyCallback to call when the request
1990 * @user_data: (closure): data to pass to the callback function
1992 * See e_source_registry_commit_source_sync() for details.
1994 * When the operation is finished, @callback will be called. You can then
1995 * call e_source_registry_commit_source_finish() to get the result of the
2001 e_source_registry_commit_source (ESourceRegistry
*registry
,
2003 GCancellable
*cancellable
,
2004 GAsyncReadyCallback callback
,
2007 GSimpleAsyncResult
*simple
;
2008 AsyncContext
*async_context
;
2010 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry
));
2011 g_return_if_fail (E_IS_SOURCE (source
));
2013 async_context
= g_slice_new0 (AsyncContext
);
2014 async_context
->source
= g_object_ref (source
);
2016 simple
= g_simple_async_result_new (
2017 G_OBJECT (registry
), callback
, user_data
,
2018 e_source_registry_commit_source
);
2020 g_simple_async_result_set_check_cancellable (simple
, cancellable
);
2022 g_simple_async_result_set_op_res_gpointer (
2023 simple
, async_context
, (GDestroyNotify
) async_context_free
);
2025 g_simple_async_result_run_in_thread (
2026 simple
, source_registry_commit_source_thread
,
2027 G_PRIORITY_DEFAULT
, cancellable
);
2029 g_object_unref (simple
);
2033 * e_source_registry_commit_source_finish:
2034 * @registry: an #ESourceRegistry
2035 * @result: a #GAsyncResult
2036 * @error: return location for a #GError, or %NULL
2038 * Finishes the operation started with e_source_registry_commit_source().
2040 * If an error occurred, the function will set @error and return %FALSE.
2042 * Returns: %TRUE on success, %FALSE on failure
2047 e_source_registry_commit_source_finish (ESourceRegistry
*registry
,
2048 GAsyncResult
*result
,
2051 GSimpleAsyncResult
*simple
;
2053 g_return_val_if_fail (
2054 g_simple_async_result_is_valid (
2055 result
, G_OBJECT (registry
),
2056 e_source_registry_commit_source
), FALSE
);
2058 simple
= G_SIMPLE_ASYNC_RESULT (result
);
2060 /* Assume success unless a GError is set. */
2061 return !g_simple_async_result_propagate_error (simple
, error
);
2064 /* Helper for e_source_registry_create_sources() */
2066 source_registry_create_sources_thread (GSimpleAsyncResult
*simple
,
2068 GCancellable
*cancellable
)
2070 AsyncContext
*async_context
;
2071 GError
*local_error
= NULL
;
2073 async_context
= g_simple_async_result_get_op_res_gpointer (simple
);
2075 e_source_registry_create_sources_sync (
2076 E_SOURCE_REGISTRY (object
),
2077 async_context
->list_of_sources
,
2078 cancellable
, &local_error
);
2080 if (local_error
!= NULL
)
2081 g_simple_async_result_take_error (simple
, local_error
);
2084 /* Helper for e_source_registry_create_sources_sync() */
2086 source_registry_create_sources_main_loop_quit_cb (gpointer user_data
)
2088 GMainLoop
*main_loop
= user_data
;
2090 g_main_loop_quit (main_loop
);
2095 /* Helper for e_source_registry_create_sources_sync() */
2097 source_registry_create_sources_object_added_cb (GDBusObjectManager
*object_manager
,
2098 GDBusObject
*dbus_object
,
2099 CreateContext
*create_context
)
2103 uid
= source_registry_dbus_object_dup_uid (dbus_object
);
2106 g_hash_table_remove (create_context
->pending_uids
, uid
);
2110 /* The hash table will be empty when all of the expected
2111 * GDBusObjects have been added to the GDBusObjectManager. */
2112 if (g_hash_table_size (create_context
->pending_uids
) == 0) {
2113 GSource
*idle_source
;
2115 idle_source
= g_idle_source_new ();
2116 g_source_set_callback (
2118 source_registry_create_sources_main_loop_quit_cb
,
2119 g_main_loop_ref (create_context
->main_loop
),
2120 (GDestroyNotify
) g_main_loop_unref
);
2121 g_source_attach (idle_source
, create_context
->main_context
);
2122 g_source_unref (idle_source
);
2127 * e_source_registry_create_sources_sync:
2128 * @registry: an #ESourceRegistry
2129 * @list_of_sources: (element-type ESource): a list of #ESource instances with
2131 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
2132 * @error: return location for a #GError, or %NULL
2134 * Requests the D-Bus service create new key files for each #ESource in
2135 * @list_of_sources. Each list element must be a scratch #ESource with
2138 * If an error occurs, the function will set @error and return %FALSE.
2140 * Returns: %TRUE on success, %FALSE on failure
2145 e_source_registry_create_sources_sync (ESourceRegistry
*registry
,
2146 GList
*list_of_sources
,
2147 GCancellable
*cancellable
,
2150 CreateContext
*create_context
;
2151 GVariantBuilder builder
;
2154 gulong object_added_id
;
2155 GError
*local_error
= NULL
;
2157 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), FALSE
);
2159 /* Verify the list elements are all ESources. */
2160 for (link
= list_of_sources
; link
!= NULL
; link
= g_list_next (link
))
2161 g_return_val_if_fail (E_IS_SOURCE (link
->data
), FALSE
);
2163 create_context
= create_context_new ();
2164 g_main_context_push_thread_default (create_context
->main_context
);
2166 g_variant_builder_init (&builder
, G_VARIANT_TYPE_ARRAY
);
2168 for (link
= list_of_sources
; link
!= NULL
; link
= g_list_next (link
)) {
2173 source
= E_SOURCE (link
->data
);
2174 uid
= e_source_dup_uid (source
);
2176 /* Takes ownership of the UID string. */
2177 g_hash_table_add (create_context
->pending_uids
, uid
);
2179 source_data
= e_source_to_string (source
, NULL
);
2180 g_variant_builder_add (&builder
, "{ss}", uid
, source_data
);
2181 g_free (source_data
);
2184 variant
= g_variant_builder_end (&builder
);
2186 /* Use G_CONNECT_AFTER so source_registry_object_added_cb()
2187 * runs first and actually adds the ESource to the internal
2188 * hash table before we go quitting our main loop. */
2189 object_added_id
= g_signal_connect_after (
2190 registry
->priv
->dbus_object_manager
, "object-added",
2191 G_CALLBACK (source_registry_create_sources_object_added_cb
),
2194 /* This function sinks the floating GVariant reference. */
2195 e_dbus_source_manager_call_create_sources_sync (
2196 registry
->priv
->dbus_source_manager
,
2197 variant
, cancellable
, &local_error
);
2199 g_variant_builder_clear (&builder
);
2201 /* Wait for an "object-added" signal for each created ESource.
2202 * But also set a short timeout to avoid getting stuck here in
2203 * case the registry service adds sources to its orphan table,
2204 * which prevents them from being exported over D-Bus. */
2205 if (local_error
== NULL
) {
2206 GSource
*timeout_source
;
2208 timeout_source
= g_timeout_source_new_seconds (2);
2209 g_source_set_callback (
2211 source_registry_create_sources_main_loop_quit_cb
,
2212 g_main_loop_ref (create_context
->main_loop
),
2213 (GDestroyNotify
) g_main_loop_unref
);
2214 g_source_attach (timeout_source
, create_context
->main_context
);
2215 g_source_unref (timeout_source
);
2217 g_main_loop_run (create_context
->main_loop
);
2220 g_signal_handler_disconnect (
2221 registry
->priv
->dbus_object_manager
, object_added_id
);
2223 g_main_context_pop_thread_default (create_context
->main_context
);
2224 create_context_free (create_context
);
2226 if (local_error
!= NULL
) {
2227 g_dbus_error_strip_remote_error (local_error
);
2228 g_propagate_error (error
, local_error
);
2236 * e_source_registry_create_sources:
2237 * @registry: an #ESourceRegistry
2238 * @list_of_sources: (element-type ESource): a list of #ESource instances with
2240 * @cancellable: (allow-none): optional #GCancellable object, or %NULL
2241 * @callback: (scope async): a #GAsyncReadyCallback to call when the request
2243 * @user_data: (closure): data to pass to the callback function
2245 * Asynchronously requests the D-Bus service create new key files for each
2246 * #ESource in @list_of_sources. Each list element must be a scratch
2247 * #ESource with no #GDBusObject.
2249 * When the operation is finished, @callback will be called. You can then
2250 * call e_source_registry_create_sources_finish() to get the result of the
2256 e_source_registry_create_sources (ESourceRegistry
*registry
,
2257 GList
*list_of_sources
,
2258 GCancellable
*cancellable
,
2259 GAsyncReadyCallback callback
,
2262 GSimpleAsyncResult
*simple
;
2263 AsyncContext
*async_context
;
2266 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry
));
2268 /* Verify the list elements are all ESources. */
2269 for (link
= list_of_sources
; link
!= NULL
; link
= g_list_next (link
))
2270 g_return_if_fail (E_IS_SOURCE (link
->data
));
2272 async_context
= g_slice_new0 (AsyncContext
);
2273 async_context
->list_of_sources
= g_list_copy (list_of_sources
);
2276 async_context
->list_of_sources
,
2277 (GFunc
) g_object_ref
, NULL
);
2279 simple
= g_simple_async_result_new (
2280 G_OBJECT (registry
), callback
, user_data
,
2281 e_source_registry_create_sources
);
2283 g_simple_async_result_set_check_cancellable (simple
, cancellable
);
2285 g_simple_async_result_set_op_res_gpointer (
2286 simple
, async_context
, (GDestroyNotify
) async_context_free
);
2288 g_simple_async_result_run_in_thread (
2289 simple
, source_registry_create_sources_thread
,
2290 G_PRIORITY_DEFAULT
, cancellable
);
2292 g_object_unref (simple
);
2296 * e_source_registry_create_sources_finish:
2297 * @registry: an #ESourceRegistry
2298 * @result: a #GAsyncResult
2299 * @error: return location for a #GError, or %NULL
2301 * Finishes the operation started with e_source_registry_create_sources().
2303 * If an error occurred, the function will set @error and return %FALSE.
2305 * Returns: %TRUE on success, %FALSE on failure
2310 e_source_registry_create_sources_finish (ESourceRegistry
*registry
,
2311 GAsyncResult
*result
,
2314 GSimpleAsyncResult
*simple
;
2316 g_return_val_if_fail (
2317 g_simple_async_result_is_valid (
2318 result
, G_OBJECT (registry
),
2319 e_source_registry_create_sources
), FALSE
);
2321 simple
= G_SIMPLE_ASYNC_RESULT (result
);
2323 /* Assume success unless a GError is set. */
2324 return !g_simple_async_result_propagate_error (simple
, error
);
2328 * e_source_registry_refresh_backend_sync:
2329 * @registry: an #ESourceRegistry
2330 * @source_uid: UID of a collection #ESource whose backend to refresh
2331 * @cancellable: optional #GCancellable object, or %NULL
2332 * @error: return location for a #GError, or %NULL
2334 * Requests the D-Bus service to refresh collection backend for an #ESource
2335 * with UID @source_uid. The result means that the refresh had been scheduled
2336 * not whether the refresh itself succeeded. The refresh is not initiated
2337 * when the collection backend is offline.
2339 * If an error occurs, the function will set @error and return %FALSE.
2341 * Returns: Whether succeeded
2346 e_source_registry_refresh_backend_sync (ESourceRegistry
*registry
,
2347 const gchar
*source_uid
,
2348 GCancellable
*cancellable
,
2351 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), FALSE
);
2352 g_return_val_if_fail (source_uid
!= NULL
, FALSE
);
2354 return e_dbus_source_manager_call_refresh_backend_sync (
2355 registry
->priv
->dbus_source_manager
,
2356 source_uid
, cancellable
, error
);
2360 e_source_registry_refresh_backend_thread (GTask
*task
,
2361 gpointer source_object
,
2363 GCancellable
*cancellable
)
2366 GError
*local_error
= NULL
;
2368 success
= e_source_registry_refresh_backend_sync (source_object
, task_data
, cancellable
, &local_error
);
2371 g_task_return_error (task
, local_error
);
2373 g_task_return_boolean (task
, success
);
2377 * e_source_registry_refresh_backend:
2378 * @registry: an #ESourceRegistry
2379 * @source_uid: UID of a collection #ESource whose backend to refresh
2380 * @cancellable: optional #GCancellable object, or %NULL
2381 * @callback: (scope async): a #GAsyncReadyCallback to call when the request
2383 * @user_data: (closure): data to pass to the callback function
2385 * Asynchronously requests the D-Bus service to refresh collection backend
2386 * for an #ESource with UID @source_uid. The result means that the refresh
2387 * had been scheduled not whether the refresh itself succeeded. The refresh
2388 * is not initiated when the collection backend is offline.
2390 * When the operation is finished, @callback will be called. You can then
2391 * call e_source_registry_refresh_backend_finish() to get the result of
2397 e_source_registry_refresh_backend (ESourceRegistry
*registry
,
2398 const gchar
*source_uid
,
2399 GCancellable
*cancellable
,
2400 GAsyncReadyCallback callback
,
2405 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry
));
2406 g_return_if_fail (source_uid
!= NULL
);
2408 task
= g_task_new (registry
, cancellable
, callback
, user_data
);
2409 g_task_set_source_tag (task
, e_source_registry_refresh_backend
);
2410 g_task_set_task_data (task
, g_strdup (source_uid
), g_free
);
2412 g_task_run_in_thread (task
, e_source_registry_refresh_backend_thread
);
2414 g_object_unref (task
);
2418 * e_source_registry_refresh_backend_finish:
2419 * @registry: an #ESourceRegistry
2420 * @result: a #GAsyncResult
2421 * @error: return location for a #GError, or %NULL
2423 * Finishes the operation started with e_source_registry_refresh_backend().
2425 * If an error occurred, the function will set @error and return %FALSE.
2427 * Returns: Whether succeeded
2432 e_source_registry_refresh_backend_finish (ESourceRegistry
*registry
,
2433 GAsyncResult
*result
,
2436 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), FALSE
);
2437 g_return_val_if_fail (g_task_is_valid (result
, registry
), FALSE
);
2438 g_return_val_if_fail (g_async_result_is_tagged (result
, e_source_registry_refresh_backend
), FALSE
);
2440 return g_task_propagate_boolean (G_TASK (result
), error
);
2444 * e_source_registry_ref_source:
2445 * @registry: an #ESourceRegistry
2446 * @uid: a unique identifier string
2448 * Looks up an #ESource in @registry by its unique identifier string.
2450 * The returned #ESource is referenced for thread-safety and must be
2451 * unreferenced with g_object_unref() when finished with it.
2453 * Returns: (transfer full): an #ESource, or %NULL if no match was found
2458 e_source_registry_ref_source (ESourceRegistry
*registry
,
2461 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
2462 g_return_val_if_fail (uid
!= NULL
, NULL
);
2464 return source_registry_sources_lookup (registry
, uid
);
2468 * e_source_registry_list_sources:
2469 * @registry: an #ESourceRegistry
2470 * @extension_name: (allow-none): an extension name, or %NULL
2472 * Returns a list of registered sources, sorted by display name. If
2473 * @extension_name is given, restrict the list to sources having that
2476 * The sources returned in the list are referenced for thread-safety.
2477 * They must each be unreferenced with g_object_unref() when finished
2478 * with them. Free the returned list itself with g_list_free().
2480 * An easy way to free the list properly in one step is as follows:
2483 * g_list_free_full (list, g_object_unref);
2486 * Returns: (element-type ESource) (transfer full): a sorted list of sources
2491 e_source_registry_list_sources (ESourceRegistry
*registry
,
2492 const gchar
*extension_name
)
2495 GQueue trash
= G_QUEUE_INIT
;
2497 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
2499 list
= g_list_sort (
2500 source_registry_sources_get_values (registry
),
2501 (GCompareFunc
) e_source_compare_by_display_name
);
2503 if (extension_name
== NULL
)
2506 for (link
= list
; link
!= NULL
; link
= g_list_next (link
)) {
2507 ESource
*source
= E_SOURCE (link
->data
);
2509 if (!e_source_has_extension (source
, extension_name
)) {
2510 g_queue_push_tail (&trash
, link
);
2511 g_object_unref (source
);
2515 /* We do want pop_head() here, not pop_head_link(). */
2516 while ((link
= g_queue_pop_head (&trash
)) != NULL
)
2517 list
= g_list_delete_link (list
, link
);
2523 * e_source_registry_list_enabled:
2524 * @registry: an #ESourceRegistry
2525 * @extension_name: (allow-none): an extension name, or %NULL
2527 * Similar to e_source_registry_list_sources(), but returns only enabled
2528 * sources according to e_source_registry_check_enabled().
2530 * The sources returned in the list are referenced for thread-safety.
2531 * They must each be unreferenced with g_object_unref() when finished
2532 * with them. Free the returned list itself with g_list_free().
2534 * An easy way to free the list properly in one step is as follows:
2537 * g_list_free_full (list, g_object_unref);
2540 * Returns: (element-type ESource) (transfer full): a sorted list of sources
2545 e_source_registry_list_enabled (ESourceRegistry
*registry
,
2546 const gchar
*extension_name
)
2549 GQueue trash
= G_QUEUE_INIT
;
2551 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
2553 list
= e_source_registry_list_sources (registry
, extension_name
);
2555 for (link
= list
; link
!= NULL
; link
= g_list_next (link
)) {
2556 ESource
*source
= E_SOURCE (link
->data
);
2558 if (!e_source_registry_check_enabled (registry
, source
)) {
2559 g_queue_push_tail (&trash
, link
);
2560 g_object_unref (source
);
2564 /* We do want pop_head() here, not pop_head_link(). */
2565 while ((link
= g_queue_pop_head (&trash
)) != NULL
)
2566 list
= g_list_delete_link (list
, link
);
2572 * e_source_registry_find_extension:
2573 * @registry: an #ESourceRegistry
2574 * @source: an #ESource
2575 * @extension_name: the extension name to find
2577 * Examines @source and its ancestors and returns the "deepest" #ESource
2578 * having an #ESourceExtension with the given @extension_name. If neither
2579 * @source nor any of its ancestors have such an extension, the function
2582 * This function is useful in cases when an #ESourceExtension is meant to
2583 * apply to both the #ESource it belongs to and the #ESource's descendants.
2585 * A common example is the #ESourceCollection extension, where descendants
2586 * of an #ESource having an #ESourceCollection extension are implied to be
2587 * members of that collection. In that example, this function can be used
2588 * to test whether @source is a member of a collection.
2590 * The returned #ESource is referenced for thread-safety and must be
2591 * unreferenced with g_object_unref() when finished with it.
2593 * Note the function returns the #ESource containing the #ESourceExtension
2594 * instead of the #ESourceExtension itself because extension instances are
2595 * not to be referenced directly (see e_source_get_extension()).
2597 * Returns: (transfer full): an #ESource, or %NULL if no match was found
2602 e_source_registry_find_extension (ESourceRegistry
*registry
,
2604 const gchar
*extension_name
)
2606 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
2607 g_return_val_if_fail (E_IS_SOURCE (source
), NULL
);
2608 g_return_val_if_fail (extension_name
!= NULL
, NULL
);
2610 g_object_ref (source
);
2612 while (!e_source_has_extension (source
, extension_name
)) {
2615 uid
= e_source_dup_parent (source
);
2617 g_object_unref (source
);
2621 source
= e_source_registry_ref_source (registry
, uid
);
2633 * e_source_registry_check_enabled:
2634 * @registry: an #ESourceRegistry
2635 * @source: an #ESource
2637 * Determines whether @source is "effectively" enabled by examining its
2638 * own #ESource:enabled property as well as those of its ancestors in the
2639 * #ESource hierarchy. If all examined #ESource:enabled properties are
2640 * %TRUE, then the function returns %TRUE. If any are %FALSE, then the
2641 * function returns %FALSE.
2643 * Use this function instead of e_source_get_enabled() to determine
2644 * things like whether to display an #ESource in a user interface or
2645 * whether to act on the data set described by the #ESource.
2647 * Returns: whether @source is "effectively" enabled
2652 e_source_registry_check_enabled (ESourceRegistry
*registry
,
2658 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), FALSE
);
2659 g_return_val_if_fail (E_IS_SOURCE (source
), FALSE
);
2661 enabled
= e_source_get_enabled (source
);
2662 parent_uid
= e_source_dup_parent (source
);
2664 while (enabled
&& parent_uid
!= NULL
) {
2667 parent
= e_source_registry_ref_source (registry
, parent_uid
);
2669 g_free (parent_uid
);
2672 if (parent
!= NULL
) {
2673 enabled
= e_source_get_enabled (parent
);
2674 parent_uid
= e_source_dup_parent (parent
);
2675 g_object_unref (parent
);
2679 g_free (parent_uid
);
2684 /* Helper for e_source_registry_build_display_tree() */
2686 source_registry_compare_nodes (GNode
*node_a
,
2689 ESource
*source_a
= E_SOURCE (node_a
->data
);
2690 ESource
*source_b
= E_SOURCE (node_b
->data
);
2691 const gchar
*uid_a
, *uid_b
;
2693 uid_a
= e_source_get_uid (source_a
);
2694 uid_b
= e_source_get_uid (source_b
);
2696 /* Sanity check, with runtime warnings. */
2697 if (uid_a
== NULL
) {
2698 g_warn_if_reached ();
2701 if (uid_b
== NULL
) {
2702 g_warn_if_reached ();
2706 /* The built-in "local-stub" source comes first at depth 1. */
2708 if (g_strcmp0 (uid_a
, "local-stub") == 0)
2711 if (g_strcmp0 (uid_b
, "local-stub") == 0)
2714 /* The built-in "system-*" sources come first at depth 2. */
2716 if (g_str_has_prefix (uid_a
, "system-"))
2719 if (g_str_has_prefix (uid_b
, "system-"))
2722 return e_source_compare_by_display_name (source_a
, source_b
);
2725 /* Helper for e_source_registry_build_display_tree() */
2727 source_registry_prune_nodes (GNode
*node
,
2728 const gchar
*extension_name
)
2730 GQueue queue
= G_QUEUE_INIT
;
2733 /* Unlink all the child nodes and place them in a queue. */
2734 while ((child_node
= g_node_first_child (node
)) != NULL
) {
2735 g_node_unlink (child_node
);
2736 g_queue_push_tail (&queue
, child_node
);
2739 /* Sort the queue by source name. */
2741 &queue
, (GCompareDataFunc
)
2742 source_registry_compare_nodes
, NULL
);
2744 /* Pop nodes off the head of the queue until the queue is empty.
2745 * If the node has either its own children or the given extension
2746 * name, put it back under the parent node (preserving the sorted
2747 * order). Otherwise delete the node and its descendants. */
2748 while ((child_node
= g_queue_pop_head (&queue
)) != NULL
) {
2749 ESource
*child
= E_SOURCE (child_node
->data
);
2750 gboolean append_child_node
= FALSE
;
2752 if (extension_name
== NULL
)
2753 append_child_node
= e_source_get_enabled (child
);
2755 else if (e_source_has_extension (child
, extension_name
))
2756 append_child_node
= e_source_get_enabled (child
);
2758 else if (g_node_first_child (child_node
) != NULL
)
2759 append_child_node
= e_source_get_enabled (child
);
2761 if (append_child_node
)
2762 g_node_append (node
, child_node
);
2764 e_source_registry_free_display_tree (child_node
);
2771 * e_source_registry_build_display_tree: (skip)
2772 * @registry: an #ESourceRegistry
2773 * @extension_name: (allow-none): an extension name, or %NULL
2775 * Returns a single #GNode tree of registered sources that can be used to
2776 * populate a #GtkTreeModel. (The root #GNode is just an empty placeholder.)
2778 * Similar to e_source_registry_list_sources(), an @extension_name can be
2779 * given to restrict the tree to sources having that extension name. Parents
2780 * of matched sources are included in the tree regardless of whether they have
2781 * an extension named @extension_name.
2783 * Disabled leaf nodes are automatically excluded from the #GNode tree.
2785 * The sources returned in the tree are referenced for thread-safety.
2786 * They must each be unreferenced with g_object_unref() when finished
2787 * with them. Free the returned tree itself with g_node_destroy().
2788 * For convenience, e_source_registry_free_display_tree() does all
2791 * Returns: (element-type ESource) (transfer full): a tree of sources,
2792 * arranged for display
2797 e_source_registry_build_display_tree (ESourceRegistry
*registry
,
2798 const gchar
*extension_name
)
2802 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
2804 /* Assemble all data sources into a tree. */
2805 root
= source_registry_sources_build_tree (registry
);
2807 /* Prune unwanted nodes from the copied source trees.
2808 * This must be done in "post" order (children first)
2809 * since it reorders and deletes child nodes. */
2811 root
, G_POST_ORDER
, G_TRAVERSE_ALL
, -1,
2812 (GNodeTraverseFunc
) source_registry_prune_nodes
,
2813 (gpointer
) extension_name
);
2818 /* Helper for e_source_registry_free_display_tree() */
2820 source_registry_unref_nodes (GNode
*node
)
2822 while (node
!= NULL
) {
2823 if (node
->children
!= NULL
)
2824 source_registry_unref_nodes (node
->children
);
2825 if (node
->data
!= NULL
)
2826 g_object_unref (node
->data
);
2832 * e_source_registry_free_display_tree:
2833 * @display_tree: a tree of sources, arranged for display
2835 * Convenience function to free a #GNode tree of registered
2836 * sources created by e_source_registry_build_display_tree().
2841 e_source_registry_free_display_tree (GNode
*display_tree
)
2843 g_return_if_fail (display_tree
!= NULL
);
2845 /* XXX This would be easier if GLib had something like
2846 * g_node_destroy_full() which took a GDestroyNotify.
2847 * Then the tree would not have to be traversed twice. */
2849 source_registry_unref_nodes (display_tree
);
2850 g_node_destroy (display_tree
);
2854 * e_source_registry_dup_unique_display_name:
2855 * @registry: an #ESourceRegistry
2856 * @source: an #ESource
2857 * @extension_name: (allow-none): an extension name, or %NULL
2859 * Compares @source's #ESource:display-name against other sources having
2860 * an #ESourceExtension named @extension_name, if given, or else against
2861 * all other sources in the @registry.
2863 * If @sources's #ESource:display-name is unique among these other sources,
2864 * the function will return the #ESource:display-name verbatim. Otherwise
2865 * the function will construct a string that includes the @sources's own
2866 * #ESource:display-name as well as those of its ancestors.
2868 * The function's return value is intended to be used in messages shown to
2869 * the user to help clarify which source is being referred to. It assumes
2870 * @source's #ESource:display-name is at least unique among its siblings.
2872 * Free the returned string with g_free() when finished with it.
2874 * Returns: a unique display name for @source
2879 e_source_registry_dup_unique_display_name (ESourceRegistry
*registry
,
2881 const gchar
*extension_name
)
2885 gchar
*display_name
;
2886 gboolean need_clarification
= FALSE
;
2888 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
2889 g_return_val_if_fail (E_IS_SOURCE (source
), NULL
);
2891 list
= e_source_registry_list_sources (registry
, extension_name
);
2893 /* Remove the input source from the list, if present. */
2894 link
= g_list_find (list
, source
);
2896 g_object_unref (link
->data
);
2897 list
= g_list_delete_link (list
, link
);
2900 /* Now find another source with a matching display name. */
2901 link
= g_list_find_custom (
2902 list
, source
, (GCompareFunc
)
2903 e_source_compare_by_display_name
);
2905 need_clarification
= (link
!= NULL
);
2907 g_list_free_full (list
, (GDestroyNotify
) g_object_unref
);
2910 display_name
= e_source_dup_display_name (source
);
2911 buffer
= g_string_new (display_name
);
2912 g_free (display_name
);
2914 if (need_clarification
) {
2915 /* Build a list of ancestor sources. */
2917 g_object_ref (source
);
2919 while (source
!= NULL
) {
2922 parent_uid
= e_source_dup_parent (source
);
2924 g_object_unref (source
);
2927 if (parent_uid
!= NULL
) {
2928 source
= e_source_registry_ref_source (
2929 registry
, parent_uid
);
2930 g_free (parent_uid
);
2933 if (source
!= NULL
) {
2934 g_object_ref (source
);
2935 list
= g_list_prepend (list
, source
);
2939 /* Display the ancestor names from the most distant
2940 * ancestor to the input source's immediate parent. */
2943 g_string_append (buffer
, " (");
2945 for (link
= list
; link
!= NULL
; link
= g_list_next (link
)) {
2947 g_string_append (buffer
, " / ");
2949 source
= E_SOURCE (link
->data
);
2950 display_name
= e_source_dup_display_name (source
);
2951 g_string_append (buffer
, display_name
);
2952 g_free (display_name
);
2956 g_string_append (buffer
, ")");
2958 g_list_free_full (list
, (GDestroyNotify
) g_object_unref
);
2961 return g_string_free (buffer
, FALSE
);
2964 /* Helper for e_source_registry_debug_dump() */
2966 source_registry_debug_dump_cb (GNode
*node
)
2970 /* Root node is an empty placeholder. */
2971 if (G_NODE_IS_ROOT (node
))
2974 depth
= g_node_depth (node
);
2975 for (ii
= 2; ii
< depth
; ii
++)
2978 if (E_IS_SOURCE (node
->data
)) {
2979 ESource
*source
= E_SOURCE (node
->data
);
2980 g_print ("\"%s\" ", e_source_get_display_name (source
));
2981 g_print ("(%s)", e_source_get_uid (source
));
2990 * e_source_registry_debug_dump:
2991 * @registry: an #ESourceRegistry
2992 * @extension_name: (allow-none): an extension name, or %NULL
2994 * Handy debugging function that uses e_source_registry_build_display_tree()
2995 * to print a tree of registered sources to standard output.
3000 e_source_registry_debug_dump (ESourceRegistry
*registry
,
3001 const gchar
*extension_name
)
3005 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry
));
3007 root
= e_source_registry_build_display_tree (registry
, extension_name
);
3010 root
, G_PRE_ORDER
, G_TRAVERSE_ALL
, -1,
3011 (GNodeTraverseFunc
) source_registry_debug_dump_cb
, NULL
);
3013 e_source_registry_free_display_tree (root
);
3017 * e_source_registry_ref_builtin_address_book:
3018 * @registry: an #ESourceRegistry
3020 * Returns the built-in address book #ESource.
3022 * This #ESource is always present and makes for a safe fallback.
3024 * The returned #ESource is referenced for thread-safety and must be
3025 * unreferenced with g_object_unref() when finished with it.
3027 * Returns: (transfer full): the built-in address book #ESource
3032 e_source_registry_ref_builtin_address_book (ESourceRegistry
*registry
)
3037 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
3039 uid
= E_SOURCE_BUILTIN_ADDRESS_BOOK_UID
;
3040 source
= e_source_registry_ref_source (registry
, uid
);
3041 g_return_val_if_fail (source
!= NULL
, NULL
);
3047 * e_source_registry_ref_builtin_calendar:
3048 * @registry: an #ESourceRegistry
3050 * Returns the built-in calendar #ESource.
3052 * This #ESource is always present and makes for a safe fallback.
3054 * The returned #ESource is referenced for thread-safety and must be
3055 * unreferenced with g_object_unref() when finished with it.
3057 * Returns: (transfer full): the built-in calendar #ESource
3062 e_source_registry_ref_builtin_calendar (ESourceRegistry
*registry
)
3067 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
3069 uid
= E_SOURCE_BUILTIN_CALENDAR_UID
;
3070 source
= e_source_registry_ref_source (registry
, uid
);
3071 g_return_val_if_fail (source
!= NULL
, NULL
);
3077 * e_source_registry_ref_builtin_mail_account:
3078 * @registry: an #ESourceRegistry
3080 * Returns the built-in mail account #ESource.
3082 * This #ESource is always present and makes for a safe fallback.
3084 * The returned #ESource is referenced for thread-safety and must be
3085 * unreferenced with g_object_unref() when finished with it.
3087 * Returns: (transfer full): the built-in mail account #ESource
3092 e_source_registry_ref_builtin_mail_account (ESourceRegistry
*registry
)
3097 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
3099 uid
= E_SOURCE_BUILTIN_MAIL_ACCOUNT_UID
;
3100 source
= e_source_registry_ref_source (registry
, uid
);
3101 g_return_val_if_fail (source
!= NULL
, NULL
);
3107 * e_source_registry_ref_builtin_memo_list:
3108 * @registry: an #ESourceRegistry
3110 * Returns the built-in memo list #ESource.
3112 * This #ESource is always present and makes for a safe fallback.
3114 * The returned #ESource is referenced for thread-safety and must be
3115 * unreferenced with g_object_unref() when finished with it.
3117 * Returns: (transfer full): the built-in memo list #ESource
3122 e_source_registry_ref_builtin_memo_list (ESourceRegistry
*registry
)
3127 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
3129 uid
= E_SOURCE_BUILTIN_MEMO_LIST_UID
;
3130 source
= e_source_registry_ref_source (registry
, uid
);
3131 g_return_val_if_fail (source
!= NULL
, NULL
);
3137 * e_source_registry_ref_builtin_proxy:
3138 * @registry: an #ESourceRegistry
3140 * Returns the built-in proxy profile #ESource.
3142 * This #ESource is always present and makes for a safe fallback.
3144 * The returned #ESource is referenced for thread-safety and must be
3145 * unreferenced with g_object_unref() when finished with it.
3147 * Returns: (transfer full): the built-in proxy profile #ESource
3152 e_source_registry_ref_builtin_proxy (ESourceRegistry
*registry
)
3157 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
3159 uid
= E_SOURCE_BUILTIN_PROXY_UID
;
3160 source
= e_source_registry_ref_source (registry
, uid
);
3161 g_return_val_if_fail (source
!= NULL
, NULL
);
3167 * e_source_registry_ref_builtin_task_list:
3168 * @registry: an #ESourceRegistry
3170 * Returns the built-in task list #ESource.
3172 * This #ESource is always present and makes for a safe fallback.
3174 * The returned #ESource is referenced for thread-safety and must be
3175 * unreferenced with g_object_unref() when finished with it.
3177 * Returns: (transfer full): the built-in task list #ESource
3182 e_source_registry_ref_builtin_task_list (ESourceRegistry
*registry
)
3187 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
3189 uid
= E_SOURCE_BUILTIN_TASK_LIST_UID
;
3190 source
= e_source_registry_ref_source (registry
, uid
);
3191 g_return_val_if_fail (source
!= NULL
, NULL
);
3197 * e_source_registry_ref_default_address_book:
3198 * @registry: an #ESourceRegistry
3200 * Returns the #ESource most recently passed to
3201 * e_source_registry_set_default_address_book() either in this session
3202 * or a previous session, or else falls back to the built-in address book.
3204 * The returned #ESource is referenced for thread-safety and must be
3205 * unreferenced with g_object_unref() when finished with it.
3207 * Returns: (transfer full): the default address book #ESource
3212 e_source_registry_ref_default_address_book (ESourceRegistry
*registry
)
3218 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
3220 key
= E_SETTINGS_DEFAULT_ADDRESS_BOOK_KEY
;
3221 uid
= g_settings_get_string (registry
->priv
->settings
, key
);
3222 source
= e_source_registry_ref_source (registry
, uid
);
3225 /* The built-in source is always present. */
3227 source
= e_source_registry_ref_builtin_address_book (registry
);
3229 g_return_val_if_fail (E_IS_SOURCE (source
), NULL
);
3235 * e_source_registry_set_default_address_book:
3236 * @registry: an #ESourceRegistry
3237 * @default_source: (allow-none): an address book #ESource, or %NULL
3239 * Sets @default_source as the default address book. If @default_source
3240 * is %NULL, the default address book is reset to the built-in address book.
3241 * This setting will persist across sessions until changed.
3246 e_source_registry_set_default_address_book (ESourceRegistry
*registry
,
3247 ESource
*default_source
)
3252 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry
));
3254 if (default_source
!= NULL
) {
3255 g_return_if_fail (E_IS_SOURCE (default_source
));
3256 uid
= e_source_get_uid (default_source
);
3258 uid
= E_SOURCE_BUILTIN_ADDRESS_BOOK_UID
;
3261 key
= E_SETTINGS_DEFAULT_ADDRESS_BOOK_KEY
;
3262 g_settings_set_string (registry
->priv
->settings
, key
, uid
);
3264 /* The GSettings::changed signal will trigger a "notify" signal
3265 * from the registry, so no need to call g_object_notify() here. */
3269 * e_source_registry_ref_default_calendar:
3270 * @registry: an #ESourceRegistry
3272 * Returns the #ESource most recently passed to
3273 * e_source_registry_set_default_calendar() either in this session
3274 * or a previous session, or else falls back to the built-in calendar.
3276 * The returned #ESource is referenced for thread-safety and must be
3277 * unreferenced with g_object_unref() when finished with it.
3279 * Returns: (transfer full): the default calendar #ESource
3284 e_source_registry_ref_default_calendar (ESourceRegistry
*registry
)
3290 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
3292 key
= E_SETTINGS_DEFAULT_CALENDAR_KEY
;
3293 uid
= g_settings_get_string (registry
->priv
->settings
, key
);
3294 source
= e_source_registry_ref_source (registry
, uid
);
3297 /* The built-in source is always present. */
3299 source
= e_source_registry_ref_builtin_calendar (registry
);
3301 g_return_val_if_fail (E_IS_SOURCE (source
), NULL
);
3307 * e_source_registry_set_default_calendar:
3308 * @registry: an #ESourceRegistry
3309 * @default_source: (allow-none): a calendar #ESource, or %NULL
3311 * Sets @default_source as the default calendar. If @default_source
3312 * is %NULL, the default calendar is reset to the built-in calendar.
3313 * This setting will persist across sessions until changed.
3318 e_source_registry_set_default_calendar (ESourceRegistry
*registry
,
3319 ESource
*default_source
)
3324 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry
));
3326 if (default_source
!= NULL
) {
3327 g_return_if_fail (E_IS_SOURCE (default_source
));
3328 uid
= e_source_get_uid (default_source
);
3330 uid
= E_SOURCE_BUILTIN_CALENDAR_UID
;
3333 key
= E_SETTINGS_DEFAULT_CALENDAR_KEY
;
3334 g_settings_set_string (registry
->priv
->settings
, key
, uid
);
3336 /* The GSettings::changed signal will trigger a "notify" signal
3337 * from the registry, so no need to call g_object_notify() here. */
3341 * e_source_registry_ref_default_mail_account:
3342 * @registry: an #ESourceRegistry
3344 * Returns the #ESource most recently passed to
3345 * e_source_registry_set_default_mail_account() either in this session
3346 * or a previous session, or else falls back to the built-in mail account.
3348 * The returned #ESource is referenced for thread-safety and must be
3349 * unreferenced with g_object_unref() when finished with it.
3351 * Returns: (transfer full): the default mail account #ESource
3356 e_source_registry_ref_default_mail_account (ESourceRegistry
*registry
)
3362 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
3364 key
= E_SETTINGS_DEFAULT_MAIL_ACCOUNT_KEY
;
3365 uid
= g_settings_get_string (registry
->priv
->settings
, key
);
3366 source
= e_source_registry_ref_source (registry
, uid
);
3369 /* The built-in source is always present. */
3371 source
= e_source_registry_ref_builtin_mail_account (registry
);
3373 g_return_val_if_fail (E_IS_SOURCE (source
), NULL
);
3379 * e_source_registry_set_default_mail_account:
3380 * @registry: an #ESourceRegistry
3381 * @default_source: (allow-none): a mail account #ESource, or %NULL
3383 * Sets @default_source as the default mail account. If @default_source
3384 * is %NULL, the default mail account is reset to the built-in mail account.
3385 * This setting will persist across sessions until changed.
3390 e_source_registry_set_default_mail_account (ESourceRegistry
*registry
,
3391 ESource
*default_source
)
3396 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry
));
3398 if (default_source
!= NULL
) {
3399 g_return_if_fail (E_IS_SOURCE (default_source
));
3400 uid
= e_source_get_uid (default_source
);
3402 uid
= E_SOURCE_BUILTIN_MAIL_ACCOUNT_UID
;
3405 key
= E_SETTINGS_DEFAULT_MAIL_ACCOUNT_KEY
;
3406 g_settings_set_string (registry
->priv
->settings
, key
, uid
);
3408 /* The GSettings::changed signal will trigger a "notify" signal
3409 * from the registry, so no need to call g_object_notify() here. */
3412 /* Helper for e_source_registry_ref_default_mail_identity() */
3414 source_registry_ref_any_mail_identity (ESourceRegistry
*registry
)
3418 const gchar
*extension_name
;
3421 /* First fallback: Return the mail identity named
3422 * by the default mail account. */
3424 source
= e_source_registry_ref_default_mail_account (registry
);
3426 /* This should never be NULL, but just to be safe. */
3427 if (source
!= NULL
) {
3428 ESourceMailAccount
*extension
;
3430 extension_name
= E_SOURCE_EXTENSION_MAIL_ACCOUNT
;
3431 extension
= e_source_get_extension (source
, extension_name
);
3432 uid
= e_source_mail_account_dup_identity_uid (extension
);
3434 g_object_unref (source
);
3439 source
= e_source_registry_ref_source (registry
, uid
);
3446 /* Second fallback: Pick any available mail identity,
3447 * preferring enabled identities. */
3449 extension_name
= E_SOURCE_EXTENSION_MAIL_IDENTITY
;
3450 list
= e_source_registry_list_sources (registry
, extension_name
);
3452 for (link
= list
; link
!= NULL
; link
= g_list_next (link
)) {
3453 ESource
*candidate
= E_SOURCE (link
->data
);
3455 if (e_source_registry_check_enabled (registry
, candidate
)) {
3456 source
= g_object_ref (candidate
);
3461 if (source
== NULL
&& list
!= NULL
)
3462 source
= g_object_ref (list
->data
);
3464 g_list_free_full (list
, (GDestroyNotify
) g_object_unref
);
3470 * e_source_registry_ref_default_mail_identity:
3471 * @registry: an #ESourceRegistry
3473 * Returns the #ESource most recently passed to
3474 * e_source_registry_set_default_mail_identity() either in this session
3475 * or a previous session, or else falls back to the mail identity named
3476 * by the default mail account. If even that fails it returns any mail
3477 * identity from @registry, or %NULL if there are none.
3479 * The returned #ESource is referenced for thread-safety and must be
3480 * unreferenced with g_object_unref() when finished with it.
3482 * Returns: (transfer full): the default mail identity #ESource, or %NULL
3487 e_source_registry_ref_default_mail_identity (ESourceRegistry
*registry
)
3493 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
3495 key
= E_SETTINGS_DEFAULT_MAIL_IDENTITY_KEY
;
3496 uid
= g_settings_get_string (registry
->priv
->settings
, key
);
3497 source
= e_source_registry_ref_source (registry
, uid
);
3501 source
= source_registry_ref_any_mail_identity (registry
);
3507 * e_source_registry_set_default_mail_identity:
3508 * @registry: an #ESourceRegistry
3509 * @default_source: (allow-none): a mail identity #ESource, or %NULL
3511 * Sets @default_source as the default mail identity. If @default_source
3512 * is %NULL, the next request for the default mail identity will use the
3513 * fallbacks described in e_source_registry_ref_default_mail_identity().
3518 e_source_registry_set_default_mail_identity (ESourceRegistry
*registry
,
3519 ESource
*default_source
)
3524 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry
));
3526 if (default_source
!= NULL
) {
3527 g_return_if_fail (E_IS_SOURCE (default_source
));
3528 uid
= e_source_get_uid (default_source
);
3530 uid
= ""; /* no built-in mail identity */
3533 key
= E_SETTINGS_DEFAULT_MAIL_IDENTITY_KEY
;
3534 g_settings_set_string (registry
->priv
->settings
, key
, uid
);
3536 /* The GSettings::changed signal will trigger a "notify" signal
3537 * from the registry, so no need to call g_object_notify() here. */
3541 * e_source_registry_ref_default_memo_list:
3542 * @registry: an #ESourceRegistry
3544 * Returns the #ESource most recently passed to
3545 * e_source_registry_set_default_memo_list() either in this session
3546 * or a previous session, or else falls back to the built-in memo list.
3548 * The returned #ESource is referenced for thread-safety and must be
3549 * unreferenced with g_object_unref() when finished with it.
3551 * Returns: (transfer full): the default memo list #ESource
3556 e_source_registry_ref_default_memo_list (ESourceRegistry
*registry
)
3562 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
3564 key
= E_SETTINGS_DEFAULT_MEMO_LIST_KEY
;
3565 uid
= g_settings_get_string (registry
->priv
->settings
, key
);
3566 source
= e_source_registry_ref_source (registry
, uid
);
3569 /* The built-in source is always present. */
3571 source
= e_source_registry_ref_builtin_memo_list (registry
);
3573 g_return_val_if_fail (E_IS_SOURCE (source
), NULL
);
3579 * e_source_registry_set_default_memo_list:
3580 * @registry: an #ESourceRegistry
3581 * @default_source: (allow-none): a memo list #ESource, or %NULL
3583 * Sets @default_source as the default memo list. If @default_source
3584 * is %NULL, the default memo list is reset to the built-in memo list.
3585 * This setting will persist across sessions until changed.
3590 e_source_registry_set_default_memo_list (ESourceRegistry
*registry
,
3591 ESource
*default_source
)
3596 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry
));
3598 if (default_source
!= NULL
) {
3599 g_return_if_fail (E_IS_SOURCE (default_source
));
3600 uid
= e_source_get_uid (default_source
);
3602 uid
= E_SOURCE_BUILTIN_MEMO_LIST_UID
;
3605 key
= E_SETTINGS_DEFAULT_MEMO_LIST_KEY
;
3606 g_settings_set_string (registry
->priv
->settings
, key
, uid
);
3608 /* The GSettings::changed signal will trigger a "notify" signal
3609 * from the registry, so no need to call g_object_notify() here. */
3613 * e_source_registry_ref_default_task_list:
3614 * @registry: an #ESourceRegistry
3616 * Returns the #ESource most recently passed to
3617 * e_source_registry_set_default_task_list() either in this session
3618 * or a previous session, or else falls back to the built-in task list.
3620 * The returned #ESource is referenced for thread-safety and must be
3621 * unreferenced with g_object_unref() when finished with it.
3623 * Returns: (transfer full): the default task list #ESource
3628 e_source_registry_ref_default_task_list (ESourceRegistry
*registry
)
3634 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
3636 key
= E_SETTINGS_DEFAULT_TASK_LIST_KEY
;
3637 uid
= g_settings_get_string (registry
->priv
->settings
, key
);
3638 source
= e_source_registry_ref_source (registry
, uid
);
3641 /* The built-in source is always present. */
3643 source
= e_source_registry_ref_builtin_task_list (registry
);
3645 g_return_val_if_fail (E_IS_SOURCE (source
), NULL
);
3651 * e_source_registry_set_default_task_list:
3652 * @registry: an #ESourceRegistry
3653 * @default_source: (allow-none): a task list #ESource, or %NULL
3655 * Sets @default_source as the default task list. If @default_source
3656 * is %NULL, the default task list is reset to the built-in task list.
3657 * This setting will persist across sessions until changed.
3662 e_source_registry_set_default_task_list (ESourceRegistry
*registry
,
3663 ESource
*default_source
)
3668 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry
));
3670 if (default_source
!= NULL
) {
3671 g_return_if_fail (E_IS_SOURCE (default_source
));
3672 uid
= e_source_get_uid (default_source
);
3674 uid
= E_SOURCE_BUILTIN_TASK_LIST_UID
;
3677 key
= E_SETTINGS_DEFAULT_TASK_LIST_KEY
;
3678 g_settings_set_string (registry
->priv
->settings
, key
, uid
);
3680 /* The GSettings::changed signal will trigger a "notify" signal
3681 * from the registry, so no need to call g_object_notify() here. */
3685 * e_source_registry_ref_default_for_extension_name:
3686 * @registry: an #ESourceRegistry
3687 * @extension_name: an extension_name
3689 * This is a convenience function to return a default #ESource based on
3690 * @extension_name. This only works with a subset of extension names.
3692 * If @extension_name is #E_SOURCE_EXTENSION_ADDRESS_BOOK, the function
3693 * returns the current default address book, or else falls back to the
3694 * built-in address book.
3696 * If @extension_name is #E_SOURCE_EXTENSION_CALENDAR, the function returns
3697 * the current default calendar, or else falls back to the built-in calendar.
3699 * If @extension_name is #E_SOURCE_EXTENSION_MAIL_ACCOUNT, the function
3700 * returns the current default mail account, or else falls back to the
3701 * built-in mail account.
3703 * If @extension_name is #E_SOURCE_EXTENSION_MAIL_IDENTITY, the function
3704 * returns the current default mail identity, or else falls back to the
3705 * mail identity named by the current default mail account.
3707 * If @extension_name is #E_SOURCE_EXTENSION_MEMO_LIST, the function returns
3708 * the current default memo list, or else falls back to the built-in memo list.
3710 * If @extension_name is #E_SOURCE_EXTENSION_TASK_LIST, the function returns
3711 * the current default task list, or else falls back to the built-in task list.
3713 * For all other values of @extension_name, the function returns %NULL.
3715 * The returned #ESource is referenced for thread-safety and must be
3716 * unreferenced with g_object_unref() when finished with it.
3718 * Returns: (transfer full): the default #ESource based on @extension_name
3723 e_source_registry_ref_default_for_extension_name (ESourceRegistry
*registry
,
3724 const gchar
*extension_name
)
3726 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
3727 g_return_val_if_fail (extension_name
!= NULL
, NULL
);
3729 if (strcmp (extension_name
, E_SOURCE_EXTENSION_ADDRESS_BOOK
) == 0)
3730 return e_source_registry_ref_default_address_book (registry
);
3732 if (strcmp (extension_name
, E_SOURCE_EXTENSION_CALENDAR
) == 0)
3733 return e_source_registry_ref_default_calendar (registry
);
3735 if (strcmp (extension_name
, E_SOURCE_EXTENSION_MAIL_ACCOUNT
) == 0)
3736 return e_source_registry_ref_default_mail_account (registry
);
3738 if (strcmp (extension_name
, E_SOURCE_EXTENSION_MAIL_IDENTITY
) == 0)
3739 return e_source_registry_ref_default_mail_identity (registry
);
3741 if (strcmp (extension_name
, E_SOURCE_EXTENSION_MEMO_LIST
) == 0)
3742 return e_source_registry_ref_default_memo_list (registry
);
3744 if (strcmp (extension_name
, E_SOURCE_EXTENSION_TASK_LIST
) == 0)
3745 return e_source_registry_ref_default_task_list (registry
);
3751 * e_source_registry_set_default_for_extension_name:
3752 * @registry: an #ESourceRegistry
3753 * @extension_name: an extension name
3754 * @default_source: (allow-none): an #ESource, or %NULL
3756 * This is a convenience function to set a default #ESource based on
3757 * @extension_name. This only works with a subset of extension names.
3759 * If @extension_name is #E_SOURCE_EXTENSION_ADDRESS_BOOK, the function
3760 * sets @default_source as the default address book. If @default_source
3761 * is %NULL, the default address book is reset to the built-in address book.
3763 * If @extension_name is #E_SOURCE_EXTENSION_CALENDAR, the function sets
3764 * @default_source as the default calendar. If @default_source is %NULL,
3765 * the default calendar is reset to the built-in calendar.
3767 * If @extension_name is #E_SOURCE_EXTENSION_MAIL_ACCOUNT, the function
3768 * sets @default_source as the default mail account. If @default_source
3769 * is %NULL, the default mail account is reset to the built-in mail account.
3771 * If @extension_name is #E_SOURCE_EXTENSION_MAIL_IDENTITY, the function
3772 * sets @default_source as the default mail identity. If @default_source
3773 * is %NULL, the next request for the default mail identity will return
3774 * the mail identity named by the default mail account.
3776 * If @extension_name is #E_SOURCE_EXTENSION_MEMO_LIST, the function sets
3777 * @default_source as the default memo list. If @default_source is %NULL,
3778 * the default memo list is reset to the built-in memo list.
3780 * If @extension_name is #E_SOURCE_EXTENSION_TASK_LIST, the function sets
3781 * @default_source as the default task list. If @default_source is %NULL,
3782 * the default task list is reset to the built-in task list.
3784 * For all other values of @extension_name, the function does nothing.
3789 e_source_registry_set_default_for_extension_name (ESourceRegistry
*registry
,
3790 const gchar
*extension_name
,
3791 ESource
*default_source
)
3793 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry
));
3794 g_return_if_fail (extension_name
!= NULL
);
3796 if (strcmp (extension_name
, E_SOURCE_EXTENSION_ADDRESS_BOOK
) == 0)
3797 e_source_registry_set_default_address_book (
3798 registry
, default_source
);
3800 if (strcmp (extension_name
, E_SOURCE_EXTENSION_CALENDAR
) == 0)
3801 e_source_registry_set_default_calendar (
3802 registry
, default_source
);
3804 if (strcmp (extension_name
, E_SOURCE_EXTENSION_MAIL_ACCOUNT
) == 0)
3805 e_source_registry_set_default_mail_account (
3806 registry
, default_source
);
3808 if (strcmp (extension_name
, E_SOURCE_EXTENSION_MAIL_IDENTITY
) == 0)
3809 e_source_registry_set_default_mail_identity (
3810 registry
, default_source
);
3812 if (strcmp (extension_name
, E_SOURCE_EXTENSION_MEMO_LIST
) == 0)
3813 e_source_registry_set_default_memo_list (
3814 registry
, default_source
);
3816 if (strcmp (extension_name
, E_SOURCE_EXTENSION_TASK_LIST
) == 0)
3817 e_source_registry_set_default_task_list (
3818 registry
, default_source
);