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