[evolution/wip/webkit-composer: 574/966] Various fixes in the spell-checking classes
- From: Tomas Popela <tpopela src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/webkit-composer: 574/966] Various fixes in the spell-checking classes
- Date: Wed, 23 Apr 2014 10:41:41 +0000 (UTC)
commit 481b248324610cb9fd07c5ff1214adc2eef9eaf9
Author: Dan Vrátil <dvratil redhat com>
Date: Mon Aug 27 13:52:34 2012 +0200
Various fixes in the spell-checking classes
e-util/e-spell-checker.c | 9 ++-
e-util/e-spell-dictionary.c | 6 +-
e-util/e-spell-entry.c | 210 +++++++++++++++++++++++++++++--------------
3 files changed, 154 insertions(+), 71 deletions(-)
---
diff --git a/e-util/e-spell-checker.c b/e-util/e-spell-checker.c
index 423ce52..867996b 100644
--- a/e-util/e-spell-checker.c
+++ b/e-util/e-spell-checker.c
@@ -85,6 +85,7 @@ struct _ESpellCheckerPrivate {
};
enum {
+ PROP_0,
PROP_ACTIVE_DICTIONARIES
};
@@ -766,6 +767,8 @@ e_spell_checker_init (ESpellChecker *checker)
{
checker->priv = G_TYPE_INSTANCE_GET_PRIVATE (
checker, E_TYPE_SPELL_CHECKER, ESpellCheckerPrivate);
+
+ checker->priv->broker = enchant_broker_init ();
}
typedef struct {
@@ -1045,7 +1048,9 @@ e_spell_checker_check_word (ESpellChecker *checker,
return recognized;
=======
ESpellChecker *e_checker;
- ListAvailDictsData data;
+ ListAvailDictsData data = { 0 };
+
+ g_return_val_if_fail (E_IS_SPELL_CHECKER (checker), NULL);
e_checker = E_SPELL_CHECKER (checker);
@@ -1073,6 +1078,8 @@ e_spell_checker_lookup_dictionary (ESpellChecker *checker,
ESpellChecker *e_checker;
ESpellDictionary *e_dict;
+ g_return_val_if_fail (E_IS_SPELL_CHECKER (checker), NULL);
+
e_checker = E_SPELL_CHECKER (checker);
e_dict = NULL;
diff --git a/e-util/e-spell-dictionary.c b/e-util/e-spell-dictionary.c
index aed60ce..e5ed02a 100644
--- a/e-util/e-spell-dictionary.c
+++ b/e-util/e-spell-dictionary.c
@@ -39,6 +39,7 @@ G_DEFINE_TYPE (
enum {
+ PROP_0,
PROP_SPELLCHECKER
};
@@ -317,6 +318,7 @@ spell_dictionary_set_enchant_dict (ESpellDictionary *dictionary,
enchant_dict_describe (enchant_dict, describe_dictionary, &data);
+ dictionary->priv->dict = enchant_dict;
dictionary->priv->code = data.language_tag;
dictionary->priv->name = data.dict_name;
dictionary->priv->collate_key = g_utf8_collate_key (data.dict_name, -1);
@@ -364,9 +366,7 @@ spell_dictionary_dispose (GObject *object)
{
ESpellDictionaryPrivate *priv = E_SPELL_DICTIONARY (object)->priv;
- e_spell_checker_free_dict (
- e_spell_dictionary_get_parent_checker (E_SPELL_DICTIONARY (object)),
- priv->dict);
+ e_spell_checker_free_dict (priv->spell_checker, priv->dict);
priv->dict = NULL;
g_free (priv->name);
diff --git a/e-util/e-spell-entry.c b/e-util/e-spell-entry.c
index 6fe9ead..f29ad1e 100644
--- a/e-util/e-spell-entry.c
+++ b/e-util/e-spell-entry.c
@@ -37,12 +37,12 @@ struct _ESpellEntryPrivate {
gint entry_scroll_offset;
gboolean custom_checkers;
gboolean checking_enabled;
+ GSList *dictionaries;
gchar **words;
gint *word_starts;
gint *word_ends;
ESpellChecker *spell_checker;
- guint active_languages_handler_id;
};
enum {
@@ -79,9 +79,13 @@ word_misspelled (ESpellEntry *entry,
ESpellChecker *spell_checker;
gssize wlen = strlen (word);
- spell_checker = e_spell_entry_get_spell_checker (entry);
- if (e_spell_checker_check_word (spell_checker, word, wlen))
- result = FALSE;
+ for (li = entry->priv->dictionaries; li; li = g_slist_next (li)) {
+ EnchantDict *dict = li->data;
+ if (enchant_dict_check (dict, word, wlen)) {
+ result = FALSE;
+ break;
+ }
+ }
}
g_free (word);
@@ -156,13 +160,8 @@ spell_entry_recheck_all (ESpellEntry *entry)
pango_attr_list_unref (entry->priv->attr_list);
entry->priv->attr_list = pango_attr_list_new ();
- if (e_spell_entry_get_checking_enabled (entry)) {
- ESpellChecker *spell_checker;
-
- spell_checker = e_spell_entry_get_spell_checker (entry);
- if (e_spell_checker_count_active_languages (spell_checker) > 0)
- check_words = TRUE;
- }
+ if (e_spell_entry_get_checking_enabled (entry))
+ check_words = (entry->priv->dictionaries != NULL);
if (check_words) {
/* Loop through words */
@@ -270,7 +269,7 @@ add_to_dictionary (GtkWidget *menuitem,
{
gchar *word;
gint start, end;
- ESpellDictionary *dict;
+ EnchantDict *dict;
get_word_extents_from_position (
entry, &start, &end, entry->priv->mark_character);
@@ -278,7 +277,7 @@ add_to_dictionary (GtkWidget *menuitem,
dict = g_object_get_data (G_OBJECT (menuitem), "spell-entry-checker");
if (dict != NULL)
- e_spell_dictionary_learn_word (dict, word, -1);
+ enchant_dict_add_to_personal (dict, word, -1);
g_free (word);
@@ -309,8 +308,10 @@ ignore_all (GtkWidget *menuitem,
entry, &start, &end, entry->priv->mark_character);
word = gtk_editable_get_chars (GTK_EDITABLE (entry), start, end);
- spell_checker = e_spell_entry_get_spell_checker (entry);
- e_spell_checker_ignore_word (spell_checker, word);
+ for (li = entry->priv->dictionaries; li; li = g_slist_next (li)) {
+ EnchantDict *dict = li->data;
+ enchant_dict_add_to_session (dict, word, -1);
+ }
g_free (word);
@@ -337,7 +338,7 @@ replace_word (GtkWidget *menuitem,
const gchar *newword;
gint start, end;
gint cursor;
- ESpellDictionary *dict;
+ EnchantDict *dict;
get_word_extents_from_position (
entry, &start, &end, entry->priv->mark_character);
@@ -361,7 +362,7 @@ replace_word (GtkWidget *menuitem,
dict = g_object_get_data (G_OBJECT (menuitem), "spell-entry-checker");
if (dict != NULL)
- e_spell_dictionary_store_correction (
+ enchant_dict_store_replacement (
dict, oldword, -1, newword, -1);
g_free (oldword);
@@ -374,7 +375,7 @@ build_suggestion_menu (ESpellEntry *entry,
const gchar *word)
{
GtkWidget *mi;
- GList *suggestions, *iter;
+ GList *suggestions;
suggestions = e_spell_dictionary_get_suggestions (dict, word, -1);
@@ -395,10 +396,13 @@ build_suggestion_menu (ESpellEntry *entry,
gtk_widget_show_all (mi);
gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mi);
} else {
- gint ii = 0;
+ GList *iter;
+ gint ii;
/* build a set of menus with suggestions */
- for (iter = suggestions; iter; iter = g_list_next (iter), ii++) {
+ for (iter = suggestions, ii = 0; iter; iter = iter->next, ii++) {
+ gchar *suggestion = iter->data;
+
if ((ii != 0) && (ii % 10 == 0)) {
mi = gtk_separator_menu_item_new ();
gtk_widget_show (mi);
@@ -412,9 +416,9 @@ build_suggestion_menu (ESpellEntry *entry,
gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), menu);
}
- mi = gtk_menu_item_new_with_label (iter->data);
+ mi = gtk_menu_item_new_with_label (suggestion);
g_object_set_data (G_OBJECT (mi), "spell-entry-checker", dict);
- g_signal_connect (mi, "activate", G_CALLBACK (replace_word), entry);
+ g_signal_connect (G_OBJECT (mi), "activate", G_CALLBACK (replace_word), entry);
gtk_widget_show (mi);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
}
@@ -427,7 +431,6 @@ static GtkWidget *
build_spelling_menu (ESpellEntry *entry,
const gchar *word)
{
- ESpellChecker *spell_checker;
ESpellDictionary *dict;
GtkWidget *topmenu, *mi;
GQueue queue = G_QUEUE_INIT;
@@ -437,35 +440,19 @@ build_spelling_menu (ESpellEntry *entry,
topmenu = gtk_menu_new ();
- spell_checker = e_spell_entry_get_spell_checker (entry);
-
- active_languages = e_spell_checker_list_active_languages (
- spell_checker, &n_active_languages);
- for (ii = 0; ii < n_active_languages; ii++) {
- dict = e_spell_checker_ref_dictionary (
- spell_checker, active_languages[ii]);
- if (dict != NULL)
- g_queue_push_tail (&queue, dict);
- }
- g_strfreev (active_languages);
-
- if (g_queue_is_empty (&queue))
- goto exit;
+ if (entry->priv->dictionaries == NULL)
+ return topmenu;
/* Suggestions */
- if (n_active_languages == 1) {
- dict = g_queue_peek_head (&queue);
+ if (entry->priv->dictionaries->next == NULL) {
+ dict = entry->priv->dictionaries->data;
build_suggestion_menu (entry, topmenu, dict, word);
} else {
GtkWidget *menu;
GList *list, *link;
- list = g_queue_peek_head_link (&queue);
-
- for (link = list; link != NULL; link = g_list_next (link)) {
- const gchar *lang_name;
-
- dict = E_SPELL_DICTIONARY (link->data);
+ for (li = entry->priv->dictionaries; li; li = g_slist_next (li)) {
+ dict = li->data;
lang_name = e_spell_dictionary_get_name (dict);
if (lang_name == NULL)
@@ -497,8 +484,8 @@ build_spelling_menu (ESpellEntry *entry,
GTK_IMAGE_MENU_ITEM (mi),
gtk_image_new_from_icon_name ("list-add", GTK_ICON_SIZE_MENU));
- if (n_active_languages == 1) {
- dict = g_queue_peek_head (&queue);
+ if (entry->priv->dictionaries->next == NULL) {
+ dict = entry->priv->dictionaries->data;
g_object_set_data (G_OBJECT (mi), "spell-entry-checker", dict);
g_signal_connect (
mi, "activate",
@@ -510,12 +497,8 @@ build_spelling_menu (ESpellEntry *entry,
menu = gtk_menu_new ();
gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), menu);
- list = g_queue_peek_head_link (&queue);
-
- for (link = list; link != NULL; link = g_list_next (link)) {
- const gchar *lang_name;
-
- dict = E_SPELL_DICTIONARY (link->data);
+ for (li = entry->priv->dictionaries; li; li = g_slist_next (li)) {
+ dict = li->data;
lang_name = e_spell_dictionary_get_name (dict);
if (lang_name == NULL)
@@ -523,10 +506,10 @@ build_spelling_menu (ESpellEntry *entry,
if (lang_name == NULL)
lang_name = "???";
- submi = gtk_menu_item_new_with_label (lang_name);
+ submi = gtk_menu_item_new_with_label (lang_name ? lang_name : "???");
g_object_set_data (G_OBJECT (submi), "spell-entry-checker", dict);
g_signal_connect (
- submi, "activate",
+ G_OBJECT (submi), "activate",
G_CALLBACK (add_to_dictionary), entry);
gtk_widget_show (submi);
@@ -599,8 +582,7 @@ spell_entry_populate_popup (ESpellEntry *entry,
gint start, end;
gchar *word;
- spell_checker = e_spell_entry_get_spell_checker (entry);
- if (e_spell_checker_count_active_languages (spell_checker) == 0)
+ if (entry->priv->dictionaries == NULL)
return;
get_word_extents_from_position (
@@ -625,8 +607,7 @@ spell_entry_changed (GtkEditable *editable)
ESpellEntry *entry = E_SPELL_ENTRY (editable);
ESpellChecker *spell_checker;
- spell_checker = e_spell_entry_get_spell_checker (entry);
- if (e_spell_checker_count_active_languages (spell_checker) == 0)
+ if (entry->priv->dictionaries == NULL)
return;
if (entry->priv->words != NULL) {
@@ -652,6 +633,73 @@ spell_entry_notify_scroll_offset (ESpellEntry *spell_entry)
&spell_entry->priv->entry_scroll_offset, NULL);
}
+static GList *
+spell_entry_load_spell_languages (ESpellEntry *entry)
+{
+ ESpellChecker *spell_checker;
+ GSettings *settings;
+ GList *dicts = NULL;
+ gchar **strv;
+ gint ii;
+
+ /* Ask GSettings for a list of spell check language codes. */
+ settings = g_settings_new ("org.gnome.evolution.mail");
+ strv = g_settings_get_strv (settings, "composer-spell-languages");
+ g_object_unref (settings);
+
+ spell_checker = entry->priv->spell_checker;
+
+ /* Convert the codes to spell language structs. */
+ for (ii = 0; strv[ii] != NULL; ii++) {
+ gchar *language_code = strv[ii];
+ ESpellDictionary *dict;
+
+ dict = e_spell_checker_lookup_dictionary (spell_checker, language_code);
+ if (dict != NULL)
+ dicts = g_list_prepend (
+ dicts, (gpointer) dict);
+ }
+
+ g_strfreev (strv);
+
+ dicts = g_list_reverse (dicts);
+
+ /* Pick a default spell language if it came back empty. */
+ if (dicts == NULL) {
+ ESpellDictionary *dict;
+
+ dict = e_spell_checker_lookup_dictionary (spell_checker, NULL);
+
+ if (dict) {
+ dicts = g_list_prepend (
+ dicts, (gpointer) dict);
+ }
+ }
+
+ return dicts;
+}
+
+static void
+spell_entry_settings_changed (ESpellEntry *spell_entry,
+ const gchar *key)
+{
+ GList *languages;
+
+ g_return_if_fail (spell_entry != NULL);
+
+ if (spell_entry->priv->custom_checkers)
+ return;
+
+ if (key && !g_str_equal (key, "composer-spell-languages"))
+ return;
+
+ languages = spell_entry_load_spell_languages (spell_entry);
+ e_spell_entry_set_languages (spell_entry, languages);
+ g_list_free (languages);
+
+ spell_entry->priv->custom_checkers = FALSE;
+}
+
static gint
spell_entry_find_position (ESpellEntry *spell_entry,
gint x)
@@ -740,15 +788,13 @@ spell_entry_dispose (GObject *object)
priv = E_SPELL_ENTRY_GET_PRIVATE (object);
- if (priv->active_languages_handler_id > 0) {
- g_signal_handler_disconnect (
- priv->spell_checker,
- priv->active_languages_handler_id);
- priv->active_languages_handler_id = 0;
- }
-
+ g_clear_object (&priv->settings);
g_clear_object (&priv->spell_checker);
+ g_slist_free_full (
+ priv->dictionaries, (GDestroyNotify) g_object_unref);
+ priv->dictionaries = NULL;
+
if (priv->attr_list != NULL) {
pango_attr_list_unref (priv->attr_list);
priv->attr_list = NULL;
@@ -872,7 +918,9 @@ e_spell_entry_init (ESpellEntry *spell_entry)
{
spell_entry->priv = E_SPELL_ENTRY_GET_PRIVATE (spell_entry);
spell_entry->priv->attr_list = pango_attr_list_new ();
+ spell_entry->priv->dictionaries = NULL;
spell_entry->priv->checking_enabled = TRUE;
+ spell_entry->priv->spell_checker = g_object_new (E_TYPE_SPELL_CHECKER, NULL);
g_signal_connect (
spell_entry, "popup-menu",
@@ -894,6 +942,34 @@ e_spell_entry_new (void)
return g_object_new (E_TYPE_SPELL_ENTRY, NULL);
}
+void
+e_spell_entry_set_languages (ESpellEntry *spell_entry,
+ GList *languages)
+{
+ GList *iter;
+
+ g_return_if_fail (spell_entry != NULL);
+
+ spell_entry->priv->custom_checkers = TRUE;
+
+ if (spell_entry->priv->dictionaries)
+ g_slist_free_full (spell_entry->priv->dictionaries, g_object_unref);
+ spell_entry->priv->dictionaries = NULL;
+
+ for (iter = languages; iter; iter = g_list_next (iter)) {
+ ESpellDictionary *dict = iter->data;
+
+ if (dict)
+ spell_entry->priv->dictionaries =
+ g_slist_prepend (spell_entry->priv->dictionaries, dict);
+ }
+
+ spell_entry->priv->dictionaries = g_slist_reverse (spell_entry->priv->dictionaries);
+
+ if (gtk_widget_get_realized (GTK_WIDGET (spell_entry)))
+ spell_entry_recheck_all (spell_entry);
+}
+
gboolean
e_spell_entry_get_checking_enabled (ESpellEntry *spell_entry)
{
@@ -908,7 +984,7 @@ e_spell_entry_set_checking_enabled (ESpellEntry *spell_entry,
{
g_return_if_fail (E_IS_SPELL_ENTRY (spell_entry));
- if (spell_entry->priv->checking_enabled == enable_checking)
+ if ((enable_checking ? 1 : 0) == (spell_entry->priv->checking_enabled ? 1 : 0))
return;
spell_entry->priv->checking_enabled = enable_checking;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]