1 /* e-html-editor-actions.c
3 * Copyright (C) 2012 Dan Vrátil <dvratil@redhat.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU Lesser General Public
7 * License as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
25 #include <glib/gi18n-lib.h>
27 #include <enchant/enchant.h>
29 #include "e-html-editor.h"
30 #include "e-html-editor-private.h"
31 #include "e-html-editor-actions.h"
32 #include "e-html-editor-utils.h"
33 #include "e-emoticon-action.h"
34 #include "e-emoticon-chooser.h"
35 #include "e-image-chooser-dialog.h"
36 #include "e-spell-checker.h"
37 #include "e-misc-utils.h"
40 insert_html_file_ready_cb (GFile
*file
,
44 EHTMLEditorSelection
*selection
;
45 gchar
*contents
= NULL
;
49 g_file_load_contents_finish (
50 file
, result
, &contents
, &length
, NULL
, &error
);
54 dialog
= gtk_message_dialog_new (
55 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (editor
))),
57 GTK_BUTTONS_CLOSE
, _("Failed to insert HTML file."));
58 gtk_message_dialog_format_secondary_text (
59 GTK_MESSAGE_DIALOG (dialog
), "%s.", error
->message
);
60 gtk_dialog_run (GTK_DIALOG (dialog
));
61 gtk_widget_destroy (dialog
);
63 g_clear_error (&error
);
64 g_object_unref (editor
);
68 selection
= e_html_editor_view_get_selection (
69 e_html_editor_get_view (editor
));
70 e_html_editor_selection_insert_html (selection
, contents
);
73 g_object_unref (editor
);
77 insert_text_file_ready_cb (GFile
*file
,
81 EHTMLEditorSelection
*selection
;
86 g_file_load_contents_finish (
87 file
, result
, &contents
, &length
, NULL
, &error
);
91 dialog
= gtk_message_dialog_new (
92 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (editor
))),
94 GTK_BUTTONS_CLOSE
, _("Failed to insert text file."));
95 gtk_message_dialog_format_secondary_text (
96 GTK_MESSAGE_DIALOG (dialog
), "%s.", error
->message
);
97 gtk_dialog_run (GTK_DIALOG (dialog
));
98 gtk_widget_destroy (dialog
);
100 g_clear_error (&error
);
101 g_object_unref (editor
);
105 selection
= e_html_editor_view_get_selection (
106 e_html_editor_get_view (editor
));
107 e_html_editor_selection_insert_text (selection
, contents
);
110 g_object_unref (editor
);
114 editor_update_static_spell_actions (EHTMLEditor
*editor
)
116 ESpellChecker
*checker
;
117 EHTMLEditorView
*view
;
120 view
= e_html_editor_get_view (editor
);
121 checker
= e_html_editor_view_get_spell_checker (view
);
123 count
= e_spell_checker_count_active_languages (checker
);
125 gtk_action_set_visible (ACTION (CONTEXT_SPELL_ADD
), count
== 1);
126 gtk_action_set_visible (ACTION (CONTEXT_SPELL_ADD_MENU
), count
> 1);
127 gtk_action_set_visible (ACTION (CONTEXT_SPELL_IGNORE
), count
> 0);
129 gtk_action_set_sensitive (ACTION (SPELL_CHECK
), count
> 0);
132 /*****************************************************************************
134 *****************************************************************************/
137 action_context_delete_cell_cb (GtkAction
*action
,
140 WebKitDOMNode
*sibling
;
141 WebKitDOMElement
*cell
;
143 g_return_if_fail (editor
->priv
->table_cell
!= NULL
);
145 cell
= e_html_editor_dom_node_find_parent_element (editor
->priv
->table_cell
, "TD");
147 cell
= e_html_editor_dom_node_find_parent_element (
148 editor
->priv
->table_cell
, "TH");
150 g_return_if_fail (cell
!= NULL
);
152 sibling
= webkit_dom_node_get_previous_sibling (WEBKIT_DOM_NODE (cell
));
154 sibling
= webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (cell
));
157 webkit_dom_node_remove_child (
158 webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (cell
)),
159 WEBKIT_DOM_NODE (cell
), NULL
);
162 webkit_dom_html_table_cell_element_set_col_span (
163 WEBKIT_DOM_HTML_TABLE_CELL_ELEMENT (sibling
),
164 webkit_dom_html_table_cell_element_get_col_span (
165 WEBKIT_DOM_HTML_TABLE_CELL_ELEMENT (sibling
)) + 1);
170 action_context_delete_column_cb (GtkAction
*action
,
173 WebKitDOMElement
*cell
, *table
;
174 WebKitDOMHTMLCollection
*rows
;
175 gulong index
, length
, ii
;
177 g_return_if_fail (editor
->priv
->table_cell
!= NULL
);
179 /* Find TD in which the selection starts */
180 cell
= e_html_editor_dom_node_find_parent_element (editor
->priv
->table_cell
, "TD");
182 cell
= e_html_editor_dom_node_find_parent_element (
183 editor
->priv
->table_cell
, "TH");
185 g_return_if_fail (cell
!= NULL
);
187 table
= e_html_editor_dom_node_find_parent_element (WEBKIT_DOM_NODE (cell
), "TABLE");
188 g_return_if_fail (table
!= NULL
);
190 rows
= webkit_dom_html_table_element_get_rows (
191 WEBKIT_DOM_HTML_TABLE_ELEMENT (table
));
192 length
= webkit_dom_html_collection_get_length (rows
);
194 index
= webkit_dom_html_table_cell_element_get_cell_index (
195 WEBKIT_DOM_HTML_TABLE_CELL_ELEMENT (cell
));
197 for (ii
= 0; ii
< length
; ii
++) {
200 row
= webkit_dom_html_collection_item (rows
, ii
);
202 webkit_dom_html_table_row_element_delete_cell (
203 WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row
), index
, NULL
);
208 action_context_delete_row_cb (GtkAction
*action
,
211 WebKitDOMElement
*row
;
213 g_return_if_fail (editor
->priv
->table_cell
!= NULL
);
215 row
= e_html_editor_dom_node_find_parent_element (editor
->priv
->table_cell
, "TR");
216 g_return_if_fail (row
!= NULL
);
218 webkit_dom_node_remove_child (
219 webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (row
)),
220 WEBKIT_DOM_NODE (row
), NULL
);
224 action_context_delete_table_cb (GtkAction
*action
,
227 WebKitDOMElement
*table
;
229 g_return_if_fail (editor
->priv
->table_cell
!= NULL
);
231 table
= e_html_editor_dom_node_find_parent_element (editor
->priv
->table_cell
, "TABLE");
232 g_return_if_fail (table
!= NULL
);
234 webkit_dom_node_remove_child (
235 webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (table
)),
236 WEBKIT_DOM_NODE (table
), NULL
);
240 action_context_insert_column_after_cb (GtkAction
*action
,
243 WebKitDOMElement
*cell
, *row
;
246 g_return_if_fail (editor
->priv
->table_cell
!= NULL
);
248 cell
= e_html_editor_dom_node_find_parent_element (editor
->priv
->table_cell
, "TD");
250 cell
= e_html_editor_dom_node_find_parent_element (
251 editor
->priv
->table_cell
, "TH");
253 g_return_if_fail (cell
!= NULL
);
255 row
= e_html_editor_dom_node_find_parent_element (WEBKIT_DOM_NODE (cell
), "TR");
256 g_return_if_fail (row
!= NULL
);
258 /* Get the first row in the table */
259 row
= WEBKIT_DOM_ELEMENT (
260 webkit_dom_node_get_first_child (
261 webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (row
))));
263 index
= webkit_dom_html_table_cell_element_get_cell_index (
264 WEBKIT_DOM_HTML_TABLE_CELL_ELEMENT (cell
));
267 webkit_dom_html_table_row_element_insert_cell (
268 WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row
), index
+ 1, NULL
);
270 row
= WEBKIT_DOM_ELEMENT (
271 webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (row
)));
276 action_context_insert_column_before_cb (GtkAction
*action
,
279 WebKitDOMElement
*cell
, *row
;
282 g_return_if_fail (editor
->priv
->table_cell
!= NULL
);
284 cell
= e_html_editor_dom_node_find_parent_element (editor
->priv
->table_cell
, "TD");
286 cell
= e_html_editor_dom_node_find_parent_element (
287 editor
->priv
->table_cell
, "TH");
289 g_return_if_fail (cell
!= NULL
);
291 row
= e_html_editor_dom_node_find_parent_element (WEBKIT_DOM_NODE (cell
), "TR");
292 g_return_if_fail (row
!= NULL
);
294 /* Get the first row in the table */
295 row
= WEBKIT_DOM_ELEMENT (
296 webkit_dom_node_get_first_child (
297 webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (row
))));
299 index
= webkit_dom_html_table_cell_element_get_cell_index (
300 WEBKIT_DOM_HTML_TABLE_CELL_ELEMENT (cell
));
303 webkit_dom_html_table_row_element_insert_cell (
304 WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row
), index
- 1, NULL
);
306 row
= WEBKIT_DOM_ELEMENT (
307 webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (row
)));
312 action_context_insert_row_above_cb (GtkAction
*action
,
315 WebKitDOMElement
*row
, *table
;
316 WebKitDOMHTMLCollection
*cells
;
317 WebKitDOMHTMLElement
*new_row
;
318 gulong index
, cell_count
, ii
;
320 g_return_if_fail (editor
->priv
->table_cell
!= NULL
);
322 row
= e_html_editor_dom_node_find_parent_element (editor
->priv
->table_cell
, "TR");
323 g_return_if_fail (row
!= NULL
);
325 table
= e_html_editor_dom_node_find_parent_element (WEBKIT_DOM_NODE (row
), "TABLE");
326 g_return_if_fail (table
!= NULL
);
328 index
= webkit_dom_html_table_row_element_get_row_index (
329 WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row
));
331 new_row
= webkit_dom_html_table_element_insert_row (
332 WEBKIT_DOM_HTML_TABLE_ELEMENT (table
), index
, NULL
);
334 cells
= webkit_dom_html_table_row_element_get_cells (
335 WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row
));
336 cell_count
= webkit_dom_html_collection_get_length (cells
);
337 for (ii
= 0; ii
< cell_count
; ii
++) {
338 webkit_dom_html_table_row_element_insert_cell (
339 WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (new_row
), -1, NULL
);
345 action_context_insert_row_below_cb (GtkAction
*action
,
348 WebKitDOMElement
*row
, *table
;
349 WebKitDOMHTMLCollection
*cells
;
350 WebKitDOMHTMLElement
*new_row
;
351 gulong index
, cell_count
, ii
;
353 g_return_if_fail (editor
->priv
->table_cell
!= NULL
);
355 row
= e_html_editor_dom_node_find_parent_element (editor
->priv
->table_cell
, "TR");
356 g_return_if_fail (row
!= NULL
);
358 table
= e_html_editor_dom_node_find_parent_element (WEBKIT_DOM_NODE (row
), "TABLE");
359 g_return_if_fail (table
!= NULL
);
361 index
= webkit_dom_html_table_row_element_get_row_index (
362 WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row
));
364 new_row
= webkit_dom_html_table_element_insert_row (
365 WEBKIT_DOM_HTML_TABLE_ELEMENT (table
), index
+ 1, NULL
);
367 cells
= webkit_dom_html_table_row_element_get_cells (
368 WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row
));
369 cell_count
= webkit_dom_html_collection_get_length (cells
);
370 for (ii
= 0; ii
< cell_count
; ii
++) {
371 webkit_dom_html_table_row_element_insert_cell (
372 WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (new_row
), -1, NULL
);
377 action_context_remove_link_cb (GtkAction
*action
,
380 EHTMLEditorView
*view
;
381 EHTMLEditorSelection
*selection
;
383 view
= e_html_editor_get_view (editor
);
384 selection
= e_html_editor_view_get_selection (view
);
386 e_html_editor_selection_unlink (selection
);
390 action_context_spell_add_cb (GtkAction
*action
,
393 ESpellChecker
*spell_checker
;
394 EHTMLEditorSelection
*selection
;
397 spell_checker
= e_html_editor_view_get_spell_checker (
398 editor
->priv
->html_editor_view
);
399 selection
= e_html_editor_view_get_selection (editor
->priv
->html_editor_view
);
401 word
= e_html_editor_selection_get_caret_word (selection
);
403 e_spell_checker_learn_word (spell_checker
, word
);
408 action_context_spell_ignore_cb (GtkAction
*action
,
411 ESpellChecker
*spell_checker
;
412 EHTMLEditorSelection
*selection
;
415 spell_checker
= e_html_editor_view_get_spell_checker (
416 editor
->priv
->html_editor_view
);
417 selection
= e_html_editor_view_get_selection (editor
->priv
->html_editor_view
);
419 word
= e_html_editor_selection_get_caret_word (selection
);
421 e_spell_checker_ignore_word (spell_checker
, word
);
426 action_copy_cb (GtkAction
*action
,
429 EHTMLEditorView
*view
= e_html_editor_get_view (editor
);
431 if (gtk_widget_has_focus (GTK_WIDGET (view
)))
432 webkit_web_view_copy_clipboard (WEBKIT_WEB_VIEW (view
));
436 action_cut_cb (GtkAction
*action
,
439 EHTMLEditorView
*view
= e_html_editor_get_view (editor
);
441 if (gtk_widget_has_focus (GTK_WIDGET (view
)))
442 webkit_web_view_cut_clipboard (WEBKIT_WEB_VIEW (view
));
446 action_indent_cb (GtkAction
*action
,
449 EHTMLEditorView
*view
= e_html_editor_get_view (editor
);
451 if (gtk_widget_has_focus (GTK_WIDGET (view
)))
452 e_html_editor_selection_indent (editor
->priv
->selection
);
456 action_insert_emoticon_cb (GtkAction
*action
,
459 EHTMLEditorView
*view
;
462 emoticon
= e_emoticon_chooser_get_current_emoticon (
463 E_EMOTICON_CHOOSER (action
));
464 g_return_if_fail (emoticon
!= NULL
);
466 view
= e_html_editor_get_view (editor
);
467 e_html_editor_view_insert_smiley (view
, emoticon
);
471 action_insert_html_file_cb (GtkToggleAction
*action
,
475 GtkFileFilter
*filter
;
477 dialog
= gtk_file_chooser_dialog_new (
478 _("Insert HTML File"), NULL
,
479 GTK_FILE_CHOOSER_ACTION_OPEN
,
480 _("_Cancel"), GTK_RESPONSE_CANCEL
,
481 _("_Open"), GTK_RESPONSE_ACCEPT
, NULL
);
483 filter
= gtk_file_filter_new ();
484 gtk_file_filter_set_name (filter
, _("HTML file"));
485 gtk_file_filter_add_mime_type (filter
, "text/html");
486 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog
), filter
);
488 if (gtk_dialog_run (GTK_DIALOG (dialog
)) == GTK_RESPONSE_ACCEPT
) {
491 file
= gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog
));
493 /* XXX Need a way to cancel this. */
494 g_file_load_contents_async (
495 file
, NULL
, (GAsyncReadyCallback
)
496 insert_html_file_ready_cb
,
497 g_object_ref (editor
));
499 g_object_unref (file
);
502 gtk_widget_destroy (dialog
);
506 action_insert_image_cb (GtkAction
*action
,
511 dialog
= e_image_chooser_dialog_new (C_("dialog-title", "Insert Image"), NULL
);
513 if (gtk_dialog_run (GTK_DIALOG (dialog
)) == GTK_RESPONSE_ACCEPT
) {
514 EHTMLEditorView
*view
;
515 EHTMLEditorSelection
*selection
;
518 uri
= gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog
));
520 view
= e_html_editor_get_view (editor
);
521 selection
= e_html_editor_view_get_selection (view
);
522 e_html_editor_selection_insert_image (selection
, uri
);
527 gtk_widget_destroy (dialog
);
531 action_insert_link_cb (GtkAction
*action
,
534 if (editor
->priv
->link_dialog
== NULL
)
535 editor
->priv
->link_dialog
=
536 e_html_editor_link_dialog_new (editor
);
538 gtk_window_present (GTK_WINDOW (editor
->priv
->link_dialog
));
542 action_insert_rule_cb (GtkAction
*action
,
545 if (editor
->priv
->hrule_dialog
== NULL
)
546 editor
->priv
->hrule_dialog
=
547 e_html_editor_hrule_dialog_new (editor
);
549 gtk_window_present (GTK_WINDOW (editor
->priv
->hrule_dialog
));
553 action_insert_table_cb (GtkAction
*action
,
556 if (editor
->priv
->table_dialog
== NULL
)
557 editor
->priv
->table_dialog
=
558 e_html_editor_table_dialog_new (editor
);
560 gtk_window_present (GTK_WINDOW (editor
->priv
->table_dialog
));
564 action_insert_text_file_cb (GtkAction
*action
,
568 GtkFileFilter
*filter
;
570 dialog
= gtk_file_chooser_dialog_new (
571 _("Insert text file"), NULL
,
572 GTK_FILE_CHOOSER_ACTION_OPEN
,
573 _("_Cancel"), GTK_RESPONSE_CANCEL
,
574 _("_Open"), GTK_RESPONSE_ACCEPT
, NULL
);
576 filter
= gtk_file_filter_new ();
577 gtk_file_filter_set_name (filter
, _("Text file"));
578 gtk_file_filter_add_mime_type (filter
, "text/plain");
579 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog
), filter
);
581 if (gtk_dialog_run (GTK_DIALOG (dialog
)) == GTK_RESPONSE_ACCEPT
) {
584 file
= gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog
));
586 /* XXX Need a way to cancel this. */
587 g_file_load_contents_async (
588 file
, NULL
, (GAsyncReadyCallback
)
589 insert_text_file_ready_cb
,
590 g_object_ref (editor
));
592 g_object_unref (file
);
595 gtk_widget_destroy (dialog
);
599 action_language_cb (GtkToggleAction
*toggle_action
,
602 ESpellChecker
*checker
;
603 EHTMLEditorView
*view
;
604 const gchar
*language_code
;
605 GtkAction
*add_action
;
609 view
= e_html_editor_get_view (editor
);
610 checker
= e_html_editor_view_get_spell_checker (view
);
611 language_code
= gtk_action_get_name (GTK_ACTION (toggle_action
));
613 active
= gtk_toggle_action_get_active (toggle_action
);
614 e_spell_checker_set_language_active (checker
, language_code
, active
);
616 /* Update "Add Word To" context menu item visibility. */
617 action_name
= g_strdup_printf ("context-spell-add-%s", language_code
);
618 add_action
= e_html_editor_get_action (editor
, action_name
);
619 gtk_action_set_visible (add_action
, active
);
620 g_free (action_name
);
622 editor_update_static_spell_actions (editor
);
624 g_signal_emit_by_name (editor
, "spell-languages-changed");
628 update_mode_combobox (gpointer data
)
630 EHTMLEditor
*editor
= data
;
631 EHTMLEditorView
*view
;
635 if (!E_IS_HTML_EDITOR (editor
))
638 view
= e_html_editor_get_view (editor
);
639 is_html
= e_html_editor_view_get_html_mode (view
);
641 action
= gtk_action_group_get_action (
642 editor
->priv
->core_editor_actions
, "mode-html");
643 gtk_radio_action_set_current_value (
644 GTK_RADIO_ACTION (action
), (is_html
? 1 : 0));
650 action_mode_cb (GtkRadioAction
*action
,
651 GtkRadioAction
*current
,
654 GtkActionGroup
*action_group
;
655 EHTMLEditorView
*view
;
656 GtkWidget
*style_combo_box
;
659 view
= e_html_editor_get_view (editor
);
660 is_html
= e_html_editor_view_get_html_mode (view
);
662 /* This must be done from idle callback, because apparently we can change
663 * current value in callback of current value change */
664 g_idle_add (update_mode_combobox
, editor
);
666 action_group
= editor
->priv
->html_actions
;
667 gtk_action_group_set_visible (action_group
, is_html
);
669 action_group
= editor
->priv
->html_context_actions
;
670 gtk_action_group_set_visible (action_group
, is_html
);
672 gtk_widget_set_sensitive (editor
->priv
->color_combo_box
, is_html
);
675 gtk_widget_show (editor
->priv
->html_toolbar
);
677 gtk_widget_hide (editor
->priv
->html_toolbar
);
680 /* Certain paragraph styles are HTML-only. */
681 gtk_action_set_sensitive (ACTION (STYLE_H1
), is_html
);
682 gtk_action_set_visible (ACTION (STYLE_H1
), is_html
);
683 gtk_action_set_sensitive (ACTION (STYLE_H2
), is_html
);
684 gtk_action_set_visible (ACTION (STYLE_H2
), is_html
);
685 gtk_action_set_sensitive (ACTION (STYLE_H3
), is_html
);
686 gtk_action_set_visible (ACTION (STYLE_H3
), is_html
);
687 gtk_action_set_sensitive (ACTION (STYLE_H4
), is_html
);
688 gtk_action_set_visible (ACTION (STYLE_H4
), is_html
);
689 gtk_action_set_sensitive (ACTION (STYLE_H5
), is_html
);
690 gtk_action_set_visible (ACTION (STYLE_H5
), is_html
);
691 gtk_action_set_sensitive (ACTION (STYLE_H6
), is_html
);
692 gtk_action_set_visible (ACTION (STYLE_H6
), is_html
);
693 gtk_action_set_sensitive (ACTION (STYLE_ADDRESS
), is_html
);
694 gtk_action_set_visible (ACTION (STYLE_ADDRESS
), is_html
);
696 /* Hide them from the action combo box as well */
697 style_combo_box
= e_html_editor_get_style_combo_box (editor
);
698 e_action_combo_box_update_model (E_ACTION_COMBO_BOX (style_combo_box
));
702 action_paste_cb (GtkAction
*action
,
705 EHTMLEditorView
*view
= e_html_editor_get_view (editor
);
707 /* If WebView doesn't have focus, focus it */
708 if (gtk_widget_has_focus (GTK_WIDGET (view
))) {
709 webkit_web_view_paste_clipboard (WEBKIT_WEB_VIEW (view
));
711 e_html_editor_view_force_spell_check (view
);
716 action_paste_as_text_cb (GtkAction
*action
,
719 EHTMLEditorView
*view
= e_html_editor_get_view (editor
);
721 if (gtk_widget_has_focus (GTK_WIDGET (view
))) {
722 e_html_editor_view_paste_as_text (view
);
723 e_html_editor_view_force_spell_check (view
);
728 action_paste_quote_cb (GtkAction
*action
,
731 EHTMLEditorView
*view
= e_html_editor_get_view (editor
);
733 if (gtk_widget_has_focus (GTK_WIDGET (view
))) {
734 e_html_editor_view_paste_clipboard_quoted (view
);
735 e_html_editor_view_force_spell_check (view
);
740 action_properties_cell_cb (GtkAction
*action
,
743 if (editor
->priv
->cell_dialog
== NULL
) {
744 editor
->priv
->cell_dialog
=
745 e_html_editor_cell_dialog_new (editor
);
748 e_html_editor_cell_dialog_show (
749 E_HTML_EDITOR_CELL_DIALOG (editor
->priv
->cell_dialog
),
750 editor
->priv
->table_cell
);
754 action_properties_image_cb (GtkAction
*action
,
757 if (editor
->priv
->image_dialog
== NULL
) {
758 editor
->priv
->image_dialog
=
759 e_html_editor_image_dialog_new (editor
);
762 e_html_editor_image_dialog_show (
763 E_HTML_EDITOR_IMAGE_DIALOG (editor
->priv
->image_dialog
),
764 editor
->priv
->image
);
768 action_properties_link_cb (GtkAction
*action
,
771 if (editor
->priv
->link_dialog
== NULL
) {
772 editor
->priv
->link_dialog
=
773 e_html_editor_link_dialog_new (editor
);
776 gtk_window_present (GTK_WINDOW (editor
->priv
->link_dialog
));
780 action_properties_page_cb (GtkAction
*action
,
783 if (editor
->priv
->page_dialog
== NULL
) {
784 editor
->priv
->page_dialog
=
785 e_html_editor_page_dialog_new (editor
);
788 gtk_window_present (GTK_WINDOW (editor
->priv
->page_dialog
));
792 action_properties_paragraph_cb (GtkAction
*action
,
795 if (editor
->priv
->paragraph_dialog
== NULL
) {
796 editor
->priv
->paragraph_dialog
=
797 e_html_editor_paragraph_dialog_new (editor
);
800 gtk_window_present (GTK_WINDOW (editor
->priv
->paragraph_dialog
));
804 action_properties_rule_cb (GtkAction
*action
,
807 if (editor
->priv
->hrule_dialog
== NULL
) {
808 editor
->priv
->hrule_dialog
=
809 e_html_editor_hrule_dialog_new (editor
);
812 gtk_window_present (GTK_WINDOW (editor
->priv
->hrule_dialog
));
816 action_properties_table_cb (GtkAction
*action
,
819 if (editor
->priv
->table_dialog
== NULL
) {
820 editor
->priv
->table_dialog
=
821 e_html_editor_table_dialog_new (editor
);
824 gtk_window_present (GTK_WINDOW (editor
->priv
->table_dialog
));
828 action_properties_text_cb (GtkAction
*action
,
831 if (editor
->priv
->text_dialog
== NULL
) {
832 editor
->priv
->text_dialog
=
833 e_html_editor_text_dialog_new (editor
);
836 gtk_window_present (GTK_WINDOW (editor
->priv
->text_dialog
));
840 action_redo_cb (GtkAction
*action
,
843 EHTMLEditorView
*view
= e_html_editor_get_view (editor
);
845 if (gtk_widget_has_focus (GTK_WIDGET (view
)))
846 webkit_web_view_redo (WEBKIT_WEB_VIEW (view
));
850 action_select_all_cb (GtkAction
*action
,
853 EHTMLEditorView
*view
= e_html_editor_get_view (editor
);
855 if (gtk_widget_has_focus (GTK_WIDGET (view
)))
856 webkit_web_view_select_all (WEBKIT_WEB_VIEW (view
));
860 action_show_find_cb (GtkAction
*action
,
863 if (editor
->priv
->find_dialog
== NULL
) {
864 editor
->priv
->find_dialog
= e_html_editor_find_dialog_new (editor
);
865 gtk_action_set_sensitive (ACTION (FIND_AGAIN
), TRUE
);
868 gtk_window_present (GTK_WINDOW (editor
->priv
->find_dialog
));
872 action_find_again_cb (GtkAction
*action
,
875 if (editor
->priv
->find_dialog
== NULL
)
878 e_html_editor_find_dialog_find_next (
879 E_HTML_EDITOR_FIND_DIALOG (editor
->priv
->find_dialog
));
883 action_show_replace_cb (GtkAction
*action
,
886 if (editor
->priv
->replace_dialog
== NULL
) {
887 editor
->priv
->replace_dialog
=
888 e_html_editor_replace_dialog_new (editor
);
891 gtk_window_present (GTK_WINDOW (editor
->priv
->replace_dialog
));
895 action_spell_check_cb (GtkAction
*action
,
898 if (editor
->priv
->spell_check_dialog
== NULL
) {
899 editor
->priv
->spell_check_dialog
=
900 e_html_editor_spell_check_dialog_new (editor
);
903 gtk_window_present (GTK_WINDOW (editor
->priv
->spell_check_dialog
));
907 action_undo_cb (GtkAction
*action
,
910 EHTMLEditorView
*view
= e_html_editor_get_view (editor
);
912 if (gtk_widget_has_focus (GTK_WIDGET (view
)))
913 webkit_web_view_undo (WEBKIT_WEB_VIEW (view
));
917 action_unindent_cb (GtkAction
*action
,
920 EHTMLEditorView
*view
= e_html_editor_get_view (editor
);
922 if (gtk_widget_has_focus (GTK_WIDGET (view
)))
923 e_html_editor_selection_unindent (editor
->priv
->selection
);
927 action_wrap_lines_cb (GtkAction
*action
,
930 EHTMLEditorView
*view
= e_html_editor_get_view (editor
);
932 if (gtk_widget_has_focus (GTK_WIDGET (view
)))
933 e_html_editor_selection_wrap_lines (editor
->priv
->selection
);
937 action_show_webkit_inspector_cb (GtkAction
*action
,
940 WebKitWebInspector
*inspector
;
941 EHTMLEditorView
*view
;
943 view
= e_html_editor_get_view (editor
);
944 inspector
= webkit_web_view_get_inspector (WEBKIT_WEB_VIEW (view
));
946 webkit_web_inspector_show (inspector
);
949 /*****************************************************************************
952 * These actions are always enabled.
953 *****************************************************************************/
955 static GtkActionEntry core_entries
[] = {
961 N_("Copy selected text to the clipboard"),
962 G_CALLBACK (action_copy_cb
) },
968 N_("Cut selected text to the clipboard"),
969 G_CALLBACK (action_cut_cb
) },
974 NULL
, /* Widgets are treating Ctrl + v shortcut themselves */
975 N_("Paste text from the clipboard"),
976 G_CALLBACK (action_paste_cb
) },
982 N_("Redo the last undone action"),
983 G_CALLBACK (action_redo_cb
) },
990 G_CALLBACK (action_select_all_cb
) },
996 N_("Undo the last action"),
997 G_CALLBACK (action_undo_cb
) },
1022 { "paragraph-style-menu",
1024 N_("_Paragraph Style"),
1045 N_("Current _Languages"),
1058 static GtkActionEntry core_editor_entries
[] = {
1061 "format-indent-more",
1062 N_("_Increase Indent"),
1063 "<Control>bracketright",
1064 N_("Increase Indent"),
1065 G_CALLBACK (action_indent_cb
) },
1067 { "insert-html-file",
1069 N_("_HTML File..."),
1072 G_CALLBACK (action_insert_html_file_cb
) },
1074 { "insert-text-file",
1076 N_("Te_xt File..."),
1079 G_CALLBACK (action_insert_text_file_cb
) },
1083 N_("Paste _Quotation"),
1084 "<Shift><Control>v",
1086 G_CALLBACK (action_paste_quote_cb
) },
1092 N_("Search for text"),
1093 G_CALLBACK (action_show_find_cb
) },
1100 G_CALLBACK (action_find_again_cb
) },
1103 "edit-find-replace",
1106 N_("Search for and replace text"),
1107 G_CALLBACK (action_show_replace_cb
) },
1110 "tools-check-spelling",
1111 N_("Check _Spelling..."),
1114 G_CALLBACK (action_spell_check_cb
) },
1117 "format-indent-less",
1118 N_("_Decrease Indent"),
1119 "<Control>bracketleft",
1120 N_("Decrease Indent"),
1121 G_CALLBACK (action_unindent_cb
) },
1128 G_CALLBACK (action_wrap_lines_cb
) },
1130 { "webkit-inspector",
1132 N_("Open Inspector"),
1135 G_CALLBACK (action_show_webkit_inspector_cb
) },
1138 static GtkRadioActionEntry core_justify_entries
[] = {
1141 "format-justify-center",
1144 N_("Center Alignment"),
1145 E_HTML_EDITOR_SELECTION_ALIGNMENT_CENTER
},
1148 "format-justify-left",
1151 N_("Left Alignment"),
1152 E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT
},
1155 "format-justify-right",
1158 N_("Right Alignment"),
1159 E_HTML_EDITOR_SELECTION_ALIGNMENT_RIGHT
}
1162 static GtkRadioActionEntry core_mode_entries
[] = {
1168 N_("HTML editing mode"),
1169 TRUE
}, /* e_html_editor_view_set_html_mode */
1175 N_("Plain text editing mode"),
1176 FALSE
} /* e_html_editor_view_set_html_mode */
1179 static GtkRadioActionEntry core_style_entries
[] = {
1186 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH
},
1193 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H1
},
1200 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H2
},
1207 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H3
},
1214 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H4
},
1221 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H5
},
1228 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_H6
},
1230 { "style-preformat",
1232 N_("_Preformatted"),
1235 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PRE
},
1242 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ADDRESS
},
1244 { "style-blockquote",
1249 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_BLOCKQUOTE
},
1251 { "style-list-bullet",
1253 N_("_Bulleted List"),
1256 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST
},
1258 { "style-list-roman",
1260 N_("_Roman Numeral List"),
1263 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ROMAN
},
1265 { "style-list-number",
1267 N_("Numbered _List"),
1270 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST
},
1272 { "style-list-alpha",
1274 N_("_Alphabetical List"),
1277 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA
}
1280 /*****************************************************************************
1281 * Core Actions (HTML only)
1283 * These actions are only enabled in HTML mode.
1284 *****************************************************************************/
1286 static GtkActionEntry html_entries
[] = {
1292 /* Translators: This is an action tooltip */
1294 G_CALLBACK (action_insert_image_cb
) },
1301 G_CALLBACK (action_insert_link_cb
) },
1304 "stock_insert-rule",
1305 /* Translators: 'Rule' here means a horizontal line in an HTML text */
1308 /* Translators: 'Rule' here means a horizontal line in an HTML text */
1310 G_CALLBACK (action_insert_rule_cb
) },
1313 "stock_insert-table",
1317 G_CALLBACK (action_insert_table_cb
) },
1319 { "properties-cell",
1324 G_CALLBACK (action_properties_cell_cb
) },
1326 { "properties-image",
1331 G_CALLBACK (action_properties_image_cb
) },
1333 { "properties-link",
1338 G_CALLBACK (action_properties_link_cb
) },
1340 { "properties-page",
1345 G_CALLBACK (action_properties_page_cb
) },
1347 { "properties-rule",
1349 /* Translators: 'Rule' here means a horizontal line in an HTML text */
1353 G_CALLBACK (action_properties_rule_cb
) },
1355 { "properties-table",
1360 G_CALLBACK (action_properties_table_cb
) },
1371 { "font-style-menu",
1380 N_("Paste As _Text"),
1383 G_CALLBACK (action_paste_as_text_cb
) },
1387 static GtkToggleActionEntry html_toggle_entries
[] = {
1398 "format-text-italic",
1406 "stock_text-monospaced",
1414 "format-text-strikethrough",
1415 N_("_Strikethrough"),
1417 N_("Strikethrough"),
1422 "format-text-underline",
1430 static GtkRadioActionEntry html_size_entries
[] = {
1434 /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as possible. */
1438 E_HTML_EDITOR_SELECTION_FONT_SIZE_TINY
},
1442 /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as possible. */
1446 E_HTML_EDITOR_SELECTION_FONT_SIZE_SMALL
},
1450 /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as possible. */
1454 E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL
},
1458 /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as possible. */
1462 E_HTML_EDITOR_SELECTION_FONT_SIZE_BIG
},
1466 /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as possible. */
1470 E_HTML_EDITOR_SELECTION_FONT_SIZE_BIGGER
},
1472 { "size-plus-three",
1474 /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as possible. */
1478 E_HTML_EDITOR_SELECTION_FONT_SIZE_LARGE
},
1482 /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as possible. */
1486 E_HTML_EDITOR_SELECTION_FONT_SIZE_VERY_LARGE
}
1489 /*****************************************************************************
1490 * Context Menu Actions
1492 * These require separate action entries so we can toggle their visiblity
1493 * rather than their sensitivity as we do with main menu / toolbar actions.
1494 * Note that some of these actions use the same callback function as their
1495 * non-context sensitive counterparts.
1496 *****************************************************************************/
1498 static GtkActionEntry context_entries
[] = {
1500 { "context-delete-cell",
1502 N_("Cell Contents"),
1505 G_CALLBACK (action_context_delete_cell_cb
) },
1507 { "context-delete-column",
1512 G_CALLBACK (action_context_delete_column_cb
) },
1514 { "context-delete-row",
1519 G_CALLBACK (action_context_delete_row_cb
) },
1521 { "context-delete-table",
1526 G_CALLBACK (action_context_delete_table_cb
) },
1530 { "context-delete-table-menu",
1532 /* Translators: Popup menu item caption, containing all the Delete options for a table */
1538 { "context-input-methods-menu",
1540 N_("Input Methods"),
1545 { "context-insert-table-menu",
1547 /* Translators: Popup menu item caption, containing all the Insert options for a table */
1553 { "context-properties-menu",
1561 /*****************************************************************************
1562 * Context Menu Actions (HTML only)
1564 * These actions are never visible in plain-text mode. Note that some
1565 * of them use the same callback function as their non-context sensitive
1567 *****************************************************************************/
1569 static GtkActionEntry html_context_entries
[] = {
1571 { "context-insert-column-after",
1576 G_CALLBACK (action_context_insert_column_after_cb
) },
1578 { "context-insert-column-before",
1580 N_("Column Before"),
1583 G_CALLBACK (action_context_insert_column_before_cb
) },
1585 { "context-insert-link",
1590 G_CALLBACK (action_insert_link_cb
) },
1592 { "context-insert-row-above",
1597 G_CALLBACK (action_context_insert_row_above_cb
) },
1599 { "context-insert-row-below",
1604 G_CALLBACK (action_context_insert_row_below_cb
) },
1606 { "context-insert-table",
1611 G_CALLBACK (action_insert_table_cb
) },
1613 { "context-properties-cell",
1618 G_CALLBACK (action_properties_cell_cb
) },
1620 { "context-properties-image",
1625 G_CALLBACK (action_properties_image_cb
) },
1627 { "context-properties-link",
1632 G_CALLBACK (action_properties_link_cb
) },
1634 { "context-properties-page",
1639 G_CALLBACK (action_properties_page_cb
) },
1641 { "context-properties-paragraph",
1646 G_CALLBACK (action_properties_paragraph_cb
) },
1648 { "context-properties-rule",
1650 /* Translators: 'Rule' here means a horizontal line in an HTML text */
1654 G_CALLBACK (action_properties_rule_cb
) },
1656 { "context-properties-table",
1661 G_CALLBACK (action_properties_table_cb
) },
1663 { "context-properties-text",
1668 G_CALLBACK (action_properties_text_cb
) },
1670 { "context-remove-link",
1675 G_CALLBACK (action_context_remove_link_cb
) }
1678 /*****************************************************************************
1679 * Context Menu Actions (spell checking only)
1681 * These actions are only visible when the word underneath the cursor is
1683 *****************************************************************************/
1685 static GtkActionEntry spell_context_entries
[] = {
1687 { "context-spell-add",
1689 N_("Add Word to Dictionary"),
1692 G_CALLBACK (action_context_spell_add_cb
) },
1694 { "context-spell-ignore",
1696 N_("Ignore Misspelled Word"),
1699 G_CALLBACK (action_context_spell_ignore_cb
) },
1701 { "context-spell-add-menu",
1710 { "context-more-suggestions-menu",
1712 N_("More Suggestions"),
1719 editor_actions_setup_languages_menu (EHTMLEditor
*editor
)
1721 ESpellChecker
*checker
;
1722 EHTMLEditorView
*view
;
1723 GtkUIManager
*manager
;
1724 GtkActionGroup
*action_group
;
1728 manager
= editor
->priv
->manager
;
1729 action_group
= editor
->priv
->language_actions
;
1730 view
= e_html_editor_get_view (editor
);
1731 checker
= e_html_editor_view_get_spell_checker (view
);
1732 merge_id
= gtk_ui_manager_new_merge_id (manager
);
1734 list
= e_spell_checker_list_available_dicts (checker
);
1736 for (link
= list
; link
!= NULL
; link
= g_list_next (link
)) {
1737 ESpellDictionary
*dictionary
= link
->data
;
1738 GtkToggleAction
*action
;
1741 action
= gtk_toggle_action_new (
1742 e_spell_dictionary_get_code (dictionary
),
1743 e_spell_dictionary_get_name (dictionary
),
1746 /* Do this BEFORE connecting to the "toggled" signal.
1747 * We're not prepared to invoke the signal handler yet.
1748 * The "Add Word To" actions have not yet been added. */
1749 active
= e_spell_checker_get_language_active (
1750 checker
, e_spell_dictionary_get_code (dictionary
));
1751 gtk_toggle_action_set_active (action
, active
);
1755 G_CALLBACK (action_language_cb
), editor
);
1757 gtk_action_group_add_action (
1758 action_group
, GTK_ACTION (action
));
1760 g_object_unref (action
);
1762 gtk_ui_manager_add_ui (
1764 "/main-menu/edit-menu/language-menu",
1765 e_spell_dictionary_get_code (dictionary
),
1766 e_spell_dictionary_get_code (dictionary
),
1767 GTK_UI_MANAGER_AUTO
, FALSE
);
1774 editor_actions_setup_spell_check_menu (EHTMLEditor
*editor
)
1776 ESpellChecker
*checker
;
1777 GtkUIManager
*manager
;
1778 GtkActionGroup
*action_group
;
1779 GList
*available_dicts
, *iter
;
1782 manager
= editor
->priv
->manager
;
1783 action_group
= editor
->priv
->spell_check_actions
;;
1784 checker
= e_html_editor_view_get_spell_checker (editor
->priv
->html_editor_view
);
1785 available_dicts
= e_spell_checker_list_available_dicts (checker
);
1786 merge_id
= gtk_ui_manager_new_merge_id (manager
);
1788 for (iter
= available_dicts
; iter
; iter
= iter
->next
) {
1789 ESpellDictionary
*dictionary
= iter
->data
;
1793 gchar
*action_label
;
1796 code
= e_spell_dictionary_get_code (dictionary
);
1797 name
= e_spell_dictionary_get_name (dictionary
);
1799 /* Add a suggestion menu. */
1800 action_name
= g_strdup_printf (
1801 "context-spell-suggest-%s-menu", code
);
1803 action
= gtk_action_new (action_name
, name
, NULL
, NULL
);
1804 gtk_action_group_add_action (action_group
, action
);
1805 g_object_unref (action
);
1807 gtk_ui_manager_add_ui (
1809 "/context-menu/context-spell-suggest",
1810 action_name
, action_name
,
1811 GTK_UI_MANAGER_MENU
, FALSE
);
1813 g_free (action_name
);
1815 /* Add an item to the "Add Word To" menu. */
1816 action_name
= g_strdup_printf ("context-spell-add-%s", code
);
1817 /* Translators: %s will be replaced with the actual dictionary
1818 * name, where a user can add a word to. This is part of an
1819 * "Add Word To" submenu. */
1820 action_label
= g_strdup_printf (_("%s Dictionary"), name
);
1822 action
= gtk_action_new (
1823 action_name
, action_label
, NULL
, NULL
);
1827 G_CALLBACK (action_context_spell_add_cb
), editor
);
1829 /* Visibility is dependent on whether the
1830 * corresponding language action is active. */
1831 gtk_action_set_visible (action
, FALSE
);
1833 gtk_action_group_add_action (action_group
, action
);
1835 g_object_unref (action
);
1837 gtk_ui_manager_add_ui (
1839 "/context-menu/context-spell-add-menu",
1840 action_name
, action_name
,
1841 GTK_UI_MANAGER_AUTO
, FALSE
);
1843 g_free (action_label
);
1844 g_free (action_name
);
1847 g_list_free (available_dicts
);
1851 editor_actions_init (EHTMLEditor
*editor
)
1854 GtkActionGroup
*action_group
;
1855 GtkUIManager
*manager
;
1856 const gchar
*domain
;
1857 EHTMLEditorView
*view
;
1858 GSettings
*settings
;
1860 g_return_if_fail (E_IS_HTML_EDITOR (editor
));
1862 manager
= e_html_editor_get_ui_manager (editor
);
1863 domain
= GETTEXT_PACKAGE
;
1864 view
= e_html_editor_get_view (editor
);
1867 action_group
= editor
->priv
->core_actions
;
1868 gtk_action_group_set_translation_domain (action_group
, domain
);
1869 gtk_action_group_add_actions (
1870 action_group
, core_entries
,
1871 G_N_ELEMENTS (core_entries
), editor
);
1872 gtk_ui_manager_insert_action_group (manager
, action_group
, 0);
1874 action_group
= editor
->priv
->core_editor_actions
;
1875 gtk_action_group_set_translation_domain (action_group
, domain
);
1876 gtk_action_group_add_actions (
1877 action_group
, core_editor_entries
,
1878 G_N_ELEMENTS (core_editor_entries
), editor
);
1879 gtk_action_group_add_radio_actions (
1880 action_group
, core_justify_entries
,
1881 G_N_ELEMENTS (core_justify_entries
),
1882 E_HTML_EDITOR_SELECTION_ALIGNMENT_LEFT
,
1884 gtk_action_group_add_radio_actions (
1885 action_group
, core_mode_entries
,
1886 G_N_ELEMENTS (core_mode_entries
),
1888 G_CALLBACK (action_mode_cb
), editor
);
1889 gtk_action_group_add_radio_actions (
1890 action_group
, core_style_entries
,
1891 G_N_ELEMENTS (core_style_entries
),
1892 E_HTML_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH
,
1894 gtk_ui_manager_insert_action_group (manager
, action_group
, 0);
1896 action
= gtk_action_group_get_action (action_group
, "mode-html");
1897 g_object_bind_property (
1899 action
, "current-value",
1900 G_BINDING_BIDIRECTIONAL
| G_BINDING_SYNC_CREATE
);
1902 /* Synchronize wiget mode with the buttons */
1903 e_html_editor_view_set_html_mode (view
, TRUE
);
1906 action
= e_emoticon_action_new (
1907 "insert-emoticon", _("_Emoticon"),
1908 _("Insert Emoticon"), NULL
);
1909 g_object_set (action
, "icon-name", "face-smile", NULL
);
1911 action
, "item-activated",
1912 G_CALLBACK (action_insert_emoticon_cb
), editor
);
1913 gtk_action_group_add_action (action_group
, action
);
1914 g_object_unref (action
);
1916 /* Core Actions (HTML only) */
1917 action_group
= editor
->priv
->html_actions
;
1918 gtk_action_group_set_translation_domain (action_group
, domain
);
1919 gtk_action_group_add_actions (
1920 action_group
, html_entries
,
1921 G_N_ELEMENTS (html_entries
), editor
);
1922 gtk_action_group_add_toggle_actions (
1923 action_group
, html_toggle_entries
,
1924 G_N_ELEMENTS (html_toggle_entries
), editor
);
1925 gtk_action_group_add_radio_actions (
1926 action_group
, html_size_entries
,
1927 G_N_ELEMENTS (html_size_entries
),
1928 E_HTML_EDITOR_SELECTION_FONT_SIZE_NORMAL
,
1930 gtk_ui_manager_insert_action_group (manager
, action_group
, 0);
1932 /* Context Menu Actions */
1933 action_group
= editor
->priv
->context_actions
;
1934 gtk_action_group_set_translation_domain (action_group
, domain
);
1935 gtk_action_group_add_actions (
1936 action_group
, context_entries
,
1937 G_N_ELEMENTS (context_entries
), editor
);
1938 gtk_ui_manager_insert_action_group (manager
, action_group
, 0);
1940 /* Context Menu Actions (HTML only) */
1941 action_group
= editor
->priv
->html_context_actions
;
1942 gtk_action_group_set_translation_domain (action_group
, domain
);
1943 gtk_action_group_add_actions (
1944 action_group
, html_context_entries
,
1945 G_N_ELEMENTS (html_context_entries
), editor
);
1946 gtk_ui_manager_insert_action_group (manager
, action_group
, 0);
1948 /* Context Menu Actions (spell check only) */
1949 action_group
= editor
->priv
->spell_check_actions
;
1950 gtk_action_group_set_translation_domain (action_group
, domain
);
1951 gtk_action_group_add_actions (
1952 action_group
, spell_context_entries
,
1953 G_N_ELEMENTS (spell_context_entries
), editor
);
1954 gtk_ui_manager_insert_action_group (manager
, action_group
, 0);
1956 /* Language actions are generated dynamically. */
1957 editor_actions_setup_languages_menu (editor
);
1958 action_group
= editor
->priv
->language_actions
;
1959 gtk_ui_manager_insert_action_group (manager
, action_group
, 0);
1961 /* Some spell check actions are generated dynamically. */
1962 action_group
= editor
->priv
->suggestion_actions
;
1963 editor_actions_setup_spell_check_menu (editor
);
1964 gtk_ui_manager_insert_action_group (manager
, action_group
, 0);
1966 /* Do this after all language actions are initialized. */
1967 editor_update_static_spell_actions (editor
);
1972 G_OBJECT (ACTION (SHOW_FIND
)),
1973 "short-label", _("_Find"), NULL
);
1975 G_OBJECT (ACTION (SHOW_REPLACE
)),
1976 "short-label", _("Re_place"), NULL
);
1978 G_OBJECT (ACTION (INSERT_IMAGE
)),
1979 "short-label", _("_Image"), NULL
);
1981 G_OBJECT (ACTION (INSERT_LINK
)),
1982 "short-label", _("_Link"), NULL
);
1984 G_OBJECT (ACTION (INSERT_RULE
)),
1985 /* Translators: 'Rule' here means a horizontal line in an HTML text */
1986 "short-label", _("_Rule"), NULL
);
1988 G_OBJECT (ACTION (INSERT_TABLE
)),
1989 "short-label", _("_Table"), NULL
);
1991 gtk_action_set_sensitive (ACTION (UNINDENT
), FALSE
);
1992 gtk_action_set_sensitive (ACTION (FIND_AGAIN
), FALSE
);
1994 g_object_bind_property (
1996 ACTION (REDO
), "sensitive",
1997 G_BINDING_SYNC_CREATE
);
1998 g_object_bind_property (
2000 ACTION (UNDO
), "sensitive",
2001 G_BINDING_SYNC_CREATE
);
2002 g_object_bind_property (
2004 ACTION (COPY
), "sensitive",
2005 G_BINDING_SYNC_CREATE
);
2006 g_object_bind_property (
2008 ACTION (CUT
), "sensitive",
2009 G_BINDING_SYNC_CREATE
);
2010 g_object_bind_property (
2012 ACTION (PASTE
), "sensitive",
2013 G_BINDING_SYNC_CREATE
);
2015 /* This is connected to JUSTIFY_LEFT action only, but
2016 * it automatically applies on all actions in the group. */
2017 g_object_bind_property (
2018 editor
->priv
->selection
, "alignment",
2019 ACTION (JUSTIFY_LEFT
), "current-value",
2020 G_BINDING_SYNC_CREATE
| G_BINDING_BIDIRECTIONAL
);
2021 g_object_bind_property (
2022 editor
->priv
->selection
, "bold",
2023 ACTION (BOLD
), "active",
2024 G_BINDING_SYNC_CREATE
| G_BINDING_BIDIRECTIONAL
);
2025 g_object_bind_property (
2026 editor
->priv
->selection
, "font-size",
2027 ACTION (FONT_SIZE_GROUP
), "current-value",
2028 G_BINDING_SYNC_CREATE
| G_BINDING_BIDIRECTIONAL
);
2029 g_object_bind_property (
2030 editor
->priv
->selection
, "block-format",
2031 ACTION (STYLE_NORMAL
), "current-value",
2032 G_BINDING_SYNC_CREATE
| G_BINDING_BIDIRECTIONAL
);
2033 g_object_bind_property (
2034 editor
->priv
->selection
, "indented",
2035 ACTION (UNINDENT
), "sensitive",
2036 G_BINDING_SYNC_CREATE
);
2037 g_object_bind_property (
2038 editor
->priv
->selection
, "italic",
2039 ACTION (ITALIC
), "active",
2040 G_BINDING_SYNC_CREATE
| G_BINDING_BIDIRECTIONAL
);
2041 g_object_bind_property (
2042 editor
->priv
->selection
, "monospaced",
2043 ACTION (MONOSPACED
), "active",
2044 G_BINDING_SYNC_CREATE
| G_BINDING_BIDIRECTIONAL
);
2045 g_object_bind_property (
2046 editor
->priv
->selection
, "strikethrough",
2047 ACTION (STRIKETHROUGH
), "active",
2048 G_BINDING_SYNC_CREATE
| G_BINDING_BIDIRECTIONAL
);
2049 g_object_bind_property (
2050 editor
->priv
->selection
, "underline",
2051 ACTION (UNDERLINE
), "active",
2052 G_BINDING_SYNC_CREATE
| G_BINDING_BIDIRECTIONAL
);
2054 /* Disable all actions and toolbars when editor is not editable */
2055 g_object_bind_property (
2057 editor
->priv
->core_editor_actions
, "sensitive",
2058 G_BINDING_SYNC_CREATE
);
2059 g_object_bind_property (
2061 editor
->priv
->html_actions
, "sensitive",
2062 G_BINDING_SYNC_CREATE
);
2063 g_object_bind_property (
2065 editor
->priv
->spell_check_actions
, "sensitive",
2066 G_BINDING_SYNC_CREATE
);
2067 g_object_bind_property (
2069 editor
->priv
->suggestion_actions
, "sensitive",
2070 G_BINDING_SYNC_CREATE
);
2072 settings
= e_util_ref_settings ("org.gnome.evolution.mail");
2073 gtk_action_set_visible (
2074 ACTION (WEBKIT_INSPECTOR
),
2075 g_settings_get_boolean (settings
, "composer-developer-mode"));
2076 g_object_unref (settings
);