diff options
Diffstat (limited to 'widgets/misc/e-spell-entry.c')
-rw-r--r-- | widgets/misc/e-spell-entry.c | 866 |
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"); - -} |