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.
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
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/>.
16 * Jeffrey Stedfast <fejj@ximian.com>
18 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
22 #include "evolution-config.h"
24 #include "em-composer-prefs.h"
27 #include <sys/types.h>
32 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <composer/e-msg-composer.h>
37 #include <shell/e-shell-utils.h>
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/e-mail-backend.h>
45 #include <mail/e-mail-junk-options.h>
46 #include <mail/e-mail-ui-session.h>
54 composer_prefs_dispose (GObject
*object
)
56 EMComposerPrefs
*prefs
= (EMComposerPrefs
*) object
;
58 if (prefs
->builder
!= NULL
) {
59 g_object_unref (prefs
->builder
);
60 prefs
->builder
= NULL
;
63 /* Chain up to parent's dispose() method. */
64 G_OBJECT_CLASS (em_composer_prefs_parent_class
)->dispose (object
);
68 em_composer_prefs_class_init (EMComposerPrefsClass
*class)
70 GObjectClass
*object_class
;
72 object_class
= G_OBJECT_CLASS (class);
73 object_class
->dispose
= composer_prefs_dispose
;
77 em_composer_prefs_init (EMComposerPrefs
*prefs
)
79 gtk_orientable_set_orientation (GTK_ORIENTABLE (prefs
), GTK_ORIENTATION_VERTICAL
);
83 spell_language_toggled_cb (GtkCellRendererToggle
*renderer
,
84 const gchar
*path_string
,
85 EMComposerPrefs
*prefs
)
93 model
= prefs
->language_model
;
95 /* Convert the path string to a tree iterator. */
96 path
= gtk_tree_path_new_from_string (path_string
);
97 valid
= gtk_tree_model_get_iter (model
, &iter
, path
);
98 gtk_tree_path_free (path
);
99 g_return_if_fail (valid
);
101 /* Toggle the active state. */
102 gtk_tree_model_get (model
, &iter
, 0, &active
, -1);
103 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
, 0, !active
, -1);
107 spell_language_save (EMComposerPrefs
*prefs
)
109 GList
*spell_languages
= NULL
;
114 model
= prefs
->language_model
;
116 /* Build a list of active spell languages. */
117 valid
= gtk_tree_model_get_iter_first (model
, &iter
);
119 ESpellDictionary
*language
;
123 model
, &iter
, 0, &active
, 2, &language
, -1);
126 spell_languages
= g_list_prepend (
127 spell_languages
, (gpointer
) language
);
129 valid
= gtk_tree_model_iter_next (model
, &iter
);
131 spell_languages
= g_list_reverse (spell_languages
);
133 /* Update the GSettings value. */
134 e_save_spell_languages (spell_languages
);
136 g_list_free (spell_languages
);
140 spell_setup (EMComposerPrefs
*prefs
)
142 GList
*list
= NULL
, *link
;
145 store
= GTK_LIST_STORE (prefs
->language_model
);
146 list
= e_spell_checker_list_available_dicts (prefs
->spell_checker
);
148 /* Populate the GtkListStore. */
149 for (link
= list
; link
!= NULL
; link
= g_list_next (link
)) {
150 ESpellDictionary
*dictionary
;
151 GtkTreeIter tree_iter
;
156 dictionary
= E_SPELL_DICTIONARY (link
->data
);
157 name
= e_spell_dictionary_get_name (dictionary
);
158 code
= e_spell_dictionary_get_code (dictionary
);
160 active
= e_spell_checker_get_language_active (
161 prefs
->spell_checker
, code
);
163 gtk_list_store_append (store
, &tree_iter
);
167 0, active
, 1, name
, 2, dictionary
, -1);
173 #define MAIL_SEND_ACCOUNT_OVERRIDE_KEY "sao-mail-send-account-override"
174 #define MAIL_CAMEL_SESSION_KEY "sao-mail-camel-session"
177 sao_dup_account_uid (GtkBuilder
*builder
,
178 gchar
**out_alias_name
,
179 gchar
**out_alias_address
)
182 GtkTreeView
*tree_view
;
183 GtkTreeSelection
*selection
;
186 gchar
*account_uid
= NULL
;
188 widget
= e_builder_get_widget (builder
, "sao-account-treeview");
189 g_return_val_if_fail (GTK_IS_TREE_VIEW (widget
), NULL
);
191 tree_view
= GTK_TREE_VIEW (widget
);
192 selection
= gtk_tree_view_get_selection (tree_view
);
194 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
197 gtk_tree_model_get (model
, &iter
,
198 E_MAIL_IDENTITY_COMBO_BOX_COLUMN_UID
, &account_uid
,
199 E_MAIL_IDENTITY_COMBO_BOX_COLUMN_NAME
, out_alias_name
,
200 E_MAIL_IDENTITY_COMBO_BOX_COLUMN_ADDRESS
, out_alias_address
,
207 sao_fill_overrides (GtkBuilder
*builder
,
208 const gchar
*tree_view_name
,
212 CamelSession
*session
= NULL
;
214 GtkListStore
*list_store
;
218 widget
= e_builder_get_widget (builder
, tree_view_name
);
219 g_return_if_fail (GTK_IS_TREE_VIEW (widget
));
221 list_store
= GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (widget
)));
222 g_return_if_fail (list_store
!= NULL
);
224 gtk_list_store_clear (list_store
);
227 session
= g_object_get_data (G_OBJECT (builder
), MAIL_CAMEL_SESSION_KEY
);
229 for (oiter
= overrides
; oiter
; oiter
= g_list_next (oiter
)) {
230 const gchar
*value
= oiter
->data
;
231 gchar
*markup
= NULL
;
233 if (!value
|| !*value
)
237 markup
= e_mail_folder_uri_to_markup (session
, value
, NULL
);
242 gtk_list_store_append (list_store
, &titer
);
245 gtk_list_store_set (list_store
, &titer
, 0, markup
, 1, value
, -1);
247 gtk_list_store_set (list_store
, &titer
, 0, value
, -1);
255 sao_account_treeview_selection_changed_cb (GtkTreeSelection
*selection
,
260 gboolean enable
= FALSE
;
262 g_return_if_fail (GTK_IS_TREE_SELECTION (selection
));
263 g_return_if_fail (GTK_IS_BUILDER (builder
));
265 widget
= e_builder_get_widget (builder
, "sao-folders-treeview");
266 g_return_if_fail (GTK_IS_WIDGET (widget
));
267 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (widget
));
268 gtk_list_store_clear (GTK_LIST_STORE (model
));
270 widget
= e_builder_get_widget (builder
, "sao-recipients-treeview");
271 g_return_if_fail (GTK_IS_WIDGET (widget
));
272 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (widget
));
273 gtk_list_store_clear (GTK_LIST_STORE (model
));
275 if (gtk_tree_selection_get_selected (selection
, NULL
, NULL
)) {
276 gchar
*account_uid
, *alias_name
= NULL
, *alias_address
= NULL
;
278 account_uid
= sao_dup_account_uid (builder
, &alias_name
, &alias_address
);
280 GList
*folder_overrides
= NULL
;
281 GList
*recipient_overrides
= NULL
;
285 e_mail_send_account_override_list_for_account (
288 MAIL_SEND_ACCOUNT_OVERRIDE_KEY
),
289 account_uid
, alias_name
, alias_address
, &folder_overrides
, &recipient_overrides
);
292 builder
, "sao-folders-treeview",
293 folder_overrides
, TRUE
);
295 builder
, "sao-recipients-treeview",
296 recipient_overrides
, FALSE
);
298 g_list_free_full (folder_overrides
, g_free
);
299 g_list_free_full (recipient_overrides
, g_free
);
300 g_free (account_uid
);
302 g_free (alias_address
);
306 widget
= e_builder_get_widget (builder
, "sao-folders-frame");
307 g_return_if_fail (GTK_IS_WIDGET (widget
));
308 gtk_widget_set_sensitive (widget
, enable
);
310 widget
= e_builder_get_widget (builder
, "sao-recipients-frame");
311 g_return_if_fail (GTK_IS_WIDGET (widget
));
312 gtk_widget_set_sensitive (widget
, enable
);
316 sao_account_row_changed_cb (GtkTreeModel
*model
,
321 GtkTreeSelection
*selection
;
324 if (gtk_tree_model_iter_n_children (model
, NULL
) != 1)
327 widget
= e_builder_get_widget (builder
, "sao-account-treeview");
328 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (widget
));
330 if (!gtk_tree_selection_get_selected (selection
, NULL
, NULL
))
331 gtk_tree_selection_select_iter (selection
, iter
);
335 sao_overrides_changed_cb (EMailSendAccountOverride
*account_override
,
339 GtkTreeSelection
*selection
;
341 g_return_if_fail (GTK_IS_BUILDER (builder
));
343 widget
= e_builder_get_widget (builder
, "sao-account-treeview");
344 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (widget
));
346 sao_account_treeview_selection_changed_cb (selection
, builder
);
350 sao_block_changed_handler (GtkBuilder
*builder
)
352 GObject
*account_override
;
354 g_return_if_fail (GTK_IS_BUILDER (builder
));
356 account_override
= g_object_get_data (G_OBJECT (builder
), MAIL_SEND_ACCOUNT_OVERRIDE_KEY
),
357 g_signal_handlers_block_by_func (account_override
, sao_overrides_changed_cb
, builder
);
361 sao_unblock_changed_handler (GtkBuilder
*builder
)
363 GObject
*account_override
;
365 g_return_if_fail (GTK_IS_BUILDER (builder
));
367 account_override
= g_object_get_data (G_OBJECT (builder
), MAIL_SEND_ACCOUNT_OVERRIDE_KEY
),
368 g_signal_handlers_unblock_by_func (account_override
, sao_overrides_changed_cb
, builder
);
372 sao_folders_treeview_selection_changed_cb (GtkTreeSelection
*selection
,
378 g_return_if_fail (GTK_IS_TREE_SELECTION (selection
));
379 g_return_if_fail (GTK_IS_BUILDER (builder
));
381 nselected
= gtk_tree_selection_count_selected_rows (selection
);
383 widget
= e_builder_get_widget (builder
, "sao-folders-remove-button");
384 g_return_if_fail (GTK_IS_WIDGET (widget
));
385 gtk_widget_set_sensitive (widget
, nselected
> 0);
389 sao_folders_add_button_clicked_cb (GtkButton
*button
,
392 GtkTreeSelection
*selection
;
393 GtkTreeView
*tree_view
;
397 EMFolderSelector
*selector
;
398 EMFolderTree
*folder_tree
;
401 gchar
*account_uid
, *alias_name
= NULL
, *alias_address
= NULL
;
403 g_return_if_fail (GTK_IS_BUTTON (button
));
404 g_return_if_fail (GTK_IS_BUILDER (builder
));
406 account_uid
= sao_dup_account_uid (builder
, &alias_name
, &alias_address
);
407 g_return_if_fail (account_uid
!= NULL
);
409 widget
= e_builder_get_widget (builder
, "sao-folders-treeview");
410 g_return_if_fail (GTK_IS_TREE_VIEW (widget
));
411 tree_view
= GTK_TREE_VIEW (widget
);
413 window
= GTK_WINDOW (gtk_widget_get_toplevel (widget
));
415 dialog
= em_folder_selector_new (
416 window
, em_folder_tree_model_get_default ());
418 gtk_window_set_title (
419 GTK_WINDOW (dialog
), _("Select Folder to Add"));
421 selector
= EM_FOLDER_SELECTOR (dialog
);
422 em_folder_selector_set_default_button_label (selector
, _("_Add"));
424 folder_tree
= em_folder_selector_get_folder_tree (selector
);
426 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_tree
));
427 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_MULTIPLE
);
429 em_folder_tree_set_excluded (folder_tree
, EMFT_EXCLUDE_NOSELECT
);
431 if (gtk_dialog_run (GTK_DIALOG (dialog
)) == GTK_RESPONSE_OK
) {
432 GList
*list
, *folder_uris
;
434 model
= gtk_tree_view_get_model (tree_view
);
436 folder_uris
= em_folder_tree_get_selected_uris (folder_tree
);
438 for (list
= folder_uris
; list
; list
= g_list_next (list
)) {
439 const gchar
*uri
= list
->data
;
442 gboolean found
= FALSE
;
444 if (gtk_tree_model_get_iter_first (model
, &iter
)) {
446 gchar
*old_uri
= NULL
;
448 gtk_tree_model_get (model
, &iter
, 1, &old_uri
, -1);
450 found
= g_strcmp0 (uri
, old_uri
) == 0;
453 } while (!found
&& gtk_tree_model_iter_next (model
, &iter
));
457 EMailSendAccountOverride
*account_override
;
458 GtkListStore
*list_store
;
459 CamelSession
*session
;
462 list_store
= GTK_LIST_STORE (model
);
463 session
= g_object_get_data (G_OBJECT (builder
), MAIL_CAMEL_SESSION_KEY
);
464 markup
= e_mail_folder_uri_to_markup (session
, uri
, NULL
);
466 gtk_list_store_append (list_store
, &iter
);
467 gtk_list_store_set (list_store
, &iter
, 0, markup
, 1, uri
, -1);
471 sao_block_changed_handler (builder
);
473 account_override
= g_object_get_data (G_OBJECT (builder
), MAIL_SEND_ACCOUNT_OVERRIDE_KEY
);
474 e_mail_send_account_override_set_for_folder (account_override
, uri
, account_uid
, alias_name
, alias_address
);
476 sao_unblock_changed_handler (builder
);
480 selection
= gtk_tree_view_get_selection (tree_view
);
482 gtk_tree_selection_unselect_all (selection
);
483 gtk_tree_selection_select_iter (selection
, &iter
);
488 g_list_free_full (folder_uris
, g_free
);
491 gtk_widget_destroy (dialog
);
492 g_free (account_uid
);
494 g_free (alias_address
);
498 sao_folders_remove_button_clicked_cb (GtkButton
*button
,
501 EMailSendAccountOverride
*account_override
;
502 GtkTreeSelection
*selection
;
503 GtkTreeView
*tree_view
;
507 GList
*selected
, *siter
;
509 g_return_if_fail (GTK_IS_BUTTON (button
));
510 g_return_if_fail (GTK_IS_BUILDER (builder
));
512 widget
= e_builder_get_widget (builder
, "sao-folders-treeview");
513 g_return_if_fail (GTK_IS_TREE_VIEW (widget
));
514 tree_view
= GTK_TREE_VIEW (widget
);
515 selection
= gtk_tree_view_get_selection (tree_view
);
516 model
= gtk_tree_view_get_model (tree_view
);
518 sao_block_changed_handler (builder
);
520 account_override
= g_object_get_data (G_OBJECT (builder
), MAIL_SEND_ACCOUNT_OVERRIDE_KEY
);
521 e_mail_send_account_override_freeze_save (account_override
);
523 selected
= gtk_tree_selection_get_selected_rows (selection
, &model
);
524 selected
= g_list_reverse (selected
);
526 for (siter
= selected
; siter
; siter
= g_list_next (siter
)) {
529 if (!gtk_tree_model_get_iter (model
, &iter
, siter
->data
))
532 gtk_tree_model_get (model
, &iter
, 1, &uri
, -1);
535 e_mail_send_account_override_remove_for_folder (account_override
, uri
);
537 gtk_list_store_remove (GTK_LIST_STORE (model
), &iter
);
541 e_mail_send_account_override_thaw_save (account_override
);
542 sao_unblock_changed_handler (builder
);
544 g_list_free_full (selected
, (GDestroyNotify
) gtk_tree_path_free
);
548 sao_recipients_treeview_selection_changed_cb (GtkTreeSelection
*selection
,
554 g_return_if_fail (GTK_IS_TREE_SELECTION (selection
));
555 g_return_if_fail (GTK_IS_BUILDER (builder
));
557 nselected
= gtk_tree_selection_count_selected_rows (selection
);
559 widget
= e_builder_get_widget (builder
, "sao-recipients-edit-button");
560 g_return_if_fail (GTK_IS_WIDGET (widget
));
561 gtk_widget_set_sensitive (widget
, nselected
== 1);
563 widget
= e_builder_get_widget (builder
, "sao-recipients-remove-button");
564 g_return_if_fail (GTK_IS_WIDGET (widget
));
565 gtk_widget_set_sensitive (widget
, nselected
> 0);
569 sao_recipient_edited_cb (GtkCellRendererText
*renderer
,
570 const gchar
*path_str
,
571 const gchar
*new_text
,
574 EMailSendAccountOverride
*account_override
;
578 gchar
*text
, *old_text
= NULL
, *account_uid
, *alias_name
= NULL
, *alias_address
= NULL
;
581 g_return_if_fail (path_str
!= NULL
);
582 g_return_if_fail (GTK_IS_BUILDER (builder
));
584 widget
= e_builder_get_widget (builder
, "sao-recipients-treeview");
585 g_return_if_fail (GTK_IS_TREE_VIEW (widget
));
587 path
= gtk_tree_path_new_from_string (path_str
);
588 g_return_if_fail (path
!= NULL
);
590 account_uid
= sao_dup_account_uid (builder
, &alias_name
, &alias_address
);
591 g_return_if_fail (account_uid
!= NULL
);
593 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (widget
));
594 g_return_if_fail (gtk_tree_model_get_iter (model
, &iter
, path
));
595 gtk_tree_path_free (path
);
597 gtk_tree_model_get (model
, &iter
, 0, &old_text
, -1);
599 sao_block_changed_handler (builder
);
601 account_override
= g_object_get_data (G_OBJECT (builder
), MAIL_SEND_ACCOUNT_OVERRIDE_KEY
);
603 text
= g_strdup (new_text
);
607 if (old_text
&& *old_text
)
608 e_mail_send_account_override_remove_for_recipient (account_override
, old_text
);
610 if (!text
|| !*text
) {
611 gtk_list_store_remove (GTK_LIST_STORE (model
), &iter
);
613 GtkTreeIter new_iter
= iter
;
614 gboolean is_new
= TRUE
;
616 if (gtk_tree_model_get_iter_first (model
, &iter
)) {
618 gchar
*old_recipient
= NULL
;
620 gtk_tree_model_get (model
, &iter
, 0, &old_recipient
, -1);
622 is_new
= !old_recipient
|| e_util_utf8_strcasecmp (text
, old_recipient
) != 0;
624 g_free (old_recipient
);
625 } while (is_new
&& gtk_tree_model_iter_next (model
, &iter
));
629 gtk_list_store_set (GTK_LIST_STORE (model
), &new_iter
, 0, text
, -1);
630 e_mail_send_account_override_set_for_recipient (account_override
, text
, account_uid
, alias_name
, alias_address
);
632 GtkTreeSelection
*selection
;
633 GtkTreePath
*path1
, *path2
;
635 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (widget
));
637 path1
= gtk_tree_model_get_path (model
, &iter
);
638 path2
= gtk_tree_model_get_path (model
, &new_iter
);
640 if (!path1
|| !path2
|| gtk_tree_path_compare (path1
, path2
) != 0)
641 gtk_list_store_remove (GTK_LIST_STORE (model
), &new_iter
);
643 gtk_tree_path_free (path1
);
644 gtk_tree_path_free (path2
);
646 gtk_tree_selection_unselect_all (selection
);
647 gtk_tree_selection_select_iter (selection
, &iter
);
651 sao_unblock_changed_handler (builder
);
653 g_free (account_uid
);
655 g_free (alias_address
);
661 sao_recipient_editing_canceled_cb (GtkCellRenderer
*renderer
,
668 g_return_if_fail (GTK_IS_BUILDER (builder
));
670 widget
= e_builder_get_widget (builder
, "sao-recipients-treeview");
671 g_return_if_fail (GTK_IS_TREE_VIEW (widget
));
673 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (widget
));
675 if (gtk_tree_model_get_iter_first (model
, &iter
)) {
677 gchar
*old_recipient
= NULL
;
679 gtk_tree_model_get (model
, &iter
, 0, &old_recipient
, -1);
681 if (!old_recipient
|| !*old_recipient
) {
682 gtk_list_store_remove (GTK_LIST_STORE (model
), &iter
);
683 g_free (old_recipient
);
687 g_free (old_recipient
);
688 } while (gtk_tree_model_iter_next (model
, &iter
));
693 sao_recipients_add_button_clicked_cb (GtkButton
*button
,
696 GtkTreeView
*tree_view
;
697 GtkTreeViewColumn
*column
;
698 GtkTreeSelection
*selection
;
705 g_return_if_fail (GTK_IS_BUTTON (button
));
706 g_return_if_fail (GTK_IS_BUILDER (builder
));
708 widget
= e_builder_get_widget (builder
, "sao-recipients-treeview");
709 g_return_if_fail (GTK_IS_TREE_VIEW (widget
));
711 tree_view
= GTK_TREE_VIEW (widget
);
712 model
= gtk_tree_view_get_model (tree_view
);
713 selection
= gtk_tree_view_get_selection (tree_view
);
715 gtk_list_store_append (GTK_LIST_STORE (model
), &iter
);
717 gtk_tree_selection_unselect_all (selection
);
718 gtk_tree_selection_select_iter (selection
, &iter
);
720 column
= gtk_tree_view_get_column (tree_view
, 0);
721 g_return_if_fail (column
!= NULL
);
723 cells
= gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column
));
724 g_return_if_fail (cells
!= NULL
);
726 path
= gtk_tree_model_get_path (model
, &iter
);
732 g_object_set (cells
->data
, "editable", TRUE
, NULL
);
733 gtk_tree_view_set_cursor_on_cell (
734 tree_view
, path
, column
, cells
->data
, TRUE
);
735 g_object_set (cells
->data
, "editable", FALSE
, NULL
);
737 gtk_tree_path_free (path
);
742 sao_recipients_edit_button_clicked_cb (GtkButton
*button
,
745 GtkTreeView
*tree_view
;
746 GtkTreeViewColumn
*column
;
747 GtkTreeSelection
*selection
;
750 GList
*cells
, *selected
;
752 g_return_if_fail (GTK_IS_BUTTON (button
));
753 g_return_if_fail (GTK_IS_BUILDER (builder
));
755 widget
= e_builder_get_widget (builder
, "sao-recipients-treeview");
756 g_return_if_fail (GTK_IS_TREE_VIEW (widget
));
758 tree_view
= GTK_TREE_VIEW (widget
);
759 selection
= gtk_tree_view_get_selection (tree_view
);
761 g_return_if_fail (gtk_tree_selection_count_selected_rows (selection
) == 1);
763 selected
= gtk_tree_selection_get_selected_rows (selection
, NULL
);
764 g_return_if_fail (selected
&& selected
->next
== NULL
);
766 path
= selected
->data
;
767 /* 'path' is freed later in the function */
768 g_list_free (selected
);
770 column
= gtk_tree_view_get_column (tree_view
, 0);
771 g_return_if_fail (column
!= NULL
);
773 cells
= gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column
));
774 g_return_if_fail (cells
!= NULL
);
776 g_object_set (cells
->data
, "editable", TRUE
, NULL
);
777 gtk_tree_view_set_cursor_on_cell (
778 tree_view
, path
, column
, cells
->data
, TRUE
);
779 g_object_set (cells
->data
, "editable", FALSE
, NULL
);
781 gtk_tree_path_free (path
);
786 sao_recipients_remove_button_clicked_cb (GtkButton
*button
,
789 EMailSendAccountOverride
*account_override
;
790 GtkTreeSelection
*selection
;
791 GtkTreeView
*tree_view
;
795 GList
*selected
, *siter
;
797 g_return_if_fail (GTK_IS_BUTTON (button
));
798 g_return_if_fail (GTK_IS_BUILDER (builder
));
800 widget
= e_builder_get_widget (builder
, "sao-recipients-treeview");
801 g_return_if_fail (GTK_IS_TREE_VIEW (widget
));
802 tree_view
= GTK_TREE_VIEW (widget
);
803 selection
= gtk_tree_view_get_selection (tree_view
);
804 model
= gtk_tree_view_get_model (tree_view
);
806 sao_block_changed_handler (builder
);
808 account_override
= g_object_get_data (G_OBJECT (builder
), MAIL_SEND_ACCOUNT_OVERRIDE_KEY
);
809 e_mail_send_account_override_freeze_save (account_override
);
811 selected
= gtk_tree_selection_get_selected_rows (selection
, &model
);
812 selected
= g_list_reverse (selected
);
814 for (siter
= selected
; siter
; siter
= g_list_next (siter
)) {
815 gchar
*recipient
= NULL
;
817 if (!gtk_tree_model_get_iter (model
, &iter
, siter
->data
))
820 gtk_tree_model_get (model
, &iter
, 0, &recipient
, -1);
822 if (recipient
&& *recipient
)
823 e_mail_send_account_override_remove_for_recipient (account_override
, recipient
);
825 gtk_list_store_remove (GTK_LIST_STORE (model
), &iter
);
829 e_mail_send_account_override_thaw_save (account_override
);
830 sao_unblock_changed_handler (builder
);
832 g_list_free_full (selected
, (GDestroyNotify
) gtk_tree_path_free
);
836 send_account_override_setup (GtkBuilder
*builder
,
837 EMailBackend
*mail_backend
,
838 ESourceRegistry
*registry
)
840 EMailIdentityComboBox
*identity_combo_box
;
841 EMailSendAccountOverride
*account_override
;
842 GtkTreeView
*tree_view
;
843 GtkTreeSelection
*selection
;
845 GtkListStore
*list_store
;
846 GtkCellRenderer
*renderer
;
849 g_return_if_fail (GTK_IS_BUILDER (builder
));
850 g_return_if_fail (E_IS_MAIL_BACKEND (mail_backend
));
851 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry
));
853 /* use its model to avoid code duplication */
854 widget
= e_mail_identity_combo_box_new (registry
);
855 e_mail_identity_combo_box_set_allow_aliases (E_MAIL_IDENTITY_COMBO_BOX (widget
), TRUE
);
857 identity_combo_box
= g_object_ref_sink (widget
);
859 widget
= e_builder_get_widget (builder
, "sao-account-treeview");
860 g_return_if_fail (GTK_IS_TREE_VIEW (widget
));
862 tree_view
= GTK_TREE_VIEW (widget
);
864 g_object_set_data_full (
865 G_OBJECT (tree_view
), "identity-combo-box",
866 identity_combo_box
, (GDestroyNotify
) gtk_widget_destroy
);
867 g_object_set_data_full (
868 G_OBJECT (builder
), MAIL_CAMEL_SESSION_KEY
,
869 g_object_ref (e_mail_backend_get_session (mail_backend
)), g_object_unref
);
871 model
= gtk_combo_box_get_model (GTK_COMBO_BOX (identity_combo_box
));
873 gtk_tree_view_set_model (tree_view
, model
);
874 gtk_tree_view_insert_column_with_attributes (
875 tree_view
, -1, _("Account"),
876 gtk_cell_renderer_text_new (),
879 selection
= gtk_tree_view_get_selection (tree_view
);
881 selection
, "changed",
882 G_CALLBACK (sao_account_treeview_selection_changed_cb
), builder
);
884 g_signal_connect (model
, "row-changed", G_CALLBACK (sao_account_row_changed_cb
), builder
);
886 widget
= e_builder_get_widget (builder
, "sao-folders-treeview");
887 g_return_if_fail (GTK_IS_TREE_VIEW (widget
));
889 tree_view
= GTK_TREE_VIEW (widget
);
891 /* markup, folder-uri */
892 list_store
= gtk_list_store_new (2, G_TYPE_STRING
, G_TYPE_STRING
);
893 gtk_tree_view_set_model (tree_view
, GTK_TREE_MODEL (list_store
));
894 gtk_tree_view_insert_column_with_attributes (
895 tree_view
, -1, _("Folder"),
896 gtk_cell_renderer_text_new (),
898 g_object_unref (list_store
);
900 selection
= gtk_tree_view_get_selection (tree_view
);
902 selection
, "changed",
903 G_CALLBACK (sao_folders_treeview_selection_changed_cb
), builder
);
905 widget
= e_builder_get_widget (builder
, "sao-folders-add-button");
906 g_return_if_fail (GTK_IS_BUTTON (widget
));
909 G_CALLBACK (sao_folders_add_button_clicked_cb
), builder
);
911 widget
= e_builder_get_widget (builder
, "sao-folders-remove-button");
912 g_return_if_fail (GTK_IS_BUTTON (widget
));
913 gtk_widget_set_sensitive (widget
, FALSE
);
916 G_CALLBACK (sao_folders_remove_button_clicked_cb
), builder
);
918 widget
= e_builder_get_widget (builder
, "sao-recipients-treeview");
919 g_return_if_fail (GTK_IS_TREE_VIEW (widget
));
921 tree_view
= GTK_TREE_VIEW (widget
);
923 renderer
= gtk_cell_renderer_text_new ();
924 g_object_set (G_OBJECT (renderer
), "mode", GTK_CELL_RENDERER_MODE_EDITABLE
, NULL
);
925 g_signal_connect (renderer
, "edited", G_CALLBACK (sao_recipient_edited_cb
), builder
);
926 g_signal_connect (renderer
, "editing-canceled", G_CALLBACK (sao_recipient_editing_canceled_cb
), builder
);
928 list_store
= gtk_list_store_new (1, G_TYPE_STRING
);
929 gtk_tree_view_set_model (tree_view
, GTK_TREE_MODEL (list_store
));
930 gtk_tree_view_insert_column_with_attributes (
931 tree_view
, -1, _("Recipient"),
932 renderer
, "text", 0, NULL
);
933 g_object_unref (list_store
);
935 selection
= gtk_tree_view_get_selection (tree_view
);
937 selection
, "changed",
938 G_CALLBACK (sao_recipients_treeview_selection_changed_cb
), builder
);
940 widget
= e_builder_get_widget (builder
, "sao-recipients-add-button");
941 g_return_if_fail (GTK_IS_BUTTON (widget
));
944 G_CALLBACK (sao_recipients_add_button_clicked_cb
), builder
);
946 widget
= e_builder_get_widget (builder
, "sao-recipients-edit-button");
947 g_return_if_fail (GTK_IS_BUTTON (widget
));
948 gtk_widget_set_sensitive (widget
, FALSE
);
951 G_CALLBACK (sao_recipients_edit_button_clicked_cb
), builder
);
953 widget
= e_builder_get_widget (builder
, "sao-recipients-remove-button");
954 g_return_if_fail (GTK_IS_BUTTON (widget
));
955 gtk_widget_set_sensitive (widget
, FALSE
);
958 G_CALLBACK (sao_recipients_remove_button_clicked_cb
), builder
);
961 widget
= e_builder_get_widget (builder
, "sao-account-treeview");
962 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (widget
));
963 sao_account_treeview_selection_changed_cb (selection
, builder
);
965 account_override
= e_mail_backend_get_send_account_override (mail_backend
);
966 g_signal_connect_object (account_override
, "changed", G_CALLBACK (sao_overrides_changed_cb
), builder
, 0);
970 emcp_widget_glade (EConfig
*ec
,
977 EMComposerPrefs
*prefs
= data
;
979 return e_builder_get_widget (prefs
->builder
, item
->label
);
982 /* plugin meta-data */
983 static EMConfigItem emcp_items
[] = {
987 (gchar
*) "composer_toplevel",
991 (gchar
*) "00.general",
992 (gchar
*) "vboxComposerGeneral",
996 (gchar
*) "00.general/00.behavior",
997 (gchar
*) "default-behavior-vbox",
1001 (gchar
*) "10.signatures",
1002 (gchar
*) "vboxSignatures",
1003 emcp_widget_glade
},
1005 /* signature/signatures and signature/preview parts not usable */
1008 (gchar
*) "20.spellcheck",
1009 (gchar
*) "vboxSpellChecking",
1010 emcp_widget_glade
},
1013 (gchar
*) "20.spellcheck/00.options",
1014 (gchar
*) "spell-options-vbox",
1015 emcp_widget_glade
},
1019 em_composer_prefs_outbox_delay_setting_to_id (GValue
*value
,
1023 gint to_set
= g_variant_get_int32 (variant
);
1028 else if (to_set
!= 0 && to_set
!= 5)
1031 str
= g_strdup_printf ("%d", to_set
);
1032 g_value_set_string (value
, str
);
1039 em_composer_prefs_outbox_delay_id_to_setting (const GValue
*value
,
1040 const GVariantType
*expected_type
,
1045 to_set
= g_value_get_string (value
) ? atoi (g_value_get_string (value
)) : -1;
1046 if (to_set
== 0 && g_strcmp0 (g_value_get_string (value
), "0") != 0)
1049 return g_variant_new_int32 (to_set
);
1053 emcp_free (EConfig
*ec
,
1057 /* the prefs data is freed automagically */
1058 g_slist_free (items
);
1062 em_composer_prefs_construct (EMComposerPrefs
*prefs
,
1065 GtkWidget
*toplevel
, *widget
, *info_pixmap
;
1066 GtkWidget
*container
;
1067 GSettings
*settings
;
1068 ESourceRegistry
*registry
;
1070 GtkListStore
*store
;
1071 GtkTreeSelection
*selection
;
1072 GtkCellRenderer
*renderer
;
1073 GtkComboBoxText
*combo_text
;
1075 EMConfigTargetPrefs
*target
;
1076 EMailBackend
*mail_backend
;
1077 EMailSendAccountOverride
*send_override
;
1081 registry
= e_shell_get_registry (shell
);
1083 settings
= e_util_ref_settings ("org.gnome.evolution.mail");
1085 /* Make sure our custom widget classes are registered with
1086 * GType before we load the GtkBuilder definition file. */
1087 g_type_ensure (E_TYPE_MAIL_JUNK_OPTIONS
);
1089 prefs
->builder
= gtk_builder_new ();
1090 e_load_ui_builder_definition (prefs
->builder
, "mail-config.ui");
1092 prefs
->spell_checker
= e_spell_checker_new ();
1094 /** @HookPoint-EMConfig: Mail Composer Preferences
1095 * @Id: org.gnome.evolution.mail.composerPrefs
1096 * @Class: org.gnome.evolution.mail.config:1.0
1097 * @Target: EMConfigTargetPrefs
1099 * The mail composer preferences settings page.
1101 ec
= em_config_new ("org.gnome.evolution.mail.composerPrefs");
1103 for (i
= 0; i
< G_N_ELEMENTS (emcp_items
); i
++)
1104 l
= g_slist_prepend (l
, &emcp_items
[i
]);
1105 e_config_add_items ((EConfig
*) ec
, l
, emcp_free
, prefs
);
1109 /* Default Behavior */
1111 widget
= e_builder_get_widget (prefs
->builder
, "chkSendHTML");
1113 settings
, "composer-send-html",
1115 G_SETTINGS_BIND_DEFAULT
);
1117 widget
= e_builder_get_widget (prefs
->builder
, "chkInheritThemeColors");
1119 settings
, "composer-inherit-theme-colors",
1121 G_SETTINGS_BIND_DEFAULT
);
1123 widget
= e_builder_get_widget (prefs
->builder
, "chkPromptAccelSend");
1125 settings
, "prompt-on-accel-send",
1127 G_SETTINGS_BIND_DEFAULT
);
1129 widget
= e_builder_get_widget (prefs
->builder
, "chkPromptEmptySubject");
1131 settings
, "prompt-on-empty-subject",
1133 G_SETTINGS_BIND_DEFAULT
);
1135 widget
= e_builder_get_widget (prefs
->builder
, "chkPromptBccOnly");
1137 settings
, "prompt-on-only-bcc",
1139 G_SETTINGS_BIND_DEFAULT
);
1141 widget
= e_builder_get_widget (prefs
->builder
, "chkPromptPrivateListReply");
1143 settings
, "prompt-on-private-list-reply",
1145 G_SETTINGS_BIND_DEFAULT
);
1147 widget
= e_builder_get_widget (prefs
->builder
, "chkPromptReplyManyRecips");
1149 settings
, "prompt-on-reply-many-recips",
1151 G_SETTINGS_BIND_DEFAULT
);
1153 widget
= e_builder_get_widget (prefs
->builder
, "chkPromptListReplyTo");
1155 settings
, "prompt-on-list-reply-to",
1157 G_SETTINGS_BIND_DEFAULT
);
1159 widget
= e_builder_get_widget (prefs
->builder
, "chkPromptManyToCCRecips");
1161 settings
, "prompt-on-many-to-cc-recips",
1163 G_SETTINGS_BIND_DEFAULT
);
1165 widget
= e_builder_get_widget (prefs
->builder
, "chkPromptSendInvalidRecip");
1167 settings
, "prompt-on-invalid-recip",
1169 G_SETTINGS_BIND_DEFAULT
);
1171 widget
= e_builder_get_widget (prefs
->builder
, "chkPromptComposerModeSwitch");
1173 settings
, "prompt-on-composer-mode-switch",
1175 G_SETTINGS_BIND_DEFAULT
);
1177 widget
= e_builder_get_widget (prefs
->builder
, "chkAutoSmileys");
1179 settings
, "composer-magic-smileys",
1181 G_SETTINGS_BIND_DEFAULT
);
1183 widget
= e_builder_get_widget (prefs
->builder
, "chkUnicodeSmileys");
1185 settings
, "composer-unicode-smileys",
1187 G_SETTINGS_BIND_DEFAULT
);
1189 widget
= e_builder_get_widget (prefs
->builder
, "chkRequestReceipt");
1191 settings
, "composer-request-receipt",
1193 G_SETTINGS_BIND_DEFAULT
);
1195 widget
= e_builder_get_widget (prefs
->builder
, "chkReplyStartBottom");
1197 settings
, "composer-reply-start-bottom",
1199 G_SETTINGS_BIND_DEFAULT
);
1201 widget
= e_builder_get_widget (prefs
->builder
, "spinWordWrapLength");
1203 settings
, "composer-word-wrap-length",
1205 G_SETTINGS_BIND_DEFAULT
);
1207 widget
= e_builder_get_widget (prefs
->builder
, "chkOutlookFilenames");
1209 settings
, "composer-outlook-filenames",
1211 G_SETTINGS_BIND_DEFAULT
);
1213 widget
= e_builder_get_widget (prefs
->builder
, "chkUseOutbox");
1215 settings
, "composer-use-outbox",
1217 G_SETTINGS_BIND_DEFAULT
);
1219 widget
= e_builder_get_widget (prefs
->builder
, "comboboxFlushOutbox");
1221 combo_text
= GTK_COMBO_BOX_TEXT (widget
);
1222 gtk_combo_box_text_append (combo_text
, "-1", _("Keep in Outbox"));
1223 gtk_combo_box_text_append (combo_text
, "0", _("Send immediately"));
1224 gtk_combo_box_text_append (combo_text
, "5", _("Send after 5 minutes"));
1226 g_settings_bind_with_mapping (
1227 settings
, "composer-delay-outbox-flush",
1228 widget
, "active-id",
1229 G_SETTINGS_BIND_DEFAULT
,
1230 em_composer_prefs_outbox_delay_setting_to_id
,
1231 em_composer_prefs_outbox_delay_id_to_setting
,
1234 e_binding_bind_property (
1235 e_builder_get_widget (prefs
->builder
, "chkUseOutbox"), "active",
1236 widget
, "sensitive",
1237 G_BINDING_SYNC_CREATE
);
1239 widget
= e_builder_get_widget (prefs
->builder
, "chkIgnoreListReplyTo");
1241 settings
, "composer-ignore-list-reply-to",
1243 G_SETTINGS_BIND_DEFAULT
);
1245 widget
= e_builder_get_widget (prefs
->builder
, "chkGroupReplyToList");
1247 settings
, "composer-group-reply-to-list",
1249 G_SETTINGS_BIND_DEFAULT
);
1251 widget
= e_builder_get_widget (prefs
->builder
, "chkSignReplyIfSigned");
1253 settings
, "composer-sign-reply-if-signed",
1255 G_SETTINGS_BIND_DEFAULT
);
1257 widget
= e_builder_get_widget (prefs
->builder
, "chkWrapQuotedTextInReplies");
1259 settings
, "composer-wrap-quoted-text-in-replies",
1261 G_SETTINGS_BIND_DEFAULT
);
1263 widget
= e_builder_get_widget (prefs
->builder
, "chkSignatureInNewOnly");
1265 settings
, "composer-signature-in-new-only",
1267 G_SETTINGS_BIND_DEFAULT
);
1269 widget
= e_builder_get_widget (prefs
->builder
, "chkTopSignature");
1271 settings
, "composer-top-signature",
1273 G_SETTINGS_BIND_DEFAULT
);
1275 widget
= e_builder_get_widget (prefs
->builder
, "chkEnableSpellChecking");
1277 settings
, "composer-inline-spelling",
1279 G_SETTINGS_BIND_DEFAULT
);
1281 widget
= e_charset_combo_box_new ();
1282 container
= e_builder_get_widget (prefs
->builder
, "hboxComposerCharset");
1283 gtk_box_pack_start (GTK_BOX (container
), widget
, FALSE
, FALSE
, 0);
1284 gtk_widget_show (widget
);
1286 settings
, "composer-charset",
1288 G_SETTINGS_BIND_DEFAULT
);
1290 container
= e_builder_get_widget (prefs
->builder
, "lblCharset");
1291 gtk_label_set_mnemonic_widget (GTK_LABEL (container
), widget
);
1293 /* Spell Checking */
1294 widget
= e_builder_get_widget (prefs
->builder
, "listSpellCheckLanguage");
1295 view
= GTK_TREE_VIEW (widget
);
1296 store
= gtk_list_store_new (
1297 3, G_TYPE_BOOLEAN
, G_TYPE_STRING
, G_TYPE_POINTER
);
1298 prefs
->language_model
= GTK_TREE_MODEL (store
);
1299 gtk_tree_view_set_model (view
, prefs
->language_model
);
1300 renderer
= gtk_cell_renderer_toggle_new ();
1302 renderer
, "toggled",
1303 G_CALLBACK (spell_language_toggled_cb
), prefs
);
1304 gtk_tree_view_insert_column_with_attributes (
1305 view
, -1, _("Enabled"),
1306 renderer
, "active", 0, NULL
);
1308 gtk_tree_view_insert_column_with_attributes (
1309 view
, -1, _("Language(s)"),
1310 gtk_cell_renderer_text_new (),
1312 selection
= gtk_tree_view_get_selection (view
);
1313 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_NONE
);
1314 info_pixmap
= e_builder_get_widget (prefs
->builder
, "pixmapSpellInfo");
1315 gtk_image_set_from_icon_name (
1316 GTK_IMAGE (info_pixmap
),
1317 "dialog-information", GTK_ICON_SIZE_BUTTON
);
1319 spell_setup (prefs
);
1321 g_signal_connect_swapped (
1322 store
, "row-changed",
1323 G_CALLBACK (spell_language_save
), prefs
);
1325 /* Forwards and Replies */
1326 widget
= e_builder_get_widget (prefs
->builder
, "comboboxForwardStyle");
1328 settings
, "forward-style-name",
1329 widget
, "active-id",
1330 G_SETTINGS_BIND_DEFAULT
);
1332 widget
= e_builder_get_widget (prefs
->builder
, "comboboxReplyStyle");
1334 settings
, "reply-style-name",
1335 widget
, "active-id",
1336 G_SETTINGS_BIND_DEFAULT
);
1339 container
= e_builder_get_widget (
1340 prefs
->builder
, "signature-alignment");
1341 widget
= e_mail_signature_manager_new (registry
);
1342 gtk_container_add (GTK_CONTAINER (container
), widget
);
1343 gtk_widget_show (widget
);
1345 /* The mail shell backend responds to the "window-added" signal
1346 * that this triggers and configures it with composer preferences. */
1347 g_signal_connect_swapped (
1348 widget
, "editor-created",
1349 G_CALLBACK (gtk_application_add_window
), shell
);
1352 settings
, "composer-send-html",
1353 widget
, "prefer-html",
1354 G_SETTINGS_BIND_GET
);
1356 /* Send Account override */
1357 mail_backend
= E_MAIL_BACKEND (e_shell_get_backend_by_name (shell
, "mail"));
1358 g_return_if_fail (mail_backend
!= NULL
);
1360 send_override
= e_mail_backend_get_send_account_override (mail_backend
);
1361 g_object_set_data_full (
1362 G_OBJECT (prefs
->builder
), MAIL_SEND_ACCOUNT_OVERRIDE_KEY
,
1363 g_object_ref (send_override
), g_object_unref
);
1365 send_account_override_setup (prefs
->builder
, mail_backend
, registry
);
1367 widget
= e_builder_get_widget (prefs
->builder
, "sao-prefer-folder-check");
1368 e_binding_bind_property (
1369 send_override
, "prefer-folder",
1371 G_BINDING_BIDIRECTIONAL
| G_BINDING_SYNC_CREATE
);
1373 /* get our toplevel widget */
1374 target
= em_config_target_new_prefs (ec
);
1375 e_config_set_target ((EConfig
*) ec
, (EConfigTarget
*) target
);
1376 toplevel
= e_config_create_widget ((EConfig
*) ec
);
1377 gtk_container_add (GTK_CONTAINER (prefs
), toplevel
);
1379 g_object_unref (settings
);
1383 em_composer_prefs_new (EPreferencesWindow
*window
)
1386 EMComposerPrefs
*prefs
;
1388 shell
= e_preferences_window_get_shell (window
);
1389 g_return_val_if_fail (E_IS_SHELL (shell
), NULL
);
1391 prefs
= g_object_new (EM_TYPE_COMPOSER_PREFS
, NULL
);
1392 em_composer_prefs_construct (prefs
, shell
);
1394 return GTK_WIDGET (prefs
);