No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-mail-config-notebook.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-mail-config-notebook.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /*
2 * e-mail-config-notebook.c
3 *
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.
8 *
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.
13 *
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/>
16 *
17 */
18
19 #include "e-mail-config-notebook.h"
20
21 #include <libebackend/libebackend.h>
22
23 #include <mail/e-mail-config-defaults-page.h>
24 #include <mail/e-mail-config-identity-page.h>
25 #include <mail/e-mail-config-provider-page.h>
26 #include <mail/e-mail-config-receiving-page.h>
27 #include <mail/e-mail-config-security-page.h>
28 #include <mail/e-mail-config-sending-page.h>
29
30 #define E_MAIL_CONFIG_NOTEBOOK_GET_PRIVATE(obj) \
31 (G_TYPE_INSTANCE_GET_PRIVATE \
32 ((obj), E_TYPE_MAIL_CONFIG_NOTEBOOK, EMailConfigNotebookPrivate))
33
34 typedef struct _AsyncContext AsyncContext;
35
36 struct _EMailConfigNotebookPrivate {
37 EMailSession *session;
38 ESource *account_source;
39 ESource *identity_source;
40 ESource *transport_source;
41 ESource *collection_source;
42 };
43
44 struct _AsyncContext {
45 ESourceRegistry *registry;
46 GCancellable *cancellable;
47 GQueue *page_queue;
48 GQueue *source_queue;
49 };
50
51 enum {
52 PROP_0,
53 PROP_ACCOUNT_SOURCE,
54 PROP_COLLECTION_SOURCE,
55 PROP_COMPLETE,
56 PROP_IDENTITY_SOURCE,
57 PROP_SESSION,
58 PROP_TRANSPORT_SOURCE
59 };
60
61 G_DEFINE_TYPE_WITH_CODE (
62 EMailConfigNotebook,
63 e_mail_config_notebook,
64 GTK_TYPE_NOTEBOOK,
65 G_IMPLEMENT_INTERFACE (
66 E_TYPE_EXTENSIBLE, NULL))
67
68 static void
69 async_context_free (AsyncContext *async_context)
70 {
71 if (async_context->registry != NULL)
72 g_object_unref (async_context->registry);
73
74 if (async_context->cancellable != NULL)
75 g_object_unref (async_context->cancellable);
76
77 g_queue_free_full (
78 async_context->page_queue,
79 (GDestroyNotify) g_object_unref);
80
81 g_queue_free_full (
82 async_context->source_queue,
83 (GDestroyNotify) g_object_unref);
84
85 g_slice_free (AsyncContext, async_context);
86 }
87
88 static void
89 mail_config_notebook_sort_pages (EMailConfigNotebook *notebook)
90 {
91 GList *list, *link;
92 gint ii = 0;
93
94 list = g_list_sort (
95 gtk_container_get_children (GTK_CONTAINER (notebook)),
96 (GCompareFunc) e_mail_config_page_compare);
97
98 for (link = list; link != NULL; link = g_list_next (link))
99 gtk_notebook_reorder_child (
100 GTK_NOTEBOOK (notebook),
101 GTK_WIDGET (link->data), ii++);
102
103 g_list_free (list);
104 }
105
106 static void
107 mail_config_notebook_page_changed (EMailConfigPage *page,
108 EMailConfigNotebook *notebook)
109 {
110 g_object_notify (G_OBJECT (notebook), "complete");
111 }
112
113 static void
114 mail_config_notebook_set_account_source (EMailConfigNotebook *notebook,
115 ESource *account_source)
116 {
117 g_return_if_fail (E_IS_SOURCE (account_source));
118 g_return_if_fail (notebook->priv->account_source == NULL);
119
120 notebook->priv->account_source = g_object_ref (account_source);
121 }
122
123 static void
124 mail_config_notebook_set_collection_source (EMailConfigNotebook *notebook,
125 ESource *collection_source)
126 {
127 g_return_if_fail (notebook->priv->collection_source == NULL);
128
129 if (collection_source != NULL) {
130 g_return_if_fail (E_IS_SOURCE (collection_source));
131 g_object_ref (collection_source);
132 }
133
134 notebook->priv->collection_source = collection_source;
135 }
136
137 static void
138 mail_config_notebook_set_identity_source (EMailConfigNotebook *notebook,
139 ESource *identity_source)
140 {
141 g_return_if_fail (E_IS_SOURCE (identity_source));
142 g_return_if_fail (notebook->priv->identity_source == NULL);
143
144 notebook->priv->identity_source = g_object_ref (identity_source);
145 }
146
147 static void
148 mail_config_notebook_set_session (EMailConfigNotebook *notebook,
149 EMailSession *session)
150 {
151 g_return_if_fail (E_IS_MAIL_SESSION (session));
152 g_return_if_fail (notebook->priv->session == NULL);
153
154 notebook->priv->session = g_object_ref (session);
155 }
156
157 static void
158 mail_config_notebook_set_transport_source (EMailConfigNotebook *notebook,
159 ESource *transport_source)
160 {
161 g_return_if_fail (E_IS_SOURCE (transport_source));
162 g_return_if_fail (notebook->priv->transport_source == NULL);
163
164 notebook->priv->transport_source = g_object_ref (transport_source);
165 }
166
167 static void
168 mail_config_notebook_set_property (GObject *object,
169 guint property_id,
170 const GValue *value,
171 GParamSpec *pspec)
172 {
173 switch (property_id) {
174 case PROP_ACCOUNT_SOURCE:
175 mail_config_notebook_set_account_source (
176 E_MAIL_CONFIG_NOTEBOOK (object),
177 g_value_get_object (value));
178 return;
179
180 case PROP_COLLECTION_SOURCE:
181 mail_config_notebook_set_collection_source (
182 E_MAIL_CONFIG_NOTEBOOK (object),
183 g_value_get_object (value));
184 return;
185
186 case PROP_IDENTITY_SOURCE:
187 mail_config_notebook_set_identity_source (
188 E_MAIL_CONFIG_NOTEBOOK (object),
189 g_value_get_object (value));
190 return;
191
192 case PROP_SESSION:
193 mail_config_notebook_set_session (
194 E_MAIL_CONFIG_NOTEBOOK (object),
195 g_value_get_object (value));
196 return;
197
198 case PROP_TRANSPORT_SOURCE:
199 mail_config_notebook_set_transport_source (
200 E_MAIL_CONFIG_NOTEBOOK (object),
201 g_value_get_object (value));
202 return;
203 }
204
205 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
206 }
207
208 static void
209 mail_config_notebook_get_property (GObject *object,
210 guint property_id,
211 GValue *value,
212 GParamSpec *pspec)
213 {
214 switch (property_id) {
215 case PROP_ACCOUNT_SOURCE:
216 g_value_set_object (
217 value,
218 e_mail_config_notebook_get_account_source (
219 E_MAIL_CONFIG_NOTEBOOK (object)));
220 return;
221
222 case PROP_COLLECTION_SOURCE:
223 g_value_set_object (
224 value,
225 e_mail_config_notebook_get_collection_source (
226 E_MAIL_CONFIG_NOTEBOOK (object)));
227 return;
228
229 case PROP_COMPLETE:
230 g_value_set_boolean (
231 value,
232 e_mail_config_notebook_check_complete (
233 E_MAIL_CONFIG_NOTEBOOK (object)));
234 return;
235
236 case PROP_IDENTITY_SOURCE:
237 g_value_set_object (
238 value,
239 e_mail_config_notebook_get_identity_source (
240 E_MAIL_CONFIG_NOTEBOOK (object)));
241 return;
242
243 case PROP_SESSION:
244 g_value_set_object (
245 value,
246 e_mail_config_notebook_get_session (
247 E_MAIL_CONFIG_NOTEBOOK (object)));
248 return;
249
250 case PROP_TRANSPORT_SOURCE:
251 g_value_set_object (
252 value,
253 e_mail_config_notebook_get_transport_source (
254 E_MAIL_CONFIG_NOTEBOOK (object)));
255 return;
256 }
257
258 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
259 }
260
261 static void
262 mail_config_notebook_dispose (GObject *object)
263 {
264 EMailConfigNotebookPrivate *priv;
265
266 priv = E_MAIL_CONFIG_NOTEBOOK_GET_PRIVATE (object);
267
268 if (priv->session != NULL) {
269 g_object_ref (priv->session);
270 priv->session = NULL;
271 }
272
273 if (priv->account_source != NULL) {
274 g_object_ref (priv->account_source);
275 priv->account_source = NULL;
276 }
277
278 if (priv->identity_source != NULL) {
279 g_object_ref (priv->identity_source);
280 priv->identity_source = NULL;
281 }
282
283 if (priv->transport_source != NULL) {
284 g_object_ref (priv->transport_source);
285 priv->transport_source = NULL;
286 }
287
288 if (priv->collection_source != NULL) {
289 g_object_ref (priv->collection_source);
290 priv->collection_source = NULL;
291 }
292
293 /* Chain up to parent's dispose() method. */
294 G_OBJECT_CLASS (e_mail_config_notebook_parent_class)->
295 dispose (object);
296 }
297
298 static void
299 mail_config_notebook_constructed (GObject *object)
300 {
301 EMailConfigNotebook *notebook;
302 ESource *source;
303 ESourceRegistry *registry;
304 ESourceExtension *extension;
305 ESourceMailIdentity *mail_identity_extension;
306 EMailConfigServiceBackend *backend;
307 CamelProvider *provider = NULL;
308 EMailSession *session;
309 EMailConfigPage *page;
310 const gchar *extension_name;
311 gboolean add_receiving_page = TRUE;
312 gboolean add_sending_page = TRUE;
313 gboolean add_transport_source;
314 gboolean gnome_online_account = FALSE;
315
316 notebook = E_MAIL_CONFIG_NOTEBOOK (object);
317
318 /* Chain up to parent's constructed() method. */
319 G_OBJECT_CLASS (e_mail_config_notebook_parent_class)->
320 constructed (object);
321
322 session = e_mail_config_notebook_get_session (notebook);
323 registry = e_mail_session_get_registry (session);
324
325 source = notebook->priv->identity_source;
326 extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
327 extension = e_source_get_extension (source, extension_name);
328 mail_identity_extension = E_SOURCE_MAIL_IDENTITY (extension);
329
330 /* If we have a collection source and the collection source
331 * has a [GNOME Online Accounts] extension, skip the Receiving
332 * and Sending pages since GOA dictates those settings. */
333 source = notebook->priv->collection_source;
334 if (source != NULL) {
335 extension_name = E_SOURCE_EXTENSION_GOA;
336 if (e_source_has_extension (source, extension_name)) {
337 gnome_online_account = TRUE;
338 add_receiving_page = FALSE;
339 add_sending_page = FALSE;
340 }
341 }
342
343 /* Keep all the display name properties synchronized.
344 * We consider the identity source's display name to
345 * be authoritative since technically that's the one
346 * shown on the Identity page. */
347
348 g_object_bind_property (
349 notebook->priv->identity_source, "display-name",
350 notebook->priv->account_source, "display-name",
351 G_BINDING_SYNC_CREATE);
352
353 g_object_bind_property (
354 notebook->priv->identity_source, "display-name",
355 notebook->priv->transport_source, "display-name",
356 G_BINDING_SYNC_CREATE);
357
358 if (notebook->priv->collection_source != NULL)
359 g_object_bind_property (
360 notebook->priv->identity_source, "display-name",
361 notebook->priv->collection_source, "display-name",
362 G_BINDING_SYNC_CREATE);
363
364 /*** Identity Page ***/
365
366 page = e_mail_config_identity_page_new (
367 registry, notebook->priv->identity_source);
368 e_mail_config_identity_page_set_show_instructions (
369 E_MAIL_CONFIG_IDENTITY_PAGE (page), FALSE);
370 if (gnome_online_account) {
371 e_mail_config_identity_page_set_show_account_info (
372 E_MAIL_CONFIG_IDENTITY_PAGE (page), FALSE);
373 e_mail_config_identity_page_set_show_email_address (
374 E_MAIL_CONFIG_IDENTITY_PAGE (page), FALSE);
375 }
376 e_mail_config_notebook_add_page (notebook, page);
377
378 /*** Receiving Page ***/
379
380 page = e_mail_config_receiving_page_new (registry);
381 backend = e_mail_config_service_page_add_scratch_source (
382 E_MAIL_CONFIG_SERVICE_PAGE (page),
383 notebook->priv->account_source,
384 notebook->priv->collection_source);
385 if (add_receiving_page) {
386 e_mail_config_notebook_add_page (notebook, page);
387
388 g_object_bind_property (
389 mail_identity_extension, "address",
390 page, "email-address",
391 G_BINDING_SYNC_CREATE);
392 }
393
394 if (backend != NULL)
395 provider = e_mail_config_service_backend_get_provider (backend);
396
397 /*** Receiving Options (conditional) ***/
398
399 /* Note: We exclude this page if it has no options,
400 * but we don't know that until we create it. */
401 page = backend ? e_mail_config_provider_page_new (backend) : NULL;
402 if (page && e_mail_config_provider_page_is_empty (
403 E_MAIL_CONFIG_PROVIDER_PAGE (page))) {
404 g_object_unref (g_object_ref_sink (page));
405 } else if (page) {
406 e_mail_config_notebook_add_page (notebook, page);
407 }
408
409 /*** Sending Page (conditional) ***/
410
411 add_transport_source =
412 (provider != NULL) &&
413 (!CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider));
414
415 if (add_transport_source) {
416 page = e_mail_config_sending_page_new (registry);
417 e_mail_config_service_page_add_scratch_source (
418 E_MAIL_CONFIG_SERVICE_PAGE (page),
419 notebook->priv->transport_source,
420 notebook->priv->collection_source);
421 if (add_sending_page) {
422 e_mail_config_notebook_add_page (notebook, page);
423
424 g_object_bind_property (
425 mail_identity_extension, "address",
426 page, "email-address",
427 G_BINDING_SYNC_CREATE);
428 }
429 }
430
431 /*** Defaults Page ***/
432
433 page = e_mail_config_defaults_page_new (
434 session,
435 notebook->priv->account_source,
436 notebook->priv->identity_source);
437 e_mail_config_notebook_add_page (notebook, page);
438
439 /*** Security Page ***/
440
441 page = e_mail_config_security_page_new (
442 notebook->priv->identity_source);
443 e_mail_config_notebook_add_page (notebook, page);
444
445 e_extensible_load_extensions (E_EXTENSIBLE (notebook));
446 }
447
448 static void
449 mail_config_notebook_page_removed (GtkNotebook *notebook,
450 GtkWidget *child,
451 guint page_num)
452 {
453 /* Do not chain up. GtkNotebook does not implement this method. */
454
455 if (E_IS_MAIL_CONFIG_PAGE (child))
456 g_signal_handlers_disconnect_by_func (
457 child, mail_config_notebook_page_changed,
458 E_MAIL_CONFIG_NOTEBOOK (notebook));
459 }
460
461 static void
462 mail_config_notebook_page_added (GtkNotebook *notebook,
463 GtkWidget *child,
464 guint page_num)
465 {
466 /* Do not chain up. GtkNotebook does not implement this method. */
467
468 if (E_IS_MAIL_CONFIG_PAGE (child))
469 g_signal_connect (
470 child, "changed",
471 G_CALLBACK (mail_config_notebook_page_changed),
472 E_MAIL_CONFIG_NOTEBOOK (notebook));
473 }
474
475 static void
476 e_mail_config_notebook_class_init (EMailConfigNotebookClass *class)
477 {
478 GObjectClass *object_class;
479 GtkNotebookClass *notebook_class;
480
481 g_type_class_add_private (class, sizeof (EMailConfigNotebookPrivate));
482
483 object_class = G_OBJECT_CLASS (class);
484 object_class->set_property = mail_config_notebook_set_property;
485 object_class->get_property = mail_config_notebook_get_property;
486 object_class->dispose = mail_config_notebook_dispose;
487 object_class->constructed = mail_config_notebook_constructed;
488
489 notebook_class = GTK_NOTEBOOK_CLASS (class);
490 notebook_class->page_removed = mail_config_notebook_page_removed;
491 notebook_class->page_added = mail_config_notebook_page_added;
492
493 g_object_class_install_property (
494 object_class,
495 PROP_ACCOUNT_SOURCE,
496 g_param_spec_object (
497 "account-source",
498 "Account Source",
499 "Mail account source being edited",
500 E_TYPE_SOURCE,
501 G_PARAM_READWRITE |
502 G_PARAM_CONSTRUCT_ONLY |
503 G_PARAM_STATIC_STRINGS));
504
505 g_object_class_install_property (
506 object_class,
507 PROP_COLLECTION_SOURCE,
508 g_param_spec_object (
509 "collection-source",
510 "Collection Source",
511 "Optional collection source being edited",
512 E_TYPE_SOURCE,
513 G_PARAM_READWRITE |
514 G_PARAM_CONSTRUCT_ONLY |
515 G_PARAM_STATIC_STRINGS));
516
517 g_object_class_install_property (
518 object_class,
519 PROP_COMPLETE,
520 g_param_spec_boolean (
521 "complete",
522 "Complete",
523 "Whether all required fields are complete",
524 FALSE, /* default is not used */
525 G_PARAM_READABLE |
526 G_PARAM_STATIC_STRINGS));
527
528 g_object_class_install_property (
529 object_class,
530 PROP_IDENTITY_SOURCE,
531 g_param_spec_object (
532 "identity-source",
533 "Identity Source",
534 "Mail identity source being edited",
535 E_TYPE_SOURCE,
536 G_PARAM_READWRITE |
537 G_PARAM_CONSTRUCT_ONLY |
538 G_PARAM_STATIC_STRINGS));
539
540 g_object_class_install_property (
541 object_class,
542 PROP_SESSION,
543 g_param_spec_object (
544 "session",
545 "Session",
546 "Mail session",
547 E_TYPE_MAIL_SESSION,
548 G_PARAM_READWRITE |
549 G_PARAM_CONSTRUCT_ONLY |
550 G_PARAM_STATIC_STRINGS));
551
552 g_object_class_install_property (
553 object_class,
554 PROP_TRANSPORT_SOURCE,
555 g_param_spec_object (
556 "transport-source",
557 "Transport Source",
558 "Mail transport source being edited",
559 E_TYPE_SOURCE,
560 G_PARAM_READWRITE |
561 G_PARAM_CONSTRUCT_ONLY |
562 G_PARAM_STATIC_STRINGS));
563 }
564
565 static void
566 e_mail_config_notebook_init (EMailConfigNotebook *notebook)
567 {
568 notebook->priv = E_MAIL_CONFIG_NOTEBOOK_GET_PRIVATE (notebook);
569 }
570
571 GtkWidget *
572 e_mail_config_notebook_new (EMailSession *session,
573 ESource *account_source,
574 ESource *identity_source,
575 ESource *transport_source,
576 ESource *collection_source)
577 {
578 g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
579 g_return_val_if_fail (E_IS_SOURCE (account_source), NULL);
580 g_return_val_if_fail (E_IS_SOURCE (identity_source), NULL);
581 g_return_val_if_fail (E_IS_SOURCE (transport_source), NULL);
582
583 /* A collection source is optional. */
584 if (collection_source != NULL)
585 g_return_val_if_fail (E_IS_SOURCE (collection_source), NULL);
586
587 return g_object_new (
588 E_TYPE_MAIL_CONFIG_NOTEBOOK,
589 "session", session,
590 "account-source", account_source,
591 "identity-source", identity_source,
592 "transport-source", transport_source,
593 "collection-source", collection_source,
594 NULL);
595 }
596
597 EMailSession *
598 e_mail_config_notebook_get_session (EMailConfigNotebook *notebook)
599 {
600 g_return_val_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook), NULL);
601
602 return notebook->priv->session;
603 }
604
605 ESource *
606 e_mail_config_notebook_get_account_source (EMailConfigNotebook *notebook)
607 {
608 g_return_val_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook), NULL);
609
610 return notebook->priv->account_source;
611 }
612
613 ESource *
614 e_mail_config_notebook_get_identity_source (EMailConfigNotebook *notebook)
615 {
616 g_return_val_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook), NULL);
617
618 return notebook->priv->identity_source;
619 }
620
621 ESource *
622 e_mail_config_notebook_get_transport_source (EMailConfigNotebook *notebook)
623 {
624 g_return_val_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook), NULL);
625
626 return notebook->priv->transport_source;
627 }
628
629 ESource *
630 e_mail_config_notebook_get_collection_source (EMailConfigNotebook *notebook)
631 {
632 g_return_val_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook), NULL);
633
634 return notebook->priv->collection_source;
635 }
636
637 void
638 e_mail_config_notebook_add_page (EMailConfigNotebook *notebook,
639 EMailConfigPage *page)
640 {
641 EMailConfigPageInterface *page_interface;
642 GtkWidget *tab_label;
643
644 g_return_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook));
645 g_return_if_fail (E_IS_MAIL_CONFIG_PAGE (page));
646
647 page_interface = E_MAIL_CONFIG_PAGE_GET_INTERFACE (page);
648 tab_label = gtk_label_new (page_interface->title);
649
650 gtk_widget_show (GTK_WIDGET (page));
651
652 gtk_notebook_append_page (
653 GTK_NOTEBOOK (notebook),
654 GTK_WIDGET (page), tab_label);
655
656 mail_config_notebook_sort_pages (notebook);
657 }
658
659 gboolean
660 e_mail_config_notebook_check_complete (EMailConfigNotebook *notebook)
661 {
662 GList *list, *link;
663 gboolean complete = TRUE;
664
665 g_return_val_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook), FALSE);
666
667 list = gtk_container_get_children (GTK_CONTAINER (notebook));
668
669 for (link = list; link != NULL; link = g_list_next (link)) {
670 if (E_IS_MAIL_CONFIG_PAGE (link->data)) {
671 EMailConfigPage *page;
672 page = E_MAIL_CONFIG_PAGE (link->data);
673 complete = e_mail_config_page_check_complete (page);
674
675 if (!complete)
676 break;
677 }
678 }
679
680 g_list_free (list);
681
682 return complete;
683 }
684
685 /********************** e_mail_config_notebook_commit() **********************/
686
687 static void
688 mail_config_notebook_page_submit_cb (GObject *source_object,
689 GAsyncResult *result,
690 gpointer user_data)
691 {
692 GSimpleAsyncResult *simple;
693 AsyncContext *async_context;
694 EMailConfigPage *next_page;
695 GError *error = NULL;
696
697 simple = G_SIMPLE_ASYNC_RESULT (user_data);
698 async_context = g_simple_async_result_get_op_res_gpointer (simple);
699
700 e_mail_config_page_submit_finish (
701 E_MAIL_CONFIG_PAGE (source_object), result, &error);
702
703 if (error != NULL) {
704 g_simple_async_result_take_error (simple, error);
705 g_simple_async_result_complete (simple);
706 g_object_unref (simple);
707 return;
708 }
709
710 next_page = g_queue_pop_head (async_context->page_queue);
711
712 /* Submit the next EMailConfigPage. */
713 if (next_page != NULL) {
714 e_mail_config_page_submit (
715 next_page, async_context->cancellable,
716 mail_config_notebook_page_submit_cb, simple);
717
718 g_object_unref (next_page);
719
720 /* All done! */
721 } else {
722 g_simple_async_result_complete (simple);
723 g_object_unref (simple);
724 }
725 }
726
727 static void
728 mail_config_notebook_source_commit_cb (GObject *source_object,
729 GAsyncResult *result,
730 gpointer user_data)
731 {
732 GSimpleAsyncResult *simple;
733 AsyncContext *async_context;
734 ESource *next_source;
735 GError *error = NULL;
736
737 simple = G_SIMPLE_ASYNC_RESULT (user_data);
738 async_context = g_simple_async_result_get_op_res_gpointer (simple);
739
740 e_source_registry_commit_source_finish (
741 E_SOURCE_REGISTRY (source_object), result, &error);
742
743 if (error != NULL) {
744 g_simple_async_result_take_error (simple, error);
745 g_simple_async_result_complete (simple);
746 g_object_unref (simple);
747 return;
748 }
749
750 next_source = g_queue_pop_head (async_context->source_queue);
751
752 /* Commit the next ESources. */
753 if (next_source != NULL) {
754 e_source_registry_commit_source (
755 async_context->registry, next_source,
756 async_context->cancellable,
757 mail_config_notebook_source_commit_cb, simple);
758
759 g_object_unref (next_source);
760
761 /* ESources done, start on the EMailConfigPages. */
762 } else {
763 EMailConfigPage *page;
764
765 /* There should be at least one page,
766 * so we can skip the NULL check here. */
767 page = g_queue_pop_head (async_context->page_queue);
768
769 e_mail_config_page_submit (
770 page, async_context->cancellable,
771 mail_config_notebook_page_submit_cb, simple);
772
773 g_object_unref (page);
774 }
775 }
776
777 void
778 e_mail_config_notebook_commit (EMailConfigNotebook *notebook,
779 GCancellable *cancellable,
780 GAsyncReadyCallback callback,
781 gpointer user_data)
782 {
783 GSimpleAsyncResult *simple;
784 AsyncContext *async_context;
785 ESourceRegistry *registry;
786 EMailSession *session;
787 ESource *source;
788 GList *list, *link;
789 GQueue *page_queue;
790 GQueue *source_queue;
791
792 g_return_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook));
793
794 session = e_mail_config_notebook_get_session (notebook);
795 registry = e_mail_session_get_registry (session);
796
797 page_queue = g_queue_new ();
798 source_queue = g_queue_new ();
799
800 /* Queue the collection data source if one is defined. */
801 source = e_mail_config_notebook_get_collection_source (notebook);
802 if (source != NULL)
803 g_queue_push_tail (source_queue, g_object_ref (source));
804
805 /* Queue the mail-related data sources for the account. */
806 source = e_mail_config_notebook_get_account_source (notebook);
807 if (source != NULL)
808 g_queue_push_tail (source_queue, g_object_ref (source));
809 source = e_mail_config_notebook_get_identity_source (notebook);
810 if (source != NULL)
811 g_queue_push_tail (source_queue, g_object_ref (source));
812 source = e_mail_config_notebook_get_transport_source (notebook);
813 if (source != NULL)
814 g_queue_push_tail (source_queue, g_object_ref (source));
815
816 list = gtk_container_get_children (GTK_CONTAINER (notebook));
817
818 /* Tell all EMailConfigPages to commit their UI state to their
819 * scratch ESources and push any additional data sources on to
820 * the given source queue, such as calendars or address books
821 * to be bundled with the mail account. */
822 for (link = list; link != NULL; link = g_list_next (link)) {
823 if (E_IS_MAIL_CONFIG_PAGE (link->data)) {
824 EMailConfigPage *page;
825 page = E_MAIL_CONFIG_PAGE (link->data);
826 g_queue_push_tail (page_queue, g_object_ref (page));
827 e_mail_config_page_commit_changes (page, source_queue);
828 }
829 }
830
831 g_list_free (list);
832
833 async_context = g_slice_new0 (AsyncContext);
834 async_context->registry = g_object_ref (registry);
835 async_context->page_queue = page_queue; /* takes ownership */
836 async_context->source_queue = source_queue; /* takes ownership */
837
838 if (G_IS_CANCELLABLE (cancellable))
839 async_context->cancellable = g_object_ref (cancellable);
840
841 simple = g_simple_async_result_new (
842 G_OBJECT (notebook), callback, user_data,
843 e_mail_config_notebook_commit);
844
845 g_simple_async_result_set_op_res_gpointer (
846 simple, async_context, (GDestroyNotify) async_context_free);
847
848 source = g_queue_pop_head (async_context->source_queue);
849 g_return_if_fail (E_IS_SOURCE (source));
850
851 e_source_registry_commit_source (
852 async_context->registry, source,
853 async_context->cancellable,
854 mail_config_notebook_source_commit_cb, simple);
855
856 g_object_unref (source);
857 }
858
859 gboolean
860 e_mail_config_notebook_commit_finish (EMailConfigNotebook *notebook,
861 GAsyncResult *result,
862 GError **error)
863 {
864 GSimpleAsyncResult *simple;
865
866 g_return_val_if_fail (
867 g_simple_async_result_is_valid (
868 result, G_OBJECT (notebook),
869 e_mail_config_notebook_commit), FALSE);
870
871 simple = G_SIMPLE_ASYNC_RESULT (result);
872
873 /* Assume success unless a GError is set. */
874 return !g_simple_async_result_propagate_error (simple, error);
875 }