aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/misc/e-spell-entry.c
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/misc/e-spell-entry.c')
-rw-r--r--widgets/misc/e-spell-entry.c866
1 files changed, 0 insertions, 866 deletions
diff --git a/widgets/misc/e-spell-entry.c b/widgets/misc/e-spell-entry.c
deleted file mode 100644
index 56f7c14f8c..0000000000
--- a/widgets/misc/e-spell-entry.c
+++ /dev/null
@@ -1,866 +0,0 @@
-/*
- * e-spell-entry.c
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- */
-
-/* This code is based on libsexy's SexySpellEntry */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib/gi18n-lib.h>
-#include <gtk/gtk.h>
-
-#include <editor/gtkhtml-spell-language.h>
-#include <editor/gtkhtml-spell-checker.h>
-
-#include "e-spell-entry.h"
-
-enum {
- PROP_0,
- PROP_CHECKING_ENABLED
-};
-
-struct _ESpellEntryPrivate
-{
- PangoAttrList *attr_list;
- gint mark_character;
- gint entry_scroll_offset;
- GSettings *settings;
- gboolean custom_checkers;
- gboolean checking_enabled;
- GSList *checkers;
- gchar **words;
- gint *word_starts;
- gint *word_ends;
-};
-
-#define E_SPELL_ENTRY_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_SPELL_ENTRY, ESpellEntryPrivate))
-
-G_DEFINE_TYPE (ESpellEntry, e_spell_entry, GTK_TYPE_ENTRY);
-
-static gboolean
-word_misspelled (ESpellEntry *entry,
- gint start,
- gint end)
-{
- const gchar *text;
- gchar *word;
- gboolean result = TRUE;
-
- if (start == end)
- return FALSE;
-
- text = gtk_entry_get_text (GTK_ENTRY (entry));
- word = g_new0 (gchar, end - start + 2);
-
- g_strlcpy (word, text + start, end - start + 1);
-
- if (g_unichar_isalpha (*word)) {
- GSList *li;
- gssize wlen = strlen (word);
-
- for (li = entry->priv->checkers; li; li = g_slist_next (li)) {
- GtkhtmlSpellChecker *checker = li->data;
- if (gtkhtml_spell_checker_check_word (checker, word, wlen)) {
- result = FALSE;
- break;
- }
- }
- }
- g_free (word);
-
- return result;
-}
-
-static void
-insert_underline (ESpellEntry *entry,
- guint start,
- guint end)
-{
- PangoAttribute *ucolor = pango_attr_underline_color_new (65535, 0, 0);
- PangoAttribute *unline = pango_attr_underline_new (PANGO_UNDERLINE_ERROR);
-
- ucolor->start_index = start;
- unline->start_index = start;
-
- ucolor->end_index = end;
- unline->end_index = end;
-
- pango_attr_list_insert (entry->priv->attr_list, ucolor);
- pango_attr_list_insert (entry->priv->attr_list, unline);
-}
-
-static void
-check_word (ESpellEntry *entry,
- gint start,
- gint end)
-{
- PangoAttrIterator *it;
-
- /* Check to see if we've got any attributes at this position.
- * If so, free them, since we'll readd it if the word is misspelled */
- it = pango_attr_list_get_iterator (entry->priv->attr_list);
-
- if (it == NULL)
- return;
- do {
- gint s, e;
- pango_attr_iterator_range (it, &s, &e);
- if (s == start) {
- GSList *attrs = pango_attr_iterator_get_attrs (it);
- g_slist_foreach (attrs, (GFunc) pango_attribute_destroy, NULL);
- g_slist_free (attrs);
- }
- } while (pango_attr_iterator_next (it));
- pango_attr_iterator_destroy (it);
-
- if (word_misspelled (entry, start, end))
- insert_underline (entry, start, end);
-}
-
-static void
-spell_entry_recheck_all (ESpellEntry *entry)
-{
- GtkWidget *widget = GTK_WIDGET (entry);
- PangoLayout *layout;
- gint length, i;
-
- if (!entry->priv->words)
- return;
-
- /* Remove all existing pango attributes. These will get read as we check */
- pango_attr_list_unref (entry->priv->attr_list);
- entry->priv->attr_list = pango_attr_list_new ();
-
- if (entry->priv->checkers && entry->priv->checking_enabled) {
- /* Loop through words */
- for (i = 0; entry->priv->words[i]; i++) {
- length = strlen (entry->priv->words[i]);
- if (length == 0)
- continue;
- check_word (entry, entry->priv->word_starts[i], entry->priv->word_ends[i]);
- }
-
- layout = gtk_entry_get_layout (GTK_ENTRY (entry));
- pango_layout_set_attributes (layout, entry->priv->attr_list);
- }
-
- if (gtk_widget_get_realized (widget))
- gtk_widget_queue_draw (widget);
-}
-
-static void
-get_word_extents_from_position (ESpellEntry *entry,
- gint *start,
- gint *end,
- guint position)
-{
- const gchar *text;
- gint i, bytes_pos;
-
- *start = -1;
- *end = -1;
-
- if (entry->priv->words == NULL)
- return;
-
- text = gtk_entry_get_text (GTK_ENTRY (entry));
- bytes_pos = (gint) (g_utf8_offset_to_pointer (text, position) - text);
-
- for (i = 0; entry->priv->words[i]; i++) {
- if (bytes_pos >= entry->priv->word_starts[i] &&
- bytes_pos <= entry->priv->word_ends[i]) {
- *start = entry->priv->word_starts[i];
- *end = entry->priv->word_ends[i];
- return;
- }
- }
-}
-
-static void
-entry_strsplit_utf8 (GtkEntry *entry,
- gchar ***set,
- gint **starts,
- gint **ends)
-{
- PangoLayout *layout;
- PangoLogAttr *log_attrs;
- const gchar *text;
- gint n_attrs, n_strings, i, j;
-
- layout = gtk_entry_get_layout (GTK_ENTRY (entry));
- text = gtk_entry_get_text (GTK_ENTRY (entry));
- pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
-
- /* Find how many words we have */
- n_strings = 0;
- for (i = 0; i < n_attrs; i++)
- if (log_attrs[i].is_word_start)
- n_strings++;
-
- *set = g_new0 (gchar *, n_strings + 1);
- *starts = g_new0 (gint, n_strings);
- *ends = g_new0 (gint, n_strings);
-
- /* Copy out strings */
- for (i = 0, j = 0; i < n_attrs; i++) {
- if (log_attrs[i].is_word_start) {
- gint cend, bytes;
- gchar *start;
-
- /* Find the end of this string */
- cend = i;
- while (!(log_attrs[cend].is_word_end))
- cend++;
-
- /* Copy sub-string */
- start = g_utf8_offset_to_pointer (text, i);
- bytes = (gint) (g_utf8_offset_to_pointer (text, cend) - start);
- (*set)[j] = g_new0 (gchar, bytes + 1);
- (*starts)[j] = (gint) (start - text);
- (*ends)[j] = (gint) (start - text + bytes);
- g_utf8_strncpy ((*set)[j], start, cend - i);
-
- /* Move on to the next word */
- j++;
- }
- }
-
- g_free (log_attrs);
-}
-
-static void
-add_to_dictionary (GtkWidget *menuitem,
- ESpellEntry *entry)
-{
- gchar *word;
- gint start, end;
- GtkhtmlSpellChecker *checker;
-
- get_word_extents_from_position (entry, &start, &end, entry->priv->mark_character);
- word = gtk_editable_get_chars (GTK_EDITABLE (entry), start, end);
-
- checker = g_object_get_data (G_OBJECT (menuitem), "spell-entry-checker");
- if (checker)
- gtkhtml_spell_checker_add_word (checker, word, -1);
-
- g_free (word);
-
- if (entry->priv->words) {
- g_strfreev (entry->priv->words);
- g_free (entry->priv->word_starts);
- g_free (entry->priv->word_ends);
- }
-
- entry_strsplit_utf8 (GTK_ENTRY (entry), &entry->priv->words, &entry->priv->word_starts, &entry->priv->word_ends);
- spell_entry_recheck_all (entry);
-}
-
-static void
-ignore_all (GtkWidget *menuitem,
- ESpellEntry *entry)
-{
- gchar *word;
- gint start, end;
- GSList *li;
-
- get_word_extents_from_position (entry, &start, &end, entry->priv->mark_character);
- word = gtk_editable_get_chars (GTK_EDITABLE (entry), start, end);
-
- for (li = entry->priv->checkers; li; li = g_slist_next (li)) {
- GtkhtmlSpellChecker *checker = li->data;
- gtkhtml_spell_checker_add_word_to_session (checker, word, -1);
- }
-
- g_free (word);
-
- if (entry->priv->words) {
- g_strfreev (entry->priv->words);
- g_free (entry->priv->word_starts);
- g_free (entry->priv->word_ends);
- }
- entry_strsplit_utf8 (GTK_ENTRY (entry), &entry->priv->words, &entry->priv->word_starts, &entry->priv->word_ends);
- spell_entry_recheck_all (entry);
-}
-
-static void
-replace_word (GtkWidget *menuitem,
- ESpellEntry *entry)
-{
- gchar *oldword;
- const gchar *newword;
- gint start, end;
- gint cursor;
- GtkhtmlSpellChecker *checker;
-
- get_word_extents_from_position (entry, &start, &end, entry->priv->mark_character);
- oldword = gtk_editable_get_chars (GTK_EDITABLE (entry), start, end);
- newword = gtk_label_get_text (GTK_LABEL (gtk_bin_get_child (GTK_BIN (menuitem))));
-
- cursor = gtk_editable_get_position (GTK_EDITABLE (entry));
- /* is the cursor at the end? If so, restore it there */
- if (g_utf8_strlen (gtk_entry_get_text (GTK_ENTRY (entry)), -1) == cursor)
- cursor = -1;
- else if (cursor > start && cursor <= end)
- cursor = start;
-
- gtk_editable_delete_text (GTK_EDITABLE (entry), start, end);
- gtk_editable_set_position (GTK_EDITABLE (entry), start);
- gtk_editable_insert_text (
- GTK_EDITABLE (entry), newword, strlen (newword),
- &start);
- gtk_editable_set_position (GTK_EDITABLE (entry), cursor);
-
- checker = g_object_get_data (G_OBJECT (menuitem), "spell-entry-checker");
-
- if (checker)
- gtkhtml_spell_checker_store_replacement (checker, oldword, -1, newword, -1);
-
- g_free (oldword);
-}
-
-static void
-build_suggestion_menu (ESpellEntry *entry,
- GtkWidget *menu,
- GtkhtmlSpellChecker *checker,
- const gchar *word)
-{
- GtkWidget *mi;
- GList *suggestions, *iter;
-
- suggestions = gtkhtml_spell_checker_get_suggestions (checker, word, -1);
-
- if (!suggestions) {
- /* no suggestions. Put something in the menu anyway... */
- GtkWidget *label = gtk_label_new (_("(no suggestions)"));
- PangoAttribute *attribute;
- PangoAttrList *attribute_list;
-
- attribute_list = pango_attr_list_new ();
- attribute = pango_attr_style_new (PANGO_STYLE_ITALIC);
- pango_attr_list_insert (attribute_list, attribute);
- gtk_label_set_attributes (GTK_LABEL (label), attribute_list);
- pango_attr_list_unref (attribute_list);
-
- mi = gtk_separator_menu_item_new ();
- gtk_container_add (GTK_CONTAINER (mi), label);
- gtk_widget_show_all (mi);
- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi);
- } else {
- gint ii = 0;
-
- /* build a set of menus with suggestions */
- for (iter = suggestions; iter; iter = g_list_next (iter), ii++) {
- if ((ii != 0) && (ii % 10 == 0)) {
- mi = gtk_separator_menu_item_new ();
- gtk_widget_show (mi);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
-
- mi = gtk_menu_item_new_with_label (_("More..."));
- gtk_widget_show (mi);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
-
- menu = gtk_menu_new ();
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), menu);
- }
-
- mi = gtk_menu_item_new_with_label (iter->data);
- g_object_set_data (G_OBJECT (mi), "spell-entry-checker", checker);
- g_signal_connect (mi, "activate", G_CALLBACK (replace_word), entry);
- gtk_widget_show (mi);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
- }
- }
-
- g_list_free_full (suggestions, g_free);
-}
-
-static GtkWidget *
-build_spelling_menu (ESpellEntry *entry,
- const gchar *word)
-{
- GtkhtmlSpellChecker *checker;
- GtkWidget *topmenu, *mi;
- gchar *label;
-
- topmenu = gtk_menu_new ();
-
- if (!entry->priv->checkers)
- return topmenu;
-
- /* Suggestions */
- if (!entry->priv->checkers->next) {
- checker = entry->priv->checkers->data;
- build_suggestion_menu (entry, topmenu, checker, word);
- } else {
- GSList *li;
- GtkWidget *menu;
- const gchar *lang_name;
-
- for (li = entry->priv->checkers; li; li = g_slist_next (li)) {
- const GtkhtmlSpellLanguage *language;
-
- checker = li->data;
- language = gtkhtml_spell_checker_get_language (checker);
- if (!language)
- continue;
-
- lang_name = gtkhtml_spell_language_get_name (language);
- if (!lang_name)
- lang_name = gtkhtml_spell_language_get_code (language);
-
- mi = gtk_menu_item_new_with_label (lang_name ? lang_name : "???");
-
- gtk_widget_show (mi);
- gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi);
- menu = gtk_menu_new ();
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), menu);
- build_suggestion_menu (entry, menu, checker, word);
- }
- }
-
- /* Separator */
- mi = gtk_separator_menu_item_new ();
- gtk_widget_show (mi);
- gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi);
-
- /* + Add to Dictionary */
- label = g_strdup_printf (_("Add \"%s\" to Dictionary"), word);
- mi = gtk_image_menu_item_new_with_label (label);
- g_free (label);
-
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU));
-
- if (!entry->priv->checkers->next) {
- checker = entry->priv->checkers->data;
- g_object_set_data (G_OBJECT (mi), "spell-entry-checker", checker);
- g_signal_connect (mi, "activate", G_CALLBACK (add_to_dictionary), entry);
- } else {
- GSList *li;
- GtkWidget *menu, *submi;
- const gchar *lang_name;
-
- menu = gtk_menu_new ();
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), menu);
-
- for (li = entry->priv->checkers; li; li = g_slist_next (li)) {
- const GtkhtmlSpellLanguage *language;
-
- checker = li->data;
- language = gtkhtml_spell_checker_get_language (checker);
- if (!language)
- continue;
-
- lang_name = gtkhtml_spell_language_get_name (language);
- if (!lang_name)
- lang_name = gtkhtml_spell_language_get_code (language);
-
- submi = gtk_menu_item_new_with_label (lang_name ? lang_name : "???");
- g_object_set_data (G_OBJECT (submi), "spell-entry-checker", checker);
- g_signal_connect (submi, "activate", G_CALLBACK (add_to_dictionary), entry);
-
- gtk_widget_show (submi);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), submi);
- }
- }
-
- gtk_widget_show_all (mi);
- gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi);
-
- /* - Ignore All */
- mi = gtk_image_menu_item_new_with_label (_("Ignore All"));
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU));
- g_signal_connect (mi, "activate", G_CALLBACK (ignore_all), entry);
- gtk_widget_show_all (mi);
- gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi);
-
- return topmenu;
-}
-
-static void
-spell_entry_add_suggestions_menu (ESpellEntry *entry,
- GtkMenu *menu,
- const gchar *word)
-{
- GtkWidget *icon, *mi;
-
- g_return_if_fail (menu != NULL);
- g_return_if_fail (word != NULL);
-
- /* separator */
- mi = gtk_separator_menu_item_new ();
- gtk_widget_show (mi);
- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi);
-
- /* Above the separator, show the suggestions menu */
- icon = gtk_image_new_from_stock (GTK_STOCK_SPELL_CHECK, GTK_ICON_SIZE_MENU);
- mi = gtk_image_menu_item_new_with_label (_("Spelling Suggestions"));
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), icon);
-
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), build_spelling_menu (entry, word));
-
- gtk_widget_show_all (mi);
- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi);
-}
-
-static gboolean
-spell_entry_popup_menu (ESpellEntry *entry)
-{
- /* Menu popped up from a keybinding (menu key or <shift>+F10). Use
- * the cursor position as the mark position */
- entry->priv->mark_character = gtk_editable_get_position (GTK_EDITABLE (entry));
-
- return FALSE;
-}
-
-static void
-spell_entry_populate_popup (ESpellEntry *entry,
- GtkMenu *menu,
- gpointer data)
-{
- gint start, end;
- gchar *word;
-
- if (!entry->priv->checkers)
- return;
-
- get_word_extents_from_position (entry, &start, &end, entry->priv->mark_character);
- if (start == end)
- return;
-
- if (!word_misspelled (entry, start, end))
- return;
-
- word = gtk_editable_get_chars (GTK_EDITABLE (entry), start, end);
- g_return_if_fail (word != NULL);
-
- spell_entry_add_suggestions_menu (entry, menu, word);
-
- g_free (word);
-}
-
-static void
-spell_entry_changed (GtkEditable *editable)
-{
- ESpellEntry *entry = E_SPELL_ENTRY (editable);
-
- if (!entry->priv->checkers)
- return;
-
- if (entry->priv->words) {
- g_strfreev (entry->priv->words);
- g_free (entry->priv->word_starts);
- g_free (entry->priv->word_ends);
- }
- entry_strsplit_utf8 (GTK_ENTRY (entry), &entry->priv->words, &entry->priv->word_starts, &entry->priv->word_ends);
- spell_entry_recheck_all (entry);
-}
-
-static void
-spell_entry_notify_scroll_offset (ESpellEntry *spell_entry)
-{
- g_return_if_fail (spell_entry != NULL);
-
- g_object_get (G_OBJECT (spell_entry), "scroll-offset", &spell_entry->priv->entry_scroll_offset, NULL);
-}
-
-static GList *
-spell_entry_load_spell_languages (void)
-{
- GSettings *settings;
- GList *spell_languages = NULL;
- gchar **strv;
- gint ii;
-
- /* Ask GSettings for a list of spell check language codes. */
- settings = g_settings_new ("org.gnome.evolution.mail");
- strv = g_settings_get_strv (settings, "composer-spell-languages");
- g_object_unref (settings);
-
- /* Convert the codes to spell language structs. */
- for (ii = 0; strv[ii] != NULL; ii++) {
- gchar *language_code = strv[ii];
- const GtkhtmlSpellLanguage *language;
-
- language = gtkhtml_spell_language_lookup (language_code);
- if (language != NULL)
- spell_languages = g_list_prepend (
- spell_languages, (gpointer) language);
- }
-
- g_strfreev (strv);
-
- spell_languages = g_list_reverse (spell_languages);
-
- /* Pick a default spell language if it came back empty. */
- if (spell_languages == NULL) {
- const GtkhtmlSpellLanguage *language;
-
- language = gtkhtml_spell_language_lookup (NULL);
-
- if (language) {
- spell_languages = g_list_prepend (
- spell_languages, (gpointer) language);
- }
- }
-
- return spell_languages;
-}
-
-static void
-spell_entry_settings_changed (ESpellEntry *spell_entry,
- const gchar *key)
-{
- GList *languages;
-
- g_return_if_fail (spell_entry != NULL);
-
- if (spell_entry->priv->custom_checkers)
- return;
-
- if (key && !g_str_equal (key, "composer-spell-languages"))
- return;
-
- languages = spell_entry_load_spell_languages ();
- e_spell_entry_set_languages (spell_entry, languages);
- g_list_free (languages);
-
- spell_entry->priv->custom_checkers = FALSE;
-}
-
-static gint
-spell_entry_find_position (ESpellEntry *spell_entry,
- gint x)
-{
- PangoLayout *layout;
- PangoLayoutLine *line;
- gint index;
- gint pos;
- gint trailing;
- const gchar *text;
- GtkEntry *entry = GTK_ENTRY (spell_entry);
-
- layout = gtk_entry_get_layout (entry);
- text = pango_layout_get_text (layout);
-
- line = pango_layout_get_lines_readonly (layout)->data;
- pango_layout_line_x_to_index (line, x * PANGO_SCALE, &index, &trailing);
-
- pos = g_utf8_pointer_to_offset (text, text + index);
- pos += trailing;
-
- return pos;
-}
-
-static gboolean
-e_spell_entry_draw (GtkWidget *widget,
- cairo_t *cr)
-{
- ESpellEntry *spell_entry = E_SPELL_ENTRY (widget);
- GtkEntry *entry = GTK_ENTRY (widget);
- PangoLayout *layout;
-
- layout = gtk_entry_get_layout (entry);
- pango_layout_set_attributes (layout, spell_entry->priv->attr_list);
-
- return GTK_WIDGET_CLASS (e_spell_entry_parent_class)->draw (widget, cr);
-}
-
-static gboolean
-e_spell_entry_button_press (GtkWidget *widget,
- GdkEventButton *event)
-{
- ESpellEntry *spell_entry = E_SPELL_ENTRY (widget);
-
- spell_entry->priv->mark_character = spell_entry_find_position (
- spell_entry, event->x + spell_entry->priv->entry_scroll_offset);
-
- return GTK_WIDGET_CLASS (e_spell_entry_parent_class)->button_press_event (widget, event);
-}
-
-static void
-spell_entry_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_CHECKING_ENABLED:
- e_spell_entry_set_checking_enabled (
- E_SPELL_ENTRY (object),
- g_value_get_boolean (value));
- return;
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-spell_entry_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_CHECKING_ENABLED:
- g_value_set_boolean (
- value,
- e_spell_entry_get_checking_enabled (
- E_SPELL_ENTRY (object)));
- return;
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-e_spell_entry_init (ESpellEntry *spell_entry)
-{
- spell_entry->priv = E_SPELL_ENTRY_GET_PRIVATE (spell_entry);
- spell_entry->priv->attr_list = pango_attr_list_new ();
- spell_entry->priv->checkers = NULL;
- spell_entry->priv->checking_enabled = TRUE;
-
- g_signal_connect (spell_entry, "popup-menu", G_CALLBACK (spell_entry_popup_menu), NULL);
- g_signal_connect (spell_entry, "populate-popup", G_CALLBACK (spell_entry_populate_popup), NULL);
- g_signal_connect (spell_entry, "changed", G_CALLBACK (spell_entry_changed), NULL);
- g_signal_connect (spell_entry, "notify::scroll-offset", G_CALLBACK (spell_entry_notify_scroll_offset), NULL);
-
- /* listen for languages changes */
- spell_entry->priv->settings = g_settings_new ("org.gnome.evolution.mail");
- g_signal_connect_swapped (spell_entry->priv->settings, "changed", G_CALLBACK (spell_entry_settings_changed), spell_entry);
-
- /* load current settings */
- spell_entry_settings_changed (spell_entry, NULL);
-}
-
-static void
-e_spell_entry_finalize (GObject *object)
-{
- ESpellEntry *entry;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (E_IS_SPELL_ENTRY (object));
-
- entry = E_SPELL_ENTRY (object);
-
- if (entry->priv->settings)
- g_object_unref (entry->priv->settings);
- if (entry->priv->checkers)
- g_slist_free_full (entry->priv->checkers, g_object_unref);
- if (entry->priv->attr_list)
- pango_attr_list_unref (entry->priv->attr_list);
- if (entry->priv->words)
- g_strfreev (entry->priv->words);
- if (entry->priv->word_starts)
- g_free (entry->priv->word_starts);
- if (entry->priv->word_ends)
- g_free (entry->priv->word_ends);
-
- G_OBJECT_CLASS (e_spell_entry_parent_class)->finalize (object);
-}
-
-static void
-e_spell_entry_class_init (ESpellEntryClass *class)
-{
- GObjectClass *object_class;
- GtkWidgetClass *widget_class;
-
- g_type_class_add_private (class, sizeof (ESpellEntryPrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->set_property = spell_entry_set_property;
- object_class->get_property = spell_entry_get_property;
- object_class->finalize = e_spell_entry_finalize;
-
- widget_class = GTK_WIDGET_CLASS (class);
- widget_class->draw = e_spell_entry_draw;
- widget_class->button_press_event = e_spell_entry_button_press;
-
- g_object_class_install_property (
- object_class,
- PROP_CHECKING_ENABLED,
- g_param_spec_boolean (
- "checking-enabled",
- "checking enabled",
- "Spell Checking is Enabled",
- TRUE,
- G_PARAM_READWRITE));
-}
-
-GtkWidget *
-e_spell_entry_new (void)
-{
- return g_object_new (E_TYPE_SPELL_ENTRY, NULL);
-}
-
-/* 'languages' consists of 'const GtkhtmlSpellLanguage *' */
-void
-e_spell_entry_set_languages (ESpellEntry *spell_entry,
- GList *languages)
-{
- GList *iter;
-
- g_return_if_fail (spell_entry != NULL);
-
- spell_entry->priv->custom_checkers = TRUE;
-
- if (spell_entry->priv->checkers)
- g_slist_free_full (spell_entry->priv->checkers, g_object_unref);
- spell_entry->priv->checkers = NULL;
-
- for (iter = languages; iter; iter = g_list_next (iter)) {
- const GtkhtmlSpellLanguage *language = iter->data;
-
- if (language)
- spell_entry->priv->checkers = g_slist_prepend (
- spell_entry->priv->checkers,
- gtkhtml_spell_checker_new (language));
- }
-
- spell_entry->priv->checkers = g_slist_reverse (spell_entry->priv->checkers);
-
- if (gtk_widget_get_realized (GTK_WIDGET (spell_entry)))
- spell_entry_recheck_all (spell_entry);
-}
-
-gboolean
-e_spell_entry_get_checking_enabled (ESpellEntry *spell_entry)
-{
- g_return_val_if_fail (spell_entry != NULL, FALSE);
-
- return spell_entry->priv->checking_enabled;
-}
-
-void
-e_spell_entry_set_checking_enabled (ESpellEntry *spell_entry,
- gboolean enable_checking)
-{
- g_return_if_fail (spell_entry != NULL);
-
- if (spell_entry->priv->checking_enabled == enable_checking)
- return;
-
- spell_entry->priv->checking_enabled = enable_checking;
- spell_entry_recheck_all (spell_entry);
-
- g_object_notify (G_OBJECT (spell_entry), "checking-enabled");
-
-}