[empathy] Separate spelling suggestions in one sub-menu per language (#532832)



commit 26e03eb5ff87e6148a7a316c9538e94e6587cfe3
Author: Vitaly Minko <vitaly minko gmail com>
Date:   Fri Oct 15 11:18:56 2010 +0200

    Separate spelling suggestions in one sub-menu per language (#532832)

 libempathy-gtk/empathy-chat.c  |   94 +++++++++++++++++++++++++++++----------
 libempathy-gtk/empathy-spell.c |   91 ++++++++++++++++++++++----------------
 libempathy-gtk/empathy-spell.h |    4 +-
 src/empathy-preferences.c      |   35 ++++++---------
 4 files changed, 140 insertions(+), 84 deletions(-)
---
diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c
index 295ee6a..fb8d538 100644
--- a/libempathy-gtk/empathy-chat.c
+++ b/libempathy-gtk/empathy-chat.c
@@ -1763,33 +1763,79 @@ chat_spelling_menu_activate_cb (GtkMenuItem     *menu_item,
                                gtk_menu_item_get_label (menu_item));
 }
 
+
+static GtkWidget *
+chat_spelling_build_suggestions_menu (const gchar *code,
+				      EmpathyChatSpell *chat_spell)
+{
+	GList     *suggestions, *l;
+	GtkWidget *menu, *menu_item;
+
+	suggestions = empathy_spell_get_suggestions (code, chat_spell->word);
+	if (suggestions == NULL)
+		return NULL;
+
+	menu = gtk_menu_new ();
+	for (l = suggestions; l; l = l->next) {
+		menu_item = gtk_menu_item_new_with_label (l->data);
+		g_signal_connect (G_OBJECT (menu_item), "activate",
+				  G_CALLBACK (chat_spelling_menu_activate_cb),
+				  chat_spell);
+		gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+	}
+	empathy_spell_free_suggestions (suggestions);
+
+	gtk_widget_show_all (menu);
+
+	return menu;
+}
+
 static GtkWidget *
 chat_spelling_build_menu (EmpathyChatSpell *chat_spell)
 {
-    GtkWidget *menu, *menu_item;
-    GList     *suggestions, *l;
-
-    menu = gtk_menu_new ();
-    suggestions = empathy_spell_get_suggestions (chat_spell->word);
-    if (suggestions == NULL) {
-        menu_item = gtk_menu_item_new_with_label (_("(No Suggestions)"));
-	gtk_widget_set_sensitive (menu_item, FALSE);
-        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
-    } else {
-        for (l = suggestions; l; l = l->next) {
-            menu_item = gtk_menu_item_new_with_label (l->data);
-            g_signal_connect (G_OBJECT (menu_item),
-                          "activate",
-                          G_CALLBACK (chat_spelling_menu_activate_cb),
-                          chat_spell);
-            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
-        }
-    }
-    empathy_spell_free_suggestions (suggestions);
+	GtkWidget *menu, *submenu, *item;
+	GList     *codes, *l;
 
-    gtk_widget_show_all (menu);
+	codes = empathy_spell_get_enabled_language_codes ();
+	g_assert (codes != NULL);
 
-    return menu;
+	if (g_list_length (codes) > 1) {
+		menu = gtk_menu_new ();
+
+		for (l = codes; l; l = l->next) {
+			const gchar *code, *name;
+
+			code = l->data;
+			name = empathy_spell_get_language_name (code);
+			if (!name)
+				continue;
+
+			item = gtk_image_menu_item_new_with_label (name);
+
+			submenu = chat_spelling_build_suggestions_menu (
+					code, chat_spell);
+			if (submenu == NULL)
+				gtk_widget_set_sensitive (item, FALSE);
+			else
+				gtk_menu_item_set_submenu (GTK_MENU_ITEM (item),
+							   submenu);
+			gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+		}
+	} else {
+		menu = chat_spelling_build_suggestions_menu (codes->data,
+							     chat_spell);
+		if (menu == NULL) {
+			menu = gtk_menu_new ();
+			item = gtk_menu_item_new_with_label (_("(No Suggestions)"));
+			gtk_widget_set_sensitive (item, FALSE);
+			gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+		}
+	}
+	g_list_free (codes);
+
+	gtk_widget_show_all (menu);
+
+	return menu;
 }
 
 static void
diff --git a/libempathy-gtk/empathy-spell.c b/libempathy-gtk/empathy-spell.c
index ff94bb0..b9abcd5 100644
--- a/libempathy-gtk/empathy-spell.c
+++ b/libempathy-gtk/empathy-spell.c
@@ -48,8 +48,11 @@ typedef struct {
 #define ISO_CODES_DATADIR    ISO_CODES_PREFIX "/share/xml/iso-codes"
 #define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
 
+/* Language code (gchar *) -> language name (gchar *) */
 static GHashTable  *iso_code_names = NULL;
-static GList       *languages = NULL;
+/* Contains only _enabled_ languages
+ * Language code (gchar *) -> language (SpellLanguage *) */
+static GHashTable  *languages = NULL;
 
 static void
 spell_iso_codes_parse_start_tag (GMarkupParseContext  *ctx,
@@ -162,24 +165,22 @@ spell_notify_languages_cb (GSettings   *gsettings,
 			   const gchar *key,
 			   gpointer     user_data)
 {
-	GList *l;
-
 	DEBUG ("Resetting languages due to config change");
 
 	/* We just reset the languages list. */
-	for (l = languages; l; l = l->next) {
-		SpellLanguage *lang;
-
-		lang = l->data;
-
-		enchant_broker_free_dict (lang->config, lang->speller);
-		enchant_broker_free (lang->config);
-
-		g_slice_free (SpellLanguage, lang);
+	if (languages != NULL) {
+		g_hash_table_destroy (languages);
+		languages = NULL;
 	}
+}
+
+static void
+empathy_spell_free_language (SpellLanguage *lang)
+{
+	enchant_broker_free_dict (lang->config, lang->speller);
+	enchant_broker_free (lang->config);
 
-	g_list_free (languages);
-	languages = NULL;
+	g_slice_free (SpellLanguage, lang);
 }
 
 static void
@@ -201,6 +202,9 @@ spell_setup_languages (void)
 		return;
 	}
 
+	languages = g_hash_table_new_full (g_str_hash, g_str_equal,
+			g_free, (GDestroyNotify) empathy_spell_free_language);
+
 	str = g_settings_get_string (gsettings,
 			EMPATHY_PREFS_CHAT_SPELL_CHECKER_LANGUAGES);
 
@@ -224,7 +228,9 @@ spell_setup_languages (void)
 			if (lang->speller == NULL) {
 				DEBUG ("language '%s' has no valid dict", strv[i]);
 			} else {
-				languages = g_list_append (languages, lang);
+				g_hash_table_insert (languages,
+						     g_strdup (strv[i]),
+						     lang);
 			}
 
 			i++;
@@ -294,6 +300,13 @@ empathy_spell_get_language_codes (void)
 	return list_langs;
 }
 
+GList *
+empathy_spell_get_enabled_language_codes (void)
+{
+	spell_setup_languages ();
+	return g_hash_table_get_keys (languages);
+}
+
 void
 empathy_spell_free_language_codes (GList *codes)
 {
@@ -309,7 +322,8 @@ empathy_spell_check (const gchar *word)
 	gboolean     digit;
 	gunichar     c;
 	gint         len;
-	GList       *l;
+	GHashTableIter iter;
+	SpellLanguage  *lang;
 
 	g_return_val_if_fail (word != NULL, FALSE);
 
@@ -332,11 +346,8 @@ empathy_spell_check (const gchar *word)
 	}
 
 	len = strlen (word);
-	for (l = languages; l; l = l->next) {
-		SpellLanguage  *lang;
-
-		lang = l->data;
-
+	g_hash_table_iter_init (&iter, languages);
+	while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &lang)) {
 		enchant_result = enchant_dict_check (lang->speller, word, len);
 
 		if (enchant_result == 0) {
@@ -348,36 +359,40 @@ empathy_spell_check (const gchar *word)
 }
 
 GList *
-empathy_spell_get_suggestions (const gchar *word)
+empathy_spell_get_suggestions (const gchar *code, const gchar *word)
 {
 	gint   len;
-	GList *l1;
 	GList *suggestion_list = NULL;
+	SpellLanguage *lang;
+	gchar **suggestions;
+	gsize   i, number_of_suggestions;
 
+	g_return_val_if_fail (code != NULL, NULL);
 	g_return_val_if_fail (word != NULL, NULL);
 
 	spell_setup_languages ();
 
-	len = strlen (word);
+	if (!languages) {
+		return NULL;
+	}
 
-	for (l1 = languages; l1; l1 = l1->next) {
-		SpellLanguage *lang;
-		gchar **suggestions;
-		gsize   i, number_of_suggestions;
+	len = strlen (word);
 
-		lang = l1->data;
+	lang = g_hash_table_lookup (languages, code);
+	if (!lang) {
+		return NULL;
+	}
 
-		suggestions = enchant_dict_suggest (lang->speller, word, len,
-						    &number_of_suggestions);
+	suggestions = enchant_dict_suggest (lang->speller, word, len,
+					    &number_of_suggestions);
 
-		for (i = 0; i < number_of_suggestions; i++) {
-			suggestion_list = g_list_append (suggestion_list,
-							 g_strdup (suggestions[i]));
-		}
+	for (i = 0; i < number_of_suggestions; i++) {
+		suggestion_list = g_list_append (suggestion_list,
+						 g_strdup (suggestions[i]));
+	}
 
-		if (suggestions) {
-			enchant_dict_free_string_list (lang->speller, suggestions);
-		}
+	if (suggestions) {
+		enchant_dict_free_string_list (lang->speller, suggestions);
 	}
 
 	return suggestion_list;
diff --git a/libempathy-gtk/empathy-spell.h b/libempathy-gtk/empathy-spell.h
index 65dbb13..aa2a3e5 100644
--- a/libempathy-gtk/empathy-spell.h
+++ b/libempathy-gtk/empathy-spell.h
@@ -31,9 +31,11 @@ G_BEGIN_DECLS
 gboolean     empathy_spell_supported           (void);
 const gchar *empathy_spell_get_language_name   (const gchar *code);
 GList       *empathy_spell_get_language_codes  (void);
+GList       *empathy_spell_get_enabled_language_codes (void);
 void         empathy_spell_free_language_codes (GList       *codes);
 gboolean     empathy_spell_check               (const gchar *word);
-GList *      empathy_spell_get_suggestions     (const gchar *word);
+GList *      empathy_spell_get_suggestions     (const gchar *code,
+						const gchar *word);
 void         empathy_spell_free_suggestions    (GList       *suggestions);
 
 G_END_DECLS
diff --git a/src/empathy-preferences.c b/src/empathy-preferences.c
index 89133ed..813637d 100644
--- a/src/empathy-preferences.c
+++ b/src/empathy-preferences.c
@@ -26,6 +26,7 @@
 #include <config.h>
 
 #include <string.h>
+#include <stdio.h>
 
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
@@ -101,7 +102,7 @@ static void     preferences_languages_load               (EmpathyPreferences
 static gboolean preferences_languages_load_foreach       (GtkTreeModel           *model,
 							  GtkTreePath            *path,
 							  GtkTreeIter            *iter,
-							  gchar                 **languages);
+							  GList                  *languages);
 static void     preferences_languages_cell_toggled_cb    (GtkCellRendererToggle  *cell,
 							  gchar                  *path_string,
 							  EmpathyPreferences      *preferences);
@@ -471,9 +472,6 @@ preferences_languages_add (EmpathyPreferences *preferences)
 
 	codes = empathy_spell_get_language_codes ();
 
-	g_settings_set_boolean (priv->gsettings_chat,
-				EMPATHY_PREFS_CHAT_SPELL_CHECKER_ENABLED,
-				codes != NULL);
 	if (!codes) {
 		gtk_widget_set_sensitive (priv->treeview_spell_checker, FALSE);
 	}
@@ -569,37 +567,34 @@ preferences_languages_load (EmpathyPreferences *preferences)
 	EmpathyPreferencesPriv *priv = GET_PRIV (preferences);
 	GtkTreeView   *view;
 	GtkTreeModel  *model;
-	gchar         *value;
-	gchar        **vlanguages;
+	GList         *enabled_codes;
 
-	value = g_settings_get_string (priv->gsettings_chat,
-				       EMPATHY_PREFS_CHAT_SPELL_CHECKER_LANGUAGES);
+	enabled_codes = empathy_spell_get_enabled_language_codes ();
 
-	if (value == NULL)
-		return;
+	g_settings_set_boolean (priv->gsettings_chat,
+				EMPATHY_PREFS_CHAT_SPELL_CHECKER_ENABLED,
+				enabled_codes != NULL);
 
-	vlanguages = g_strsplit (value, ",", -1);
-	g_free (value);
+	if (enabled_codes == NULL)
+		return;
 
 	view = GTK_TREE_VIEW (priv->treeview_spell_checker);
 	model = gtk_tree_view_get_model (view);
 
 	gtk_tree_model_foreach (model,
 				(GtkTreeModelForeachFunc) preferences_languages_load_foreach,
-				vlanguages);
+				enabled_codes);
 
-	g_strfreev (vlanguages);
+	g_list_free (enabled_codes);
 }
 
 static gboolean
 preferences_languages_load_foreach (GtkTreeModel  *model,
 				    GtkTreePath   *path,
 				    GtkTreeIter   *iter,
-				    gchar        **languages)
+				    GList         *languages)
 {
 	gchar    *code;
-	gchar    *lang;
-	gint      i;
 	gboolean  found = FALSE;
 
 	if (!languages) {
@@ -611,10 +606,8 @@ preferences_languages_load_foreach (GtkTreeModel  *model,
 		return FALSE;
 	}
 
-	for (i = 0, lang = languages[i]; lang; lang = languages[++i]) {
-		if (!tp_strdiff (lang, code)) {
-			found = TRUE;
-		}
+	if (g_list_find_custom (languages, code, (GCompareFunc) strcmp)) {
+		found = TRUE;
 	}
 
 	g_free (code);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]