[evolution/webkit-composer: 10/231] Initial import of GtkhtmlEditor class
- From: Tomas Popela <tpopela src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/webkit-composer: 10/231] Initial import of GtkhtmlEditor class
- Date: Fri, 13 Sep 2013 14:06:50 +0000 (UTC)
commit ce1dc48cdb461a3fd2a13a56f721bd6a69becafc
Author: Dan Vrátil <dvratil redhat com>
Date: Thu Jul 26 21:18:08 2012 +0200
Initial import of GtkhtmlEditor class
GtkhtmlEditor => EEditor
EEditor is a GtkBox which handles installation of menu actions and toolbars and
bindings between EEditorWidget and these actions.
As of now, only elementary formatting works.
e-util/Makefile.am | 6 +
e-util/e-editor-actions.c | 2438 +++++++++++++++++++++++++++++++++++++++++++++
e-util/e-editor-actions.h | 152 +++
e-util/e-editor-private.h | 72 ++
e-util/e-editor-widgets.h | 234 +++++
e-util/e-editor.c | 576 +++++++++++
e-util/e-editor.h | 95 ++
e-util/e-util.h | 3 +
8 files changed, 3576 insertions(+), 0 deletions(-)
---
diff --git a/e-util/Makefile.am b/e-util/Makefile.am
index f4ee068..165109b 100644
--- a/e-util/Makefile.am
+++ b/e-util/Makefile.am
@@ -175,8 +175,11 @@ evolution_util_include_HEADERS = \
e-destination-store.h \
e-dialog-utils.h \
e-dialog-widgets.h \
+ e-editor-actions.h \
e-editor-selection.h \
e-editor-widget.h \
+ e-editor-widgets.h \
+ e-editor.h \
e-emoticon-action.h \
e-emoticon-chooser-menu.h \
e-emoticon-chooser.h \
@@ -423,8 +426,11 @@ libevolution_util_la_SOURCES = \
e-destination-store.c \
e-dialog-utils.c \
e-dialog-widgets.c \
+ e-editor-actions.c \
+ e-editor-private.h \
e-editor-selection.c \
e-editor-widget.c \
+ e-editor.c \
e-emoticon-action.c \
e-emoticon-chooser-menu.c \
e-emoticon-chooser.c \
diff --git a/e-util/e-editor-actions.c b/e-util/e-editor-actions.c
new file mode 100644
index 0000000..74f89f3
--- /dev/null
+++ b/e-util/e-editor-actions.c
@@ -0,0 +1,2438 @@
+/* e-editor-actions.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+//#include "e-editor-private.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gio/gio.h>
+#include <glib/gi18n-lib.h>
+#include <string.h>
+
+#include "e-editor.h"
+#include "e-editor-actions.h"
+#include "e-editor-private.h"
+#include "e-editor-widgets.h"
+#include "e-emoticon-action.h"
+#include "e-image-chooser-dialog.h"
+
+static void
+insert_html_file_ready_cb (GFile *file,
+ GAsyncResult *result,
+ EEditor *editor)
+{
+ EEditorSelection *selection;
+ gchar *contents = NULL;
+ gsize length;
+ GError *error = NULL;
+
+ g_file_load_contents_finish (
+ file, result, &contents, &length, NULL, &error);
+ if (error != NULL) {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (
+ GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (editor))),
+ 0, GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE, _("Failed to insert HTML file."));
+ gtk_message_dialog_format_secondary_text (
+ GTK_MESSAGE_DIALOG (dialog), "%s.", error->message);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ g_clear_error (&error);
+ g_object_unref (editor);
+ return;
+ }
+
+ selection = e_editor_widget_get_selection (
+ e_editor_get_editor_widget (editor));
+ e_editor_selection_insert_html (selection, contents);
+ g_free (contents);
+
+ g_object_unref (editor);
+}
+
+static void
+insert_text_file_ready_cb (GFile *file,
+ GAsyncResult *result,
+ EEditor *editor)
+{
+ EEditorSelection *selection;
+ gchar *contents;
+ gsize length;
+ GError *error = NULL;
+
+ g_file_load_contents_finish (
+ file, result, &contents, &length, NULL, &error);
+ if (error != NULL) {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (
+ GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (editor))),
+ 0, GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE, _("Failed to insert text file."));
+ gtk_message_dialog_format_secondary_text (
+ GTK_MESSAGE_DIALOG (dialog), "%s.", error->message);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ g_clear_error (&error);
+ g_object_unref (editor);
+ return;
+ }
+
+ selection = e_editor_widget_get_selection (
+ e_editor_get_editor_widget (editor));
+ e_editor_selection_insert_text (selection, contents);
+ g_free (contents);
+
+ g_object_unref (editor);
+}
+
+static void
+replace_answer (EEditor *editor,
+ EEditorWidgetReplaceAnswer answer)
+{
+ /* FIXME WEBKIT
+ if (e_editor_widget_replace (e_editor_get_editor_widget (editor), answer))
+ gtk_widget_hide (WIDGET (REPLACE_CONFIRMATION_WINDOW));
+ */
+}
+
+/*****************************************************************************
+ * Action Callbacks
+ *****************************************************************************/
+
+static void
+action_bold_cb (GtkToggleAction *action,
+ EEditor *editor)
+{
+ EEditorSelection *selection;
+
+ selection = e_editor_widget_get_selection (
+ e_editor_get_editor_widget (editor));
+ e_editor_selection_set_bold (
+ selection, gtk_toggle_action_get_active (action));
+}
+
+
+static void
+action_confirm_replace_cb (GtkAction *action,
+ EEditor *editor)
+{
+ replace_answer (editor, E_EDITOR_WIDGET_REPLACE_ANSWER_REPLACE);
+}
+
+static void
+action_confirm_replace_all_cb (GtkAction *action,
+ EEditor *editor)
+{
+ replace_answer (editor, E_EDITOR_WIDGET_REPLACE_ANSWER_REPLACE_ALL);
+}
+
+static void
+action_confirm_replace_cancel_cb (GtkAction *action,
+ EEditor *editor)
+{
+ replace_answer (editor, E_EDITOR_WIDGET_REPLACE_ANSWER_CANCEL);
+}
+
+static void
+action_confirm_replace_next_cb (GtkAction *action,
+ EEditor *editor)
+{
+ replace_answer (editor, E_EDITOR_WIDGET_REPLACE_ANSWER_NEXT);
+}
+
+static WebKitDOMNode *
+find_parent_element_by_type (WebKitDOMNode *node, GType type)
+{
+ while (node) {
+
+ if (g_type_is_a (type, webkit_dom_node_get_type ()))
+ return node;
+
+ node = webkit_dom_node_get_parent_node (node);
+ }
+
+ return NULL;
+}
+
+static void
+action_context_delete_cell_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMRange *range;
+ WebKitDOMNode *start, *end, *cell;
+ gboolean single_row;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ window = webkit_dom_document_get_default_view (document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (webkit_dom_dom_selection_get_range_count (selection) < 1)
+ return;
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+
+ /* Find TD in which the selection starts */
+ start = webkit_dom_range_get_start_container (range, NULL);
+ if (!WEBKIT_DOM_IS_HTML_TABLE_CELL_ELEMENT (start)) {
+ start = find_parent_element_by_type (
+ start, WEBKIT_TYPE_DOM_HTML_TABLE_CELL_ELEMENT);
+ }
+
+ /* Find TD in which the selection ends */
+ end = webkit_dom_range_get_end_container (range, NULL);
+ if (!WEBKIT_DOM_IS_HTML_TABLE_CELL_ELEMENT (end)) {
+ end = find_parent_element_by_type (
+ end, WEBKIT_TYPE_DOM_HTML_TABLE_CELL_ELEMENT);
+ }
+
+ single_row = (webkit_dom_node_get_parent_node (start) ==
+ webkit_dom_node_get_parent_node (end));
+
+ cell = start;
+ while (cell) {
+ WebKitDOMNodeList *nodes;
+ gulong length, i;
+
+ /* Remove all child nodes in the cell */
+ nodes = webkit_dom_node_get_child_nodes (cell);
+ length = webkit_dom_node_list_get_length (nodes);
+ for (i = 0; i < length; i++) {
+ webkit_dom_node_remove_child (
+ cell,
+ webkit_dom_node_list_item (nodes, i),
+ NULL);
+ }
+
+ if (cell == end)
+ break;
+
+ cell = webkit_dom_node_get_next_sibling (cell);
+
+ if (!cell && !single_row) {
+ cell = webkit_dom_node_get_first_child (
+ webkit_dom_node_get_parent_node (cell));
+ }
+ }
+}
+
+static void
+action_context_delete_column_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMRange *range;
+ WebKitDOMNode *start, *end, *first_row;
+ gulong index, count, i;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ window = webkit_dom_document_get_default_view (document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (webkit_dom_dom_selection_get_range_count (selection) < 1) {
+ return;
+ }
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+
+ /* Find TD in which the selection starts */
+ start = webkit_dom_range_get_start_container (range, NULL);
+ if (!WEBKIT_DOM_IS_HTML_TABLE_CELL_ELEMENT (start)) {
+ start = find_parent_element_by_type (
+ start, WEBKIT_TYPE_DOM_HTML_TABLE_CELL_ELEMENT);
+ }
+
+ /* Find TD in which the selection ends */
+ end = webkit_dom_range_get_end_container (range, NULL);
+ if (!WEBKIT_DOM_IS_HTML_TABLE_CELL_ELEMENT (end)) {
+ end = find_parent_element_by_type (
+ end, WEBKIT_TYPE_DOM_HTML_TABLE_CELL_ELEMENT);
+ }
+
+ first_row = find_parent_element_by_type (
+ start, WEBKIT_TYPE_DOM_HTML_TABLE_ROW_ELEMENT);
+ first_row = webkit_dom_node_get_first_child (
+ webkit_dom_node_get_parent_node (first_row));
+
+ index = webkit_dom_html_table_cell_element_get_cell_index (
+ WEBKIT_DOM_HTML_TABLE_CELL_ELEMENT (start));
+ count = webkit_dom_html_table_cell_element_get_cell_index (
+ WEBKIT_DOM_HTML_TABLE_CELL_ELEMENT (end)) - index;
+
+ for (i = 0; i < count; i++) {
+ WebKitDOMNode *row = first_row;
+
+ while (row) {
+ webkit_dom_html_table_row_element_delete_cell (
+ WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row),
+ index, NULL);
+
+ row = webkit_dom_node_get_next_sibling (row);
+ }
+ }
+}
+
+static void
+action_context_delete_row_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMRange *range;
+ WebKitDOMNode *start, *end, *table;
+ gulong index, row_count, i;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ window = webkit_dom_document_get_default_view (document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (webkit_dom_dom_selection_get_range_count (selection) < 1)
+ return;
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+
+ start = webkit_dom_range_get_start_container (range, NULL);
+ if (!WEBKIT_DOM_IS_HTML_TABLE_ROW_ELEMENT (start)) {
+ start = find_parent_element_by_type (
+ start, WEBKIT_TYPE_DOM_HTML_TABLE_ROW_ELEMENT);
+ }
+
+ end = webkit_dom_range_get_end_container (range, NULL);
+ if (!WEBKIT_DOM_IS_HTML_TABLE_ROW_ELEMENT (end)) {
+ end = find_parent_element_by_type (
+ end, WEBKIT_TYPE_DOM_HTML_TABLE_ROW_ELEMENT);
+ }
+
+ table = find_parent_element_by_type (
+ start, WEBKIT_TYPE_DOM_HTML_TABLE_ELEMENT);
+
+ index = webkit_dom_html_table_row_element_get_row_index (
+ WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (start));
+ row_count = webkit_dom_html_table_row_element_get_row_index (
+ WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (end)) - index;
+
+ for (i = 0; i < row_count; i++) {
+ webkit_dom_html_table_element_delete_row (
+ WEBKIT_DOM_HTML_TABLE_ELEMENT (table), index, NULL);
+ }
+}
+
+static void
+action_context_delete_table_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMRange *range;
+ WebKitDOMNode *table;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ window = webkit_dom_document_get_default_view (document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (webkit_dom_dom_selection_get_range_count (selection) < 1)
+ return;
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+
+ table = webkit_dom_range_get_start_container (range, NULL);
+ if (!WEBKIT_DOM_IS_HTML_TABLE_ELEMENT (table)) {
+ table = find_parent_element_by_type (
+ table, WEBKIT_TYPE_DOM_HTML_TABLE_ELEMENT);
+ }
+
+ webkit_dom_node_remove_child (
+ webkit_dom_node_get_parent_node (table), table, NULL);
+}
+
+static void
+action_context_insert_column_after_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMRange *range;
+ WebKitDOMNode *cell, *row;
+ gulong index;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ window = webkit_dom_document_get_default_view (document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (webkit_dom_dom_selection_get_range_count (selection) < 1)
+ return;
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+
+ cell = webkit_dom_range_get_end_container (range, NULL);
+ if (!WEBKIT_DOM_IS_HTML_TABLE_CELL_ELEMENT (cell)) {
+ cell = find_parent_element_by_type (
+ cell, WEBKIT_TYPE_DOM_HTML_TABLE_CELL_ELEMENT);
+ }
+
+ row = find_parent_element_by_type (
+ cell, WEBKIT_TYPE_DOM_HTML_TABLE_ROW_ELEMENT);
+ /* Get the first row in the table */
+ row = webkit_dom_node_get_first_child (
+ webkit_dom_node_get_parent_node (row));
+
+ index = webkit_dom_html_table_cell_element_get_cell_index (
+ WEBKIT_DOM_HTML_TABLE_CELL_ELEMENT (cell));
+
+ while (row) {
+ webkit_dom_html_table_row_element_insert_cell (
+ WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row), index + 1, NULL);
+
+ row = webkit_dom_node_get_next_sibling (row);
+ }
+}
+
+static void
+action_context_insert_column_before_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMRange *range;
+ WebKitDOMNode *cell, *row;
+ gulong index;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ window = webkit_dom_document_get_default_view (document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (webkit_dom_dom_selection_get_range_count (selection) < 1)
+ return;
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+
+ cell = webkit_dom_range_get_start_container (range, NULL);
+ if (!WEBKIT_DOM_IS_HTML_TABLE_CELL_ELEMENT (cell)) {
+ cell = find_parent_element_by_type (
+ cell, WEBKIT_TYPE_DOM_HTML_TABLE_CELL_ELEMENT);
+ }
+
+ row = find_parent_element_by_type (
+ cell, WEBKIT_TYPE_DOM_HTML_TABLE_ROW_ELEMENT);
+ /* Get the first row in the table */
+ row = webkit_dom_node_get_first_child (
+ webkit_dom_node_get_parent_node (row));
+
+ index = webkit_dom_html_table_cell_element_get_cell_index (
+ WEBKIT_DOM_HTML_TABLE_CELL_ELEMENT (cell));
+
+ while (row) {
+ webkit_dom_html_table_row_element_insert_cell (
+ WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row), index - 1, NULL);
+
+ row = webkit_dom_node_get_next_sibling (row);
+ }
+}
+
+static void
+action_context_insert_row_above_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMRange *range;
+ WebKitDOMNode *row, *table;
+ gulong index;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ window = webkit_dom_document_get_default_view (document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (webkit_dom_dom_selection_get_range_count (selection) < 1)
+ return;
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+
+ row = webkit_dom_range_get_start_container (range, NULL);
+ if (!WEBKIT_DOM_IS_HTML_TABLE_CELL_ELEMENT (row)) {
+ row = find_parent_element_by_type (
+ row, WEBKIT_TYPE_DOM_HTML_TABLE_ROW_ELEMENT);
+ }
+
+ table = find_parent_element_by_type (
+ row, WEBKIT_TYPE_DOM_HTML_TABLE_ELEMENT);
+
+ index = webkit_dom_html_table_row_element_get_row_index (
+ WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row));
+
+ webkit_dom_html_table_element_insert_row (
+ WEBKIT_DOM_HTML_TABLE_ELEMENT (table), index - 1, NULL);
+}
+
+static void
+action_context_insert_row_below_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMRange *range;
+ WebKitDOMNode *row, *table;
+ gulong index;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ window = webkit_dom_document_get_default_view (document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (webkit_dom_dom_selection_get_range_count (selection) < 1)
+ return;
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+
+ row = webkit_dom_range_get_end_container (range, NULL);
+ if (!WEBKIT_DOM_IS_HTML_TABLE_CELL_ELEMENT (row)) {
+ row = find_parent_element_by_type (
+ row, WEBKIT_TYPE_DOM_HTML_TABLE_ROW_ELEMENT);
+ }
+
+ table = find_parent_element_by_type (
+ row, WEBKIT_TYPE_DOM_HTML_TABLE_ELEMENT);
+
+ index = webkit_dom_html_table_row_element_get_row_index (
+ WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row));
+
+ webkit_dom_html_table_element_insert_row (
+ WEBKIT_DOM_HTML_TABLE_ELEMENT (table), index + 1, NULL);
+}
+
+static void
+action_context_remove_link_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ webkit_dom_document_exec_command (document, "unlink", FALSE, "");
+}
+
+static void
+action_context_spell_add_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMRange *range;
+ WebKitSpellChecker *spell_checker;
+ gchar *word;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ window = webkit_dom_document_get_default_view (document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (webkit_dom_dom_selection_get_range_count (selection) < 1)
+ return;
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+ word = webkit_dom_range_get_text (range);
+
+ spell_checker = WEBKIT_SPELL_CHECKER (webkit_get_text_checker ());
+ webkit_spell_checker_learn_word (spell_checker, word);
+
+ g_free (word);
+}
+
+static void
+action_context_spell_ignore_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMRange *range;
+ WebKitSpellChecker *spell_checker;
+ gchar *word;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ window = webkit_dom_document_get_default_view (document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (webkit_dom_dom_selection_get_range_count (selection) < 1)
+ return;
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+ word = webkit_dom_range_get_text (range);
+
+ spell_checker = WEBKIT_SPELL_CHECKER (webkit_get_text_checker ());
+ webkit_spell_checker_ignore_word (spell_checker, word);
+
+ g_free (word);
+}
+
+static void
+action_copy_cb (GtkAction *action,
+ EEditor *editor)
+{
+ webkit_web_view_copy_clipboard (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+}
+
+static void
+action_cut_cb (GtkAction *action,
+ EEditor *editor)
+{
+ webkit_web_view_cut_clipboard (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+}
+
+static void
+action_find_cb (GtkAction *action,
+ EEditor *editor)
+{
+ gboolean found;
+
+
+ found = webkit_web_view_search_text (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)),
+ gtk_entry_get_text (GTK_ENTRY (WIDGET (FIND_ENTRY))),
+ gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (WIDGET (FIND_CASE_SENSITIVE))),
+ !gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (WIDGET (FIND_BACKWARDS))),
+ gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (WIDGET (FIND_WRAP))));
+
+ gtk_action_set_sensitive (ACTION (FIND), found);
+
+ if (!found)
+ gtk_label_set_label (
+ GTK_LABEL (WIDGET (FIND_RESULT_LABEL)),
+ N_("No match found"));
+}
+
+static void
+action_find_again_cb (GtkAction *action,
+ EEditor *editor)
+{
+ /* FIXME WEBKIT
+ * Verify that this actually works and if so, then just change the
+ * callback and remove this function. If not, then we are in trouble...
+ */
+
+ action_find_cb (action, editor);
+}
+
+
+static void
+action_find_and_replace_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMNode *start, *end;
+ WebKitDOMNodeList *children;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMRange *range;
+ WebKitDOMNode *node;
+
+ gulong length, i;
+ const gchar *needle, *replacement;
+ gboolean case_sensitive, backwards, wrap, only_selection;
+
+ needle = gtk_entry_get_text (GTK_ENTRY (WIDGET (REPLACE_ENTRY)));
+ replacement = gtk_entry_get_text (
+ GTK_ENTRY (WIDGET (REPLACE_WITH_ENTRY)));
+ case_sensitive = gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (WIDGET (REPLACE_CASE_SENSITIVE)));
+ wrap = gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (WIDGET (REPLACE_WRAP)));
+ backwards = gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (WIDGET (REPLACE_BACKWARDS)));
+ only_selection = gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (WIDGET (REPLACE_ONLY_SELECTION)));
+
+ /* XXX Port this if to native WebKit API if they ever implement
+ * support for find&replace...unless this implementation
+ * is better ;) */
+
+ /* FIXME WEBKIT This is not working at all */
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ window = webkit_dom_document_get_default_view (document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (webkit_dom_dom_selection_get_range_count (selection) < 1)
+ return;
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+ start = webkit_dom_range_get_start_container (range, NULL);
+
+ if (only_selection) {
+ end = webkit_dom_range_get_end_container (range, NULL);
+ } else {
+ end = NULL;
+ }
+
+ /* WEBKIT FIXME Implement me! */
+ /*
+ node = start;
+ while (node && (node != end)) {
+
+
+
+ }
+ */
+
+ /*
+ html = gtkhtml_editor_get_html (editor);
+
+ gtk_widget_hide (WIDGET (REPLACE_WINDOW));
+
+ html_engine_replace (
+ html->engine,
+ gtk_entry_get_text (GTK_ENTRY (WIDGET (REPLACE_ENTRY))),
+ gtk_entry_get_text (GTK_ENTRY (WIDGET (REPLACE_WITH_ENTRY))),
+ gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (WIDGET (REPLACE_CASE_SENSITIVE))),
+ !gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (WIDGET (REPLACE_BACKWARDS))),
+ FALSE, replace_ask_cb, editor);
+ */
+}
+
+/* FIXME WEBKIT
+static void
+replace_ask_cb (HTMLEngine *engine,
+ gpointer data)
+{
+ GtkhtmlEditor *editor = data;
+
+ gtk_window_present (GTK_WINDOW (WIDGET (REPLACE_CONFIRMATION_WINDOW)));
+}
+
+static void
+replace_answer (GtkhtmlEditor *editor,
+ HTMLReplaceQueryAnswer answer)
+{
+ GtkHTML *html;
+
+ html = gtkhtml_editor_get_html (editor);
+
+ if (html_engine_replace_do (html->engine, answer))
+ gtk_widget_hide (WIDGET (REPLACE_CONFIRMATION_WINDOW));
+}
+*/
+
+static void
+action_indent_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ webkit_dom_document_exec_command (document, "indent", FALSE, "");
+}
+
+static void
+action_insert_emoticon_cb (GtkAction *action,
+ EEditor *editor)
+{
+ /* FIXME WEBKIT
+ GtkHTML *html;
+ HTMLObject *image;
+ GtkIconInfo *icon_info;
+ GtkIconTheme *icon_theme;
+ GtkhtmlFaceChooser *chooser;
+ GtkhtmlFace *face;
+ const gchar *filename;
+ gchar *uri = NULL;
+
+ html = gtkhtml_editor_get_html (editor);
+
+ chooser = GTKHTML_FACE_CHOOSER (action);
+ face = gtkhtml_face_chooser_get_current_face (chooser);
+ g_return_if_fail (face != NULL);
+
+ icon_theme = gtk_icon_theme_get_default ();
+ icon_info = gtk_icon_theme_lookup_icon (
+ icon_theme, face->icon_name, 16, 0);
+ g_return_if_fail (icon_info != NULL);
+
+ filename = gtk_icon_info_get_filename (icon_info);
+ if (filename != NULL)
+ uri = g_filename_to_uri (filename, NULL, NULL);
+ gtk_icon_info_free (icon_info);
+ g_return_if_fail (uri != NULL);
+
+ image = html_image_new (
+ html_engine_get_image_factory (html->engine),
+ uri, NULL, NULL, -1, -1, FALSE, FALSE, 0, NULL,
+ HTML_VALIGN_MIDDLE, FALSE);
+ html_image_set_alt (HTML_IMAGE (image), face->text_face);
+ html_engine_paste_object (
+ html->engine, image, html_object_get_length (image));
+
+ g_free (uri);
+ */
+}
+
+static void
+action_insert_html_file_cb (GtkToggleAction *action,
+ EEditor *editor)
+{
+ GtkWidget *dialog;
+ GtkFileFilter *filter;
+
+ dialog = gtk_file_chooser_dialog_new (
+ _("Insert HTML File"), NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, _("HTML file"));
+ gtk_file_filter_add_mime_type (filter, "text/html");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+ GFile *file = gtk_file_chooser_get_file (
+ GTK_FILE_CHOOSER (dialog));
+
+ /* XXX Need a way to cancel this. */
+ g_file_load_contents_async (
+ file, NULL, (GAsyncReadyCallback)
+ insert_html_file_ready_cb,
+ g_object_ref (editor));
+
+ g_object_unref (file);
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+action_insert_image_cb (GtkAction *action,
+ EEditor *editor)
+{
+ GtkWidget *dialog;
+
+ dialog = e_image_chooser_dialog_new (
+ _("Insert Image"), NULL);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+ gchar *uri;
+ EEditorSelection *selection;
+
+ uri = gtk_file_chooser_get_uri (
+ GTK_FILE_CHOOSER (dialog));
+
+ selection = e_editor_widget_get_selection (
+ e_editor_get_editor_widget (editor));
+ e_editor_selection_insert_image (selection, uri);
+ g_free (uri);
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+action_insert_link_cb (GtkAction *action,
+ EEditor *editor)
+{
+ /* FIXME WEBKIT */
+ gtk_window_present (GTK_WINDOW (WIDGET (LINK_PROPERTIES_WINDOW)));
+}
+
+static void
+action_insert_rule_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ webkit_dom_document_exec_command (
+ document, "insertHorizontalRule", FALSE, "");
+
+ /* FIXME WEBKIT - does the action work? */
+ gtk_action_activate (ACTION (PROPERTIES_RULE));
+}
+
+static void
+action_insert_table_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMElement *table;
+ WebKitDOMDOMWindow *window;
+ WebKitDOMDOMSelection *selection;
+ WebKitDOMRange *range;
+ gint i;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ window = webkit_dom_document_get_default_view (document);
+ selection = webkit_dom_dom_window_get_selection (window);
+ if (webkit_dom_dom_selection_get_range_count (selection) < 1)
+ return;
+
+ range = webkit_dom_dom_selection_get_range_at (selection, 0, NULL);
+
+ /* Default 3x3 table */
+ table = webkit_dom_document_create_element (document, "TABLE", NULL);
+ for (i = 0; i < 3; i++) {
+ WebKitDOMHTMLElement *row;
+ gint j;
+
+ row = webkit_dom_html_table_element_insert_row (
+ WEBKIT_DOM_HTML_TABLE_ELEMENT (table), -1, NULL);
+
+ for (j = 0; j < 3; j++) {
+ webkit_dom_html_table_row_element_insert_cell (
+ WEBKIT_DOM_HTML_TABLE_ROW_ELEMENT (row),
+ -1, NULL);
+ }
+ }
+
+ webkit_dom_range_insert_node (range, WEBKIT_DOM_NODE (table), NULL);
+
+ /* FIXME WEBKIT - does the action work? */
+ gtk_action_activate (ACTION (PROPERTIES_TABLE));
+}
+
+static void
+action_insert_text_file_cb (GtkAction *action,
+ EEditor *editor)
+{
+ GtkWidget *dialog;
+ GtkFileFilter *filter;
+
+ dialog = gtk_file_chooser_dialog_new (
+ _("Insert text file"), NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, _("Text file"));
+ gtk_file_filter_add_mime_type (filter, "text/plain");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+ GFile *file = gtk_file_chooser_get_file (
+ GTK_FILE_CHOOSER (dialog));
+
+ /* XXX Need a way to cancel this. */
+ g_file_load_contents_async (
+ file, NULL, (GAsyncReadyCallback)
+ insert_text_file_ready_cb,
+ g_object_ref (editor));
+
+ g_object_unref (file);
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+action_italic_cb (GtkToggleAction *action,
+ EEditor *editor)
+{
+ EEditorSelection *selection;
+
+ selection = e_editor_widget_get_selection (
+ e_editor_get_editor_widget (editor));
+ e_editor_selection_set_italic (
+ selection, gtk_toggle_action_get_active (action));
+}
+
+static void
+action_justify_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+ const gchar *command;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+
+ switch (gtk_radio_action_get_current_value (current))
+ {
+ case E_EDITOR_SELECTION_ALIGNMENT_CENTER:
+ command = "justifyCenter";
+ break;
+
+ case E_EDITOR_SELECTION_ALIGNMENT_LEFT:
+ command = "justifyLeft";
+ break;
+
+ case E_EDITOR_SELECTION_ALIGNMENT_RIGHT:
+ command = "justifyRight";
+ break;
+ }
+
+ webkit_dom_document_exec_command (document, command, FALSE, "");
+}
+
+static void
+action_language_cb (GtkToggleAction *action,
+ EEditor *editor)
+{
+ /* FIXME WEBKIT */
+ /*
+ const GtkhtmlSpellLanguage *language;
+ GtkhtmlSpellChecker *checker;
+ const gchar *language_code;
+ GtkAction *add_action;
+ GtkHTML *html;
+ GList *list;
+ guint length;
+ gchar *action_name;
+ gboolean active;
+
+ active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ language_code = gtk_action_get_name (GTK_ACTION (action));
+ language = gtkhtml_spell_language_lookup (language_code);
+
+ checker = g_hash_table_lookup (
+ editor->priv->available_spell_checkers, language);
+ g_return_if_fail (checker != NULL);
+
+ //Update the list of active spell checkers.
+ list = editor->priv->active_spell_checkers;
+ if (active)
+ list = g_list_insert_sorted (
+ list, g_object_ref (checker),
+ (GCompareFunc) gtkhtml_spell_checker_compare);
+ else {
+ GList *link;
+
+ link = g_list_find (list, checker);
+ g_return_if_fail (link != NULL);
+ list = g_list_delete_link (list, link);
+ g_object_unref (checker);
+ }
+ editor->priv->active_spell_checkers = list;
+ length = g_list_length (list);
+
+ // Update "Add Word To" context menu item visibility.
+ action_name = g_strdup_printf ("context-spell-add-%s", language_code);
+ add_action = gtkhtml_editor_get_action (editor, action_name);
+ gtk_action_set_visible (add_action, active);
+ g_free (action_name);
+
+ gtk_action_set_visible (ACTION (CONTEXT_SPELL_ADD), length == 1);
+ gtk_action_set_visible (ACTION (CONTEXT_SPELL_ADD_MENU), length > 1);
+ gtk_action_set_visible (ACTION (CONTEXT_SPELL_IGNORE), length > 0);
+
+ gtk_action_set_sensitive (ACTION (SPELL_CHECK), length > 0);
+
+ html = gtkhtml_editor_get_html (editor);
+ html_engine_spell_check (html->engine);
+
+ gtkthtml_editor_emit_spell_languages_changed (editor);
+ */
+}
+
+static void
+action_mode_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EEditor *editor)
+{
+ /* FIXME WEBKIT */
+ /*
+ GtkActionGroup *action_group;
+ HTMLPainter *new_painter;
+ HTMLPainter *old_painter;
+ GtkHTML *html;
+ EditorMode mode;
+ gboolean html_mode;
+
+ html = gtkhtml_editor_get_html (editor);
+ mode = gtk_radio_action_get_current_value (current);
+ html_mode = (mode == EDITOR_MODE_HTML);
+
+ action_group = editor->priv->html_actions;
+ gtk_action_group_set_sensitive (action_group, html_mode);
+
+ action_group = editor->priv->html_context_actions;
+ gtk_action_group_set_visible (action_group, html_mode);
+
+ gtk_widget_set_sensitive (editor->priv->color_combo_box, html_mode);
+
+ if (html_mode)
+ gtk_widget_show (editor->priv->html_toolbar);
+ else
+ gtk_widget_hide (editor->priv->html_toolbar);
+
+ // Certain paragraph styles are HTML-only.
+ gtk_action_set_sensitive (ACTION (STYLE_H1), html_mode);
+ gtk_action_set_sensitive (ACTION (STYLE_H2), html_mode);
+ gtk_action_set_sensitive (ACTION (STYLE_H3), html_mode);
+ gtk_action_set_sensitive (ACTION (STYLE_H4), html_mode);
+ gtk_action_set_sensitive (ACTION (STYLE_H5), html_mode);
+ gtk_action_set_sensitive (ACTION (STYLE_H6), html_mode);
+ gtk_action_set_sensitive (ACTION (STYLE_ADDRESS), html_mode);
+
+ // Swap painters.
+
+ if (html_mode) {
+ new_painter = editor->priv->html_painter;
+ old_painter = editor->priv->plain_painter;
+ } else {
+ new_painter = editor->priv->plain_painter;
+ old_painter = editor->priv->html_painter;
+ }
+
+ // Might be true during initialization.
+ if (html->engine->painter == new_painter)
+ return;
+
+ html_gdk_painter_unrealize (HTML_GDK_PAINTER (old_painter));
+ if (html->engine->window != NULL)
+ html_gdk_painter_realize (
+ HTML_GDK_PAINTER (new_painter),
+ html->engine->window);
+
+ html_font_manager_set_default (
+ &new_painter->font_manager,
+ old_painter->font_manager.variable.face,
+ old_painter->font_manager.fixed.face,
+ old_painter->font_manager.var_size,
+ old_painter->font_manager.var_points,
+ old_painter->font_manager.fix_size,
+ old_painter->font_manager.fix_points);
+
+ html_engine_set_painter (html->engine, new_painter);
+ html_engine_schedule_redraw (html->engine);
+
+ g_object_notify (G_OBJECT (editor), "html-mode");
+ */
+}
+
+static void
+action_monospaced_cb (GtkToggleAction *action,
+ EEditor *editor)
+{
+ /* FIXME WEBKIT */
+ /*
+ GtkHTML *html;
+ GtkHTMLFontStyle and_mask;
+ GtkHTMLFontStyle or_mask;
+
+ if (editor->priv->ignore_style_change)
+ return;
+
+ if (gtk_toggle_action_get_active (action)) {
+ and_mask = GTK_HTML_FONT_STYLE_MAX;
+ or_mask = GTK_HTML_FONT_STYLE_FIXED;
+ } else {
+ and_mask = ~GTK_HTML_FONT_STYLE_FIXED;
+ or_mask = 0;
+ }
+
+ html = gtkhtml_editor_get_html (editor);
+ gtk_html_set_font_style (html, and_mask, or_mask);
+ */
+}
+
+static void
+action_paste_cb (GtkAction *action,
+ EEditor *editor)
+{
+ webkit_web_view_paste_clipboard (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+}
+
+static void
+action_paste_quote_cb (GtkAction *action,
+ EEditor *editor)
+{
+ /* FIXME WEBKIT */
+ /*
+ GtkHTML *html;
+
+ html = gtkhtml_editor_get_html (editor);
+ gtk_html_paste (html, TRUE);
+ */
+}
+
+static void
+action_properties_cell_cb (GtkAction *action,
+ EEditor *editor)
+{
+ gtk_window_present (GTK_WINDOW (WIDGET (CELL_PROPERTIES_WINDOW)));
+}
+
+static void
+action_properties_image_cb (GtkAction *action,
+ EEditor *editor)
+{
+ gtk_window_present (GTK_WINDOW (WIDGET (IMAGE_PROPERTIES_WINDOW)));
+}
+
+static void
+action_properties_link_cb (GtkAction *action,
+ EEditor *editor)
+{
+ gtk_window_present (GTK_WINDOW (WIDGET (LINK_PROPERTIES_WINDOW)));
+}
+
+static void
+action_properties_page_cb (GtkAction *action,
+ EEditor *editor)
+{
+ gtk_window_present (GTK_WINDOW (WIDGET (PAGE_PROPERTIES_WINDOW)));
+}
+
+static void
+action_properties_paragraph_cb (GtkAction *action,
+ EEditor *editor)
+{
+ gtk_window_present (GTK_WINDOW (WIDGET (PARAGRAPH_PROPERTIES_WINDOW)));
+}
+
+static void
+action_properties_rule_cb (GtkAction *action,
+ EEditor *editor)
+{
+ gtk_window_present (GTK_WINDOW (WIDGET (RULE_PROPERTIES_WINDOW)));
+}
+
+static void
+action_properties_table_cb (GtkAction *action,
+ EEditor *editor)
+{
+ gtk_window_present (GTK_WINDOW (WIDGET (TABLE_PROPERTIES_WINDOW)));
+}
+
+static void
+action_properties_text_cb (GtkAction *action,
+ EEditor *editor)
+{
+ gtk_window_present (GTK_WINDOW (WIDGET (TEXT_PROPERTIES_WINDOW)));
+}
+
+static void
+action_style_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EEditor *editor)
+{
+ EEditorSelection *selection;
+
+ /* FIXME WEBKIT What's this good for? */
+ if (editor->priv->ignore_style_change)
+ return;
+
+ selection = e_editor_widget_get_selection (
+ e_editor_get_editor_widget (editor));
+ e_editor_selection_set_block_format (
+ selection, gtk_radio_action_get_current_value (current));
+}
+
+static void
+action_redo_cb (GtkAction *action,
+ EEditor *editor)
+{
+ webkit_web_view_redo (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+}
+
+static void
+action_select_all_cb (GtkAction *action,
+ EEditor *editor)
+{
+ webkit_web_view_select_all (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+}
+
+static void
+action_show_find_cb (GtkAction *action,
+ EEditor *editor)
+{
+ gtk_widget_set_sensitive (WIDGET (FIND_BUTTON), TRUE);
+
+ gtk_window_present (GTK_WINDOW (WIDGET (FIND_WINDOW)));
+}
+
+static void
+action_show_replace_cb (GtkAction *action,
+ EEditor *editor)
+{
+ gtk_window_present (GTK_WINDOW (WIDGET (REPLACE_WINDOW)));
+}
+
+static void
+action_size_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EEditor *editor)
+{
+ EEditorSelection *selection;
+
+ if (editor->priv->ignore_style_change)
+ return;
+
+ selection = e_editor_widget_get_selection (
+ e_editor_get_editor_widget (editor));
+ e_editor_selection_set_font_size (
+ selection, gtk_radio_action_get_current_value (current));
+}
+
+static void
+action_spell_check_cb (GtkAction *action,
+ EEditor *editor)
+{
+ /* FIXME WEBKIT
+ e_editor_widget_spell_check (editor);
+ */
+}
+
+static void
+action_strikethrough_cb (GtkToggleAction *action,
+ EEditor *editor)
+{
+ EEditorSelection *selection;
+
+ if (editor->priv->ignore_style_change)
+ return;
+
+ selection = e_editor_widget_get_selection (
+ e_editor_get_editor_widget (editor));
+ e_editor_selection_set_italic (
+ selection, gtk_toggle_action_get_active (action));
+}
+
+static void
+action_test_url_cb (GtkAction *action,
+ EEditor *editor)
+{
+ /* FIXME WEBKIT What does this do? */
+ /*
+ GtkEntry *entry;
+ GtkWindow *window;
+ const gchar *text;
+
+ entry = GTK_ENTRY (WIDGET (LINK_PROPERTIES_URL_ENTRY));
+ window = GTK_WINDOW (WIDGET (LINK_PROPERTIES_WINDOW));
+
+ text = gtk_entry_get_text (entry);
+
+ if (text != NULL && *text != '\0')
+ gtkhtml_editor_show_uri (window, text);
+ */
+}
+
+static void
+action_underline_cb (GtkToggleAction *action,
+ EEditor *editor)
+{
+ EEditorSelection *selection;
+
+ if (editor->priv->ignore_style_change)
+ return;
+
+ selection = e_editor_widget_get_selection (
+ e_editor_get_editor_widget (editor));
+ e_editor_selection_set_underline (
+ selection, gtk_toggle_action_get_active (action));
+}
+
+static void
+action_undo_cb (GtkAction *action,
+ EEditor *editor)
+{
+ webkit_web_view_undo (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+}
+
+static void
+action_unindent_cb (GtkAction *action,
+ EEditor *editor)
+{
+ WebKitDOMDocument *document;
+
+ document = webkit_web_view_get_dom_document (
+ WEBKIT_WEB_VIEW (e_editor_get_editor_widget (editor)));
+ webkit_dom_document_exec_command (
+ document, "outdent", FALSE, "");
+}
+
+static void
+action_wrap_lines_cb (GtkAction *action,
+ EEditor *editor)
+{
+ /* FIXME WEBKIT */
+ /*
+ e_editor_widget_wrap_lines (editor);
+ */
+}
+
+/*****************************************************************************
+ * Core Actions
+ *
+ * These actions are always enabled.
+ *****************************************************************************/
+
+static GtkActionEntry core_entries[] = {
+
+ { "confirm-replace",
+ NULL,
+ N_("_Replace"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_confirm_replace_cb) },
+
+ { "confirm-replace-all",
+ NULL,
+ N_("Replace _All"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_confirm_replace_all_cb) },
+
+ { "confirm-replace-cancel",
+ GTK_STOCK_CLOSE,
+ NULL,
+ NULL,
+ NULL,
+ G_CALLBACK (action_confirm_replace_cancel_cb) },
+
+ { "confirm-replace-next",
+ NULL,
+ N_("_Next"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_confirm_replace_next_cb) },
+
+ { "copy",
+ GTK_STOCK_COPY,
+ N_("_Copy"),
+ "<Control>c",
+ NULL,
+ G_CALLBACK (action_copy_cb) },
+
+ { "cut",
+ GTK_STOCK_CUT,
+ N_("Cu_t"),
+ "<Control>x",
+ NULL,
+ G_CALLBACK (action_cut_cb) },
+
+ { "find",
+ GTK_STOCK_FIND,
+ NULL,
+ NULL,
+ NULL,
+ G_CALLBACK (action_find_cb) },
+
+ { "find-again",
+ NULL,
+ N_("Find A_gain"),
+ "<Control>g",
+ NULL,
+ G_CALLBACK (action_find_again_cb) },
+
+ { "find-and-replace",
+ GTK_STOCK_FIND_AND_REPLACE,
+ NULL,
+ NULL,
+ NULL,
+ G_CALLBACK (action_find_and_replace_cb) },
+
+ { "indent",
+ GTK_STOCK_INDENT,
+ N_("_Increase Indent"),
+ "<Control>bracketright",
+ N_("Increase Indent"),
+ G_CALLBACK (action_indent_cb) },
+
+ { "insert-html-file",
+ NULL,
+ N_("_HTML File..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_insert_html_file_cb) },
+
+ { "insert-text-file",
+ NULL,
+ N_("Te_xt File..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_insert_text_file_cb) },
+
+ { "paste",
+ GTK_STOCK_PASTE,
+ N_("_Paste"),
+ "<Control>v",
+ NULL,
+ G_CALLBACK (action_paste_cb) },
+
+ { "paste-quote",
+ NULL,
+ N_("Paste _Quotation"),
+ "<Shift><Control>v",
+ NULL,
+ G_CALLBACK (action_paste_quote_cb) },
+
+ { "redo",
+ GTK_STOCK_REDO,
+ N_("_Redo"),
+ "<Shift><Control>z",
+ NULL,
+ G_CALLBACK (action_redo_cb) },
+
+ { "select-all",
+ GTK_STOCK_SELECT_ALL,
+ N_("Select _All"),
+ "<Control>a",
+ NULL,
+ G_CALLBACK (action_select_all_cb) },
+
+ { "show-find",
+ GTK_STOCK_FIND,
+ N_("_Find..."),
+ "<Control>f",
+ NULL,
+ G_CALLBACK (action_show_find_cb) },
+
+ { "show-replace",
+ GTK_STOCK_FIND_AND_REPLACE,
+ N_("Re_place..."),
+ "<Control>h",
+ NULL,
+ G_CALLBACK (action_show_replace_cb) },
+
+ { "spell-check",
+ GTK_STOCK_SPELL_CHECK,
+ N_("Check _Spelling..."),
+ "F7",
+ NULL,
+ G_CALLBACK (action_spell_check_cb) },
+
+ { "test-url",
+ NULL,
+ N_("_Test URL..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_test_url_cb) },
+
+ { "undo",
+ GTK_STOCK_UNDO,
+ N_("_Undo"),
+ "<Control>z",
+ NULL,
+ G_CALLBACK (action_undo_cb) },
+
+ { "unindent",
+ GTK_STOCK_UNINDENT,
+ N_("_Decrease Indent"),
+ "<Control>bracketleft",
+ N_("Decrease Indent"),
+ G_CALLBACK (action_unindent_cb) },
+
+ { "wrap-lines",
+ NULL,
+ N_("_Wrap Lines"),
+ "<Control>k",
+ NULL,
+ G_CALLBACK (action_wrap_lines_cb) },
+
+ /* Menus */
+
+ { "edit-menu",
+ NULL,
+ N_("_Edit"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "file-menu",
+ NULL,
+ N_("_File"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "format-menu",
+ NULL,
+ N_("For_mat"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "paragraph-style-menu",
+ NULL,
+ N_("_Paragraph Style"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "insert-menu",
+ NULL,
+ N_("_Insert"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "justify-menu",
+ NULL,
+ N_("_Alignment"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "language-menu",
+ NULL,
+ N_("Current _Languages"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "view-menu",
+ NULL,
+ N_("_View"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static GtkRadioActionEntry core_justify_entries[] = {
+
+ { "justify-center",
+ GTK_STOCK_JUSTIFY_CENTER,
+ N_("_Center"),
+ "<Control>e",
+ N_("Center Alignment"),
+ E_EDITOR_SELECTION_ALIGNMENT_CENTER },
+
+ { "justify-left",
+ GTK_STOCK_JUSTIFY_LEFT,
+ N_("_Left"),
+ "<Control>l",
+ N_("Left Alignment"),
+ E_EDITOR_SELECTION_ALIGNMENT_LEFT },
+
+ { "justify-right",
+ GTK_STOCK_JUSTIFY_RIGHT,
+ N_("_Right"),
+ "<Control>r",
+ N_("Right Alignment"),
+ E_EDITOR_SELECTION_ALIGNMENT_RIGHT }
+};
+
+static GtkRadioActionEntry core_mode_entries[] = {
+
+ { "mode-html",
+ NULL,
+ N_("_HTML"),
+ NULL,
+ N_("HTML editing mode"),
+ E_EDITOR_WIDGET_MODE_HTML },
+
+ { "mode-plain",
+ NULL,
+ N_("Plain _Text"),
+ NULL,
+ N_("Plain text editing mode"),
+ E_EDITOR_WIDGET_MODE_PLAIN_TEXT }
+};
+
+static GtkRadioActionEntry core_style_entries[] = {
+
+ { "style-normal",
+ NULL,
+ N_("_Normal"),
+ "<Control>0",
+ NULL,
+ E_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH },
+
+ { "style-h1",
+ NULL,
+ N_("Header _1"),
+ "<Control>1",
+ NULL,
+ E_EDITOR_SELECTION_BLOCK_FORMAT_H1 },
+
+ { "style-h2",
+ NULL,
+ N_("Header _2"),
+ "<Control>2",
+ NULL,
+ E_EDITOR_SELECTION_BLOCK_FORMAT_H2 },
+
+ { "style-h3",
+ NULL,
+ N_("Header _3"),
+ "<Control>3",
+ NULL,
+ E_EDITOR_SELECTION_BLOCK_FORMAT_H3 },
+
+ { "style-h4",
+ NULL,
+ N_("Header _4"),
+ "<Control>4",
+ NULL,
+ E_EDITOR_SELECTION_BLOCK_FORMAT_H4 },
+
+ { "style-h5",
+ NULL,
+ N_("Header _5"),
+ "<Control>5",
+ NULL,
+ E_EDITOR_SELECTION_BLOCK_FORMAT_H5 },
+
+ { "style-h6",
+ NULL,
+ N_("Header _6"),
+ "<Control>6",
+ NULL,
+ E_EDITOR_SELECTION_BLOCK_FORMAT_H6 },
+
+ { "style-address",
+ NULL,
+ N_("A_ddress"),
+ "<Control>8",
+ NULL,
+ E_EDITOR_SELECTION_BLOCK_FORMAT_ADDRESS },
+
+ { "style-preformat",
+ NULL,
+ N_("_Preformatted"),
+ "<Control>7",
+ NULL,
+ E_EDITOR_SELECTION_BLOCK_FORMAT_PRE },
+
+ { "style-list-bullet",
+ NULL,
+ N_("_Bulleted List"),
+ NULL,
+ NULL,
+ E_EDITOR_SELECTION_BLOCK_FORMAT_UNORDERED_LIST },
+
+ { "style-list-roman",
+ NULL,
+ N_("_Roman Numeral List"),
+ NULL,
+ NULL,
+ E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ROMAN },
+
+ { "style-list-number",
+ NULL,
+ N_("Numbered _List"),
+ NULL,
+ NULL,
+ E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST },
+
+ { "style-list-alpha",
+ NULL,
+ N_("_Alphabetical List"),
+ NULL,
+ NULL,
+ E_EDITOR_SELECTION_BLOCK_FORMAT_ORDERED_LIST_ALPHA }
+};
+
+/*****************************************************************************
+ * Core Actions (HTML only)
+ *
+ * These actions are only enabled in HTML mode.
+ *****************************************************************************/
+
+static GtkActionEntry html_entries[] = {
+
+ { "insert-image",
+ "insert-image",
+ N_("_Image..."),
+ NULL,
+ N_("Insert Image"),
+ G_CALLBACK (action_insert_image_cb) },
+
+ { "insert-link",
+ "insert-link",
+ N_("_Link..."),
+ NULL,
+ N_("Insert Link"),
+ G_CALLBACK (action_insert_link_cb) },
+
+ { "insert-rule",
+ "stock_insert-rule",
+ /* Translators: 'Rule' here means a horizontal line in an HTML text */
+ N_("_Rule..."),
+ NULL,
+ /* Translators: 'Rule' here means a horizontal line in an HTML text */
+ N_("Insert Rule"),
+ G_CALLBACK (action_insert_rule_cb) },
+
+ { "insert-table",
+ "stock_insert-table",
+ N_("_Table..."),
+ NULL,
+ N_("Insert Table"),
+ G_CALLBACK (action_insert_table_cb) },
+
+ { "properties-cell",
+ NULL,
+ N_("_Cell..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_cell_cb) },
+
+ { "properties-image",
+ NULL,
+ N_("_Image..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_image_cb) },
+
+ { "properties-link",
+ NULL,
+ N_("_Link..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_link_cb) },
+
+ { "properties-page",
+ NULL,
+ N_("Pa_ge..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_page_cb) },
+
+ { "properties-rule",
+ NULL,
+ /* Translators: 'Rule' here means a horizontal line in an HTML text */
+ N_("_Rule..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_rule_cb) },
+
+ { "properties-table",
+ NULL,
+ N_("_Table..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_table_cb) },
+
+ /* Menus */
+
+ { "font-size-menu",
+ NULL,
+ N_("Font _Size"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "font-style-menu",
+ NULL,
+ N_("_Font Style"),
+ NULL,
+ NULL,
+ NULL },
+};
+
+static GtkToggleActionEntry html_toggle_entries[] = {
+
+ { "bold",
+ GTK_STOCK_BOLD,
+ N_("_Bold"),
+ "<Control>b",
+ N_("Bold"),
+ G_CALLBACK (action_bold_cb),
+ FALSE },
+
+ { "italic",
+ GTK_STOCK_ITALIC,
+ N_("_Italic"),
+ "<Control>i",
+ N_("Italic"),
+ G_CALLBACK (action_italic_cb),
+ FALSE },
+
+ { "monospaced",
+ "stock_text-monospaced",
+ N_("_Plain Text"),
+ "<Control>t",
+ N_("Plain Text"),
+ G_CALLBACK (action_monospaced_cb),
+ FALSE },
+
+ { "strikethrough",
+ GTK_STOCK_STRIKETHROUGH,
+ N_("_Strikethrough"),
+ NULL,
+ N_("Strikethrough"),
+ G_CALLBACK (action_strikethrough_cb),
+ FALSE },
+
+ { "underline",
+ GTK_STOCK_UNDERLINE,
+ N_("_Underline"),
+ "<Control>u",
+ N_("Underline"),
+ G_CALLBACK (action_underline_cb),
+ FALSE }
+};
+
+static GtkRadioActionEntry html_size_entries[] = {
+
+ { "size-minus-two",
+ NULL,
+ /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as
possible. */
+ N_("-2"),
+ NULL,
+ NULL,
+ E_EDITOR_SELECTION_FONT_SIZE_TINY },
+
+ { "size-minus-one",
+ NULL,
+ /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as
possible. */
+ N_("-1"),
+ NULL,
+ NULL,
+ E_EDITOR_SELECTION_FONT_SIZE_SMALL },
+
+ { "size-plus-zero",
+ NULL,
+ /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as
possible. */
+ N_("+0"),
+ NULL,
+ NULL,
+ E_EDITOR_SELECTION_FONT_SIZE_NORMAL },
+
+ { "size-plus-one",
+ NULL,
+ /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as
possible. */
+ N_("+1"),
+ NULL,
+ NULL,
+ E_EDITOR_SELECTION_FONT_SIZE_BIG },
+
+ { "size-plus-two",
+ NULL,
+ /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as
possible. */
+ N_("+2"),
+ NULL,
+ NULL,
+ E_EDITOR_SELECTION_FONT_SIZE_BIGGER },
+
+ { "size-plus-three",
+ NULL,
+ /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as
possible. */
+ N_("+3"),
+ NULL,
+ NULL,
+ E_EDITOR_SELECTION_FONT_SIZE_LARGE },
+
+ { "size-plus-four",
+ NULL,
+ /* Translators: This is a font size level. It is shown on a tool bar. Please keep it as short as
possible. */
+ N_("+4"),
+ NULL,
+ NULL,
+ E_EDITOR_SELECTION_FONT_SIZE_VERY_LARGE }
+};
+
+/*****************************************************************************
+ * Context Menu Actions
+ *
+ * These require separate action entries so we can toggle their visiblity
+ * rather than their sensitivity as we do with main menu / toolbar actions.
+ * Note that some of these actions use the same callback function as their
+ * non-context sensitive counterparts.
+ *****************************************************************************/
+
+static GtkActionEntry context_entries[] = {
+
+ { "context-delete-cell",
+ NULL,
+ N_("Cell Contents"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_context_delete_cell_cb) },
+
+ { "context-delete-column",
+ NULL,
+ N_("Column"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_context_delete_column_cb) },
+
+ { "context-delete-row",
+ NULL,
+ N_("Row"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_context_delete_row_cb) },
+
+ { "context-delete-table",
+ NULL,
+ N_("Table"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_context_delete_table_cb) },
+
+ /* Menus */
+
+ { "context-delete-table-menu",
+ NULL,
+ /* Translators: Popup menu item caption, containing all the Delete options for a table */
+ N_("Table Delete"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "context-input-methods-menu",
+ NULL,
+ N_("Input Methods"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "context-insert-table-menu",
+ NULL,
+ /* Translators: Popup menu item caption, containing all the Insert options for a table */
+ N_("Table Insert"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "context-properties-menu",
+ NULL,
+ N_("Properties"),
+ NULL,
+ NULL,
+ NULL },
+};
+
+/*****************************************************************************
+ * Context Menu Actions (HTML only)
+ *
+ * These actions are never visible in plain-text mode. Note that some
+ * of them use the same callback function as their non-context sensitive
+ * counterparts.
+ *****************************************************************************/
+
+static GtkActionEntry html_context_entries[] = {
+
+ { "context-insert-column-after",
+ NULL,
+ N_("Column After"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_context_insert_column_after_cb) },
+
+ { "context-insert-column-before",
+ NULL,
+ N_("Column Before"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_context_insert_column_before_cb) },
+
+ { "context-insert-link",
+ NULL,
+ N_("Insert _Link"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_insert_link_cb) },
+
+ { "context-insert-row-above",
+ NULL,
+ N_("Row Above"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_context_insert_row_above_cb) },
+
+ { "context-insert-row-below",
+ NULL,
+ N_("Row Below"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_context_insert_row_below_cb) },
+
+ { "context-insert-table",
+ NULL,
+ N_("Table"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_insert_table_cb) },
+
+ { "context-properties-cell",
+ NULL,
+ N_("Cell..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_cell_cb) },
+
+ { "context-properties-image",
+ NULL,
+ N_("Image..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_image_cb) },
+
+ { "context-properties-link",
+ NULL,
+ N_("Link..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_link_cb) },
+
+ { "context-properties-page",
+ NULL,
+ N_("Page..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_page_cb) },
+
+ { "context-properties-paragraph",
+ NULL,
+ N_("Paragraph..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_paragraph_cb) },
+
+ { "context-properties-rule",
+ NULL,
+ /* Translators: 'Rule' here means a horizontal line in an HTML text */
+ N_("Rule..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_rule_cb) },
+
+ { "context-properties-table",
+ NULL,
+ N_("Table..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_table_cb) },
+
+ { "context-properties-text",
+ NULL,
+ N_("Text..."),
+ NULL,
+ NULL,
+ G_CALLBACK (action_properties_text_cb) },
+
+ { "context-remove-link",
+ NULL,
+ N_("Remove Link"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_context_remove_link_cb) }
+};
+
+/*****************************************************************************
+ * Context Menu Actions (spell checking only)
+ *
+ * These actions are only visible when the word underneath the cursor is
+ * misspelled.
+ *****************************************************************************/
+
+static GtkActionEntry spell_context_entries[] = {
+
+ { "context-spell-add",
+ NULL,
+ N_("Add Word to Dictionary"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_context_spell_add_cb) },
+
+ { "context-spell-ignore",
+ NULL,
+ N_("Ignore Misspelled Word"),
+ NULL,
+ NULL,
+ G_CALLBACK (action_context_spell_ignore_cb) },
+
+ { "context-spell-add-menu",
+ NULL,
+ N_("Add Word To"),
+ NULL,
+ NULL,
+ NULL },
+
+ /* Menus */
+
+ { "context-more-suggestions-menu",
+ NULL,
+ N_("More Suggestions"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static void
+editor_actions_setup_languages_menu (EEditor *editor)
+{
+ /* FIXME WEBKIT
+ GtkUIManager *manager;
+ GtkActionGroup *action_group;
+ const GList *available_languages;
+ guint merge_id;
+
+ manager = editor->priv->manager;
+ action_group = editor->priv->language_actions;
+ available_languages = gtkhtml_spell_language_get_available ();
+ merge_id = gtk_ui_manager_new_merge_id (manager);
+
+ while (available_languages != NULL) {
+ GtkhtmlSpellLanguage *language = available_languages->data;
+ GtkhtmlSpellChecker *checker;
+ GtkToggleAction *action;
+
+ checker = gtkhtml_spell_checker_new (language);
+
+ g_hash_table_insert (
+ editor->priv->available_spell_checkers,
+ language, checker);
+
+ action = gtk_toggle_action_new (
+ gtkhtml_spell_language_get_code (language),
+ gtkhtml_spell_language_get_name (language),
+ NULL, NULL);
+
+ g_signal_connect (
+ action, "toggled",
+ G_CALLBACK (action_language_cb), editor);
+
+ gtk_action_group_add_action (
+ action_group, GTK_ACTION (action));
+
+ g_object_unref (action);
+
+ gtk_ui_manager_add_ui (
+ manager, merge_id,
+ "/main-menu/edit-menu/language-menu",
+ gtkhtml_spell_language_get_code (language),
+ gtkhtml_spell_language_get_code (language),
+ GTK_UI_MANAGER_AUTO, FALSE);
+
+ available_languages = g_list_next (available_languages);
+ }
+ */
+}
+
+static void
+editor_actions_setup_spell_check_menu (EEditor *editor)
+{
+ /*
+ GtkUIManager *manager;
+ GtkActionGroup *action_group;
+ const GList *available_languages;
+ guint merge_id;
+
+ manager = editor->priv->manager;
+ action_group = editor->priv->spell_check_actions;;
+ available_languages = gtkhtml_spell_language_get_available ();
+ merge_id = gtk_ui_manager_new_merge_id (manager);
+
+ while (available_languages != NULL) {
+ GtkhtmlSpellLanguage *language = available_languages->data;
+ GtkAction *action;
+ const gchar *code;
+ const gchar *name;
+ gchar *action_label;
+ gchar *action_name;
+
+ code = gtkhtml_spell_language_get_code (language);
+ name = gtkhtml_spell_language_get_name (language);
+
+ // Add a suggestion menu.
+
+ action_name = g_strdup_printf (
+ "context-spell-suggest-%s-menu", code);
+
+ action = gtk_action_new (action_name, name, NULL, NULL);
+ gtk_action_group_add_action (action_group, action);
+ g_object_unref (action);
+
+ gtk_ui_manager_add_ui (
+ manager, merge_id,
+ "/context-menu/context-spell-suggest",
+ action_name, action_name,
+ GTK_UI_MANAGER_MENU, FALSE);
+
+ g_free (action_name);
+
+ // Add an item to the "Add Word To" menu.
+
+ action_name = g_strdup_printf ("context-spell-add-%s", code);
+ // Translators: %s will be replaced with the actual dictionary name,
+ //where a user can add a word to. This is part of an "Add Word To" submenu.
+ action_label = g_strdup_printf (_("%s Dictionary"), name);
+
+ action = gtk_action_new (
+ action_name, action_label, NULL, NULL);
+
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (action_context_spell_add_cb), editor);
+
+ // Visibility is dependent on whether the
+ //corresponding language action is active.
+ gtk_action_set_visible (action, FALSE);
+
+ gtk_action_group_add_action (action_group, action);
+
+ g_object_unref (action);
+
+ gtk_ui_manager_add_ui (
+ manager, merge_id,
+ "/context-menu/context-spell-add-menu",
+ action_name, action_name,
+ GTK_UI_MANAGER_AUTO, FALSE);
+
+ g_free (action_label);
+ g_free (action_name);
+
+ available_languages = g_list_next (available_languages);
+ }
+ */
+}
+
+void
+editor_actions_init (EEditor *editor)
+{
+ GtkAction *action;
+ GtkActionGroup *action_group;
+ GtkUIManager *manager;
+ const gchar *domain;
+
+ g_return_if_fail (E_IS_EDITOR (editor));
+
+ manager = e_editor_get_ui_manager (editor);
+ domain = GETTEXT_PACKAGE;
+
+ /* Core Actions */
+ action_group = editor->priv->core_actions;
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_action_group_add_actions (
+ action_group, core_entries,
+ G_N_ELEMENTS (core_entries), editor);
+ gtk_action_group_add_radio_actions (
+ action_group, core_justify_entries,
+ G_N_ELEMENTS (core_justify_entries),
+ E_EDITOR_SELECTION_ALIGNMENT_LEFT,
+ G_CALLBACK (action_justify_cb), editor);
+ gtk_action_group_add_radio_actions (
+ action_group, core_mode_entries,
+ G_N_ELEMENTS (core_mode_entries),
+ E_EDITOR_WIDGET_MODE_HTML,
+ G_CALLBACK (action_mode_cb), editor);
+ gtk_action_group_add_radio_actions (
+ action_group, core_style_entries,
+ G_N_ELEMENTS (core_style_entries),
+ E_EDITOR_SELECTION_BLOCK_FORMAT_PARAGRAPH,
+ G_CALLBACK (action_style_cb), editor);
+ gtk_ui_manager_insert_action_group (manager, action_group, 0);
+
+ /* Face Action */
+ action = e_emoticon_action_new (
+ "insert-face", _("_Emoticon"),
+ _("Insert Emoticon"), NULL);
+ g_object_set (action, "icon-name", "face-smile", NULL);
+ g_signal_connect (
+ action, "item-activated",
+ G_CALLBACK (action_insert_emoticon_cb), editor);
+ gtk_action_group_add_action (action_group, action);
+
+ /* Core Actions (HTML only) */
+ action_group = editor->priv->html_actions;
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_action_group_add_actions (
+ action_group, html_entries,
+ G_N_ELEMENTS (html_entries), editor);
+ gtk_action_group_add_toggle_actions (
+ action_group, html_toggle_entries,
+ G_N_ELEMENTS (html_toggle_entries), editor);
+ gtk_action_group_add_radio_actions (
+ action_group, html_size_entries,
+ G_N_ELEMENTS (html_size_entries),
+ E_EDITOR_SELECTION_FONT_SIZE_NORMAL,
+ G_CALLBACK (action_size_cb), editor);
+ gtk_ui_manager_insert_action_group (manager, action_group, 0);
+
+ /* Context Menu Actions */
+ action_group = editor->priv->context_actions;
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_action_group_add_actions (
+ action_group, context_entries,
+ G_N_ELEMENTS (context_entries), editor);
+ gtk_ui_manager_insert_action_group (manager, action_group, 0);
+
+ /* Context Menu Actions (HTML only) */
+ action_group = editor->priv->html_context_actions;
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_action_group_add_actions (
+ action_group, html_context_entries,
+ G_N_ELEMENTS (html_context_entries), editor);
+ gtk_ui_manager_insert_action_group (manager, action_group, 0);
+
+ /* Context Menu Actions (spell check only) */
+ action_group = editor->priv->spell_check_actions;
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_action_group_add_actions (
+ action_group, spell_context_entries,
+ G_N_ELEMENTS (spell_context_entries), editor);
+ gtk_ui_manager_insert_action_group (manager, action_group, 0);
+
+ /* Language actions are generated dynamically. */
+ editor_actions_setup_languages_menu (editor);
+ action_group = editor->priv->language_actions;
+ gtk_ui_manager_insert_action_group (manager, action_group, 0);
+
+ /* Some spell check actions are generated dynamically. */
+ action_group = editor->priv->suggestion_actions;
+ editor_actions_setup_spell_check_menu (editor);
+ gtk_ui_manager_insert_action_group (manager, action_group, 0);
+
+ /* Fine Tuning */
+
+ g_object_set (
+ G_OBJECT (ACTION (FIND)),
+ "short-label", _("_Find"), NULL);
+ g_object_set (
+ G_OBJECT (ACTION (FIND_AND_REPLACE)),
+ "short-label", _("Re_place"), NULL);
+ g_object_set (
+ G_OBJECT (ACTION (INSERT_IMAGE)),
+ "short-label", _("_Image"), NULL);
+ g_object_set (
+ G_OBJECT (ACTION (INSERT_LINK)),
+ "short-label", _("_Link"), NULL);
+ g_object_set (
+ G_OBJECT (ACTION (INSERT_RULE)),
+ /* Translators: 'Rule' here means a horizontal line in an HTML text */
+ "short-label", _("_Rule"), NULL);
+ g_object_set (
+ G_OBJECT (ACTION (INSERT_TABLE)),
+ "short-label", _("_Table"), NULL);
+
+ gtk_action_set_sensitive (ACTION (UNINDENT), FALSE);
+}
+
diff --git a/e-util/e-editor-actions.h b/e-util/e-editor-actions.h
new file mode 100644
index 0000000..3f84b13
--- /dev/null
+++ b/e-util/e-editor-actions.h
@@ -0,0 +1,152 @@
+/* e-editor-actions.h
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
+#error "Only <e-util/e-util.h> should be included directly."
+#endif
+
+#ifndef E_EDITOR_ACTIONS_H
+#define E_EDITOR_ACTIONS_H
+
+#define E_EDITOR_ACTION(editor, name) \
+ (e_editor_get_action (E_EDITOR (editor), (name)))
+
+#define E_EDITOR_ACTION_BOLD(editor) \
+ E_EDITOR_ACTION ((editor), "bold")
+#define E_EDITOR_ACTION_CONFIRM_REPLACE(editor) \
+ E_EDITOR_ACTION ((editor), "confirm-replace")
+#define E_EDITOR_ACTION_CONFIRM_REPLACE_ALL(editor) \
+ E_EDITOR_ACTION ((editor), "confirm-replace-all")
+#define E_EDITOR_ACTION_CONFIRM_REPLACE_CANCEL(editor) \
+ E_EDITOR_ACTION ((editor), "confirm-replace-cancel")
+#define E_EDITOR_ACTION_CONFIRM_REPLACE_NEXT(editor) \
+ E_EDITOR_ACTION ((editor), "confirm-replace-next")
+#define E_EDITOR_ACTION_CONTEXT_DELETE_CELL(editor) \
+ E_EDITOR_ACTION ((editor), "context-delete-cell")
+#define E_EDITOR_ACTION_CONTEXT_DELETE_COLUMN(editor) \
+ E_EDITOR_ACTION ((editor), "context-delete-column")
+#define E_EDITOR_ACTION_CONTEXT_DELETE_ROW(editor) \
+ E_EDITOR_ACTION ((editor), "context-delete-row")
+#define E_EDITOR_ACTION_CONTEXT_DELETE_TABLE(editor) \
+ E_EDITOR_ACTION ((editor), "context-delete-table")
+#define E_EDITOR_ACTION_CONTEXT_INSERT_COLUMN_AFTER(editor) \
+ E_EDITOR_ACTION ((editor), "context-insert-column-after")
+#define E_EDITOR_ACTION_CONTEXT_INSERT_COLUMN_BEFORE(editor) \
+ E_EDITOR_ACTION ((editor), "context-insert-column-before")
+#define E_EDITOR_ACTION_CONTEXT_INSERT_ROW_ABOVE(editor) \
+ E_EDITOR_ACTION ((editor), "context-insert-row-above")
+#define E_EDITOR_ACTION_CONTEXT_INSERT_ROW_BELOW(editor) \
+ E_EDITOR_ACTION ((editor), "context-insert-row-below")
+#define E_EDITOR_ACTION_CONTEXT_INSERT_TABLE(editor) \
+ E_EDITOR_ACTION ((editor), "context-insert-table")
+#define E_EDITOR_ACTION_CONTEXT_PROPERTIES_CELL(editor) \
+ E_EDITOR_ACTION ((editor), "context-properties-cell")
+#define E_EDITOR_ACTION_CONTEXT_PROPERTIES_IMAGE(editor) \
+ E_EDITOR_ACTION ((editor), "context-properties-image")
+#define E_EDITOR_ACTION_CONTEXT_PROPERTIES_LINK(editor) \
+ E_EDITOR_ACTION ((editor), "context-properties-link")
+#define E_EDITOR_ACTION_CONTEXT_PROPERTIES_PARAGRAPH(editor) \
+ E_EDITOR_ACTION ((editor), "context-properties-paragraph")
+#define E_EDITOR_ACTION_CONTEXT_PROPERTIES_RULE(editor) \
+ E_EDITOR_ACTION ((editor), "context-properties-rule")
+#define E_EDITOR_ACTION_CONTEXT_PROPERTIES_TABLE(editor) \
+ E_EDITOR_ACTION ((editor), "context-properties-table")
+#define E_EDITOR_ACTION_CONTEXT_PROPERTIES_TEXT(editor) \
+ E_EDITOR_ACTION ((editor), "context-properties-text")
+#define E_EDITOR_ACTION_CONTEXT_REMOVE_LINK(editor) \
+ E_EDITOR_ACTION ((editor), "context-remove-link")
+#define E_EDITOR_ACTION_CONTEXT_SPELL_ADD(editor) \
+ E_EDITOR_ACTION ((editor), "context-spell-add")
+#define E_EDITOR_ACTION_CONTEXT_SPELL_ADD_MENU(editor) \
+ E_EDITOR_ACTION ((editor), "context-spell-add-menu")
+#define E_EDITOR_ACTION_CONTEXT_SPELL_IGNORE(editor) \
+ E_EDITOR_ACTION ((editor), "context-spell-ignore")
+#define E_EDITOR_ACTION_COPY(editor) \
+ E_EDITOR_ACTION ((editor), "copy")
+#define E_EDITOR_ACTION_CUT(editor) \
+ E_EDITOR_ACTION ((editor), "cut")
+#define E_EDITOR_ACTION_EDIT_MENU(editor) \
+ E_EDITOR_ACTION ((editor), "edit-menu")
+#define E_EDITOR_ACTION_FIND(editor) \
+ E_EDITOR_ACTION ((editor), "find")
+#define E_EDITOR_ACTION_FIND_AND_REPLACE(editor) \
+ E_EDITOR_ACTION ((editor), "find-and-replace")
+#define E_EDITOR_ACTION_FORMAT_MENU(editor) \
+ E_EDITOR_ACTION ((editor), "format-menu")
+#define E_EDITOR_ACTION_FORMAT_TEXT(editor) \
+ E_EDITOR_ACTION ((editor), "format-text")
+#define E_EDITOR_ACTION_INSERT_IMAGE(editor) \
+ E_EDITOR_ACTION ((editor), "insert-image")
+#define E_EDITOR_ACTION_INSERT_LINK(editor) \
+ E_EDITOR_ACTION ((editor), "insert-link")
+#define E_EDITOR_ACTION_INSERT_MENU(editor) \
+ E_EDITOR_ACTION ((editor), "insert-menu")
+#define E_EDITOR_ACTION_INSERT_RULE(editor) \
+ E_EDITOR_ACTION ((editor), "insert-rule")
+#define E_EDITOR_ACTION_INSERT_TABLE(editor) \
+ E_EDITOR_ACTION ((editor), "insert-table")
+#define E_EDITOR_ACTION_ITALIC(editor) \
+ E_EDITOR_ACTION ((editor), "italic")
+#define E_EDITOR_ACTION_JUSTIFY_CENTER(editor) \
+ E_EDITOR_ACTION ((editor), "justify-center")
+#define E_EDITOR_ACTION_JUSTIFY_LEFT(editor) \
+ E_EDITOR_ACTION ((editor), "justify-left")
+#define E_EDITOR_ACTION_JUSTIFY_RIGHT(editor) \
+ E_EDITOR_ACTION ((editor), "justify-right")
+#define E_EDITOR_ACTION_MODE_HTML(editor) \
+ E_EDITOR_ACTION ((editor), "mode-html")
+#define E_EDITOR_ACTION_MODE_PLAIN(editor) \
+ E_EDITOR_ACTION ((editor), "mode-plain")
+#define E_EDITOR_ACTION_MONOSPACED(editor) \
+ E_EDITOR_ACTION ((editor), "monospaced")
+#define E_EDITOR_ACTION_PROPERTIES_RULE(editor) \
+ E_EDITOR_ACTION ((editor), "properties-rule")
+#define E_EDITOR_ACTION_PROPERTIES_TABLE(editor) \
+ E_EDITOR_ACTION ((editor), "properties-table")
+#define E_EDITOR_ACTION_SHOW_FIND(editor) \
+ E_EDITOR_ACTION ((editor), "show-find")
+#define E_EDITOR_ACTION_SHOW_REPLACE(editor) \
+ E_EDITOR_ACTION ((editor), "show-replace")
+#define E_EDITOR_ACTION_SIZE_PLUS_ZERO(editor) \
+ E_EDITOR_ACTION ((editor), "size-plus-zero")
+#define E_EDITOR_ACTION_SPELL_CHECK(editor) \
+ E_EDITOR_ACTION ((editor), "spell-check")
+#define E_EDITOR_ACTION_STRIKETHROUGH(editor) \
+ E_EDITOR_ACTION ((editor), "strikethrough")
+#define E_EDITOR_ACTION_STYLE_ADDRESS(editor) \
+ E_EDITOR_ACTION ((editor), "style-address")
+#define E_EDITOR_ACTION_STYLE_H1(editor) \
+ E_EDITOR_ACTION ((editor), "style-h1")
+#define E_EDITOR_ACTION_STYLE_H2(editor) \
+ E_EDITOR_ACTION ((editor), "style-h2")
+#define E_EDITOR_ACTION_STYLE_H3(editor) \
+ E_EDITOR_ACTION ((editor), "style-h3")
+#define E_EDITOR_ACTION_STYLE_H4(editor) \
+ E_EDITOR_ACTION ((editor), "style-h4")
+#define E_EDITOR_ACTION_STYLE_H5(editor) \
+ E_EDITOR_ACTION ((editor), "style-h5")
+#define E_EDITOR_ACTION_STYLE_H6(editor) \
+ E_EDITOR_ACTION ((editor), "style-h6")
+#define E_EDITOR_ACTION_STYLE_NORMAL(editor) \
+ E_EDITOR_ACTION ((editor), "style-normal")
+#define E_EDITOR_ACTION_TEST_URL(editor) \
+ E_EDITOR_ACTION ((editor), "test-url")
+#define E_EDITOR_ACTION_UNDERLINE(editor) \
+ E_EDITOR_ACTION ((editor), "underline")
+#define E_EDITOR_ACTION_UNINDENT(editor) \
+ E_EDITOR_ACTION ((editor), "unindent")
+
+#endif /* E_EDITOR_ACTIONS_H */
diff --git a/e-util/e-editor-private.h b/e-util/e-editor-private.h
new file mode 100644
index 0000000..31451f0
--- /dev/null
+++ b/e-util/e-editor-private.h
@@ -0,0 +1,72 @@
+/* e-editor-private.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef E_EDITOR_PRIVATE_H
+#define E_EDITOR_PRIVATE_H
+
+#include <e-editor.h>
+#include <e-action-combo-box.h>
+#include <e-color-combo.h>
+#include <e-editor-actions.h>
+#include <e-editor-widgets.h>
+#include <e-editor-widget.h>
+
+#ifdef HAVE_XFREE
+#include <X11/XF86keysym.h>
+#endif
+
+
+#define ACTION(name) (E_EDITOR_ACTION_##name (editor))
+#define WIDGET(name) (E_EDITOR_WIDGETS_##name (editor))
+
+G_BEGIN_DECLS
+
+struct _EEditorPrivate {
+ GtkUIManager *manager;
+ GtkActionGroup *core_actions;
+ GtkActionGroup *html_actions;
+ GtkActionGroup *context_actions;
+ GtkActionGroup *html_context_actions;
+ GtkActionGroup *language_actions;
+ GtkActionGroup *spell_check_actions;
+ GtkActionGroup *suggestion_actions;
+ GtkBuilder *builder;
+
+ GtkWidget *main_menu;
+ GtkWidget *main_toolbar;
+ GtkWidget *edit_toolbar;
+ GtkWidget *html_toolbar;
+ GtkWidget *edit_area;
+
+ GtkWidget *color_combo_box;
+ GtkWidget *mode_combo_box;
+ GtkWidget *size_combo_box;
+ GtkWidget *style_combo_box;
+ GtkWidget *scrolled_window;
+
+ EEditorWidget *editor_widget;
+
+ guint ignore_style_change : 1;
+
+ gchar *filename;
+};
+
+void editor_actions_init (EEditor *editor);
+
+G_END_DECLS
+
+#endif /* E_EDITOR_PRIVATE_H */
diff --git a/e-util/e-editor-widgets.h b/e-util/e-editor-widgets.h
new file mode 100644
index 0000000..5b28a7e
--- /dev/null
+++ b/e-util/e-editor-widgets.h
@@ -0,0 +1,234 @@
+/* e-editor-widgets.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
+#error "Only <e-util/e-util.h> should be included directly."
+#endif
+
+#ifndef E_EDITOR_WIDGETS_H
+#define E_EDITOR_WIDGETS_H
+
+#define E_EDITOR_WIDGETS(editor, name) \
+ (e_editor_get_widget ((editor), (name)))
+
+/* Cell Properties Window */
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_CELL_RADIO_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-cell-radio-button")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_COLOR_COMBO(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-color-combo")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_COLUMN_RADIO_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-column-radio-button")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_COLUMN_SPAN_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-column-span-spin-button")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_HEADER_STYLE_CHECK_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-header-style-check-button")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_HORIZONTAL_COMBO_BOX(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-horizontal-combo-box")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_IMAGE_FILE_CHOOSER(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-image-file-chooser")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_ROW_RADIO_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-row-radio-button")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_ROW_SPAN_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-row-span-spin-button")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_TABLE_RADIO_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-table-radio-button")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_VERTICAL_COMBO_BOX(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-vertical-combo-box")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_WIDTH_CHECK_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-width-check-button")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_WIDTH_COMBO_BOX(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-width-combo-box")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_WIDTH_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-width-spin-button")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_WINDOW(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-window")
+#define E_EDITOR_WIDGETS_CELL_PROPERTIES_WRAP_TEXT_CHECK_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "cell-properties-wrap-text-check-button")
+
+/* Find Window */
+#define E_EDITOR_WIDGETS_FIND_BACKWARDS(editor) \
+ E_EDITOR_WIDGETS ((editor), "find-backwards")
+#define E_EDITOR_WIDGETS_FIND_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "find-button")
+#define E_EDITOR_WIDGETS_FIND_CASE_SENSITIVE(editor) \
+ E_EDITOR_WIDGETS ((editor), "find-case-sensitive")
+#define E_EDITOR_WIDGETS_FIND_WINDOW(editor) \
+ E_EDITOR_WIDGETS ((editor), "find-window")
+#define E_EDITOR_WIDGETS_FIND_ENTRY(editor) \
+ E_EDITOR_WIDGETS ((editor), "find-entry")
+#define E_EDITOR_WIDGETS_FIND_REGULAR_EXPRESSION(editor) \
+ E_EDITOR_WIDGETS ((editor), "find-regular-expression")
+#define E_EDITOR_WIDGETS_FIND_RESULT_LABEL(editor) \
+ E_EDITOR_WIDGETS ((editor), "find-result-label")
+#define E_EDITOR_WIDGETS_FIND_WRAP(editor) \
+ E_EDITOR_WIDGETS ((editor), "find-wrap")
+
+/* Image Properties Window */
+#define E_EDITOR_WIDGETS_IMAGE_PROPERTIES_ALIGNMENT_COMBO_BOX(editor) \
+ E_EDITOR_WIDGETS ((editor), "image-properties-alignment-combo-box")
+#define E_EDITOR_WIDGETS_IMAGE_PROPERTIES_BORDER_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "image-properties-border-spin-button")
+#define E_EDITOR_WIDGETS_IMAGE_PROPERTIES_DESCRIPTION_ENTRY(editor) \
+ E_EDITOR_WIDGETS ((editor), "image-properties-description-entry")
+#define E_EDITOR_WIDGETS_IMAGE_PROPERTIES_HEIGHT_COMBO_BOX(editor) \
+ E_EDITOR_WIDGETS ((editor), "image-properties-height-combo-box")
+#define E_EDITOR_WIDGETS_IMAGE_PROPERTIES_HEIGHT_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "image-properties-height-spin-button")
+#define E_EDITOR_WIDGETS_IMAGE_PROPERTIES_SOURCE_FILE_CHOOSER(editor) \
+ E_EDITOR_WIDGETS ((editor), "image-properties-source-file-chooser")
+#define E_EDITOR_WIDGETS_IMAGE_PROPERTIES_URL_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "image-properties-url-button")
+#define E_EDITOR_WIDGETS_IMAGE_PROPERTIES_URL_ENTRY(editor) \
+ E_EDITOR_WIDGETS ((editor), "image-properties-url-entry")
+#define E_EDITOR_WIDGETS_IMAGE_PROPERTIES_WIDTH_COMBO_BOX(editor) \
+ E_EDITOR_WIDGETS ((editor), "image-properties-width-combo-box")
+#define E_EDITOR_WIDGETS_IMAGE_PROPERTIES_WIDTH_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "image-properties-width-spin-button")
+#define E_EDITOR_WIDGETS_IMAGE_PROPERTIES_WINDOW(editor) \
+ E_EDITOR_WIDGETS ((editor), "image-properties-window")
+#define E_EDITOR_WIDGETS_IMAGE_PROPERTIES_X_PADDING_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "image-properties-x-padding-spin-button")
+#define E_EDITOR_WIDGETS_IMAGE_PROPERTIES_Y_PADDING_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "image-properties-y-padding-spin-button")
+
+/* Link Properties Window */
+#define E_EDITOR_WIDGETS_LINK_PROPERTIES_DESCRIPTION_ENTRY(editor) \
+ E_EDITOR_WIDGETS ((editor), "link-properties-description-entry")
+#define E_EDITOR_WIDGETS_LINK_PROPERTIES_TEST_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "link-properties-test-button")
+#define E_EDITOR_WIDGETS_LINK_PROPERTIES_URL_ENTRY(editor) \
+ E_EDITOR_WIDGETS ((editor), "link-properties-url-entry")
+#define E_EDITOR_WIDGETS_LINK_PROPERTIES_WINDOW(editor) \
+ E_EDITOR_WIDGETS ((editor), "link-properties-window")
+
+/* Page Properties Window */
+#define E_EDITOR_WIDGETS_PAGE_PROPERTIES_BACKGROUND_COLOR_COMBO(editor) \
+ E_EDITOR_WIDGETS ((editor), "page-properties-background-color-combo")
+#define E_EDITOR_WIDGETS_PAGE_PROPERTIES_CUSTOM_FILE_CHOOSER(editor) \
+ E_EDITOR_WIDGETS ((editor), "page-properties-custom-file-chooser")
+#define E_EDITOR_WIDGETS_PAGE_PROPERTIES_LINK_COLOR_COMBO(editor) \
+ E_EDITOR_WIDGETS ((editor), "page-properties-link-color-combo")
+#define E_EDITOR_WIDGETS_PAGE_PROPERTIES_TEMPLATE_COMBO_BOX(editor) \
+ E_EDITOR_WIDGETS ((editor), "page-properties-template-combo-box")
+#define E_EDITOR_WIDGETS_PAGE_PROPERTIES_TEXT_COLOR_COMBO(editor) \
+ E_EDITOR_WIDGETS ((editor), "page-properties-text-color-combo")
+#define E_EDITOR_WIDGETS_PAGE_PROPERTIES_WINDOW(editor) \
+ E_EDITOR_WIDGETS ((editor), "page-properties-window")
+
+/* Paragraph Properties Window */
+#define E_EDITOR_WIDGETS_PARAGRAPH_PROPERTIES_CENTER_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "paragraph-properties-center-button")
+#define E_EDITOR_WIDGETS_PARAGRAPH_PROPERTIES_LEFT_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "paragraph-properties-left-button")
+#define E_EDITOR_WIDGETS_PARAGRAPH_PROPERTIES_RIGHT_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "paragraph-properties-right-button")
+#define E_EDITOR_WIDGETS_PARAGRAPH_PROPERTIES_STYLE_COMBO_BOX(editor) \
+ E_EDITOR_WIDGETS ((editor), "paragraph-properties-style-combo-box")
+#define E_EDITOR_WIDGETS_PARAGRAPH_PROPERTIES_WINDOW(editor) \
+ E_EDITOR_WIDGETS ((editor), "paragraph-properties-window")
+
+/* Replace Confirmation Window */
+#define E_EDITOR_WIDGETS_REPLACE_CONFIRMATION_CLOSE_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "replace-confirmation-close-button")
+#define E_EDITOR_WIDGETS_REPLACE_CONFIRMATION_NEXT_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "replace-confirmation-next-button")
+#define E_EDITOR_WIDGETS_REPLACE_CONFIRMATION_REPLACE_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "replace-confirmation-replace-button")
+#define E_EDITOR_WIDGETS_REPLACE_CONFIRMATION_REPLACE_ALL_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "replace-confirmation-replace-all-button")
+#define E_EDITOR_WIDGETS_REPLACE_CONFIRMATION_WINDOW(editor) \
+ E_EDITOR_WIDGETS ((editor), "replace-confirmation-window")
+
+/* Replace Window */
+#define E_EDITOR_WIDGETS_REPLACE_BACKWARDS(editor) \
+ E_EDITOR_WIDGETS ((editor), "replace-backwards")
+#define E_EDITOR_WIDGETS_REPLACE_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "replace-button")
+#define E_EDITOR_WIDGETS_REPLACE_CASE_SENSITIVE(editor) \
+ E_EDITOR_WIDGETS ((editor), "replace-case-sensitive")
+#define E_EDITOR_WIDGETS_REPLACE_ENTRY(editor) \
+ E_EDITOR_WIDGETS ((editor), "replace-entry")
+#define E_EDITOR_WIDGETS_REPLACE_WITH_ENTRY(editor) \
+ E_EDITOR_WIDGETS ((editor), "replace-with-entry")
+#define E_EDITOR_WIDGETS_REPLACE_WINDOW(editor) \
+ E_EDITOR_WIDGETS ((editor), "replace-window")
+#define E_EDITOR_WIDGETS_REPLACE_WRAP(editor) \
+ E_EDITOR_WIDGETS ((editor), "replace-wrap")
+#define E_EDITOR_WIDGETS_REPLACE_ONLY_SELECTION(editor) \
+ E_EDITOR_WIDGETS ((editor), "replace-only-selection")
+
+/* Rule Properties Window */
+#define E_EDITOR_WIDGETS_RULE_PROPERTIES_ALIGNMENT_COMBO_BOX(editor) \
+ E_EDITOR_WIDGETS ((editor), "rule-properties-alignment-combo-box")
+#define E_EDITOR_WIDGETS_RULE_PROPERTIES_SHADED_CHECK_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "rule-properties-shaded-check-button")
+#define E_EDITOR_WIDGETS_RULE_PROPERTIES_SIZE_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "rule-properties-size-spin-button")
+#define E_EDITOR_WIDGETS_RULE_PROPERTIES_WIDTH_COMBO_BOX(editor) \
+ E_EDITOR_WIDGETS ((editor), "rule-properties-width-combo-box")
+#define E_EDITOR_WIDGETS_RULE_PROPERTIES_WIDTH_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "rule-properties-width-spin-button")
+#define E_EDITOR_WIDGETS_RULE_PROPERTIES_WINDOW(editor) \
+ E_EDITOR_WIDGETS ((editor), "rule-properties-window")
+
+/* Spell Check Window */
+#define E_EDITOR_WIDGETS_SPELL_WINDOW(editor) \
+ E_EDITOR_WIDGETS ((editor), "spell-window")
+
+/* Table Properties Window */
+#define E_EDITOR_WIDGETS_TABLE_PROPERTIES_ALIGNMENT_COMBO_BOX(editor) \
+ E_EDITOR_WIDGETS ((editor), "table-properties-alignment-combo-box")
+#define E_EDITOR_WIDGETS_TABLE_PROPERTIES_BORDER_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "table-properties-border-spin-button")
+#define E_EDITOR_WIDGETS_TABLE_PROPERTIES_COLOR_COMBO(editor) \
+ E_EDITOR_WIDGETS ((editor), "table-properties-color-combo")
+#define E_EDITOR_WIDGETS_TABLE_PROPERTIES_COLS_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "table-properties-cols-spin-button")
+#define E_EDITOR_WIDGETS_TABLE_PROPERTIES_IMAGE_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "table-properties-image-button")
+#define E_EDITOR_WIDGETS_TABLE_PROPERTIES_PADDING_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "table-properties-padding-spin-button")
+#define E_EDITOR_WIDGETS_TABLE_PROPERTIES_ROWS_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "table-properties-rows-spin-button")
+#define E_EDITOR_WIDGETS_TABLE_PROPERTIES_SPACING_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "table-properties-spacing-spin-button")
+#define E_EDITOR_WIDGETS_TABLE_PROPERTIES_WIDTH_CHECK_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "table-properties-width-check-button")
+#define E_EDITOR_WIDGETS_TABLE_PROPERTIES_WIDTH_COMBO_BOX(editor) \
+ E_EDITOR_WIDGETS ((editor), "table-properties-width-combo-box")
+#define E_EDITOR_WIDGETS_TABLE_PROPERTIES_WIDTH_SPIN_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "table-properties-width-spin-button")
+#define E_EDITOR_WIDGETS_TABLE_PROPERTIES_WINDOW(editor) \
+ E_EDITOR_WIDGETS ((editor), "table-properties-window")
+
+/* Text Properties Window */
+#define E_EDITOR_WIDGETS_TEXT_PROPERTIES_BOLD_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "text-properties-bold-button")
+#define E_EDITOR_WIDGETS_TEXT_PROPERTIES_COLOR_COMBO(editor) \
+ E_EDITOR_WIDGETS ((editor), "text-properties-color-combo")
+#define E_EDITOR_WIDGETS_TEXT_PROPERTIES_ITALIC_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "text-properties-italic-button")
+#define E_EDITOR_WIDGETS_TEXT_PROPERTIES_SIZE_COMBO_BOX(editor) \
+ E_EDITOR_WIDGETS ((editor), "text-properties-size-combo-box")
+#define E_EDITOR_WIDGETS_TEXT_PROPERTIES_STRIKETHROUGH_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "text-properties-strikethrough-button")
+#define E_EDITOR_WIDGETS_TEXT_PROPERTIES_UNDERLINE_BUTTON(editor) \
+ E_EDITOR_WIDGETS ((editor), "text-properties-underline-button")
+#define E_EDITOR_WIDGETS_TEXT_PROPERTIES_WINDOW(editor) \
+ E_EDITOR_WIDGETS ((editor), "text-properties-window")
+
+#endif /* E_EDITOR_WIDGETS_H */
diff --git a/e-util/e-editor.c b/e-util/e-editor.c
new file mode 100644
index 0000000..61bfdd9
--- /dev/null
+++ b/e-util/e-editor.c
@@ -0,0 +1,576 @@
+/* e-editor.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-editor.h"
+#include "e-editor-private.h"
+
+#include <glib/gi18n-lib.h>
+
+G_DEFINE_TYPE (
+ EEditor,
+ e_editor,
+ GTK_TYPE_BOX);
+
+enum {
+ PROP_0,
+ PROP_FILENAME
+};
+
+static gchar *
+editor_find_ui_file (const gchar *basename)
+{
+ gchar *filename;
+
+ g_return_val_if_fail (basename != NULL, NULL);
+
+ /* Support running directly from the source tree. */
+ filename = g_build_filename (".", basename, NULL);
+ if (g_file_test (filename, G_FILE_TEST_EXISTS))
+ return filename;
+ g_free (filename);
+
+ /* XXX This is kinda broken. */
+ filename = g_build_filename (EVOLUTION_UIDIR, basename, NULL);
+ if (g_file_test (filename, G_FILE_TEST_EXISTS))
+ return filename;
+ g_free (filename);
+
+ g_critical ("Could not locate '%s'", basename);
+
+ return NULL;
+}
+
+static void
+editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+
+ case PROP_FILENAME:
+ e_editor_set_filename (E_EDITOR (object),
+ g_value_get_string (value));
+ return;
+
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+
+ case PROP_FILENAME:
+ g_value_set_string (
+ value, e_editor_get_filename(
+ E_EDITOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+editor_constructed (GObject *object)
+{
+ EEditor *editor = E_EDITOR (object);
+ EEditorPrivate *priv = editor->priv;
+
+ GtkWidget *widget;
+ GtkToolbar *toolbar;
+ GtkToolItem *tool_item;
+
+ /* Construct main window widgets. */
+
+ widget = e_editor_get_managed_widget (editor, "/main-menu");
+ gtk_box_pack_start (GTK_BOX (editor), widget, FALSE, FALSE, 0);
+ priv->main_menu = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = e_editor_get_managed_widget (editor, "/main-toolbar");
+ gtk_box_pack_start (GTK_BOX (editor), widget, FALSE, FALSE, 0);
+ priv->main_toolbar = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ gtk_style_context_add_class (
+ gtk_widget_get_style_context (widget),
+ GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
+
+ widget = e_editor_get_managed_widget (editor, "/edit-toolbar");
+ gtk_toolbar_set_style (GTK_TOOLBAR (widget), GTK_TOOLBAR_BOTH_HORIZ);
+ gtk_box_pack_start (GTK_BOX (editor), widget, FALSE, FALSE, 0);
+ priv->edit_toolbar = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = e_editor_get_managed_widget (editor, "/html-toolbar");
+ gtk_toolbar_set_style (GTK_TOOLBAR (widget), GTK_TOOLBAR_BOTH_HORIZ);
+ gtk_box_pack_start (GTK_BOX (editor), widget, FALSE, FALSE, 0);
+ priv->html_toolbar = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_box_pack_start (GTK_BOX (editor), widget, TRUE, TRUE, 0);
+ priv->scrolled_window = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = GTK_WIDGET (e_editor_get_editor_widget (editor));
+ gtk_container_add (GTK_CONTAINER (priv->scrolled_window), widget);
+ gtk_widget_show (widget);
+
+ /* Add some combo boxes to the "edit" toolbar. */
+
+ toolbar = GTK_TOOLBAR (priv->edit_toolbar);
+
+ tool_item = gtk_tool_item_new ();
+ widget = e_action_combo_box_new_with_action (
+ GTK_RADIO_ACTION (ACTION (STYLE_NORMAL)));
+ gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (widget), FALSE);
+ gtk_container_add (GTK_CONTAINER (tool_item), widget);
+ gtk_widget_set_tooltip_text (widget, _("Paragraph Style"));
+ gtk_toolbar_insert (toolbar, tool_item, 0);
+ priv->style_combo_box = g_object_ref (widget);
+ gtk_widget_show_all (GTK_WIDGET (tool_item));
+
+ tool_item = gtk_separator_tool_item_new ();
+ gtk_toolbar_insert (toolbar, tool_item, 0);
+ gtk_widget_show_all (GTK_WIDGET (tool_item));
+
+ tool_item = gtk_tool_item_new ();
+ widget = e_action_combo_box_new_with_action (
+ GTK_RADIO_ACTION (ACTION (MODE_HTML)));
+ gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (widget), FALSE);
+ gtk_container_add (GTK_CONTAINER (tool_item), widget);
+ gtk_widget_set_tooltip_text (widget, _("Editing Mode"));
+ gtk_toolbar_insert (toolbar, tool_item, 0);
+ priv->mode_combo_box = g_object_ref (widget);
+ gtk_widget_show_all (GTK_WIDGET (tool_item));
+
+ /* Add some combo boxes to the "html" toolbar. */
+
+ toolbar = GTK_TOOLBAR (priv->html_toolbar);
+
+ tool_item = gtk_tool_item_new ();
+ widget = e_color_combo_new ();
+ gtk_container_add (GTK_CONTAINER (tool_item), widget);
+ gtk_widget_set_tooltip_text (widget, _("Font Color"));
+ gtk_toolbar_insert (toolbar, tool_item, 0);
+ priv->color_combo_box = g_object_ref (widget);
+ gtk_widget_show_all (GTK_WIDGET (tool_item));
+
+ tool_item = gtk_tool_item_new ();
+ widget = e_action_combo_box_new_with_action (
+ GTK_RADIO_ACTION (ACTION (SIZE_PLUS_ZERO)));
+ gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (widget), FALSE);
+ gtk_container_add (GTK_CONTAINER (tool_item), widget);
+ gtk_widget_set_tooltip_text (widget, _("Font Size"));
+ gtk_toolbar_insert (toolbar, tool_item, 0);
+ priv->size_combo_box = g_object_ref (widget);
+ gtk_widget_show_all (GTK_WIDGET (tool_item));
+
+ /* Initialize painters (requires "edit_area"). */
+
+ /* FIXME WEBKIT
+ html = e_editor_widget_get_html (E_EDITOR_WIDGET (editor));
+ gtk_widget_ensure_style (GTK_WIDGET (html));
+ priv->html_painter = g_object_ref (html->engine->painter);
+ priv->plain_painter = html_plain_painter_new (priv->edit_area, TRUE);
+ */
+
+ /* Add input methods to the context menu. */
+
+ /* FIXME WEBKIT
+ widget = e_editor_get_managed_widget (
+ editor, "/context-menu/context-input-methods-menu");
+ widget = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ gtk_im_multicontext_append_menuitems (
+ GTK_IM_MULTICONTEXT (html->priv->im_context),
+ GTK_MENU_SHELL (widget));
+ */
+
+ /* Configure color stuff. */
+
+ /* FIXME WEBKIT
+ priv->palette = gtkhtml_color_palette_new ();
+ priv->text_color = gtkhtml_color_state_new ();
+
+ gtkhtml_color_state_set_default_label (
+ priv->text_color, _("Automatic"));
+ gtkhtml_color_state_set_palette (
+ priv->text_color, priv->palette);
+ */
+
+ /* Text color widgets share state. */
+
+ /* FIXME WEBKIT
+ widget = priv->color_combo_box;
+ gtkhtml_color_combo_set_state (
+ GTKHTML_COLOR_COMBO (widget), priv->text_color);
+
+ widget = WIDGET (TEXT_PROPERTIES_COLOR_COMBO);
+ gtkhtml_color_combo_set_state (
+ GTKHTML_COLOR_COMBO (widget), priv->text_color);
+ */
+
+ /* These color widgets share a custom color palette. */
+
+ /* FIXME WEBKIT
+ widget = WIDGET (CELL_PROPERTIES_COLOR_COMBO);
+ gtkhtml_color_combo_set_palette (
+ GTKHTML_COLOR_COMBO (widget), priv->palette);
+
+ widget = WIDGET (PAGE_PROPERTIES_BACKGROUND_COLOR_COMBO);
+ gtkhtml_color_combo_set_palette (
+ GTKHTML_COLOR_COMBO (widget), priv->palette);
+
+ widget = WIDGET (PAGE_PROPERTIES_LINK_COLOR_COMBO);
+ gtkhtml_color_combo_set_palette (
+ GTKHTML_COLOR_COMBO (widget), priv->palette);
+
+ widget = WIDGET (TABLE_PROPERTIES_COLOR_COMBO);
+ gtkhtml_color_combo_set_palette (
+ GTKHTML_COLOR_COMBO (widget), priv->palette);
+ */
+}
+
+static void
+editor_dispose (GObject *object)
+{
+ EEditor *editor = E_EDITOR (object);
+ EEditorPrivate *priv = editor->priv;
+
+ /* Disconnect signal handlers from the color
+ * state object since it may live on. */
+ /* FIXME WEBKIT
+ if (priv->text_color != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->text_color, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, editor);
+ }
+ */
+
+ g_clear_object (&priv->manager);
+ g_clear_object (&priv->manager);
+ g_clear_object (&priv->core_actions);
+ g_clear_object (&priv->html_actions);
+ g_clear_object (&priv->context_actions);
+ g_clear_object (&priv->html_context_actions);
+ g_clear_object (&priv->language_actions);
+ g_clear_object (&priv->spell_check_actions);
+ g_clear_object (&priv->suggestion_actions);
+ g_clear_object (&priv->builder);
+
+ /* FIXME WEBKIT
+ g_hash_table_remove_all (priv->available_spell_checkers);
+
+ g_list_foreach (
+ priv->active_spell_checkers,
+ (GFunc) g_object_unref, NULL);
+ g_list_free (priv->active_spell_checkers);
+ priv->active_spell_checkers = NULL;
+ */
+
+ g_clear_object (&priv->main_menu);
+ g_clear_object (&priv->main_toolbar);
+ g_clear_object (&priv->edit_toolbar);
+ g_clear_object (&priv->html_toolbar);
+ g_clear_object (&priv->edit_area);
+
+ g_clear_object (&priv->color_combo_box);
+ g_clear_object (&priv->mode_combo_box);
+ g_clear_object (&priv->size_combo_box);
+ g_clear_object (&priv->style_combo_box);
+ g_clear_object (&priv->scrolled_window);
+
+ /* FIXME WEBKIT
+ DISPOSE (priv->palette);
+ DISPOSE (priv->text_color);
+ */
+}
+
+static void
+e_editor_class_init (EEditorClass *klass)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (klass, sizeof (EEditorPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->set_property = editor_set_property;
+ object_class->get_property = editor_get_property;
+ object_class->constructed = editor_constructed;
+ object_class->dispose = editor_dispose;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FILENAME,
+ g_param_spec_string (
+ "filename",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+}
+
+static void
+e_editor_init (EEditor *editor)
+{
+ EEditorPrivate *priv;
+ GError *error;
+ gchar *filename;
+
+ editor->priv = G_TYPE_INSTANCE_GET_PRIVATE (
+ editor, E_TYPE_EDITOR, EEditorPrivate);
+
+ priv = editor->priv;
+
+ priv->manager = gtk_ui_manager_new ();
+ priv->core_actions = gtk_action_group_new ("core");
+ priv->html_actions = gtk_action_group_new ("html");
+ priv->context_actions = gtk_action_group_new ("core-context");
+ priv->html_context_actions = gtk_action_group_new ("html-context");
+ priv->language_actions = gtk_action_group_new ("language");
+ priv->spell_check_actions = gtk_action_group_new ("spell-check");
+ priv->suggestion_actions = gtk_action_group_new ("suggestion");
+ priv->editor_widget = e_editor_widget_new ();
+
+ filename = editor_find_ui_file ("e-editor-manager.ui");
+
+ error = NULL;
+ if (!gtk_ui_manager_add_ui_from_file (priv->manager, filename, &error)) {
+ g_critical ("Couldn't load builder file: %s\n", error->message);
+ g_clear_error (&error);
+ }
+
+ g_free (filename);
+
+ filename = editor_find_ui_file ("e-editor-builder.ui");
+
+ priv->builder = gtk_builder_new ();
+ /* To keep translated strings in subclasses */
+ gtk_builder_set_translation_domain (priv->builder, GETTEXT_PACKAGE);
+ error = NULL;
+ if (!gtk_builder_add_from_file (priv->builder, filename, &error)) {
+ g_critical ("Couldn't load builder file: %s\n", error->message);
+ g_clear_error (&error);
+ }
+
+ g_free (filename);
+
+ editor_actions_init (editor);
+}
+
+GtkWidget *
+e_editor_new (void)
+{
+ return g_object_new (E_TYPE_EDITOR,
+ "orientation", GTK_ORIENTATION_VERTICAL,
+ NULL);
+}
+
+EEditorWidget *
+e_editor_get_editor_widget (EEditor *editor)
+{
+ g_return_val_if_fail (E_IS_EDITOR (editor), NULL);
+
+ return editor->priv->editor_widget;
+}
+
+
+GtkBuilder *
+e_editor_get_builder (EEditor *editor)
+{
+ g_return_val_if_fail (E_IS_EDITOR (editor), NULL);
+
+ return editor->priv->builder;
+}
+
+GtkUIManager *
+e_editor_get_ui_manager (EEditor *editor)
+{
+ g_return_val_if_fail (E_IS_EDITOR (editor), NULL);
+
+ return editor->priv->manager;
+}
+
+GtkAction *
+e_editor_get_action (EEditor *editor,
+ const gchar *action_name)
+{
+ GtkUIManager *manager;
+ GtkAction *action = NULL;
+ GList *iter;
+
+ g_return_val_if_fail (E_IS_EDITOR (editor), NULL);
+ g_return_val_if_fail (action_name != NULL, NULL);
+
+ manager = e_editor_get_ui_manager (editor);
+ iter = gtk_ui_manager_get_action_groups (manager);
+
+ while (iter != NULL && action == NULL) {
+ GtkActionGroup *action_group = iter->data;
+
+ action = gtk_action_group_get_action (
+ action_group, action_name);
+ iter = g_list_next (iter);
+ }
+
+ g_return_val_if_fail (action != NULL, NULL);
+
+ return action;
+}
+
+GtkActionGroup *
+e_editor_get_action_group (EEditor *editor,
+ const gchar *group_name)
+{
+ GtkUIManager *manager;
+ GList *iter;
+
+ g_return_val_if_fail (E_IS_EDITOR (editor), NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+
+ manager = e_editor_get_ui_manager (editor);
+ iter = gtk_ui_manager_get_action_groups (manager);
+
+ while (iter != NULL) {
+ GtkActionGroup *action_group = iter->data;
+ const gchar *name;
+
+ name = gtk_action_group_get_name (action_group);
+ if (strcmp (name, group_name) == 0)
+ return action_group;
+
+ iter = g_list_next (iter);
+ }
+
+ return NULL;
+}
+
+GtkWidget *
+e_editor_get_widget (EEditor *editor,
+ const gchar *widget_name)
+{
+ GtkBuilder *builder;
+ GObject *object;
+
+ g_return_val_if_fail (E_IS_EDITOR (editor), NULL);
+ g_return_val_if_fail (widget_name != NULL, NULL);
+
+ builder = e_editor_get_builder (editor);
+ object = gtk_builder_get_object (builder, widget_name);
+ g_return_val_if_fail (GTK_IS_WIDGET (object), NULL);
+
+ return GTK_WIDGET (object);
+}
+
+GtkWidget *
+e_editor_get_managed_widget (EEditor *editor,
+ const gchar *widget_path)
+{
+ GtkUIManager *manager;
+ GtkWidget *widget;
+
+ g_return_val_if_fail (E_IS_EDITOR (editor), NULL);
+ g_return_val_if_fail (widget_path != NULL, NULL);
+
+ manager = e_editor_get_ui_manager (editor);
+ widget = gtk_ui_manager_get_widget (manager, widget_path);
+
+ g_return_val_if_fail (widget != NULL, NULL);
+
+ return widget;
+}
+
+const gchar *
+e_editor_get_filename (EEditor *editor)
+{
+ g_return_val_if_fail (E_IS_EDITOR (editor), NULL);
+
+ return editor->priv->filename;
+}
+
+void
+e_editor_set_filename (EEditor *editor,
+ const gchar *filename)
+{
+ g_return_if_fail (E_IS_EDITOR (editor));
+
+ if (g_strcmp0 (editor->priv->filename, filename) == 0)
+ return;
+
+ g_free (editor->priv->filename);
+ editor->priv->filename = g_strdup (filename);
+
+ g_object_notify (G_OBJECT (editor), "filename");
+}
+
+gboolean
+e_editor_save (EEditor *editor,
+ const gchar *filename,
+ gboolean as_html,
+ GError **error)
+{
+ GFile *file;
+ GFileOutputStream *stream;
+ gchar *content;
+ gsize written;
+
+ file = g_file_new_for_path (filename);
+ stream = g_file_replace (
+ file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error);
+ if ((error && *error) || !stream)
+ return FALSE;
+
+ if (as_html) {
+ content = e_editor_widget_get_text_html (
+ E_EDITOR_WIDGET (editor));
+ } else {
+ content = e_editor_widget_get_text_plain (
+ E_EDITOR_WIDGET (editor));
+ }
+
+ if (!content || !*content) {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Failed to obtain content of editor");
+ return FALSE;
+ }
+
+ g_output_stream_write_all (
+ G_OUTPUT_STREAM (stream), content, strlen (content),
+ &written, NULL, error);
+
+ g_free (content);
+ g_object_unref (stream);
+ g_object_unref (file);
+
+ return TRUE;
+}
diff --git a/e-util/e-editor.h b/e-util/e-editor.h
new file mode 100644
index 0000000..9b878eb
--- /dev/null
+++ b/e-util/e-editor.h
@@ -0,0 +1,95 @@
+/* e-editor.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
+#error "Only <e-util/e-util.h> should be included directly."
+#endif
+
+#ifndef E_EDITOR_H
+#define E_EDITOR_H
+
+#include <gtk/gtk.h>
+#include <e-util/e-editor-widget.h>
+
+/* Standard GObject macros */
+#define E_TYPE_EDITOR \
+ (e_editor_get_type ())
+#define E_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_EDITOR, EEditor))
+#define E_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_EDITOR, EEditorClass))
+#define E_IS_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_EDITOR))
+#define E_IS_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_EDITOR))
+#define E_EDITOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_EDITOR, EEditorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EEditor EEditor;
+typedef struct _EEditorClass EEditorClass;
+typedef struct _EEditorPrivate EEditorPrivate;
+
+struct _EEditor {
+ GtkBox parent;
+
+ EEditorPrivate *priv;
+};
+
+struct _EEditorClass {
+ GtkBoxClass parent_class;
+};
+
+GType e_editor_get_type (void);
+GtkWidget * e_editor_new (void);
+
+EEditorWidget* e_editor_get_editor_widget (EEditor *editor);
+
+GtkBuilder * e_editor_get_builder (EEditor *editor);
+GtkUIManager * e_editor_get_ui_manager (EEditor *editor);
+GtkAction * e_editor_get_action (EEditor *editor,
+ const gchar *action_name);
+GtkActionGroup *e_editor_get_action_group (EEditor *editor,
+ const gchar *group_name);
+GtkWidget * e_editor_get_widget (EEditor *editor,
+ const gchar *widget_name);
+GtkWidget * e_editor_get_managed_widget
+ (EEditor *editor,
+ const gchar *widget_path);
+const gchar * e_editor_get_filename (EEditor *editor);
+void e_editor_set_filename (EEditor *editor,
+ const gchar *filename);
+
+
+/*****************************************************************************
+ * High-Level Editing Interface
+ *****************************************************************************/
+
+gboolean e_editor_save (EEditor *editor,
+ const gchar *filename,
+ gboolean as_html,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_EDITOR_H */
diff --git a/e-util/e-util.h b/e-util/e-util.h
index 27d73bb..c6a9421 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -92,8 +92,11 @@
#include <e-util/e-destination-store.h>
#include <e-util/e-dialog-utils.h>
#include <e-util/e-dialog-widgets.h>
+#include <e-util/e-editor-actions.h>
#include <e-util/e-editor-selection.h>
#include <e-util/e-editor-widget.h>
+#include <e-util/e-editor-widgets.h>
+#include <e-util/e-editor.h>
#include <e-util/e-emoticon-action.h>
#include <e-util/e-emoticon-chooser-menu.h>
#include <e-util/e-emoticon-chooser.h>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]