aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaly Minko <vitaly.minko@gmail.com>2010-10-15 17:18:56 +0800
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2010-10-15 17:18:56 +0800
commit26e03eb5ff87e6148a7a316c9538e94e6587cfe3 (patch)
tree2c008c2c1813c13dfa9dde6fb44534458db6e0c6
parentc07cc33d2453bc8bcb5597439f620a7534680d31 (diff)
downloadgsoc2013-empathy-26e03eb5ff87e6148a7a316c9538e94e6587cfe3.tar
gsoc2013-empathy-26e03eb5ff87e6148a7a316c9538e94e6587cfe3.tar.gz
gsoc2013-empathy-26e03eb5ff87e6148a7a316c9538e94e6587cfe3.tar.bz2
gsoc2013-empathy-26e03eb5ff87e6148a7a316c9538e94e6587cfe3.tar.lz
gsoc2013-empathy-26e03eb5ff87e6148a7a316c9538e94e6587cfe3.tar.xz
gsoc2013-empathy-26e03eb5ff87e6148a7a316c9538e94e6587cfe3.tar.zst
gsoc2013-empathy-26e03eb5ff87e6148a7a316c9538e94e6587cfe3.zip
Separate spelling suggestions in one sub-menu per language (#532832)
-rw-r--r--libempathy-gtk/empathy-chat.c90
-rw-r--r--libempathy-gtk/empathy-spell.c91
-rw-r--r--libempathy-gtk/empathy-spell.h4
-rw-r--r--src/empathy-preferences.c35
4 files changed, 138 insertions, 82 deletions
diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c
index 295ee6af1..fb8d538ef 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 ff94bb053..b9abcd5f7 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 65dbb131d..aa2a3e51e 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 89133edb5..813637dca 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);