1 /*
2 * e-proxy-preferences.c
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18 /**
19 * SECTION: e-proxy-preferences
20 * @include: e-util/e-util.h
21 * @short_description: Manage network proxy preferences
22 *
23 * #EProxyPreferences is the main widget for displaying network proxy
24 * preferences. A link button toggles between a basic mode (for most
25 * users) and advanced mode. Basic mode only shows proxy details for
26 * the built-in proxy profile, which all new accounts use by default.
27 * Advanced mode reveals a sidebar of proxy profiles, allowing users
28 * to create or delete custom profiles and apply them to particular
29 * accounts.
30 **/
31
32 #include "evolution-config.h"
33
34 #include <glib/gi18n-lib.h>
35
36 #include "e-proxy-editor.h"
37 #include "e-proxy-link-selector.h"
38 #include "e-proxy-selector.h"
39
40 #include "e-proxy-preferences.h"
41
42 #define E_PROXY_PREFERENCES_GET_PRIVATE(obj) \
43 (G_TYPE_INSTANCE_GET_PRIVATE \
44 ((obj), E_TYPE_PROXY_PREFERENCES, EProxyPreferencesPrivate))
45
46 /* Rate-limit committing proxy changes to the registry. */
47 #define COMMIT_DELAY_SECS 2
48
49 struct _EProxyPreferencesPrivate {
50 ESourceRegistry *registry;
51 gulong source_changed_handler_id;
52
53 /* The widgets are not referenced. */
54 GtkWidget *proxy_selector;
55 GtkWidget *proxy_editor;
56 GtkWidget *toplevel;
57
58 gulong toplevel_notify_id;
59
60 GMutex commit_lock;
61 guint commit_timeout_id;
62 GHashTable *commit_sources;
63
64 gboolean show_advanced;
65 };
66
67 enum {
68 PROP_0,
69 PROP_REGISTRY,
70 PROP_SHOW_ADVANCED
71 };
72
73 /* Forward Declarations */
74 static void proxy_preferences_commit_changes
75 (EProxyPreferences *preferences);
76 static void proxy_preferences_toplevel_notify_visible_cb
77 (GtkWidget *widget,
78 GParamSpec *param,
79 EProxyPreferences *preferences);
80
G_DEFINE_TYPE(EProxyPreferences,e_proxy_preferences,GTK_TYPE_BOX)81 G_DEFINE_TYPE (
82 EProxyPreferences,
83 e_proxy_preferences,
84 GTK_TYPE_BOX)
85
86 static gboolean
87 proxy_preferences_commit_timeout_cb (gpointer user_data)
88 {
89 EProxyPreferences *preferences = user_data;
90
91 proxy_preferences_commit_changes (preferences);
92
93 return FALSE;
94 }
95
96 static void
proxy_preferences_commit_stash(EProxyPreferences * preferences,ESource * source,gboolean start_timeout)97 proxy_preferences_commit_stash (EProxyPreferences *preferences,
98 ESource *source,
99 gboolean start_timeout)
100 {
101 gboolean commit_now = FALSE;
102
103 g_mutex_lock (&preferences->priv->commit_lock);
104
105 g_hash_table_replace (
106 preferences->priv->commit_sources,
107 e_source_dup_uid (source),
108 e_weak_ref_new (source));
109
110 if (preferences->priv->commit_timeout_id > 0) {
111 g_source_remove (preferences->priv->commit_timeout_id);
112 preferences->priv->commit_timeout_id = 0;
113 }
114
115 if (start_timeout) {
116 if (!preferences->priv->toplevel) {
117 GtkWidget *toplevel;
118
119 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (preferences));
120
121 if (toplevel) {
122 g_object_weak_ref (G_OBJECT (toplevel),
123 (GWeakNotify) g_nullify_pointer, &preferences->priv->toplevel);
124
125 preferences->priv->toplevel_notify_id = g_signal_connect (
126 toplevel, "notify::visible",
127 G_CALLBACK (proxy_preferences_toplevel_notify_visible_cb), preferences);
128
129 preferences->priv->toplevel = toplevel;
130
131 if (!gtk_widget_get_visible (toplevel)) {
132 start_timeout = FALSE;
133 commit_now = TRUE;
134 }
135 }
136 }
137 }
138
139 if (start_timeout) {
140 preferences->priv->commit_timeout_id =
141 e_named_timeout_add_seconds (
142 COMMIT_DELAY_SECS,
143 proxy_preferences_commit_timeout_cb,
144 preferences);
145 }
146
147 g_mutex_unlock (&preferences->priv->commit_lock);
148
149 if (commit_now)
150 e_proxy_preferences_submit (preferences);
151 }
152
153 static GList *
proxy_preferences_commit_claim(EProxyPreferences * preferences)154 proxy_preferences_commit_claim (EProxyPreferences *preferences)
155 {
156 GQueue queue = G_QUEUE_INIT;
157 GList *list, *link;
158
159 g_mutex_lock (&preferences->priv->commit_lock);
160
161 if (preferences->priv->commit_timeout_id > 0) {
162 g_source_remove (preferences->priv->commit_timeout_id);
163 preferences->priv->commit_timeout_id = 0;
164 }
165
166 /* Returns a list of GWeakRefs which may hold an ESource. */
167 list = g_hash_table_get_values (preferences->priv->commit_sources);
168
169 for (link = list; link != NULL; link = g_list_next (link)) {
170 ESource *source;
171
172 source = g_weak_ref_get ((GWeakRef *) link->data);
173 if (source != NULL)
174 g_queue_push_tail (&queue, source);
175 }
176
177 g_list_free (list);
178
179 g_hash_table_remove_all (preferences->priv->commit_sources);
180
181 g_mutex_unlock (&preferences->priv->commit_lock);
182
183 return g_queue_peek_head_link (&queue);
184 }
185
186 static gboolean
proxy_preferences_activate_link_cb(GtkLinkButton * button,EProxyPreferences * preferences)187 proxy_preferences_activate_link_cb (GtkLinkButton *button,
188 EProxyPreferences *preferences)
189 {
190 EProxySelector *selector;
191
192 selector = E_PROXY_SELECTOR (preferences->priv->proxy_selector);
193
194 if (e_proxy_preferences_get_show_advanced (preferences)) {
195 /* Basic mode always shows the built-in proxy profile. */
196 e_proxy_preferences_set_show_advanced (preferences, FALSE);
197 e_proxy_selector_set_selected (selector, NULL);
198 } else {
199 e_proxy_preferences_set_show_advanced (preferences, TRUE);
200 }
201
202 return TRUE;
203 }
204
205 static gboolean
proxy_preferences_switch_to_label(GBinding * binding,const GValue * source_value,GValue * target_value,gpointer user_data)206 proxy_preferences_switch_to_label (GBinding *binding,
207 const GValue *source_value,
208 GValue *target_value,
209 gpointer user_data)
210 {
211 const gchar *string;
212
213 if (g_value_get_boolean (source_value))
214 string = _("Switch to Basic Proxy Preferences");
215 else
216 string = _("Switch to Advanced Proxy Preferences");
217
218 g_value_set_string (target_value, string);
219
220 return TRUE;
221 }
222
223 static gboolean
proxy_preferences_source_to_display_name(GBinding * binding,const GValue * source_value,GValue * target_value,gpointer user_data)224 proxy_preferences_source_to_display_name (GBinding *binding,
225 const GValue *source_value,
226 GValue *target_value,
227 gpointer user_data)
228 {
229 ESource *source;
230 gchar *display_name;
231
232 source = g_value_get_object (source_value);
233 g_return_val_if_fail (source != NULL, FALSE);
234
235 display_name = e_source_dup_display_name (source);
236 g_value_take_string (target_value, display_name);
237
238 return TRUE;
239 }
240
241 static void
proxy_preferences_write_done_cb(GObject * source_object,GAsyncResult * result,gpointer user_data)242 proxy_preferences_write_done_cb (GObject *source_object,
243 GAsyncResult *result,
244 gpointer user_data)
245 {
246 ESource *source;
247 EProxyPreferences *preferences;
248 GError *error = NULL;
249
250 source = E_SOURCE (source_object);
251 preferences = E_PROXY_PREFERENCES (user_data);
252
253 e_source_write_finish (source, result, &error);
254
255 /* FIXME Display the error in an alert sink. */
256 if (error != NULL) {
257 g_warning ("%s: %s", G_STRFUNC, error->message);
258 g_error_free (error);
259 }
260
261 g_object_unref (preferences);
262 }
263
264 static void
proxy_preferences_commit_changes(EProxyPreferences * preferences)265 proxy_preferences_commit_changes (EProxyPreferences *preferences)
266 {
267 GList *list, *link;
268
269 list = proxy_preferences_commit_claim (preferences);
270
271 for (link = list; link != NULL; link = g_list_next (link)) {
272 e_source_write (
273 E_SOURCE (link->data), NULL,
274 proxy_preferences_write_done_cb,
275 g_object_ref (preferences));
276 }
277
278 g_list_free_full (list, (GDestroyNotify) g_object_unref);
279 }
280
281 static void
proxy_preferences_toplevel_notify_visible_cb(GtkWidget * widget,GParamSpec * param,EProxyPreferences * preferences)282 proxy_preferences_toplevel_notify_visible_cb (GtkWidget *widget,
283 GParamSpec *param,
284 EProxyPreferences *preferences)
285 {
286 g_return_if_fail (GTK_IS_WIDGET (widget));
287 g_return_if_fail (E_IS_PROXY_PREFERENCES (preferences));
288
289 /* The toplevel widget was hidden, save anything pending immediately */
290 if (!gtk_widget_get_visible (widget))
291 e_proxy_preferences_submit (preferences);
292 }
293
294 static void
proxy_preferences_source_changed_cb(ESourceRegistry * registry,ESource * source,EProxyPreferences * preferences)295 proxy_preferences_source_changed_cb (ESourceRegistry *registry,
296 ESource *source,
297 EProxyPreferences *preferences)
298 {
299 if (e_source_has_extension (source, E_SOURCE_EXTENSION_PROXY))
300 proxy_preferences_commit_stash (preferences, source, TRUE);
301 }
302
303 static void
proxy_preferences_set_registry(EProxyPreferences * preferences,ESourceRegistry * registry)304 proxy_preferences_set_registry (EProxyPreferences *preferences,
305 ESourceRegistry *registry)
306 {
307 gulong handler_id;
308
309 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
310 g_return_if_fail (preferences->priv->registry == NULL);
311
312 preferences->priv->registry = g_object_ref (registry);
313
314 handler_id = g_signal_connect (
315 registry, "source-changed",
316 G_CALLBACK (proxy_preferences_source_changed_cb), preferences);
317 preferences->priv->source_changed_handler_id = handler_id;
318 }
319
320 static void
proxy_preferences_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)321 proxy_preferences_set_property (GObject *object,
322 guint property_id,
323 const GValue *value,
324 GParamSpec *pspec)
325 {
326 switch (property_id) {
327 case PROP_REGISTRY:
328 proxy_preferences_set_registry (
329 E_PROXY_PREFERENCES (object),
330 g_value_get_object (value));
331 return;
332
333 case PROP_SHOW_ADVANCED:
334 e_proxy_preferences_set_show_advanced (
335 E_PROXY_PREFERENCES (object),
336 g_value_get_boolean (value));
337 return;
338 }
339
340 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
341 }
342
343 static void
proxy_preferences_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)344 proxy_preferences_get_property (GObject *object,
345 guint property_id,
346 GValue *value,
347 GParamSpec *pspec)
348 {
349 switch (property_id) {
350 case PROP_REGISTRY:
351 g_value_set_object (
352 value,
353 e_proxy_preferences_get_registry (
354 E_PROXY_PREFERENCES (object)));
355 return;
356
357 case PROP_SHOW_ADVANCED:
358 g_value_set_boolean (
359 value,
360 e_proxy_preferences_get_show_advanced (
361 E_PROXY_PREFERENCES (object)));
362 return;
363 }
364
365 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
366 }
367
368 static void
proxy_preferences_dispose(GObject * object)369 proxy_preferences_dispose (GObject *object)
370 {
371 EProxyPreferencesPrivate *priv;
372
373 priv = E_PROXY_PREFERENCES_GET_PRIVATE (object);
374
375 if (priv->toplevel) {
376 g_object_weak_unref (G_OBJECT (priv->toplevel),
377 (GWeakNotify) g_nullify_pointer, &priv->toplevel);
378
379 if (priv->toplevel_notify_id) {
380 g_signal_handler_disconnect (priv->toplevel, priv->toplevel_notify_id);
381 priv->toplevel_notify_id = 0;
382 }
383
384 priv->toplevel = NULL;
385 }
386
387 if (priv->source_changed_handler_id > 0) {
388 g_signal_handler_disconnect (
389 priv->registry,
390 priv->source_changed_handler_id);
391 priv->source_changed_handler_id = 0;
392 }
393
394 if (priv->commit_timeout_id > 0) {
395 g_source_remove (priv->commit_timeout_id);
396 priv->commit_timeout_id = 0;
397
398 /* Make sure the changes are committed, or at least its write invoked */
399 proxy_preferences_commit_changes (E_PROXY_PREFERENCES (object));
400 }
401
402 g_clear_object (&priv->registry);
403
404 g_hash_table_remove_all (priv->commit_sources);
405
406 /* Chain up to parent's dispose() method. */
407 G_OBJECT_CLASS (e_proxy_preferences_parent_class)->dispose (object);
408 }
409
410 static void
proxy_preferences_finalize(GObject * object)411 proxy_preferences_finalize (GObject *object)
412 {
413 EProxyPreferencesPrivate *priv;
414
415 priv = E_PROXY_PREFERENCES_GET_PRIVATE (object);
416
417 g_mutex_clear (&priv->commit_lock);
418 g_hash_table_destroy (priv->commit_sources);
419
420 /* Chain up to parent's finalize() method. */
421 G_OBJECT_CLASS (e_proxy_preferences_parent_class)->finalize (object);
422 }
423
424 static void
proxy_preferences_constructed(GObject * object)425 proxy_preferences_constructed (GObject *object)
426 {
427 EProxyPreferences *preferences;
428 ESourceRegistry *registry;
429 GtkWidget *widget;
430 GtkWidget *container;
431 GtkWidget *container2;
432 PangoAttribute *attr;
433 PangoAttrList *attr_list;
434 GList *list;
435 const gchar *extension_name;
436 gboolean show_advanced;
437
438 /* Chain up to parent's constructed() method. */
439 G_OBJECT_CLASS (e_proxy_preferences_parent_class)->constructed (object);
440
441 preferences = E_PROXY_PREFERENCES (object);
442 registry = e_proxy_preferences_get_registry (preferences);
443
444 gtk_orientable_set_orientation (
445 GTK_ORIENTABLE (preferences), GTK_ORIENTATION_VERTICAL);
446 gtk_box_set_spacing (GTK_BOX (preferences), 12);
447
448 widget = gtk_grid_new ();
449 gtk_grid_set_row_spacing (GTK_GRID (widget), 12);
450 gtk_grid_set_column_spacing (GTK_GRID (widget), 12);
451 gtk_box_pack_start (GTK_BOX (preferences), widget, TRUE, TRUE, 0);
452 gtk_widget_show (widget);
453
454 container = widget;
455
456 widget = e_proxy_selector_new (registry);
457 gtk_widget_set_vexpand (widget, TRUE);
458 gtk_widget_set_size_request (widget, 200, -1);
459 gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 1, 3);
460 preferences->priv->proxy_selector = widget; /* do not reference */
461
462 e_binding_bind_property (
463 preferences, "show-advanced",
464 widget, "visible",
465 G_BINDING_SYNC_CREATE);
466
467 attr_list = pango_attr_list_new ();
468 attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
469 pango_attr_list_insert (attr_list, attr);
470
471 widget = gtk_label_new ("");
472 gtk_widget_set_hexpand (widget, TRUE);
473 gtk_widget_set_valign (widget, GTK_ALIGN_START);
474 gtk_label_set_attributes (GTK_LABEL (widget), attr_list);
475 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
476 gtk_grid_attach (GTK_GRID (container), widget, 1, 0, 1, 1);
477 gtk_widget_show (widget);
478
479 e_binding_bind_property_full (
480 preferences->priv->proxy_selector, "selected",
481 widget, "label",
482 G_BINDING_SYNC_CREATE,
483 proxy_preferences_source_to_display_name,
484 NULL, NULL, NULL);
485
486 pango_attr_list_unref (attr_list);
487
488 widget = e_proxy_editor_new (registry);
489 gtk_widget_set_margin_left (widget, 12);
490 gtk_widget_set_valign (widget, GTK_ALIGN_START);
491 gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 1, 1);
492 preferences->priv->proxy_editor = widget; /* do not reference */
493 gtk_widget_show (widget);
494
495 e_binding_bind_property (
496 preferences->priv->proxy_selector, "selected",
497 widget, "source",
498 G_BINDING_SYNC_CREATE);
499
500 widget = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
501 gtk_widget_set_margin_left (widget, 12);
502 gtk_widget_set_vexpand (widget, TRUE);
503 gtk_grid_attach (GTK_GRID (container), widget, 1, 2, 1, 1);
504 gtk_widget_show (widget);
505
506 container = widget;
507
508 /* Nested containers to control multiple levels of visibility. */
509
510 widget = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
511 gtk_widget_set_vexpand (widget, TRUE);
512 gtk_container_add (GTK_CONTAINER (container), widget);
513
514 e_binding_bind_property (
515 preferences, "show-advanced",
516 widget, "visible",
517 G_BINDING_SYNC_CREATE);
518
519 container = widget;
520
521 widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
522 gtk_container_add (GTK_CONTAINER (container), widget);
523
524 container = widget;
525
526 widget = gtk_label_new (
527 _("Apply custom proxy settings to these accounts:"));
528 gtk_widget_set_halign (widget, GTK_ALIGN_START);
529 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
530 gtk_widget_show (widget);
531
532 widget = gtk_scrolled_window_new (NULL, NULL);
533 gtk_scrolled_window_set_policy (
534 GTK_SCROLLED_WINDOW (widget),
535 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
536 gtk_scrolled_window_set_shadow_type (
537 GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
538 gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
539 gtk_widget_show (widget);
540
541 container2 = widget;
542
543 widget = e_proxy_link_selector_new (registry);
544 gtk_container_add (GTK_CONTAINER (container2), widget);
545 gtk_widget_show (widget);
546
547 e_binding_bind_property (
548 preferences->priv->proxy_selector, "selected",
549 widget, "target-source",
550 G_BINDING_SYNC_CREATE);
551
552 /* This is bound to the GtkBox created above. */
553 e_binding_bind_property (
554 widget, "show-toggles",
555 container, "visible",
556 G_BINDING_SYNC_CREATE);
557
558 widget = gtk_link_button_new ("");
559 gtk_widget_set_halign (widget, GTK_ALIGN_START);
560 gtk_widget_set_tooltip_markup (
561 widget, _(
562 "<b>Advanced Proxy Preferences</b> lets you "
563 "define alternate network proxies and apply "
564 "them to specific accounts"));
565 gtk_box_pack_start (GTK_BOX (preferences), widget, FALSE, FALSE, 0);
566 gtk_widget_show (widget);
567
568 e_binding_bind_property_full (
569 preferences, "show-advanced",
570 widget, "label",
571 G_BINDING_SYNC_CREATE,
572 proxy_preferences_switch_to_label,
573 NULL, NULL, NULL);
574
575 e_binding_bind_property (
576 preferences, "show-advanced",
577 widget, "has-tooltip",
578 G_BINDING_SYNC_CREATE |
579 G_BINDING_INVERT_BOOLEAN);
580
581 g_signal_connect (
582 widget, "activate-link",
583 G_CALLBACK (proxy_preferences_activate_link_cb),
584 preferences);
585
586 extension_name = E_SOURCE_EXTENSION_PROXY;
587 list = e_source_registry_list_sources (registry, extension_name);
588 show_advanced = (g_list_length (list) > 1);
589 g_list_free_full (list, (GDestroyNotify) g_object_unref);
590
591 /* Switch to advanced mode if there are multiple proxy profiles. */
592 e_proxy_preferences_set_show_advanced (preferences, show_advanced);
593 }
594
595 static void
e_proxy_preferences_class_init(EProxyPreferencesClass * class)596 e_proxy_preferences_class_init (EProxyPreferencesClass *class)
597 {
598 GObjectClass *object_class;
599
600 g_type_class_add_private (class, sizeof (EProxyPreferencesPrivate));
601
602 object_class = G_OBJECT_CLASS (class);
603 object_class->set_property = proxy_preferences_set_property;
604 object_class->get_property = proxy_preferences_get_property;
605 object_class->dispose = proxy_preferences_dispose;
606 object_class->finalize = proxy_preferences_finalize;
607 object_class->constructed = proxy_preferences_constructed;
608
609 g_object_class_install_property (
610 object_class,
611 PROP_REGISTRY,
612 g_param_spec_object (
613 "registry",
614 "Registry",
615 "Data source registry",
616 E_TYPE_SOURCE_REGISTRY,
617 G_PARAM_READWRITE |
618 G_PARAM_CONSTRUCT_ONLY |
619 G_PARAM_STATIC_STRINGS));
620
621 g_object_class_install_property (
622 object_class,
623 PROP_SHOW_ADVANCED,
624 g_param_spec_boolean (
625 "show-advanced",
626 "Show Advanced",
627 "Show advanced proxy preferences",
628 FALSE,
629 G_PARAM_READWRITE |
630 G_PARAM_STATIC_STRINGS));
631 }
632
633 static void
e_proxy_preferences_init(EProxyPreferences * preferences)634 e_proxy_preferences_init (EProxyPreferences *preferences)
635 {
636 GHashTable *commit_sources;
637
638 /* Keys are UIDs, values are allocated GWeakRefs. */
639 commit_sources = g_hash_table_new_full (
640 (GHashFunc) g_str_hash,
641 (GEqualFunc) g_str_equal,
642 (GDestroyNotify) g_free,
643 (GDestroyNotify) e_weak_ref_free);
644
645 preferences->priv = E_PROXY_PREFERENCES_GET_PRIVATE (preferences);
646
647 g_mutex_init (&preferences->priv->commit_lock);
648 preferences->priv->commit_sources = commit_sources;
649 }
650
651 /**
652 * e_proxy_preferences_new:
653 * @registry: an #ESourceRegistry
654 *
655 * Creates a new #EProxyPreferences widget using #ESource instances in
656 * @registry.
657 *
658 * Returns: a new #EProxyPreferences
659 **/
660 GtkWidget *
e_proxy_preferences_new(ESourceRegistry * registry)661 e_proxy_preferences_new (ESourceRegistry *registry)
662 {
663 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
664
665 return g_object_new (
666 E_TYPE_PROXY_PREFERENCES,
667 "registry", registry, NULL);
668 }
669
670 /**
671 * e_proxy_preferences_submit:
672 * @preferences: an #EProxyPreferences
673 *
674 * Writes the displayed proxy profile details to the #ESource being edited,
675 * and submits the changes to the registry service asynchronously.
676 *
677 * Normally changes are submitted to the registry service automatically
678 * after a brief delay, but changes may sometimes need to be submitted
679 * explicitly such as when the top-level window is closing.
680 **/
681 void
e_proxy_preferences_submit(EProxyPreferences * preferences)682 e_proxy_preferences_submit (EProxyPreferences *preferences)
683 {
684 EProxyEditor *proxy_editor;
685 ESource *source;
686
687 g_return_if_fail (E_IS_PROXY_PREFERENCES (preferences));
688
689 proxy_editor = E_PROXY_EDITOR (preferences->priv->proxy_editor);
690
691 /* Save user changes to the proxy source. */
692 e_proxy_editor_save (proxy_editor);
693
694 /* This part normally happens from a "source-changed"
695 * signal handler, but we can't wait for that here. */
696 source = e_proxy_editor_ref_source (proxy_editor);
697 proxy_preferences_commit_stash (preferences, source, FALSE);
698 g_object_unref (source);
699
700 /* Commit any pending changes immediately. */
701 proxy_preferences_commit_changes (preferences);
702 }
703
704 /**
705 * e_proxy_preferences_get_registry:
706 * @preferences: an #EProxyPreferences
707 *
708 * Returns the #ESourceRegistry passed to e_proxy_preferences_new().
709 *
710 * Returns: an #ESourceRegistry
711 **/
712 ESourceRegistry *
e_proxy_preferences_get_registry(EProxyPreferences * preferences)713 e_proxy_preferences_get_registry (EProxyPreferences *preferences)
714 {
715 g_return_val_if_fail (E_IS_PROXY_PREFERENCES (preferences), NULL);
716
717 return preferences->priv->registry;
718 }
719
720 /**
721 * e_proxy_preferences_get_show_advanced:
722 * @preferences: an #EProxyPreferences
723 *
724 * Returns whether @preferences is currently in advanced mode.
725 *
726 * Returns: whether advanced proxy preferences are visible
727 **/
728 gboolean
e_proxy_preferences_get_show_advanced(EProxyPreferences * preferences)729 e_proxy_preferences_get_show_advanced (EProxyPreferences *preferences)
730 {
731 g_return_val_if_fail (E_IS_PROXY_PREFERENCES (preferences), FALSE);
732
733 return preferences->priv->show_advanced;
734 }
735
736 /**
737 * e_proxy_preferences_set_show_advanced:
738 * @preferences: an #EProxyPreferences
739 * @show_advanced: whether to show advanced proxy preferences
740 *
741 * Switches @preferences to advanced mode if @show_advanced is %TRUE,
742 * or to basic mode if @show_advanced is %FALSE.
743 **/
744 void
e_proxy_preferences_set_show_advanced(EProxyPreferences * preferences,gboolean show_advanced)745 e_proxy_preferences_set_show_advanced (EProxyPreferences *preferences,
746 gboolean show_advanced)
747 {
748 g_return_if_fail (E_IS_PROXY_PREFERENCES (preferences));
749
750 if (show_advanced == preferences->priv->show_advanced)
751 return;
752
753 preferences->priv->show_advanced = show_advanced;
754
755 g_object_notify (G_OBJECT (preferences), "show-advanced");
756 }
757
758