1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* e-source-combo-box.c
3 *
4 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "evolution-config.h"
20
21 #include <libedataserverui/libedataserverui.h>
22
23 #include "e-source-combo-box.h"
24
25 #define E_SOURCE_COMBO_BOX_GET_PRIVATE(obj) \
26 (G_TYPE_INSTANCE_GET_PRIVATE \
27 ((obj), E_TYPE_SOURCE_COMBO_BOX, ESourceComboBoxPrivate))
28
29 struct _ESourceComboBoxPrivate {
30 ESourceRegistry *registry;
31 gchar *extension_name;
32 GHashTable *hide_sources;
33
34 gulong source_added_handler_id;
35 gulong source_removed_handler_id;
36 gulong source_enabled_handler_id;
37 gulong source_disabled_handler_id;
38
39 gboolean show_colors;
40 };
41
42 enum {
43 PROP_0,
44 PROP_EXTENSION_NAME,
45 PROP_REGISTRY,
46 PROP_SHOW_COLORS
47 };
48
49 enum {
50 COLUMN_COLOR, /* GDK_TYPE_RGBA */
51 COLUMN_NAME, /* G_TYPE_STRING */
52 COLUMN_SENSITIVE, /* G_TYPE_BOOLEAN */
53 COLUMN_UID, /* G_TYPE_STRING */
54 NUM_COLUMNS
55 };
56
G_DEFINE_TYPE(ESourceComboBox,e_source_combo_box,GTK_TYPE_COMBO_BOX)57 G_DEFINE_TYPE (ESourceComboBox, e_source_combo_box, GTK_TYPE_COMBO_BOX)
58
59 static gboolean
60 source_combo_box_traverse (GNode *node,
61 ESourceComboBox *combo_box)
62 {
63 ESource *source;
64 ESourceSelectable *extension = NULL;
65 GtkTreeModel *model;
66 GtkTreeIter iter;
67 GString *indented;
68 GdkRGBA rgba;
69 const gchar *ext_name;
70 const gchar *display_name;
71 const gchar *uid;
72 gboolean sensitive = FALSE;
73 gboolean use_color = FALSE;
74 guint depth;
75
76 /* Skip the root node. */
77 if (G_NODE_IS_ROOT (node))
78 return FALSE;
79
80 ext_name = e_source_combo_box_get_extension_name (combo_box);
81
82 source = E_SOURCE (node->data);
83
84 if (ext_name != NULL && e_source_has_extension (source, ext_name)) {
85 extension = e_source_get_extension (source, ext_name);
86 sensitive = TRUE;
87
88 if (g_hash_table_size (combo_box->priv->hide_sources) && E_IS_SOURCE_BACKEND (extension)) {
89 ESourceBackend *backend = E_SOURCE_BACKEND (extension);
90
91 if (e_source_backend_get_backend_name (backend) &&
92 g_hash_table_contains (combo_box->priv->hide_sources, e_source_backend_get_backend_name (backend))) {
93 return FALSE;
94 }
95 }
96 }
97
98 uid = e_source_get_uid (source);
99
100 if (g_hash_table_contains (combo_box->priv->hide_sources, uid) || (e_source_get_parent (source) &&
101 g_hash_table_contains (combo_box->priv->hide_sources, e_source_get_parent (source)))) {
102 return FALSE;
103 }
104
105 display_name = e_source_get_display_name (source);
106
107 model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
108 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
109
110 indented = g_string_new (NULL);
111
112 depth = g_node_depth (node);
113 g_warn_if_fail (depth > 1);
114 while (--depth > 1)
115 g_string_append (indented, " ");
116 g_string_append (indented, display_name);
117
118 if (E_IS_SOURCE_SELECTABLE (extension)) {
119 const gchar *color_spec;
120
121 color_spec = e_source_selectable_get_color (extension);
122 if (color_spec != NULL && *color_spec != '\0')
123 use_color = gdk_rgba_parse (&rgba, color_spec);
124 }
125
126 gtk_list_store_set (
127 GTK_LIST_STORE (model), &iter,
128 COLUMN_COLOR, use_color ? &rgba : NULL,
129 COLUMN_NAME, indented->str,
130 COLUMN_SENSITIVE, sensitive,
131 COLUMN_UID, uid,
132 -1);
133
134 g_string_free (indented, TRUE);
135
136 return FALSE;
137 }
138
139 static void
source_combo_box_build_model(ESourceComboBox * combo_box)140 source_combo_box_build_model (ESourceComboBox *combo_box)
141 {
142 ESourceRegistry *registry;
143 GtkComboBox *gtk_combo_box;
144 GtkTreeModel *model;
145 GNode *root;
146 const gchar *active_id;
147 const gchar *extension_name;
148
149 registry = e_source_combo_box_get_registry (combo_box);
150 extension_name = e_source_combo_box_get_extension_name (combo_box);
151
152 gtk_combo_box = GTK_COMBO_BOX (combo_box);
153 model = gtk_combo_box_get_model (gtk_combo_box);
154
155 /* Constructor properties trigger this function before the
156 * list store is configured. Detect it and return silently. */
157 if (model == NULL)
158 return;
159
160 /* Remember the active ID so we can try to restore it. */
161 active_id = gtk_combo_box_get_active_id (gtk_combo_box);
162
163 gtk_list_store_clear (GTK_LIST_STORE (model));
164
165 /* If we have no registry, leave the combo box empty. */
166 if (registry == NULL)
167 return;
168
169 /* If we have no extension name, leave the combo box empty. */
170 if (extension_name == NULL)
171 return;
172
173 root = e_source_registry_build_display_tree (registry, extension_name);
174
175 g_node_traverse (
176 root, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
177 (GNodeTraverseFunc) source_combo_box_traverse,
178 combo_box);
179
180 e_source_registry_free_display_tree (root);
181
182 /* Restore the active ID, or else set it to something reasonable. */
183 gtk_combo_box_set_active_id (gtk_combo_box, active_id);
184 if (gtk_combo_box_get_active_id (gtk_combo_box) == NULL) {
185 ESource *source;
186
187 source = e_source_registry_ref_default_for_extension_name (
188 registry, extension_name);
189 if (source != NULL) {
190 e_source_combo_box_set_active (combo_box, source);
191 g_object_unref (source);
192 }
193 }
194
195 if (!gtk_combo_box_get_active_id (gtk_combo_box)) {
196 GtkTreeIter iter;
197
198 if (gtk_tree_model_get_iter_first (model, &iter)) {
199 do {
200 gboolean sensitive = FALSE;
201
202 gtk_tree_model_get (model, &iter, COLUMN_SENSITIVE, &sensitive, -1);
203
204 if (sensitive) {
205 gchar *uid = NULL;
206
207 gtk_tree_model_get (model, &iter, COLUMN_UID, &uid, -1);
208
209 if (uid) {
210 gtk_combo_box_set_active_id (gtk_combo_box, uid);
211 g_free (uid);
212 break;
213 } else {
214 g_free (uid);
215 }
216 }
217 } while (gtk_tree_model_iter_next (model, &iter));
218 }
219 }
220 }
221
222 static void
source_combo_box_source_added_cb(ESourceRegistry * registry,ESource * source,ESourceComboBox * combo_box)223 source_combo_box_source_added_cb (ESourceRegistry *registry,
224 ESource *source,
225 ESourceComboBox *combo_box)
226 {
227 source_combo_box_build_model (combo_box);
228 }
229
230 static void
source_combo_box_source_removed_cb(ESourceRegistry * registry,ESource * source,ESourceComboBox * combo_box)231 source_combo_box_source_removed_cb (ESourceRegistry *registry,
232 ESource *source,
233 ESourceComboBox *combo_box)
234 {
235 source_combo_box_build_model (combo_box);
236 }
237
238 static void
source_combo_box_source_enabled_cb(ESourceRegistry * registry,ESource * source,ESourceComboBox * combo_box)239 source_combo_box_source_enabled_cb (ESourceRegistry *registry,
240 ESource *source,
241 ESourceComboBox *combo_box)
242 {
243 source_combo_box_build_model (combo_box);
244 }
245
246 static void
source_combo_box_source_disabled_cb(ESourceRegistry * registry,ESource * source,ESourceComboBox * combo_box)247 source_combo_box_source_disabled_cb (ESourceRegistry *registry,
248 ESource *source,
249 ESourceComboBox *combo_box)
250 {
251 source_combo_box_build_model (combo_box);
252 }
253
254 static void
source_combo_box_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)255 source_combo_box_set_property (GObject *object,
256 guint property_id,
257 const GValue *value,
258 GParamSpec *pspec)
259 {
260 switch (property_id) {
261 case PROP_EXTENSION_NAME:
262 e_source_combo_box_set_extension_name (
263 E_SOURCE_COMBO_BOX (object),
264 g_value_get_string (value));
265 return;
266
267 case PROP_REGISTRY:
268 e_source_combo_box_set_registry (
269 E_SOURCE_COMBO_BOX (object),
270 g_value_get_object (value));
271 return;
272
273 case PROP_SHOW_COLORS:
274 e_source_combo_box_set_show_colors (
275 E_SOURCE_COMBO_BOX (object),
276 g_value_get_boolean (value));
277 return;
278 }
279
280 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
281 }
282
283 static void
source_combo_box_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)284 source_combo_box_get_property (GObject *object,
285 guint property_id,
286 GValue *value,
287 GParamSpec *pspec)
288 {
289 switch (property_id) {
290 case PROP_EXTENSION_NAME:
291 g_value_set_string (
292 value,
293 e_source_combo_box_get_extension_name (
294 E_SOURCE_COMBO_BOX (object)));
295 return;
296
297 case PROP_REGISTRY:
298 g_value_set_object (
299 value,
300 e_source_combo_box_get_registry (
301 E_SOURCE_COMBO_BOX (object)));
302 return;
303
304 case PROP_SHOW_COLORS:
305 g_value_set_boolean (
306 value,
307 e_source_combo_box_get_show_colors (
308 E_SOURCE_COMBO_BOX (object)));
309 return;
310 }
311
312 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
313 }
314
315 static void
source_combo_box_dispose(GObject * object)316 source_combo_box_dispose (GObject *object)
317 {
318 ESourceComboBoxPrivate *priv;
319
320 priv = E_SOURCE_COMBO_BOX_GET_PRIVATE (object);
321
322 if (priv->registry != NULL) {
323 g_signal_handler_disconnect (
324 priv->registry,
325 priv->source_added_handler_id);
326 g_signal_handler_disconnect (
327 priv->registry,
328 priv->source_removed_handler_id);
329 g_signal_handler_disconnect (
330 priv->registry,
331 priv->source_enabled_handler_id);
332 g_signal_handler_disconnect (
333 priv->registry,
334 priv->source_disabled_handler_id);
335 g_object_unref (priv->registry);
336 priv->registry = NULL;
337 }
338
339 /* Chain up to parent's "dispose" method. */
340 G_OBJECT_CLASS (e_source_combo_box_parent_class)->dispose (object);
341 }
342
343 static void
source_combo_box_finalize(GObject * object)344 source_combo_box_finalize (GObject *object)
345 {
346 ESourceComboBoxPrivate *priv;
347
348 priv = E_SOURCE_COMBO_BOX_GET_PRIVATE (object);
349
350 g_free (priv->extension_name);
351 g_hash_table_destroy (priv->hide_sources);
352
353 /* Chain up to parent's "finalize" method. */
354 G_OBJECT_CLASS (e_source_combo_box_parent_class)->finalize (object);
355 }
356
357 static void
source_combo_box_constructed(GObject * object)358 source_combo_box_constructed (GObject *object)
359 {
360 ESourceComboBox *combo_box;
361 GtkCellRenderer *renderer;
362 GtkCellLayout *layout;
363 GtkListStore *store;
364
365 combo_box = E_SOURCE_COMBO_BOX (object);
366
367 /* Chain up to parent's constructed() method. */
368 G_OBJECT_CLASS (e_source_combo_box_parent_class)->constructed (object);
369
370 store = gtk_list_store_new (
371 NUM_COLUMNS,
372 GDK_TYPE_RGBA, /* COLUMN_COLOR */
373 G_TYPE_STRING, /* COLUMN_NAME */
374 G_TYPE_BOOLEAN, /* COLUMN_SENSITIVE */
375 G_TYPE_STRING); /* COLUMN_UID */
376 gtk_combo_box_set_model (
377 GTK_COMBO_BOX (combo_box),
378 GTK_TREE_MODEL (store));
379 g_object_unref (store);
380
381 gtk_combo_box_set_id_column (GTK_COMBO_BOX (combo_box), COLUMN_UID);
382
383 layout = GTK_CELL_LAYOUT (combo_box);
384
385 renderer = e_cell_renderer_color_new ();
386 gtk_cell_layout_pack_start (layout, renderer, FALSE);
387 gtk_cell_layout_set_attributes (
388 layout, renderer,
389 "rgba", COLUMN_COLOR,
390 "sensitive", COLUMN_SENSITIVE,
391 NULL);
392
393 e_binding_bind_property (
394 combo_box, "show-colors",
395 renderer, "visible",
396 G_BINDING_SYNC_CREATE);
397
398 renderer = gtk_cell_renderer_text_new ();
399 gtk_cell_layout_pack_start (layout, renderer, TRUE);
400 gtk_cell_layout_set_attributes (
401 layout, renderer,
402 "text", COLUMN_NAME,
403 "sensitive", COLUMN_SENSITIVE,
404 NULL);
405
406 source_combo_box_build_model (combo_box);
407 }
408
409 static void
e_source_combo_box_class_init(ESourceComboBoxClass * class)410 e_source_combo_box_class_init (ESourceComboBoxClass *class)
411 {
412 GObjectClass *object_class = G_OBJECT_CLASS (class);
413
414 g_type_class_add_private (class, sizeof (ESourceComboBoxPrivate));
415
416 object_class->set_property = source_combo_box_set_property;
417 object_class->get_property = source_combo_box_get_property;
418 object_class->dispose = source_combo_box_dispose;
419 object_class->finalize = source_combo_box_finalize;
420 object_class->constructed = source_combo_box_constructed;
421
422 g_object_class_install_property (
423 object_class,
424 PROP_EXTENSION_NAME,
425 g_param_spec_string (
426 "extension-name",
427 "Extension Name",
428 "ESource extension name to filter",
429 NULL,
430 G_PARAM_READWRITE |
431 G_PARAM_CONSTRUCT));
432
433 /* XXX Don't use G_PARAM_CONSTRUCT_ONLY here. We need to allow
434 * for this class to be instantiated by a GtkBuilder with no
435 * special construct parameters, and then subsequently give
436 * it an ESourceRegistry. */
437 g_object_class_install_property (
438 object_class,
439 PROP_REGISTRY,
440 g_param_spec_object (
441 "registry",
442 "Registry",
443 "Data source registry",
444 E_TYPE_SOURCE_REGISTRY,
445 G_PARAM_READWRITE |
446 G_PARAM_CONSTRUCT |
447 G_PARAM_STATIC_STRINGS));
448
449 g_object_class_install_property (
450 object_class,
451 PROP_SHOW_COLORS,
452 g_param_spec_boolean (
453 "show-colors",
454 "Show Colors",
455 "Whether to show colors next to names",
456 TRUE,
457 G_PARAM_READWRITE |
458 G_PARAM_CONSTRUCT |
459 G_PARAM_STATIC_STRINGS));
460 }
461
462 static void
e_source_combo_box_init(ESourceComboBox * combo_box)463 e_source_combo_box_init (ESourceComboBox *combo_box)
464 {
465 combo_box->priv = E_SOURCE_COMBO_BOX_GET_PRIVATE (combo_box);
466 combo_box->priv->hide_sources = g_hash_table_new_full (camel_strcase_hash, camel_strcase_equal, g_free, NULL);
467 }
468
469 /**
470 * e_source_combo_box_new:
471 * @registry: an #ESourceRegistry, or %NULL
472 * @extension_name: an #ESource extension name
473 *
474 * Creates a new #ESourceComboBox widget that lets the user pick an #ESource
475 * from the provided #ESourceRegistry. The displayed sources are restricted
476 * to those which have an @extension_name extension.
477 *
478 * Returns: a new #ESourceComboBox
479 *
480 * Since: 2.22
481 **/
482 GtkWidget *
e_source_combo_box_new(ESourceRegistry * registry,const gchar * extension_name)483 e_source_combo_box_new (ESourceRegistry *registry,
484 const gchar *extension_name)
485 {
486 if (registry != NULL)
487 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
488
489 return g_object_new (
490 E_TYPE_SOURCE_COMBO_BOX, "registry", registry,
491 "extension-name", extension_name, NULL);
492 }
493
494 /**
495 * e_source_combo_box_get_registry:
496 * @combo_box: an #ESourceComboBox
497 *
498 * Returns the #ESourceRegistry used to populate @combo_box.
499 *
500 * Returns: the #ESourceRegistry, or %NULL
501 *
502 * Since: 3.6
503 **/
504 ESourceRegistry *
e_source_combo_box_get_registry(ESourceComboBox * combo_box)505 e_source_combo_box_get_registry (ESourceComboBox *combo_box)
506 {
507 g_return_val_if_fail (E_IS_SOURCE_COMBO_BOX (combo_box), NULL);
508
509 return combo_box->priv->registry;
510 }
511
512 /**
513 * e_source_combo_box_set_registry:
514 * @combo_box: an #ESourceComboBox
515 * @registry: an #ESourceRegistry
516 *
517 * Sets the #ESourceRegistry used to populate @combo_box.
518 *
519 * This function is intended for cases where @combo_box is instantiated
520 * by a #GtkBuilder and has to be given an #ESourceRegistry after it is
521 * fully constructed.
522 *
523 * Since: 3.6
524 **/
525 void
e_source_combo_box_set_registry(ESourceComboBox * combo_box,ESourceRegistry * registry)526 e_source_combo_box_set_registry (ESourceComboBox *combo_box,
527 ESourceRegistry *registry)
528 {
529 g_return_if_fail (E_IS_SOURCE_COMBO_BOX (combo_box));
530
531 if (combo_box->priv->registry == registry)
532 return;
533
534 if (registry != NULL) {
535 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
536 g_object_ref (registry);
537 }
538
539 if (combo_box->priv->registry != NULL) {
540 g_signal_handler_disconnect (
541 combo_box->priv->registry,
542 combo_box->priv->source_added_handler_id);
543 g_signal_handler_disconnect (
544 combo_box->priv->registry,
545 combo_box->priv->source_removed_handler_id);
546 g_signal_handler_disconnect (
547 combo_box->priv->registry,
548 combo_box->priv->source_enabled_handler_id);
549 g_signal_handler_disconnect (
550 combo_box->priv->registry,
551 combo_box->priv->source_disabled_handler_id);
552 g_object_unref (combo_box->priv->registry);
553 }
554
555 combo_box->priv->registry = registry;
556
557 combo_box->priv->source_added_handler_id = 0;
558 combo_box->priv->source_removed_handler_id = 0;
559 combo_box->priv->source_enabled_handler_id = 0;
560 combo_box->priv->source_disabled_handler_id = 0;
561
562 if (registry != NULL) {
563 gulong handler_id;
564
565 handler_id = g_signal_connect (
566 registry, "source-added",
567 G_CALLBACK (source_combo_box_source_added_cb),
568 combo_box);
569 combo_box->priv->source_added_handler_id = handler_id;
570
571 handler_id = g_signal_connect (
572 registry, "source-removed",
573 G_CALLBACK (source_combo_box_source_removed_cb),
574 combo_box);
575 combo_box->priv->source_removed_handler_id = handler_id;
576
577 handler_id = g_signal_connect (
578 registry, "source-enabled",
579 G_CALLBACK (source_combo_box_source_enabled_cb),
580 combo_box);
581 combo_box->priv->source_enabled_handler_id = handler_id;
582
583 handler_id = g_signal_connect (
584 registry, "source-disabled",
585 G_CALLBACK (source_combo_box_source_disabled_cb),
586 combo_box);
587 combo_box->priv->source_disabled_handler_id = handler_id;
588 }
589
590 source_combo_box_build_model (combo_box);
591
592 g_object_notify (G_OBJECT (combo_box), "registry");
593 }
594
595 /**
596 * e_source_combo_box_get_extension_name:
597 * @combo_box: an #ESourceComboBox
598 *
599 * Returns the extension name used to filter which data sources are
600 * shown in @combo_box.
601 *
602 * Returns: the #ESource extension name
603 *
604 * Since: 3.6
605 **/
606 const gchar *
e_source_combo_box_get_extension_name(ESourceComboBox * combo_box)607 e_source_combo_box_get_extension_name (ESourceComboBox *combo_box)
608 {
609 g_return_val_if_fail (E_IS_SOURCE_COMBO_BOX (combo_box), NULL);
610
611 return combo_box->priv->extension_name;
612 }
613
614 /**
615 * e_source_combo_box_set_extension_name:
616 * @combo_box: an #ESourceComboBox
617 * @extension_name: an #ESource extension name
618 *
619 * Sets the extension name used to filter which data sources are shown in
620 * @combo_box.
621 *
622 * Since: 3.6
623 **/
624 void
e_source_combo_box_set_extension_name(ESourceComboBox * combo_box,const gchar * extension_name)625 e_source_combo_box_set_extension_name (ESourceComboBox *combo_box,
626 const gchar *extension_name)
627 {
628 g_return_if_fail (E_IS_SOURCE_COMBO_BOX (combo_box));
629
630 if (g_strcmp0 (combo_box->priv->extension_name, extension_name) == 0)
631 return;
632
633 g_free (combo_box->priv->extension_name);
634 combo_box->priv->extension_name = g_strdup (extension_name);
635
636 source_combo_box_build_model (combo_box);
637
638 g_object_notify (G_OBJECT (combo_box), "extension-name");
639 }
640
641 /**
642 * e_source_combo_box_get_show_colors:
643 * @combo_box: an #ESourceComboBox
644 *
645 * Returns whether colors are shown next to data sources.
646 *
647 * Returns: %TRUE if colors are being shown
648 *
649 * Since: 3.6
650 **/
651 gboolean
e_source_combo_box_get_show_colors(ESourceComboBox * combo_box)652 e_source_combo_box_get_show_colors (ESourceComboBox *combo_box)
653 {
654 g_return_val_if_fail (E_IS_SOURCE_COMBO_BOX (combo_box), FALSE);
655
656 return combo_box->priv->show_colors;
657 }
658
659 /**
660 * e_source_combo_box_set_show_colors:
661 * @combo_box: an #ESourceComboBox
662 * @show_colors: whether to show colors
663 *
664 * Sets whether to show colors next to data sources.
665 *
666 * Since: 3.6
667 **/
668 void
e_source_combo_box_set_show_colors(ESourceComboBox * combo_box,gboolean show_colors)669 e_source_combo_box_set_show_colors (ESourceComboBox *combo_box,
670 gboolean show_colors)
671 {
672 g_return_if_fail (E_IS_SOURCE_COMBO_BOX (combo_box));
673
674 if ((show_colors ? 1 : 0) == (combo_box->priv->show_colors ? 1 : 0))
675 return;
676
677 combo_box->priv->show_colors = show_colors;
678
679 source_combo_box_build_model (combo_box);
680
681 g_object_notify (G_OBJECT (combo_box), "show-colors");
682 }
683
684 /**
685 * e_source_combo_box_ref_active:
686 * @combo_box: an #ESourceComboBox
687 *
688 * Returns the #ESource corresponding to the currently active item,
689 * or %NULL if there is no active item.
690 *
691 * The returned #ESource is referenced for thread-safety and must be
692 * unreferenced with g_object_unref() when finished with it.
693 *
694 * Returns: an #ESource or %NULL
695 *
696 * Since: 3.6
697 **/
698 ESource *
e_source_combo_box_ref_active(ESourceComboBox * combo_box)699 e_source_combo_box_ref_active (ESourceComboBox *combo_box)
700 {
701 ESourceRegistry *registry;
702 GtkComboBox *gtk_combo_box;
703 const gchar *active_id;
704
705 g_return_val_if_fail (E_IS_SOURCE_COMBO_BOX (combo_box), NULL);
706
707 registry = e_source_combo_box_get_registry (combo_box);
708
709 gtk_combo_box = GTK_COMBO_BOX (combo_box);
710 active_id = gtk_combo_box_get_active_id (gtk_combo_box);
711
712 if (active_id == NULL)
713 return NULL;
714
715 return e_source_registry_ref_source (registry, active_id);
716 }
717
718 /**
719 * e_source_combo_box_set_active:
720 * @combo_box: an #ESourceComboBox
721 * @source: an #ESource
722 *
723 * Sets the active item to the one corresponding to @source.
724 *
725 * Since: 2.22
726 **/
727 void
e_source_combo_box_set_active(ESourceComboBox * combo_box,ESource * source)728 e_source_combo_box_set_active (ESourceComboBox *combo_box,
729 ESource *source)
730 {
731 GtkComboBox *gtk_combo_box;
732 const gchar *uid;
733
734 g_return_if_fail (E_IS_SOURCE_COMBO_BOX (combo_box));
735 g_return_if_fail (E_IS_SOURCE (source));
736
737 uid = e_source_get_uid (source);
738
739 gtk_combo_box = GTK_COMBO_BOX (combo_box);
740 gtk_combo_box_set_active_id (gtk_combo_box, uid);
741 }
742
743 /**
744 * e_source_combo_box_hide_sources:
745 * @combo_box: an #ESourceComboBox
746 * @...: a NULL-terminated list of UID-s of the sources to hide
747 *
748 * The UID-s can be also backend names. Apart of that, these are checked
749 * for both the ESource::uid and the ESource::parent.
750 *
751 * The next call replaces the list of source UID-s to be hidden.
752 *
753 * Since: 3.40
754 **/
755 void
e_source_combo_box_hide_sources(ESourceComboBox * combo_box,...)756 e_source_combo_box_hide_sources (ESourceComboBox *combo_box,
757 ...)
758 {
759 const gchar *backend_name;
760 va_list va;
761
762 g_return_if_fail (E_IS_SOURCE_COMBO_BOX (combo_box));
763
764 g_hash_table_remove_all (combo_box->priv->hide_sources);
765
766 va_start (va, combo_box);
767
768 while (backend_name = va_arg (va, const gchar *), backend_name) {
769 g_hash_table_insert (combo_box->priv->hide_sources, g_strdup (backend_name), NULL);
770 }
771
772 va_end (va);
773
774 source_combo_box_build_model (combo_box);
775 }
776