1 /*
2  * This program is free software; you can redistribute it and/or modify it
3  * under the terms of the GNU Lesser General Public License as published by
4  * the Free Software Foundation.
5  *
6  * This program is distributed in the hope that it will be useful, but
7  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
9  * for more details.
10  *
11  * You should have received a copy of the GNU Lesser General Public License
12  * along with this program; if not, see <http://www.gnu.org/licenses/>.
13  *
14  *
15  * Authors:
16  *		Jeffrey Stedfast <fejj@ximian.com>
17  *
18  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
19  *
20  */
21 
22 #include "evolution-config.h"
23 
24 #include "em-composer-prefs.h"
25 
26 #include <string.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 
32 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
34 
35 #include <composer/e-msg-composer.h>
36 
37 #include <shell/e-shell-utils.h>
38 
39 #include <mail/em-config.h>
40 #include <mail/em-folder-selection-button.h>
41 #include <mail/em-folder-selector.h>
42 #include <mail/em-folder-tree.h>
43 #include <mail/em-folder-tree-model.h>
44 #include <mail/em-composer-utils.h>
45 #include <mail/e-mail-backend.h>
46 #include <mail/e-mail-junk-options.h>
47 #include <mail/e-mail-ui-session.h>
48 
G_DEFINE_TYPE(EMComposerPrefs,em_composer_prefs,GTK_TYPE_BOX)49 G_DEFINE_TYPE (
50 	EMComposerPrefs,
51 	em_composer_prefs,
52 	GTK_TYPE_BOX)
53 
54 static void
55 composer_prefs_dispose (GObject *object)
56 {
57 	EMComposerPrefs *prefs = (EMComposerPrefs *) object;
58 
59 	g_clear_object (&prefs->builder);
60 
61 	/* Chain up to parent's dispose() method. */
62 	G_OBJECT_CLASS (em_composer_prefs_parent_class)->dispose (object);
63 }
64 
65 static void
em_composer_prefs_class_init(EMComposerPrefsClass * class)66 em_composer_prefs_class_init (EMComposerPrefsClass *class)
67 {
68 	GObjectClass *object_class;
69 
70 	object_class = G_OBJECT_CLASS (class);
71 	object_class->dispose = composer_prefs_dispose;
72 }
73 
74 static void
em_composer_prefs_init(EMComposerPrefs * prefs)75 em_composer_prefs_init (EMComposerPrefs *prefs)
76 {
77 	gtk_orientable_set_orientation (GTK_ORIENTABLE (prefs), GTK_ORIENTATION_VERTICAL);
78 }
79 
80 static void
spell_language_toggled_cb(GtkCellRendererToggle * renderer,const gchar * path_string,EMComposerPrefs * prefs)81 spell_language_toggled_cb (GtkCellRendererToggle *renderer,
82                            const gchar *path_string,
83                            EMComposerPrefs *prefs)
84 {
85 	GtkTreeModel *model;
86 	GtkTreePath *path;
87 	GtkTreeIter iter;
88 	gboolean active;
89 	gboolean valid;
90 
91 	model = prefs->language_model;
92 
93 	/* Convert the path string to a tree iterator. */
94 	path = gtk_tree_path_new_from_string (path_string);
95 	valid = gtk_tree_model_get_iter (model, &iter, path);
96 	gtk_tree_path_free (path);
97 	g_return_if_fail (valid);
98 
99 	/* Toggle the active state. */
100 	gtk_tree_model_get (model, &iter, 0, &active, -1);
101 	gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, !active, -1);
102 }
103 
104 static void
spell_language_save(EMComposerPrefs * prefs)105 spell_language_save (EMComposerPrefs *prefs)
106 {
107 	GList *spell_languages = NULL;
108 	GtkTreeModel *model;
109 	GtkTreeIter iter;
110 	gboolean valid;
111 
112 	model = prefs->language_model;
113 
114 	/* Build a list of active spell languages. */
115 	valid = gtk_tree_model_get_iter_first (model, &iter);
116 	while (valid) {
117 		ESpellDictionary *language;
118 		gboolean active;
119 
120 		gtk_tree_model_get (
121 			model, &iter, 0, &active, 2, &language, -1);
122 
123 		if (active)
124 			spell_languages = g_list_prepend (
125 				spell_languages, (gpointer) language);
126 
127 		valid = gtk_tree_model_iter_next (model, &iter);
128 	}
129 	spell_languages = g_list_reverse (spell_languages);
130 
131 	/* Update the GSettings value. */
132 	e_save_spell_languages (spell_languages);
133 
134 	g_list_free (spell_languages);
135 }
136 
137 static void
spell_setup(EMComposerPrefs * prefs)138 spell_setup (EMComposerPrefs *prefs)
139 {
140 	GList *list = NULL, *link;
141 	GtkListStore *store;
142 
143 	store = GTK_LIST_STORE (prefs->language_model);
144 	list = e_spell_checker_list_available_dicts (prefs->spell_checker);
145 
146 	/* Populate the GtkListStore. */
147 	for (link = list; link != NULL; link = g_list_next (link)) {
148 		ESpellDictionary *dictionary;
149 		GtkTreeIter tree_iter;
150 		const gchar *name;
151 		const gchar *code;
152 		gboolean active;
153 
154 		dictionary = E_SPELL_DICTIONARY (link->data);
155 		name = e_spell_dictionary_get_name (dictionary);
156 		code = e_spell_dictionary_get_code (dictionary);
157 
158 		active = e_spell_checker_get_language_active (
159 			prefs->spell_checker, code);
160 
161 		gtk_list_store_append (store, &tree_iter);
162 
163 		gtk_list_store_set (
164 			store, &tree_iter,
165 			0, active, 1, name, 2, dictionary, -1);
166 	}
167 
168 	g_list_free (list);
169 }
170 
171 #define MAIL_SEND_ACCOUNT_OVERRIDE_KEY "sao-mail-send-account-override"
172 #define MAIL_CAMEL_SESSION_KEY "sao-mail-camel-session"
173 
174 static gchar *
sao_dup_account_uid(GtkBuilder * builder,gchar ** out_alias_name,gchar ** out_alias_address)175 sao_dup_account_uid (GtkBuilder *builder,
176 		     gchar **out_alias_name,
177 		     gchar **out_alias_address)
178 {
179 	GtkWidget *widget;
180 	GtkTreeView *tree_view;
181 	GtkTreeSelection *selection;
182 	GtkTreeModel *model;
183 	GtkTreeIter iter;
184 	gchar *account_uid = NULL;
185 
186 	widget = e_builder_get_widget (builder, "sao-account-treeview");
187 	g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), NULL);
188 
189 	tree_view = GTK_TREE_VIEW (widget);
190 	selection = gtk_tree_view_get_selection (tree_view);
191 
192 	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
193 		return NULL;
194 
195 	gtk_tree_model_get (model, &iter,
196 		E_MAIL_IDENTITY_COMBO_BOX_COLUMN_UID, &account_uid,
197 		E_MAIL_IDENTITY_COMBO_BOX_COLUMN_NAME, out_alias_name,
198 		E_MAIL_IDENTITY_COMBO_BOX_COLUMN_ADDRESS, out_alias_address,
199 		-1);
200 
201 	return account_uid;
202 }
203 
204 static void
sao_fill_overrides(GtkBuilder * builder,const gchar * tree_view_name,GList * overrides,gboolean is_folder)205 sao_fill_overrides (GtkBuilder *builder,
206                     const gchar *tree_view_name,
207                     GList *overrides,
208                     gboolean is_folder)
209 {
210 	CamelSession *session = NULL;
211 	GtkWidget *widget;
212 	GtkListStore *list_store;
213 	GtkTreeIter titer;
214 	GList *oiter;
215 
216 	widget = e_builder_get_widget (builder, tree_view_name);
217 	g_return_if_fail (GTK_IS_TREE_VIEW (widget));
218 
219 	list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (widget)));
220 	g_return_if_fail (list_store != NULL);
221 
222 	gtk_list_store_clear (list_store);
223 
224 	if (is_folder)
225 		session = g_object_get_data (G_OBJECT (builder), MAIL_CAMEL_SESSION_KEY);
226 
227 	for (oiter = overrides; oiter; oiter = g_list_next (oiter)) {
228 		const gchar *value = oiter->data;
229 		gchar *markup = NULL;
230 
231 		if (!value || !*value)
232 			continue;
233 
234 		if (is_folder) {
235 			markup = e_mail_folder_uri_to_markup (session, value, NULL);
236 			if (!markup)
237 				continue;
238 		}
239 
240 		gtk_list_store_append (list_store, &titer);
241 
242 		if (is_folder) {
243 			gtk_list_store_set (list_store, &titer, 0, markup, 1, value, -1);
244 		} else {
245 			gtk_list_store_set (list_store, &titer, 0, value, -1);
246 		}
247 
248 		g_free (markup);
249 	}
250 }
251 
252 static void
sao_account_treeview_selection_changed_cb(GtkTreeSelection * selection,GtkBuilder * builder)253 sao_account_treeview_selection_changed_cb (GtkTreeSelection *selection,
254                                            GtkBuilder *builder)
255 {
256 	GtkTreeModel *model;
257 	GtkWidget *widget;
258 	gboolean enable = FALSE;
259 
260 	g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
261 	g_return_if_fail (GTK_IS_BUILDER (builder));
262 
263 	widget = e_builder_get_widget (builder, "sao-folders-treeview");
264 	g_return_if_fail (GTK_IS_WIDGET (widget));
265 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
266 	gtk_list_store_clear (GTK_LIST_STORE (model));
267 
268 	widget = e_builder_get_widget (builder, "sao-recipients-treeview");
269 	g_return_if_fail (GTK_IS_WIDGET (widget));
270 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
271 	gtk_list_store_clear (GTK_LIST_STORE (model));
272 
273 	if (gtk_tree_selection_get_selected (selection, NULL, NULL)) {
274 		gchar *account_uid, *alias_name = NULL, *alias_address = NULL;
275 
276 		account_uid = sao_dup_account_uid (builder, &alias_name, &alias_address);
277 		if (account_uid) {
278 			GList *folder_overrides = NULL;
279 			GList *recipient_overrides = NULL;
280 
281 			enable = TRUE;
282 
283 			e_mail_send_account_override_list_for_account (
284 				g_object_get_data (
285 					G_OBJECT (builder),
286 					MAIL_SEND_ACCOUNT_OVERRIDE_KEY),
287 				account_uid, alias_name, alias_address, &folder_overrides, &recipient_overrides);
288 
289 			sao_fill_overrides (
290 				builder, "sao-folders-treeview",
291 				folder_overrides, TRUE);
292 			sao_fill_overrides (
293 				builder, "sao-recipients-treeview",
294 				recipient_overrides, FALSE);
295 
296 			g_list_free_full (folder_overrides, g_free);
297 			g_list_free_full (recipient_overrides, g_free);
298 			g_free (account_uid);
299 			g_free (alias_name);
300 			g_free (alias_address);
301 		}
302 	}
303 
304 	widget = e_builder_get_widget (builder, "sao-folders-frame");
305 	g_return_if_fail (GTK_IS_WIDGET (widget));
306 	gtk_widget_set_sensitive (widget, enable);
307 
308 	widget = e_builder_get_widget (builder, "sao-recipients-frame");
309 	g_return_if_fail (GTK_IS_WIDGET (widget));
310 	gtk_widget_set_sensitive (widget, enable);
311 }
312 
313 static void
sao_account_row_changed_cb(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,GtkBuilder * builder)314 sao_account_row_changed_cb (GtkTreeModel *model,
315 			    GtkTreePath *path,
316 			    GtkTreeIter *iter,
317 			    GtkBuilder *builder)
318 {
319 	GtkTreeSelection *selection;
320 	GtkWidget *widget;
321 
322 	if (gtk_tree_model_iter_n_children (model, NULL) != 1)
323 		return;
324 
325 	widget = e_builder_get_widget (builder, "sao-account-treeview");
326 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
327 
328 	if (!gtk_tree_selection_get_selected (selection, NULL, NULL))
329 		gtk_tree_selection_select_iter (selection, iter);
330 }
331 
332 static void
sao_overrides_changed_cb(EMailSendAccountOverride * account_override,GtkBuilder * builder)333 sao_overrides_changed_cb (EMailSendAccountOverride *account_override,
334                           GtkBuilder *builder)
335 {
336 	GtkWidget *widget;
337 	GtkTreeSelection *selection;
338 
339 	g_return_if_fail (GTK_IS_BUILDER (builder));
340 
341 	widget = e_builder_get_widget (builder, "sao-account-treeview");
342 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
343 
344 	sao_account_treeview_selection_changed_cb (selection, builder);
345 }
346 
347 static void
sao_block_changed_handler(GtkBuilder * builder)348 sao_block_changed_handler (GtkBuilder *builder)
349 {
350 	GObject *account_override;
351 
352 	g_return_if_fail (GTK_IS_BUILDER (builder));
353 
354 	account_override = g_object_get_data (G_OBJECT (builder), MAIL_SEND_ACCOUNT_OVERRIDE_KEY),
355 	g_signal_handlers_block_by_func (account_override, sao_overrides_changed_cb, builder);
356 }
357 
358 static void
sao_unblock_changed_handler(GtkBuilder * builder)359 sao_unblock_changed_handler (GtkBuilder *builder)
360 {
361 	GObject *account_override;
362 
363 	g_return_if_fail (GTK_IS_BUILDER (builder));
364 
365 	account_override = g_object_get_data (G_OBJECT (builder), MAIL_SEND_ACCOUNT_OVERRIDE_KEY),
366 	g_signal_handlers_unblock_by_func (account_override, sao_overrides_changed_cb, builder);
367 }
368 
369 static void
sao_folders_treeview_selection_changed_cb(GtkTreeSelection * selection,GtkBuilder * builder)370 sao_folders_treeview_selection_changed_cb (GtkTreeSelection *selection,
371                                            GtkBuilder *builder)
372 {
373 	GtkWidget *widget;
374 	gint nselected;
375 
376 	g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
377 	g_return_if_fail (GTK_IS_BUILDER (builder));
378 
379 	nselected = gtk_tree_selection_count_selected_rows (selection);
380 
381 	widget = e_builder_get_widget (builder, "sao-folders-remove-button");
382 	g_return_if_fail (GTK_IS_WIDGET (widget));
383 	gtk_widget_set_sensitive (widget, nselected > 0);
384 }
385 
386 static void
sao_folders_add_button_clicked_cb(GtkButton * button,GtkBuilder * builder)387 sao_folders_add_button_clicked_cb (GtkButton *button,
388                                    GtkBuilder *builder)
389 {
390 	GtkTreeSelection *selection;
391 	GtkTreeView *tree_view;
392 	GtkTreeModel *model;
393 	GtkTreeIter iter;
394 	GtkWidget *widget;
395 	EMFolderSelector *selector;
396 	EMFolderTree *folder_tree;
397 	GtkWidget *dialog;
398 	GtkWindow *window;
399 	gchar *account_uid, *alias_name = NULL, *alias_address = NULL;
400 
401 	g_return_if_fail (GTK_IS_BUTTON (button));
402 	g_return_if_fail (GTK_IS_BUILDER (builder));
403 
404 	account_uid = sao_dup_account_uid (builder, &alias_name, &alias_address);
405 	g_return_if_fail (account_uid != NULL);
406 
407 	widget = e_builder_get_widget (builder, "sao-folders-treeview");
408 	g_return_if_fail (GTK_IS_TREE_VIEW (widget));
409 	tree_view = GTK_TREE_VIEW (widget);
410 
411 	window = GTK_WINDOW (gtk_widget_get_toplevel (widget));
412 
413 	dialog = em_folder_selector_new (
414 		window, em_folder_tree_model_get_default ());
415 
416 	gtk_window_set_title (
417 		GTK_WINDOW (dialog), _("Select Folder to Add"));
418 
419 	selector = EM_FOLDER_SELECTOR (dialog);
420 	em_folder_selector_set_default_button_label (selector, _("_Add"));
421 
422 	folder_tree = em_folder_selector_get_folder_tree (selector);
423 
424 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_tree));
425 	gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
426 
427 	em_folder_tree_set_excluded (folder_tree, EMFT_EXCLUDE_NOSELECT);
428 
429 	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
430 		GList *list, *folder_uris;
431 
432 		model = gtk_tree_view_get_model (tree_view);
433 
434 		folder_uris = em_folder_tree_get_selected_uris (folder_tree);
435 
436 		for (list = folder_uris; list; list = g_list_next (list)) {
437 			const gchar *uri = list->data;
438 
439 			if (uri && *uri) {
440 				gboolean found = FALSE;
441 
442 				if (gtk_tree_model_get_iter_first (model, &iter)) {
443 					do {
444 						gchar *old_uri = NULL;
445 
446 						gtk_tree_model_get (model, &iter, 1, &old_uri, -1);
447 
448 						found = g_strcmp0 (uri, old_uri) == 0;
449 
450 						g_free (old_uri);
451 					} while (!found && gtk_tree_model_iter_next (model, &iter));
452 				}
453 
454 				if (!found) {
455 					EMailSendAccountOverride *account_override;
456 					GtkListStore *list_store;
457 					CamelSession *session;
458 					gchar *markup;
459 
460 					list_store = GTK_LIST_STORE (model);
461 					session = g_object_get_data (G_OBJECT (builder), MAIL_CAMEL_SESSION_KEY);
462 					markup = e_mail_folder_uri_to_markup (session, uri, NULL);
463 
464 					gtk_list_store_append (list_store, &iter);
465 					gtk_list_store_set (list_store, &iter, 0, markup, 1, uri, -1);
466 
467 					g_free (markup);
468 
469 					sao_block_changed_handler (builder);
470 
471 					account_override = g_object_get_data (G_OBJECT (builder), MAIL_SEND_ACCOUNT_OVERRIDE_KEY);
472 					e_mail_send_account_override_set_for_folder (account_override, uri, account_uid, alias_name, alias_address);
473 
474 					sao_unblock_changed_handler (builder);
475 				}
476 
477 				if (!list->next) {
478 					selection = gtk_tree_view_get_selection (tree_view);
479 
480 					gtk_tree_selection_unselect_all (selection);
481 					gtk_tree_selection_select_iter (selection, &iter);
482 				}
483 			}
484 		}
485 
486 		g_list_free_full (folder_uris, g_free);
487 	}
488 
489 	gtk_widget_destroy (dialog);
490 	g_free (account_uid);
491 	g_free (alias_name);
492 	g_free (alias_address);
493 }
494 
495 static void
sao_folders_remove_button_clicked_cb(GtkButton * button,GtkBuilder * builder)496 sao_folders_remove_button_clicked_cb (GtkButton *button,
497                                       GtkBuilder *builder)
498 {
499 	EMailSendAccountOverride *account_override;
500 	GtkTreeSelection *selection;
501 	GtkTreeView *tree_view;
502 	GtkTreeModel *model;
503 	GtkTreeIter iter;
504 	GtkWidget *widget;
505 	GList *selected, *siter;
506 
507 	g_return_if_fail (GTK_IS_BUTTON (button));
508 	g_return_if_fail (GTK_IS_BUILDER (builder));
509 
510 	widget = e_builder_get_widget (builder, "sao-folders-treeview");
511 	g_return_if_fail (GTK_IS_TREE_VIEW (widget));
512 	tree_view = GTK_TREE_VIEW (widget);
513 	selection = gtk_tree_view_get_selection (tree_view);
514 	model = gtk_tree_view_get_model (tree_view);
515 
516 	sao_block_changed_handler (builder);
517 
518 	account_override = g_object_get_data (G_OBJECT (builder), MAIL_SEND_ACCOUNT_OVERRIDE_KEY);
519 	e_mail_send_account_override_freeze_save (account_override);
520 
521 	selected = gtk_tree_selection_get_selected_rows (selection, &model);
522 	selected = g_list_reverse (selected);
523 
524 	for (siter = selected; siter; siter = g_list_next (siter)) {
525 		gchar *uri = NULL;
526 
527 		if (!gtk_tree_model_get_iter (model, &iter, siter->data))
528 			continue;
529 
530 		gtk_tree_model_get (model, &iter, 1, &uri, -1);
531 
532 		if (uri && *uri)
533 			e_mail_send_account_override_remove_for_folder (account_override, uri);
534 
535 		gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
536 		g_free (uri);
537 	}
538 
539 	e_mail_send_account_override_thaw_save (account_override);
540 	sao_unblock_changed_handler (builder);
541 
542 	g_list_free_full (selected, (GDestroyNotify) gtk_tree_path_free);
543 }
544 
545 static void
sao_recipients_treeview_selection_changed_cb(GtkTreeSelection * selection,GtkBuilder * builder)546 sao_recipients_treeview_selection_changed_cb (GtkTreeSelection *selection,
547                                               GtkBuilder *builder)
548 {
549 	GtkWidget *widget;
550 	gint nselected;
551 
552 	g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
553 	g_return_if_fail (GTK_IS_BUILDER (builder));
554 
555 	nselected = gtk_tree_selection_count_selected_rows (selection);
556 
557 	widget = e_builder_get_widget (builder, "sao-recipients-edit-button");
558 	g_return_if_fail (GTK_IS_WIDGET (widget));
559 	gtk_widget_set_sensitive (widget, nselected == 1);
560 
561 	widget = e_builder_get_widget (builder, "sao-recipients-remove-button");
562 	g_return_if_fail (GTK_IS_WIDGET (widget));
563 	gtk_widget_set_sensitive (widget, nselected > 0);
564 }
565 
566 static void
sao_recipient_edited_cb(GtkCellRendererText * renderer,const gchar * path_str,const gchar * new_text,GtkBuilder * builder)567 sao_recipient_edited_cb (GtkCellRendererText *renderer,
568                          const gchar *path_str,
569                          const gchar *new_text,
570                          GtkBuilder *builder)
571 {
572 	EMailSendAccountOverride *account_override;
573 	GtkTreePath *path;
574 	GtkTreeModel *model;
575 	GtkTreeIter iter;
576 	gchar *text, *old_text = NULL, *account_uid, *alias_name = NULL, *alias_address = NULL;
577 	GtkWidget *widget;
578 
579 	g_return_if_fail (path_str != NULL);
580 	g_return_if_fail (GTK_IS_BUILDER (builder));
581 
582 	widget = e_builder_get_widget (builder, "sao-recipients-treeview");
583 	g_return_if_fail (GTK_IS_TREE_VIEW (widget));
584 
585 	path = gtk_tree_path_new_from_string (path_str);
586 	g_return_if_fail (path != NULL);
587 
588 	account_uid = sao_dup_account_uid (builder, &alias_name, &alias_address);
589 	g_return_if_fail (account_uid != NULL);
590 
591 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
592 	g_return_if_fail (gtk_tree_model_get_iter (model, &iter, path));
593 	gtk_tree_path_free (path);
594 
595 	gtk_tree_model_get (model, &iter, 0, &old_text, -1);
596 
597 	sao_block_changed_handler (builder);
598 
599 	account_override = g_object_get_data (G_OBJECT (builder), MAIL_SEND_ACCOUNT_OVERRIDE_KEY);
600 
601 	text = g_strdup (new_text);
602 	if (text)
603 		g_strchomp (text);
604 
605 	if (old_text && *old_text)
606 		e_mail_send_account_override_remove_for_recipient (account_override, old_text);
607 
608 	if (!text || !*text) {
609 		gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
610 	} else {
611 		GtkTreeIter new_iter = iter;
612 		gboolean is_new = TRUE;
613 
614 		if (gtk_tree_model_get_iter_first (model, &iter)) {
615 			do {
616 				gchar *old_recipient = NULL;
617 
618 				gtk_tree_model_get (model, &iter, 0, &old_recipient, -1);
619 
620 				is_new = !old_recipient || e_util_utf8_strcasecmp (text, old_recipient) != 0;
621 
622 				g_free (old_recipient);
623 			} while (is_new && gtk_tree_model_iter_next (model, &iter));
624 		}
625 
626 		if (is_new) {
627 			gtk_list_store_set (GTK_LIST_STORE (model), &new_iter, 0, text, -1);
628 			e_mail_send_account_override_set_for_recipient (account_override, text, account_uid, alias_name, alias_address);
629 		} else {
630 			GtkTreeSelection *selection;
631 			GtkTreePath *path1, *path2;
632 
633 			selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
634 
635 			path1 = gtk_tree_model_get_path (model, &iter);
636 			path2 = gtk_tree_model_get_path (model, &new_iter);
637 
638 			if (!path1 || !path2 || gtk_tree_path_compare (path1, path2) != 0)
639 				gtk_list_store_remove (GTK_LIST_STORE (model), &new_iter);
640 
641 			gtk_tree_path_free (path1);
642 			gtk_tree_path_free (path2);
643 
644 			gtk_tree_selection_unselect_all (selection);
645 			gtk_tree_selection_select_iter (selection, &iter);
646 		}
647 	}
648 
649 	sao_unblock_changed_handler (builder);
650 
651 	g_free (account_uid);
652 	g_free (alias_name);
653 	g_free (alias_address);
654 	g_free (old_text);
655 	g_free (text);
656 }
657 
658 static void
sao_recipient_editing_canceled_cb(GtkCellRenderer * renderer,GtkBuilder * builder)659 sao_recipient_editing_canceled_cb (GtkCellRenderer *renderer,
660                                    GtkBuilder *builder)
661 {
662 	GtkTreeModel *model;
663 	GtkTreeIter iter;
664 	GtkWidget *widget;
665 
666 	g_return_if_fail (GTK_IS_BUILDER (builder));
667 
668 	widget = e_builder_get_widget (builder, "sao-recipients-treeview");
669 	g_return_if_fail (GTK_IS_TREE_VIEW (widget));
670 
671 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
672 
673 	if (gtk_tree_model_get_iter_first (model, &iter)) {
674 		do {
675 			gchar *old_recipient = NULL;
676 
677 			gtk_tree_model_get (model, &iter, 0, &old_recipient, -1);
678 
679 			if (!old_recipient || !*old_recipient) {
680 				gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
681 				g_free (old_recipient);
682 				break;
683 			}
684 
685 			g_free (old_recipient);
686 		} while (gtk_tree_model_iter_next (model, &iter));
687 	}
688 }
689 
690 static void
sao_recipients_add_button_clicked_cb(GtkButton * button,GtkBuilder * builder)691 sao_recipients_add_button_clicked_cb (GtkButton *button,
692                                       GtkBuilder *builder)
693 {
694 	GtkTreeView *tree_view;
695 	GtkTreeViewColumn *column;
696 	GtkTreeSelection *selection;
697 	GtkTreeModel *model;
698 	GtkTreePath *path;
699 	GtkTreeIter iter;
700 	GtkWidget *widget;
701 	GList *cells;
702 
703 	g_return_if_fail (GTK_IS_BUTTON (button));
704 	g_return_if_fail (GTK_IS_BUILDER (builder));
705 
706 	widget = e_builder_get_widget (builder, "sao-recipients-treeview");
707 	g_return_if_fail (GTK_IS_TREE_VIEW (widget));
708 
709 	tree_view = GTK_TREE_VIEW (widget);
710 	model = gtk_tree_view_get_model (tree_view);
711 	selection = gtk_tree_view_get_selection (tree_view);
712 
713 	gtk_list_store_append (GTK_LIST_STORE (model), &iter);
714 
715 	gtk_tree_selection_unselect_all (selection);
716 	gtk_tree_selection_select_iter (selection, &iter);
717 
718 	column = gtk_tree_view_get_column (tree_view, 0);
719 	g_return_if_fail (column != NULL);
720 
721 	cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
722 	g_return_if_fail (cells != NULL);
723 
724 	path = gtk_tree_model_get_path (model, &iter);
725 	if (path == NULL) {
726 		g_list_free (cells);
727 		return;
728 	}
729 
730 	g_object_set (cells->data, "editable", TRUE, NULL);
731 	gtk_tree_view_set_cursor_on_cell (
732 		tree_view, path, column, cells->data, TRUE);
733 	g_object_set (cells->data, "editable", FALSE, NULL);
734 
735 	gtk_tree_path_free (path);
736 	g_list_free (cells);
737 }
738 
739 static void
sao_recipients_edit_button_clicked_cb(GtkButton * button,GtkBuilder * builder)740 sao_recipients_edit_button_clicked_cb (GtkButton *button,
741                                        GtkBuilder *builder)
742 {
743 	GtkTreeView *tree_view;
744 	GtkTreeViewColumn *column;
745 	GtkTreeSelection *selection;
746 	GtkTreePath *path;
747 	GtkWidget *widget;
748 	GList *cells, *selected;
749 
750 	g_return_if_fail (GTK_IS_BUTTON (button));
751 	g_return_if_fail (GTK_IS_BUILDER (builder));
752 
753 	widget = e_builder_get_widget (builder, "sao-recipients-treeview");
754 	g_return_if_fail (GTK_IS_TREE_VIEW (widget));
755 
756 	tree_view = GTK_TREE_VIEW (widget);
757 	selection = gtk_tree_view_get_selection (tree_view);
758 
759 	g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1);
760 
761 	selected = gtk_tree_selection_get_selected_rows (selection, NULL);
762 	g_return_if_fail (selected && selected->next == NULL);
763 
764 	path = selected->data;
765 	/* 'path' is freed later in the function */
766 	g_list_free (selected);
767 
768 	column = gtk_tree_view_get_column (tree_view, 0);
769 	g_return_if_fail (column != NULL);
770 
771 	cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
772 	g_return_if_fail (cells != NULL);
773 
774 	g_object_set (cells->data, "editable", TRUE, NULL);
775 	gtk_tree_view_set_cursor_on_cell (
776 		tree_view, path, column, cells->data, TRUE);
777 	g_object_set (cells->data, "editable", FALSE, NULL);
778 
779 	gtk_tree_path_free (path);
780 	g_list_free (cells);
781 }
782 
783 static void
sao_recipients_remove_button_clicked_cb(GtkButton * button,GtkBuilder * builder)784 sao_recipients_remove_button_clicked_cb (GtkButton *button,
785                                          GtkBuilder *builder)
786 {
787 	EMailSendAccountOverride *account_override;
788 	GtkTreeSelection *selection;
789 	GtkTreeView *tree_view;
790 	GtkTreeModel *model;
791 	GtkTreeIter iter;
792 	GtkWidget *widget;
793 	GList *selected, *siter;
794 
795 	g_return_if_fail (GTK_IS_BUTTON (button));
796 	g_return_if_fail (GTK_IS_BUILDER (builder));
797 
798 	widget = e_builder_get_widget (builder, "sao-recipients-treeview");
799 	g_return_if_fail (GTK_IS_TREE_VIEW (widget));
800 	tree_view = GTK_TREE_VIEW (widget);
801 	selection = gtk_tree_view_get_selection (tree_view);
802 	model = gtk_tree_view_get_model (tree_view);
803 
804 	sao_block_changed_handler (builder);
805 
806 	account_override = g_object_get_data (G_OBJECT (builder), MAIL_SEND_ACCOUNT_OVERRIDE_KEY);
807 	e_mail_send_account_override_freeze_save (account_override);
808 
809 	selected = gtk_tree_selection_get_selected_rows (selection, &model);
810 	selected = g_list_reverse (selected);
811 
812 	for (siter = selected; siter; siter = g_list_next (siter)) {
813 		gchar *recipient = NULL;
814 
815 		if (!gtk_tree_model_get_iter (model, &iter, siter->data))
816 			continue;
817 
818 		gtk_tree_model_get (model, &iter, 0, &recipient, -1);
819 
820 		if (recipient && *recipient)
821 			e_mail_send_account_override_remove_for_recipient (account_override, recipient);
822 
823 		gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
824 		g_free (recipient);
825 	}
826 
827 	e_mail_send_account_override_thaw_save (account_override);
828 	sao_unblock_changed_handler (builder);
829 
830 	g_list_free_full (selected, (GDestroyNotify) gtk_tree_path_free);
831 }
832 
833 static void
send_account_override_setup(GtkBuilder * builder,EMailBackend * mail_backend,ESourceRegistry * registry)834 send_account_override_setup (GtkBuilder *builder,
835                              EMailBackend *mail_backend,
836                              ESourceRegistry *registry)
837 {
838 	EMailIdentityComboBox *identity_combo_box;
839 	EMailSendAccountOverride *account_override;
840 	GtkTreeView *tree_view;
841 	GtkTreeSelection *selection;
842 	GtkTreeModel *model;
843 	GtkListStore *list_store;
844 	GtkCellRenderer *renderer;
845 	GtkWidget *widget;
846 
847 	g_return_if_fail (GTK_IS_BUILDER (builder));
848 	g_return_if_fail (E_IS_MAIL_BACKEND (mail_backend));
849 	g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
850 
851 	/* use its model to avoid code duplication */
852 	widget = e_mail_identity_combo_box_new (registry);
853 	e_mail_identity_combo_box_set_allow_aliases (E_MAIL_IDENTITY_COMBO_BOX (widget), TRUE);
854 
855 	identity_combo_box = E_MAIL_IDENTITY_COMBO_BOX (g_object_ref_sink (widget));
856 
857 	widget = e_builder_get_widget (builder, "sao-account-treeview");
858 	g_return_if_fail (GTK_IS_TREE_VIEW (widget));
859 
860 	tree_view = GTK_TREE_VIEW (widget);
861 
862 	g_object_set_data_full (
863 		G_OBJECT (tree_view), "identity-combo-box",
864 		identity_combo_box, (GDestroyNotify) gtk_widget_destroy);
865 	g_object_set_data_full (
866 		G_OBJECT (builder), MAIL_CAMEL_SESSION_KEY,
867 		g_object_ref (e_mail_backend_get_session (mail_backend)), g_object_unref);
868 
869 	model = gtk_combo_box_get_model (GTK_COMBO_BOX (identity_combo_box));
870 
871 	gtk_tree_view_set_model (tree_view, model);
872 	gtk_tree_view_insert_column_with_attributes (
873 		tree_view, -1, _("Account"),
874 		gtk_cell_renderer_text_new (),
875 		"text", 0, NULL);
876 
877 	selection = gtk_tree_view_get_selection (tree_view);
878 	g_signal_connect (
879 		selection, "changed",
880 		G_CALLBACK (sao_account_treeview_selection_changed_cb), builder);
881 
882 	g_signal_connect (model, "row-changed", G_CALLBACK (sao_account_row_changed_cb), builder);
883 
884 	widget = e_builder_get_widget (builder, "sao-folders-treeview");
885 	g_return_if_fail (GTK_IS_TREE_VIEW (widget));
886 
887 	tree_view = GTK_TREE_VIEW (widget);
888 
889 	/* markup, folder-uri */
890 	list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
891 	gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (list_store));
892 	gtk_tree_view_insert_column_with_attributes (
893 		tree_view, -1, _("Folder"),
894 		gtk_cell_renderer_text_new (),
895 		"markup", 0, NULL);
896 	g_object_unref (list_store);
897 
898 	selection = gtk_tree_view_get_selection (tree_view);
899 	g_signal_connect (
900 		selection, "changed",
901 		G_CALLBACK (sao_folders_treeview_selection_changed_cb), builder);
902 
903 	widget = e_builder_get_widget (builder, "sao-folders-add-button");
904 	g_return_if_fail (GTK_IS_BUTTON (widget));
905 	g_signal_connect (
906 		widget, "clicked",
907 		G_CALLBACK (sao_folders_add_button_clicked_cb), builder);
908 
909 	widget = e_builder_get_widget (builder, "sao-folders-remove-button");
910 	g_return_if_fail (GTK_IS_BUTTON (widget));
911 	gtk_widget_set_sensitive (widget, FALSE);
912 	g_signal_connect (
913 		widget, "clicked",
914 		G_CALLBACK (sao_folders_remove_button_clicked_cb), builder);
915 
916 	widget = e_builder_get_widget (builder, "sao-recipients-treeview");
917 	g_return_if_fail (GTK_IS_TREE_VIEW (widget));
918 
919 	tree_view = GTK_TREE_VIEW (widget);
920 
921 	renderer = gtk_cell_renderer_text_new ();
922 	g_object_set (G_OBJECT (renderer), "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL);
923 	g_signal_connect (renderer, "edited", G_CALLBACK (sao_recipient_edited_cb), builder);
924 	g_signal_connect (renderer, "editing-canceled", G_CALLBACK (sao_recipient_editing_canceled_cb), builder);
925 
926 	list_store = gtk_list_store_new (1, G_TYPE_STRING);
927 	gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (list_store));
928 	gtk_tree_view_insert_column_with_attributes (
929 		tree_view, -1, _("Recipient"),
930 		renderer, "text", 0, NULL);
931 	g_object_unref (list_store);
932 
933 	selection = gtk_tree_view_get_selection (tree_view);
934 	g_signal_connect (
935 		selection, "changed",
936 		G_CALLBACK (sao_recipients_treeview_selection_changed_cb), builder);
937 
938 	widget = e_builder_get_widget (builder, "sao-recipients-add-button");
939 	g_return_if_fail (GTK_IS_BUTTON (widget));
940 	g_signal_connect (
941 		widget, "clicked",
942 		G_CALLBACK (sao_recipients_add_button_clicked_cb), builder);
943 
944 	widget = e_builder_get_widget (builder, "sao-recipients-edit-button");
945 	g_return_if_fail (GTK_IS_BUTTON (widget));
946 	gtk_widget_set_sensitive (widget, FALSE);
947 	g_signal_connect (
948 		widget, "clicked",
949 		G_CALLBACK (sao_recipients_edit_button_clicked_cb), builder);
950 
951 	widget = e_builder_get_widget (builder, "sao-recipients-remove-button");
952 	g_return_if_fail (GTK_IS_BUTTON (widget));
953 	gtk_widget_set_sensitive (widget, FALSE);
954 	g_signal_connect (
955 		widget, "clicked",
956 		G_CALLBACK (sao_recipients_remove_button_clicked_cb), builder);
957 
958 	/* init view */
959 	widget = e_builder_get_widget (builder, "sao-account-treeview");
960 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
961 	sao_account_treeview_selection_changed_cb (selection, builder);
962 
963 	account_override = e_mail_backend_get_send_account_override (mail_backend);
964 	g_signal_connect_object (account_override, "changed", G_CALLBACK (sao_overrides_changed_cb), builder, 0);
965 }
966 
967 static GtkWidget *
emcp_widget_glade(EConfig * ec,EConfigItem * item,GtkWidget * parent,GtkWidget * old,gint position,gpointer data)968 emcp_widget_glade (EConfig *ec,
969                    EConfigItem *item,
970                    GtkWidget *parent,
971                    GtkWidget *old,
972                    gint position,
973                    gpointer data)
974 {
975 	EMComposerPrefs *prefs = data;
976 
977 	return e_builder_get_widget (prefs->builder, item->label);
978 }
979 
980 /* plugin meta-data */
981 static EMConfigItem emcp_items[] = {
982 
983 	{ E_CONFIG_BOOK,
984 	  (gchar *) "",
985 	  (gchar *) "composer_toplevel",
986 	  emcp_widget_glade },
987 
988 	{ E_CONFIG_PAGE,
989 	  (gchar *) "00.general",
990 	  (gchar *) "vboxComposerGeneral",
991 	  emcp_widget_glade },
992 
993 	{ E_CONFIG_SECTION,
994 	  (gchar *) "00.general/00.behavior",
995 	  (gchar *) "default-behavior-vbox",
996 	  emcp_widget_glade },
997 
998 	{ E_CONFIG_PAGE,
999 	  (gchar *) "10.signatures",
1000 	  (gchar *) "vboxSignatures",
1001 	  emcp_widget_glade },
1002 
1003 	/* signature/signatures and signature/preview parts not usable */
1004 
1005 	{ E_CONFIG_PAGE,
1006 	  (gchar *) "20.spellcheck",
1007 	  (gchar *) "vboxSpellChecking",
1008 	  emcp_widget_glade },
1009 
1010 	{ E_CONFIG_SECTION,
1011 	  (gchar *) "20.spellcheck/00.options",
1012 	  (gchar *) "spell-options-vbox",
1013 	  emcp_widget_glade },
1014 };
1015 
1016 static gboolean
em_composer_prefs_outbox_delay_setting_to_id(GValue * value,GVariant * variant,gpointer user_data)1017 em_composer_prefs_outbox_delay_setting_to_id (GValue *value,
1018 					      GVariant *variant,
1019 					      gpointer user_data)
1020 {
1021 	gint to_set = g_variant_get_int32 (variant);
1022 	gchar *str;
1023 
1024 	if (to_set < 0)
1025 		to_set = -1;
1026 	else if (to_set != 0 && to_set != 5)
1027 		to_set = 5;
1028 
1029 	str = g_strdup_printf ("%d", to_set);
1030 	g_value_set_string (value, str);
1031 	g_free (str);
1032 
1033 	return TRUE;
1034 }
1035 
1036 static GVariant *
em_composer_prefs_outbox_delay_id_to_setting(const GValue * value,const GVariantType * expected_type,gpointer user_data)1037 em_composer_prefs_outbox_delay_id_to_setting (const GValue *value,
1038 					      const GVariantType *expected_type,
1039 					      gpointer user_data)
1040 {
1041 	gint to_set;
1042 
1043 	to_set = g_value_get_string (value) ? atoi (g_value_get_string (value)) : -1;
1044 	if (to_set == 0 && g_strcmp0 (g_value_get_string (value), "0") != 0)
1045 		to_set = -1;
1046 
1047 	return g_variant_new_int32 (to_set);
1048 }
1049 
1050 static void
emcp_free(EConfig * ec,GSList * items,gpointer data)1051 emcp_free (EConfig *ec,
1052            GSList *items,
1053            gpointer data)
1054 {
1055 	/* the prefs data is freed automagically */
1056 	g_slist_free (items);
1057 }
1058 
1059 static void
em_composer_prefs_construct(EMComposerPrefs * prefs,EShell * shell)1060 em_composer_prefs_construct (EMComposerPrefs *prefs,
1061                              EShell *shell)
1062 {
1063 	GtkWidget *toplevel, *widget, *info_pixmap;
1064 	GtkWidget *container;
1065 	GSettings *settings;
1066 	ESourceRegistry *registry;
1067 	GtkTreeView *view;
1068 	GtkListStore *store;
1069 	GtkTreeSelection *selection;
1070 	GtkCellRenderer *renderer;
1071 	GtkComboBoxText *combo_text;
1072 	EMConfig *ec;
1073 	EMConfigTargetPrefs *target;
1074 	EMailBackend *mail_backend;
1075 	EMailSendAccountOverride *send_override;
1076 	GSList *l;
1077 	gint i;
1078 
1079 	registry = e_shell_get_registry (shell);
1080 
1081 	settings = e_util_ref_settings ("org.gnome.evolution.mail");
1082 
1083 	/* Make sure our custom widget classes are registered with
1084 	 * GType before we load the GtkBuilder definition file. */
1085 	g_type_ensure (E_TYPE_MAIL_JUNK_OPTIONS);
1086 
1087 	prefs->builder = gtk_builder_new ();
1088 	e_load_ui_builder_definition (prefs->builder, "mail-config.ui");
1089 
1090 	prefs->spell_checker = e_spell_checker_new ();
1091 
1092 	/** @HookPoint-EMConfig: Mail Composer Preferences
1093 	 * @Id: org.gnome.evolution.mail.composerPrefs
1094 	 * @Class: org.gnome.evolution.mail.config:1.0
1095 	 * @Target: EMConfigTargetPrefs
1096 	 *
1097 	 * The mail composer preferences settings page.
1098 	 */
1099 	ec = em_config_new ("org.gnome.evolution.mail.composerPrefs");
1100 	l = NULL;
1101 	for (i = 0; i < G_N_ELEMENTS (emcp_items); i++)
1102 		l = g_slist_prepend (l, &emcp_items[i]);
1103 	e_config_add_items ((EConfig *) ec, l, emcp_free, prefs);
1104 
1105 	/* General tab */
1106 
1107 	/* Default Behavior */
1108 
1109 	widget = e_builder_get_widget (prefs->builder, "chkSendHTML");
1110 	g_settings_bind (
1111 		settings, "composer-send-html",
1112 		widget, "active",
1113 		G_SETTINGS_BIND_DEFAULT);
1114 
1115 	widget = e_builder_get_widget (prefs->builder, "chkInheritThemeColors");
1116 	g_settings_bind (
1117 		settings, "composer-inherit-theme-colors",
1118 		widget, "active",
1119 		G_SETTINGS_BIND_DEFAULT);
1120 
1121 	widget = e_builder_get_widget (prefs->builder, "chkPromptAccelSend");
1122 	g_settings_bind (
1123 		settings, "prompt-on-accel-send",
1124 		widget, "active",
1125 		G_SETTINGS_BIND_DEFAULT);
1126 
1127 	widget = e_builder_get_widget (prefs->builder, "chkPromptEmptySubject");
1128 	g_settings_bind (
1129 		settings, "prompt-on-empty-subject",
1130 		widget, "active",
1131 		G_SETTINGS_BIND_DEFAULT);
1132 
1133 	widget = e_builder_get_widget (prefs->builder, "chkPromptBccOnly");
1134 	g_settings_bind (
1135 		settings, "prompt-on-only-bcc",
1136 		widget, "active",
1137 		G_SETTINGS_BIND_DEFAULT);
1138 
1139 	widget = e_builder_get_widget (prefs->builder, "chkPromptPrivateListReply");
1140 	g_settings_bind (
1141 		settings, "prompt-on-private-list-reply",
1142 		widget, "active",
1143 		G_SETTINGS_BIND_DEFAULT);
1144 
1145 	widget = e_builder_get_widget (prefs->builder, "chkPromptReplyManyRecips");
1146 	g_settings_bind (
1147 		settings, "prompt-on-reply-many-recips",
1148 		widget, "active",
1149 		G_SETTINGS_BIND_DEFAULT);
1150 
1151 	widget = e_builder_get_widget (prefs->builder, "chkPromptListReplyTo");
1152 	g_settings_bind (
1153 		settings, "prompt-on-list-reply-to",
1154 		widget, "active",
1155 		G_SETTINGS_BIND_DEFAULT);
1156 
1157 	widget = e_builder_get_widget (prefs->builder, "chkPromptManyToCCRecips");
1158 	g_settings_bind (
1159 		settings, "prompt-on-many-to-cc-recips",
1160 		widget, "active",
1161 		G_SETTINGS_BIND_DEFAULT);
1162 
1163 	widget = e_builder_get_widget (prefs->builder, "chkPromptSendInvalidRecip");
1164 	g_settings_bind (
1165 		settings, "prompt-on-invalid-recip",
1166 		widget, "active",
1167 		G_SETTINGS_BIND_DEFAULT);
1168 
1169 	widget = e_builder_get_widget (prefs->builder, "chkPromptComposerModeSwitch");
1170 	g_settings_bind (
1171 		settings, "prompt-on-composer-mode-switch",
1172 		widget, "active",
1173 		G_SETTINGS_BIND_DEFAULT);
1174 
1175 	widget = e_builder_get_widget (prefs->builder, "chkAutoSmileys");
1176 	g_settings_bind (
1177 		settings, "composer-magic-smileys",
1178 		widget, "active",
1179 		G_SETTINGS_BIND_DEFAULT);
1180 
1181 	widget = e_builder_get_widget (prefs->builder, "chkUnicodeSmileys");
1182 	g_settings_bind (
1183 		settings, "composer-unicode-smileys",
1184 		widget, "active",
1185 		G_SETTINGS_BIND_DEFAULT);
1186 
1187 	widget = e_builder_get_widget (prefs->builder, "chkRequestReceipt");
1188 	g_settings_bind (
1189 		settings, "composer-request-receipt",
1190 		widget, "active",
1191 		G_SETTINGS_BIND_DEFAULT);
1192 
1193 	widget = e_builder_get_widget (prefs->builder, "chkReplyStartBottom");
1194 	g_settings_bind (
1195 		settings, "composer-reply-start-bottom",
1196 		widget, "active",
1197 		G_SETTINGS_BIND_DEFAULT);
1198 
1199 	widget = e_builder_get_widget (prefs->builder, "spinWordWrapLength");
1200 	g_settings_bind (
1201 		settings, "composer-word-wrap-length",
1202 		widget, "value",
1203 		G_SETTINGS_BIND_DEFAULT);
1204 
1205 	widget = e_builder_get_widget (prefs->builder, "chkOutlookFilenames");
1206 	g_settings_bind (
1207 		settings, "composer-outlook-filenames",
1208 		widget, "active",
1209 		G_SETTINGS_BIND_DEFAULT);
1210 
1211 	widget = e_builder_get_widget (prefs->builder, "chkUseOutbox");
1212 	g_settings_bind (
1213 		settings, "composer-use-outbox",
1214 		widget, "active",
1215 		G_SETTINGS_BIND_DEFAULT);
1216 
1217 	widget = e_builder_get_widget (prefs->builder, "comboboxFlushOutbox");
1218 
1219 	combo_text = GTK_COMBO_BOX_TEXT (widget);
1220 	gtk_combo_box_text_append (combo_text, "-1", _("Keep in Outbox"));
1221 	gtk_combo_box_text_append (combo_text,  "0", _("Send immediately"));
1222 	gtk_combo_box_text_append (combo_text,  "5", _("Send after 5 minutes"));
1223 
1224 	g_settings_bind_with_mapping (
1225 		settings, "composer-delay-outbox-flush",
1226 		widget, "active-id",
1227 		G_SETTINGS_BIND_DEFAULT,
1228 		em_composer_prefs_outbox_delay_setting_to_id,
1229 		em_composer_prefs_outbox_delay_id_to_setting,
1230 		NULL, NULL);
1231 
1232 	e_binding_bind_property (
1233 		e_builder_get_widget (prefs->builder, "chkUseOutbox"), "active",
1234 		widget, "sensitive",
1235 		G_BINDING_SYNC_CREATE);
1236 
1237 	widget = e_builder_get_widget (prefs->builder, "chkIgnoreListReplyTo");
1238 	g_settings_bind (
1239 		settings, "composer-ignore-list-reply-to",
1240 		widget, "active",
1241 		G_SETTINGS_BIND_DEFAULT);
1242 
1243 	widget = e_builder_get_widget (prefs->builder, "chkGroupReplyToList");
1244 	g_settings_bind (
1245 		settings, "composer-group-reply-to-list",
1246 		widget, "active",
1247 		G_SETTINGS_BIND_DEFAULT);
1248 
1249 	widget = e_builder_get_widget (prefs->builder, "chkSignReplyIfSigned");
1250 	g_settings_bind (
1251 		settings, "composer-sign-reply-if-signed",
1252 		widget, "active",
1253 		G_SETTINGS_BIND_DEFAULT);
1254 
1255 	widget = e_builder_get_widget (prefs->builder, "chkWrapQuotedTextInReplies");
1256 	g_settings_bind (
1257 		settings, "composer-wrap-quoted-text-in-replies",
1258 		widget, "active",
1259 		G_SETTINGS_BIND_DEFAULT);
1260 
1261 	widget = e_builder_get_widget (prefs->builder, "chkSignatureInNewOnly");
1262 	g_settings_bind (
1263 		settings, "composer-signature-in-new-only",
1264 		widget, "active",
1265 		G_SETTINGS_BIND_DEFAULT);
1266 
1267 	widget = e_builder_get_widget (prefs->builder, "chkTopSignature");
1268 	g_settings_bind (
1269 		settings, "composer-top-signature",
1270 		widget, "active",
1271 		G_SETTINGS_BIND_DEFAULT);
1272 
1273 	widget = e_builder_get_widget (prefs->builder, "chkEnableSpellChecking");
1274 	g_settings_bind (
1275 		settings, "composer-inline-spelling",
1276 		widget, "active",
1277 		G_SETTINGS_BIND_DEFAULT);
1278 
1279 	widget = e_charset_combo_box_new ();
1280 	container = e_builder_get_widget (prefs->builder, "hboxComposerCharset");
1281 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
1282 	gtk_widget_show (widget);
1283 	g_settings_bind (
1284 		settings, "composer-charset",
1285 		widget, "charset",
1286 		G_SETTINGS_BIND_DEFAULT);
1287 
1288 	container = e_builder_get_widget (prefs->builder, "lblCharset");
1289 	gtk_label_set_mnemonic_widget (GTK_LABEL (container), widget);
1290 
1291 	/* Spell Checking */
1292 	widget = e_builder_get_widget (prefs->builder, "listSpellCheckLanguage");
1293 	view = GTK_TREE_VIEW (widget);
1294 	store = gtk_list_store_new (
1295 		3, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER);
1296 	prefs->language_model = GTK_TREE_MODEL (store);
1297 	gtk_tree_view_set_model (view, prefs->language_model);
1298 	renderer = gtk_cell_renderer_toggle_new ();
1299 	g_signal_connect (
1300 		renderer, "toggled",
1301 		G_CALLBACK (spell_language_toggled_cb), prefs);
1302 	gtk_tree_view_insert_column_with_attributes (
1303 		view, -1, _("Enabled"),
1304 		renderer, "active", 0, NULL);
1305 
1306 	gtk_tree_view_insert_column_with_attributes (
1307 		view, -1, _("Language(s)"),
1308 		gtk_cell_renderer_text_new (),
1309 		"text", 1, NULL);
1310 	selection = gtk_tree_view_get_selection (view);
1311 	gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
1312 	info_pixmap = e_builder_get_widget (prefs->builder, "pixmapSpellInfo");
1313 	gtk_image_set_from_icon_name (
1314 		GTK_IMAGE (info_pixmap),
1315 		"dialog-information", GTK_ICON_SIZE_BUTTON);
1316 
1317 	spell_setup (prefs);
1318 
1319 	g_signal_connect_swapped (
1320 		store, "row-changed",
1321 		G_CALLBACK (spell_language_save), prefs);
1322 
1323 	/* Forwards and Replies */
1324 	widget = e_builder_get_widget (prefs->builder, "comboboxForwardStyle");
1325 	g_settings_bind (
1326 		settings, "forward-style-name",
1327 		widget, "active-id",
1328 		G_SETTINGS_BIND_DEFAULT);
1329 
1330 	widget = e_builder_get_widget (prefs->builder, "comboboxReplyStyle");
1331 	g_settings_bind (
1332 		settings, "reply-style-name",
1333 		widget, "active-id",
1334 		G_SETTINGS_BIND_DEFAULT);
1335 
1336 	widget = e_builder_get_widget (prefs->builder, "comboboxForwardReplyAttribLanguage");
1337 	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (widget), "", _("Same as user interface"));
1338 	em_utils_add_installed_languages (GTK_COMBO_BOX_TEXT (widget));
1339 
1340 	g_settings_bind (
1341 		settings, "composer-attribution-language",
1342 		widget, "active-id",
1343 		G_SETTINGS_BIND_DEFAULT);
1344 
1345 	if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1)
1346 		gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
1347 
1348 	/* Signatures */
1349 	container = e_builder_get_widget (
1350 		prefs->builder, "signature-alignment");
1351 	widget = e_mail_signature_manager_new (registry);
1352 	gtk_container_add (GTK_CONTAINER (container), widget);
1353 	gtk_widget_show (widget);
1354 
1355 	/* The mail shell backend responds to the "window-added" signal
1356 	 * that this triggers and configures it with composer preferences. */
1357 	g_signal_connect_swapped (
1358 		widget, "editor-created",
1359 		G_CALLBACK (gtk_application_add_window), shell);
1360 
1361 	g_settings_bind (
1362 		settings, "composer-send-html",
1363 		widget, "prefer-html",
1364 		G_SETTINGS_BIND_GET);
1365 
1366 	/* Send Account override */
1367 	mail_backend = E_MAIL_BACKEND (e_shell_get_backend_by_name (shell, "mail"));
1368 	g_return_if_fail (mail_backend != NULL);
1369 
1370 	send_override = e_mail_backend_get_send_account_override (mail_backend);
1371 	g_object_set_data_full (
1372 		G_OBJECT (prefs->builder), MAIL_SEND_ACCOUNT_OVERRIDE_KEY,
1373 		g_object_ref (send_override), g_object_unref);
1374 
1375 	send_account_override_setup (prefs->builder, mail_backend, registry);
1376 
1377 	widget = e_builder_get_widget (prefs->builder, "sao-prefer-folder-check");
1378 	e_binding_bind_property (
1379 		send_override, "prefer-folder",
1380 		widget, "active",
1381 		G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
1382 
1383 	/* get our toplevel widget */
1384 	target = em_config_target_new_prefs (ec);
1385 	e_config_set_target ((EConfig *) ec, (EConfigTarget *) target);
1386 	toplevel = e_config_create_widget ((EConfig *) ec);
1387 	gtk_container_add (GTK_CONTAINER (prefs), toplevel);
1388 
1389 	g_object_unref (settings);
1390 }
1391 
1392 GtkWidget *
em_composer_prefs_new(EPreferencesWindow * window)1393 em_composer_prefs_new (EPreferencesWindow *window)
1394 {
1395 	EShell *shell;
1396 	EMComposerPrefs *prefs;
1397 
1398 	shell = e_preferences_window_get_shell (window);
1399 	g_return_val_if_fail (E_IS_SHELL (shell), NULL);
1400 
1401 	prefs = g_object_new (EM_TYPE_COMPOSER_PREFS, NULL);
1402 	em_composer_prefs_construct (prefs, shell);
1403 
1404 	return GTK_WIDGET (prefs);
1405 }
1406