evolution-3.6.4/mail/e-mail-config-provider-page.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-mail-config-provider-page.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-mail-config-provider-page.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /*
  2  * e-mail-config-provider-page.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-provider-page.h"
 20 
 21 #include <config.h>
 22 #include <string.h>
 23 #include <glib/gi18n-lib.h>
 24 
 25 #include <libebackend/libebackend.h>
 26 
 27 #define E_MAIL_CONFIG_PROVIDER_PAGE_GET_PRIVATE(obj) \
 28 	(G_TYPE_INSTANCE_GET_PRIVATE \
 29 	((obj), E_TYPE_MAIL_CONFIG_PROVIDER_PAGE, EMailConfigProviderPagePrivate))
 30 
 31 #define STANDARD_MARGIN   12
 32 #define DEPENDENCY_MARGIN 24
 33 
 34 struct _EMailConfigProviderPagePrivate {
 35 	EMailConfigServiceBackend *backend;
 36 	gboolean is_empty;
 37 };
 38 
 39 enum {
 40 	PROP_0,
 41 	PROP_BACKEND
 42 };
 43 
 44 /* Forward Declarations */
 45 static void	e_mail_config_provider_page_interface_init
 46 					(EMailConfigPageInterface *interface);
 47 
 48 G_DEFINE_TYPE_WITH_CODE (
 49 	EMailConfigProviderPage,
 50 	e_mail_config_provider_page,
 51 	E_TYPE_MAIL_CONFIG_ACTIVITY_PAGE,
 52 	G_IMPLEMENT_INTERFACE (
 53 		E_TYPE_EXTENSIBLE, NULL)
 54 	G_IMPLEMENT_INTERFACE (
 55 		E_TYPE_MAIL_CONFIG_PAGE,
 56 		e_mail_config_provider_page_interface_init))
 57 
 58 static void
 59 mail_config_provider_page_handle_dependency (EMailConfigProviderPage *page,
 60                                              CamelProviderConfEntry *entry,
 61                                              GtkWidget *widget)
 62 {
 63 	EMailConfigServiceBackend *backend;
 64 	CamelSettings *settings;
 65 	GBindingFlags binding_flags = G_BINDING_SYNC_CREATE;
 66 	const gchar *depname = entry->depname;
 67 	gint margin;
 68 
 69 	if (depname == NULL)
 70 		return;
 71 
 72 	if (*depname == '!') {
 73 		binding_flags |= G_BINDING_INVERT_BOOLEAN;
 74 		depname++;
 75 	}
 76 
 77 	backend = e_mail_config_provider_page_get_backend (page);
 78 	settings = e_mail_config_service_backend_get_settings (backend);
 79 
 80 	g_object_bind_property (
 81 		settings, depname,
 82 		widget, "sensitive",
 83 		binding_flags);
 84 
 85 	/* Further indent the widget to show its dependency. */
 86 	margin = gtk_widget_get_margin_left (widget);
 87 	gtk_widget_set_margin_left (widget, margin + DEPENDENCY_MARGIN);
 88 }
 89 
 90 static void
 91 mail_config_provider_page_add_section (EMailConfigProviderPage *page,
 92                                        CamelProviderConfEntry *entry)
 93 {
 94 	EMailConfigServiceBackend *backend;
 95 	CamelProvider *provider;
 96 	GtkWidget *widget;
 97 	gchar *markup;
 98 
 99 	g_return_if_fail (entry->text != NULL);
100 
101 	backend = e_mail_config_provider_page_get_backend (page);
102 	provider = e_mail_config_service_backend_get_provider (backend);
103 
104 	markup = g_markup_printf_escaped ("<b>%s</b>", entry->text);
105 
106 	widget = gtk_label_new (markup);
107 	gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
108 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
109 	gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
110 	gtk_widget_show (widget);
111 
112 	/* Skip the top margin if this is the first entry. */
113 	if (entry != provider->extra_conf)
114 		gtk_widget_set_margin_top (widget, 6);
115 
116 	g_free (markup);
117 }
118 
119 static void
120 mail_config_provider_page_add_checkbox (EMailConfigProviderPage *page,
121                                         CamelProviderConfEntry *entry)
122 {
123 	EMailConfigServiceBackend *backend;
124 	CamelSettings *settings;
125 	GtkWidget *widget;
126 
127 	g_return_if_fail (entry->text != NULL);
128 
129 	backend = e_mail_config_provider_page_get_backend (page);
130 	settings = e_mail_config_service_backend_get_settings (backend);
131 
132 	widget = gtk_check_button_new_with_mnemonic (entry->text);
133 	gtk_widget_set_margin_left (widget, STANDARD_MARGIN);
134 	gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
135 	gtk_widget_show (widget);
136 
137 	g_object_bind_property (
138 		settings, entry->name,
139 		widget, "active",
140 		G_BINDING_BIDIRECTIONAL |
141 		G_BINDING_SYNC_CREATE);
142 
143 	mail_config_provider_page_handle_dependency (page, entry, widget);
144 }
145 
146 static void
147 mail_config_provider_page_add_checkspin (EMailConfigProviderPage *page,
148                                          CamelProviderConfEntry *entry)
149 {
150 	EMailConfigServiceBackend *backend;
151 	CamelSettings *settings;
152 	GObjectClass *class;
153 	GParamSpec *pspec;
154 	GParamSpec *use_pspec;
155 	GtkAdjustment *adjustment;
156 	GtkWidget *hbox, *spin;
157 	GtkWidget *prefix;
158 	gchar *use_property_name;
159 	gchar *pre, *post;
160 
161 	g_return_if_fail (entry->text != NULL);
162 
163 	backend = e_mail_config_provider_page_get_backend (page);
164 	settings = e_mail_config_service_backend_get_settings (backend);
165 
166 	/* The entry->name property (e.g. "foo") should be numeric for the
167 	 * spin button.  If a "use" boolean property exists (e.g. "use-foo")
168 	 * then a checkbox is also shown. */
169 
170 	class = G_OBJECT_GET_CLASS (settings);
171 	pspec = g_object_class_find_property (class, entry->name);
172 	g_return_if_fail (pspec != NULL);
173 
174 	use_property_name = g_strconcat ("use-", entry->name, NULL);
175 	use_pspec = g_object_class_find_property (class, use_property_name);
176 	if (use_pspec != NULL && use_pspec->value_type != G_TYPE_BOOLEAN)
177 		use_pspec = NULL;
178 	g_free (use_property_name);
179 
180 	/* Make sure we can convert to and from doubles. */
181 	g_return_if_fail (
182 		g_value_type_transformable (
183 		pspec->value_type, G_TYPE_DOUBLE));
184 	g_return_if_fail (
185 		g_value_type_transformable (
186 		G_TYPE_DOUBLE, pspec->value_type));
187 
188 	if (G_IS_PARAM_SPEC_CHAR (pspec)) {
189 		GParamSpecChar *pspec_char;
190 		pspec_char = G_PARAM_SPEC_CHAR (pspec);
191 		adjustment = gtk_adjustment_new (
192 			(gdouble) pspec_char->default_value,
193 			(gdouble) pspec_char->minimum,
194 			(gdouble) pspec_char->maximum,
195 			1.0, 1.0, 0.0);
196 
197 	} else if (G_IS_PARAM_SPEC_UCHAR (pspec)) {
198 		GParamSpecUChar *pspec_uchar;
199 		pspec_uchar = G_PARAM_SPEC_UCHAR (pspec);
200 		adjustment = gtk_adjustment_new (
201 			(gdouble) pspec_uchar->default_value,
202 			(gdouble) pspec_uchar->minimum,
203 			(gdouble) pspec_uchar->maximum,
204 			1.0, 1.0, 0.0);
205 
206 	} else if (G_IS_PARAM_SPEC_INT (pspec)) {
207 		GParamSpecInt *pspec_int;
208 		pspec_int = G_PARAM_SPEC_INT (pspec);
209 		adjustment = gtk_adjustment_new (
210 			(gdouble) pspec_int->default_value,
211 			(gdouble) pspec_int->minimum,
212 			(gdouble) pspec_int->maximum,
213 			1.0, 1.0, 0.0);
214 
215 	} else if (G_IS_PARAM_SPEC_UINT (pspec)) {
216 		GParamSpecUInt *pspec_uint;
217 		pspec_uint = G_PARAM_SPEC_UINT (pspec);
218 		adjustment = gtk_adjustment_new (
219 			(gdouble) pspec_uint->default_value,
220 			(gdouble) pspec_uint->minimum,
221 			(gdouble) pspec_uint->maximum,
222 			1.0, 1.0, 0.0);
223 
224 	} else if (G_IS_PARAM_SPEC_LONG (pspec)) {
225 		GParamSpecLong *pspec_long;
226 		pspec_long = G_PARAM_SPEC_LONG (pspec);
227 		adjustment = gtk_adjustment_new (
228 			(gdouble) pspec_long->default_value,
229 			(gdouble) pspec_long->minimum,
230 			(gdouble) pspec_long->maximum,
231 			1.0, 1.0, 0.0);
232 
233 	} else if (G_IS_PARAM_SPEC_ULONG (pspec)) {
234 		GParamSpecULong *pspec_ulong;
235 		pspec_ulong = G_PARAM_SPEC_ULONG (pspec);
236 		adjustment = gtk_adjustment_new (
237 			(gdouble) pspec_ulong->default_value,
238 			(gdouble) pspec_ulong->minimum,
239 			(gdouble) pspec_ulong->maximum,
240 			1.0, 1.0, 0.0);
241 
242 	} else if (G_IS_PARAM_SPEC_FLOAT (pspec)) {
243 		GParamSpecFloat *pspec_float;
244 		pspec_float = G_PARAM_SPEC_FLOAT (pspec);
245 		adjustment = gtk_adjustment_new (
246 			(gdouble) pspec_float->default_value,
247 			(gdouble) pspec_float->minimum,
248 			(gdouble) pspec_float->maximum,
249 			1.0, 1.0, 0.0);
250 
251 	} else if (G_IS_PARAM_SPEC_DOUBLE (pspec)) {
252 		GParamSpecDouble *pspec_double;
253 		pspec_double = G_PARAM_SPEC_DOUBLE (pspec);
254 		adjustment = gtk_adjustment_new (
255 			(gdouble) pspec_double->default_value,
256 			(gdouble) pspec_double->minimum,
257 			(gdouble) pspec_double->maximum,
258 			1.0, 1.0, 0.0);
259 
260 	} else
261 		g_return_if_reached ();
262 
263 	pre = g_alloca (strlen (entry->text) + 1);
264 	strcpy (pre, entry->text);
265 	post = strstr (pre, "%s");
266 	if (post != NULL) {
267 		*post = '\0';
268 		post += 2;
269 	}
270 
271 	hbox = gtk_hbox_new (FALSE, 3);
272 	gtk_widget_set_margin_left (hbox, STANDARD_MARGIN);
273 	gtk_box_pack_start (GTK_BOX (page), hbox, FALSE, FALSE, 0);
274 	gtk_widget_show (hbox);
275 
276 	if (use_pspec != NULL) {
277 		prefix = gtk_check_button_new_with_mnemonic (pre);
278 
279 		g_object_bind_property (
280 			settings, use_pspec->name,
281 			prefix, "active",
282 			G_BINDING_BIDIRECTIONAL |
283 			G_BINDING_SYNC_CREATE);
284 	} else {
285 		prefix = gtk_label_new_with_mnemonic (pre);
286 	}
287 	gtk_box_pack_start (GTK_BOX (hbox), prefix, FALSE, TRUE, 0);
288 	gtk_widget_show (prefix);
289 
290 	spin = gtk_spin_button_new (adjustment, 1.0, 0);
291 	gtk_box_pack_start (GTK_BOX (hbox), spin, FALSE, TRUE, 0);
292 	gtk_widget_show (spin);
293 
294 	g_object_bind_property (
295 		settings, entry->name,
296 		spin, "value",
297 		G_BINDING_BIDIRECTIONAL |
298 		G_BINDING_SYNC_CREATE);
299 
300 	if (use_pspec != NULL)
301 		g_object_bind_property (
302 			prefix, "active",
303 			spin, "sensitive",
304 			G_BINDING_SYNC_CREATE);
305 
306 	if (post != NULL) {
307 		GtkWidget *label = gtk_label_new_with_mnemonic (post);
308 		gtk_label_set_mnemonic_widget (GTK_LABEL (label), prefix);
309 		gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
310 		gtk_widget_show (label);
311 	}
312 
313 	mail_config_provider_page_handle_dependency (page, entry, hbox);
314 }
315 
316 static void
317 mail_config_provider_page_add_entry (EMailConfigProviderPage *page,
318                                      CamelProviderConfEntry *entry)
319 {
320 	EMailConfigServiceBackend *backend;
321 	CamelSettings *settings;
322 	GtkWidget *hbox;
323 	GtkWidget *input;
324 	GtkWidget *label;
325 
326 	g_return_if_fail (entry->text != NULL);
327 
328 	backend = e_mail_config_provider_page_get_backend (page);
329 	settings = e_mail_config_service_backend_get_settings (backend);
330 
331 	hbox = gtk_hbox_new (FALSE, 0);
332 	gtk_box_set_spacing (GTK_BOX (hbox), 6);
333 	gtk_widget_set_margin_left (hbox, STANDARD_MARGIN);
334 	gtk_box_pack_start (GTK_BOX (page), hbox, FALSE, FALSE, 0);
335 	gtk_widget_show (hbox);
336 
337 	label = gtk_label_new_with_mnemonic (entry->text);
338 	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
339 	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
340 	gtk_widget_show (label);
341 
342 	input = gtk_entry_new ();
343 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), input);
344 	gtk_box_pack_start (GTK_BOX (hbox), input, TRUE, TRUE, 0);
345 	gtk_widget_show (input);
346 
347 	g_object_bind_property (
348 		settings, entry->name,
349 		input, "text",
350 		G_BINDING_BIDIRECTIONAL |
351 		G_BINDING_SYNC_CREATE);
352 
353 	g_object_bind_property (
354 		input, "sensitive",
355 		label, "sensitive",
356 		G_BINDING_SYNC_CREATE);
357 
358 	mail_config_provider_page_handle_dependency (page, entry, hbox);
359 }
360 
361 static void
362 mail_config_provider_page_add_options (EMailConfigProviderPage *page,
363                                        CamelProviderConfEntry *entry)
364 {
365 	EMailConfigServiceBackend *backend;
366 	CamelProvider *provider;
367 	CamelSettings *settings;
368 	GtkCellRenderer *renderer;
369 	GtkListStore *store;
370 	GtkWidget *hbox;
371 	GtkWidget *combo;
372 	GtkWidget *label;
373 	gchar **tokens;
374 	guint length, ii;
375 
376 	/* The 'value' string is of the format:
377 	 *
378 	 *   'nick0:caption0:nick1:caption1:...nickN:captionN'
379 	 *
380 	 * where 'nick' is the nickname a GEnumValue and 'caption'
381 	 * is the localized combo box item displayed to the user. */
382 
383 	g_return_if_fail (entry->text != NULL);
384 	g_return_if_fail (entry->value != NULL);
385 
386 	backend = e_mail_config_provider_page_get_backend (page);
387 	provider = e_mail_config_service_backend_get_provider (backend);
388 	settings = e_mail_config_service_backend_get_settings (backend);
389 
390 	hbox = gtk_hbox_new (FALSE, 0);
391 	gtk_box_set_spacing (GTK_BOX (hbox), 6);
392 	gtk_widget_set_margin_left (hbox, STANDARD_MARGIN);
393 	gtk_box_pack_start (GTK_BOX (page), hbox, FALSE, FALSE, 0);
394 	gtk_widget_show (hbox);
395 
396 	label = gtk_label_new_with_mnemonic (entry->text);
397 	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
398 	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
399 	gtk_widget_show (label);
400 
401 	/* 0: 'nick', 1: caption */
402 	store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
403 
404 	tokens = g_strsplit (entry->value, ":", -1);
405 	length = g_strv_length (tokens);
406 
407 	/* Take the strings two at a time. */
408 	for (ii = 0; ii + 1 < length; ii += 2) {
409 		GtkTreeIter iter;
410 		const gchar *nick;
411 		const gchar *caption;
412 
413 		nick = tokens[ii + 0];
414 		caption = tokens[ii + 1];
415 
416 		/* Localize the caption. */
417 		caption = dgettext (provider->translation_domain, caption);
418 
419 		gtk_list_store_append (store, &iter);
420 		gtk_list_store_set (store, &iter, 0, nick, 1, caption, -1);
421 	}
422 
423 	g_strfreev (tokens);
424 
425 	combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
426 	gtk_combo_box_set_id_column (GTK_COMBO_BOX (combo), 0);
427 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
428 	gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
429 	gtk_widget_show (combo);
430 
431 	g_object_bind_property_full (
432 		settings, entry->name,
433 		combo, "active-id",
434 		G_BINDING_BIDIRECTIONAL |
435 		G_BINDING_SYNC_CREATE,
436 		e_binding_transform_enum_value_to_nick,
437 		e_binding_transform_enum_nick_to_value,
438 		NULL, (GDestroyNotify) NULL);
439 
440 	renderer = gtk_cell_renderer_text_new ();
441 	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
442 	gtk_cell_layout_set_attributes (
443 		GTK_CELL_LAYOUT (combo), renderer, "text", 1, NULL);
444 
445 	mail_config_provider_page_handle_dependency (page, entry, hbox);
446 }
447 
448 static void
449 mail_config_provider_page_add_widgets (EMailConfigProviderPage *page)
450 {
451 	EMailConfigServiceBackend *backend;
452 	CamelProviderConfEntry *entries;
453 	CamelProvider *provider;
454 	GtkWidget *container;
455 	GtkWidget *widget;
456 	ESource *source;
457 	ESourceExtension *extension;
458 	gboolean first_section = TRUE;
459 	const gchar *extension_name;
460 	const gchar *text;
461 	gchar *markup;
462 	gint ii;
463 
464 	/* XXX We begin the page with our own section header and refresh
465 	 *     interval setting, and then skip the CamelProvider's first
466 	 *     CAMEL_PROVIDER_CONF_SECTION_START entry.
467 	 *
468 	 *     This is all very brittle.  I'm convinced that generating
469 	 *     a user interface from an array of records like this is a
470 	 *     bad idea.  We already have EMailConfigServiceBackend for
471 	 *     building provider-specific "Receving Email" and "Sending
472 	 *     EMail" pages by hand.  We should do similarly here. */
473 
474 	backend = e_mail_config_provider_page_get_backend (page);
475 	source = e_mail_config_service_backend_get_source (backend);
476 	provider = e_mail_config_service_backend_get_provider (backend);
477 	g_return_if_fail (provider != NULL);
478 
479 	/* XXX I guess refresh options go in the mail account source,
480 	 *     even if the source is part of a collection.  I did not
481 	 *     think about it too hard, so hopefully this is right. */
482 	extension_name = E_SOURCE_EXTENSION_REFRESH;
483 	extension = e_source_get_extension (source, extension_name);
484 
485 	text = _("Checking for New Mail");
486 	markup = g_markup_printf_escaped ("<b>%s</b>", text);
487 	widget = gtk_label_new (markup);
488 	gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
489 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
490 	gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
491 	gtk_widget_show (widget);
492 	g_free (markup);
493 
494 	widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
495 	gtk_widget_set_margin_left (widget, STANDARD_MARGIN);
496 	gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
497 	gtk_widget_show (widget);
498 
499 	container = widget;
500 
501 	text = _("Check for _new messages every");
502 	widget = gtk_check_button_new_with_mnemonic (text);
503 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
504 	gtk_widget_show (widget);
505 
506 	g_object_bind_property (
507 		extension, "enabled",
508 		widget, "active",
509 		G_BINDING_BIDIRECTIONAL |
510 		G_BINDING_SYNC_CREATE);
511 
512 	widget = gtk_spin_button_new_with_range (1.0, 1440.0, 1.0);
513 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
514 	gtk_widget_show (widget);
515 
516 	g_object_bind_property (
517 		extension, "enabled",
518 		widget, "sensitive",
519 		G_BINDING_SYNC_CREATE);
520 
521 	g_object_bind_property (
522 		extension, "interval-minutes",
523 		widget, "value",
524 		G_BINDING_BIDIRECTIONAL |
525 		G_BINDING_SYNC_CREATE);
526 
527 	widget = gtk_label_new (_("minutes"));
528 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
529 	gtk_widget_show (widget);
530 
531 	/* Note the "text" member of each CamelProviderConfEntry is
532 	 * already localized, so we can use it directly in widgets. */
533 
534 	entries = provider->extra_conf;
535 
536 	/* Loop until we see CAMEL_PROVIDER_CONF_END. */
537 	for (ii = 0; entries[ii].type != CAMEL_PROVIDER_CONF_END; ii++) {
538 
539 		/* Skip entries with no name. */
540 		if (entries[ii].name == NULL)
541 			continue;
542 
543 		switch (entries[ii].type) {
544 			case CAMEL_PROVIDER_CONF_SECTION_START:
545 				/* Skip the first section start. */
546 				if (first_section) {
547 					first_section = FALSE;
548 					continue;
549 				}
550 				mail_config_provider_page_add_section (
551 					page, &entries[ii]);
552 				break;
553 
554 			case CAMEL_PROVIDER_CONF_CHECKBOX:
555 				mail_config_provider_page_add_checkbox (
556 					page, &entries[ii]);
557 				break;
558 
559 			case CAMEL_PROVIDER_CONF_CHECKSPIN:
560 				mail_config_provider_page_add_checkspin (
561 					page, &entries[ii]);
562 				break;
563 
564 			case CAMEL_PROVIDER_CONF_ENTRY:
565 				mail_config_provider_page_add_entry (
566 					page, &entries[ii]);
567 				break;
568 
569 			case CAMEL_PROVIDER_CONF_OPTIONS:
570 				mail_config_provider_page_add_options (
571 					page, &entries[ii]);
572 				break;
573 
574 			default:
575 				break;  /* skip it */
576 		}
577 	}
578 }
579 
580 static void
581 mail_config_provider_page_set_backend (EMailConfigProviderPage *page,
582                                        EMailConfigServiceBackend *backend)
583 {
584 	g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
585 	g_return_if_fail (page->priv->backend == NULL);
586 
587 	page->priv->backend = g_object_ref (backend);
588 }
589 
590 static void
591 mail_config_provider_page_set_property (GObject *object,
592                                         guint property_id,
593                                         const GValue *value,
594                                         GParamSpec *pspec)
595 {
596 	switch (property_id) {
597 		case PROP_BACKEND:
598 			mail_config_provider_page_set_backend (
599 				E_MAIL_CONFIG_PROVIDER_PAGE (object),
600 				g_value_get_object (value));
601 			return;
602 	}
603 
604 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
605 }
606 
607 static void
608 mail_config_provider_page_get_property (GObject *object,
609                                         guint property_id,
610                                         GValue *value,
611                                         GParamSpec *pspec)
612 {
613 	switch (property_id) {
614 		case PROP_BACKEND:
615 			g_value_set_object (
616 				value,
617 				e_mail_config_provider_page_get_backend (
618 				E_MAIL_CONFIG_PROVIDER_PAGE (object)));
619 			return;
620 	}
621 
622 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
623 }
624 
625 static void
626 mail_config_provider_page_dispose (GObject *object)
627 {
628 	EMailConfigProviderPagePrivate *priv;
629 
630 	priv = E_MAIL_CONFIG_PROVIDER_PAGE_GET_PRIVATE (object);
631 
632 	if (priv->backend != NULL) {
633 		g_object_unref (priv->backend);
634 		priv->backend = NULL;
635 	}
636 
637 	/* Chain up parent's dispose() method. */
638 	G_OBJECT_CLASS (e_mail_config_provider_page_parent_class)->
639 		dispose (object);
640 }
641 
642 static void
643 mail_config_provider_page_constructed (GObject *object)
644 {
645 	EMailConfigProviderPage *page;
646 	EMailConfigServiceBackend *backend;
647 	CamelProvider *provider;
648 
649 	page = E_MAIL_CONFIG_PROVIDER_PAGE (object);
650 
651 	/* Chain up parent's constructed() method. */
652 	G_OBJECT_CLASS (e_mail_config_provider_page_parent_class)->
653 		constructed (object);
654 
655 	gtk_box_set_spacing (GTK_BOX (object), 6);
656 
657 	gtk_orientable_set_orientation (
658 		GTK_ORIENTABLE (object), GTK_ORIENTATION_VERTICAL);
659 
660 	backend = e_mail_config_provider_page_get_backend (page);
661 	provider = e_mail_config_service_backend_get_provider (backend);
662 
663 	if (provider != NULL && provider->extra_conf != NULL)
664 		mail_config_provider_page_add_widgets (page);
665 	else
666 		page->priv->is_empty = TRUE;
667 
668 	e_extensible_load_extensions (E_EXTENSIBLE (page));
669 }
670 
671 static void
672 e_mail_config_provider_page_class_init (EMailConfigProviderPageClass *class)
673 {
674 	GObjectClass *object_class;
675 
676 	g_type_class_add_private (class, sizeof (EMailConfigProviderPagePrivate));
677 
678 	object_class = G_OBJECT_CLASS (class);
679 	object_class->set_property = mail_config_provider_page_set_property;
680 	object_class->get_property = mail_config_provider_page_get_property;
681 	object_class->dispose = mail_config_provider_page_dispose;
682 	object_class->constructed = mail_config_provider_page_constructed;
683 
684 	g_object_class_install_property (
685 		object_class,
686 		PROP_BACKEND,
687 		g_param_spec_object (
688 			"backend",
689 			"Backend",
690 			"Service backend to generate options from",
691 			E_TYPE_MAIL_CONFIG_SERVICE_BACKEND,
692 			G_PARAM_READWRITE |
693 			G_PARAM_CONSTRUCT_ONLY |
694 			G_PARAM_STATIC_STRINGS));
695 }
696 
697 static void
698 e_mail_config_provider_page_interface_init (EMailConfigPageInterface *interface)
699 {
700 	interface->title = _("Receiving Options");
701 	interface->sort_order = E_MAIL_CONFIG_PROVIDER_PAGE_SORT_ORDER;
702 }
703 
704 static void
705 e_mail_config_provider_page_init (EMailConfigProviderPage *page)
706 {
707 	page->priv = E_MAIL_CONFIG_PROVIDER_PAGE_GET_PRIVATE (page);
708 }
709 
710 EMailConfigPage *
711 e_mail_config_provider_page_new (EMailConfigServiceBackend *backend)
712 {
713 	g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), NULL);
714 
715 	return g_object_new (
716 		E_TYPE_MAIL_CONFIG_PROVIDER_PAGE,
717 		"backend", backend, NULL);
718 }
719 
720 gboolean
721 e_mail_config_provider_page_is_empty (EMailConfigProviderPage *page)
722 {
723 	g_return_val_if_fail (E_IS_MAIL_CONFIG_PROVIDER_PAGE (page), TRUE);
724 
725 	return page->priv->is_empty;
726 }
727 
728 EMailConfigServiceBackend *
729 e_mail_config_provider_page_get_backend (EMailConfigProviderPage *page)
730 {
731 	g_return_val_if_fail (E_IS_MAIL_CONFIG_PROVIDER_PAGE (page), NULL);
732 
733 	return page->priv->backend;
734 }