diff options
author | Tomas Popela <tpopela@redhat.com> | 2014-06-09 22:32:25 +0800 |
---|---|---|
committer | Tomas Popela <tpopela@redhat.com> | 2014-06-09 22:32:25 +0800 |
commit | 8650fb139a9143f04615de74ff569bce3e0c4ce3 (patch) | |
tree | 89a41d08f179a5359b8eaee0c9344b8a5bf07cb3 /e-util/e-html-editor-spell-check-dialog.c | |
parent | 04b7c97275ae420dca43f3e65c2ef54d02f01bdd (diff) | |
download | gsoc2013-evolution-8650fb139a9143f04615de74ff569bce3e0c4ce3.tar gsoc2013-evolution-8650fb139a9143f04615de74ff569bce3e0c4ce3.tar.gz gsoc2013-evolution-8650fb139a9143f04615de74ff569bce3e0c4ce3.tar.bz2 gsoc2013-evolution-8650fb139a9143f04615de74ff569bce3e0c4ce3.tar.lz gsoc2013-evolution-8650fb139a9143f04615de74ff569bce3e0c4ce3.tar.xz gsoc2013-evolution-8650fb139a9143f04615de74ff569bce3e0c4ce3.tar.zst gsoc2013-evolution-8650fb139a9143f04615de74ff569bce3e0c4ce3.zip |
Bug 540362: [webkit-composer] Use webkit for composer
Merge wip/webkit-composer branch into master.
Diffstat (limited to 'e-util/e-html-editor-spell-check-dialog.c')
-rw-r--r-- | e-util/e-html-editor-spell-check-dialog.c | 710 |
1 files changed, 710 insertions, 0 deletions
diff --git a/e-util/e-html-editor-spell-check-dialog.c b/e-util/e-html-editor-spell-check-dialog.c new file mode 100644 index 0000000000..b399dfabd8 --- /dev/null +++ b/e-util/e-html-editor-spell-check-dialog.c @@ -0,0 +1,710 @@ +/* + * e-html-editor-spell-dialog.c + * + * Copyright (C) 2012 Dan Vrátil <dvratil@redhat.com> + * + * 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-html-editor-spell-check-dialog.h" + +#include <glib/gi18n-lib.h> +#include <enchant/enchant.h> + +#include "e-html-editor-view.h" +#include "e-spell-checker.h" +#include "e-spell-dictionary.h" + +#define E_HTML_EDITOR_SPELL_CHECK_DIALOG_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_HTML_EDITOR_SPELL_CHECK_DIALOG, EHTMLEditorSpellCheckDialogPrivate)) + +struct _EHTMLEditorSpellCheckDialogPrivate { + GtkWidget *add_word_button; + GtkWidget *back_button; + GtkWidget *dictionary_combo; + GtkWidget *ignore_button; + GtkWidget *replace_button; + GtkWidget *replace_all_button; + GtkWidget *skip_button; + GtkWidget *suggestion_label; + GtkWidget *tree_view; + + WebKitDOMDOMSelection *selection; + + gchar *word; + ESpellDictionary *current_dict; +}; + +enum { + COLUMN_NAME, + COLUMN_DICTIONARY, + NUM_COLUMNS +}; + +G_DEFINE_TYPE ( + EHTMLEditorSpellCheckDialog, + e_html_editor_spell_check_dialog, + E_TYPE_HTML_EDITOR_DIALOG) + +static void +html_editor_spell_check_dialog_set_word (EHTMLEditorSpellCheckDialog *dialog, + const gchar *word) +{ + EHTMLEditor *editor; + EHTMLEditorView *view; + GtkTreeView *tree_view; + GtkListStore *store; + gchar *markup; + GList *list, *link; + + if (word == NULL) + return; + + if (dialog->priv->word != word) { + g_free (dialog->priv->word); + dialog->priv->word = g_strdup (word); + } + + markup = g_strdup_printf (_("<b>Suggestions for '%s'</b>"), word); + gtk_label_set_markup ( + GTK_LABEL (dialog->priv->suggestion_label), markup); + g_free (markup); + + tree_view = GTK_TREE_VIEW (dialog->priv->tree_view); + store = GTK_LIST_STORE (gtk_tree_view_get_model (tree_view)); + gtk_list_store_clear (store); + + list = e_spell_dictionary_get_suggestions ( + dialog->priv->current_dict, word, -1); + + for (link = list; link != NULL; link = g_list_next (link)) { + GtkTreeIter iter; + gchar *suggestion = link->data; + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, suggestion, -1); + } + + g_list_free_full (list, (GDestroyNotify) g_free); + + /* We give focus to WebKit so that the currently selected word + * is highlited. Without focus selection is not visible (at + * least with my default color scheme). The focus in fact is not + * given to WebKit, because this dialog is modal, but it satisfies + * it in a way that it paints the selection :) */ + editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog)); + view = e_html_editor_get_view (editor); + gtk_widget_grab_focus (GTK_WIDGET (view)); +} + +static gboolean +select_next_word (EHTMLEditorSpellCheckDialog *dialog) +{ + WebKitDOMNode *anchor, *focus; + gulong anchor_offset, focus_offset; + + anchor = webkit_dom_dom_selection_get_anchor_node (dialog->priv->selection); + anchor_offset = webkit_dom_dom_selection_get_anchor_offset (dialog->priv->selection); + + focus = webkit_dom_dom_selection_get_focus_node (dialog->priv->selection); + focus_offset = webkit_dom_dom_selection_get_focus_offset (dialog->priv->selection); + + /* Jump _behind_ next word */ + webkit_dom_dom_selection_modify ( + dialog->priv->selection, "move", "forward", "word"); + /* Jump before the word */ + webkit_dom_dom_selection_modify ( + dialog->priv->selection, "move", "backward", "word"); + /* Select it */ + webkit_dom_dom_selection_modify ( + dialog->priv->selection, "extend", "forward", "word"); + + /* If the selection didn't change, then we have most probably + * reached the end of document - return FALSE */ + return !((anchor == webkit_dom_dom_selection_get_anchor_node ( + dialog->priv->selection)) && + (anchor_offset == webkit_dom_dom_selection_get_anchor_offset ( + dialog->priv->selection)) && + (focus == webkit_dom_dom_selection_get_focus_node ( + dialog->priv->selection)) && + (focus_offset == webkit_dom_dom_selection_get_focus_offset ( + dialog->priv->selection))); +} + +static gboolean +html_editor_spell_check_dialog_next (EHTMLEditorSpellCheckDialog *dialog) +{ + WebKitDOMNode *start = NULL, *end = NULL; + gulong start_offset, end_offset; + + if (dialog->priv->word == NULL) { + webkit_dom_dom_selection_modify ( + dialog->priv->selection, "move", "left", "documentboundary"); + } else { + /* Remember last selected word */ + start = webkit_dom_dom_selection_get_anchor_node ( + dialog->priv->selection); + end = webkit_dom_dom_selection_get_focus_node ( + dialog->priv->selection); + start_offset = webkit_dom_dom_selection_get_anchor_offset ( + dialog->priv->selection); + end_offset = webkit_dom_dom_selection_get_focus_offset ( + dialog->priv->selection); + } + + while (select_next_word (dialog)) { + WebKitDOMRange *range; + WebKitSpellChecker *checker; + gint loc, len; + gchar *word; + + range = webkit_dom_dom_selection_get_range_at ( + dialog->priv->selection, 0, NULL); + word = webkit_dom_range_get_text (range); + + checker = WEBKIT_SPELL_CHECKER (webkit_get_text_checker ()); + webkit_spell_checker_check_spelling_of_string ( + checker, word, &loc, &len); + + /* Found misspelled word! */ + if (loc != -1) { + html_editor_spell_check_dialog_set_word (dialog, word); + g_free (word); + return TRUE; + } + + g_free (word); + } + + /* Restore the selection to contain the last misspelled word. This is + * reached only when we reach the end of the document */ + if (start && end) { + webkit_dom_dom_selection_set_base_and_extent ( + dialog->priv->selection, start, start_offset, + end, end_offset, NULL); + } + + /* Close the dialog */ + gtk_widget_hide (GTK_WIDGET (dialog)); + return FALSE; +} + +static gboolean +select_previous_word (EHTMLEditorSpellCheckDialog *dialog) +{ + WebKitDOMNode *old_anchor_node; + WebKitDOMNode *new_anchor_node; + gulong old_anchor_offset; + gulong new_anchor_offset; + + old_anchor_node = webkit_dom_dom_selection_get_anchor_node ( + dialog->priv->selection); + old_anchor_offset = webkit_dom_dom_selection_get_anchor_offset ( + dialog->priv->selection); + + /* Jump on the beginning of current word */ + webkit_dom_dom_selection_modify ( + dialog->priv->selection, "move", "backward", "word"); + /* Jump before previous word */ + webkit_dom_dom_selection_modify ( + dialog->priv->selection, "move", "backward", "word"); + /* Select it */ + webkit_dom_dom_selection_modify ( + dialog->priv->selection, "extend", "forward", "word"); + + /* If the selection start didn't change, then we have most probably + * reached the beginnig of document. Return FALSE */ + + new_anchor_node = webkit_dom_dom_selection_get_anchor_node ( + dialog->priv->selection); + new_anchor_offset = webkit_dom_dom_selection_get_anchor_offset ( + dialog->priv->selection); + + return (new_anchor_node != old_anchor_node) || + (new_anchor_offset != old_anchor_offset); +} + +static gboolean +html_editor_spell_check_dialog_prev (EHTMLEditorSpellCheckDialog *dialog) +{ + WebKitDOMNode *start = NULL, *end = NULL; + gulong start_offset, end_offset; + + if (dialog->priv->word == NULL) { + webkit_dom_dom_selection_modify ( + dialog->priv->selection, + "move", "right", "documentboundary"); + webkit_dom_dom_selection_modify ( + dialog->priv->selection, + "extend", "backward", "word"); + } else { + /* Remember last selected word */ + start = webkit_dom_dom_selection_get_anchor_node ( + dialog->priv->selection); + end = webkit_dom_dom_selection_get_focus_node ( + dialog->priv->selection); + start_offset = webkit_dom_dom_selection_get_anchor_offset ( + dialog->priv->selection); + end_offset = webkit_dom_dom_selection_get_focus_offset ( + dialog->priv->selection); + } + + while (select_previous_word (dialog)) { + WebKitDOMRange *range; + WebKitSpellChecker *checker; + gint loc, len; + gchar *word; + + range = webkit_dom_dom_selection_get_range_at ( + dialog->priv->selection, 0, NULL); + word = webkit_dom_range_get_text (range); + + checker = WEBKIT_SPELL_CHECKER (webkit_get_text_checker ()); + webkit_spell_checker_check_spelling_of_string ( + checker, word, &loc, &len); + + /* Found misspelled word! */ + if (loc != -1) { + html_editor_spell_check_dialog_set_word (dialog, word); + g_free (word); + return TRUE; + } + + g_free (word); + } + + /* Restore the selection to contain the last misspelled word. This is + * reached only when we reach the beginning of the document */ + if (start && end) { + webkit_dom_dom_selection_set_base_and_extent ( + dialog->priv->selection, start, start_offset, + end, end_offset, NULL); + } + + /* Close the dialog */ + gtk_widget_hide (GTK_WIDGET (dialog)); + return FALSE; +} + +static void +html_editor_spell_check_dialog_replace (EHTMLEditorSpellCheckDialog *dialog) +{ + EHTMLEditor *editor; + EHTMLEditorView *view; + EHTMLEditorSelection *editor_selection; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; + gchar *replacement; + + editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog)); + view = e_html_editor_get_view (editor); + editor_selection = e_html_editor_view_get_selection (view); + + selection = gtk_tree_view_get_selection ( + GTK_TREE_VIEW (dialog->priv->tree_view)); + gtk_tree_selection_get_selected (selection, &model, &iter); + gtk_tree_model_get (model, &iter, 0, &replacement, -1); + + e_html_editor_selection_insert_html ( + editor_selection, replacement); + + g_free (replacement); + html_editor_spell_check_dialog_next (dialog); +} + +static void +html_editor_spell_check_dialog_replace_all (EHTMLEditorSpellCheckDialog *dialog) +{ + EHTMLEditor *editor; + EHTMLEditorView *view; + EHTMLEditorSelection *editor_selection; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; + gchar *replacement; + + editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog)); + view = e_html_editor_get_view (editor); + editor_selection = e_html_editor_view_get_selection (view); + + selection = gtk_tree_view_get_selection ( + GTK_TREE_VIEW (dialog->priv->tree_view)); + gtk_tree_selection_get_selected (selection, &model, &iter); + gtk_tree_model_get (model, &iter, 0, &replacement, -1); + + /* Repeatedly search for 'word', then replace selection by + * 'replacement'. Repeat until there's at least one occurence of + * 'word' in the document */ + while (webkit_web_view_search_text ( + WEBKIT_WEB_VIEW (view), dialog->priv->word, + FALSE, TRUE, TRUE)) { + + e_html_editor_selection_insert_html ( + editor_selection, replacement); + } + + g_free (replacement); + html_editor_spell_check_dialog_next (dialog); +} + +static void +html_editor_spell_check_dialog_ignore (EHTMLEditorSpellCheckDialog *dialog) +{ + if (dialog->priv->word == NULL) + return; + + e_spell_dictionary_ignore_word ( + dialog->priv->current_dict, dialog->priv->word, -1); + + html_editor_spell_check_dialog_next (dialog); +} + +static void +html_editor_spell_check_dialog_learn (EHTMLEditorSpellCheckDialog *dialog) +{ + if (dialog->priv->word == NULL) + return; + + e_spell_dictionary_learn_word ( + dialog->priv->current_dict, dialog->priv->word, -1); + + html_editor_spell_check_dialog_next (dialog); +} + +static void +html_editor_spell_check_dialog_set_dictionary (EHTMLEditorSpellCheckDialog *dialog) +{ + GtkComboBox *combo_box; + GtkTreeModel *model; + GtkTreeIter iter; + ESpellDictionary *dictionary; + + combo_box = GTK_COMBO_BOX (dialog->priv->dictionary_combo); + gtk_combo_box_get_active_iter (combo_box, &iter); + model = gtk_combo_box_get_model (combo_box); + + gtk_tree_model_get (model, &iter, 1, &dictionary, -1); + + dialog->priv->current_dict = dictionary; + + /* Update suggestions */ + html_editor_spell_check_dialog_set_word (dialog, dialog->priv->word); +} + +static void +html_editor_spell_check_dialog_show (GtkWidget *widget) +{ + EHTMLEditor *editor; + EHTMLEditorView *view; + EHTMLEditorSpellCheckDialog *dialog; + WebKitDOMDocument *document; + WebKitDOMDOMWindow *window; + + dialog = E_HTML_EDITOR_SPELL_CHECK_DIALOG (widget); + + g_free (dialog->priv->word); + dialog->priv->word = NULL; + + editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog)); + view = e_html_editor_get_view (editor); + + document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)); + window = webkit_dom_document_get_default_view (document); + dialog->priv->selection = webkit_dom_dom_window_get_selection (window); + + /* Select the first word or quit */ + if (html_editor_spell_check_dialog_next (dialog)) { + GTK_WIDGET_CLASS (e_html_editor_spell_check_dialog_parent_class)-> + show (widget); + } +} + +static void +html_editor_spell_check_dialog_finalize (GObject *object) +{ + EHTMLEditorSpellCheckDialogPrivate *priv; + + priv = E_HTML_EDITOR_SPELL_CHECK_DIALOG_GET_PRIVATE (object); + + g_free (priv->word); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (e_html_editor_spell_check_dialog_parent_class)-> + finalize (object); +} + +static void +html_editor_spell_check_dialog_constructed (GObject *object) +{ + EHTMLEditorSpellCheckDialog *dialog; + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_html_editor_spell_check_dialog_parent_class)-> + constructed (object); + + dialog = E_HTML_EDITOR_SPELL_CHECK_DIALOG (object); + e_html_editor_spell_check_dialog_update_dictionaries (dialog); +} + +static void +e_html_editor_spell_check_dialog_class_init (EHTMLEditorSpellCheckDialogClass *class) +{ + GtkWidgetClass *widget_class; + GObjectClass *object_class; + + g_type_class_add_private ( + class, sizeof (EHTMLEditorSpellCheckDialogPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->finalize = html_editor_spell_check_dialog_finalize; + object_class->constructed = html_editor_spell_check_dialog_constructed; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->show = html_editor_spell_check_dialog_show; +} + +static void +e_html_editor_spell_check_dialog_init (EHTMLEditorSpellCheckDialog *dialog) +{ + GtkWidget *widget; + GtkGrid *main_layout; + GtkListStore *store; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + + dialog->priv = E_HTML_EDITOR_SPELL_CHECK_DIALOG_GET_PRIVATE (dialog); + + main_layout = e_html_editor_dialog_get_container (E_HTML_EDITOR_DIALOG (dialog)); + + /* == Suggestions == */ + widget = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL (widget), _("<b>Suggestions</b>")); + gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5); + gtk_grid_attach (main_layout, widget, 0, 0, 2, 1); + dialog->priv->suggestion_label = widget; + + /* Tree view */ + widget = gtk_tree_view_new (); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (widget), FALSE); + gtk_widget_set_vexpand (widget, TRUE); + gtk_widget_set_hexpand (widget, TRUE); + dialog->priv->tree_view = widget; + + /* Column */ + column = gtk_tree_view_column_new_with_attributes ( + "", gtk_cell_renderer_text_new (), "text", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (widget), column); + + /* Store */ + store = gtk_list_store_new (1, G_TYPE_STRING); + gtk_tree_view_set_model ( + GTK_TREE_VIEW (widget), GTK_TREE_MODEL (store)); + + /* Scrolled Window */ + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_set_size_request (widget, 150, -1); + 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_ETCHED_IN); + gtk_container_add (GTK_CONTAINER (widget), dialog->priv->tree_view); + gtk_grid_attach (main_layout, widget, 0, 1, 1, 5); + + /* Replace */ + widget = gtk_button_new_with_mnemonic (_("Replace")); + gtk_button_set_image ( + GTK_BUTTON (widget), + gtk_image_new_from_stock ( + GTK_STOCK_CONVERT, GTK_ICON_SIZE_BUTTON)); + gtk_grid_attach (main_layout, widget, 1, 1, 1, 1); + dialog->priv->replace_button = widget; + + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (html_editor_spell_check_dialog_replace), dialog); + + /* Replace All */ + widget = gtk_button_new_with_mnemonic (_("Replace All")); + gtk_button_set_image ( + GTK_BUTTON (widget), + gtk_image_new_from_stock ( + GTK_STOCK_APPLY, GTK_ICON_SIZE_BUTTON)); + gtk_grid_attach (main_layout, widget, 1, 2, 1, 1); + dialog->priv->replace_all_button = widget; + + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (html_editor_spell_check_dialog_replace_all), dialog); + + /* Ignore */ + widget = gtk_button_new_with_mnemonic (_("Ignore")); + gtk_button_set_image ( + GTK_BUTTON (widget), + gtk_image_new_from_stock ( + GTK_STOCK_CLEAR, GTK_ICON_SIZE_BUTTON)); + gtk_grid_attach (main_layout, widget, 1, 3, 1, 1); + dialog->priv->ignore_button = widget; + + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (html_editor_spell_check_dialog_ignore), dialog); + + /* Skip */ + widget = gtk_button_new_with_mnemonic (_("Skip")); + gtk_button_set_image ( + GTK_BUTTON (widget), + gtk_image_new_from_stock ( + GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_BUTTON)); + gtk_grid_attach (main_layout, widget, 1, 4, 1, 1); + dialog->priv->skip_button = widget; + + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (html_editor_spell_check_dialog_next), dialog); + + /* Back */ + widget = gtk_button_new_with_mnemonic (_("Back")); + gtk_button_set_image ( + GTK_BUTTON (widget), + gtk_image_new_from_stock ( + GTK_STOCK_GO_BACK, GTK_ICON_SIZE_BUTTON)); + gtk_grid_attach (main_layout, widget, 1, 5, 1, 1); + + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (html_editor_spell_check_dialog_prev), dialog); + + /* Dictionary label */ + widget = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL (widget), _("<b>Dictionary</b>")); + gtk_misc_set_alignment (GTK_MISC (widget), 0, 0); + gtk_grid_attach (main_layout, widget, 0, 6, 2, 1); + + /* Dictionaries combo */ + widget = gtk_combo_box_new (); + gtk_grid_attach (main_layout, widget, 0, 7, 1, 1); + dialog->priv->dictionary_combo = widget; + + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start ( + GTK_CELL_LAYOUT (widget), renderer, TRUE); + gtk_cell_layout_add_attribute ( + GTK_CELL_LAYOUT (widget), renderer, "text", 0); + + g_signal_connect_swapped ( + widget, "changed", + G_CALLBACK (html_editor_spell_check_dialog_set_dictionary), dialog); + + /* Add Word button */ + widget = gtk_button_new_with_mnemonic (_("Add Word")); + gtk_button_set_image ( + GTK_BUTTON (widget), + gtk_image_new_from_stock ( + GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON)); + gtk_grid_attach (main_layout, widget, 1, 7, 1, 1); + dialog->priv->add_word_button = widget; + + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (html_editor_spell_check_dialog_learn), dialog); + + gtk_widget_show_all (GTK_WIDGET (main_layout)); +} + +GtkWidget * +e_html_editor_spell_check_dialog_new (EHTMLEditor *editor) +{ + return g_object_new ( + E_TYPE_HTML_EDITOR_SPELL_CHECK_DIALOG, + "editor", editor, + "title", N_("Spell Checking"), + NULL); +} + +void +e_html_editor_spell_check_dialog_update_dictionaries (EHTMLEditorSpellCheckDialog *dialog) +{ + EHTMLEditor *editor; + EHTMLEditorView *view; + ESpellChecker *spell_checker; + GtkComboBox *combo_box; + GtkListStore *store; + GQueue queue = G_QUEUE_INIT; + gchar **languages; + guint n_languages = 0; + guint ii; + + g_return_if_fail (E_IS_HTML_EDITOR_SPELL_CHECK_DIALOG (dialog)); + + editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog)); + view = e_html_editor_get_view (editor); + spell_checker = e_html_editor_view_get_spell_checker (view); + + languages = e_spell_checker_list_active_languages ( + spell_checker, &n_languages); + for (ii = 0; ii < n_languages; ii++) { + ESpellDictionary *dictionary; + + dictionary = e_spell_checker_ref_dictionary ( + spell_checker, languages[ii]); + if (dictionary != NULL) + g_queue_push_tail (&queue, dictionary); + else + g_warning ( + "%s: No '%s' dictionary found", + G_STRFUNC, languages[ii]); + } + g_strfreev (languages); + + /* Populate a list store for the combo box. */ + store = gtk_list_store_new ( + NUM_COLUMNS, + G_TYPE_STRING, /* COLUMN_NAME */ + E_TYPE_SPELL_DICTIONARY); /* COLUMN_DICTIONARY */ + + while (!g_queue_is_empty (&queue)) { + ESpellDictionary *dictionary; + GtkTreeIter iter; + const gchar *name; + + dictionary = g_queue_pop_head (&queue); + name = e_spell_dictionary_get_name (dictionary); + + gtk_list_store_append (store, &iter); + gtk_list_store_set ( + store, &iter, + COLUMN_NAME, name, + COLUMN_DICTIONARY, dictionary, + -1); + + g_object_unref (dictionary); + } + + /* FIXME Try to restore selection. */ + combo_box = GTK_COMBO_BOX (dialog->priv->dictionary_combo); + gtk_combo_box_set_model (combo_box, GTK_TREE_MODEL (store)); + gtk_combo_box_set_active (combo_box, 0); + + g_object_unref (store); +} + |