From bd32e81f1393b901781b654070606a81e5cb0fed Mon Sep 17 00:00:00 2001 From: JosephMcc Date: Thu, 8 Feb 2018 23:26:23 -0800 Subject: [PATCH] spell-plugin: Port to gspell --- configure.ac | 46 +- debian/control | 3 +- plugins/Makefile.am | 2 +- plugins/spell/Makefile.am | 18 +- plugins/spell/languages-dialog.ui | 140 --- plugins/spell/spell-checker.ui | 369 ------ plugins/spell/xed-automatic-spell-checker.c | 967 --------------- plugins/spell/xed-automatic-spell-checker.h | 67 - plugins/spell/xed-spell-checker-dialog.c | 726 ----------- plugins/spell/xed-spell-checker-dialog.h | 92 -- plugins/spell/xed-spell-checker-language.c | 439 ------- plugins/spell/xed-spell-checker-language.h | 51 - plugins/spell/xed-spell-checker.c | 564 --------- plugins/spell/xed-spell-checker.h | 109 -- plugins/spell/xed-spell-language-dialog.c | 284 ----- plugins/spell/xed-spell-language-dialog.h | 65 - plugins/spell/xed-spell-plugin.c | 1216 ++++++------------- plugins/spell/xed-spell-utils.c | 94 -- plugins/spell/xed-spell-utils.h | 37 - 19 files changed, 365 insertions(+), 4924 deletions(-) delete mode 100644 plugins/spell/languages-dialog.ui delete mode 100644 plugins/spell/spell-checker.ui delete mode 100644 plugins/spell/xed-automatic-spell-checker.c delete mode 100644 plugins/spell/xed-automatic-spell-checker.h delete mode 100644 plugins/spell/xed-spell-checker-dialog.c delete mode 100644 plugins/spell/xed-spell-checker-dialog.h delete mode 100644 plugins/spell/xed-spell-checker-language.c delete mode 100644 plugins/spell/xed-spell-checker-language.h delete mode 100644 plugins/spell/xed-spell-checker.c delete mode 100644 plugins/spell/xed-spell-checker.h delete mode 100644 plugins/spell/xed-spell-language-dialog.c delete mode 100644 plugins/spell/xed-spell-language-dialog.h delete mode 100644 plugins/spell/xed-spell-utils.c delete mode 100644 plugins/spell/xed-spell-utils.h diff --git a/configure.ac b/configure.ac index e282b07..ee138fc 100644 --- a/configure.ac +++ b/configure.ac @@ -94,49 +94,25 @@ dnl ================================================================ dnl spell plugins checks: enchant and iso-codes dnl ================================================================ -ENCHANT_REQUIRED=1.6.0 -ISO_CODES_REQUIRED=0.35 +GSPELL_REQUIRED=0.2.5 AC_ARG_ENABLE([spell], AS_HELP_STRING([--disable-spell],[Disable spell plugin (default: enabled)]), - [enable_enchant=$enableval], - [enable_enchant=yes]) + [enable_spell=$enableval], + [enable_spell=yes]) -if test "x$enable_enchant" = "xyes" ; then +if test "x$enable_spell" = "xyes" ; then - PKG_CHECK_MODULES(ENCHANT, enchant >= $ENCHANT_REQUIRED, \ - have_enchant=yes, have_enchant=no) + PKG_CHECK_MODULES(GSPELL, gspell-1 >= $GSPELL_REQUIRED, \ + have_gspell=yes, have_gspell=no) - if test "x$have_enchant" = "xyes"; then - - PKG_CHECK_EXISTS([iso-codes >= $ISO_CODES_REQUIRED], - [have_iso_codes=yes],[have_iso_codes=no]) - - if test "x$have_iso_codes" = "xyes"; then - AC_MSG_CHECKING([whether iso-codes has iso-639 and iso-3166 domains]) - if $PKG_CONFIG --variable=domains iso-codes | grep 639 > /dev/null && \ - $PKG_CONFIG --variable=domains iso-codes | grep 3166 > /dev/null ; then - result=yes - else - result=no - have_iso_codes=no - fi - AC_MSG_RESULT([$result]) - fi - - if test "x$have_iso_codes" = "xyes"; then - AC_DEFINE_UNQUOTED([ISO_CODES_PREFIX],["`$PKG_CONFIG --variable=prefix iso-codes`"],[ISO codes prefix]) - AC_DEFINE([HAVE_ISO_CODES],[1],[Define if you have the iso-codes package]) - else - AC_MSG_ERROR([iso-codes is required to build the spell plugin. Use --disable-spell to build without spell plugin.]) - fi - else - enable_enchant=no - AC_MSG_ERROR([Enchant library not found or too old. Use --disable-spell to build without spell plugin.]) + if test "x$have_gspell" = "xno"; then + enable_spell=no + AC_MSG_ERROR([gspell library not found or too old. Use --disable-spell to build without spell plugin.]) fi fi -AM_CONDITIONAL(ENABLE_ENCHANT, test x"$enable_enchant" = "xyes") +AM_CONDITIONAL(ENABLE_SPELL, test x"$enable_spell" = "xyes") dnl ================================================================ dnl Start of pkg-config checks @@ -255,7 +231,7 @@ Configuration: Source code location: ${srcdir} Compiler: ${CC} - Spell Plugin enabled: $enable_enchant + Spell Plugin enabled: $enable_spell Gvfs metadata enabled: $enable_gvfs_metadata GObject Introspection: ${enable_introspection} " diff --git a/debian/control b/debian/control index 493e733..8d7e25e 100644 --- a/debian/control +++ b/debian/control @@ -7,10 +7,9 @@ Build-Depends: autotools-dev, gobject-introspection, gtk-doc-tools, intltool, - iso-codes, - libenchant-dev, libgirepository1.0-dev, libglib2.0-dev, + libgspell-1-dev, libgtk-3-dev, libgtksourceview-3.0-dev, libpeas-dev, diff --git a/plugins/Makefile.am b/plugins/Makefile.am index e6e56c7..846c57c 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -19,7 +19,7 @@ SUBDIRS = \ time \ trailsave -if ENABLE_ENCHANT +if ENABLE_SPELL SUBDIRS += spell endif diff --git a/plugins/spell/Makefile.am b/plugins/spell/Makefile.am index 1afd0d3..504a4f0 100644 --- a/plugins/spell/Makefile.am +++ b/plugins/spell/Makefile.am @@ -4,7 +4,7 @@ plugindir = $(XED_PLUGINS_LIBS_DIR) AM_CPPFLAGS = \ -I$(top_srcdir) \ $(XED_CFLAGS) \ - $(ENCHANT_CFLAGS) \ + $(GSPELL_CFLAGS) \ $(WARN_CFLAGS) \ $(DISABLE_DEPRECATED_CFLAGS) @@ -17,25 +17,13 @@ plugin_LTLIBRARIES = libspell.la libspell_la_SOURCES = \ xed-spell-plugin.c \ xed-spell-plugin.h \ - xed-spell-checker.c \ - xed-spell-checker.h \ - xed-spell-checker-dialog.c \ - xed-spell-checker-dialog.h \ - xed-spell-checker-language.c \ - xed-spell-checker-language.h \ - xed-spell-language-dialog.c \ - xed-spell-language-dialog.h \ - xed-automatic-spell-checker.c \ - xed-automatic-spell-checker.h \ - xed-spell-utils.c \ - xed-spell-utils.h \ $(BUILT_SOURCES) libspell_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) -libspell_la_LIBADD = $(XED_LIBS) $(ENCHANT_LIBS) +libspell_la_LIBADD = $(XED_LIBS) $(GSPELL_LIBS) uidir = $(XED_PLUGINS_DATA_DIR)/spell -ui_DATA = spell-checker.ui languages-dialog.ui xed-spell-setup-dialog.ui +ui_DATA = xed-spell-setup-dialog.ui xed-spell-marshal.h: xed-spell-marshal.list $(GLIB_GENMARSHAL) $(AM_V_GEN) $(GLIB_GENMARSHAL) $< --header --prefix=xed_marshal > $@ diff --git a/plugins/spell/languages-dialog.ui b/plugins/spell/languages-dialog.ui deleted file mode 100644 index 28ec4fb..0000000 --- a/plugins/spell/languages-dialog.ui +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - - False - 5 - Set language - True - True - dialog - - - True - False - 2 - - - True - False - end - - - gtk-help - True - True - True - False - True - - - True - True - 0 - - - - - gtk-cancel - True - True - True - False - True - - - True - True - 1 - - - - - gtk-ok - True - True - True - False - True - - - True - True - 2 - - - - - False - True - end - 0 - - - - - True - False - True - True - 5 - vertical - 11 - - - True - False - Select the _language of the current document. - True - True - languages_treeview - 0 - - - False - False - 0 - - - - - 180 - True - True - etched-in - - - 180 - True - True - False - - - - - - - - True - True - 1 - - - - - False - True - 0 - - - - - - helpbutton1 - closebutton1 - button1 - - - diff --git a/plugins/spell/spell-checker.ui b/plugins/spell/spell-checker.ui deleted file mode 100644 index f5f8a30..0000000 --- a/plugins/spell/spell-checker.ui +++ /dev/null @@ -1,369 +0,0 @@ - - - - - - False - False - True - dialog - True - Check spelling - - - True - False - 12 - vertical - 6 - - - True - False - True - 6 - 12 - - - True - False - Misspelled word: - 0 - - - 0 - 0 - - - - - True - False - word - True - center - 0 - - - 1 - 0 - - - - - True - False - Change _to: - True - 0 - - - 0 - 1 - - - - - True - False - True - 12 - - - True - True - True - - - False - True - 0 - - - - - Check _Word - True - True - True - True - - - False - True - 1 - - - - - 1 - 1 - - - - - False - True - 0 - - - - - True - False - 6 - 12 - - - True - False - _Suggestions: - True - 0 - - - 0 - 0 - - - - - True - True - True - True - in - - - True - True - False - - - - - - - - 0 - 1 - - - - - True - False - 6 - vertical - 12 - - - True - False - 12 - 12 - - - _Ignore - True - True - True - True - - - 0 - 0 - - - - - Ignore _All - True - True - True - True - - - 1 - 0 - - - - - Cha_nge - True - True - True - True - - - 0 - 1 - - - - - Change A_ll - True - True - True - True - - - 1 - 1 - - - - - False - True - 0 - - - - - True - False - vertical - 11 - - - True - False - User dictionary: - True - 0 - - - False - True - 0 - - - - - True - False - 6 - True - - - Add w_ord - True - True - True - True - - - False - True - 0 - - - - - False - True - 2 - - - - - False - True - 1 - - - - - 1 - 1 - - - - - True - False - 12 - - - True - False - Language: - - - False - True - 0 - - - - - True - False - Language - True - - - False - True - 1 - - - - - 0 - 2 - - - - - True - False - True - end - - - _Close - True - True - True - end - True - - - - True - True - 0 - - - - - 1 - 3 - - - - - - - - - - - - - - True - True - 1 - - - - - - diff --git a/plugins/spell/xed-automatic-spell-checker.c b/plugins/spell/xed-automatic-spell-checker.c deleted file mode 100644 index 1202920..0000000 --- a/plugins/spell/xed-automatic-spell-checker.c +++ /dev/null @@ -1,967 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-automatic-spell-checker.c - * This file is part of xed - * - * Copyright (C) 2002 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -/* This is a modified version of gtkspell 2.0.5 (gtkspell.sf.net) */ -/* gtkspell - a spell-checking addon for GTK's TextView widget - * Copyright (c) 2002 Evan Martin. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include - -#include "xed-automatic-spell-checker.h" -#include "xed-spell-utils.h" - -struct _XedAutomaticSpellChecker -{ - XedDocument *doc; - GSList *views; - - GtkTextMark *mark_insert_start; - GtkTextMark *mark_insert_end; - gboolean deferred_check; - - GtkTextTag *tag_highlight; - GtkTextMark *mark_click; - - XedSpellChecker *spell_checker; -}; - -static GQuark automatic_spell_checker_id = 0; -static GQuark suggestion_id = 0; - -static void xed_automatic_spell_checker_free_internal (XedAutomaticSpellChecker *spell); - -static void -view_destroy (XedView *view, - XedAutomaticSpellChecker *spell) -{ - xed_automatic_spell_checker_detach_view (spell, view); -} - -static void -check_word (XedAutomaticSpellChecker *spell, - GtkTextIter *start, - GtkTextIter *end) -{ - gchar *word; - - word = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), start, end, FALSE); - - /* - g_print ("Check word: %s [%d - %d]\n", word, gtk_text_iter_get_offset (start), - gtk_text_iter_get_offset (end)); - */ - - if (!xed_spell_checker_check_word (spell->spell_checker, word, -1)) - { - /* - g_print ("Apply tag: [%d - %d]\n", gtk_text_iter_get_offset (start), - gtk_text_iter_get_offset (end)); - */ - gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (spell->doc), spell->tag_highlight, start, end); - } - - g_free (word); -} - -static void -check_range (XedAutomaticSpellChecker *spell, - GtkTextIter start, - GtkTextIter end, - gboolean force_all) -{ - /* we need to "split" on word boundaries. - * luckily, Pango knows what "words" are - * so we don't have to figure it out. */ - - GtkTextIter wstart; - GtkTextIter wend; - GtkTextIter cursor; - GtkTextIter precursor; - gboolean highlight; - - /* - g_print ("Check range: [%d - %d]\n", gtk_text_iter_get_offset (&start), - gtk_text_iter_get_offset (&end)); - */ - - if (gtk_text_iter_inside_word (&end)) - { - gtk_text_iter_forward_word_end (&end); - } - - if (!gtk_text_iter_starts_word (&start)) - { - if (gtk_text_iter_inside_word (&start) || gtk_text_iter_ends_word (&start)) - { - gtk_text_iter_backward_word_start (&start); - } - else - { - /* if we're neither at the beginning nor inside a word, - * me must be in some spaces. - * skip forward to the beginning of the next word. */ - - if (gtk_text_iter_forward_word_end (&start)) - { - gtk_text_iter_backward_word_start (&start); - } - } - } - - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (spell->doc), - &cursor, - gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (spell->doc))); - - precursor = cursor; - gtk_text_iter_backward_char (&precursor); - - highlight = gtk_text_iter_has_tag (&cursor, spell->tag_highlight) || - gtk_text_iter_has_tag (&precursor, spell->tag_highlight); - - gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc), spell->tag_highlight, &start, &end); - - /* Fix a corner case when replacement occurs at beginning of buffer: - * An iter at offset 0 seems to always be inside a word, - * even if it's not. Possibly a pango bug. - */ - if (gtk_text_iter_get_offset (&start) == 0) - { - gtk_text_iter_forward_word_end(&start); - gtk_text_iter_backward_word_start(&start); - } - - wstart = start; - - while (xed_spell_utils_skip_no_spell_check (&wstart, &end) && gtk_text_iter_compare (&wstart, &end) < 0) - { - gboolean inword; - - /* move wend to the end of the current word. */ - wend = wstart; - - gtk_text_iter_forward_word_end (&wend); - - inword = (gtk_text_iter_compare (&wstart, &cursor) < 0) && (gtk_text_iter_compare (&cursor, &wend) <= 0); - - if (inword && !force_all) - { - /* this word is being actively edited, - * only check if it's already highligted, - * otherwise defer this check until later. */ - if (highlight) - { - check_word (spell, &wstart, &wend); - } - else - { - spell->deferred_check = TRUE; - } - } - else - { - check_word (spell, &wstart, &wend); - spell->deferred_check = FALSE; - } - - /* now move wend to the beginning of the next word, */ - gtk_text_iter_forward_word_end (&wend); - gtk_text_iter_backward_word_start (&wend); - - /* make sure we've actually advanced - * (we don't advance in some corner cases), */ - if (gtk_text_iter_equal (&wstart, &wend)) - { - break; /* we're done in these cases.. */ - } - - /* and then pick this as the new next word beginning. */ - wstart = wend; - } -} - -static void -check_deferred_range (XedAutomaticSpellChecker *spell, - gboolean force_all) -{ - GtkTextIter start, end; - - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (spell->doc), &start, spell->mark_insert_start); - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (spell->doc), &end, spell->mark_insert_end); - - check_range (spell, start, end, force_all); -} - -/* insertion works like this: - * - before the text is inserted, we mark the position in the buffer. - * - after the text is inserted, we see where our mark is and use that and - * the current position to check the entire range of inserted text. - * - * this may be overkill for the common case (inserting one character). */ - -static void -insert_text_before (GtkTextBuffer *buffer, - GtkTextIter *iter, - gchar *text, - gint len, - XedAutomaticSpellChecker *spell) -{ - gtk_text_buffer_move_mark (buffer, spell->mark_insert_start, iter); -} - -static void -insert_text_after (GtkTextBuffer *buffer, - GtkTextIter *iter, - gchar *text, - gint len, - XedAutomaticSpellChecker *spell) -{ - GtkTextIter start; - - /* we need to check a range of text. */ - gtk_text_buffer_get_iter_at_mark (buffer, &start, spell->mark_insert_start); - - check_range (spell, start, *iter, FALSE); - - gtk_text_buffer_move_mark (buffer, spell->mark_insert_end, iter); -} - -/* deleting is more simple: we're given the range of deleted text. - * after deletion, the start and end iters should be at the same position - * (because all of the text between them was deleted!). - * this means we only really check the words immediately bounding the - * deletion. - */ - -static void -delete_range_after (GtkTextBuffer *buffer, - GtkTextIter *start, - GtkTextIter *end, - XedAutomaticSpellChecker *spell) -{ - check_range (spell, *start, *end, FALSE); -} - -static void -mark_set (GtkTextBuffer *buffer, - GtkTextIter *iter, - GtkTextMark *mark, - XedAutomaticSpellChecker *spell) -{ - /* if the cursor has moved and there is a deferred check so handle it now */ - if ((mark == gtk_text_buffer_get_insert (buffer)) && spell->deferred_check) - { - check_deferred_range (spell, FALSE); - } -} - -static void -get_word_extents_from_mark (GtkTextBuffer *buffer, - GtkTextIter *start, - GtkTextIter *end, - GtkTextMark *mark) -{ - gtk_text_buffer_get_iter_at_mark(buffer, start, mark); - - if (!gtk_text_iter_starts_word (start)) - { - gtk_text_iter_backward_word_start (start); - } - - *end = *start; - - if (gtk_text_iter_inside_word (end)) - { - gtk_text_iter_forward_word_end (end); - } -} - -static void -remove_tag_to_word (XedAutomaticSpellChecker *spell, - const gchar *word) -{ - GtkTextIter iter; - GtkTextIter match_start, match_end; - - gboolean found; - - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (spell->doc), &iter, 0); - - found = TRUE; - - while (found) - { - found = gtk_text_iter_forward_search (&iter, - word, - GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY, - &match_start, - &match_end, - NULL); - - if (found) - { - if (gtk_text_iter_starts_word (&match_start) && gtk_text_iter_ends_word (&match_end)) - { - gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc), - spell->tag_highlight, - &match_start, - &match_end); - } - - iter = match_end; - } - } -} - -static void -add_to_dictionary (GtkWidget *menuitem, - XedAutomaticSpellChecker *spell) -{ - gchar *word; - - GtkTextIter start, end; - - get_word_extents_from_mark (GTK_TEXT_BUFFER (spell->doc), &start, &end, spell->mark_click); - - word = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), &start, &end, FALSE); - - xed_spell_checker_add_word_to_personal (spell->spell_checker, word, -1); - - g_free (word); -} - -static void -ignore_all (GtkWidget *menuitem, - XedAutomaticSpellChecker *spell) -{ - gchar *word; - - GtkTextIter start, end; - - get_word_extents_from_mark (GTK_TEXT_BUFFER (spell->doc), &start, &end, spell->mark_click); - - word = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), &start, &end, FALSE); - - xed_spell_checker_add_word_to_session (spell->spell_checker, word, -1); - - g_free (word); -} - -static void -replace_word (GtkWidget *menuitem, - XedAutomaticSpellChecker *spell) -{ - gchar *oldword; - const gchar *newword; - - GtkTextIter start, end; - - get_word_extents_from_mark (GTK_TEXT_BUFFER (spell->doc), &start, &end, spell->mark_click); - - oldword = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), &start, &end, FALSE); - - newword = g_object_get_qdata (G_OBJECT (menuitem), suggestion_id); - g_return_if_fail (newword != NULL); - - gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (spell->doc)); - - gtk_text_buffer_delete (GTK_TEXT_BUFFER (spell->doc), &start, &end); - gtk_text_buffer_insert (GTK_TEXT_BUFFER (spell->doc), &start, newword, -1); - - gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (spell->doc)); - - xed_spell_checker_set_correction (spell->spell_checker, - oldword, strlen (oldword), - newword, strlen (newword)); - - g_free (oldword); -} - -static GtkWidget * -build_suggestion_menu (XedAutomaticSpellChecker *spell, - const gchar *word) -{ - GtkWidget *topmenu, *menu; - GtkWidget *mi; - GSList *suggestions; - GSList *list; - gchar *label_text; - - topmenu = menu = gtk_menu_new(); - - suggestions = xed_spell_checker_get_suggestions (spell->spell_checker, word, -1); - - list = suggestions; - - if (suggestions == NULL) - { - /* no suggestions. put something in the menu anyway... */ - GtkWidget *label; - /* Translators: Displayed in the "Check Spelling" dialog if there are no suggestions for the current misspelled word */ - label = gtk_label_new (_("(no suggested words)")); - - mi = gtk_menu_item_new (); - gtk_widget_set_sensitive (mi, FALSE); - gtk_container_add (GTK_CONTAINER(mi), label); - gtk_widget_show_all (mi); - gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi); - } - else - { - gint count = 0; - - /* build a set of menus with suggestions. */ - while (suggestions != NULL) - { - GtkWidget *label; - - if (count == 10) - { - /* Separator */ - mi = gtk_menu_item_new (); - gtk_widget_show (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - - mi = gtk_menu_item_new_with_mnemonic (_("_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); - count = 0; - } - - label_text = g_strdup_printf ("%s", (gchar*) suggestions->data); - - label = gtk_label_new (label_text); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_widget_set_halign (label, GTK_ALIGN_START); - - mi = gtk_menu_item_new (); - gtk_container_add (GTK_CONTAINER (mi), label); - - gtk_widget_show_all (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - - g_object_set_qdata_full (G_OBJECT (mi), - suggestion_id, - g_strdup (suggestions->data), - (GDestroyNotify)g_free); - - g_free (label_text); - g_signal_connect (mi, "activate", - G_CALLBACK (replace_word), spell); - - count++; - - suggestions = g_slist_next (suggestions); - } - } - - /* free the suggestion list */ - suggestions = list; - - while (list) - { - g_free (list->data); - list = g_slist_next (list); - } - - g_slist_free (suggestions); - - /* Separator */ - mi = gtk_menu_item_new (); - gtk_widget_show (mi); - gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi); - - /* Ignore all */ - mi = gtk_menu_item_new_with_mnemonic (_("_Ignore All")); - - g_signal_connect (mi, "activate", - G_CALLBACK(ignore_all), spell); - - gtk_widget_show_all (mi); - - gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi); - - /* + Add to Dictionary */ - mi = gtk_menu_item_new_with_mnemonic (_("_Add")); - - g_signal_connect (mi, "activate", - G_CALLBACK (add_to_dictionary), spell); - - gtk_widget_show_all (mi); - - gtk_menu_shell_append (GTK_MENU_SHELL (topmenu), mi); - - return topmenu; -} - -static void -populate_popup (GtkTextView *textview, - GtkMenu *menu, - XedAutomaticSpellChecker *spell) -{ - GtkWidget *mi; - GtkTextIter start, end; - char *word; - - /* we need to figure out if they picked a misspelled word. */ - get_word_extents_from_mark (GTK_TEXT_BUFFER (spell->doc), &start, &end, spell->mark_click); - - /* if our highlight algorithm ever messes up, - * this isn't correct, either. */ - if (!gtk_text_iter_has_tag (&start, spell->tag_highlight)) - { - return; /* word wasn't misspelled. */ - } - - /* menu separator comes first. */ - mi = gtk_menu_item_new (); - gtk_widget_show (mi); - gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi); - - /* then, on top of it, the suggestions menu. */ - mi = gtk_menu_item_new_with_mnemonic (_("_Spelling Suggestions...")); - - word = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (spell->doc), &start, &end, FALSE); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), build_suggestion_menu (spell, word)); - g_free(word); - - gtk_widget_show_all (mi); - gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi); -} - -void -xed_automatic_spell_checker_recheck_all (XedAutomaticSpellChecker *spell) -{ - GtkTextIter start, end; - - g_return_if_fail (spell != NULL); - - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (spell->doc), &start, &end); - - check_range (spell, start, end, TRUE); -} - -static void -add_word_signal_cb (XedSpellChecker *checker, - const gchar *word, - gint len, - XedAutomaticSpellChecker *spell) -{ - gchar *w; - - if (len < 0) - { - w = g_strdup (word); - } - else - { - w = g_strndup (word, len); - } - - remove_tag_to_word (spell, w); - - g_free (w); -} - -static void -set_language_cb (XedSpellChecker *checker, - const XedSpellCheckerLanguage *lang, - XedAutomaticSpellChecker *spell) -{ - xed_automatic_spell_checker_recheck_all (spell); -} - -static void -clear_session_cb (XedSpellChecker *checker, - XedAutomaticSpellChecker *spell) -{ - xed_automatic_spell_checker_recheck_all (spell); -} - -/* When the user right-clicks on a word, they want to check that word. - * Here, we do NOT move the cursor to the location of the clicked-upon word - * since that prevents the use of edit functions on the context menu. - */ -static gboolean -button_press_event (GtkTextView *view, - GdkEventButton *event, - XedAutomaticSpellChecker *spell) -{ - if (event->button == 3) - { - gint x, y; - GtkTextIter iter; - - GtkTextBuffer *buffer = gtk_text_view_get_buffer (view); - - /* handle deferred check if it exists */ - if (spell->deferred_check) - { - check_deferred_range (spell, TRUE); - } - - gtk_text_view_window_to_buffer_coords (view, GTK_TEXT_WINDOW_TEXT, event->x, event->y, &x, &y); - - gtk_text_view_get_iter_at_location (view, &iter, x, y); - - gtk_text_buffer_move_mark (buffer, spell->mark_click, &iter); - } - - return FALSE; /* false: let gtk process this event, too. - we don't want to eat any events. */ -} - -/* Move the insert mark before popping up the menu, otherwise it - * will contain the wrong set of suggestions. - */ -static gboolean -popup_menu_event (GtkTextView *view, - XedAutomaticSpellChecker *spell) -{ - GtkTextIter iter; - GtkTextBuffer *buffer; - - buffer = gtk_text_view_get_buffer (view); - - /* handle deferred check if it exists */ - if (spell->deferred_check) - { - check_deferred_range (spell, TRUE); - } - - gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer)); - gtk_text_buffer_move_mark (buffer, spell->mark_click, &iter); - - return FALSE; -} - -static void -tag_table_changed (GtkTextTagTable *table, - XedAutomaticSpellChecker *spell) -{ - g_return_if_fail (spell->tag_highlight != NULL); - - gtk_text_tag_set_priority (spell->tag_highlight, gtk_text_tag_table_get_size (table) - 1); -} - -static void -tag_added_or_removed (GtkTextTagTable *table, - GtkTextTag *tag, - XedAutomaticSpellChecker *spell) -{ - tag_table_changed (table, spell); -} - -static void -tag_changed (GtkTextTagTable *table, - GtkTextTag *tag, - gboolean size_changed, - XedAutomaticSpellChecker *spell) -{ - tag_table_changed (table, spell); -} - -static void -highlight_updated (GtkSourceBuffer *buffer, - GtkTextIter *start, - GtkTextIter *end, - XedAutomaticSpellChecker *spell) -{ - check_range (spell, *start, *end, FALSE); -} - -static void -spell_tag_destroyed (XedAutomaticSpellChecker *spell, - GObject *where_the_object_was) -{ - spell->tag_highlight = NULL; -} - -XedAutomaticSpellChecker * -xed_automatic_spell_checker_new (XedDocument *doc, - XedSpellChecker *checker) -{ - XedAutomaticSpellChecker *spell; - GtkTextTagTable *tag_table; - GtkTextIter start, end; - - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - g_return_val_if_fail (XED_IS_SPELL_CHECKER (checker), NULL); - g_return_val_if_fail ((spell = xed_automatic_spell_checker_get_from_document (doc)) == NULL, spell); - - /* attach to the widget */ - spell = g_new0 (XedAutomaticSpellChecker, 1); - - spell->doc = doc; - spell->spell_checker = g_object_ref (checker); - - if (automatic_spell_checker_id == 0) - { - automatic_spell_checker_id = g_quark_from_string ("XedAutomaticSpellCheckerID"); - } - if (suggestion_id == 0) - { - suggestion_id = g_quark_from_string ("XedAutoSuggestionID"); - } - - g_object_set_qdata_full (G_OBJECT (doc), automatic_spell_checker_id, - spell, (GDestroyNotify)xed_automatic_spell_checker_free_internal); - - g_signal_connect (doc, "insert-text", - G_CALLBACK (insert_text_before), spell); - g_signal_connect_after (doc, "insert-text", - G_CALLBACK (insert_text_after), spell); - g_signal_connect_after (doc, "delete-range", - G_CALLBACK (delete_range_after), spell); - g_signal_connect (doc, "mark-set", - G_CALLBACK (mark_set), spell); - - g_signal_connect (doc, "highlight-updated", - G_CALLBACK (highlight_updated), spell); - - g_signal_connect (spell->spell_checker, "add_word_to_session", - G_CALLBACK (add_word_signal_cb), spell); - g_signal_connect (spell->spell_checker, "add_word_to_personal", - G_CALLBACK (add_word_signal_cb), spell); - g_signal_connect (spell->spell_checker, "clear_session", - G_CALLBACK (clear_session_cb), spell); - g_signal_connect (spell->spell_checker, "set_language", - G_CALLBACK (set_language_cb), spell); - - spell->tag_highlight = gtk_text_buffer_create_tag (GTK_TEXT_BUFFER (doc), - "gtkspell-misspelled", - "underline", PANGO_UNDERLINE_ERROR, - NULL); - - g_object_weak_ref (G_OBJECT (spell->tag_highlight), (GWeakNotify)spell_tag_destroyed, spell); - - tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (doc)); - - gtk_text_tag_set_priority (spell->tag_highlight, gtk_text_tag_table_get_size (tag_table) - 1); - - g_signal_connect (tag_table, "tag-added", - G_CALLBACK (tag_added_or_removed), spell); - g_signal_connect (tag_table, "tag-removed", - G_CALLBACK (tag_added_or_removed), spell); - g_signal_connect (tag_table, "tag-changed", - G_CALLBACK (tag_changed), spell); - - /* we create the mark here, but we don't use it until text is - * inserted, so we don't really care where iter points. */ - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), &start, &end); - - spell->mark_insert_start = gtk_text_buffer_get_mark (GTK_TEXT_BUFFER (doc), - "xed-automatic-spell-checker-insert-start"); - - if (spell->mark_insert_start == NULL) - { - spell->mark_insert_start = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), - "xed-automatic-spell-checker-insert-start", - &start, - TRUE); - } - else - { - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), spell->mark_insert_start, &start); - } - - spell->mark_insert_end = gtk_text_buffer_get_mark (GTK_TEXT_BUFFER (doc), - "xed-automatic-spell-checker-insert-end"); - - if (spell->mark_insert_end == NULL) - { - spell->mark_insert_end = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), - "xed-automatic-spell-checker-insert-end", - &start, - TRUE); - } - else - { - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), spell->mark_insert_end, &start); - } - - spell->mark_click = gtk_text_buffer_get_mark (GTK_TEXT_BUFFER (doc), - "xed-automatic-spell-checker-click"); - - if (spell->mark_click == NULL) - { - spell->mark_click = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), - "xed-automatic-spell-checker-click", - &start, - TRUE); - } - else - { - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), spell->mark_click, &start); - } - - spell->deferred_check = FALSE; - - return spell; -} - -XedAutomaticSpellChecker * -xed_automatic_spell_checker_get_from_document (const XedDocument *doc) -{ - g_return_val_if_fail (XED_IS_DOCUMENT (doc), NULL); - - if (automatic_spell_checker_id == 0) - { - return NULL; - } - - return g_object_get_qdata (G_OBJECT (doc), automatic_spell_checker_id); -} - -void -xed_automatic_spell_checker_free (XedAutomaticSpellChecker *spell) -{ - g_return_if_fail (spell != NULL); - g_return_if_fail (xed_automatic_spell_checker_get_from_document (spell->doc) == spell); - - if (automatic_spell_checker_id == 0) - { - return; - } - - g_object_set_qdata (G_OBJECT (spell->doc), automatic_spell_checker_id, NULL); -} - -static void -xed_automatic_spell_checker_free_internal (XedAutomaticSpellChecker *spell) -{ - GtkTextTagTable *table; - GtkTextIter start, end; - GSList *list; - - g_return_if_fail (spell != NULL); - - table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (spell->doc)); - - if (table != NULL && spell->tag_highlight != NULL) - { - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (spell->doc), &start, &end); - gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc), spell->tag_highlight, &start, &end); - - g_signal_handlers_disconnect_matched (G_OBJECT (table), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); - - gtk_text_tag_table_remove (table, spell->tag_highlight); - } - - g_signal_handlers_disconnect_matched (G_OBJECT (spell->doc), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); - - g_signal_handlers_disconnect_matched (G_OBJECT (spell->spell_checker), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); - - g_object_unref (spell->spell_checker); - - list = spell->views; - while (list != NULL) - { - XedView *view = XED_VIEW (list->data); - - g_signal_handlers_disconnect_matched (G_OBJECT (view), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); - - g_signal_handlers_disconnect_matched (G_OBJECT (view), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); - - list = g_slist_next (list); - } - - g_slist_free (spell->views); - - g_free (spell); -} - -void -xed_automatic_spell_checker_attach_view (XedAutomaticSpellChecker *spell, - XedView *view) -{ - g_return_if_fail (spell != NULL); - g_return_if_fail (XED_IS_VIEW (view)); - - g_return_if_fail (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)) == GTK_TEXT_BUFFER (spell->doc)); - - g_signal_connect (view, "button-press-event", - G_CALLBACK (button_press_event), spell); - g_signal_connect (view, "popup-menu", - G_CALLBACK (popup_menu_event), spell); - g_signal_connect (view, "populate-popup", - G_CALLBACK (populate_popup), spell); - g_signal_connect (view, "destroy", - G_CALLBACK (view_destroy), spell); - - spell->views = g_slist_prepend (spell->views, view); -} - -void -xed_automatic_spell_checker_detach_view (XedAutomaticSpellChecker *spell, - XedView *view) -{ - g_return_if_fail (spell != NULL); - g_return_if_fail (XED_IS_VIEW (view)); - - g_return_if_fail (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)) == GTK_TEXT_BUFFER (spell->doc)); - g_return_if_fail (spell->views != NULL); - - g_signal_handlers_disconnect_matched (G_OBJECT (view), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); - - g_signal_handlers_disconnect_matched (G_OBJECT (view), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - spell); - - spell->views = g_slist_remove (spell->views, view); -} - diff --git a/plugins/spell/xed-automatic-spell-checker.h b/plugins/spell/xed-automatic-spell-checker.h deleted file mode 100644 index b057a52..0000000 --- a/plugins/spell/xed-automatic-spell-checker.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-automatic-spell-checker.h - * This file is part of xed - * - * Copyright (C) 2002 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -/* This is a modified version of gtkspell 2.0.2 (gtkspell.sf.net) */ -/* gtkspell - a spell-checking addon for GTK's TextView widget - * Copyright (c) 2002 Evan Martin. - */ - -#ifndef __XED_AUTOMATIC_SPELL_CHECKER_H__ -#define __XED_AUTOMATIC_SPELL_CHECKER_H__ - -#include -#include - -#include "xed-spell-checker.h" - -typedef struct _XedAutomaticSpellChecker XedAutomaticSpellChecker; - -XedAutomaticSpellChecker *xed_automatic_spell_checker_new ( - XedDocument *doc, - XedSpellChecker *checker); - -XedAutomaticSpellChecker *xed_automatic_spell_checker_get_from_document ( - const XedDocument *doc); - -void xed_automatic_spell_checker_free ( - XedAutomaticSpellChecker *spell); - -void xed_automatic_spell_checker_attach_view ( - XedAutomaticSpellChecker *spell, - XedView *view); - -void xed_automatic_spell_checker_detach_view ( - XedAutomaticSpellChecker *spell, - XedView *view); - -void xed_automatic_spell_checker_recheck_all ( - XedAutomaticSpellChecker *spell); - -#endif /* __XED_AUTOMATIC_SPELL_CHECKER_H__ */ - diff --git a/plugins/spell/xed-spell-checker-dialog.c b/plugins/spell/xed-spell-checker-dialog.c deleted file mode 100644 index 3fee5b7..0000000 --- a/plugins/spell/xed-spell-checker-dialog.c +++ /dev/null @@ -1,726 +0,0 @@ -/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-spell-checker-dialog.c - * This file is part of xed - * - * Copyright (C) 2002 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include "xed-spell-checker-dialog.h" -#include "xed-spell-marshal.h" - -struct _XedSpellCheckerDialog -{ - GtkWindow parent_instance; - - XedSpellChecker *spell_checker; - - gchar *misspelled_word; - - GtkWidget *misspelled_word_label; - GtkWidget *word_entry; - GtkWidget *check_word_button; - GtkWidget *ignore_button; - GtkWidget *ignore_all_button; - GtkWidget *change_button; - GtkWidget *change_all_button; - GtkWidget *add_word_button; - GtkWidget *close_button; - GtkWidget *suggestions_list; - GtkWidget *language_label; - - GtkTreeModel *suggestions_list_model; -}; - -enum -{ - IGNORE, - IGNORE_ALL, - CHANGE, - CHANGE_ALL, - ADD_WORD_TO_PERSONAL, - LAST_SIGNAL -}; - -enum -{ - COLUMN_SUGGESTIONS, - NUM_COLUMNS -}; - -static void update_suggestions_list_model (XedSpellCheckerDialog *dlg, - GSList *suggestions); - -static void word_entry_changed_handler (GtkEditable *editable, - XedSpellCheckerDialog *dlg); -static void close_button_clicked_handler (GtkButton *button, - XedSpellCheckerDialog *dlg); -static void suggestions_list_selection_changed_handler (GtkTreeSelection *selection, - XedSpellCheckerDialog *dlg); -static void check_word_button_clicked_handler (GtkButton *button, - XedSpellCheckerDialog *dlg); -static void add_word_button_clicked_handler (GtkButton *button, - XedSpellCheckerDialog *dlg); -static void ignore_button_clicked_handler (GtkButton *button, - XedSpellCheckerDialog *dlg); -static void ignore_all_button_clicked_handler (GtkButton *button, - XedSpellCheckerDialog *dlg); -static void change_button_clicked_handler (GtkButton *button, - XedSpellCheckerDialog *dlg); -static void change_all_button_clicked_handler (GtkButton *button, - XedSpellCheckerDialog *dlg); -static void suggestions_list_row_activated_handler (GtkTreeView *view, - GtkTreePath *path, - GtkTreeViewColumn *column, - XedSpellCheckerDialog *dlg); - - -static guint signals [LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE(XedSpellCheckerDialog, xed_spell_checker_dialog, GTK_TYPE_WINDOW) - -static void -xed_spell_checker_dialog_dispose (GObject *object) -{ - XedSpellCheckerDialog *dlg = XED_SPELL_CHECKER_DIALOG (object); - - if (dlg->spell_checker != NULL) - { - g_object_unref (dlg->spell_checker); - dlg->spell_checker = NULL; - } - - if (dlg->misspelled_word != NULL) - { - g_free (dlg->misspelled_word); - dlg->misspelled_word = NULL; - } - - G_OBJECT_CLASS (xed_spell_checker_dialog_parent_class)->dispose (object); -} - -static void -xed_spell_checker_dialog_class_init (XedSpellCheckerDialogClass * klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = xed_spell_checker_dialog_dispose; - - signals[IGNORE] = - g_signal_new ("ignore", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedSpellCheckerDialogClass, ignore), - NULL, NULL, - xed_marshal_VOID__STRING, - G_TYPE_NONE, - 1, - G_TYPE_STRING); - - signals[IGNORE_ALL] = - g_signal_new ("ignore_all", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedSpellCheckerDialogClass, ignore_all), - NULL, NULL, - xed_marshal_VOID__STRING, - G_TYPE_NONE, - 1, - G_TYPE_STRING); - - signals[CHANGE] = - g_signal_new ("change", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedSpellCheckerDialogClass, change), - NULL, NULL, - xed_marshal_VOID__STRING_STRING, - G_TYPE_NONE, - 2, - G_TYPE_STRING, - G_TYPE_STRING); - - signals[CHANGE_ALL] = - g_signal_new ("change_all", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedSpellCheckerDialogClass, change_all), - NULL, NULL, - xed_marshal_VOID__STRING_STRING, - G_TYPE_NONE, - 2, - G_TYPE_STRING, - G_TYPE_STRING); - - signals[ADD_WORD_TO_PERSONAL] = - g_signal_new ("add_word_to_personal", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedSpellCheckerDialogClass, add_word_to_personal), - NULL, NULL, - xed_marshal_VOID__STRING, - G_TYPE_NONE, - 1, - G_TYPE_STRING); -} - -static void -create_dialog (XedSpellCheckerDialog *dlg, - const gchar *data_dir) -{ - GtkWidget *error_widget; - GtkWidget *content; - GtkTreeViewColumn *column; - GtkCellRenderer *cell; - GtkTreeSelection *selection; - gchar *root_objects[] = { - "content", - "check_word_image", - "add_word_image", - "ignore_image", - "change_image", - "ignore_all_image", - "change_all_image", - NULL - }; - gboolean ret; - gchar *ui_file; - - g_return_if_fail (dlg != NULL); - - dlg->spell_checker = NULL; - dlg->misspelled_word = NULL; - - ui_file = g_build_filename (data_dir, "spell-checker.ui", NULL); - ret = xed_utils_get_ui_objects (ui_file, - root_objects, - &error_widget, - - "content", &content, - "misspelled_word_label", &dlg->misspelled_word_label, - "word_entry", &dlg->word_entry, - "check_word_button", &dlg->check_word_button, - "ignore_button", &dlg->ignore_button, - "ignore_all_button", &dlg->ignore_all_button, - "change_button", &dlg->change_button, - "change_all_button", &dlg->change_all_button, - "add_word_button", &dlg->add_word_button, - "close_button", &dlg->close_button, - "suggestions_list", &dlg->suggestions_list, - "language_label", &dlg->language_label, - NULL); - g_free (ui_file); - - if (!ret) - { - gtk_widget_show (error_widget); - - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), - error_widget, TRUE, TRUE, 0); - - return; - } - - gtk_label_set_label (GTK_LABEL (dlg->misspelled_word_label), ""); - gtk_widget_set_sensitive (dlg->word_entry, FALSE); - gtk_widget_set_sensitive (dlg->check_word_button, FALSE); - gtk_widget_set_sensitive (dlg->ignore_button, FALSE); - gtk_widget_set_sensitive (dlg->ignore_all_button, FALSE); - gtk_widget_set_sensitive (dlg->change_button, FALSE); - gtk_widget_set_sensitive (dlg->change_all_button, FALSE); - gtk_widget_set_sensitive (dlg->add_word_button, FALSE); - - gtk_label_set_label (GTK_LABEL (dlg->language_label), ""); - - gtk_container_add (GTK_CONTAINER (dlg), content); - g_object_unref (content); - - gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE); - gtk_window_set_title (GTK_WINDOW (dlg), _("Check Spelling")); - - /* Suggestion list */ - dlg->suggestions_list_model = GTK_TREE_MODEL ( - gtk_list_store_new (NUM_COLUMNS, G_TYPE_STRING)); - - gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->suggestions_list), - dlg->suggestions_list_model); - - /* Add the suggestions column */ - cell = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes (_("Suggestions"), cell, - "text", COLUMN_SUGGESTIONS, NULL); - - gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->suggestions_list), column); - - gtk_tree_view_set_search_column (GTK_TREE_VIEW (dlg->suggestions_list), - COLUMN_SUGGESTIONS); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->suggestions_list)); - - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - - /* Set default button */ - gtk_widget_set_can_default (dlg->change_button, TRUE); - gtk_widget_grab_default (dlg->change_button); - - gtk_entry_set_activates_default (GTK_ENTRY (dlg->word_entry), TRUE); - - /* Connect signals */ - g_signal_connect (dlg->word_entry, "changed", - G_CALLBACK (word_entry_changed_handler), dlg); - g_signal_connect (dlg->close_button, "clicked", - G_CALLBACK (close_button_clicked_handler), dlg); - g_signal_connect (selection, "changed", - G_CALLBACK (suggestions_list_selection_changed_handler), - dlg); - g_signal_connect (dlg->check_word_button, "clicked", - G_CALLBACK (check_word_button_clicked_handler), dlg); - g_signal_connect (dlg->add_word_button, "clicked", - G_CALLBACK (add_word_button_clicked_handler), dlg); - g_signal_connect (dlg->ignore_button, "clicked", - G_CALLBACK (ignore_button_clicked_handler), dlg); - g_signal_connect (dlg->ignore_all_button, "clicked", - G_CALLBACK (ignore_all_button_clicked_handler), dlg); - g_signal_connect (dlg->change_button, "clicked", - G_CALLBACK (change_button_clicked_handler), dlg); - g_signal_connect (dlg->change_all_button, "clicked", - G_CALLBACK (change_all_button_clicked_handler), dlg); - g_signal_connect (dlg->suggestions_list, "row-activated", - G_CALLBACK (suggestions_list_row_activated_handler), dlg); -} - -static void -xed_spell_checker_dialog_init (XedSpellCheckerDialog *dlg) -{ -} - -GtkWidget * -xed_spell_checker_dialog_new (const gchar *data_dir) -{ - XedSpellCheckerDialog *dlg; - - dlg = XED_SPELL_CHECKER_DIALOG ( - g_object_new (XED_TYPE_SPELL_CHECKER_DIALOG, NULL)); - - g_return_val_if_fail (dlg != NULL, NULL); - - create_dialog (dlg, data_dir); - - return GTK_WIDGET (dlg); -} - -GtkWidget * -xed_spell_checker_dialog_new_from_spell_checker (XedSpellChecker *spell, - const gchar *data_dir) -{ - XedSpellCheckerDialog *dlg; - - g_return_val_if_fail (spell != NULL, NULL); - - dlg = XED_SPELL_CHECKER_DIALOG ( - g_object_new (XED_TYPE_SPELL_CHECKER_DIALOG, NULL)); - - g_return_val_if_fail (dlg != NULL, NULL); - - create_dialog (dlg, data_dir); - - xed_spell_checker_dialog_set_spell_checker (dlg, spell); - - return GTK_WIDGET (dlg); -} - -void -xed_spell_checker_dialog_set_spell_checker (XedSpellCheckerDialog *dlg, XedSpellChecker *spell) -{ - const XedSpellCheckerLanguage* language; - const gchar *lang; - gchar *tmp; - - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - g_return_if_fail (spell != NULL); - - if (dlg->spell_checker != NULL) - g_object_unref (dlg->spell_checker); - - dlg->spell_checker = spell; - g_object_ref (dlg->spell_checker); - - language = xed_spell_checker_get_language (dlg->spell_checker); - - lang = xed_spell_checker_language_to_string (language); - tmp = g_strdup_printf("%s", lang); - - gtk_label_set_label (GTK_LABEL (dlg->language_label), tmp); - g_free (tmp); - - if (dlg->misspelled_word != NULL) - xed_spell_checker_dialog_set_misspelled_word (dlg, dlg->misspelled_word, -1); - else - gtk_list_store_clear (GTK_LIST_STORE (dlg->suggestions_list_model)); - - /* TODO: reset all widgets */ -} - -void -xed_spell_checker_dialog_set_misspelled_word (XedSpellCheckerDialog *dlg, - const gchar *word, - gint len) -{ - gchar *tmp; - GSList *sug; - - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - g_return_if_fail (word != NULL); - - g_return_if_fail (dlg->spell_checker != NULL); - g_return_if_fail (!xed_spell_checker_check_word (dlg->spell_checker, word, -1)); - - /* build_suggestions_list */ - if (dlg->misspelled_word != NULL) - g_free (dlg->misspelled_word); - - dlg->misspelled_word = g_strdup (word); - - tmp = g_strdup_printf("%s", word); - gtk_label_set_label (GTK_LABEL (dlg->misspelled_word_label), tmp); - g_free (tmp); - - sug = xed_spell_checker_get_suggestions (dlg->spell_checker, - dlg->misspelled_word, - -1); - - update_suggestions_list_model (dlg, sug); - - /* free the suggestion list */ - g_slist_foreach (sug, (GFunc)g_free, NULL); - g_slist_free (sug); - - gtk_widget_set_sensitive (dlg->ignore_button, TRUE); - gtk_widget_set_sensitive (dlg->ignore_all_button, TRUE); - gtk_widget_set_sensitive (dlg->add_word_button, TRUE); -} - -static void -update_suggestions_list_model (XedSpellCheckerDialog *dlg, GSList *suggestions) -{ - GtkListStore *store; - GtkTreeIter iter; - GtkTreeSelection *sel; - - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - g_return_if_fail (GTK_IS_LIST_STORE (dlg->suggestions_list_model)); - - store = GTK_LIST_STORE (dlg->suggestions_list_model); - gtk_list_store_clear (store); - - gtk_widget_set_sensitive (dlg->word_entry, TRUE); - - if (suggestions == NULL) - { - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - /* Translators: Displayed in the "Check Spelling" dialog if there are no suggestions - * for the current misspelled word */ - COLUMN_SUGGESTIONS, _("(no suggested words)"), - -1); - - gtk_entry_set_text (GTK_ENTRY (dlg->word_entry), ""); - - gtk_widget_set_sensitive (dlg->suggestions_list, FALSE); - - return; - } - - gtk_widget_set_sensitive (dlg->suggestions_list, TRUE); - - gtk_entry_set_text (GTK_ENTRY (dlg->word_entry), (gchar*)suggestions->data); - - while (suggestions != NULL) - { - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - COLUMN_SUGGESTIONS, (gchar*)suggestions->data, - -1); - - suggestions = g_slist_next (suggestions); - } - - sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->suggestions_list)); - gtk_tree_model_get_iter_first (dlg->suggestions_list_model, &iter); - gtk_tree_selection_select_iter (sel, &iter); -} - -static void -word_entry_changed_handler (GtkEditable *editable, XedSpellCheckerDialog *dlg) -{ - const gchar *text; - - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - - text = gtk_entry_get_text (GTK_ENTRY (dlg->word_entry)); - - if (g_utf8_strlen (text, -1) > 0) - { - gtk_widget_set_sensitive (dlg->check_word_button, TRUE); - gtk_widget_set_sensitive (dlg->change_button, TRUE); - gtk_widget_set_sensitive (dlg->change_all_button, TRUE); - } - else - { - gtk_widget_set_sensitive (dlg->check_word_button, FALSE); - gtk_widget_set_sensitive (dlg->change_button, FALSE); - gtk_widget_set_sensitive (dlg->change_all_button, FALSE); - } -} - -static void -close_button_clicked_handler (GtkButton *button, XedSpellCheckerDialog *dlg) -{ - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - - gtk_widget_destroy (GTK_WIDGET (dlg)); -} - -static void -suggestions_list_selection_changed_handler (GtkTreeSelection *selection, - XedSpellCheckerDialog *dlg) -{ - GtkTreeIter iter; - GValue value = {0, }; - const gchar *text; - - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - - if (! gtk_tree_selection_get_selected (selection, NULL, &iter)) - return; - - gtk_tree_model_get_value (dlg->suggestions_list_model, &iter, - COLUMN_SUGGESTIONS, - &value); - - text = g_value_get_string (&value); - - gtk_entry_set_text (GTK_ENTRY (dlg->word_entry), text); - - g_value_unset (&value); -} - -static void -check_word_button_clicked_handler (GtkButton *button, XedSpellCheckerDialog *dlg) -{ - const gchar *word; - gssize len; - - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - - word = gtk_entry_get_text (GTK_ENTRY (dlg->word_entry)); - len = strlen (word); - g_return_if_fail (len > 0); - - if (xed_spell_checker_check_word (dlg->spell_checker, word, len)) - { - GtkListStore *store; - GtkTreeIter iter; - - store = GTK_LIST_STORE (dlg->suggestions_list_model); - gtk_list_store_clear (store); - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - /* Translators: Displayed in the "Check Spelling" dialog if the current word isn't misspelled */ - COLUMN_SUGGESTIONS, _("(correct spelling)"), - -1); - - gtk_widget_set_sensitive (dlg->suggestions_list, FALSE); - } - else - { - GSList *sug; - - sug = xed_spell_checker_get_suggestions (dlg->spell_checker, - word, - len); - - update_suggestions_list_model (dlg, sug); - - /* free the suggestion list */ - g_slist_foreach (sug, (GFunc)g_free, NULL); - g_slist_free (sug); - } -} - -static void -add_word_button_clicked_handler (GtkButton *button, XedSpellCheckerDialog *dlg) -{ - gchar *word; - - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - g_return_if_fail (dlg->misspelled_word != NULL); - - xed_spell_checker_add_word_to_personal (dlg->spell_checker, - dlg->misspelled_word, - -1); - - word = g_strdup (dlg->misspelled_word); - - g_signal_emit (G_OBJECT (dlg), signals [ADD_WORD_TO_PERSONAL], 0, word); - - g_free (word); -} - -static void -ignore_button_clicked_handler (GtkButton *button, XedSpellCheckerDialog *dlg) -{ - gchar *word; - - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - g_return_if_fail (dlg->misspelled_word != NULL); - - word = g_strdup (dlg->misspelled_word); - - g_signal_emit (G_OBJECT (dlg), signals [IGNORE], 0, word); - - g_free (word); -} - -static void -ignore_all_button_clicked_handler (GtkButton *button, XedSpellCheckerDialog *dlg) -{ - gchar *word; - - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - g_return_if_fail (dlg->misspelled_word != NULL); - - xed_spell_checker_add_word_to_session (dlg->spell_checker, - dlg->misspelled_word, - -1); - - word = g_strdup (dlg->misspelled_word); - - g_signal_emit (G_OBJECT (dlg), signals [IGNORE_ALL], 0, word); - - g_free (word); -} - -static void -change_button_clicked_handler (GtkButton *button, XedSpellCheckerDialog *dlg) -{ - const gchar *entry_text; - gchar *change; - gchar *word; - - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - g_return_if_fail (dlg->misspelled_word != NULL); - - entry_text = gtk_entry_get_text (GTK_ENTRY (dlg->word_entry)); - g_return_if_fail (entry_text != NULL); - g_return_if_fail (*entry_text != '\0'); - change = g_strdup (entry_text); - - xed_spell_checker_set_correction (dlg->spell_checker, - dlg->misspelled_word, -1, - change, -1); - - word = g_strdup (dlg->misspelled_word); - - g_signal_emit (G_OBJECT (dlg), signals [CHANGE], 0, word, change); - - g_free (word); - g_free (change); -} - -/* double click on one of the suggestions is like clicking on "change" */ -static void -suggestions_list_row_activated_handler (GtkTreeView *view, - GtkTreePath *path, - GtkTreeViewColumn *column, - XedSpellCheckerDialog *dlg) -{ - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - - change_button_clicked_handler (GTK_BUTTON (dlg->change_button), dlg); -} - -static void -change_all_button_clicked_handler (GtkButton *button, XedSpellCheckerDialog *dlg) -{ - const gchar *entry_text; - gchar *change; - gchar *word; - - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - g_return_if_fail (dlg->misspelled_word != NULL); - - entry_text = gtk_entry_get_text (GTK_ENTRY (dlg->word_entry)); - g_return_if_fail (entry_text != NULL); - g_return_if_fail (*entry_text != '\0'); - change = g_strdup (entry_text); - - xed_spell_checker_set_correction (dlg->spell_checker, - dlg->misspelled_word, -1, - change, -1); - - word = g_strdup (dlg->misspelled_word); - - g_signal_emit (G_OBJECT (dlg), signals [CHANGE_ALL], 0, word, change); - - g_free (word); - g_free (change); -} - -void -xed_spell_checker_dialog_set_completed (XedSpellCheckerDialog *dlg) -{ - gchar *tmp; - - g_return_if_fail (XED_IS_SPELL_CHECKER_DIALOG (dlg)); - - tmp = g_strdup_printf("%s", _("Completed spell checking")); - gtk_label_set_label (GTK_LABEL (dlg->misspelled_word_label), - tmp); - g_free (tmp); - - gtk_list_store_clear (GTK_LIST_STORE (dlg->suggestions_list_model)); - gtk_entry_set_text (GTK_ENTRY (dlg->word_entry), ""); - - gtk_widget_set_sensitive (dlg->word_entry, FALSE); - gtk_widget_set_sensitive (dlg->check_word_button, FALSE); - gtk_widget_set_sensitive (dlg->ignore_button, FALSE); - gtk_widget_set_sensitive (dlg->ignore_all_button, FALSE); - gtk_widget_set_sensitive (dlg->change_button, FALSE); - gtk_widget_set_sensitive (dlg->change_all_button, FALSE); - gtk_widget_set_sensitive (dlg->add_word_button, FALSE); - gtk_widget_set_sensitive (dlg->suggestions_list, FALSE); -} - diff --git a/plugins/spell/xed-spell-checker-dialog.h b/plugins/spell/xed-spell-checker-dialog.h deleted file mode 100644 index ca5b9ef..0000000 --- a/plugins/spell/xed-spell-checker-dialog.h +++ /dev/null @@ -1,92 +0,0 @@ -/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-spell-checker-dialog.h - * This file is part of xed - * - * Copyright (C) 2002 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -#ifndef __XED_SPELL_CHECKER_DIALOG_H__ -#define __XED_SPELL_CHECKER_DIALOG_H__ - -#include -#include "xed-spell-checker.h" - -G_BEGIN_DECLS - -#define XED_TYPE_SPELL_CHECKER_DIALOG (xed_spell_checker_dialog_get_type ()) -#define XED_SPELL_CHECKER_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_SPELL_CHECKER_DIALOG, XedSpellCheckerDialog)) -#define XED_SPELL_CHECKER_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_SPELL_CHECKER_DIALOG, XedSpellCheckerDialog)) -#define XED_IS_SPELL_CHECKER_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_SPELL_CHECKER_DIALOG)) -#define XED_IS_SPELL_CHECKER_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_SPELL_CHECKER_DIALOG)) -#define XED_SPELL_CHECKER_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_SPELL_CHECKER_DIALOG, XedSpellCheckerDialog)) - - -typedef struct _XedSpellCheckerDialog XedSpellCheckerDialog; - -typedef struct _XedSpellCheckerDialogClass XedSpellCheckerDialogClass; - -struct _XedSpellCheckerDialogClass -{ - GtkWindowClass parent_class; - - /* Signals */ - void (*ignore) (XedSpellCheckerDialog *dlg, - const gchar *word); - void (*ignore_all) (XedSpellCheckerDialog *dlg, - const gchar *word); - void (*change) (XedSpellCheckerDialog *dlg, - const gchar *word, - const gchar *change_to); - void (*change_all) (XedSpellCheckerDialog *dlg, - const gchar *word, - const gchar *change_to); - void (*add_word_to_personal) (XedSpellCheckerDialog *dlg, - const gchar *word); - -}; - -GType xed_spell_checker_dialog_get_type (void) G_GNUC_CONST; - -/* Constructors */ -GtkWidget *xed_spell_checker_dialog_new (const gchar *data_dir); -GtkWidget *xed_spell_checker_dialog_new_from_spell_checker - (XedSpellChecker *spell, - const gchar *data_dir); - -void xed_spell_checker_dialog_set_spell_checker - (XedSpellCheckerDialog *dlg, - XedSpellChecker *spell); -void xed_spell_checker_dialog_set_misspelled_word - (XedSpellCheckerDialog *dlg, - const gchar* word, - gint len); - -void xed_spell_checker_dialog_set_completed - (XedSpellCheckerDialog *dlg); - -G_END_DECLS - -#endif /* __XED_SPELL_CHECKER_DIALOG_H__ */ - diff --git a/plugins/spell/xed-spell-checker-language.c b/plugins/spell/xed-spell-checker-language.c deleted file mode 100644 index afaba78..0000000 --- a/plugins/spell/xed-spell-checker-language.c +++ /dev/null @@ -1,439 +0,0 @@ -/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-spell-checker-language.c - * This file is part of xed - * - * Copyright (C) 2006 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2006. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -/* Part of the code taked from Epiphany. - * - * Copyright (C) 2003, 2004 Christian Persch - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include - -#include -#include - -#include "xed-spell-checker-language.h" - -#include - -#define ISO_639_DOMAIN "iso_639" -#define ISO_3166_DOMAIN "iso_3166" - -#define ISOCODESLOCALEDIR ISO_CODES_PREFIX "/share/locale" - -struct _XedSpellCheckerLanguage -{ - gchar *abrev; - gchar *name; -}; - -static gboolean available_languages_initialized = FALSE; -static GSList *available_languages = NULL; - -static GHashTable *iso_639_table = NULL; -static GHashTable *iso_3166_table = NULL; - -static void -bind_iso_domains (void) -{ - static gboolean bound = FALSE; - - if (bound == FALSE) - { - bindtextdomain (ISO_639_DOMAIN, ISOCODESLOCALEDIR); - bind_textdomain_codeset (ISO_639_DOMAIN, "UTF-8"); - - bindtextdomain(ISO_3166_DOMAIN, ISOCODESLOCALEDIR); - bind_textdomain_codeset (ISO_3166_DOMAIN, "UTF-8"); - - bound = TRUE; - } -} - -static void -read_iso_639_entry (xmlTextReaderPtr reader, - GHashTable *table) -{ - xmlChar *code, *name; - - code = xmlTextReaderGetAttribute (reader, (const xmlChar *) "iso_639_1_code"); - name = xmlTextReaderGetAttribute (reader, (const xmlChar *) "name"); - - /* Get iso-639-2 code */ - if (code == NULL || code[0] == '\0') - { - xmlFree (code); - /* FIXME: use the 2T or 2B code? */ - code = xmlTextReaderGetAttribute (reader, (const xmlChar *) "iso_639_2T_code"); - } - - if (code != NULL && code[0] != '\0' && name != NULL && name[0] != '\0') - { - g_hash_table_insert (table, code, name); - } - else - { - xmlFree (code); - xmlFree (name); - } -} - -static void -read_iso_3166_entry (xmlTextReaderPtr reader, - GHashTable *table) -{ - xmlChar *code, *name; - - code = xmlTextReaderGetAttribute (reader, (const xmlChar *) "alpha_2_code"); - name = xmlTextReaderGetAttribute (reader, (const xmlChar *) "name"); - - if (code != NULL && code[0] != '\0' && name != NULL && name[0] != '\0') - { - char *lcode; - - lcode = g_ascii_strdown ((char *) code, -1); - xmlFree (code); - - /* g_print ("%s -> %s\n", lcode, name); */ - - g_hash_table_insert (table, lcode, name); - } - else - { - xmlFree (code); - xmlFree (name); - } -} - -typedef enum -{ - STATE_START, - STATE_STOP, - STATE_ENTRIES, -} ParserState; - -static void -load_iso_entries (int iso, - GFunc read_entry_func, - gpointer user_data) -{ - xmlTextReaderPtr reader; - ParserState state = STATE_START; - xmlChar iso_entries[32], iso_entry[32]; - char *filename; - int ret = -1; - - xed_debug_message (DEBUG_PLUGINS, "Loading ISO-%d codes", iso); - - filename = g_strdup_printf (ISO_CODES_PREFIX "/share/xml/iso-codes/iso_%d.xml", iso); - reader = xmlNewTextReaderFilename (filename); - if (reader == NULL) goto out; - - xmlStrPrintf (iso_entries, sizeof (iso_entries), (const xmlChar *)"iso_%d_entries", iso); - xmlStrPrintf (iso_entry, sizeof (iso_entry), (const xmlChar *)"iso_%d_entry", iso); - - ret = xmlTextReaderRead (reader); - - while (ret == 1) - { - const xmlChar *tag; - xmlReaderTypes type; - - tag = xmlTextReaderConstName (reader); - type = xmlTextReaderNodeType (reader); - - if (state == STATE_ENTRIES && - type == XML_READER_TYPE_ELEMENT && - xmlStrEqual (tag, iso_entry)) - { - read_entry_func (reader, user_data); - } - else if (state == STATE_START && - type == XML_READER_TYPE_ELEMENT && - xmlStrEqual (tag, iso_entries)) - { - state = STATE_ENTRIES; - } - else if (state == STATE_ENTRIES && - type == XML_READER_TYPE_END_ELEMENT && - xmlStrEqual (tag, iso_entries)) - { - state = STATE_STOP; - } - else if (type == XML_READER_TYPE_SIGNIFICANT_WHITESPACE || - type == XML_READER_TYPE_WHITESPACE || - type == XML_READER_TYPE_TEXT || - type == XML_READER_TYPE_COMMENT) - { - /* eat it */ - } - else - { - /* ignore it */ - } - - ret = xmlTextReaderRead (reader); - } - - xmlFreeTextReader (reader); - -out: - if (ret < 0 || state != STATE_STOP) - { - g_warning ("Failed to load ISO-%d codes from %s!\n", - iso, filename); - } - - g_free (filename); -} - -static GHashTable * -create_iso_639_table (void) -{ - GHashTable *table; - - bind_iso_domains (); - table = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) xmlFree, - (GDestroyNotify) xmlFree); - - load_iso_entries (639, (GFunc) read_iso_639_entry, table); - - return table; -} - -static GHashTable * -create_iso_3166_table (void) -{ - GHashTable *table; - - bind_iso_domains (); - table = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) xmlFree); - - load_iso_entries (3166, (GFunc) read_iso_3166_entry, table); - - return table; -} - -static char * -create_name_for_language (const char *code) -{ - char **str; - char *name = NULL; - const char *langname, *localename; - int len; - - g_return_val_if_fail (iso_639_table != NULL, NULL); - g_return_val_if_fail (iso_3166_table != NULL, NULL); - - str = g_strsplit (code, "_", -1); - len = g_strv_length (str); - g_return_val_if_fail (len != 0, NULL); - - langname = (const char *) g_hash_table_lookup (iso_639_table, str[0]); - - if (len == 1 && langname != NULL) - { - name = g_strdup (dgettext (ISO_639_DOMAIN, langname)); - } - else if (len == 2 && langname != NULL) - { - gchar *locale_code = g_ascii_strdown (str[1], -1); - - localename = (const char *) g_hash_table_lookup (iso_3166_table, locale_code); - g_free (locale_code); - - if (localename != NULL) - { - /* Translators: the first %s is the language name, and - * the second %s is the locale name. Example: - * "French (France)" - */ - name = g_strdup_printf (C_("language", "%s (%s)"), - dgettext (ISO_639_DOMAIN, langname), - dgettext (ISO_3166_DOMAIN, localename)); - } - else - { - name = g_strdup_printf (C_("language", "%s (%s)"), - dgettext (ISO_639_DOMAIN, langname), str[1]); - } - } - else - { - /* Translators: this refers to an unknown language code - * (one which isn't in our built-in list). - */ - name = g_strdup_printf (C_("language", "Unknown (%s)"), code); - } - - g_strfreev (str); - - return name; -} - -static void -enumerate_dicts (const char * const lang_tag, - const char * const provider_name, - const char * const provider_desc, - const char * const provider_file, - void * user_data) -{ - gchar *lang_name; - - GTree *dicts = (GTree *)user_data; - - lang_name = create_name_for_language (lang_tag); - g_return_if_fail (lang_name != NULL); - - /* g_print ("%s - %s\n", lang_tag, lang_name); */ - - g_tree_replace (dicts, g_strdup (lang_tag), lang_name); -} - -static gint -key_cmp (gconstpointer a, gconstpointer b, gpointer user_data) -{ - return strcmp (a, b); -} - -static gint -lang_cmp (const XedSpellCheckerLanguage *a, - const XedSpellCheckerLanguage *b) -{ - return g_utf8_collate (a->name, b->name); -} - -static gboolean -build_langs_list (const gchar *key, - const gchar *value, - gpointer data) -{ - XedSpellCheckerLanguage *lang = g_new (XedSpellCheckerLanguage, 1); - - lang->abrev = g_strdup (key); - lang->name = g_strdup (value); - - available_languages = g_slist_insert_sorted (available_languages, - lang, - (GCompareFunc)lang_cmp); - - return FALSE; -} - -const GSList * -xed_spell_checker_get_available_languages (void) -{ - EnchantBroker *broker; - GTree *dicts; - - if (available_languages_initialized) - return available_languages; - - g_return_val_if_fail (available_languages == NULL, NULL); - - available_languages_initialized = TRUE; - - broker = enchant_broker_init (); - g_return_val_if_fail (broker != NULL, NULL); - - /* Use a GTree to efficiently remove duplicates while building the list */ - dicts = g_tree_new_full (key_cmp, - NULL, - (GDestroyNotify)g_free, - (GDestroyNotify)g_free); - - iso_639_table = create_iso_639_table (); - iso_3166_table = create_iso_3166_table (); - - enchant_broker_list_dicts (broker, enumerate_dicts, dicts); - - enchant_broker_free (broker); - - g_hash_table_destroy (iso_639_table); - g_hash_table_destroy (iso_3166_table); - - iso_639_table = NULL; - iso_3166_table = NULL; - - g_tree_foreach (dicts, (GTraverseFunc)build_langs_list, NULL); - - g_tree_destroy (dicts); - - return available_languages; -} - -const gchar * -xed_spell_checker_language_to_string (const XedSpellCheckerLanguage *lang) -{ - if (lang == NULL) - /* Translators: this refers the Default language used by the - * spell checker - */ - return C_("language", "Default"); - - return lang->name; -} - -const gchar * -xed_spell_checker_language_to_key (const XedSpellCheckerLanguage *lang) -{ - g_return_val_if_fail (lang != NULL, NULL); - - return lang->abrev; -} - -const XedSpellCheckerLanguage * -xed_spell_checker_language_from_key (const gchar *key) -{ - const GSList *langs; - - g_return_val_if_fail (key != NULL, NULL); - - langs = xed_spell_checker_get_available_languages (); - - while (langs != NULL) - { - const XedSpellCheckerLanguage *l = (const XedSpellCheckerLanguage *)langs->data; - - if (g_ascii_strcasecmp (key, l->abrev) == 0) - return l; - - langs = g_slist_next (langs); - } - - return NULL; -} diff --git a/plugins/spell/xed-spell-checker-language.h b/plugins/spell/xed-spell-checker-language.h deleted file mode 100644 index 1976eb8..0000000 --- a/plugins/spell/xed-spell-checker-language.h +++ /dev/null @@ -1,51 +0,0 @@ -/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-spell-checker-language.h - * This file is part of xed - * - * Copyright (C) 2006 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2006. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -#ifndef __XED_SPELL_CHECKER_LANGUAGE_H__ -#define __XED_SPELL_CHECKER_LANGUAGE_H__ - -#include - -G_BEGIN_DECLS - -typedef struct _XedSpellCheckerLanguage XedSpellCheckerLanguage; - -const gchar *xed_spell_checker_language_to_string (const XedSpellCheckerLanguage *lang); - -const gchar *xed_spell_checker_language_to_key (const XedSpellCheckerLanguage *lang); - -const XedSpellCheckerLanguage *xed_spell_checker_language_from_key (const gchar *key); - -/* GSList contains "XedSpellCheckerLanguage*" items */ -const GSList *xed_spell_checker_get_available_languages - (void); - -G_END_DECLS - -#endif /* __XED_SPELL_CHECKER_LANGUAGE_H__ */ diff --git a/plugins/spell/xed-spell-checker.c b/plugins/spell/xed-spell-checker.c deleted file mode 100644 index 65d55fa..0000000 --- a/plugins/spell/xed-spell-checker.c +++ /dev/null @@ -1,564 +0,0 @@ -/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-spell-checker.c - * This file is part of xed - * - * Copyright (C) 2002-2006 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002-2006. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include - -#include -#include - -#include "xed-spell-checker.h" -#include "xed-spell-utils.h" -#include "xed-spell-marshal.h" - -struct _XedSpellChecker -{ - GObject parent_instance; - - EnchantDict *dict; - EnchantBroker *broker; - const XedSpellCheckerLanguage *active_lang; -}; - -/* GObject properties */ -enum { - PROP_0 = 0, - PROP_LANGUAGE, - LAST_PROP -}; - -/* Signals */ -enum { - ADD_WORD_TO_PERSONAL = 0, - ADD_WORD_TO_SESSION, - SET_LANGUAGE, - CLEAR_SESSION, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE(XedSpellChecker, xed_spell_checker, G_TYPE_OBJECT) - -static void -xed_spell_checker_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - /* - XedSpellChecker *spell = XED_SPELL_CHECKER (object); - */ - - switch (prop_id) - { - case PROP_LANGUAGE: - /* TODO */ - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -xed_spell_checker_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - /* - XedSpellChecker *spell = XED_SPELL_CHECKER (object); - */ - - switch (prop_id) - { - case PROP_LANGUAGE: - /* TODO */ - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -xed_spell_checker_finalize (GObject *object) -{ - XedSpellChecker *spell_checker; - - g_return_if_fail (XED_IS_SPELL_CHECKER (object)); - - spell_checker = XED_SPELL_CHECKER (object); - - if (spell_checker->dict != NULL) - { - enchant_broker_free_dict (spell_checker->broker, spell_checker->dict); - } - - if (spell_checker->broker != NULL) - { - enchant_broker_free (spell_checker->broker); - } - - G_OBJECT_CLASS (xed_spell_checker_parent_class)->finalize (object); -} - -static void -xed_spell_checker_class_init (XedSpellCheckerClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - - object_class->set_property = xed_spell_checker_set_property; - object_class->get_property = xed_spell_checker_get_property; - - object_class->finalize = xed_spell_checker_finalize; - - g_object_class_install_property (object_class, - PROP_LANGUAGE, - g_param_spec_pointer ("language", - "Language", - "The language used by the spell checker", - G_PARAM_READWRITE)); - - signals[ADD_WORD_TO_PERSONAL] = - g_signal_new ("add_word_to_personal", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedSpellCheckerClass, add_word_to_personal), - NULL, NULL, - xed_marshal_VOID__STRING_INT, - G_TYPE_NONE, - 2, - G_TYPE_STRING, - G_TYPE_INT); - - signals[ADD_WORD_TO_SESSION] = - g_signal_new ("add_word_to_session", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedSpellCheckerClass, add_word_to_session), - NULL, NULL, - xed_marshal_VOID__STRING_INT, - G_TYPE_NONE, - 2, - G_TYPE_STRING, - G_TYPE_INT); - - signals[SET_LANGUAGE] = - g_signal_new ("set_language", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedSpellCheckerClass, set_language), - NULL, NULL, - xed_marshal_VOID__POINTER, - G_TYPE_NONE, - 1, - G_TYPE_POINTER); - - signals[CLEAR_SESSION] = - g_signal_new ("clear_session", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedSpellCheckerClass, clear_session), - NULL, NULL, - xed_marshal_VOID__VOID, - G_TYPE_NONE, - 0); -} - -static void -xed_spell_checker_init (XedSpellChecker *spell_checker) -{ - spell_checker->broker = enchant_broker_init (); - spell_checker->dict = NULL; - spell_checker->active_lang = NULL; -} - -XedSpellChecker * -xed_spell_checker_new (void) -{ - XedSpellChecker *spell; - - spell = XED_SPELL_CHECKER (g_object_new (XED_TYPE_SPELL_CHECKER, NULL)); - - g_return_val_if_fail (spell != NULL, NULL); - - return spell; -} - -static gboolean -lazy_init (XedSpellChecker *spell, - const XedSpellCheckerLanguage *language) -{ - if (spell->dict != NULL) - { - return TRUE; - } - - g_return_val_if_fail (spell->broker != NULL, FALSE); - - spell->active_lang = NULL; - - if (language != NULL) - { - spell->active_lang = language; - } - else - { - /* First try to get a default language */ - const XedSpellCheckerLanguage *l; - gint i = 0; - const gchar * const *lang_tags = g_get_language_names (); - - while (lang_tags [i]) - { - l = xed_spell_checker_language_from_key (lang_tags [i]); - - if (l != NULL) - { - spell->active_lang = l; - break; - } - - i++; - } - } - - /* Second try to get a default language */ - if (spell->active_lang == NULL) - { - spell->active_lang = xed_spell_checker_language_from_key ("en_US"); - } - - /* Last try to get a default language */ - if (spell->active_lang == NULL) - { - const GSList *langs; - langs = xed_spell_checker_get_available_languages (); - if (langs != NULL) - { - spell->active_lang = (const XedSpellCheckerLanguage *)langs->data; - } - } - - if (spell->active_lang != NULL) - { - const gchar *key; - - key = xed_spell_checker_language_to_key (spell->active_lang); - - spell->dict = enchant_broker_request_dict (spell->broker, key); - } - - if (spell->dict == NULL) - { - spell->active_lang = NULL; - - if (language != NULL) - { - g_warning ("Spell checker plugin: cannot select a default language."); - } - - return FALSE; - } - - return TRUE; -} - -gboolean -xed_spell_checker_set_language (XedSpellChecker *spell, - const XedSpellCheckerLanguage *language) -{ - gboolean ret; - - g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE); - - if (spell->dict != NULL) - { - enchant_broker_free_dict (spell->broker, spell->dict); - spell->dict = NULL; - } - - ret = lazy_init (spell, language); - - if (ret) - { - g_signal_emit (G_OBJECT (spell), signals[SET_LANGUAGE], 0, language); - } - else - { - g_warning ("Spell checker plugin: cannot use language %s.", xed_spell_checker_language_to_string (language)); - } - - return ret; -} - -const XedSpellCheckerLanguage * -xed_spell_checker_get_language (XedSpellChecker *spell) -{ - g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), NULL); - - if (!lazy_init (spell, spell->active_lang)) - { - return NULL; - } - - return spell->active_lang; -} - -gboolean -xed_spell_checker_check_word (XedSpellChecker *spell, - const gchar *word, - gssize len) -{ - gint enchant_result; - gboolean res = FALSE; - - g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE); - g_return_val_if_fail (word != NULL, FALSE); - - if (!lazy_init (spell, spell->active_lang)) - { - return FALSE; - } - - if (len < 0) - { - len = strlen (word); - } - - if (strcmp (word, "xed") == 0) - { - return TRUE; - } - - if (xed_spell_utils_is_digit (word, len)) - { - return TRUE; - } - - g_return_val_if_fail (spell->dict != NULL, FALSE); - enchant_result = enchant_dict_check (spell->dict, word, len); - - switch (enchant_result) - { - case -1: - /* error */ - res = FALSE; - - g_warning ("Spell checker plugin: error checking word '%s' (%s).", - word, enchant_dict_get_error (spell->dict)); - - break; - case 1: - /* it is not in the directory */ - res = FALSE; - break; - case 0: - /* is is in the directory */ - res = TRUE; - break; - default: - g_return_val_if_reached (FALSE); - } - - return res; -} - - -/* return NULL on error or if no suggestions are found */ -GSList * -xed_spell_checker_get_suggestions (XedSpellChecker *spell, - const gchar *word, - gssize len) -{ - gchar **suggestions; - size_t n_suggestions = 0; - GSList *suggestions_list = NULL; - gint i; - - g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), NULL); - g_return_val_if_fail (word != NULL, NULL); - - if (!lazy_init (spell, spell->active_lang)) - { - return NULL; - } - - g_return_val_if_fail (spell->dict != NULL, NULL); - - if (len < 0) - { - len = strlen (word); - } - - suggestions = enchant_dict_suggest (spell->dict, word, len, &n_suggestions); - - if (n_suggestions == 0) - { - return NULL; - } - - g_return_val_if_fail (suggestions != NULL, NULL); - - for (i = 0; i < (gint)n_suggestions; i++) - { - suggestions_list = g_slist_prepend (suggestions_list, suggestions[i]); - } - - /* The single suggestions will be freed by the caller */ - g_free (suggestions); - - suggestions_list = g_slist_reverse (suggestions_list); - - return suggestions_list; -} - -gboolean -xed_spell_checker_add_word_to_personal (XedSpellChecker *spell, - const gchar *word, - gssize len) -{ - g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE); - g_return_val_if_fail (word != NULL, FALSE); - - if (!lazy_init (spell, spell->active_lang)) - { - return FALSE; - } - - g_return_val_if_fail (spell->dict != NULL, FALSE); - - if (len < 0) - { - len = strlen (word); - } - - enchant_dict_add (spell->dict, word, len); - - g_signal_emit (G_OBJECT (spell), signals[ADD_WORD_TO_PERSONAL], 0, word, len); - - return TRUE; -} - -gboolean -xed_spell_checker_add_word_to_session (XedSpellChecker *spell, - const gchar *word, - gssize len) -{ - g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE); - g_return_val_if_fail (word != NULL, FALSE); - - if (!lazy_init (spell, spell->active_lang)) - { - return FALSE; - } - - g_return_val_if_fail (spell->dict != NULL, FALSE); - - if (len < 0) - { - len = strlen (word); - } - - enchant_dict_add_to_session (spell->dict, word, len); - - g_signal_emit (G_OBJECT (spell), signals[ADD_WORD_TO_SESSION], 0, word, len); - - return TRUE; -} - -gboolean -xed_spell_checker_clear_session (XedSpellChecker *spell) -{ - g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE); - - /* free and re-request dictionary */ - if (spell->dict != NULL) - { - enchant_broker_free_dict (spell->broker, spell->dict); - spell->dict = NULL; - } - - if (!lazy_init (spell, spell->active_lang)) - { - return FALSE; - } - - g_signal_emit (G_OBJECT (spell), signals[CLEAR_SESSION], 0); - - return TRUE; -} - -/* - * Informs dictionary, that word 'word' will be replaced/corrected by word - * 'replacement' - */ -gboolean -xed_spell_checker_set_correction (XedSpellChecker *spell, - const gchar *word, - gssize w_len, - const gchar *replacement, - gssize r_len) -{ - g_return_val_if_fail (XED_IS_SPELL_CHECKER (spell), FALSE); - g_return_val_if_fail (word != NULL, FALSE); - g_return_val_if_fail (replacement != NULL, FALSE); - - if (!lazy_init (spell, spell->active_lang)) - { - return FALSE; - } - - g_return_val_if_fail (spell->dict != NULL, FALSE); - - if (w_len < 0) - { - w_len = strlen (word); - } - - if (r_len < 0) - { - r_len = strlen (replacement); - } - - enchant_dict_store_replacement (spell->dict, - word, - w_len, - replacement, - r_len); - - return TRUE; -} - diff --git a/plugins/spell/xed-spell-checker.h b/plugins/spell/xed-spell-checker.h deleted file mode 100644 index 1e6ad50..0000000 --- a/plugins/spell/xed-spell-checker.h +++ /dev/null @@ -1,109 +0,0 @@ -/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-spell-checker.h - * This file is part of xed - * - * Copyright (C) 2002-2006 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -#ifndef __XED_SPELL_CHECKER_H__ -#define __XED_SPELL_CHECKER_H__ - -#include -#include - -#include "xed-spell-checker-language.h" - -G_BEGIN_DECLS - -#define XED_TYPE_SPELL_CHECKER (xed_spell_checker_get_type ()) -#define XED_SPELL_CHECKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_SPELL_CHECKER, XedSpellChecker)) -#define XED_SPELL_CHECKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_SPELL_CHECKER, XedSpellChecker)) -#define XED_IS_SPELL_CHECKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_SPELL_CHECKER)) -#define XED_IS_SPELL_CHECKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_SPELL_CHECKER)) -#define XED_SPELL_CHECKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_SPELL_CHECKER, XedSpellChecker)) - -typedef struct _XedSpellChecker XedSpellChecker; - -typedef struct _XedSpellCheckerClass XedSpellCheckerClass; - -struct _XedSpellCheckerClass -{ - GObjectClass parent_class; - - /* Signals */ - void (*add_word_to_personal) (XedSpellChecker *spell, - const gchar *word, - gint len); - - void (*add_word_to_session) (XedSpellChecker *spell, - const gchar *word, - gint len); - - void (*set_language) (XedSpellChecker *spell, - const XedSpellCheckerLanguage *lang); - - void (*clear_session) (XedSpellChecker *spell); -}; - - -GType xed_spell_checker_get_type (void) G_GNUC_CONST; - -/* Constructors */ -XedSpellChecker *xed_spell_checker_new (void); - -gboolean xed_spell_checker_set_language (XedSpellChecker *spell, - const XedSpellCheckerLanguage *lang); -const XedSpellCheckerLanguage - *xed_spell_checker_get_language (XedSpellChecker *spell); - -gboolean xed_spell_checker_check_word (XedSpellChecker *spell, - const gchar *word, - gssize len); - -GSList *xed_spell_checker_get_suggestions (XedSpellChecker *spell, - const gchar *word, - gssize len); - -gboolean xed_spell_checker_add_word_to_personal - (XedSpellChecker *spell, - const gchar *word, - gssize len); - -gboolean xed_spell_checker_add_word_to_session - (XedSpellChecker *spell, - const gchar *word, - gssize len); - -gboolean xed_spell_checker_clear_session (XedSpellChecker *spell); - -gboolean xed_spell_checker_set_correction (XedSpellChecker *spell, - const gchar *word, - gssize w_len, - const gchar *replacement, - gssize r_len); -G_END_DECLS - -#endif /* __XED_SPELL_CHECKER_H__ */ - diff --git a/plugins/spell/xed-spell-language-dialog.c b/plugins/spell/xed-spell-language-dialog.c deleted file mode 100644 index 452447a..0000000 --- a/plugins/spell/xed-spell-language-dialog.c +++ /dev/null @@ -1,284 +0,0 @@ -/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-spell-language-dialog.c - * This file is part of xed - * - * Copyright (C) 2002 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include "xed-spell-language-dialog.h" -#include "xed-spell-checker-language.h" - - -enum -{ - COLUMN_LANGUAGE_NAME = 0, - COLUMN_LANGUAGE_POINTER, - ENCODING_NUM_COLS -}; - - -struct _XedSpellLanguageDialog -{ - GtkDialog dialog; - - GtkWidget *languages_treeview; - GtkTreeModel *model; -}; - -G_DEFINE_TYPE (XedSpellLanguageDialog, xed_spell_language_dialog, GTK_TYPE_DIALOG) - - -static void -xed_spell_language_dialog_class_init (XedSpellLanguageDialogClass *klass) -{ - /* GObjectClass *object_class = G_OBJECT_CLASS (klass); */ -} - -static void -dialog_response_handler (GtkDialog *dlg, - gint res_id) -{ - if (res_id == GTK_RESPONSE_HELP) - { - xed_app_show_help (XED_APP (g_application_get_default ()), GTK_WINDOW (dlg), NULL, "xed-spell-checker-plugin"); - - g_signal_stop_emission_by_name (dlg, "response"); - } -} - -static void -scroll_to_selected (GtkTreeView *tree_view) -{ - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - - model = gtk_tree_view_get_model (tree_view); - g_return_if_fail (model != NULL); - - /* Scroll to selected */ - selection = gtk_tree_view_get_selection (tree_view); - g_return_if_fail (selection != NULL); - - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - GtkTreePath* path; - - path = gtk_tree_model_get_path (model, &iter); - g_return_if_fail (path != NULL); - - gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 1.0, 0.0); - gtk_tree_path_free (path); - } -} - -static void -language_row_activated (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - XedSpellLanguageDialog *dialog) -{ - gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); -} - -static void -create_dialog (XedSpellLanguageDialog *dlg, - const gchar *data_dir) -{ - GtkWidget *error_widget; - GtkWidget *content; - gboolean ret; - GtkCellRenderer *cell; - GtkTreeViewColumn *column; - gchar *ui_file; - gchar *root_objects[] = { - "content", - NULL - }; - - gtk_dialog_add_buttons (GTK_DIALOG (dlg), - _("_Cancel"), GTK_RESPONSE_CANCEL, - _("_OK"), GTK_RESPONSE_OK, - _("_Help"), GTK_RESPONSE_HELP, - NULL); - - gtk_window_set_title (GTK_WINDOW (dlg), _("Set language")); - gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); - gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE); - - /* HIG defaults */ - gtk_container_set_border_width (GTK_CONTAINER (dlg), 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), 2); - gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), 5); - gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dlg))), 6); - - g_signal_connect (dlg, "response", - G_CALLBACK (dialog_response_handler), NULL); - - ui_file = g_build_filename (data_dir, "languages-dialog.ui", NULL); - ret = xed_utils_get_ui_objects (ui_file, - root_objects, - &error_widget, - "content", &content, - "languages_treeview", &dlg->languages_treeview, - NULL); - g_free (ui_file); - - if (!ret) - { - gtk_widget_show (error_widget); - - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), error_widget, TRUE, TRUE, 0); - - return; - } - - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), content, TRUE, TRUE, 0); - g_object_unref (content); - gtk_container_set_border_width (GTK_CONTAINER (content), 5); - - dlg->model = GTK_TREE_MODEL (gtk_list_store_new (ENCODING_NUM_COLS, G_TYPE_STRING, G_TYPE_POINTER)); - - gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->languages_treeview), dlg->model); - - g_object_unref (dlg->model); - - /* Add the encoding column */ - cell = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes (_("Languages"), - cell, - "text", - COLUMN_LANGUAGE_NAME, - NULL); - - gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->languages_treeview), column); - - gtk_tree_view_set_search_column (GTK_TREE_VIEW (dlg->languages_treeview), COLUMN_LANGUAGE_NAME); - - g_signal_connect (dlg->languages_treeview, "realize", - G_CALLBACK (scroll_to_selected), dlg); - g_signal_connect (dlg->languages_treeview, "row-activated", - G_CALLBACK (language_row_activated), dlg); -} - -static void -xed_spell_language_dialog_init (XedSpellLanguageDialog *dlg) -{ - -} - -static void -populate_language_list (XedSpellLanguageDialog *dlg, - const XedSpellCheckerLanguage *cur_lang) -{ - GtkListStore *store; - GtkTreeIter iter; - - const GSList* langs; - - /* create list store */ - store = GTK_LIST_STORE (dlg->model); - - langs = xed_spell_checker_get_available_languages (); - - while (langs) - { - const gchar *name; - - name = xed_spell_checker_language_to_string ((const XedSpellCheckerLanguage*)langs->data); - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - COLUMN_LANGUAGE_NAME, name, - COLUMN_LANGUAGE_POINTER, langs->data, - -1); - - if (langs->data == cur_lang) - { - GtkTreeSelection *selection; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->languages_treeview)); - g_return_if_fail (selection != NULL); - - gtk_tree_selection_select_iter (selection, &iter); - } - - langs = g_slist_next (langs); - } -} - -GtkWidget * -xed_spell_language_dialog_new (GtkWindow *parent, - const XedSpellCheckerLanguage *cur_lang, - const gchar *data_dir) -{ - XedSpellLanguageDialog *dlg; - - g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL); - - dlg = g_object_new (XED_TYPE_SPELL_LANGUAGE_DIALOG, NULL); - - create_dialog (dlg, data_dir); - - populate_language_list (dlg, cur_lang); - - gtk_window_set_transient_for (GTK_WINDOW (dlg), parent); - gtk_widget_grab_focus (dlg->languages_treeview); - - return GTK_WIDGET (dlg); -} - -const XedSpellCheckerLanguage * -xed_spell_language_get_selected_language (XedSpellLanguageDialog *dlg) -{ - GValue value = {0, }; - const XedSpellCheckerLanguage* lang; - - GtkTreeIter iter; - GtkTreeSelection *selection; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->languages_treeview)); - g_return_val_if_fail (selection != NULL, NULL); - - if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - return NULL; - } - - gtk_tree_model_get_value (dlg->model, &iter, COLUMN_LANGUAGE_POINTER, &value); - - lang = (const XedSpellCheckerLanguage* ) g_value_get_pointer (&value); - - return lang; -} - diff --git a/plugins/spell/xed-spell-language-dialog.h b/plugins/spell/xed-spell-language-dialog.h deleted file mode 100644 index b11c454..0000000 --- a/plugins/spell/xed-spell-language-dialog.h +++ /dev/null @@ -1,65 +0,0 @@ -/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * xed-spell-language-dialog.h - * This file is part of xed - * - * Copyright (C) 2002 Paolo Maggi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/* - * Modified by the xed Team, 2002. See the AUTHORS file for a - * list of people on the xed Team. - * See the ChangeLog files for a list of changes. - */ - -#ifndef __XED_SPELL_LANGUAGE_DIALOG_H__ -#define __XED_SPELL_LANGUAGE_DIALOG_H__ - -#include -#include "xed-spell-checker-language.h" - -G_BEGIN_DECLS - -#define XED_TYPE_SPELL_LANGUAGE_DIALOG (xed_spell_language_dialog_get_type()) -#define XED_SPELL_LANGUAGE_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XED_TYPE_SPELL_LANGUAGE_DIALOG, XedSpellLanguageDialog)) -#define XED_SPELL_LANGUAGE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XED_TYPE_SPELL_LANGUAGE_DIALOG, XedSpellLanguageDialogClass)) -#define XED_IS_SPELL_LANGUAGE_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XED_TYPE_SPELL_LANGUAGE_DIALOG)) -#define XED_IS_SPELL_LANGUAGE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_SPELL_LANGUAGE_DIALOG)) -#define XED_SPELL_LANGUAGE_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XED_TYPE_SPELL_LANGUAGE_DIALOG, XedSpellLanguageDialogClass)) - - -typedef struct _XedSpellLanguageDialog XedSpellLanguageDialog; -typedef struct _XedSpellLanguageDialogClass XedSpellLanguageDialogClass; - -struct _XedSpellLanguageDialogClass -{ - GtkDialogClass parent_class; -}; - -GType xed_spell_language_dialog_get_type (void) G_GNUC_CONST; - -GtkWidget *xed_spell_language_dialog_new (GtkWindow *parent, - const XedSpellCheckerLanguage *cur_lang, - const gchar *data_dir); - -const XedSpellCheckerLanguage *xed_spell_language_get_selected_language (XedSpellLanguageDialog *dlg); - -G_END_DECLS - -#endif /* __XED_SPELL_LANGUAGE_DIALOG_H__ */ - diff --git a/plugins/spell/xed-spell-plugin.c b/plugins/spell/xed-spell-plugin.c index 5dd72f9..7c4efdc 100644 --- a/plugins/spell/xed-spell-plugin.c +++ b/plugins/spell/xed-spell-plugin.c @@ -18,41 +18,29 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifdef HAVE_CONFIG_H #include -#endif #include "xed-spell-plugin.h" -#include "xed-spell-utils.h" #include /* For strlen */ #include #include +#include #include #include #include -#include #include -#include - -#include "xed-spell-checker.h" -#include "xed-spell-checker-dialog.h" -#include "xed-spell-language-dialog.h" -#include "xed-automatic-spell-checker.h" +#include #define XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE "metadata::xed-spell-language" #define XED_METADATA_ATTRIBUTE_SPELL_ENABLED "metadata::xed-spell-enabled" -#define XED_AUTOMATIC_SPELL_VIEW "XedAutomaticSpellView" +#define SPELL_ENABLED_STR "1" #define MENU_PATH "/MenuBar/ToolsMenu/ToolsOps_1" -#define XED_SPELL_PLUGIN_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ - XED_TYPE_SPELL_PLUGIN, \ - XedSpellPluginPrivate)) - /* GSettings keys */ #define SPELL_SCHEMA "org.x.editor.plugins.spell" #define AUTOCHECK_TYPE_KEY "autocheck-type" @@ -60,53 +48,38 @@ static void xed_window_activatable_iface_init (XedWindowActivatableInterface *iface); static void peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface); -G_DEFINE_DYNAMIC_TYPE_EXTENDED (XedSpellPlugin, - xed_spell_plugin, - PEAS_TYPE_EXTENSION_BASE, - 0, - G_IMPLEMENT_INTERFACE_DYNAMIC (XED_TYPE_WINDOW_ACTIVATABLE, - xed_window_activatable_iface_init) - G_IMPLEMENT_INTERFACE_DYNAMIC (PEAS_GTK_TYPE_CONFIGURABLE, - peas_gtk_configurable_iface_init)) - struct _XedSpellPluginPrivate { XedWindow *window; GtkActionGroup *action_group; guint ui_id; - guint message_cid; - gulong tab_added_id; - gulong tab_removed_id; GSettings *settings; }; -typedef struct _CheckRange CheckRange; - -struct _CheckRange -{ - GtkTextMark *start_mark; - GtkTextMark *end_mark; - - gint mw_start; /* misspelled word start */ - gint mw_end; /* end */ - - GtkTextMark *current_mark; -}; - enum { PROP_0, PROP_WINDOW }; -static void spell_cb (GtkAction *action, - XedSpellPlugin *plugin); +G_DEFINE_DYNAMIC_TYPE_EXTENDED (XedSpellPlugin, + xed_spell_plugin, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC (XED_TYPE_WINDOW_ACTIVATABLE, + xed_window_activatable_iface_init) + G_IMPLEMENT_INTERFACE_DYNAMIC (PEAS_GTK_TYPE_CONFIGURABLE, + peas_gtk_configurable_iface_init) + G_ADD_PRIVATE_DYNAMIC (XedSpellPlugin)) + +static void check_spell_cb (GtkAction *action, + XedSpellPlugin *plugin); static void set_language_cb (GtkAction *action, XedSpellPlugin *plugin); -static void auto_spell_cb (GtkAction *action, - XedSpellPlugin *plugin); +static void inline_checker_cb (GtkAction *action, + XedSpellPlugin *plugin); /* UI actions. */ static const GtkActionEntry action_entries[] = @@ -116,7 +89,7 @@ static const GtkActionEntry action_entries[] = N_("_Check Spelling..."), "F7", N_("Check the current document for incorrect spelling"), - G_CALLBACK (spell_cb) + G_CALLBACK (check_spell_cb) }, { "ConfigSpell", @@ -130,12 +103,12 @@ static const GtkActionEntry action_entries[] = static const GtkToggleActionEntry toggle_action_entries[] = { - { "AutoSpell", + { "InlineSpellChecker", NULL, N_("_Autocheck Spelling"), NULL, N_("Automatically spell-check the current document"), - G_CALLBACK (auto_spell_cb), + G_CALLBACK (inline_checker_cb), FALSE } }; @@ -160,37 +133,6 @@ typedef enum AUTOCHECK_ALWAYS } XedSpellPluginAutocheckType; - - -static GQuark spell_checker_id = 0; -static GQuark check_range_id = 0; - -static void -xed_spell_plugin_init (XedSpellPlugin *plugin) -{ - xed_debug_message (DEBUG_PLUGINS, "XedSpellPlugin initializing"); - - plugin->priv = G_TYPE_INSTANCE_GET_PRIVATE (plugin, XED_TYPE_SPELL_PLUGIN, XedSpellPluginPrivate); - - plugin->priv->settings = g_settings_new (SPELL_SCHEMA); -} - -static void -xed_spell_plugin_dispose (GObject *object) -{ - XedSpellPlugin *plugin = XED_SPELL_PLUGIN (object); - - xed_debug_message (DEBUG_PLUGINS, "XedSpellPlugin disposing"); - - g_clear_object (&plugin->priv->settings); - g_clear_object (&plugin->priv->window); - g_clear_object (&plugin->priv->action_group); - g_clear_object (&plugin->priv->settings); - - G_OBJECT_CLASS (xed_spell_plugin_parent_class)->dispose (object); -} - - static void xed_spell_plugin_set_property (GObject *object, guint prop_id, @@ -229,44 +171,94 @@ xed_spell_plugin_get_property (GObject *object, } } - static void -set_spell_language_cb (XedSpellChecker *spell, - const XedSpellCheckerLanguage *lang, - XedDocument *doc) +xed_spell_plugin_dispose (GObject *object) { - const gchar *key; + XedSpellPlugin *plugin = XED_SPELL_PLUGIN (object); - g_return_if_fail (XED_IS_DOCUMENT (doc)); - g_return_if_fail (lang != NULL); + xed_debug_message (DEBUG_PLUGINS, "XedSpellPlugin disposing"); - key = xed_spell_checker_language_to_key (lang); - g_return_if_fail (key != NULL); + g_clear_object (&plugin->priv->settings); + g_clear_object (&plugin->priv->window); + g_clear_object (&plugin->priv->action_group); + g_clear_object (&plugin->priv->settings); - xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE, key, NULL); + G_OBJECT_CLASS (xed_spell_plugin_parent_class)->dispose (object); } static void -set_language_from_metadata (XedSpellChecker *spell, - XedDocument *doc) +xed_spell_plugin_class_init (XedSpellPluginClass *klass) { - const XedSpellCheckerLanguage *lang = NULL; - gchar *value = NULL; + GObjectClass *object_class = G_OBJECT_CLASS (klass); - value = xed_document_get_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE); + object_class->dispose = xed_spell_plugin_dispose; + object_class->set_property = xed_spell_plugin_set_property; + object_class->get_property = xed_spell_plugin_get_property; - if (value != NULL) + g_object_class_override_property (object_class, PROP_WINDOW, "window"); +} + +static void +xed_spell_plugin_class_finalize (XedSpellPluginClass *klass) +{ +} + +static void +xed_spell_plugin_init (XedSpellPlugin *plugin) +{ + xed_debug_message (DEBUG_PLUGINS, "XedSpellPlugin initializing"); + + plugin->priv = xed_spell_plugin_get_instance_private (plugin); + + plugin->priv->settings = g_settings_new (SPELL_SCHEMA); +} + +static GspellChecker * +get_spell_checker (XedDocument *doc) +{ + GspellTextBuffer *gspell_buffer; + + gspell_buffer = gspell_text_buffer_get_from_gtk_text_buffer (GTK_TEXT_BUFFER (doc)); + return gspell_text_buffer_get_spell_checker (gspell_buffer); +} + +static const GspellLanguage * +get_language_from_metadata (XedDocument *doc) +{ + const GspellLanguage *lang = NULL; + gchar *language_code = NULL; + + language_code = xed_document_get_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE); + + if (language_code != NULL) { - lang = xed_spell_checker_language_from_key (value); - g_free (value); + lang = gspell_language_lookup (language_code); + g_free (language_code); } - if (lang != NULL) - { - g_signal_handlers_block_by_func (spell, set_spell_language_cb, doc); - xed_spell_checker_set_language (spell, lang); - g_signal_handlers_unblock_by_func (spell, set_spell_language_cb, doc); - } + return lang; +} + +static void +check_spell_cb (GtkAction *action, + XedSpellPlugin *plugin) +{ + XedSpellPluginPrivate *priv; + XedView *view; + GspellNavigator *navigator; + GtkWidget *dialog; + + xed_debug (DEBUG_PLUGINS); + + priv = plugin->priv; + + view = xed_window_get_active_view (priv->window); + g_return_if_fail (view != NULL); + + navigator = gspell_navigator_text_view_new (GTK_TEXT_VIEW (view)); + dialog = gspell_checker_dialog_new (GTK_WINDOW (priv->window), navigator); + + gtk_widget_show (dialog); } static XedSpellPluginAutocheckType @@ -291,507 +283,21 @@ set_autocheck_type (GSettings *settings, g_settings_set_enum (settings, AUTOCHECK_TYPE_KEY, autocheck_type); } -static XedSpellChecker * -get_spell_checker_from_document (XedDocument *doc) -{ - XedSpellChecker *spell; - gpointer data; - - xed_debug (DEBUG_PLUGINS); - - g_return_val_if_fail (doc != NULL, NULL); - - data = g_object_get_qdata (G_OBJECT (doc), spell_checker_id); - - if (data == NULL) - { - spell = xed_spell_checker_new (); - - set_language_from_metadata (spell, doc); - - g_object_set_qdata_full (G_OBJECT (doc), - spell_checker_id, - spell, - (GDestroyNotify) g_object_unref); - - g_signal_connect (spell, "set_language", - G_CALLBACK (set_spell_language_cb), doc); - } - else - { - g_return_val_if_fail (XED_IS_SPELL_CHECKER (data), NULL); - spell = XED_SPELL_CHECKER (data); - } - - return spell; -} - -static CheckRange * -get_check_range (XedDocument *doc) -{ - CheckRange *range; - - xed_debug (DEBUG_PLUGINS); - - g_return_val_if_fail (doc != NULL, NULL); - - range = (CheckRange *) g_object_get_qdata (G_OBJECT (doc), check_range_id); - - return range; -} - static void -update_current (XedDocument *doc, - gint current) +language_dialog_response_cb (GtkDialog *dialog, + gint response_id, + gpointer user_data) { - CheckRange *range; - GtkTextIter iter; - GtkTextIter end_iter; - - xed_debug (DEBUG_PLUGINS); - - g_return_if_fail (doc != NULL); - g_return_if_fail (current >= 0); - - range = get_check_range (doc); - g_return_if_fail (range != NULL); - - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &iter, current); - - if (!gtk_text_iter_inside_word (&iter)) + if (response_id == GTK_RESPONSE_HELP) { - /* if we're not inside a word, - * we must be in some spaces. - * skip forward to the beginning of the next word. */ - if (!gtk_text_iter_is_end (&iter)) - { - gtk_text_iter_forward_word_end (&iter); - gtk_text_iter_backward_word_start (&iter); - } - } - else - { - if (!gtk_text_iter_starts_word (&iter)) - { - gtk_text_iter_backward_word_start (&iter); - } - } - - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), &end_iter, range->end_mark); - - if (gtk_text_iter_compare (&end_iter, &iter) < 0) - { - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->current_mark, &end_iter); - } - else - { - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->current_mark, &iter); - } -} - -static void -set_check_range (XedDocument *doc, - GtkTextIter *start, - GtkTextIter *end) -{ - CheckRange *range; - GtkTextIter iter; - - xed_debug (DEBUG_PLUGINS); - - range = get_check_range (doc); - - if (range == NULL) - { - xed_debug_message (DEBUG_PLUGINS, "There was not a previous check range"); - - gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &iter); - - range = g_new0 (CheckRange, 1); - - range->start_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), - "check_range_start_mark", &iter, TRUE); - - range->end_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), - "check_range_end_mark", &iter, FALSE); - - range->current_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), - "check_range_current_mark", &iter, TRUE); - - g_object_set_qdata_full (G_OBJECT (doc), check_range_id, range, (GDestroyNotify)g_free); - } - - if (xed_spell_utils_skip_no_spell_check (start, end)) - { - if (!gtk_text_iter_inside_word (end)) - { - /* if we're neither inside a word, - * we must be in some spaces. - * skip backward to the end of the previous word. */ - if (!gtk_text_iter_is_end (end)) - { - gtk_text_iter_backward_word_start (end); - gtk_text_iter_forward_word_end (end); - } - } - else - { - if (!gtk_text_iter_ends_word (end)) - { - gtk_text_iter_forward_word_end (end); - } - } - } - else - { - /* no spell checking in the specified range */ - start = end; - } - - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->start_mark, start); - gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->end_mark, end); - - range->mw_start = -1; - range->mw_end = -1; - - update_current (doc, gtk_text_iter_get_offset (start)); -} - -static gchar * -get_current_word (XedDocument *doc, - gint *start, - gint *end) -{ - const CheckRange *range; - GtkTextIter end_iter; - GtkTextIter current_iter; - gint range_end; - - xed_debug (DEBUG_PLUGINS); - - g_return_val_if_fail (doc != NULL, NULL); - g_return_val_if_fail (start != NULL, NULL); - g_return_val_if_fail (end != NULL, NULL); - - range = get_check_range (doc); - g_return_val_if_fail (range != NULL, NULL); - - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), &end_iter, range->end_mark); - - range_end = gtk_text_iter_get_offset (&end_iter); - - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), ¤t_iter, range->current_mark); - - end_iter = current_iter; - - if (!gtk_text_iter_is_end (&end_iter)) - { - xed_debug_message (DEBUG_PLUGINS, "Current is not end"); - - gtk_text_iter_forward_word_end (&end_iter); - } - - *start = gtk_text_iter_get_offset (¤t_iter); - *end = MIN (gtk_text_iter_get_offset (&end_iter), range_end); - - xed_debug_message (DEBUG_PLUGINS, "Current word extends [%d, %d]", *start, *end); - - if (!(*start < *end)) - { - return NULL; - } - - return gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), ¤t_iter, &end_iter, TRUE); -} - -static gboolean -goto_next_word (XedDocument *doc) -{ - CheckRange *range; - GtkTextIter current_iter; - GtkTextIter old_current_iter; - GtkTextIter end_iter; - - xed_debug (DEBUG_PLUGINS); - - g_return_val_if_fail (doc != NULL, FALSE); - - range = get_check_range (doc); - g_return_val_if_fail (range != NULL, FALSE); - - gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), ¤t_iter, range->current_mark); - gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &end_iter); - - old_current_iter = current_iter; - - gtk_text_iter_forward_word_ends (¤t_iter, 2); - gtk_text_iter_backward_word_start (¤t_iter); - - if (xed_spell_utils_skip_no_spell_check (¤t_iter, &end_iter) && - (gtk_text_iter_compare (&old_current_iter, ¤t_iter) < 0) && - (gtk_text_iter_compare (¤t_iter, &end_iter) < 0)) - { - update_current (doc, gtk_text_iter_get_offset (¤t_iter)); - return TRUE; - } - - return FALSE; -} - -static gchar * -get_next_misspelled_word (XedView *view) -{ - XedDocument *doc; - CheckRange *range; - gint start, end; - gchar *word; - XedSpellChecker *spell; - - g_return_val_if_fail (view != NULL, NULL); - - doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - g_return_val_if_fail (doc != NULL, NULL); - - range = get_check_range (doc); - g_return_val_if_fail (range != NULL, NULL); - - spell = get_spell_checker_from_document (doc); - g_return_val_if_fail (spell != NULL, NULL); - - word = get_current_word (doc, &start, &end); - if (word == NULL) - { - return NULL; - } - - xed_debug_message (DEBUG_PLUGINS, "Word to check: %s", word); - - while (xed_spell_checker_check_word (spell, word, -1)) - { - g_free (word); - - if (!goto_next_word (doc)) - { - return NULL; - } - - /* may return null if we reached the end of the selection */ - word = get_current_word (doc, &start, &end); - if (word == NULL) - { - return NULL; - } - - xed_debug_message (DEBUG_PLUGINS, "Word to check: %s", word); - } - - if (!goto_next_word (doc)) - { - update_current (doc, gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (doc))); - } - - if (word != NULL) - { - GtkTextIter s, e; - - range->mw_start = start; - range->mw_end = end; - - xed_debug_message (DEBUG_PLUGINS, "Select [%d, %d]", start, end); - - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &s, start); - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &e, end); - - gtk_text_buffer_select_range (GTK_TEXT_BUFFER (doc), &s, &e); - - xed_view_scroll_to_cursor (view); - } - else - { - range->mw_start = -1; - range->mw_end = -1; - } - - return word; -} - -static void -ignore_cb (XedSpellCheckerDialog *dlg, - const gchar *w, - XedView *view) -{ - gchar *word = NULL; - - xed_debug (DEBUG_PLUGINS); - - g_return_if_fail (w != NULL); - g_return_if_fail (view != NULL); - - word = get_next_misspelled_word (view); - if (word == NULL) - { - xed_spell_checker_dialog_set_completed (dlg); - + xed_app_show_help (XED_APP (g_application_get_default ()), + GTK_WINDOW (dialog), + NULL, + "xed-spellcheck"); return; } - xed_spell_checker_dialog_set_misspelled_word (XED_SPELL_CHECKER_DIALOG (dlg), word, -1); - - g_free (word); -} - -static void -change_cb (XedSpellCheckerDialog *dlg, - const gchar *word, - const gchar *change, - XedView *view) -{ - XedDocument *doc; - CheckRange *range; - gchar *w = NULL; - GtkTextIter start, end; - - xed_debug (DEBUG_PLUGINS); - - g_return_if_fail (view != NULL); - g_return_if_fail (word != NULL); - g_return_if_fail (change != NULL); - - doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - g_return_if_fail (doc != NULL); - - range = get_check_range (doc); - g_return_if_fail (range != NULL); - - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &start, range->mw_start); - if (range->mw_end < 0) - { - gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &end); - } - else - { - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &end, range->mw_end); - } - - w = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), &start, &end, TRUE); - g_return_if_fail (w != NULL); - - if (strcmp (w, word) != 0) - { - g_free (w); - return; - } - - g_free (w); - - gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER(doc)); - - gtk_text_buffer_delete (GTK_TEXT_BUFFER (doc), &start, &end); - gtk_text_buffer_insert (GTK_TEXT_BUFFER (doc), &start, change, -1); - - gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER(doc)); - - update_current (doc, range->mw_start + g_utf8_strlen (change, -1)); - - /* go to next misspelled word */ - ignore_cb (dlg, word, view); -} - -static void -change_all_cb (XedSpellCheckerDialog *dlg, - const gchar *word, - const gchar *change, - XedView *view) -{ - XedDocument *doc; - CheckRange *range; - gchar *w = NULL; - GtkTextIter start, end; - GtkSourceSearchSettings *search_settings; - GtkSourceSearchContext *search_context; - - xed_debug (DEBUG_PLUGINS); - - g_return_if_fail (view != NULL); - g_return_if_fail (word != NULL); - g_return_if_fail (change != NULL); - - doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - g_return_if_fail (doc != NULL); - - range = get_check_range (doc); - g_return_if_fail (range != NULL); - - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &start, range->mw_start); - if (range->mw_end < 0) - { - gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &end); - } - else - { - gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &end, range->mw_end); - } - - w = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), &start, &end, TRUE); - g_return_if_fail (w != NULL); - - if (strcmp (w, word) != 0) - { - g_free (w); - return; - } - - g_free (w); - - search_settings = gtk_source_search_settings_new (); - gtk_source_search_settings_set_case_sensitive (search_settings, TRUE); - gtk_source_search_settings_set_at_word_boundaries (search_settings, TRUE); - gtk_source_search_settings_set_search_text (search_settings, word); - - search_context = gtk_source_search_context_new (GTK_SOURCE_BUFFER (doc), search_settings); - - gtk_source_search_context_set_highlight (search_context, FALSE); - - gtk_source_search_context_replace_all (search_context, change, -1, NULL); - - update_current (doc, range->mw_start + g_utf8_strlen (change, -1)); - - /* go to next misspelled word */ - ignore_cb (dlg, word, view); - - g_object_unref (search_settings); - g_object_unref (search_context); -} - -static void -add_word_cb (XedSpellCheckerDialog *dlg, - const gchar *word, - XedView *view) -{ - g_return_if_fail (view != NULL); - g_return_if_fail (word != NULL); - - /* go to next misspelled word */ - ignore_cb (dlg, word, view); -} - -static void -language_dialog_response (GtkDialog *dlg, - gint res_id, - XedSpellChecker *spell) -{ - if (res_id == GTK_RESPONSE_OK) - { - const XedSpellCheckerLanguage *lang; - - lang = xed_spell_language_get_selected_language (XED_SPELL_LANGUAGE_DIALOG (dlg)); - if (lang != NULL) - { - xed_spell_checker_set_language (spell, lang); - } - } - - gtk_widget_destroy (GTK_WIDGET (dlg)); + gtk_widget_destroy (GTK_WIDGET (dialog)); } static void @@ -899,11 +405,10 @@ set_language_cb (GtkAction *action, { XedSpellPluginPrivate *priv; XedDocument *doc; - XedSpellChecker *spell; - const XedSpellCheckerLanguage *lang; - GtkWidget *dlg; - GtkWindowGroup *wg; - gchar *data_dir; + GspellChecker *checker; + const GspellLanguage *lang; + GtkWidget *dialog; + GtkWindowGroup *window_group; xed_debug (DEBUG_PLUGINS); @@ -912,145 +417,38 @@ set_language_cb (GtkAction *action, doc = xed_window_get_active_document (priv->window); g_return_if_fail (doc != NULL); - spell = get_spell_checker_from_document (doc); - g_return_if_fail (spell != NULL); + checker = get_spell_checker (doc); + g_return_if_fail (checker != NULL); - lang = xed_spell_checker_get_language (spell); + lang = gspell_checker_get_language (checker); - data_dir = peas_extension_base_get_data_dir (PEAS_EXTENSION_BASE (plugin)); - dlg = xed_spell_language_dialog_new (GTK_WINDOW (priv->window), lang, data_dir); - g_free (data_dir); + dialog = gspell_language_chooser_dialog_new (GTK_WINDOW (priv->window), + lang, + GTK_DIALOG_MODAL | + GTK_DIALOG_DESTROY_WITH_PARENT); - wg = xed_window_get_group (priv->window); + g_object_bind_property (dialog, "language", + checker, "language", + G_BINDING_DEFAULT); - gtk_window_group_add_window (wg, GTK_WINDOW (dlg)); + window_group = xed_window_get_group (priv->window); - gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); + gtk_window_group_add_window (window_group, GTK_WINDOW (dialog)); - g_signal_connect (dlg, "response", - G_CALLBACK (language_dialog_response), spell); + gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Help"), GTK_RESPONSE_HELP); - gtk_widget_show (dlg); + g_signal_connect (dialog, "response", + G_CALLBACK (language_dialog_response_cb), NULL); + + gtk_widget_show (dialog); } static void -spell_cb (GtkAction *action, - XedSpellPlugin *plugin) +inline_checker_cb (GtkAction *action, + XedSpellPlugin *plugin) { XedSpellPluginPrivate *priv; XedView *view; - XedDocument *doc; - XedSpellChecker *spell; - GtkWidget *dlg; - GtkTextIter start, end; - gchar *word; - gchar *data_dir; - - xed_debug (DEBUG_PLUGINS); - - priv = plugin->priv; - - view = xed_window_get_active_view (priv->window); - g_return_if_fail (view != NULL); - - doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - g_return_if_fail (doc != NULL); - - spell = get_spell_checker_from_document (doc); - g_return_if_fail (spell != NULL); - - if (gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (doc)) <= 0) - { - GtkWidget *statusbar; - - statusbar = xed_window_get_statusbar (priv->window); - xed_statusbar_flash_message (XED_STATUSBAR (statusbar), priv->message_cid, _("The document is empty.")); - - return; - } - - if (!gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), &start, &end)) - { - /* no selection, get the whole doc */ - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc), &start, &end); - } - - set_check_range (doc, &start, &end); - - word = get_next_misspelled_word (view); - if (word == NULL) - { - GtkWidget *statusbar; - - statusbar = xed_window_get_statusbar (priv->window); - xed_statusbar_flash_message (XED_STATUSBAR (statusbar), priv->message_cid, _("No misspelled words")); - - return; - } - - data_dir = peas_extension_base_get_data_dir (PEAS_EXTENSION_BASE (plugin)); - dlg = xed_spell_checker_dialog_new_from_spell_checker (spell, data_dir); - g_free (data_dir); - - gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); - gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (priv->window)); - - g_signal_connect (dlg, "ignore", G_CALLBACK (ignore_cb), view); - g_signal_connect (dlg, "ignore_all", G_CALLBACK (ignore_cb), view); - - g_signal_connect (dlg, "change", G_CALLBACK (change_cb), view); - g_signal_connect (dlg, "change_all", G_CALLBACK (change_all_cb), view); - - g_signal_connect (dlg, "add_word_to_personal", G_CALLBACK (add_word_cb), view); - - xed_spell_checker_dialog_set_misspelled_word (XED_SPELL_CHECKER_DIALOG (dlg), word, -1); - - g_free (word); - - gtk_widget_show (dlg); -} - -static void -set_auto_spell (XedWindow *window, - XedView *view, - gboolean active) -{ - XedAutomaticSpellChecker *autospell; - XedSpellChecker *spell; - XedDocument *doc; - - doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - - spell = get_spell_checker_from_document (doc); - g_return_if_fail (spell != NULL); - - autospell = xed_automatic_spell_checker_get_from_document (doc); - - if (active) - { - if (autospell == NULL) - { - autospell = xed_automatic_spell_checker_new (doc, spell); - xed_automatic_spell_checker_attach_view (autospell, view); - xed_automatic_spell_checker_recheck_all (autospell); - } - } - else - { - if (autospell != NULL) - { - xed_automatic_spell_checker_free (autospell); - } - } -} - -static void -auto_spell_cb (GtkAction *action, - XedSpellPlugin *plugin) -{ - XedSpellPluginPrivate *priv; - XedDocument *doc; - XedView *view; gboolean active; xed_debug (DEBUG_PLUGINS); @@ -1058,24 +456,27 @@ auto_spell_cb (GtkAction *action, priv = plugin->priv; active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); - xed_debug_message (DEBUG_PLUGINS, active ? "Auto Spell activated" : "Auto Spell deactivated"); + xed_debug_message (DEBUG_PLUGINS, active ? "Inline Checker activated" : "Inline Checker deactivated"); view = xed_window_get_active_view (priv->window); - if (view == NULL) + if (view != NULL) { - return; + XedDocument *doc; + GspellTextView *gspell_view; + + doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + + if (get_autocheck_type (plugin) == AUTOCHECK_DOCUMENT) + { + xed_document_set_metadata (doc, + XED_METADATA_ATTRIBUTE_SPELL_ENABLED, + active ? SPELL_ENABLED_STR : NULL, + NULL); + } + + gspell_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (view)); + gspell_text_view_set_inline_spell_checking (gspell_view, active); } - - doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - - if (get_autocheck_type (plugin) == AUTOCHECK_DOCUMENT) - { - xed_document_set_metadata (doc, - XED_METADATA_ATTRIBUTE_SPELL_ENABLED, - active ? "1" : NULL, NULL); - } - - set_auto_spell (priv->window, view, active); } static void @@ -1088,30 +489,33 @@ update_ui (XedSpellPlugin *plugin) xed_debug (DEBUG_PLUGINS); priv = plugin->priv; + view = xed_window_get_active_view (priv->window); if (view != NULL) { - XedDocument *doc; XedTab *tab; - XedTabState state; - gboolean autospell; + GtkTextBuffer *buffer; - doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); tab = xed_window_get_active_tab (priv->window); - state = xed_tab_get_state (tab); - autospell = (doc != NULL && xed_automatic_spell_checker_get_from_document (doc) != NULL); + g_return_if_fail (xed_tab_get_view (tab) == view); /* If the document is loading we can't get the metadata so we endup with an useless speller */ - if (state == XED_TAB_STATE_NORMAL) + if (xed_tab_get_state (tab) == XED_TAB_STATE_NORMAL) { - action = gtk_action_group_get_action (priv->action_group, "AutoSpell"); + GspellTextView *gspell_view; + gboolean inline_checking_enabled; - g_signal_handlers_block_by_func (action, auto_spell_cb, plugin); - set_auto_spell (priv->window, view, autospell); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), autospell); - g_signal_handlers_unblock_by_func (action, auto_spell_cb, plugin); + gspell_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (view)); + inline_checking_enabled = gspell_text_view_get_inline_spell_checking (gspell_view); + + action = gtk_action_group_get_action (priv->action_group, "InlineSpellChecker"); + + g_signal_handlers_block_by_func (action, inline_checker_cb, plugin); + gspell_text_view_set_inline_spell_checking (gspell_view, inline_checking_enabled); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), inline_checking_enabled); + g_signal_handlers_unblock_by_func (action, inline_checker_cb, plugin); } } @@ -1121,139 +525,239 @@ update_ui (XedSpellPlugin *plugin) } static void -set_auto_spell_from_metadata (XedSpellPlugin *plugin, - XedView *view, - GtkActionGroup *action_group) +setup_inline_checker_from_metadata (XedSpellPlugin *plugin, + XedView *view) { - gboolean active = FALSE; - gchar *active_str = NULL; - XedWindow *window; + XedSpellPluginPrivate *priv; XedDocument *doc; - XedDocument *active_doc; + gboolean enabled = FALSE; + gchar *enabled_str = NULL; + GspellTextView *gspell_view; + XedView *active_view; XedSpellPluginAutocheckType autocheck_type; - doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + priv = plugin->priv; autocheck_type = get_autocheck_type (plugin); + doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + switch (autocheck_type) { case AUTOCHECK_ALWAYS: { - active = TRUE; + enabled = TRUE; break; } case AUTOCHECK_DOCUMENT: { - active_str = xed_document_get_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_ENABLED); + enabled_str = xed_document_get_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_ENABLED); break; } case AUTOCHECK_NEVER: default: - active = FALSE; + enabled = FALSE; break; } - if (active_str) + if (enabled_str != NULL) { - active = *active_str == '1'; - - g_free (active_str); + enabled = g_str_equal (enabled_str, SPELL_ENABLED_STR); + g_free (enabled_str); } - window = XED_WINDOW (plugin->priv->window); + gspell_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (view)); + gspell_text_view_set_inline_spell_checking (gspell_view, enabled); - set_auto_spell (window, view, active); + /* In case that the view is the active one we mark the spell action */ + active_view = xed_window_get_active_view (plugin->priv->window); - /* In case that the doc is the active one we mark the spell action */ - active_doc = xed_window_get_active_document (window); - - if (active_doc == doc && action_group != NULL) + if (active_view == view && priv->action_group != NULL) { GtkAction *action; - action = gtk_action_group_get_action (action_group, "AutoSpell"); + action = gtk_action_group_get_action (priv->action_group, "InlineSpellChecker"); - g_signal_handlers_block_by_func (action, auto_spell_cb, plugin); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), active); - g_signal_handlers_unblock_by_func (action, auto_spell_cb, plugin); + g_signal_handlers_block_by_func (action, inline_checker_cb, plugin); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), enabled); + g_signal_handlers_unblock_by_func (action, inline_checker_cb, plugin); } } +static void +language_notify_cb (GspellChecker *checker, + GParamSpec *pspec, + XedDocument *doc) +{ + const GspellLanguage *lang; + const gchar *language_code; + + g_return_if_fail (XED_IS_DOCUMENT (doc)); + + lang = gspell_checker_get_language (checker); + g_return_if_fail (lang != NULL); + + language_code = gspell_language_get_code (lang); + g_return_if_fail (language_code != NULL); + + xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE, language_code, NULL); +} + static void on_document_loaded (XedDocument *doc, XedSpellPlugin *plugin) { - XedSpellChecker *spell; + GspellChecker *checker; + XedTab *tab; XedView *view; - spell = XED_SPELL_CHECKER (g_object_get_qdata (G_OBJECT (doc), spell_checker_id)); - if (spell != NULL) + checker = get_spell_checker (doc); + + if (checker != NULL) { - set_language_from_metadata (spell, doc); + const GspellLanguage *lang; + + lang = get_language_from_metadata (doc); + + if (lang != NULL) + { + g_signal_handlers_block_by_func (checker, language_notify_cb, doc); + gspell_checker_set_language (checker, lang); + g_signal_handlers_unblock_by_func (checker, language_notify_cb, doc); + } } - view = XED_VIEW (g_object_get_data (G_OBJECT (doc), XED_AUTOMATIC_SPELL_VIEW)); - - set_auto_spell_from_metadata (plugin, view, plugin->priv->action_group); + tab = xed_tab_get_from_document (doc); + view = xed_tab_get_view (tab); + setup_inline_checker_from_metadata (plugin, view); } static void on_document_saved (XedDocument *doc, XedSpellPlugin *plugin) { - XedAutomaticSpellChecker *autospell; - XedSpellChecker *spell; - const gchar *key; + XedTab *tab; + XedView *view; + GspellChecker *checker; + const gchar *language_code = NULL; + GspellTextView *gspell_view; + gboolean inline_checking_enabled; /* Make sure to save the metadata here too */ - autospell = xed_automatic_spell_checker_get_from_document (doc); - spell = XED_SPELL_CHECKER (g_object_get_qdata (G_OBJECT (doc), spell_checker_id)); + checker = get_spell_checker (doc); - if (spell != NULL) + if (checker != NULL) { - key = xed_spell_checker_language_to_key (xed_spell_checker_get_language (spell)); - } - else - { - key = NULL; + const GspellLanguage *lang; + + lang = gspell_checker_get_language (checker); + if (lang != NULL) + { + language_code = gspell_language_get_code (lang); + } } + tab = xed_tab_get_from_document (doc); + view = xed_tab_get_view (tab); + + gspell_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (view)); + inline_checking_enabled = gspell_text_view_get_inline_spell_checking (gspell_view); + if (get_autocheck_type (plugin) == AUTOCHECK_DOCUMENT) { xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_ENABLED, - autospell != NULL ? "1" : NULL, + inline_checking_enabled ? SPELL_ENABLED_STR : NULL, XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE, - key, + language_code, NULL); } else { - xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE, key, NULL); + xed_document_set_metadata (doc, XED_METADATA_ATTRIBUTE_SPELL_LANGUAGE, language_code, NULL); } } +static void +activate_spell_checking_in_view (XedSpellPlugin *plugin, + XedView *view) +{ + XedDocument *doc; + + doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + + /* It is possible that a GspellChecker has already been set, for example + * if a XedTab has moved to another window. + */ + if (get_spell_checker (doc) == NULL) + { + const GspellLanguage *lang; + GspellChecker *checker; + GspellTextBuffer *gspell_buffer; + + lang = get_language_from_metadata (doc); + checker = gspell_checker_new (lang); + + g_signal_connect_object (checker, "notify::language", + G_CALLBACK (language_notify_cb), doc, 0); + + gspell_buffer = gspell_text_buffer_get_from_gtk_text_buffer (GTK_TEXT_BUFFER (doc)); + gspell_text_buffer_set_spell_checker (gspell_buffer, checker); + g_object_unref (checker); + + setup_inline_checker_from_metadata (plugin, view); + } + + g_signal_connect_object (doc, "loaded", + G_CALLBACK (on_document_loaded), plugin, 0); + g_signal_connect_object (doc, "saved", + G_CALLBACK (on_document_saved), plugin, 0); +} + +static void +disconnect_view (XedSpellPlugin *plugin, + XedView *view) +{ + GtkTextBuffer *buffer; + + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); + + /* It should still be the same buffer as the one where the signal + * handlers were connected. If not, we assume that the old buffer is + * finalized. And it is anyway safe to call + * g_signal_handlers_disconnect_by_func() if no signal handlers are + * found. + */ + g_signal_handlers_disconnect_by_func (buffer, on_document_loaded, plugin); + g_signal_handlers_disconnect_by_func (buffer, on_document_saved, plugin); +} + +static void +deactivate_spell_checking_in_view (XedSpellPlugin *plugin, + XedView *view) +{ + GtkTextBuffer *gtk_buffer; + GspellTextBuffer *gspell_buffer; + GspellTextView *gspell_view; + + disconnect_view (plugin, view); + + gtk_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); + gspell_buffer = gspell_text_buffer_get_from_gtk_text_buffer (gtk_buffer); + gspell_text_buffer_set_spell_checker (gspell_buffer, NULL); + + gspell_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (view)); + gspell_text_view_set_inline_spell_checking (gspell_view, FALSE); +} + static void tab_added_cb (XedWindow *window, XedTab *tab, XedSpellPlugin *plugin) { - XedView *view; - XedDocument *doc; - - view = xed_tab_get_view (tab); - doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); - - g_object_set_data (G_OBJECT (doc), XED_AUTOMATIC_SPELL_VIEW, view); - - g_signal_connect (doc, "loaded", - G_CALLBACK (on_document_loaded), plugin); - - g_signal_connect (doc, "saved", - G_CALLBACK (on_document_saved), plugin); + activate_spell_checking_in_view (plugin, xed_tab_get_view (tab)); } static void @@ -1261,25 +765,27 @@ tab_removed_cb (XedWindow *window, XedTab *tab, XedSpellPlugin *plugin) { - XedDocument *doc; - - doc = xed_tab_get_document (tab); - g_object_set_data (G_OBJECT (doc), XED_AUTOMATIC_SPELL_VIEW, NULL); - - g_signal_handlers_disconnect_by_func (doc, on_document_loaded, plugin); - g_signal_handlers_disconnect_by_func (doc, on_document_saved, plugin); + /* Don't deactivate completely the spell checking in @tab, since the tab + * can be moved to another window and we don't want to loose the spell + * checking settings (they are not saved in metadata for unsaved + * documents). + */ + disconnect_view (plugin, xed_tab_get_view (tab)); } static void xed_spell_plugin_activate (XedWindowActivatable *activatable) { + XedSpellPlugin *plugin; XedSpellPluginPrivate *priv; GtkUIManager *manager; - GList *views, *l; + GList *views; + GList *l; xed_debug (DEBUG_PLUGINS); - priv = XED_SPELL_PLUGIN (activatable)->priv; + plugin = XED_SPELL_PLUGIN (activatable); + priv = plugin->priv; manager = xed_window_get_ui_manager (priv->window); @@ -1298,9 +804,6 @@ xed_spell_plugin_activate (XedWindowActivatable *activatable) priv->ui_id = gtk_ui_manager_new_merge_id (manager); - priv->message_cid = gtk_statusbar_get_context_id (GTK_STATUSBAR (xed_window_get_statusbar (priv->window)), - "spell_plugin_message"); - gtk_ui_manager_add_ui (manager, priv->ui_id, MENU_PATH, @@ -1312,8 +815,8 @@ xed_spell_plugin_activate (XedWindowActivatable *activatable) gtk_ui_manager_add_ui (manager, priv->ui_id, MENU_PATH, - "AutoSpell", - "AutoSpell", + "InlineSpellChecker", + "InlineSpellChecker", GTK_UI_MANAGER_MENUITEM, FALSE); @@ -1328,35 +831,43 @@ xed_spell_plugin_activate (XedWindowActivatable *activatable) update_ui (XED_SPELL_PLUGIN (activatable)); views = xed_window_get_views (priv->window); - for (l = views; l != NULL; l = g_list_next (l)) + for (l = views; l != NULL; l = l->next) { - XedView *view = XED_VIEW (l->data); - - set_auto_spell_from_metadata (XED_SPELL_PLUGIN (activatable), view, priv->action_group); + activate_spell_checking_in_view (plugin, XED_VIEW (l->data)); } - priv->tab_added_id = g_signal_connect (priv->window, "tab-added", - G_CALLBACK (tab_added_cb), activatable); - priv->tab_removed_id = g_signal_connect (priv->window, "tab-removed", - G_CALLBACK (tab_removed_cb), activatable); + g_signal_connect (priv->window, "tab-added", + G_CALLBACK (tab_added_cb), activatable); + g_signal_connect (priv->window, "tab-removed", + G_CALLBACK (tab_removed_cb), activatable); } static void xed_spell_plugin_deactivate (XedWindowActivatable *activatable) { + XedSpellPlugin *plugin; XedSpellPluginPrivate *priv; GtkUIManager *manager; + GList *views; + GList *l; xed_debug (DEBUG_PLUGINS); - priv = XED_SPELL_PLUGIN (activatable)->priv; + plugin = XED_SPELL_PLUGIN (activatable); + priv = plugin->priv; manager = xed_window_get_ui_manager (priv->window); gtk_ui_manager_remove_ui (manager, priv->ui_id); gtk_ui_manager_remove_action_group (manager, priv->action_group); - g_signal_handler_disconnect (priv->window, priv->tab_added_id); - g_signal_handler_disconnect (priv->window, priv->tab_removed_id); + g_signal_handlers_disconnect_by_func (priv->window, tab_added_cb, activatable); + g_signal_handlers_disconnect_by_func (priv->window, tab_removed_cb, activatable); + + views = xed_window_get_views (priv->window); + for (l = views; l != NULL; l = l->next) + { + deactivate_spell_checking_in_view (plugin, XED_VIEW (l->data)); + } } static void @@ -1377,35 +888,6 @@ xed_spell_plugin_create_configure_widget (PeasGtkConfigurable *configurable) return widget->content; } -static void -xed_spell_plugin_class_init (XedSpellPluginClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = xed_spell_plugin_dispose; - object_class->set_property = xed_spell_plugin_set_property; - object_class->get_property = xed_spell_plugin_get_property; - - if (spell_checker_id == 0) - { - spell_checker_id = g_quark_from_string ("XedSpellCheckerID"); - } - - if (check_range_id == 0) - { - check_range_id = g_quark_from_string ("CheckRangeID"); - } - - g_object_class_override_property (object_class, PROP_WINDOW, "window"); - - g_type_class_add_private (object_class, sizeof (XedSpellPluginPrivate)); -} - -static void -xed_spell_plugin_class_finalize (XedSpellPluginClass *klass) -{ -} - static void xed_window_activatable_iface_init (XedWindowActivatableInterface *iface) { diff --git a/plugins/spell/xed-spell-utils.c b/plugins/spell/xed-spell-utils.c deleted file mode 100644 index b36c736..0000000 --- a/plugins/spell/xed-spell-utils.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * xed-spell-utils.c - * This file is part of xed - * - * Copyright (C) 2010 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -#include - -#include "xed-spell-utils.h" -#include - -gboolean -xed_spell_utils_is_digit (const char *text, gssize length) -{ - gunichar c; - const gchar *p; - const gchar *end; - - g_return_val_if_fail (text != NULL, FALSE); - - if (length < 0) - length = strlen (text); - - p = text; - end = text + length; - - while (p != end) { - const gchar *next; - next = g_utf8_next_char (p); - - c = g_utf8_get_char (p); - - if (!g_unichar_isdigit (c) && c != '.' && c != ',') - return FALSE; - - p = next; - } - - return TRUE; -} - -gboolean -xed_spell_utils_skip_no_spell_check (GtkTextIter *start, - GtkTextIter *end) -{ - GtkSourceBuffer *buffer = GTK_SOURCE_BUFFER (gtk_text_iter_get_buffer (start)); - - while (gtk_source_buffer_iter_has_context_class (buffer, start, "no-spell-check")) - { - GtkTextIter last = *start; - - if (!gtk_source_buffer_iter_forward_to_context_class_toggle (buffer, start, "no-spell-check")) - { - return FALSE; - } - - if (gtk_text_iter_compare (start, &last) <= 0) - { - return FALSE; - } - - gtk_text_iter_forward_word_end (start); - gtk_text_iter_backward_word_start (start); - - if (gtk_text_iter_compare (start, &last) <= 0) - { - return FALSE; - } - - if (gtk_text_iter_compare (start, end) >= 0) - { - return FALSE; - } - } - - return TRUE; -} - diff --git a/plugins/spell/xed-spell-utils.h b/plugins/spell/xed-spell-utils.h deleted file mode 100644 index 263979c..0000000 --- a/plugins/spell/xed-spell-utils.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * xed-spell-utils.h - * This file is part of xed - * - * Copyright (C) 2010 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -#ifndef __XED_SPELL_UTILS_H__ -#define __XED_SPELL_UTILS_H__ - -#include - -G_BEGIN_DECLS - -gboolean xed_spell_utils_is_digit (const char *text, gssize length); - -gboolean xed_spell_utils_skip_no_spell_check (GtkTextIter *start, GtkTextIter *end); - -G_END_DECLS - -#endif /* __XED_SPELL_UTILS_H__ */ -