evolution-3.6.4/modules/mail/em-mailer-prefs.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found em-mailer-prefs.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found em-mailer-prefs.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  * This program is free software; you can redistribute it and/or
   3  * modify it under the terms of the GNU Lesser General Public
   4  * License as published by the Free Software Foundation; either
   5  * version 2 of the License, or (at your option) version 3.
   6  *
   7  * This program is distributed in the hope that it will be useful,
   8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  10  * Lesser General Public License for more details.
  11  *
  12  * You should have received a copy of the GNU Lesser General Public
  13  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  14  *
  15  *
  16  * Authors:
  17  *		Jeffrey Stedfast <fejj@ximian.com>
  18  *
  19  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  20  *
  21  */
  22 
  23 #ifdef HAVE_CONFIG_H
  24 #include <config.h>
  25 #endif
  26 
  27 #include <string.h>
  28 #include <glib/gi18n-lib.h>
  29 
  30 #include "em-mailer-prefs.h"
  31 
  32 #include <gtkhtml/gtkhtml-properties.h>
  33 #include <libxml/tree.h>
  34 
  35 #include <e-util/e-util.h>
  36 #include <e-util/e-datetime-format.h>
  37 #include <e-util/e-util-private.h>
  38 
  39 #include <misc/e-charset-combo-box.h>
  40 #include <misc/e-port-entry.h>
  41 #include <shell/e-shell-utils.h>
  42 
  43 #include <mail/e-mail-backend.h>
  44 #include <mail/e-mail-junk-options.h>
  45 #include <mail/e-mail-label-manager.h>
  46 #include <mail/e-mail-reader-utils.h>
  47 #include <mail/em-folder-selection-button.h>
  48 #include <mail/em-config.h>
  49 
  50 enum {
  51 	HEADER_LIST_NAME_COLUMN, /* displayable name of the header (may be a translation) */
  52 	HEADER_LIST_ENABLED_COLUMN, /* is the header enabled? */
  53 	HEADER_LIST_IS_DEFAULT_COLUMN,  /* is this header a default header, eg From: */
  54 	HEADER_LIST_HEADER_COLUMN, /* the real name of this header */
  55 	HEADER_LIST_N_COLUMNS
  56 };
  57 
  58 static GType col_types[] = {
  59 	G_TYPE_STRING,
  60 	G_TYPE_BOOLEAN,
  61 	G_TYPE_BOOLEAN,
  62 	G_TYPE_STRING
  63 };
  64 
  65 /* temporarily copied from em-format.c */
  66 static const gchar *default_headers[] = {
  67 	N_("From"),
  68 	N_("Reply-To"),
  69 	N_("To"),
  70 	N_("Cc"),
  71 	N_("Bcc"),
  72 	N_("Subject"),
  73 	N_("Date"),
  74 	N_("Newsgroups"),
  75 	N_("Face"),
  76 	"x-evolution-mailer", /* DO NOT translate */
  77 };
  78 
  79 #define EM_FORMAT_HEADER_XMAILER "x-evolution-mailer"
  80 
  81 /* for empty trash on exit frequency */
  82 static const struct {
  83 	const gchar *label;
  84 	gint days;
  85 } empty_trash_frequency[] = {
  86 	{ N_("Every time"), 0 },
  87 	{ N_("Once per day"), 1 },
  88 	{ N_("Once per week"), 7 },
  89 	{ N_("Once per month"), 30 },
  90 };
  91 
  92 G_DEFINE_TYPE (
  93 	EMMailerPrefs,
  94 	em_mailer_prefs,
  95 	GTK_TYPE_VBOX)
  96 
  97 static void
  98 em_mailer_prefs_finalize (GObject *object)
  99 {
 100 	EMMailerPrefs *prefs = (EMMailerPrefs *) object;
 101 
 102 	g_object_unref (prefs->builder);
 103 	g_object_unref (prefs->settings);
 104 
 105 	/* Chain up to parent's finalize() method. */
 106 	G_OBJECT_CLASS (em_mailer_prefs_parent_class)->finalize (object);
 107 }
 108 
 109 static void
 110 em_mailer_prefs_class_init (EMMailerPrefsClass *class)
 111 {
 112 	GObjectClass *object_class;
 113 
 114 	object_class = G_OBJECT_CLASS (class);
 115 	object_class->finalize = em_mailer_prefs_finalize;
 116 }
 117 
 118 static void
 119 em_mailer_prefs_init (EMMailerPrefs *preferences)
 120 {
 121 	preferences->settings = g_settings_new ("org.gnome.evolution.mail");
 122 }
 123 
 124 static gboolean
 125 mark_seen_milliseconds_to_seconds (GBinding *binding,
 126                                    const GValue *source_value,
 127                                    GValue *target_value,
 128                                    gpointer user_data)
 129 {
 130 	gint milliseconds;
 131 	gdouble seconds;
 132 
 133 	milliseconds = g_value_get_int (source_value);
 134 	seconds = milliseconds / 1000.0;
 135 	g_value_set_double (target_value, seconds);
 136 
 137 	return TRUE;
 138 }
 139 
 140 static gboolean
 141 mark_seen_seconds_to_milliseconds (GBinding *binding,
 142                                    const GValue *source_value,
 143                                    GValue *target_value,
 144                                    gpointer user_data)
 145 {
 146 	gint milliseconds;
 147 	gdouble seconds;
 148 
 149 	seconds = g_value_get_double (source_value);
 150 	milliseconds = seconds * 1000;
 151 	g_value_set_int (target_value, milliseconds);
 152 
 153 	return TRUE;
 154 }
 155 
 156 enum {
 157 	JH_LIST_COLUMN_NAME,
 158 	JH_LIST_COLUMN_VALUE
 159 };
 160 
 161 static void
 162 jh_tree_refill (EMMailerPrefs *prefs)
 163 {
 164 	GtkListStore *store = prefs->junk_header_list_store;
 165 	gchar **strv;
 166 	gint ii;
 167 
 168 	strv = g_settings_get_strv (prefs->settings, "junk-custom-header");
 169 
 170 	gtk_list_store_clear (store);
 171 
 172 	for (ii = 0; strv[ii] != NULL; ii++) {
 173 		GtkTreeIter iter;
 174 		gchar **tokens = g_strsplit (strv[ii], "=", 2);
 175 
 176 		gtk_list_store_append (store, &iter);
 177 		gtk_list_store_set (
 178 			store, &iter,
 179 			JH_LIST_COLUMN_NAME , tokens[0] ? tokens[0] : "",
 180 			JH_LIST_COLUMN_VALUE, tokens[1] ? tokens[1] : "" ,
 181 			-1);
 182 		g_strfreev (tokens);
 183 	}
 184 
 185 	g_strfreev (strv);
 186 }
 187 
 188 static void
 189 jh_dialog_entry_changed_cb (GtkEntry *entry,
 190                             gpointer user_data)
 191 {
 192 	GtkBuilder *builder = GTK_BUILDER (user_data);
 193 	GtkWidget *ok_button, *entry1, *entry2;
 194 	const gchar *name, *value;
 195 
 196 	ok_button = e_builder_get_widget (builder, "junk-header-ok");
 197 	entry1 = e_builder_get_widget (builder, "junk-header-name");
 198 	entry2 = e_builder_get_widget (builder, "junk-header-content");
 199 
 200 	name = gtk_entry_get_text (GTK_ENTRY (entry1));
 201 	value = gtk_entry_get_text (GTK_ENTRY (entry2));
 202 
 203 	gtk_widget_set_sensitive (ok_button, name && *name && value && *value);
 204 }
 205 
 206 static void
 207 jh_add_cb (GtkWidget *widget,
 208            gpointer user_data)
 209 {
 210 	GtkWidget *dialog;
 211 	GtkWidget *entry;
 212 	EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
 213 	GtkBuilder *builder = gtk_builder_new ();
 214 	gchar *tok;
 215 	const gchar *name, *value;
 216 
 217 	e_load_ui_builder_definition (builder, "mail-config.ui");
 218 	dialog = e_builder_get_widget (builder, "add-custom-junk-header");
 219 	jh_dialog_entry_changed_cb (NULL, builder);
 220 
 221 	entry = e_builder_get_widget (builder, "junk-header-name");
 222 	g_signal_connect (
 223 		entry, "changed",
 224 		G_CALLBACK (jh_dialog_entry_changed_cb), builder);
 225 	entry = e_builder_get_widget (builder, "junk-header-content");
 226 	g_signal_connect (
 227 		entry, "changed",
 228 		G_CALLBACK (jh_dialog_entry_changed_cb), builder);
 229 
 230 	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
 231 		gchar **strv;
 232 		GPtrArray *array;
 233 		gint ii;
 234 
 235 		name = gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (builder, "junk-header-name")));
 236 		value = gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (builder, "junk-header-content")));
 237 
 238 		strv = g_settings_get_strv (prefs->settings, "junk-custom-header");
 239 		array = g_ptr_array_new ();
 240 		for (ii = 0; strv[ii] != NULL; ii++)
 241 			g_ptr_array_add (array, strv[ii]);
 242 		tok = g_strdup_printf ("%s=%s", name, value);
 243 		g_ptr_array_add (array, tok);
 244 		g_ptr_array_add (array, NULL);
 245 		g_settings_set_strv (prefs->settings, "junk-custom-header", (const gchar * const *) array->pdata);
 246 
 247 		g_ptr_array_free (array, TRUE);
 248 		g_strfreev (strv);
 249 	}
 250 
 251 	g_object_unref (builder);
 252 	gtk_widget_destroy (dialog);
 253 
 254 	jh_tree_refill (prefs);
 255 }
 256 
 257 static void
 258 jh_remove_cb (GtkWidget *widget,
 259               gpointer user_data)
 260 {
 261 	EMMailerPrefs *prefs = user_data;
 262 	GtkTreeSelection *selection;
 263 	GtkTreeModel *model;
 264 	GtkTreeIter iter;
 265 
 266 	g_return_if_fail (prefs != NULL);
 267 
 268 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->junk_header_tree));
 269 	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
 270 		GPtrArray *array = g_ptr_array_new ();
 271 		gchar *name = NULL, *value = NULL;
 272 		gchar **strv;
 273 		gint ii;
 274 
 275 		strv = g_settings_get_strv (prefs->settings, "junk-custom-header");
 276 		gtk_tree_model_get (model, &iter, JH_LIST_COLUMN_NAME, &name, JH_LIST_COLUMN_VALUE, &value, -1);
 277 		for (ii = 0; strv[ii] != NULL; ii++) {
 278 			gchar *test;
 279 			gint len = strlen (name);
 280 			test = strncmp (strv[ii], name, len) == 0 ? (gchar *) strv[ii] + len : NULL;
 281 
 282 			if (test) {
 283 				test++;
 284 				if (strcmp (test, value) == 0)
 285 					continue;
 286 			}
 287 
 288 			g_ptr_array_add (array, strv[ii]);
 289 		}
 290 
 291 		g_ptr_array_add (array, NULL);
 292 
 293 		g_settings_set_strv (prefs->settings, "junk-custom-header", (const gchar * const *) array->pdata);
 294 
 295 		g_strfreev (strv);
 296 		g_ptr_array_free (array, TRUE);
 297 		g_free (name);
 298 		g_free (value);
 299 
 300 		jh_tree_refill (prefs);
 301 	}
 302 }
 303 
 304 static GtkListStore *
 305 init_junk_tree (GtkWidget *label_tree,
 306                 EMMailerPrefs *prefs)
 307 {
 308 	GtkListStore *store;
 309 	GtkCellRenderer *renderer;
 310 
 311 	g_return_val_if_fail (label_tree != NULL, NULL);
 312 	g_return_val_if_fail (prefs != NULL, NULL);
 313 
 314 	store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
 315 	gtk_tree_view_set_model (GTK_TREE_VIEW (label_tree), GTK_TREE_MODEL (store));
 316 
 317 	renderer = gtk_cell_renderer_text_new ();
 318 	gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (label_tree), -1, _("Header"), renderer, "text", JH_LIST_COLUMN_NAME, NULL);
 319 	g_object_set (renderer, "editable", TRUE, NULL);
 320 
 321 	renderer = gtk_cell_renderer_text_new ();
 322 	gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (label_tree), -1, _("Contains Value"), renderer, "text", JH_LIST_COLUMN_VALUE, NULL);
 323 	g_object_set (renderer, "editable", TRUE, NULL);
 324 
 325 	return store;
 326 }
 327 
 328 static void
 329 emmp_header_remove_sensitivity (EMMailerPrefs *prefs)
 330 {
 331 	GtkTreeIter iter;
 332 	GtkTreeSelection *selection = gtk_tree_view_get_selection (prefs->header_list);
 333 	gboolean is_default;
 334 
 335 	/* remove button should be sensitive if the currenlty selected entry in the list view
 336 	 * is not a default header. if there are no entries, or none is selected, it should be
 337 	 * disabled
 338 	*/
 339 	if (gtk_tree_selection_get_selected (selection, NULL, &iter)) {
 340 		gtk_tree_model_get (
 341 			GTK_TREE_MODEL (prefs->header_list_store), &iter,
 342 			HEADER_LIST_IS_DEFAULT_COLUMN, &is_default,
 343 			-1);
 344 		if (is_default)
 345 			gtk_widget_set_sensitive (GTK_WIDGET (prefs->remove_header), FALSE);
 346 		else
 347 			gtk_widget_set_sensitive (GTK_WIDGET (prefs->remove_header), TRUE);
 348 	} else {
 349 		gtk_widget_set_sensitive (GTK_WIDGET (prefs->remove_header), FALSE);
 350 	}
 351 }
 352 
 353 static gboolean
 354 emmp_header_is_valid (const gchar *header)
 355 {
 356 	gint len = g_utf8_strlen (header, -1);
 357 
 358 	if (header[0] == 0
 359 	    || g_utf8_strchr (header, len, ':') != NULL
 360 	    || g_utf8_strchr (header, len, ' ') != NULL)
 361 		return FALSE;
 362 
 363 	return TRUE;
 364 }
 365 
 366 static void
 367 emmp_header_add_sensitivity (EMMailerPrefs *prefs)
 368 {
 369 	const gchar *entry_contents;
 370 	GtkTreeIter iter;
 371 	gboolean valid;
 372 
 373 	/* the add header button should be sensitive if the text box contains
 374 	 * a valid header string, that is not a duplicate with something already
 375 	 * in the list view
 376 	*/
 377 	entry_contents = gtk_entry_get_text (GTK_ENTRY (prefs->entry_header));
 378 	if (!emmp_header_is_valid (entry_contents)) {
 379 		gtk_widget_set_sensitive (GTK_WIDGET (prefs->add_header), FALSE);
 380 		return;
 381 	}
 382 
 383 	/* check if this is a duplicate */
 384 	valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (prefs->header_list_store), &iter);
 385 	while (valid) {
 386 		gchar *header_name;
 387 
 388 		gtk_tree_model_get (
 389 			GTK_TREE_MODEL (prefs->header_list_store), &iter,
 390 			HEADER_LIST_HEADER_COLUMN, &header_name,
 391 			-1);
 392 		if (g_ascii_strcasecmp (header_name, entry_contents) == 0) {
 393 			gtk_widget_set_sensitive (GTK_WIDGET (prefs->add_header), FALSE);
 394 			g_free (header_name);
 395 			return;
 396 		}
 397 
 398 		g_free (header_name);
 399 
 400 		valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (prefs->header_list_store), &iter);
 401 	}
 402 
 403 	gtk_widget_set_sensitive (GTK_WIDGET (prefs->add_header), TRUE);
 404 }
 405 
 406 static void
 407 emmp_save_headers (EMMailerPrefs *prefs)
 408 {
 409 	GPtrArray *headers;
 410 	GtkTreeIter iter;
 411 	gboolean valid;
 412 
 413 	/* Headers */
 414 	headers = g_ptr_array_new_full (3, g_free);
 415 	valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (prefs->header_list_store), &iter);
 416 	while (valid) {
 417 		struct _EMailReaderHeader h;
 418 		gboolean enabled;
 419 		gchar *xml;
 420 
 421 		h.name = NULL;
 422 
 423 		gtk_tree_model_get (
 424 			GTK_TREE_MODEL (prefs->header_list_store), &iter,
 425 			HEADER_LIST_HEADER_COLUMN, &h.name,
 426 			HEADER_LIST_ENABLED_COLUMN, &enabled,
 427 			-1);
 428 		h.enabled = enabled;
 429 
 430 		if ((xml = e_mail_reader_header_to_xml (&h)))
 431 			g_ptr_array_add (headers, xml);
 432 
 433 		g_free (h.name);
 434 
 435 		valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (prefs->header_list_store), &iter);
 436 	}
 437 
 438 	g_ptr_array_add (headers, NULL);
 439 
 440 	g_settings_set_strv (prefs->settings, "headers", (const gchar * const *) headers->pdata);
 441 
 442 	g_ptr_array_free (headers, TRUE);
 443 }
 444 
 445 static void
 446 emmp_header_list_enabled_toggled (GtkCellRendererToggle *cell,
 447                                   const gchar *path_string,
 448                                   EMMailerPrefs *prefs)
 449 {
 450 	GtkTreeModel *model = GTK_TREE_MODEL (prefs->header_list_store);
 451 	GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
 452 	GtkTreeIter iter;
 453 	gint enabled;
 454 
 455 	gtk_tree_model_get_iter (model, &iter, path);
 456 	gtk_tree_model_get (
 457 		model, &iter,
 458 		HEADER_LIST_ENABLED_COLUMN, &enabled, -1);
 459 	enabled = !enabled;
 460 	gtk_list_store_set (
 461 		GTK_LIST_STORE (model), &iter,
 462 		HEADER_LIST_ENABLED_COLUMN, enabled, -1);
 463 	gtk_tree_path_free (path);
 464 
 465 	emmp_save_headers (prefs);
 466 }
 467 
 468 static void
 469 emmp_header_add_header (GtkWidget *widget,
 470                         EMMailerPrefs *prefs)
 471 {
 472 	GtkTreeModel *model = GTK_TREE_MODEL (prefs->header_list_store);
 473 	GtkTreeIter iter;
 474 	const gchar *text = gtk_entry_get_text (prefs->entry_header);
 475 
 476 	g_strstrip ((gchar *) text);
 477 
 478 	if (text && (strlen (text) > 0)) {
 479 		gtk_list_store_append (GTK_LIST_STORE (model), &iter);
 480 		gtk_list_store_set (
 481 			GTK_LIST_STORE (model), &iter,
 482 			HEADER_LIST_NAME_COLUMN, text,
 483 			HEADER_LIST_ENABLED_COLUMN, TRUE,
 484 			HEADER_LIST_HEADER_COLUMN, text,
 485 			HEADER_LIST_IS_DEFAULT_COLUMN, FALSE,
 486 			-1);
 487 		gtk_entry_set_text (prefs->entry_header, "");
 488 		emmp_header_remove_sensitivity (prefs);
 489 		emmp_header_add_sensitivity (prefs);
 490 
 491 		emmp_save_headers (prefs);
 492 	}
 493 }
 494 
 495 static void
 496 emmp_header_remove_header (GtkWidget *button,
 497                            gpointer user_data)
 498 {
 499 	EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
 500 	GtkTreeModel *model = GTK_TREE_MODEL (prefs->header_list_store);
 501 	GtkTreeSelection *selection;
 502 	GtkTreeIter iter;
 503 
 504 	selection = gtk_tree_view_get_selection (prefs->header_list);
 505 
 506 	if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
 507 		return;
 508 
 509 	gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
 510 	emmp_header_remove_sensitivity (prefs);
 511 
 512 	emmp_save_headers (prefs);
 513 }
 514 
 515 static void
 516 emmp_header_list_row_selected (GtkTreeSelection *selection,
 517                                gpointer user_data)
 518 {
 519 	EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
 520 
 521 	emmp_header_remove_sensitivity (prefs);
 522 }
 523 
 524 static void
 525 emmp_header_entry_changed (GtkWidget *entry,
 526                            gpointer user_data)
 527 {
 528 	EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
 529 
 530 	emmp_header_add_sensitivity (prefs);
 531 }
 532 
 533 static void
 534 toggle_button_toggled (GtkToggleButton *toggle,
 535                        EMMailerPrefs *prefs)
 536 {
 537 	const gchar *key;
 538 
 539 	key = g_object_get_data ((GObject *) toggle, "key");
 540 	g_settings_set_boolean (
 541 		prefs->settings, key,
 542 		gtk_toggle_button_get_active (toggle));
 543 }
 544 
 545 static void
 546 junk_book_lookup_button_toggled (GtkToggleButton *toggle,
 547                                  EMMailerPrefs *prefs)
 548 {
 549 	toggle_button_toggled (toggle, prefs);
 550 	gtk_widget_set_sensitive (
 551 		GTK_WIDGET (prefs->junk_lookup_local_only),
 552 		gtk_toggle_button_get_active (toggle));
 553 }
 554 
 555 static void
 556 custom_junk_button_toggled (GtkToggleButton *toggle,
 557                             EMMailerPrefs *prefs)
 558 {
 559 	toggle_button_toggled (toggle, prefs);
 560 	if (gtk_toggle_button_get_active (toggle)) {
 561 		gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_remove, TRUE);
 562 		gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_add, TRUE);
 563 		gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_tree, TRUE);
 564 	} else {
 565 		gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_tree, FALSE);
 566 		gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_add, FALSE);
 567 		gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_remove, FALSE);
 568 	}
 569 
 570 }
 571 
 572 static void
 573 toggle_button_init (EMMailerPrefs *prefs,
 574                     GtkToggleButton *toggle,
 575                     gint not,
 576                     const gchar *key,
 577                     GCallback toggled)
 578 {
 579 	gboolean v_bool;
 580 
 581 	v_bool = g_settings_get_boolean (prefs->settings, key);
 582 	gtk_toggle_button_set_active (toggle, not ? !v_bool : v_bool);
 583 
 584 	if (toggled) {
 585 		g_object_set_data ((GObject *) toggle, "key", (gpointer) key);
 586 		g_signal_connect (
 587 			toggle, "toggled", toggled, prefs);
 588 	}
 589 
 590 	if (!g_settings_is_writable (prefs->settings, key))
 591 		gtk_widget_set_sensitive (GTK_WIDGET (toggle), FALSE);
 592 }
 593 
 594 static void
 595 trash_days_changed (GtkComboBox *combo_box,
 596                     EMMailerPrefs *prefs)
 597 {
 598 	gint index;
 599 
 600 	index = gtk_combo_box_get_active (combo_box);
 601 	g_return_if_fail (index >= 0);
 602 	g_return_if_fail (index < G_N_ELEMENTS (empty_trash_frequency));
 603 
 604 	g_settings_set_int (
 605 		prefs->settings,
 606 		"trash-empty-on-exit-days",
 607 		empty_trash_frequency[index].days);
 608 }
 609 
 610 static void
 611 emmp_empty_trash_init (EMMailerPrefs *prefs,
 612                        GtkComboBox *combo_box)
 613 {
 614 	gint days, hist = 0, ii;
 615 	GtkListStore *store;
 616 	GtkTreeIter iter;
 617 
 618 	days = g_settings_get_int (
 619 		prefs->settings,
 620 		"trash-empty-on-exit-days");
 621 
 622 	store = GTK_LIST_STORE (gtk_combo_box_get_model (combo_box));
 623 	gtk_list_store_clear (store);
 624 
 625 	for (ii = 0; ii < G_N_ELEMENTS (empty_trash_frequency); ii++) {
 626 		if (days >= empty_trash_frequency[ii].days)
 627 			hist = ii;
 628 
 629 		gtk_list_store_append (store, &iter);
 630 		gtk_list_store_set (
 631 			store, &iter,
 632 			0,  gettext (empty_trash_frequency[ii].label),
 633 			-1);
 634 	}
 635 
 636 	g_signal_connect (
 637 		combo_box, "changed",
 638 		G_CALLBACK (trash_days_changed), prefs);
 639 
 640 	gtk_combo_box_set_active (combo_box, hist);
 641 }
 642 
 643 static void
 644 junk_days_changed (GtkComboBox *combo_box,
 645                    EMMailerPrefs *prefs)
 646 {
 647 	gint index;
 648 
 649 	index = gtk_combo_box_get_active (combo_box);
 650 	g_return_if_fail (index >= 0);
 651 	g_return_if_fail (index < G_N_ELEMENTS (empty_trash_frequency));
 652 
 653 	g_settings_set_int (
 654 		prefs->settings,
 655 		"junk-empty-on-exit-days",
 656 		empty_trash_frequency[index].days);
 657 }
 658 
 659 static void
 660 emmp_empty_junk_init (EMMailerPrefs *prefs,
 661                       GtkComboBox *combo_box)
 662 {
 663 	gint days, hist = 0, ii;
 664 	GtkListStore *store;
 665 	GtkTreeIter iter;
 666 
 667 	days = g_settings_get_int (
 668 		prefs->settings,
 669 		"junk-empty-on-exit-days");
 670 
 671 	store = GTK_LIST_STORE (gtk_combo_box_get_model (combo_box));
 672 	gtk_list_store_clear (store);
 673 
 674 	for (ii = 0; ii < G_N_ELEMENTS (empty_trash_frequency); ii++) {
 675 		if (days >= empty_trash_frequency[ii].days)
 676 			hist = ii;
 677 
 678 		gtk_list_store_append (store, &iter);
 679 		gtk_list_store_set (
 680 			store, &iter,
 681 			0, gettext (empty_trash_frequency[ii].label),
 682 			-1);
 683 	}
 684 
 685 	g_signal_connect (
 686 		combo_box, "changed",
 687 		G_CALLBACK (junk_days_changed), prefs);
 688 
 689 	gtk_combo_box_set_active (combo_box, hist);
 690 }
 691 
 692 static void
 693 http_images_changed (GtkWidget *widget,
 694                      EMMailerPrefs *prefs)
 695 {
 696 	EMailImageLoadingPolicy policy;
 697 
 698 	if (gtk_toggle_button_get_active (prefs->images_always))
 699 		policy = E_MAIL_IMAGE_LOADING_POLICY_ALWAYS;
 700 	else if (gtk_toggle_button_get_active (prefs->images_sometimes))
 701 		policy = E_MAIL_IMAGE_LOADING_POLICY_SOMETIMES;
 702 	else
 703 		policy = E_MAIL_IMAGE_LOADING_POLICY_NEVER;
 704 
 705 	g_settings_set_int (prefs->settings, "load-http-images", policy);
 706 }
 707 
 708 static GtkWidget *
 709 emmp_widget_glade (EConfig *ec,
 710                    EConfigItem *item,
 711                    GtkWidget *parent,
 712                    GtkWidget *old,
 713                    gint position,
 714                    gpointer data)
 715 {
 716 	EMMailerPrefs *prefs = data;
 717 
 718 	return e_builder_get_widget (prefs->builder, item->label);
 719 }
 720 
 721 /* plugin meta-data */
 722 static EMConfigItem emmp_items[] = {
 723 	{ E_CONFIG_BOOK, (gchar *) "", (gchar *) "preferences_toplevel", emmp_widget_glade },
 724 	{ E_CONFIG_PAGE, (gchar *) "00.general", (gchar *) "vboxMailGeneral", emmp_widget_glade },
 725 	{ E_CONFIG_SECTION, (gchar *) "00.general/10.display", (gchar *) "message-display-vbox", emmp_widget_glade },
 726 	{ E_CONFIG_SECTION, (gchar *) "00.general/20.delete", (gchar *) "delete-mail-vbox", emmp_widget_glade },
 727 	{ E_CONFIG_PAGE, (gchar *) "10.html", (gchar *) "vboxHtmlMail", emmp_widget_glade },
 728 	{ E_CONFIG_SECTION, (gchar *) "10.html/00.general", (gchar *) "html-general-vbox", emmp_widget_glade },
 729 	{ E_CONFIG_SECTION, (gchar *) "10.html/10.images", (gchar *) "loading-images-vbox", emmp_widget_glade },
 730 	{ E_CONFIG_PAGE, (gchar *) "20.labels", (gchar *) "frameColours", emmp_widget_glade },
 731 	/* this is a table, so we can't use it { E_CONFIG_SECTION, "20.labels/00.labels", "tableColours", emmp_widget_glade }, */
 732 	{ E_CONFIG_PAGE, (gchar *) "30.headers", (gchar *) "vboxHeaderTab", emmp_widget_glade },
 733 	/* no subvbox for section { E_CONFIG_PAGE, "30.headers/00.headers", "vbox199", emmp_widget_glade }, */
 734 	{ E_CONFIG_PAGE, (gchar *) "40.junk", (gchar *) "vboxJunk", emmp_widget_glade },
 735 	/* no subvbox for section { E_CONFIG_SECTION, "40.junk/00.general", xxx, emmp_widget_glade } */
 736 	{ E_CONFIG_SECTION_TABLE, (gchar *) "40.junk/10.options", (gchar *) "junk-general-table", emmp_widget_glade },
 737 };
 738 
 739 static void
 740 emmp_free (EConfig *ec,
 741            GSList *items,
 742            gpointer data)
 743 {
 744 	/* the prefs data is freed automagically */
 745 
 746 	g_slist_free (items);
 747 }
 748 
 749 static void
 750 em_mailer_prefs_construct (EMMailerPrefs *prefs,
 751                            EMailSession *session,
 752                            EShell *shell)
 753 {
 754 	GSList *header_add_list, *p;
 755 	gchar **headers_config;
 756 	EShellSettings *shell_settings;
 757 	GHashTable *default_header_hash;
 758 	GtkWidget *toplevel;
 759 	GtkWidget *container;
 760 	GtkWidget *table;
 761 	GtkWidget *widget;
 762 	GtkTreeSelection *selection;
 763 	GtkCellRenderer *renderer;
 764 	GtkTreeIter iter;
 765 	gboolean locked;
 766 	gint val, i;
 767 	EMConfig *ec;
 768 	EMConfigTargetPrefs *target;
 769 	GSList *l;
 770 
 771 	shell_settings = e_shell_get_shell_settings (shell);
 772 
 773 	/* Make sure our custom widget classes are registered with
 774 	 * GType before we load the GtkBuilder definition file. */
 775 	E_TYPE_MAIL_JUNK_OPTIONS;
 776 	EM_TYPE_FOLDER_SELECTION_BUTTON;
 777 
 778 	prefs->builder = gtk_builder_new ();
 779 	e_load_ui_builder_definition (prefs->builder, "mail-config.ui");
 780 
 781 	/** @HookPoint-EMConfig: Mail Preferences Page
 782 	 * @Id: org.gnome.evolution.mail.prefs
 783 	 * @Type: E_CONFIG_BOOK
 784 	 * @Class: org.gnome.evolution.mail.config:1.0
 785 	 * @Target: EMConfigTargetPrefs
 786 	 *
 787 	 * The main mail preferences page.
 788 	 */
 789 	ec = em_config_new (E_CONFIG_BOOK, "org.gnome.evolution.mail.prefs");
 790 	l = NULL;
 791 	for (i = 0; i < G_N_ELEMENTS (emmp_items); i++)
 792 		l = g_slist_prepend (l, &emmp_items[i]);
 793 	e_config_add_items ((EConfig *) ec, l, emmp_free, prefs);
 794 
 795 	/* General tab */
 796 
 797 	widget = e_builder_get_widget (prefs->builder, "chkCheckMailOnStart");
 798 	g_object_bind_property (
 799 		shell_settings, "mail-check-on-start",
 800 		widget, "active",
 801 		G_BINDING_BIDIRECTIONAL |
 802 		G_BINDING_SYNC_CREATE);
 803 
 804 	widget = e_builder_get_widget (prefs->builder, "chkCheckMailInAllOnStart");
 805 	g_object_bind_property (
 806 		shell_settings, "mail-check-all-on-start",
 807 		widget, "active",
 808 		G_BINDING_BIDIRECTIONAL |
 809 		G_BINDING_SYNC_CREATE);
 810 	g_object_bind_property (
 811 		shell_settings, "mail-check-on-start",
 812 		widget, "sensitive",
 813 		G_BINDING_BIDIRECTIONAL |
 814 		G_BINDING_SYNC_CREATE);
 815 
 816 	/* Message Display */
 817 
 818 	widget = e_builder_get_widget (prefs->builder, "chkMarkTimeout");
 819 	g_object_bind_property (
 820 		shell_settings, "mail-mark-seen",
 821 		widget, "active",
 822 		G_BINDING_BIDIRECTIONAL |
 823 		G_BINDING_SYNC_CREATE);
 824 
 825 	/* The "mark seen" timeout requires special transform functions
 826 	 * because we display the timeout value to the user in seconds
 827 	 * but store the settings value in milliseconds. */
 828 	widget = e_builder_get_widget (prefs->builder, "spinMarkTimeout");
 829 	g_object_bind_property (
 830 		shell_settings, "mail-mark-seen",
 831 		widget, "sensitive",
 832 		G_BINDING_SYNC_CREATE);
 833 	g_object_bind_property_full (
 834 		shell_settings, "mail-mark-seen-timeout",
 835 		widget, "value",
 836 		G_BINDING_BIDIRECTIONAL |
 837 		G_BINDING_SYNC_CREATE,
 838 		mark_seen_milliseconds_to_seconds,
 839 		mark_seen_seconds_to_milliseconds,
 840 		NULL, (GDestroyNotify) NULL);
 841 
 842 	widget = e_builder_get_widget (prefs->builder, "view-check");
 843 	g_object_bind_property (
 844 		shell_settings, "mail-global-view-setting",
 845 		widget, "active",
 846 		G_BINDING_BIDIRECTIONAL |
 847 		G_BINDING_SYNC_CREATE);
 848 
 849 	widget = e_charset_combo_box_new ();
 850 	container = e_builder_get_widget (prefs->builder, "hboxDefaultCharset");
 851 	gtk_label_set_mnemonic_widget (GTK_LABEL (e_builder_get_widget (prefs->builder, "lblDefaultCharset")), widget);
 852 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
 853 	gtk_widget_show (widget);
 854 	g_object_bind_property (
 855 		shell_settings, "mail-charset",
 856 		widget, "charset",
 857 		G_BINDING_BIDIRECTIONAL |
 858 		G_BINDING_SYNC_CREATE);
 859 
 860 	widget = e_builder_get_widget (prefs->builder, "chkHighlightCitations");
 861 	g_object_bind_property (
 862 		shell_settings, "mail-mark-citations",
 863 		widget, "active",
 864 		G_BINDING_BIDIRECTIONAL |
 865 		G_BINDING_SYNC_CREATE);
 866 
 867 	widget = e_builder_get_widget (prefs->builder, "colorButtonHighlightCitations");
 868 	g_object_bind_property (
 869 		shell_settings, "mail-mark-citations",
 870 		widget, "sensitive",
 871 		G_BINDING_BIDIRECTIONAL |
 872 		G_BINDING_SYNC_CREATE);
 873 	g_object_bind_property_full (
 874 		shell_settings, "mail-citation-color",
 875 		widget, "color",
 876 		G_BINDING_BIDIRECTIONAL |
 877 		G_BINDING_SYNC_CREATE,
 878 		e_binding_transform_string_to_color,
 879 		e_binding_transform_color_to_string,
 880 		NULL, (GDestroyNotify) NULL);
 881 
 882 	widget = e_builder_get_widget (prefs->builder, "thread-by-subject");
 883 	g_object_bind_property (
 884 		shell_settings, "mail-thread-by-subject",
 885 		widget, "active",
 886 		G_BINDING_BIDIRECTIONAL |
 887 		G_BINDING_SYNC_CREATE);
 888 
 889 	/* Deleting Mail */
 890 	widget = e_builder_get_widget (prefs->builder, "chkEmptyTrashOnExit");
 891 	g_object_bind_property (
 892 		shell_settings, "mail-empty-trash-on-exit",
 893 		widget, "active",
 894 		G_BINDING_BIDIRECTIONAL |
 895 		G_BINDING_SYNC_CREATE);
 896 
 897 	widget = e_builder_get_widget (prefs->builder, "comboboxEmptyTrashDays");
 898 	g_object_bind_property (
 899 		shell_settings, "mail-empty-trash-on-exit",
 900 		widget, "sensitive",
 901 		G_BINDING_BIDIRECTIONAL |
 902 		G_BINDING_SYNC_CREATE);
 903 	emmp_empty_trash_init (prefs, GTK_COMBO_BOX (widget));
 904 
 905 	widget = e_builder_get_widget (prefs->builder, "chkConfirmExpunge");
 906 	g_object_bind_property (
 907 		shell_settings, "mail-confirm-expunge",
 908 		widget, "active",
 909 		G_BINDING_BIDIRECTIONAL |
 910 		G_BINDING_SYNC_CREATE);
 911 
 912 	/* Mail Fonts */
 913 	widget = e_builder_get_widget (prefs->builder, "radFontUseSame");
 914 	g_object_bind_property (
 915 		shell_settings, "mail-use-custom-fonts",
 916 		widget, "active",
 917 		G_BINDING_BIDIRECTIONAL |
 918 		G_BINDING_SYNC_CREATE |
 919 		G_BINDING_INVERT_BOOLEAN);
 920 
 921 	widget = e_builder_get_widget (prefs->builder, "FontFixed");
 922 	g_object_bind_property (
 923 		shell_settings, "mail-font-monospace",
 924 		widget, "font-name",
 925 		G_BINDING_BIDIRECTIONAL |
 926 		G_BINDING_SYNC_CREATE);
 927 	g_object_bind_property (
 928 		shell_settings, "mail-use-custom-fonts",
 929 		widget, "sensitive",
 930 		G_BINDING_BIDIRECTIONAL |
 931 		G_BINDING_SYNC_CREATE);
 932 
 933 	widget = e_builder_get_widget (prefs->builder, "FontVariable");
 934 	g_object_bind_property (
 935 		shell_settings, "mail-font-variable",
 936 		widget, "font-name",
 937 		G_BINDING_BIDIRECTIONAL |
 938 		G_BINDING_SYNC_CREATE);
 939 	g_object_bind_property (
 940 		shell_settings, "mail-use-custom-fonts",
 941 		widget, "sensitive",
 942 		G_BINDING_BIDIRECTIONAL |
 943 		G_BINDING_SYNC_CREATE);
 944 
 945 	/* HTML Mail tab */
 946 
 947 	/* Loading Images */
 948 	locked = !g_settings_is_writable (prefs->settings, "load-http-images");
 949 
 950 	val = g_settings_get_int (prefs->settings, "load-http-images");
 951 	prefs->images_never = GTK_TOGGLE_BUTTON (e_builder_get_widget (prefs->builder, "radImagesNever"));
 952 	gtk_toggle_button_set_active (prefs->images_never, val == E_MAIL_IMAGE_LOADING_POLICY_NEVER);
 953 	if (locked)
 954 		gtk_widget_set_sensitive ((GtkWidget *) prefs->images_never, FALSE);
 955 
 956 	prefs->images_sometimes = GTK_TOGGLE_BUTTON (e_builder_get_widget (prefs->builder, "radImagesSometimes"));
 957 	gtk_toggle_button_set_active (prefs->images_sometimes, val == E_MAIL_IMAGE_LOADING_POLICY_SOMETIMES);
 958 	if (locked)
 959 		gtk_widget_set_sensitive ((GtkWidget *) prefs->images_sometimes, FALSE);
 960 
 961 	prefs->images_always = GTK_TOGGLE_BUTTON (e_builder_get_widget (prefs->builder, "radImagesAlways"));
 962 	gtk_toggle_button_set_active (prefs->images_always, val == E_MAIL_IMAGE_LOADING_POLICY_ALWAYS);
 963 	if (locked)
 964 		gtk_widget_set_sensitive ((GtkWidget *) prefs->images_always, FALSE);
 965 
 966 	g_signal_connect (
 967 		prefs->images_never, "toggled",
 968 		G_CALLBACK (http_images_changed), prefs);
 969 	g_signal_connect (
 970 		prefs->images_sometimes, "toggled",
 971 		G_CALLBACK (http_images_changed), prefs);
 972 	g_signal_connect (
 973 		prefs->images_always, "toggled",
 974 		G_CALLBACK (http_images_changed), prefs);
 975 
 976 	widget = e_builder_get_widget (prefs->builder, "chkShowAnimatedImages");
 977 	g_object_bind_property (
 978 		shell_settings, "mail-show-animated-images",
 979 		widget, "active",
 980 		G_BINDING_BIDIRECTIONAL |
 981 		G_BINDING_SYNC_CREATE);
 982 
 983 	widget = e_builder_get_widget (prefs->builder, "chkPromptWantHTML");
 984 	g_object_bind_property (
 985 		shell_settings, "mail-confirm-unwanted-html",
 986 		widget, "active",
 987 		G_BINDING_BIDIRECTIONAL |
 988 		G_BINDING_SYNC_CREATE);
 989 
 990 	container = e_builder_get_widget (prefs->builder, "labels-alignment");
 991 	widget = e_mail_label_manager_new ();
 992 	gtk_container_add (GTK_CONTAINER (container), widget);
 993 	gtk_widget_show (widget);
 994 
 995 	g_object_bind_property (
 996 		session, "label-store",
 997 		widget, "list-store",
 998 		G_BINDING_SYNC_CREATE);
 999 
1000 	/* headers */
1001 	locked = !g_settings_is_writable (prefs->settings, "headers");
1002 
1003 	widget = e_builder_get_widget (prefs->builder, "photo_show");
1004 	g_object_bind_property (
1005 		shell_settings, "mail-show-sender-photo",
1006 		widget, "active",
1007 		G_BINDING_BIDIRECTIONAL |
1008 		G_BINDING_SYNC_CREATE);
1009 
1010 	widget = e_builder_get_widget (prefs->builder, "photo_local");
1011 	g_object_bind_property (
1012 		shell_settings, "mail-show-sender-photo",
1013 		widget, "sensitive",
1014 		G_BINDING_BIDIRECTIONAL |
1015 		G_BINDING_SYNC_CREATE);
1016 	g_object_bind_property (
1017 		shell_settings, "mail-only-local-photos",
1018 		widget, "active",
1019 		G_BINDING_BIDIRECTIONAL |
1020 		G_BINDING_SYNC_CREATE);
1021 
1022 	/* always de-sensitised until the user types something in the entry */
1023 	prefs->add_header = GTK_BUTTON (e_builder_get_widget (prefs->builder, "cmdHeadersAdd"));
1024 	gtk_widget_set_sensitive ((GtkWidget *) prefs->add_header, FALSE);
1025 
1026 	/* always de-sensitised until the user selects a header in the list */
1027 	prefs->remove_header = GTK_BUTTON (e_builder_get_widget (prefs->builder, "cmdHeadersRemove"));
1028 	gtk_widget_set_sensitive ((GtkWidget *) prefs->remove_header, FALSE);
1029 
1030 	prefs->entry_header = GTK_ENTRY (e_builder_get_widget (prefs->builder, "txtHeaders"));
1031 	gtk_widget_set_sensitive ((GtkWidget *) prefs->entry_header, !locked);
1032 
1033 	prefs->header_list = GTK_TREE_VIEW (e_builder_get_widget (prefs->builder, "treeHeaders"));
1034 	gtk_widget_set_sensitive ((GtkWidget *) prefs->header_list, !locked);
1035 
1036 	selection = gtk_tree_view_get_selection (prefs->header_list);
1037 	g_signal_connect (
1038 		selection, "changed",
1039 		G_CALLBACK (emmp_header_list_row_selected), prefs);
1040 	g_signal_connect (
1041 		prefs->entry_header, "changed",
1042 		G_CALLBACK (emmp_header_entry_changed), prefs);
1043 	g_signal_connect (
1044 		prefs->entry_header,
1045 		"activate", G_CALLBACK (emmp_header_add_header), prefs);
1046 	/* initialise the tree with appropriate headings */
1047 	prefs->header_list_store = gtk_list_store_newv (HEADER_LIST_N_COLUMNS, col_types);
1048 	g_signal_connect (
1049 		prefs->add_header, "clicked",
1050 		G_CALLBACK (emmp_header_add_header), prefs);
1051 	g_signal_connect (
1052 		prefs->remove_header, "clicked",
1053 		G_CALLBACK (emmp_header_remove_header), prefs);
1054 	gtk_tree_view_set_model (prefs->header_list, GTK_TREE_MODEL (prefs->header_list_store));
1055 
1056 	renderer = gtk_cell_renderer_toggle_new ();
1057 	g_object_set (renderer, "activatable", TRUE, NULL);
1058 	g_signal_connect (
1059 		renderer, "toggled",
1060 		G_CALLBACK (emmp_header_list_enabled_toggled), prefs);
1061 	gtk_tree_view_insert_column_with_attributes (
1062 		GTK_TREE_VIEW (prefs->header_list), -1,
1063 		"Enabled", renderer,
1064 		"active", HEADER_LIST_ENABLED_COLUMN,
1065 		NULL);
1066 	renderer = gtk_cell_renderer_text_new ();
1067 	gtk_tree_view_insert_column_with_attributes (
1068 		GTK_TREE_VIEW (prefs->header_list), -1,
1069 		"Name", renderer,
1070 		"text", HEADER_LIST_NAME_COLUMN,
1071 		NULL);
1072 
1073 	/* populated the listview with entries; firstly we add all the default headers, and then
1074 	 * we add read header configuration out of settings. If a header in settings is a default header,
1075 	 * we update the enabled flag accordingly
1076 	*/
1077 	header_add_list = NULL;
1078 	default_header_hash = g_hash_table_new (g_str_hash, g_str_equal);
1079 	for (i = 0; i < G_N_ELEMENTS (default_headers); i++) {
1080 		EMailReaderHeader *h;
1081 
1082 		h = g_malloc (sizeof (EMailReaderHeader));
1083 		h->is_default = TRUE;
1084 		h->name = g_strdup (default_headers[i]);
1085 		h->enabled = strcmp ((gchar *) default_headers[i], "x-evolution-mailer") != 0;
1086 		g_hash_table_insert (default_header_hash, (gpointer) default_headers[i], h);
1087 		header_add_list = g_slist_append (header_add_list, h);
1088 	}
1089 
1090 	/* read stored headers from settings */
1091 	headers_config = g_settings_get_strv (prefs->settings, "headers");
1092 	if (headers_config) {
1093 		for (i = 0; headers_config[i]; i++) {
1094 			EMailReaderHeader *h, *def;
1095 			const gchar *xml = headers_config[i];
1096 
1097 			h = e_mail_reader_header_from_xml (xml);
1098 			if (h) {
1099 				def = g_hash_table_lookup (default_header_hash, h->name);
1100 				if (def) {
1101 					def->enabled = h->enabled;
1102 					e_mail_reader_header_free (h);
1103 				} else {
1104 					h->is_default = FALSE;
1105 					header_add_list = g_slist_append (header_add_list, h);
1106 				}
1107 			}
1108 		}
1109 
1110 		g_strfreev (headers_config);
1111 	}
1112 
1113 	g_hash_table_destroy (default_header_hash);
1114 
1115 	p = header_add_list;
1116 	while (p) {
1117 		struct _EMailReaderHeader *h = (struct _EMailReaderHeader *) p->data;
1118 		const gchar *name;
1119 
1120 		if (g_ascii_strcasecmp (h->name, EM_FORMAT_HEADER_XMAILER) == 0)
1121 			name = _("Mailer");
1122 		else
1123 			name = _(h->name);
1124 
1125 		gtk_list_store_append (prefs->header_list_store, &iter);
1126 		gtk_list_store_set (
1127 			prefs->header_list_store, &iter,
1128 			HEADER_LIST_NAME_COLUMN, name,
1129 			HEADER_LIST_ENABLED_COLUMN, h->enabled,
1130 			HEADER_LIST_IS_DEFAULT_COLUMN, h->is_default,
1131 			HEADER_LIST_HEADER_COLUMN, h->name,
1132 			-1);
1133 
1134 		e_mail_reader_header_free (h);
1135 		p = p->next;
1136 	}
1137 
1138 	g_slist_free (header_add_list);
1139 
1140 	/* date/time format */
1141 	table = e_builder_get_widget (prefs->builder, "datetime-format-table");
1142 	/* To Translators: 'Table column' is a label for configurable date/time format for table columns showing a date in message list */
1143 	e_datetime_format_add_setup_widget (table, 0, "mail", "table",  DTFormatKindDateTime, _("_Table column:"));
1144 	/* To Translators: 'Date header' is a label for configurable date/time format for 'Date' header in mail message window/preview */
1145 	e_datetime_format_add_setup_widget (table, 1, "mail", "header", DTFormatKindDateTime, _("_Date header:"));
1146 	widget = gtk_check_button_new_with_mnemonic (_("Show _original header value"));
1147 	gtk_widget_show (widget);
1148 	gtk_table_attach ((GtkTable *) table, widget, 0, 3, 2, 3, GTK_EXPAND | GTK_FILL, 0, 12, 0);
1149 	g_object_bind_property (
1150 		shell_settings, "mail-show-real-date",
1151 		widget, "active",
1152 		G_BINDING_BIDIRECTIONAL |
1153 		G_BINDING_SYNC_CREATE);
1154 
1155 	/* Junk prefs */
1156 	widget = e_builder_get_widget (prefs->builder, "chkCheckIncomingMail");
1157 	g_object_bind_property (
1158 		shell_settings, "mail-check-for-junk",
1159 		widget, "active",
1160 		G_BINDING_BIDIRECTIONAL |
1161 		G_BINDING_SYNC_CREATE);
1162 
1163 	widget = e_builder_get_widget (prefs->builder, "junk_empty_check");
1164 	g_object_bind_property (
1165 		shell_settings, "mail-empty-junk-on-exit",
1166 		widget, "active",
1167 		G_BINDING_BIDIRECTIONAL |
1168 		G_BINDING_SYNC_CREATE);
1169 
1170 	widget = e_builder_get_widget (prefs->builder, "junk_empty_combobox");
1171 	emmp_empty_junk_init (prefs, GTK_COMBO_BOX (widget));
1172 	g_object_bind_property (
1173 		shell_settings, "mail-empty-junk-on-exit",
1174 		widget, "sensitive",
1175 		G_BINDING_SYNC_CREATE);
1176 
1177 	widget = e_builder_get_widget (prefs->builder, "junk-module-options");
1178 	e_mail_junk_options_set_session (E_MAIL_JUNK_OPTIONS (widget), session);
1179 
1180 	prefs->junk_header_check = (GtkToggleButton *) e_builder_get_widget (prefs->builder, "junk_header_check");
1181 	prefs->junk_header_tree = (GtkTreeView *) e_builder_get_widget (prefs->builder, "junk_header_tree");
1182 	prefs->junk_header_add = (GtkButton *) e_builder_get_widget (prefs->builder, "junk_header_add");
1183 	prefs->junk_header_remove = (GtkButton *) e_builder_get_widget (prefs->builder, "junk_header_remove");
1184 	prefs->junk_book_lookup = (GtkToggleButton *) e_builder_get_widget (prefs->builder, "lookup_book");
1185 	prefs->junk_lookup_local_only = (GtkToggleButton *) e_builder_get_widget (prefs->builder, "junk_lookup_local_only");
1186 	toggle_button_init (
1187 		prefs, prefs->junk_book_lookup,
1188 		FALSE, "junk-lookup-addressbook",
1189 		G_CALLBACK (junk_book_lookup_button_toggled));
1190 
1191 	toggle_button_init (
1192 		prefs, prefs->junk_lookup_local_only,
1193 		FALSE, "junk-lookup-addressbook-local-only",
1194 		G_CALLBACK (toggle_button_toggled));
1195 
1196 	junk_book_lookup_button_toggled (prefs->junk_book_lookup, prefs);
1197 
1198 	prefs->junk_header_list_store = init_junk_tree ((GtkWidget *) prefs->junk_header_tree, prefs);
1199 	toggle_button_init (
1200 		prefs, prefs->junk_header_check,
1201 		FALSE, "junk-check-custom-header",
1202 		G_CALLBACK (custom_junk_button_toggled));
1203 
1204 	custom_junk_button_toggled (prefs->junk_header_check, prefs);
1205 	jh_tree_refill (prefs);
1206 	g_signal_connect (
1207 		prefs->junk_header_add, "clicked",
1208 		G_CALLBACK (jh_add_cb), prefs);
1209 	g_signal_connect (
1210 		prefs->junk_header_remove, "clicked",
1211 		G_CALLBACK (jh_remove_cb), prefs);
1212 
1213 	/* get our toplevel widget */
1214 	target = em_config_target_new_prefs (ec);
1215 	e_config_set_target ((EConfig *) ec, (EConfigTarget *) target);
1216 	toplevel = e_config_create_widget ((EConfig *) ec);
1217 	gtk_container_add (GTK_CONTAINER (prefs), toplevel);
1218 }
1219 
1220 GtkWidget *
1221 em_mailer_prefs_new (EPreferencesWindow *window)
1222 {
1223 	EMMailerPrefs *new;
1224 	EShell *shell;
1225 	EShellBackend *shell_backend;
1226 	EMailBackend *backend;
1227 	EMailSession *session;
1228 
1229 	/* XXX Figure out a better way to get the EMailSession. */
1230 	shell = e_preferences_window_get_shell (window);
1231 	shell_backend = e_shell_get_backend_by_name (shell, "mail");
1232 
1233 	backend = E_MAIL_BACKEND (shell_backend);
1234 	session = e_mail_backend_get_session (backend);
1235 
1236 	new = g_object_new (EM_TYPE_MAILER_PREFS, NULL);
1237 
1238 	/* FIXME Kill this function. */
1239 	em_mailer_prefs_construct (new, session, shell);
1240 
1241 	return GTK_WIDGET (new);
1242 }