2
* This program is free software; you can redistribute it and/or
3
* modify it under the terms of the GNU Lesser General Public
4
* License as published by the Free Software Foundation; either
5
* version 2 of the License, or (at your option) version 3.
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
* Lesser General Public License for more details.
12
* You should have received a copy of the GNU Lesser General Public
13
* License along with the program; if not, see <http://www.gnu.org/licenses/>
17
* Jeffrey Stedfast <fejj@ximian.com>
19
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
28
#include <sys/types.h>
33
#include "e-util/e-signature-utils.h"
34
#include "e-util/gconf-bridge.h"
36
#include "em-composer-prefs.h"
37
#include "composer/e-msg-composer.h"
38
#include "shell/e-shell-utils.h"
40
#include <glib/gi18n.h>
41
#include <glib/gstdio.h>
43
#include <gtkhtml/gtkhtml.h>
44
#include <editor/gtkhtml-spell-language.h>
46
#include "e-util/e-util.h"
47
#include "e-util/e-util-private.h"
48
#include "widgets/misc/e-charset-combo-box.h"
49
#include "widgets/misc/e-signature-editor.h"
50
#include "widgets/misc/e-signature-manager.h"
51
#include "widgets/misc/e-signature-preview.h"
53
#include "em-config.h"
54
#include "em-folder-selection-button.h"
62
transform_old_to_new_reply_style (GBinding *binding,
63
const GValue *source_value,
67
gboolean success = TRUE;
69
/* XXX This is the kind of legacy crap we wind up
70
* with when we don't migrate things properly. */
72
switch (g_value_get_int (source_value)) {
73
case 0: /* Quoted: 0 -> 2 */
74
g_value_set_int (target_value, 2);
77
case 1: /* Do Not Quote: 1 -> 3 */
78
g_value_set_int (target_value, 3);
81
case 2: /* Attach: 2 -> 0 */
82
g_value_set_int (target_value, 0);
85
case 3: /* Outlook: 3 -> 1 */
86
g_value_set_int (target_value, 1);
98
transform_new_to_old_reply_style (GBinding *binding,
99
const GValue *source_value,
100
GValue *target_value,
103
gboolean success = TRUE;
105
/* XXX This is the kind of legacy crap we wind up
106
* with when we don't migrate things properly. */
108
switch (g_value_get_int (source_value)) {
109
case 0: /* Attach: 0 -> 2 */
110
g_value_set_int (target_value, 2);
113
case 1: /* Outlook: 1 -> 3 */
114
g_value_set_int (target_value, 3);
117
case 2: /* Quoted: 2 -> 0 */
118
g_value_set_int (target_value, 0);
121
case 3: /* Do Not Quote: 3 -> 1 */
122
g_value_set_int (target_value, 1);
134
composer_prefs_finalize (GObject *object)
136
EMComposerPrefs *prefs = (EMComposerPrefs *) object;
138
g_object_unref (prefs->builder);
140
/* Chain up to parent's finalize() method. */
141
G_OBJECT_CLASS (em_composer_prefs_parent_class)->finalize (object);
145
em_composer_prefs_class_init (EMComposerPrefsClass *class)
147
GObjectClass *object_class;
149
object_class = G_OBJECT_CLASS (class);
150
object_class->finalize = composer_prefs_finalize;
154
em_composer_prefs_init (EMComposerPrefs *prefs)
159
spell_language_toggled_cb (GtkCellRendererToggle *renderer,
160
const gchar *path_string,
161
EMComposerPrefs *prefs)
169
model = prefs->language_model;
171
/* Convert the path string to a tree iterator. */
172
path = gtk_tree_path_new_from_string (path_string);
173
valid = gtk_tree_model_get_iter (model, &iter, path);
174
gtk_tree_path_free (path);
175
g_return_if_fail (valid);
177
/* Toggle the active state. */
178
gtk_tree_model_get (model, &iter, 0, &active, -1);
179
gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, !active, -1);
183
spell_language_save (EMComposerPrefs *prefs)
185
GList *spell_languages = NULL;
190
model = prefs->language_model;
192
/* Build a list of active spell languages. */
193
valid = gtk_tree_model_get_iter_first (model, &iter);
195
const GtkhtmlSpellLanguage *language;
199
model, &iter, 0, &active, 2, &language, -1);
202
spell_languages = g_list_prepend (
203
spell_languages, (gpointer) language);
205
valid = gtk_tree_model_iter_next (model, &iter);
207
spell_languages = g_list_reverse (spell_languages);
209
/* Update the GConf value. */
210
e_save_spell_languages (spell_languages);
212
g_list_free (spell_languages);
216
spell_setup (EMComposerPrefs *prefs)
218
const GList *available_languages;
219
GList *active_languages;
222
store = GTK_LIST_STORE (prefs->language_model);
223
available_languages = gtkhtml_spell_language_get_available ();
225
active_languages = e_load_spell_languages ();
227
/* Populate the GtkListStore. */
228
while (available_languages != NULL) {
229
const GtkhtmlSpellLanguage *language;
230
GtkTreeIter tree_iter;
234
language = available_languages->data;
235
name = gtkhtml_spell_language_get_name (language);
236
active = (g_list_find (active_languages, language) != NULL);
238
gtk_list_store_append (store, &tree_iter);
242
0, active, 1, name, 2, language, -1);
244
available_languages = available_languages->next;
247
g_list_free (active_languages);
251
emcp_widget_glade (EConfig *ec,
258
EMComposerPrefs *prefs = data;
260
return e_builder_get_widget (prefs->builder, item->label);
263
/* plugin meta-data */
264
static EMConfigItem emcp_items[] = {
268
(gchar *) "composer_toplevel",
272
(gchar *) "00.general",
273
(gchar *) "vboxComposerGeneral",
277
(gchar *) "00.general/00.behavior",
278
(gchar *) "default-behavior-vbox",
282
(gchar *) "10.signatures",
283
(gchar *) "vboxSignatures",
286
/* signature/signatures and signature/preview parts not usable */
289
(gchar *) "20.spellcheck",
290
(gchar *) "vboxSpellChecking",
293
{ E_CONFIG_SECTION_TABLE,
294
(gchar *) "20.spellcheck/00.languages",
295
(gchar *) "languages-table",
299
(gchar *) "20.spellcheck/00.options",
300
(gchar *) "spell-options-vbox",
305
emcp_free (EConfig *ec, GSList *items, gpointer data)
307
/* the prefs data is freed automagically */
308
g_slist_free (items);
312
em_composer_prefs_construct (EMComposerPrefs *prefs,
315
GtkWidget *toplevel, *widget, *info_pixmap;
316
GtkWidget *container;
317
EShellSettings *shell_settings;
318
ESignatureList *signature_list;
319
ESignatureTreeView *signature_tree_view;
322
GtkTreeSelection *selection;
323
GtkCellRenderer *renderer;
326
EMConfigTargetPrefs *target;
330
shell_settings = e_shell_get_shell_settings (shell);
332
/* Make sure our custom widget classes are registered with
333
* GType before we load the GtkBuilder definition file. */
334
EM_TYPE_FOLDER_SELECTION_BUTTON;
336
prefs->builder = gtk_builder_new ();
337
e_load_ui_builder_definition (prefs->builder, "mail-config.ui");
339
/** @HookPoint-EMConfig: Mail Composer Preferences
340
* @Id: org.gnome.evolution.mail.composerPrefs
341
* @Type: E_CONFIG_BOOK
342
* @Class: org.gnome.evolution.mail.config:1.0
343
* @Target: EMConfigTargetPrefs
345
* The mail composer preferences settings page.
347
ec = em_config_new(E_CONFIG_BOOK, "org.gnome.evolution.mail.composerPrefs");
349
for (i = 0; i < G_N_ELEMENTS (emcp_items); i++)
350
l = g_slist_prepend (l, &emcp_items[i]);
351
e_config_add_items ((EConfig *) ec, l, NULL, NULL, emcp_free, prefs);
355
/* Default Behavior */
357
/* Express mode does not honor this setting. */
358
widget = e_builder_get_widget (prefs->builder, "chkSendHTML");
359
if (e_shell_get_express_mode (shell))
360
gtk_widget_hide (widget);
362
g_object_bind_property (
363
shell_settings, "composer-format-html",
365
G_BINDING_BIDIRECTIONAL |
366
G_BINDING_SYNC_CREATE);
368
widget = e_builder_get_widget (prefs->builder, "chkPromptEmptySubject");
369
g_object_bind_property (
370
shell_settings, "composer-prompt-empty-subject",
372
G_BINDING_BIDIRECTIONAL |
373
G_BINDING_SYNC_CREATE);
375
widget = e_builder_get_widget (prefs->builder, "chkPromptBccOnly");
376
g_object_bind_property (
377
shell_settings, "composer-prompt-only-bcc",
379
G_BINDING_BIDIRECTIONAL |
380
G_BINDING_SYNC_CREATE);
382
widget = e_builder_get_widget (prefs->builder, "chkPromptPrivateListReply");
383
g_object_bind_property (
384
shell_settings, "composer-prompt-private-list-reply",
386
G_BINDING_BIDIRECTIONAL |
387
G_BINDING_SYNC_CREATE);
389
widget = e_builder_get_widget (prefs->builder, "chkPromptReplyManyRecips");
390
g_object_bind_property (
391
shell_settings, "composer-prompt-reply-many-recips",
393
G_BINDING_BIDIRECTIONAL |
394
G_BINDING_SYNC_CREATE);
396
widget = e_builder_get_widget (prefs->builder, "chkPromptListReplyTo");
397
g_object_bind_property (
398
shell_settings, "composer-prompt-list-reply-to",
400
G_BINDING_BIDIRECTIONAL |
401
G_BINDING_SYNC_CREATE);
403
widget = e_builder_get_widget (prefs->builder, "chkPromptSendInvalidRecip");
404
g_object_bind_property (
405
shell_settings, "composer-prompt-send-invalid-recip",
407
G_BINDING_BIDIRECTIONAL |
408
G_BINDING_SYNC_CREATE);
410
widget = e_builder_get_widget (prefs->builder, "chkAutoSmileys");
411
g_object_bind_property (
412
shell_settings, "composer-magic-smileys",
414
G_BINDING_BIDIRECTIONAL |
415
G_BINDING_SYNC_CREATE);
417
widget = e_builder_get_widget (prefs->builder, "chkRequestReceipt");
418
g_object_bind_property (
419
shell_settings, "composer-request-receipt",
421
G_BINDING_BIDIRECTIONAL |
422
G_BINDING_SYNC_CREATE);
424
widget = e_builder_get_widget (prefs->builder, "chkReplyStartBottom");
425
g_object_bind_property (
426
shell_settings, "composer-reply-start-bottom",
428
G_BINDING_BIDIRECTIONAL |
429
G_BINDING_SYNC_CREATE);
431
widget = e_builder_get_widget (prefs->builder, "chkOutlookFilenames");
432
g_object_bind_property (
433
shell_settings, "composer-outlook-filenames",
435
G_BINDING_BIDIRECTIONAL |
436
G_BINDING_SYNC_CREATE);
438
widget = e_builder_get_widget (prefs->builder, "chkIgnoreListReplyTo");
439
g_object_bind_property (
440
shell_settings, "composer-ignore-list-reply-to",
442
G_BINDING_BIDIRECTIONAL |
443
G_BINDING_SYNC_CREATE);
445
widget = e_builder_get_widget (prefs->builder, "chkGroupReplyToList");
446
g_object_bind_property (
447
shell_settings, "composer-group-reply-to-list",
449
G_BINDING_BIDIRECTIONAL |
450
G_BINDING_SYNC_CREATE);
452
widget = e_builder_get_widget (prefs->builder, "chkTopSignature");
453
g_object_bind_property (
454
shell_settings, "composer-top-signature",
456
G_BINDING_BIDIRECTIONAL |
457
G_BINDING_SYNC_CREATE);
459
widget = e_builder_get_widget (prefs->builder, "chkEnableSpellChecking");
460
g_object_bind_property (
461
shell_settings, "composer-inline-spelling",
463
G_BINDING_BIDIRECTIONAL |
464
G_BINDING_SYNC_CREATE);
466
widget = e_charset_combo_box_new ();
467
container = e_builder_get_widget (prefs->builder, "hboxComposerCharset");
468
gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
469
gtk_widget_show (widget);
470
g_object_bind_property (
471
shell_settings, "composer-charset",
473
G_BINDING_BIDIRECTIONAL |
474
G_BINDING_SYNC_CREATE);
477
widget = e_builder_get_widget (prefs->builder, "listSpellCheckLanguage");
478
view = GTK_TREE_VIEW (widget);
479
store = gtk_list_store_new (
480
3, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER);
481
g_signal_connect_swapped (
482
store, "row-changed",
483
G_CALLBACK (spell_language_save), prefs);
484
prefs->language_model = GTK_TREE_MODEL (store);
485
gtk_tree_view_set_model (view, prefs->language_model);
486
renderer = gtk_cell_renderer_toggle_new ();
489
G_CALLBACK (spell_language_toggled_cb), prefs);
490
gtk_tree_view_insert_column_with_attributes (
491
view, -1, _("Enabled"),
492
renderer, "active", 0, NULL);
494
gtk_tree_view_insert_column_with_attributes (
495
view, -1, _("Language(s)"),
496
gtk_cell_renderer_text_new (),
498
selection = gtk_tree_view_get_selection (view);
499
gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
500
info_pixmap = e_builder_get_widget (prefs->builder, "pixmapSpellInfo");
501
gtk_image_set_from_stock (
502
GTK_IMAGE (info_pixmap),
503
GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_BUTTON);
505
widget = e_builder_get_widget (prefs->builder, "colorButtonSpellCheckColor");
506
g_object_bind_property_full (
507
shell_settings, "composer-spell-color",
509
G_BINDING_BIDIRECTIONAL |
510
G_BINDING_SYNC_CREATE,
511
e_binding_transform_string_to_color,
512
e_binding_transform_color_to_string,
513
NULL, (GDestroyNotify) NULL);
517
/* Forwards and Replies */
518
widget = e_builder_get_widget (prefs->builder, "comboboxForwardStyle");
519
g_object_bind_property (
520
shell_settings, "mail-forward-style",
522
G_BINDING_BIDIRECTIONAL |
523
G_BINDING_SYNC_CREATE);
525
widget = e_builder_get_widget (prefs->builder, "comboboxReplyStyle");
526
g_object_bind_property_full (
527
shell_settings, "mail-reply-style",
529
G_BINDING_BIDIRECTIONAL |
530
G_BINDING_SYNC_CREATE,
531
transform_old_to_new_reply_style,
532
transform_new_to_old_reply_style,
533
NULL, (GDestroyNotify) NULL);
536
signature_list = e_get_signature_list ();
537
container = e_builder_get_widget (prefs->builder, "signature-alignment");
538
widget = e_signature_manager_new (signature_list);
539
gtk_container_add (GTK_CONTAINER (container), widget);
540
gtk_widget_show (widget);
542
/* The mail shell backend responds to the "window-created" signal
543
* that this triggers and configures it with composer preferences. */
544
g_signal_connect_swapped (
545
widget, "editor-created",
546
G_CALLBACK (e_shell_watch_window), shell);
548
/* Express mode does not honor this setting. */
549
if (!e_shell_get_express_mode (shell))
550
g_object_bind_property (
551
shell_settings, "composer-format-html",
552
widget, "prefer-html",
553
G_BINDING_SYNC_CREATE);
555
signature_tree_view = e_signature_manager_get_tree_view (
556
E_SIGNATURE_MANAGER (widget));
558
container = e_builder_get_widget (
559
prefs->builder, "signature-preview-scrolled-window");
560
widget = e_signature_preview_new ();
561
gtk_container_add (GTK_CONTAINER (container), widget);
562
gtk_widget_show (widget);
564
g_object_bind_property (
565
signature_tree_view, "selected",
567
G_BINDING_SYNC_CREATE);
569
/* Sanitize the dialog for Express mode */
570
e_shell_hide_widgets_for_express_mode (shell, prefs->builder,
571
"chkOutlookFilenames",
575
/* get our toplevel widget */
576
client = gconf_client_get_default ();
577
target = em_config_target_new_prefs (ec, client);
578
e_config_set_target ((EConfig *) ec, (EConfigTarget *) target);
579
toplevel = e_config_create_widget ((EConfig *) ec);
580
gtk_container_add (GTK_CONTAINER (prefs), toplevel);
581
g_object_unref (client);
585
em_composer_prefs_new (EPreferencesWindow *window)
587
EMComposerPrefs *prefs;
588
EShell *shell = e_preferences_window_get_shell (window);
590
g_return_val_if_fail (E_IS_SHELL (shell), NULL);
592
prefs = g_object_new (EM_TYPE_COMPOSER_PREFS, NULL);
593
em_composer_prefs_construct (prefs, shell);
595
return GTK_WIDGET (prefs);