4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) version 3.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with the program; if not, see <http://www.gnu.org/licenses/>
20
* SECTION: e-source-registry
21
* @include: libedataserver/libedataserver.h
22
* @short_description: A central repository for data sources
24
* The #ESourceRegistry is a global singleton store for all #ESource
25
* instances. It uses file monitors to react to key file creation and
26
* deletion events, either constructing an #ESource instance from the
27
* newly created key file, or removing from the logical #ESource
28
* hierarchy the instance corresponding to the deleted key file.
30
* The #ESourceRegistry can be queried for individual #ESource instances
31
* by their unique identifier string or key file path, for collections of
32
* #ESource instances having a particular extension, or for all available
35
* The #ESourceRegistry API also provides a front-end for the
36
* "org.gnome.Evolution.DefaultSources" #GSettings schema which tracks
37
* which #ESource instances are designated to be the user's default address
38
* book, calendar, memo list and task list for desktop integration.
41
#include "e-source-registry.h"
44
#include <glib/gstdio.h>
45
#include <glib/gi18n-lib.h>
47
/* XXX Yeah, yeah... */
48
#define GCR_API_SUBJECT_TO_CHANGE
50
#include <gcr/gcr-base.h>
52
/* Private D-Bus classes. */
53
#include <e-dbus-source.h>
54
#include <e-dbus-source-manager.h>
56
#include <libedataserver/e-marshal.h>
57
#include <libedataserver/e-data-server-util.h>
58
#include <libedataserver/e-source-collection.h>
60
/* Needed for the defaults API. */
61
#include <libedataserver/e-source-address-book.h>
62
#include <libedataserver/e-source-calendar.h>
63
#include <libedataserver/e-source-mail-account.h>
64
#include <libedataserver/e-source-mail-identity.h>
66
#include "e-dbus-authenticator.h"
68
#define E_SOURCE_REGISTRY_GET_PRIVATE(obj) \
69
(G_TYPE_INSTANCE_GET_PRIVATE \
70
((obj), E_TYPE_SOURCE_REGISTRY, ESourceRegistryPrivate))
72
#define DBUS_OBJECT_PATH "/org/gnome/evolution/dataserver/SourceManager"
73
#define GSETTINGS_SCHEMA "org.gnome.Evolution.DefaultSources"
75
/* Built-in data source UIDs. */
76
#define E_SOURCE_BUILTIN_ADDRESS_BOOK_UID "system-address-book"
77
#define E_SOURCE_BUILTIN_CALENDAR_UID "system-calendar"
78
#define E_SOURCE_BUILTIN_MAIL_ACCOUNT_UID "local"
79
#define E_SOURCE_BUILTIN_MEMO_LIST_UID "system-memo-list"
80
#define E_SOURCE_BUILTIN_TASK_LIST_UID "system-task-list"
82
/* GSettings keys for default data sources. */
83
#define E_SETTINGS_DEFAULT_ADDRESS_BOOK_KEY "default-address-book"
84
#define E_SETTINGS_DEFAULT_CALENDAR_KEY "default-calendar"
85
#define E_SETTINGS_DEFAULT_MAIL_ACCOUNT_KEY "default-mail-account"
86
#define E_SETTINGS_DEFAULT_MAIL_IDENTITY_KEY "default-mail-identity"
87
#define E_SETTINGS_DEFAULT_MEMO_LIST_KEY "default-memo-list"
88
#define E_SETTINGS_DEFAULT_TASK_LIST_KEY "default-task-list"
90
typedef struct _AsyncContext AsyncContext;
91
typedef struct _AuthContext AuthContext;
92
typedef struct _SourceClosure SourceClosure;
93
typedef struct _ThreadClosure ThreadClosure;
95
struct _ESourceRegistryPrivate {
96
GMainContext *main_context;
98
GThread *manager_thread;
99
ThreadClosure *thread_closure;
101
GDBusObjectManager *dbus_object_manager;
102
EDBusSourceManager *dbus_source_manager;
104
GHashTable *object_path_table;
105
GMutex *object_path_table_lock;
108
GMutex *sources_lock;
113
struct _AsyncContext {
115
GList *list_of_sources;
116
ESourceAuthenticator *auth;
119
/* Used in e_source_registry_authenticate_sync() */
120
struct _AuthContext {
121
ESourceAuthenticator *auth;
122
EDBusAuthenticator *dbus_auth;
123
GCancellable *cancellable;
124
GMainLoop *main_loop;
125
ESourceAuthenticationResult auth_result;
126
GcrSecretExchange *secret_exchange;
127
gboolean authenticating;
132
struct _SourceClosure {
133
ESourceRegistry *registry;
137
struct _ThreadClosure {
138
ESourceRegistry *registry;
139
GMainContext *main_context;
140
GMainLoop *main_loop;
141
GCond *main_loop_cond;
142
GMutex *main_loop_mutex;
147
PROP_DEFAULT_ADDRESS_BOOK,
148
PROP_DEFAULT_CALENDAR,
149
PROP_DEFAULT_MAIL_ACCOUNT,
150
PROP_DEFAULT_MAIL_IDENTITY,
151
PROP_DEFAULT_MEMO_LIST,
152
PROP_DEFAULT_TASK_LIST
164
/* Forward Declarations */
165
static void source_registry_add_source (ESourceRegistry *registry,
167
static void e_source_registry_initable_init (GInitableIface *interface);
169
static guint signals[LAST_SIGNAL];
171
/* By default, the GAsyncInitable interface calls GInitable.init()
172
* from a separate thread, so we only have to override GInitable. */
173
G_DEFINE_TYPE_WITH_CODE (
177
G_IMPLEMENT_INTERFACE (
178
G_TYPE_INITABLE, e_source_registry_initable_init)
179
G_IMPLEMENT_INTERFACE (
180
G_TYPE_ASYNC_INITABLE, NULL))
183
async_context_free (AsyncContext *async_context)
185
if (async_context->source != NULL)
186
g_object_unref (async_context->source);
189
async_context->list_of_sources,
190
(GDestroyNotify) g_object_unref);
192
if (async_context->auth != NULL)
193
g_object_unref (async_context->auth);
195
g_slice_free (AsyncContext, async_context);
199
auth_context_free (AuthContext *auth_context)
201
if (auth_context->auth != NULL)
202
g_object_unref (auth_context->auth);
204
if (auth_context->dbus_auth != NULL)
205
g_object_unref (auth_context->dbus_auth);
207
if (auth_context->cancellable != NULL)
208
g_object_unref (auth_context->cancellable);
210
if (auth_context->main_loop != NULL)
211
g_main_loop_unref (auth_context->main_loop);
213
if (auth_context->secret_exchange != NULL)
214
g_object_unref (auth_context->secret_exchange);
216
g_slice_free (AuthContext, auth_context);
220
source_closure_free (SourceClosure *closure)
222
g_object_unref (closure->registry);
223
g_object_unref (closure->source);
225
g_slice_free (SourceClosure, closure);
229
thread_closure_free (ThreadClosure *closure)
231
/* The registry member is not referenced. */
233
g_main_context_unref (closure->main_context);
234
g_main_loop_unref (closure->main_loop);
235
g_cond_free (closure->main_loop_cond);
236
g_mutex_free (closure->main_loop_mutex);
238
g_slice_free (ThreadClosure, closure);
242
source_registry_object_path_table_insert (ESourceRegistry *registry,
243
const gchar *object_path,
246
g_return_if_fail (object_path != NULL);
247
g_return_if_fail (E_IS_SOURCE (source));
249
g_mutex_lock (registry->priv->object_path_table_lock);
251
g_hash_table_insert (
252
registry->priv->object_path_table,
253
g_strdup (object_path),
254
g_object_ref (source));
256
g_mutex_unlock (registry->priv->object_path_table_lock);
260
source_registry_object_path_table_lookup (ESourceRegistry *registry,
261
const gchar *object_path)
265
g_return_val_if_fail (object_path != NULL, NULL);
267
g_mutex_lock (registry->priv->object_path_table_lock);
269
source = g_hash_table_lookup (
270
registry->priv->object_path_table, object_path);
272
g_object_ref (source);
274
g_mutex_unlock (registry->priv->object_path_table_lock);
280
source_registry_object_path_table_remove (ESourceRegistry *registry,
281
const gchar *object_path)
285
g_return_val_if_fail (object_path != NULL, FALSE);
287
g_mutex_lock (registry->priv->object_path_table_lock);
289
removed = g_hash_table_remove (
290
registry->priv->object_path_table, object_path);
292
g_mutex_unlock (registry->priv->object_path_table_lock);
298
source_registry_sources_insert (ESourceRegistry *registry,
303
uid = e_source_get_uid (source);
304
g_return_if_fail (uid != NULL);
306
g_mutex_lock (registry->priv->sources_lock);
308
g_hash_table_insert (
309
registry->priv->sources,
310
g_strdup (uid), g_object_ref (source));
312
g_mutex_unlock (registry->priv->sources_lock);
316
source_registry_sources_remove (ESourceRegistry *registry,
322
uid = e_source_get_uid (source);
323
g_return_val_if_fail (uid != NULL, FALSE);
325
g_mutex_lock (registry->priv->sources_lock);
327
removed = g_hash_table_remove (registry->priv->sources, uid);
329
g_mutex_unlock (registry->priv->sources_lock);
335
source_registry_sources_lookup (ESourceRegistry *registry,
340
g_return_val_if_fail (uid != NULL, NULL);
342
g_mutex_lock (registry->priv->sources_lock);
344
source = g_hash_table_lookup (registry->priv->sources, uid);
347
g_object_ref (source);
349
g_mutex_unlock (registry->priv->sources_lock);
355
source_registry_sources_get_values (ESourceRegistry *registry)
359
g_mutex_lock (registry->priv->sources_lock);
361
values = g_hash_table_get_values (registry->priv->sources);
363
g_list_foreach (values, (GFunc) g_object_ref, NULL);
365
g_mutex_unlock (registry->priv->sources_lock);
371
source_registry_sources_build_tree (ESourceRegistry *registry)
378
g_mutex_lock (registry->priv->sources_lock);
380
root = g_node_new (NULL);
381
index = g_hash_table_new (g_str_hash, g_str_equal);
383
/* Add a GNode for each ESource to the index. */
384
g_hash_table_iter_init (&iter, registry->priv->sources);
385
while (g_hash_table_iter_next (&iter, &key, &value)) {
386
ESource *source = g_object_ref (value);
387
g_hash_table_insert (index, key, g_node_new (source));
390
/* Traverse the index and link the nodes together. */
391
g_hash_table_iter_init (&iter, index);
392
while (g_hash_table_iter_next (&iter, NULL, &value)) {
396
const gchar *parent_uid;
398
source_node = (GNode *) value;
399
source = E_SOURCE (source_node->data);
400
parent_uid = e_source_get_parent (source);
402
if (parent_uid == NULL || *parent_uid == '\0') {
405
parent_node = g_hash_table_lookup (index, parent_uid);
406
g_warn_if_fail (parent_node != NULL);
409
/* Should never be NULL, but just to be safe. */
410
if (parent_node != NULL)
411
g_node_append (parent_node, source_node);
414
g_hash_table_destroy (index);
416
g_mutex_unlock (registry->priv->sources_lock);
422
source_registry_settings_changed_cb (GSettings *settings,
424
ESourceRegistry *registry)
426
/* We define a property name that matches every key in
427
* the "org.gnome.Evolution.DefaultSources" schema. */
428
g_object_notify (G_OBJECT (registry), key);
432
source_registry_source_changed_idle_cb (gpointer user_data)
434
SourceClosure *closure = user_data;
438
signals[SOURCE_CHANGED], 0,
445
source_registry_source_notify_enabled_idle_cb (gpointer user_data)
447
SourceClosure *closure = user_data;
449
if (e_source_get_enabled (closure->source))
452
signals[SOURCE_ENABLED], 0,
457
signals[SOURCE_DISABLED], 0,
464
source_registry_source_changed_cb (ESource *source,
465
ESourceRegistry *registry)
467
GSource *idle_source;
468
SourceClosure *closure;
470
closure = g_slice_new0 (SourceClosure);
471
closure->registry = g_object_ref (registry);
472
closure->source = g_object_ref (source);
474
idle_source = g_idle_source_new ();
475
g_source_set_callback (
477
source_registry_source_changed_idle_cb,
478
closure, (GDestroyNotify) source_closure_free);
479
g_source_attach (idle_source, registry->priv->main_context);
480
g_source_unref (idle_source);
484
source_registry_source_notify_enabled_cb (ESource *source,
486
ESourceRegistry *registry)
488
GSource *idle_source;
489
SourceClosure *closure;
491
closure = g_slice_new0 (SourceClosure);
492
closure->registry = g_object_ref (registry);
493
closure->source = g_object_ref (source);
495
idle_source = g_idle_source_new ();
496
g_source_set_callback (
498
source_registry_source_notify_enabled_idle_cb,
499
closure, (GDestroyNotify) source_closure_free);
500
g_source_attach (idle_source, registry->priv->main_context);
501
g_source_unref (idle_source);
505
source_registry_new_source (ESourceRegistry *registry,
506
GDBusObject *dbus_object)
508
GMainContext *main_context;
510
const gchar *object_path;
511
GError *error = NULL;
513
/* We don't want the ESource emitting "changed" signals from
514
* the manager thread, so we pass it the same main context the
515
* registry uses for scheduling signal emissions. */
516
main_context = registry->priv->main_context;
517
source = e_source_new (dbus_object, main_context, &error);
518
object_path = g_dbus_object_get_object_path (dbus_object);
520
/* The likelihood of an error here is slim, so it's
521
* sufficient to just print a warning if one occurs. */
523
g_warn_if_fail (source == NULL);
525
"ESourceRegistry: Failed to create a "
526
"data source object for path '%s': %s",
527
object_path, error->message);
528
g_error_free (error);
532
g_return_val_if_fail (E_IS_SOURCE (source), NULL);
534
/* Add the ESource to the object path table immediately. */
535
source_registry_object_path_table_insert (
536
registry, object_path, source);
542
source_registry_unref_source (ESource *source)
544
g_signal_handlers_disconnect_matched (
545
source, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
546
source_registry_source_changed_cb, NULL);
548
g_signal_handlers_disconnect_matched (
549
source, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
550
source_registry_source_notify_enabled_cb, NULL);
552
g_object_unref (source);
556
source_registry_add_source (ESourceRegistry *registry,
561
uid = e_source_get_uid (source);
562
g_return_if_fail (uid != NULL);
564
g_mutex_lock (registry->priv->sources_lock);
566
/* Check if we already have this source in the registry. */
567
if (g_hash_table_lookup (registry->priv->sources, uid) != NULL) {
568
g_mutex_unlock (registry->priv->sources_lock);
574
G_CALLBACK (source_registry_source_changed_cb),
578
source, "notify::enabled",
579
G_CALLBACK (source_registry_source_notify_enabled_cb),
582
g_mutex_unlock (registry->priv->sources_lock);
584
source_registry_sources_insert (registry, source);
586
g_signal_emit (registry, signals[SOURCE_ADDED], 0, source);
590
source_registry_remove_source (ESourceRegistry *registry,
593
g_object_ref (source);
595
if (source_registry_sources_remove (registry, source))
596
g_signal_emit (registry, signals[SOURCE_REMOVED], 0, source);
598
g_object_unref (source);
602
source_registry_object_added_idle_cb (gpointer user_data)
604
SourceClosure *closure = user_data;
606
source_registry_add_source (closure->registry, closure->source);
612
source_registry_object_added_cb (GDBusObjectManager *object_manager,
613
GDBusObject *dbus_object,
614
ESourceRegistry *registry)
616
SourceClosure *closure;
617
GSource *idle_source;
620
g_return_if_fail (E_DBUS_IS_OBJECT (dbus_object));
622
source = source_registry_new_source (registry, dbus_object);
623
g_return_if_fail (source != NULL);
625
/* Schedule a callback on the ESourceRegistry's GMainContext. */
627
closure = g_slice_new0 (SourceClosure);
628
closure->registry = g_object_ref (registry);
629
closure->source = g_object_ref (source);
631
idle_source = g_idle_source_new ();
632
g_source_set_callback (
634
source_registry_object_added_idle_cb,
635
closure, (GDestroyNotify) source_closure_free);
636
g_source_attach (idle_source, registry->priv->main_context);
637
g_source_unref (idle_source);
639
g_object_unref (source);
643
source_registry_object_removed_idle_cb (gpointer user_data)
645
SourceClosure *closure = user_data;
647
source_registry_remove_source (closure->registry, closure->source);
653
source_registry_object_removed_cb (GDBusObjectManager *manager,
654
GDBusObject *dbus_object,
655
ESourceRegistry *registry)
657
SourceClosure *closure;
658
GSource *idle_source;
660
const gchar *object_path;
662
/* Find the corresponding ESource in the object path table.
663
* Note that the lookup returns a new ESource reference. */
664
object_path = g_dbus_object_get_object_path (dbus_object);
665
source = source_registry_object_path_table_lookup (
666
registry, object_path);
667
g_return_if_fail (E_IS_SOURCE (source));
669
/* Remove the ESource from the object path table immediately. */
670
source_registry_object_path_table_remove (registry, object_path);
672
/* Schedule a callback on the ESourceRegistry's GMainContext. */
674
closure = g_slice_new0 (SourceClosure);
675
closure->registry = g_object_ref (registry);
676
closure->source = g_object_ref (source);
678
idle_source = g_idle_source_new ();
679
g_source_set_callback (
681
source_registry_object_removed_idle_cb,
682
closure, (GDestroyNotify) source_closure_free);
683
g_source_attach (idle_source, registry->priv->main_context);
684
g_source_unref (idle_source);
686
g_object_unref (source);
690
source_registry_object_manager_running (gpointer data)
692
ThreadClosure *closure = data;
694
g_mutex_lock (closure->main_loop_mutex);
695
g_cond_broadcast (closure->main_loop_cond);
696
g_mutex_unlock (closure->main_loop_mutex);
702
source_registry_object_manager_thread (gpointer data)
704
GDBusObjectManager *object_manager;
705
ThreadClosure *closure = data;
706
GSource *idle_source;
708
gulong object_added_id;
709
gulong object_removed_id;
710
GError *error = NULL;
712
/* GDBusObjectManagerClient grabs the thread-default GMainContext
713
* at creation time and only emits signals from that GMainContext.
714
* Running it in a separate thread prevents its signal emissions
715
* from being inhibited by someone overriding the thread-default
718
/* This becomes the GMainContext that GDBusObjectManagerClient
719
* will emit signals from. Make it the thread-default context
720
* for this thread before creating the client. */
721
g_main_context_push_thread_default (closure->main_context);
723
object_manager = e_dbus_object_manager_client_new_for_bus_sync (
725
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
726
SOURCES_DBUS_SERVICE_NAME,
730
/* If this fails there's really no point in continuing
731
* since we rely on the object manager to populate the
732
* registry. Abort the process with a fatal error. */
734
g_error ("%s", error->message);
735
g_assert_not_reached ();
738
/* Give the registry a handle to the object manager. */
739
closure->registry->priv->dbus_object_manager =
740
g_object_ref (object_manager);
742
/* Now populate the registry with an initial set of ESources. */
744
list = g_dbus_object_manager_get_objects (object_manager);
746
for (link = list; link != NULL; link = g_list_next (link)) {
747
GDBusObject *dbus_object;
750
dbus_object = G_DBUS_OBJECT (link->data);
752
source = source_registry_new_source (
753
closure->registry, dbus_object);
755
if (source != NULL) {
756
source_registry_add_source (
757
closure->registry, source);
758
g_object_unref (source);
762
g_list_free_full (list, (GDestroyNotify) g_object_unref);
764
/* Schedule a one-time idle callback to broadcast through a
765
* condition variable that our main loop is up and running. */
767
idle_source = g_idle_source_new ();
768
g_source_set_callback (
770
source_registry_object_manager_running,
771
closure, (GDestroyNotify) NULL);
772
g_source_attach (idle_source, closure->main_context);
773
g_source_unref (idle_source);
775
/* Listen for D-Bus object additions and removals. */
777
object_added_id = g_signal_connect (
778
object_manager, "object-added",
779
G_CALLBACK (source_registry_object_added_cb),
782
object_removed_id = g_signal_connect (
783
object_manager, "object-removed",
784
G_CALLBACK (source_registry_object_removed_cb),
787
/* Now we mostly idle here for the rest of the session. */
789
g_main_loop_run (closure->main_loop);
791
/* Clean up and exit. */
793
g_signal_handler_disconnect (object_manager, object_added_id);
794
g_signal_handler_disconnect (object_manager, object_removed_id);
796
g_object_unref (object_manager);
798
g_main_context_pop_thread_default (closure->main_context);
804
source_registry_set_property (GObject *object,
809
switch (property_id) {
810
case PROP_DEFAULT_ADDRESS_BOOK:
811
e_source_registry_set_default_address_book (
812
E_SOURCE_REGISTRY (object),
813
g_value_get_object (value));
816
case PROP_DEFAULT_CALENDAR:
817
e_source_registry_set_default_calendar (
818
E_SOURCE_REGISTRY (object),
819
g_value_get_object (value));
822
case PROP_DEFAULT_MAIL_ACCOUNT:
823
e_source_registry_set_default_mail_account (
824
E_SOURCE_REGISTRY (object),
825
g_value_get_object (value));
828
case PROP_DEFAULT_MAIL_IDENTITY:
829
e_source_registry_set_default_mail_identity (
830
E_SOURCE_REGISTRY (object),
831
g_value_get_object (value));
834
case PROP_DEFAULT_MEMO_LIST:
835
e_source_registry_set_default_memo_list (
836
E_SOURCE_REGISTRY (object),
837
g_value_get_object (value));
840
case PROP_DEFAULT_TASK_LIST:
841
e_source_registry_set_default_task_list (
842
E_SOURCE_REGISTRY (object),
843
g_value_get_object (value));
847
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
851
source_registry_get_property (GObject *object,
856
switch (property_id) {
857
case PROP_DEFAULT_ADDRESS_BOOK:
858
g_value_take_object (
860
e_source_registry_ref_default_address_book (
861
E_SOURCE_REGISTRY (object)));
864
case PROP_DEFAULT_CALENDAR:
865
g_value_take_object (
867
e_source_registry_ref_default_calendar (
868
E_SOURCE_REGISTRY (object)));
871
case PROP_DEFAULT_MAIL_ACCOUNT:
872
g_value_take_object (
874
e_source_registry_ref_default_mail_account (
875
E_SOURCE_REGISTRY (object)));
878
case PROP_DEFAULT_MAIL_IDENTITY:
879
g_value_take_object (
881
e_source_registry_ref_default_mail_identity (
882
E_SOURCE_REGISTRY (object)));
885
case PROP_DEFAULT_MEMO_LIST:
886
g_value_take_object (
888
e_source_registry_ref_default_memo_list (
889
E_SOURCE_REGISTRY (object)));
892
case PROP_DEFAULT_TASK_LIST:
893
g_value_take_object (
895
e_source_registry_ref_default_task_list (
896
E_SOURCE_REGISTRY (object)));
900
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
904
source_registry_dispose (GObject *object)
906
ESourceRegistryPrivate *priv;
908
priv = E_SOURCE_REGISTRY_GET_PRIVATE (object);
910
/* Terminate the manager thread first. */
911
if (priv->manager_thread != NULL) {
912
g_main_loop_quit (priv->thread_closure->main_loop);
913
g_thread_join (priv->manager_thread);
914
thread_closure_free (priv->thread_closure);
915
priv->manager_thread = NULL;
916
priv->thread_closure = NULL;
919
if (priv->main_context != NULL) {
920
g_main_context_unref (priv->main_context);
921
priv->main_context = NULL;
924
if (priv->dbus_object_manager != NULL) {
925
g_object_unref (priv->dbus_object_manager);
926
priv->dbus_object_manager = NULL;
929
if (priv->dbus_source_manager != NULL) {
930
g_object_unref (priv->dbus_source_manager);
931
priv->dbus_source_manager = NULL;
934
g_hash_table_remove_all (priv->object_path_table);
936
g_hash_table_remove_all (priv->sources);
938
if (priv->settings != NULL) {
939
g_object_unref (priv->settings);
940
priv->settings = NULL;
943
/* Chain up to parent's finalize() method. */
944
G_OBJECT_CLASS (e_source_registry_parent_class)->dispose (object);
948
source_registry_finalize (GObject *object)
950
ESourceRegistryPrivate *priv;
952
priv = E_SOURCE_REGISTRY_GET_PRIVATE (object);
954
g_hash_table_destroy (priv->object_path_table);
955
g_mutex_free (priv->object_path_table_lock);
957
g_hash_table_destroy (priv->sources);
958
g_mutex_free (priv->sources_lock);
960
/* Chain up to parent's finalize() method. */
961
G_OBJECT_CLASS (e_source_registry_parent_class)->finalize (object);
965
source_registry_initable_init (GInitable *initable,
966
GCancellable *cancellable,
969
ESourceRegistry *registry;
970
ThreadClosure *closure;
972
registry = E_SOURCE_REGISTRY (initable);
974
closure = g_slice_new0 (ThreadClosure);
975
closure->registry = registry; /* do not reference */
976
closure->main_context = g_main_context_new ();
977
/* It's important to pass 'is_running=FALSE' here because
978
* we wait for the main loop to start running as a way of
979
* synchronizing with the manager thread. */
980
closure->main_loop = g_main_loop_new (closure->main_context, FALSE);
981
closure->main_loop_cond = g_cond_new ();
982
closure->main_loop_mutex = g_mutex_new ();
984
registry->priv->thread_closure = closure;
986
registry->priv->manager_thread = g_thread_create (
987
source_registry_object_manager_thread,
988
closure, TRUE /* joinable */, error);
990
if (registry->priv->manager_thread == NULL)
993
/* Wait for notification that the manager
994
* thread's main loop has been started. */
995
g_mutex_lock (closure->main_loop_mutex);
996
while (!g_main_loop_is_running (closure->main_loop))
998
closure->main_loop_cond,
999
closure->main_loop_mutex);
1000
g_mutex_unlock (closure->main_loop_mutex);
1002
/* We should now have a GDBusObjectManagerClient available. */
1003
g_return_val_if_fail (
1004
G_IS_DBUS_OBJECT_MANAGER_CLIENT (
1005
registry->priv->dbus_object_manager), FALSE);
1007
/* The registry should now be populated with sources. */
1008
g_warn_if_fail (g_hash_table_size (registry->priv->sources) > 0);
1010
/* The EDBusSourceManagerProxy is just another D-Bus interface
1011
* that resides at the same object path. It's unrelated to the
1012
* GDBusObjectManagerClient and doesn't need its own thread. */
1013
registry->priv->dbus_source_manager =
1014
e_dbus_source_manager_proxy_new_for_bus_sync (
1016
G_DBUS_PROXY_FLAGS_NONE,
1017
SOURCES_DBUS_SERVICE_NAME,
1019
cancellable, error);
1021
if (registry->priv->dbus_source_manager == NULL)
1028
e_source_registry_class_init (ESourceRegistryClass *class)
1030
GObjectClass *object_class;
1032
g_type_class_add_private (class, sizeof (ESourceRegistryPrivate));
1034
object_class = G_OBJECT_CLASS (class);
1035
object_class->set_property = source_registry_set_property;
1036
object_class->get_property = source_registry_get_property;
1037
object_class->dispose = source_registry_dispose;
1038
object_class->finalize = source_registry_finalize;
1040
/* The property names correspond to the key names in the
1041
* "org.gnome.Evolution.DefaultSources" GSettings schema. */
1044
* ESourceRegistry:default-address-book:
1046
* The default address book #ESource.
1048
g_object_class_install_property (
1050
PROP_DEFAULT_ADDRESS_BOOK,
1051
g_param_spec_object (
1052
"default-address-book",
1053
"Default Address Book",
1054
"The default address book ESource",
1057
G_PARAM_STATIC_STRINGS));
1060
* ESourceRegistry:default-calendar:
1062
* The default calendar #ESource.
1064
g_object_class_install_property (
1066
PROP_DEFAULT_CALENDAR,
1067
g_param_spec_object (
1070
"The default calendar ESource",
1073
G_PARAM_STATIC_STRINGS));
1076
* ESourceRegistry:default-mail-account:
1078
* The default mail account #ESource.
1080
g_object_class_install_property (
1082
PROP_DEFAULT_MAIL_ACCOUNT,
1083
g_param_spec_object (
1084
"default-mail-account",
1085
"Default Mail Account",
1086
"The default mail account ESource",
1089
G_PARAM_STATIC_STRINGS));
1092
* ESourceRegistry:default-mail-identity:
1094
* The default mail identity #ESource.
1096
g_object_class_install_property (
1098
PROP_DEFAULT_MAIL_IDENTITY,
1099
g_param_spec_object (
1100
"default-mail-identity",
1101
"Default Mail Identity",
1102
"The default mail identity ESource",
1105
G_PARAM_STATIC_STRINGS));
1108
* ESourceRegistry:default-memo-list:
1110
* The default memo list #ESource.
1112
g_object_class_install_property (
1114
PROP_DEFAULT_MEMO_LIST,
1115
g_param_spec_object (
1116
"default-memo-list",
1117
"Default Memo List",
1118
"The default memo list ESource",
1121
G_PARAM_STATIC_STRINGS));
1124
* ESourceRegistry:default-task-list:
1126
* The default task list #ESource.
1128
g_object_class_install_property (
1130
PROP_DEFAULT_TASK_LIST,
1131
g_param_spec_object (
1132
"default-task-list",
1133
"Default Task List",
1134
"The default task list ESource",
1137
G_PARAM_STATIC_STRINGS));
1140
* ESourceRegistry::source-added:
1141
* @registry: the #ESourceRegistry which emitted the signal
1142
* @source: the newly-added #ESource
1144
* Emitted when an #ESource is added to @registry.
1146
signals[SOURCE_ADDED] = g_signal_new (
1148
G_OBJECT_CLASS_TYPE (object_class),
1150
G_STRUCT_OFFSET (ESourceRegistryClass, source_added),
1152
g_cclosure_marshal_VOID__OBJECT,
1157
* ESourceRegistry::source-changed:
1158
* @registry: the #ESourceRegistry which emitted the signal
1159
* @source: the #ESource that changed
1161
* Emitted when an #ESource registered with @registry emits
1162
* its #ESource::changed signal.
1164
signals[SOURCE_CHANGED] = g_signal_new (
1166
G_OBJECT_CLASS_TYPE (object_class),
1168
G_STRUCT_OFFSET (ESourceRegistryClass, source_changed),
1170
g_cclosure_marshal_VOID__OBJECT,
1175
* ESourceRegistry::source-removed:
1176
* @registry: the #ESourceRegistry which emitted the signal
1177
* @source: the #ESource that got removed
1179
* Emitted when an #ESource is removed from @registry.
1181
signals[SOURCE_REMOVED] = g_signal_new (
1183
G_OBJECT_CLASS_TYPE (object_class),
1185
G_STRUCT_OFFSET (ESourceRegistryClass, source_removed),
1187
g_cclosure_marshal_VOID__OBJECT,
1192
* ESourceRegistry::source-enabled:
1193
* @registry: the #ESourceRegistry which emitted the signal
1194
* @source: the #ESource that got enabled
1196
* Emitted when an #ESource #ESource:enabled property becomes %TRUE.
1198
signals[SOURCE_ENABLED] = g_signal_new (
1200
G_OBJECT_CLASS_TYPE (object_class),
1202
G_STRUCT_OFFSET (ESourceRegistryClass, source_enabled),
1204
g_cclosure_marshal_VOID__OBJECT,
1209
* ESourceRegistry::source-disabled:
1210
* @registry: the #ESourceRegistry which emitted the signal
1211
* @source: the #ESource that got disabled
1213
* Emitted when an #ESource #ESource:enabled property becomes %FALSE.
1215
signals[SOURCE_DISABLED] = g_signal_new (
1217
G_OBJECT_CLASS_TYPE (object_class),
1219
G_STRUCT_OFFSET (ESourceRegistryClass, source_disabled),
1221
g_cclosure_marshal_VOID__OBJECT,
1227
e_source_registry_initable_init (GInitableIface *interface)
1229
interface->init = source_registry_initable_init;
1233
e_source_registry_init (ESourceRegistry *registry)
1235
registry->priv = E_SOURCE_REGISTRY_GET_PRIVATE (registry);
1237
/* This is so the object manager thread can schedule signal
1238
* emissions on the thread-default context for this thread. */
1239
registry->priv->main_context = g_main_context_ref_thread_default ();
1241
/* D-Bus object path -> ESource */
1242
registry->priv->object_path_table =
1243
g_hash_table_new_full (
1244
(GHashFunc) g_str_hash,
1245
(GEqualFunc) g_str_equal,
1246
(GDestroyNotify) g_free,
1247
(GDestroyNotify) g_object_unref);
1249
registry->priv->object_path_table_lock = g_mutex_new ();
1251
/* UID string -> ESource */
1252
registry->priv->sources = g_hash_table_new_full (
1253
(GHashFunc) g_str_hash,
1254
(GEqualFunc) g_str_equal,
1255
(GDestroyNotify) g_free,
1256
(GDestroyNotify) source_registry_unref_source);
1258
registry->priv->sources_lock = g_mutex_new ();
1260
registry->priv->settings = g_settings_new (GSETTINGS_SCHEMA);
1263
registry->priv->settings, "changed",
1264
G_CALLBACK (source_registry_settings_changed_cb), registry);
1268
* e_source_registry_new_sync:
1269
* @cancellable: (allow-none): optional #GCancellable object, or %NULL
1270
* @error: return location for a #GError, or %NULL
1272
* Creates a new #ESourceRegistry front-end for the registry D-Bus service.
1273
* If an error occurs in connecting to the D-Bus service, the function sets
1274
* @error and returns %NULL.
1276
* Returns: a new #ESourceRegistry, or %NULL
1281
e_source_registry_new_sync (GCancellable *cancellable,
1284
return g_initable_new (
1285
E_TYPE_SOURCE_REGISTRY,
1286
cancellable, error, NULL);
1290
* e_source_registry_new:
1291
* @cancellable: (allow-none): optional #GCancellable object, or %NULL
1292
* @callback: (scope async): a #GAsyncReadyCallback to call when the request
1294
* @user_data: (closure): data to pass to the callback function
1296
* Asynchronously creates a new #ESourceRegistry front-end for the registry
1299
* When the operation is finished, @callback will be called. You can then
1300
* call e_source_registry_new_finish() to get the result of the operation.
1305
e_source_registry_new (GCancellable *cancellable,
1306
GAsyncReadyCallback callback,
1309
g_async_initable_new_async (
1310
E_TYPE_SOURCE_REGISTRY,
1311
G_PRIORITY_DEFAULT, cancellable,
1312
callback, user_data, NULL);
1316
* e_source_registry_new_finish:
1317
* @result: a #GAsyncResult
1318
* @error: return location for a #GError, or %NULL
1320
* Finishes the operation started with e_source_registry_new_finish().
1321
* If an error occurs in connecting to the D-Bus service, the function
1322
* sets @error and returns %NULL.
1324
* Returns: a new #ESourceRegistry, or %NULL
1329
e_source_registry_new_finish (GAsyncResult *result,
1332
GObject *source_object;
1335
g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
1337
source_object = g_async_result_get_source_object (result);
1338
g_return_val_if_fail (source_object != NULL, NULL);
1340
object = g_async_initable_new_finish (
1341
G_ASYNC_INITABLE (source_object), result, error);
1343
g_object_unref (source_object);
1345
return (object != NULL) ? E_SOURCE_REGISTRY (object) : NULL;
1348
/* Helper for e_source_registry_authenticate() */
1350
source_registry_authenticate_thread (GSimpleAsyncResult *simple,
1352
GCancellable *cancellable)
1354
AsyncContext *async_context;
1355
GError *error = NULL;
1357
async_context = g_simple_async_result_get_op_res_gpointer (simple);
1359
e_source_registry_authenticate_sync (
1360
E_SOURCE_REGISTRY (object),
1361
async_context->source,
1362
async_context->auth,
1363
cancellable, &error);
1366
g_simple_async_result_take_error (simple, error);
1369
/* Helper for e_source_registry_authenticate_sync() */
1371
source_registry_authenticate_respond_cb (AuthContext *auth_context)
1373
ESourceAuthenticationResult auth_result;
1374
GError *non_fatal_error = NULL;
1376
g_return_val_if_fail (auth_context->authenticating, FALSE);
1378
auth_result = auth_context->auth_result;
1380
/* Allow the next authentication attempt to proceed. */
1381
auth_context->authenticating = FALSE;
1383
/* Send the server a status update based on the authentication
1384
* result. Note, we don't really care if the D-Bus message gets
1385
* through to the server at this point. If it doesn't, the auth
1386
* session will either time out on its own or the authentication
1387
* dialog will eventually be dismissed by the user. */
1389
/* If an error occurred while attempting to authenticate,
1390
* tell the server to cancel the authentication session. */
1391
if (auth_result == E_SOURCE_AUTHENTICATION_ERROR) {
1392
e_dbus_authenticator_call_cancel_sync (
1393
auth_context->dbus_auth,
1394
auth_context->cancellable,
1396
g_main_loop_quit (auth_context->main_loop);
1397
auth_context->success = FALSE;
1399
/* If the password was accepted, let the server know so it
1400
* can close any authentication dialogs and save the user
1401
* provided password to the keyring. */
1402
} else if (auth_result == E_SOURCE_AUTHENTICATION_ACCEPTED) {
1403
e_dbus_authenticator_call_accepted_sync (
1404
auth_context->dbus_auth,
1405
auth_context->cancellable,
1407
g_main_loop_quit (auth_context->main_loop);
1408
auth_context->success = TRUE;
1410
/* If the password was rejected, let the server know so it can
1411
* indicate failure and request a different password, and then
1412
* wait for the next "response" signal. */
1414
e_dbus_authenticator_call_rejected_sync (
1415
auth_context->dbus_auth,
1416
auth_context->cancellable,
1420
/* Leave breadcrumbs if something went wrong,
1421
* but don't fail the whole operation over it. */
1422
if (non_fatal_error != NULL) {
1423
g_warning ("%s: %s", G_STRFUNC, non_fatal_error->message);
1424
g_error_free (non_fatal_error);
1430
/* Helper for e_source_registry_authenticate_sync() */
1432
source_registry_authenticate_authenticate_cb (EDBusAuthenticator *dbus_auth,
1433
const gchar *encrypted_secret,
1434
AuthContext *auth_context)
1436
GSource *idle_source;
1437
GMainContext *main_context;
1439
gboolean valid_secret;
1441
/* We should only get one secret at a time. */
1442
g_return_if_fail (!auth_context->authenticating);
1444
valid_secret = gcr_secret_exchange_receive (
1445
auth_context->secret_exchange, encrypted_secret);
1446
g_return_if_fail (valid_secret);
1448
auth_context->authenticating = TRUE;
1450
/* This avoids revealing the password in a stack trace. */
1451
password = g_string_new (
1452
gcr_secret_exchange_get_secret (
1453
auth_context->secret_exchange, NULL));
1455
/* Try authenticating with the given password. We have to
1456
* call this synchronously because some authenticators use
1457
* mutexes to serialize I/O operations and are not prepared
1458
* to make authentication attempts from a different thread.
1460
* Unfortunately this means we won't notice server-side
1461
* dismissals while the main loop is blocked. We respond
1462
* to the server from a low-priority idle callback so that
1463
* any pending "dismissed" signals get handled first. */
1465
auth_context->auth_result =
1466
e_source_authenticator_try_password_sync (
1467
auth_context->auth, password,
1468
auth_context->cancellable,
1469
auth_context->error);
1471
idle_source = g_idle_source_new ();
1472
main_context = g_main_context_get_thread_default ();
1473
g_source_set_callback (
1474
idle_source, (GSourceFunc)
1475
source_registry_authenticate_respond_cb,
1476
auth_context, NULL);
1477
g_source_attach (idle_source, main_context);
1478
g_source_unref (idle_source);
1480
g_string_free (password, TRUE);
1483
/* Helper for e_source_registry_authenticate_sync() */
1485
source_registry_authenticate_dismissed_cb (EDBusAuthenticator *dbus_auth,
1486
AuthContext *auth_context)
1488
/* Be careful not to overwrite an existing error in case this
1489
* is called after e_source_authenticator_try_password_sync()
1490
* but prior to the idle callback. */
1491
if (auth_context->auth_result != E_SOURCE_AUTHENTICATION_ERROR) {
1492
/* XXX Use a separate error code for dismissals? */
1493
g_set_error_literal (
1494
auth_context->error,
1495
G_IO_ERROR, G_IO_ERROR_CANCELLED,
1496
_("The user declined to authenticate"));
1497
auth_context->auth_result = E_SOURCE_AUTHENTICATION_ERROR;
1500
g_main_loop_quit (auth_context->main_loop);
1501
auth_context->success = FALSE;
1504
/* Helper for e_source_registry_authenticate_sync() */
1506
source_registry_call_authenticate_for_source (ESourceRegistry *registry,
1507
ESourceAuthenticator *auth,
1509
gchar **out_object_path,
1510
GCancellable *cancellable,
1513
ESource *collection;
1515
gchar *prompt_title = NULL;
1516
gchar *prompt_message = NULL;
1517
gchar *prompt_description = NULL;
1520
/* If the source is a member of a collection, we want to store
1521
* the password under the UID of the "collection" source so it
1522
* will apply to the entire collection.
1524
* XXX This assumes all sources in a collection share a single
1525
* password. If that turns out not to be true in all cases
1526
* we could maybe add a "SharedPassword: true/false" key to
1527
* [Collection] and apply it here.
1529
collection = e_source_registry_find_extension (
1530
registry, source, E_SOURCE_EXTENSION_COLLECTION);
1531
if (collection != NULL)
1532
source = collection;
1534
g_object_ref (source);
1536
uid = e_source_get_uid (source);
1538
e_source_authenticator_get_prompt_strings (
1542
&prompt_description);
1544
success = e_dbus_source_manager_call_authenticate_sync (
1545
registry->priv->dbus_source_manager, uid,
1546
prompt_title, prompt_message, prompt_description,
1547
out_object_path, cancellable, error);
1549
g_free (prompt_title);
1550
g_free (prompt_message);
1551
g_free (prompt_description);
1553
g_object_unref (source);
1559
* e_source_registry_authenticate_sync:
1560
* @registry: an #ESourceRegistry
1561
* @source: an #ESource
1562
* @auth: an #ESourceAuthenticator
1563
* @cancellable: (allow-none): optional #GCancellable object, or %NULL
1564
* @error: return location for a #GError, or %NULL
1566
* Authenticates @source, using @auth to handle the authentication
1567
* attempts. The operation loops until authentication is successful or
1568
* the user aborts further authentication attempts. If an error occurs,
1569
* the function will set @error and return %FALSE.
1571
* Note that @source need not have a #GDBusObject, which means this
1572
* function can test authentication on a scratch #ESource.
1574
* Only backend implementations and data source editors should call this
1575
* function. The intent is for basic client applications to not have to
1576
* deal with authentication at all.
1578
* Returns: %TRUE on success, %FALSE on failure
1583
e_source_registry_authenticate_sync (ESourceRegistry *registry,
1585
ESourceAuthenticator *auth,
1586
GCancellable *cancellable,
1589
AuthContext *auth_context;
1590
GMainContext *main_context;
1591
EDBusAuthenticator *dbus_auth;
1592
gchar *encryption_key;
1593
gchar *object_path = NULL;
1596
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
1597
g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
1598
g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATOR (auth), FALSE);
1600
/* This extracts authentication prompt details for the ESource
1601
* before initiating an authentication session with the server,
1602
* so split it out of the main algorithm for clarity's sake. */
1603
success = source_registry_call_authenticate_for_source (
1604
registry, auth, source, &object_path, cancellable, error);
1607
g_warn_if_fail (object_path == NULL);
1611
g_return_val_if_fail (object_path != NULL, FALSE);
1613
main_context = g_main_context_new ();
1614
g_main_context_push_thread_default (main_context);
1616
dbus_auth = e_dbus_authenticator_proxy_new_for_bus_sync (
1618
G_DBUS_PROXY_FLAGS_NONE,
1619
SOURCES_DBUS_SERVICE_NAME,
1620
object_path, cancellable, error);
1622
g_free (object_path);
1624
if (dbus_auth == NULL) {
1629
auth_context = g_slice_new0 (AuthContext);
1630
auth_context->auth = g_object_ref (auth);
1631
auth_context->dbus_auth = dbus_auth; /* takes ownership */
1632
auth_context->main_loop = g_main_loop_new (main_context, FALSE);
1633
auth_context->error = error;
1635
/* This just needs to be something other than
1636
* E_SOURCE_AUTHENTICATION_ERROR so we don't trip
1637
* up source_registry_authenticate_dismissed_cb(). */
1638
auth_context->auth_result = E_SOURCE_AUTHENTICATION_REJECTED;
1640
if (G_IS_CANCELLABLE (cancellable))
1641
auth_context->cancellable = g_object_ref (cancellable);
1643
auth_context->secret_exchange =
1644
gcr_secret_exchange_new (GCR_SECRET_EXCHANGE_PROTOCOL_1);
1647
dbus_auth, "authenticate",
1648
G_CALLBACK (source_registry_authenticate_authenticate_cb),
1652
dbus_auth, "dismissed",
1653
G_CALLBACK (source_registry_authenticate_dismissed_cb),
1656
encryption_key = gcr_secret_exchange_begin (
1657
auth_context->secret_exchange);
1659
/* Signal the D-Bus server that we're ready to begin the
1660
* authentication session. This must happen AFTER we've
1661
* connected to the response signal since the server may
1662
* already have a response ready and waiting for us. */
1663
success = e_dbus_authenticator_call_ready_sync (
1664
dbus_auth, encryption_key, cancellable, error);
1666
g_free (encryption_key);
1669
g_main_loop_run (auth_context->main_loop);
1670
success = auth_context->success;
1673
auth_context_free (auth_context);
1676
g_main_context_pop_thread_default (main_context);
1677
g_main_context_unref (main_context);
1683
* e_source_registry_authenticate:
1684
* @registry: an #ESourceRegistry
1685
* @source: an #ESource
1686
* @auth: an #ESourceAuthenticator
1687
* @cancellable: (allow-none): optional #GCancellable object, or %NULL
1688
* @callback: (scope async): a #GAsyncReadyCallback to call when the request
1690
* @user_data: (closure): data to pass to the callback function
1692
* Asynchronously authenticates @source, using @auth to handle the
1693
* authentication attempts. The operation loops until authentication
1694
* is successful or the user aborts further authentication attempts.
1696
* Note that @source need not have a #GDBusObject, which means this
1697
* function can test authentication on a scratch #ESource.
1699
* When the operation is finished, @callback will be called. You can then
1700
* call e_source_registry_authenticate_finish() to get the result of the
1703
* Only backend implementations and data source editors should call this
1704
* function. The intent is for basic client applications to not have to
1705
* deal with authentication at all.
1710
e_source_registry_authenticate (ESourceRegistry *registry,
1712
ESourceAuthenticator *auth,
1713
GCancellable *cancellable,
1714
GAsyncReadyCallback callback,
1717
GSimpleAsyncResult *simple;
1718
AsyncContext *async_context;
1720
g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
1721
g_return_if_fail (E_IS_SOURCE (source));
1722
g_return_if_fail (E_IS_SOURCE_AUTHENTICATOR (auth));
1724
async_context = g_slice_new0 (AsyncContext);
1725
async_context->source = g_object_ref (source);
1726
async_context->auth = g_object_ref (auth);
1728
simple = g_simple_async_result_new (
1729
G_OBJECT (registry), callback, user_data,
1730
e_source_registry_authenticate);
1732
g_simple_async_result_set_check_cancellable (simple, cancellable);
1734
g_simple_async_result_set_op_res_gpointer (
1735
simple, async_context, (GDestroyNotify) async_context_free);
1737
g_simple_async_result_run_in_thread (
1738
simple, source_registry_authenticate_thread,
1739
G_PRIORITY_DEFAULT, cancellable);
1741
g_object_unref (simple);
1745
* e_source_registry_authenticate_finish:
1746
* @registry: an #ESourceRegistry
1747
* @result: a #GAsyncResult
1748
* @error: return location for a #GError, or %NULL
1750
* Finishes the operation started with e_source_registry_authenticate().
1751
* If an error occurred, the function will set @error and return %FALSE.
1753
* Returns: %TRUE on success, %FALSE on failure
1758
e_source_registry_authenticate_finish (ESourceRegistry *registry,
1759
GAsyncResult *result,
1762
GSimpleAsyncResult *simple;
1764
g_return_val_if_fail (
1765
g_simple_async_result_is_valid (
1766
result, G_OBJECT (registry),
1767
e_source_registry_authenticate), FALSE);
1769
simple = G_SIMPLE_ASYNC_RESULT (result);
1771
/* Assume success unless a GError is set. */
1772
return !g_simple_async_result_propagate_error (simple, error);
1775
/* Helper for e_source_registry_commit_source() */
1777
source_registry_commit_source_thread (GSimpleAsyncResult *simple,
1779
GCancellable *cancellable)
1781
AsyncContext *async_context;
1782
GError *error = NULL;
1784
async_context = g_simple_async_result_get_op_res_gpointer (simple);
1786
e_source_registry_commit_source_sync (
1787
E_SOURCE_REGISTRY (object),
1788
async_context->source,
1789
cancellable, &error);
1792
g_simple_async_result_take_error (simple, error);
1796
* e_source_registry_commit_source_sync:
1797
* @registry: an #ESourceRegistry
1798
* @source: an #ESource with changes to commit
1799
* @cancellable: (allow-none): optional #GCancellable object, or %NULL
1800
* @error: return location for #GError, or %NULL
1802
* This is a convenience function intended for use with graphical
1803
* #ESource editors. Call this function when the user is finished
1804
* making changes to @source.
1806
* If @source has a #GDBusObject, its contents are submitted to the D-Bus
1807
* service through e_source_write_sync().
1809
* If @source does NOT have a #GDBusObject (implying it's a scratch
1810
* #ESource), its contents are submitted to the D-Bus service through
1811
* e_source_registry_create_sources_sync().
1813
* If an error occurs, the function will set @error and return %FALSE.
1815
* Returns: %TRUE on success, %FALSE on failure
1820
e_source_registry_commit_source_sync (ESourceRegistry *registry,
1822
GCancellable *cancellable,
1825
GDBusObject *dbus_object;
1828
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
1829
g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
1831
dbus_object = e_source_ref_dbus_object (source);
1833
if (dbus_object != NULL) {
1834
success = e_source_write_sync (source, cancellable, error);
1835
g_object_unref (dbus_object);
1837
GList *list = g_list_prepend (NULL, source);
1838
success = e_source_registry_create_sources_sync (
1839
registry, list, cancellable, error);
1847
* e_source_registry_commit_source:
1848
* @registry: an #ESourceRegistry
1849
* @source: an #ESource with changes to commit
1850
* @cancellable: (allow-none): optional #GCancellable object, or %NULL
1851
* @callback: (scope async): a #GAsyncReadyCallback to call when the request
1853
* @user_data: (closure): data to pass to the callback function
1855
* See e_source_registry_commit_source_sync() for details.
1857
* When the operation is finished, @callback will be called. You can then
1858
* call e_source_registry_commit_source_finish() to get the result of the
1864
e_source_registry_commit_source (ESourceRegistry *registry,
1866
GCancellable *cancellable,
1867
GAsyncReadyCallback callback,
1870
GSimpleAsyncResult *simple;
1871
AsyncContext *async_context;
1873
g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
1874
g_return_if_fail (E_IS_SOURCE (source));
1876
async_context = g_slice_new0 (AsyncContext);
1877
async_context->source = g_object_ref (source);
1879
simple = g_simple_async_result_new (
1880
G_OBJECT (registry), callback, user_data,
1881
e_source_registry_commit_source);
1883
g_simple_async_result_set_check_cancellable (simple, cancellable);
1885
g_simple_async_result_set_op_res_gpointer (
1886
simple, async_context, (GDestroyNotify) async_context_free);
1888
g_simple_async_result_run_in_thread (
1889
simple, source_registry_commit_source_thread,
1890
G_PRIORITY_DEFAULT, cancellable);
1892
g_object_unref (simple);
1896
* e_source_registry_commit_source_finish:
1897
* @registry: an #ESourceRegistry
1898
* @result: a #GAsyncResult
1899
* @error: return location for a #GError, or %NULL
1901
* Finishes the operation started with e_source_registry_commit_source().
1903
* If an error occurred, the function will set @error and return %FALSE.
1905
* Returns: %TRUE on success, %FALSE on failure
1910
e_source_registry_commit_source_finish (ESourceRegistry *registry,
1911
GAsyncResult *result,
1914
GSimpleAsyncResult *simple;
1916
g_return_val_if_fail (
1917
g_simple_async_result_is_valid (
1918
result, G_OBJECT (registry),
1919
e_source_registry_commit_source), FALSE);
1921
simple = G_SIMPLE_ASYNC_RESULT (result);
1923
/* Assume success unless a GError is set. */
1924
return !g_simple_async_result_propagate_error (simple, error);
1927
/* Helper for e_source_registry_create_sources() */
1929
source_registry_create_sources_thread (GSimpleAsyncResult *simple,
1931
GCancellable *cancellable)
1933
AsyncContext *async_context;
1934
GError *error = NULL;
1936
async_context = g_simple_async_result_get_op_res_gpointer (simple);
1938
e_source_registry_create_sources_sync (
1939
E_SOURCE_REGISTRY (object),
1940
async_context->list_of_sources,
1941
cancellable, &error);
1944
g_simple_async_result_take_error (simple, error);
1948
* e_source_registry_create_sources_sync:
1949
* @registry: an #ESourceRegistry
1950
* @list_of_sources: (element-type ESource): a list of #ESource instances with
1952
* @cancellable: (allow-none): optional #GCancellable object, or %NULL
1953
* @error: return location for a #GError, or %NULL
1955
* Requests the D-Bus service create new key files for each #ESource in
1956
* @list_of_sources. Each list element must be a scratch #ESource with
1959
* If an error occurs, the function will set @error and return %FALSE.
1961
* Returns: %TRUE on success, %FALSE on failure
1966
e_source_registry_create_sources_sync (ESourceRegistry *registry,
1967
GList *list_of_sources,
1968
GCancellable *cancellable,
1971
GVariantBuilder builder;
1976
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
1978
/* Verify the list elements are all ESources. */
1979
for (link = list_of_sources; link != NULL; link = g_list_next (link))
1980
g_return_val_if_fail (E_IS_SOURCE (link->data), FALSE);
1982
g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
1984
for (link = list_of_sources; link != NULL; link = g_list_next (link)) {
1989
source = E_SOURCE (link->data);
1990
uid = e_source_get_uid (source);
1992
source_data = e_source_to_string (source, NULL);
1993
g_variant_builder_add (&builder, "{ss}", uid, source_data);
1994
g_free (source_data);
1997
variant = g_variant_builder_end (&builder);
1999
/* This function sinks the floating GVariant reference. */
2000
success = e_dbus_source_manager_call_create_sources_sync (
2001
registry->priv->dbus_source_manager,
2002
variant, cancellable, error);
2004
g_variant_builder_clear (&builder);
2010
* e_source_registry_create_sources:
2011
* @registry: an #ESourceRegistry
2012
* @list_of_sources: (element-type ESource): a list of #ESource instances with
2014
* @cancellable: (allow-none): optional #GCancellable object, or %NULL
2015
* @callback: (scope async): a #GAsyncReadyCallback to call when the request
2017
* @user_data: (closure): data to pass to the callback function
2019
* Asynchronously requests the D-Bus service create new key files for each
2020
* #ESource in @list_of_sources. Each list element must be a scratch
2021
* #ESource with no #GDBusObject.
2023
* When the operation is finished, @callback will be called. You can then
2024
* call e_source_registry_create_sources_finish() to get the result of the
2030
e_source_registry_create_sources (ESourceRegistry *registry,
2031
GList *list_of_sources,
2032
GCancellable *cancellable,
2033
GAsyncReadyCallback callback,
2036
GSimpleAsyncResult *simple;
2037
AsyncContext *async_context;
2040
g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
2042
/* Verify the list elements are all ESources. */
2043
for (link = list_of_sources; link != NULL; link = g_list_next (link))
2044
g_return_if_fail (E_IS_SOURCE (link->data));
2046
async_context = g_slice_new0 (AsyncContext);
2047
async_context->list_of_sources = g_list_copy (list_of_sources);
2050
async_context->list_of_sources,
2051
(GFunc) g_object_ref, NULL);
2053
simple = g_simple_async_result_new (
2054
G_OBJECT (registry), callback, user_data,
2055
e_source_registry_create_sources);
2057
g_simple_async_result_set_check_cancellable (simple, cancellable);
2059
g_simple_async_result_set_op_res_gpointer (
2060
simple, async_context, (GDestroyNotify) async_context_free);
2062
g_simple_async_result_run_in_thread (
2063
simple, source_registry_create_sources_thread,
2064
G_PRIORITY_DEFAULT, cancellable);
2066
g_object_unref (simple);
2070
* e_source_registry_create_sources_finish:
2071
* @registry: an #ESourceRegistry
2072
* @result: a #GAsyncResult
2073
* @error: return location for a #GError, or %NULL
2075
* Finishes the operation started with e_source_registry_create_sources().
2077
* If an error occurred, the function will set @error and return %FALSE.
2079
* Returns: %TRUE on success, %FALSE on failure
2084
e_source_registry_create_sources_finish (ESourceRegistry *registry,
2085
GAsyncResult *result,
2088
GSimpleAsyncResult *simple;
2090
g_return_val_if_fail (
2091
g_simple_async_result_is_valid (
2092
result, G_OBJECT (registry),
2093
e_source_registry_create_sources), FALSE);
2095
simple = G_SIMPLE_ASYNC_RESULT (result);
2097
/* Assume success unless a GError is set. */
2098
return !g_simple_async_result_propagate_error (simple, error);
2102
* e_source_registry_ref_source:
2103
* @registry: an #ESourceRegistry
2104
* @uid: a unique identifier string
2106
* Looks up an #ESource in @registry by its unique identifier string.
2108
* The returned #ESource is referenced for thread-safety and must be
2109
* unreferenced with g_object_unref() when finished with it.
2111
* Returns: (transfer full): an #ESource, or %NULL if no match was found
2116
e_source_registry_ref_source (ESourceRegistry *registry,
2119
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
2120
g_return_val_if_fail (uid != NULL, NULL);
2122
return source_registry_sources_lookup (registry, uid);
2126
* e_source_registry_list_sources:
2127
* @registry: an #ESourceRegistry
2128
* @extension_name: (allow-none): an extension name, or %NULL
2130
* Returns a list of registered sources, sorted by display name. If
2131
* @extension_name is given, restrict the list to sources having that
2134
* The sources returned in the list are referenced for thread-safety.
2135
* They must each be unreferenced with g_object_unref() when finished
2136
* when them. Free the returned list itself with g_list_free().
2138
* An easy way to free the list properly in one step is as follows:
2141
* g_list_free_full (list, g_object_unref);
2144
* Returns: (element-type ESource) (transfer full): a sorted list of sources
2149
e_source_registry_list_sources (ESourceRegistry *registry,
2150
const gchar *extension_name)
2153
GQueue trash = G_QUEUE_INIT;
2155
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
2157
list = g_list_sort (
2158
source_registry_sources_get_values (registry),
2159
(GCompareFunc) e_source_compare_by_display_name);
2161
if (extension_name == NULL)
2164
for (link = list; link != NULL; link = g_list_next (link)) {
2165
ESource *source = E_SOURCE (link->data);
2167
if (!e_source_has_extension (source, extension_name)) {
2168
g_queue_push_tail (&trash, link);
2169
g_object_unref (source);
2173
/* We do want pop_head() here, not pop_head_link(). */
2174
while ((link = g_queue_pop_head (&trash)) != NULL)
2175
list = g_list_delete_link (list, link);
2181
* e_source_registry_find_extension:
2182
* @registry: an #ESourceRegistry
2183
* @source: an #ESource
2184
* @extension_name: the extension name to find
2186
* Examines @source and its ancestors and returns the "deepest" #ESource
2187
* having an #ESourceExtension with the given @extension_name. If neither
2188
* @source nor any of its ancestors have such an extension, the function
2191
* This function is useful in cases when an #ESourceExtension is meant to
2192
* apply to both the #ESource it belongs to and the #ESource's descendants.
2194
* A common example is the #ESourceCollection extension, where descendants
2195
* of an #ESource having an #ESourceCollection extension are implied to be
2196
* members of that collection. In that example, this function can be used
2197
* to test whether @source is a member of a collection.
2199
* The returned #ESource is referenced for thread-safety and must be
2200
* unreferenced with g_object_unref() when finished with it.
2202
* Note the function returns the #ESource containing the #ESourceExtension
2203
* instead of the #ESourceExtension itself because extension instances are
2204
* not to be referenced directly (see e_source_get_extension()).
2206
* Returns: (transfer full): an #ESource, or %NULL if no match was found
2211
e_source_registry_find_extension (ESourceRegistry *registry,
2213
const gchar *extension_name)
2215
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
2216
g_return_val_if_fail (E_IS_SOURCE (source), NULL);
2217
g_return_val_if_fail (extension_name != NULL, NULL);
2219
g_object_ref (source);
2221
while (!e_source_has_extension (source, extension_name)) {
2224
uid = e_source_dup_parent (source);
2226
g_object_unref (source);
2230
source = e_source_registry_ref_source (registry, uid);
2241
/* Helper for e_source_registry_build_display_tree() */
2243
source_registry_compare_nodes (GNode *node_a,
2246
ESource *source_a = E_SOURCE (node_a->data);
2247
ESource *source_b = E_SOURCE (node_b->data);
2248
const gchar *uid_a, *uid_b;
2250
uid_a = e_source_get_uid (source_a);
2251
uid_b = e_source_get_uid (source_b);
2253
/* Sanity check, with runtime warnings. */
2254
if (uid_a == NULL) {
2255
g_warn_if_reached ();
2258
if (uid_b == NULL) {
2259
g_warn_if_reached ();
2263
/* The built-in "local-stub" source comes first at depth 1. */
2265
if (g_strcmp0 (uid_a, "local-stub") == 0)
2268
if (g_strcmp0 (uid_b, "local-stub") == 0)
2271
/* The built-in "system-*" sources come first at depth 2. */
2273
if (g_str_has_prefix (uid_a, "system-"))
2276
if (g_str_has_prefix (uid_b, "system-"))
2279
return e_source_compare_by_display_name (source_a, source_b);
2282
/* Helper for e_source_registry_build_display_tree() */
2284
source_registry_prune_nodes (GNode *node,
2285
const gchar *extension_name)
2287
GQueue queue = G_QUEUE_INIT;
2290
/* Unlink all the child nodes and place them in a queue. */
2291
while ((child_node = g_node_first_child (node)) != NULL) {
2292
g_node_unlink (child_node);
2293
g_queue_push_tail (&queue, child_node);
2296
/* Sort the queue by source name. */
2298
&queue, (GCompareDataFunc)
2299
source_registry_compare_nodes, NULL);
2301
/* Pop nodes off the head of the queue until the queue is empty.
2302
* If the node has either its own children or the given extension
2303
* name, put it back under the parent node (preserving the sorted
2304
* order). Otherwise delete the node and its descendants. */
2305
while ((child_node = g_queue_pop_head (&queue)) != NULL) {
2306
ESource *child = E_SOURCE (child_node->data);
2307
gboolean append_child_node = FALSE;
2309
if (extension_name == NULL)
2310
append_child_node = e_source_get_enabled (child);
2312
else if (e_source_has_extension (child, extension_name))
2313
append_child_node = e_source_get_enabled (child);
2315
else if (g_node_first_child (child_node) != NULL)
2316
append_child_node = e_source_get_enabled (child);
2318
if (append_child_node)
2319
g_node_append (node, child_node);
2321
e_source_registry_free_display_tree (child_node);
2328
* e_source_registry_build_display_tree:
2329
* @registry: an #ESourceRegistry
2330
* @extension_name: (allow-none): an extension name, or %NULL
2332
* Returns a single #GNode tree of registered sources that can be used to
2333
* populate a #GtkTreeModel. (The root #GNode is just an empty placeholder.)
2335
* Similar to e_source_registry_list_sources(), an @extension_name can be
2336
* given to restrict the tree to sources having that extension name. Parents
2337
* of matched sources are included in the tree regardless of whether they have
2338
* an extension named @extension_name.
2340
* Disabled leaf nodes are automatically excluded from the #GNode tree.
2342
* The sources returned in the tree are referenced for thread-safety.
2343
* They must each be unreferenced with g_object_unref() when finished
2344
* with them. Free the returned tree itself with g_node_destroy().
2345
* For convenience, e_source_registry_free_display_tree() does all
2348
* Returns: (element-type ESource) (transfer full): a tree of sources,
2349
* arranged for display
2354
e_source_registry_build_display_tree (ESourceRegistry *registry,
2355
const gchar *extension_name)
2359
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
2361
/* Assemble all data sources into a tree. */
2362
root = source_registry_sources_build_tree (registry);
2364
/* Prune unwanted nodes from the copied source trees.
2365
* This must be done in "post" order (children first)
2366
* since it reorders and deletes child nodes. */
2368
root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
2369
(GNodeTraverseFunc) source_registry_prune_nodes,
2370
(gpointer) extension_name);
2375
/* Helper for e_source_registry_free_display_tree() */
2377
source_registry_unref_nodes (GNode *node)
2379
while (node != NULL) {
2380
if (node->children != NULL)
2381
source_registry_unref_nodes (node->children);
2382
if (node->data != NULL)
2383
g_object_unref (node->data);
2389
* e_source_registry_free_display_tree:
2390
* @display_tree: a tree of sources, arranged for display
2392
* Convenience function to free a #GNode tree of registered
2393
* sources created by e_source_registry_build_display_tree().
2398
e_source_registry_free_display_tree (GNode *display_tree)
2400
g_return_if_fail (display_tree != NULL);
2402
/* XXX This would be easier if GLib had something like
2403
* g_node_destroy_full() which took a GDestroyNotify.
2404
* Then the tree would not have to be traversed twice. */
2406
source_registry_unref_nodes (display_tree);
2407
g_node_destroy (display_tree);
2410
/* Helper for e_source_registry_debug_dump() */
2412
source_registry_debug_dump_cb (GNode *node)
2416
/* Root node is an empty placeholder. */
2417
if (G_NODE_IS_ROOT (node))
2420
depth = g_node_depth (node);
2421
for (ii = 2; ii < depth; ii++)
2424
if (E_IS_SOURCE (node->data)) {
2425
ESource *source = E_SOURCE (node->data);
2426
g_print ("\"%s\" ", e_source_get_display_name (source));
2427
g_print ("(%s)", e_source_get_uid (source));
2436
* e_source_registry_debug_dump:
2437
* @registry: an #ESourceRegistry
2438
* @extension_name: (allow-none): an extension name, or %NULL
2440
* Handy debugging function that uses e_source_registry_build_display_tree()
2441
* to print a tree of registered sources to standard output.
2446
e_source_registry_debug_dump (ESourceRegistry *registry,
2447
const gchar *extension_name)
2451
g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
2453
root = e_source_registry_build_display_tree (registry, extension_name);
2456
root, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
2457
(GNodeTraverseFunc) source_registry_debug_dump_cb, NULL);
2459
e_source_registry_free_display_tree (root);
2463
* e_source_registry_ref_builtin_address_book:
2464
* @registry: an #ESourceRegistry
2466
* Returns the built-in address book #ESource.
2468
* This #ESource is always present and makes for a safe fallback.
2470
* The returned #ESource is referenced for thread-safety and must be
2471
* unreferenced with g_object_unref() when finished with it.
2473
* Returns: (transfer full): the built-in address book #ESource
2478
e_source_registry_ref_builtin_address_book (ESourceRegistry *registry)
2483
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
2485
uid = E_SOURCE_BUILTIN_ADDRESS_BOOK_UID;
2486
source = e_source_registry_ref_source (registry, uid);
2487
g_return_val_if_fail (source != NULL, NULL);
2493
* e_source_registry_ref_default_address_book:
2494
* @registry: an #ESourceRegistry
2496
* Returns the #ESource most recently passed to
2497
* e_source_registry_set_default_address_book() either in this session
2498
* or a previous session, or else falls back to the built-in address book.
2500
* The returned #ESource is referenced for thread-safety and must be
2501
* unreferenced with g_object_unref() when finished with it.
2503
* Returns: (transfer full): the default address book #ESource
2508
e_source_registry_ref_default_address_book (ESourceRegistry *registry)
2514
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
2516
key = E_SETTINGS_DEFAULT_ADDRESS_BOOK_KEY;
2517
uid = g_settings_get_string (registry->priv->settings, key);
2518
source = e_source_registry_ref_source (registry, uid);
2521
/* The built-in source is always present. */
2523
source = e_source_registry_ref_builtin_address_book (registry);
2525
g_return_val_if_fail (E_IS_SOURCE (source), NULL);
2531
* e_source_registry_set_default_address_book:
2532
* @registry: an #ESourceRegistry
2533
* @default_source: (allow-none): an address book #ESource, or %NULL
2535
* Sets @default_source as the default address book. If @default_source
2536
* is %NULL, the default address book is reset to the built-in address book.
2537
* This setting will persist across sessions until changed.
2542
e_source_registry_set_default_address_book (ESourceRegistry *registry,
2543
ESource *default_source)
2548
g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
2550
if (default_source != NULL) {
2551
g_return_if_fail (E_IS_SOURCE (default_source));
2552
uid = e_source_get_uid (default_source);
2554
uid = E_SOURCE_BUILTIN_ADDRESS_BOOK_UID;
2557
key = E_SETTINGS_DEFAULT_ADDRESS_BOOK_KEY;
2558
g_settings_set_string (registry->priv->settings, key, uid);
2560
/* The GSettings::changed signal will trigger a "notify" signal
2561
* from the registry, so no need to call g_object_notify() here. */
2565
* e_source_registry_ref_builtin_calendar:
2566
* @registry: an #ESourceRegistry
2568
* Returns the built-in calendar #ESource.
2570
* This #ESource is always present and makes for a safe fallback.
2572
* The returned #ESource is referenced for thread-safety and must be
2573
* unreferenced with g_object_unref() when finished with it.
2575
* Returns: (transfer full): the built-in calendar #ESource
2580
e_source_registry_ref_builtin_calendar (ESourceRegistry *registry)
2585
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
2587
uid = E_SOURCE_BUILTIN_CALENDAR_UID;
2588
source = e_source_registry_ref_source (registry, uid);
2589
g_return_val_if_fail (source != NULL, NULL);
2595
* e_source_registry_ref_default_calendar:
2596
* @registry: an #ESourceRegistry
2598
* Returns the #ESource most recently passed to
2599
* e_source_registry_set_default_calendar() either in this session
2600
* or a previous session, or else falls back to the built-in calendar.
2602
* The returned #ESource is referenced for thread-safety and must be
2603
* unreferenced with g_object_unref() when finished with it.
2605
* Returns: (transfer full): the default calendar #ESource
2610
e_source_registry_ref_default_calendar (ESourceRegistry *registry)
2616
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
2618
key = E_SETTINGS_DEFAULT_CALENDAR_KEY;
2619
uid = g_settings_get_string (registry->priv->settings, key);
2620
source = e_source_registry_ref_source (registry, uid);
2623
/* The built-in source is always present. */
2625
source = e_source_registry_ref_builtin_calendar (registry);
2627
g_return_val_if_fail (E_IS_SOURCE (source), NULL);
2633
* e_source_registry_set_default_calendar:
2634
* @registry: an #ESourceRegistry
2635
* @default_source: (allow-none): a calendar #ESource, or %NULL
2637
* Sets @default_source as the default calendar. If @default_source
2638
* is %NULL, the default calendar is reset to the built-in calendar.
2639
* This setting will persist across sessions until changed.
2644
e_source_registry_set_default_calendar (ESourceRegistry *registry,
2645
ESource *default_source)
2650
g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
2652
if (default_source != NULL) {
2653
g_return_if_fail (E_IS_SOURCE (default_source));
2654
uid = e_source_get_uid (default_source);
2656
uid = E_SOURCE_BUILTIN_CALENDAR_UID;
2659
key = E_SETTINGS_DEFAULT_CALENDAR_KEY;
2660
g_settings_set_string (registry->priv->settings, key, uid);
2662
/* The GSettings::changed signal will trigger a "notify" signal
2663
* from the registry, so no need to call g_object_notify() here. */
2667
* e_source_registry_ref_builtin_mail_account:
2668
* @registry: an #ESourceRegistry
2670
* Returns the built-in mail account #ESource.
2672
* This #ESource is always present and makes for a safe fallback.
2674
* The returned #ESource is referenced for thread-safety and must be
2675
* unreferenced with g_object_unref() when finished with it.
2677
* Returns: (transfer full): the built-in mail account #ESource
2682
e_source_registry_ref_builtin_mail_account (ESourceRegistry *registry)
2687
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
2689
uid = E_SOURCE_BUILTIN_MAIL_ACCOUNT_UID;
2690
source = e_source_registry_ref_source (registry, uid);
2691
g_return_val_if_fail (source != NULL, NULL);
2697
* e_source_registry_ref_default_mail_account:
2698
* @registry: an #ESourceRegistry
2700
* Returns the #ESource most recently passed to
2701
* e_source_registry_set_default_mail_account() either in this session
2702
* or a previous session, or else falls back to the built-in mail account.
2704
* The returned #ESource is referenced for thread-safety and must be
2705
* unreferenced with g_object_unref() when finished with it.
2707
* Returns: (transfer full): the default mail account #ESource
2712
e_source_registry_ref_default_mail_account (ESourceRegistry *registry)
2718
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
2720
key = E_SETTINGS_DEFAULT_MAIL_ACCOUNT_KEY;
2721
uid = g_settings_get_string (registry->priv->settings, key);
2722
source = e_source_registry_ref_source (registry, uid);
2725
/* The built-in source is always present. */
2727
source = e_source_registry_ref_builtin_mail_account (registry);
2729
g_return_val_if_fail (E_IS_SOURCE (source), NULL);
2735
* e_source_registry_set_default_mail_account:
2736
* @registry: an #ESourceRegistry
2737
* @default_source: (allow-none): a mail account #ESource, or %NULL
2739
* Sets @default_source as the default mail account. If @default_source
2740
* is %NULL, the default mail account is reset to the built-in mail account.
2741
* This setting will persist across sessions until changed.
2746
e_source_registry_set_default_mail_account (ESourceRegistry *registry,
2747
ESource *default_source)
2752
g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
2754
if (default_source != NULL) {
2755
g_return_if_fail (E_IS_SOURCE (default_source));
2756
uid = e_source_get_uid (default_source);
2758
uid = E_SOURCE_BUILTIN_MAIL_ACCOUNT_UID;
2761
key = E_SETTINGS_DEFAULT_MAIL_ACCOUNT_KEY;
2762
g_settings_set_string (registry->priv->settings, key, uid);
2764
/* The GSettings::changed signal will trigger a "notify" signal
2765
* from the registry, so no need to call g_object_notify() here. */
2768
/* Helper for e_source_registry_ref_default_mail_identity() */
2770
source_registry_ref_any_mail_identity (ESourceRegistry *registry)
2774
const gchar *extension_name;
2777
/* First fallback: Return the mail identity named
2778
* by the default mail account. */
2780
source = e_source_registry_ref_default_mail_account (registry);
2782
/* This should never be NULL, but just to be safe. */
2783
if (source != NULL) {
2784
ESourceMailAccount *extension;
2786
extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
2787
extension = e_source_get_extension (source, extension_name);
2788
uid = e_source_mail_account_dup_identity_uid (extension);
2790
g_object_unref (source);
2795
source = e_source_registry_ref_source (registry, uid);
2802
/* Second fallback: Pick any available mail identity,
2803
* preferring enabled identities. */
2805
extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
2806
list = e_source_registry_list_sources (registry, extension_name);
2808
for (link = list; link != NULL; link = g_list_next (link)) {
2809
ESource *candidate = E_SOURCE (link->data);
2811
if (e_source_get_enabled (candidate)) {
2812
source = g_object_ref (candidate);
2817
if (source == NULL && list != NULL)
2818
source = g_object_ref (link->data);
2820
g_list_free_full (list, (GDestroyNotify) g_object_unref);
2826
* e_source_registry_ref_default_mail_identity:
2827
* @registry: an #ESourceRegistry
2829
* Returns the #ESource most recently passed to
2830
* e_source_registry_set_default_mail_identity() either in this session
2831
* or a previous session, or else falls back to the mail identity named
2832
* by the default mail account. If even that fails it returns any mail
2833
* identity from @registry, or %NULL if there are none.
2835
* The returned #ESource is referenced for thread-safety and must be
2836
* unreferenced with g_object_unref() when finished with it.
2838
* Returns: (transfer full): the default mail identity #ESource, or %NULL
2843
e_source_registry_ref_default_mail_identity (ESourceRegistry *registry)
2849
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
2851
key = E_SETTINGS_DEFAULT_MAIL_IDENTITY_KEY;
2852
uid = g_settings_get_string (registry->priv->settings, key);
2853
source = e_source_registry_ref_source (registry, uid);
2857
source = source_registry_ref_any_mail_identity (registry);
2863
* e_source_registry_set_default_mail_identity:
2864
* @registry: an #ESourceRegistry
2865
* @default_source: (allow-none): a mail identity #ESource, or %NULL
2867
* Sets @default_source as the default mail identity. If @default_source
2868
* is %NULL, the next request for the default mail identity will use the
2869
* fallbacks described in e_source_registry_get_default_mail_identity().
2874
e_source_registry_set_default_mail_identity (ESourceRegistry *registry,
2875
ESource *default_source)
2880
g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
2882
if (default_source != NULL) {
2883
g_return_if_fail (E_IS_SOURCE (default_source));
2884
uid = e_source_get_uid (default_source);
2886
uid = ""; /* no built-in mail identity */
2889
key = E_SETTINGS_DEFAULT_MAIL_IDENTITY_KEY;
2890
g_settings_set_string (registry->priv->settings, key, uid);
2892
/* The GSettings::changed signal will trigger a "notify" signal
2893
* from the registry, so no need to call g_object_notify() here. */
2897
* e_source_registry_ref_builtin_memo_list:
2898
* @registry: an #ESourceRegistry
2900
* Returns the built-in memo list #ESource.
2902
* This #ESource is always present and makes for a safe fallback.
2904
* The returned #ESource is referenced for thread-safety and must be
2905
* unreferenced with g_object_unref() when finished with it.
2907
* Returns: (transfer full): the built-in memo list #ESource
2912
e_source_registry_ref_builtin_memo_list (ESourceRegistry *registry)
2917
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
2919
uid = E_SOURCE_BUILTIN_MEMO_LIST_UID;
2920
source = e_source_registry_ref_source (registry, uid);
2921
g_return_val_if_fail (source != NULL, NULL);
2927
* e_source_registry_ref_default_memo_list:
2928
* @registry: an #ESourceRegistry
2930
* Returns the #ESource most recently passed to
2931
* e_source_registry_set_default_memo_list() either in this session
2932
* or a previous session, or else falls back to the built-in memo list.
2934
* The returned #ESource is referenced for thread-safety and must be
2935
* unreferenced with g_object_unref() when finished with it.
2937
* Returns: (transfer full): the default memo list #ESource
2942
e_source_registry_ref_default_memo_list (ESourceRegistry *registry)
2948
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
2950
key = E_SETTINGS_DEFAULT_MEMO_LIST_KEY;
2951
uid = g_settings_get_string (registry->priv->settings, key);
2952
source = e_source_registry_ref_source (registry, uid);
2955
/* The built-in source is always present. */
2957
source = e_source_registry_ref_builtin_memo_list (registry);
2959
g_return_val_if_fail (E_IS_SOURCE (source), NULL);
2965
* e_source_registry_set_default_memo_list:
2966
* @registry: an #ESourceRegistry
2967
* @default_source: (allow-none): a memo list #ESource, or %NULL
2969
* Sets @default_source as the default memo list. If @default_source
2970
* is %NULL, the default memo list is reset to the built-in memo list.
2971
* This setting will persist across sessions until changed.
2976
e_source_registry_set_default_memo_list (ESourceRegistry *registry,
2977
ESource *default_source)
2982
g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
2984
if (default_source != NULL) {
2985
g_return_if_fail (E_IS_SOURCE (default_source));
2986
uid = e_source_get_uid (default_source);
2988
uid = E_SOURCE_BUILTIN_MEMO_LIST_UID;
2991
key = E_SETTINGS_DEFAULT_MEMO_LIST_KEY;
2992
g_settings_set_string (registry->priv->settings, key, uid);
2994
/* The GSettings::changed signal will trigger a "notify" signal
2995
* from the registry, so no need to call g_object_notify() here. */
2999
* e_source_registry_ref_builtin_task_list:
3000
* @registry: an #ESourceRegistry
3002
* Returns the built-in task list #ESource.
3004
* This #ESource is always present and makes for a safe fallback.
3006
* The returned #ESource is referenced for thread-safety and must be
3007
* unreferenced with g_object_unref() when finished with it.
3009
* Returns: (transfer full): the built-in task list #ESource
3014
e_source_registry_ref_builtin_task_list (ESourceRegistry *registry)
3019
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
3021
uid = E_SOURCE_BUILTIN_TASK_LIST_UID;
3022
source = e_source_registry_ref_source (registry, uid);
3023
g_return_val_if_fail (source != NULL, NULL);
3029
* e_source_registry_ref_default_task_list:
3030
* @registry: an #ESourceRegistry
3032
* Returns the #ESource most recently passed to
3033
* e_source_registry_set_default_task_list() either in this session
3034
* or a previous session, or else falls back to the built-in task list.
3036
* The returned #ESource is referenced for thread-safety and must be
3037
* unreferenced with g_object_unref() when finished with it.
3039
* Returns: (transfer full): the default task list #ESource
3044
e_source_registry_ref_default_task_list (ESourceRegistry *registry)
3050
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
3052
key = E_SETTINGS_DEFAULT_TASK_LIST_KEY;
3053
uid = g_settings_get_string (registry->priv->settings, key);
3054
source = e_source_registry_ref_source (registry, uid);
3057
/* The built-in source is always present. */
3059
source = e_source_registry_ref_builtin_task_list (registry);
3061
g_return_val_if_fail (E_IS_SOURCE (source), NULL);
3067
* e_source_registry_set_default_task_list:
3068
* @registry: an #ESourceRegistry
3069
* @default_source: (allow-none): a task list #ESource, or %NULL
3071
* Sets @default_source as the default task list. If @default_source
3072
* is %NULL, the default task list is reset to the built-in task list.
3073
* This setting will persist across sessions until changed.
3078
e_source_registry_set_default_task_list (ESourceRegistry *registry,
3079
ESource *default_source)
3084
g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
3086
if (default_source != NULL) {
3087
g_return_if_fail (E_IS_SOURCE (default_source));
3088
uid = e_source_get_uid (default_source);
3090
uid = E_SOURCE_BUILTIN_TASK_LIST_UID;
3093
key = E_SETTINGS_DEFAULT_TASK_LIST_KEY;
3094
g_settings_set_string (registry->priv->settings, key, uid);
3096
/* The GSettings::changed signal will trigger a "notify" signal
3097
* from the registry, so no need to call g_object_notify() here. */
3101
* e_source_registry_ref_default_for_extension_name:
3102
* @registry: an #ESourceRegistry
3103
* @extension_name: an extension_name
3105
* This is a convenience function to return a default #ESource based on
3106
* @extension_name. This only works with a subset of extension names.
3108
* If @extension_name is #E_SOURCE_EXTENSION_ADDRESS_BOOK, the function
3109
* returns the current default address book, or else falls back to the
3110
* built-in address book.
3112
* If @extension_name is #E_SOURCE_EXTENSION_CALENDAR, the function returns
3113
* the current default calendar, or else falls back to the built-in calendar.
3115
* If @extension_name is #E_SOURCE_EXTENSION_MAIL_ACCOUNT, the function
3116
* returns the current default mail account, or else falls back to the
3117
* built-in mail account.
3119
* If @extension_name is #E_SOURCE_EXTENSION_MAIL_IDENTITY, the function
3120
* returns the current default mail identity, or else falls back to the
3121
* mail identity named by the current default mail account.
3123
* If @extension_name is #E_SOURCE_EXTENSION_MEMO_LIST, the function returns
3124
* the current default memo list, or else falls back to the built-in memo list.
3126
* If @extension_name is #E_SOURCE_EXTENSION_TASK_LIST, the function returns
3127
* the current default task list, or else falls back to the built-in task list.
3129
* For all other values of @extension_name, the function returns %NULL.
3131
* The returned #ESource is referenced for thread-safety and must be
3132
* unreferenced with g_object_unref() when finished with it.
3134
* Returns: (transfer full): the default #ESource based on @extension_name
3139
e_source_registry_ref_default_for_extension_name (ESourceRegistry *registry,
3140
const gchar *extension_name)
3142
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
3143
g_return_val_if_fail (extension_name != NULL, NULL);
3145
if (strcmp (extension_name, E_SOURCE_EXTENSION_ADDRESS_BOOK) == 0)
3146
return e_source_registry_ref_default_address_book (registry);
3148
if (strcmp (extension_name, E_SOURCE_EXTENSION_CALENDAR) == 0)
3149
return e_source_registry_ref_default_calendar (registry);
3151
if (strcmp (extension_name, E_SOURCE_EXTENSION_MAIL_ACCOUNT) == 0)
3152
return e_source_registry_ref_default_mail_account (registry);
3154
if (strcmp (extension_name, E_SOURCE_EXTENSION_MAIL_IDENTITY) == 0)
3155
return e_source_registry_ref_default_mail_identity (registry);
3157
if (strcmp (extension_name, E_SOURCE_EXTENSION_MEMO_LIST) == 0)
3158
return e_source_registry_ref_default_memo_list (registry);
3160
if (strcmp (extension_name, E_SOURCE_EXTENSION_TASK_LIST) == 0)
3161
return e_source_registry_ref_default_task_list (registry);
3167
* e_source_registry_set_default_for_extension_name:
3168
* @registry: an #ESourceRegistry
3169
* @extension_name: an extension name
3170
* @default_source: (allow-none): an #ESource, or %NULL
3172
* This is a convenience function to set a default #ESource based on
3173
* @extension_name. This only works with a subset of extension names.
3175
* If @extension_name is #E_SOURCE_EXTENSION_ADDRESS_BOOK, the function
3176
* sets @default_source as the default address book. If @default_source
3177
* is %NULL, the default address book is reset to the built-in address book.
3179
* If @extension_name is #E_SOURCE_EXTENSION_CALENDAR, the function sets
3180
* @default_source as the default calendar. If @default_source is %NULL,
3181
* the default calendar is reset to the built-in calendar.
3183
* If @extension_name is #E_SOURCE_EXTENSION_MAIL_ACCOUNT, the function
3184
* sets @default_source as the default mail account. If @default_source
3185
* is %NULL, the default mail account is reset to the built-in mail account.
3187
* If @extension_name is #E_SOURCE_EXTENSION_MAIL_IDENTITY, the function
3188
* sets @default_source as the default mail identity. If @default_source
3189
* is %NULL, the next request for the default mail identity will return
3190
* the mail identity named by the default mail account.
3192
* If @extension_name is #E_SOURCE_EXTENSION_MEMO_LIST, the function sets
3193
* @default_source as the default memo list. If @default_source is %NULL,
3194
* the default memo list is reset to the built-in memo list.
3196
* If @extension_name is #E_SOURCE_EXTENSION_TASK_LIST, the function sets
3197
* @default_source as the default task list. If @default_source is %NULL,
3198
* the default task list is reset to the built-in task list.
3200
* For all other values of @extension_name, the function does nothing.
3205
e_source_registry_set_default_for_extension_name (ESourceRegistry *registry,
3206
const gchar *extension_name,
3207
ESource *default_source)
3209
g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
3210
g_return_if_fail (extension_name != NULL);
3212
if (strcmp (extension_name, E_SOURCE_EXTENSION_ADDRESS_BOOK) == 0)
3213
e_source_registry_set_default_address_book (
3214
registry, default_source);
3216
if (strcmp (extension_name, E_SOURCE_EXTENSION_CALENDAR) == 0)
3217
e_source_registry_set_default_calendar (
3218
registry, default_source);
3220
if (strcmp (extension_name, E_SOURCE_EXTENSION_MAIL_ACCOUNT) == 0)
3221
e_source_registry_set_default_mail_account (
3222
registry, default_source);
3224
if (strcmp (extension_name, E_SOURCE_EXTENSION_MAIL_IDENTITY) == 0)
3225
e_source_registry_set_default_mail_identity (
3226
registry, default_source);
3228
if (strcmp (extension_name, E_SOURCE_EXTENSION_MEMO_LIST) == 0)
3229
e_source_registry_set_default_memo_list (
3230
registry, default_source);
3232
if (strcmp (extension_name, E_SOURCE_EXTENSION_TASK_LIST) == 0)
3233
e_source_registry_set_default_task_list (
3234
registry, default_source);