commit 0731794dd71f6fea4ee479df51a4a5e15474bdbc Author: Vitaly Minko Date: Thu Oct 21 15:46:25 2010 +0400 Add a new popup-menu item in the chat window allowing to add words to dictionaries (#550775). diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index fb8d538..d6b9cf7 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -172,6 +172,8 @@ static guint signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (EmpathyChat, empathy_chat, GTK_TYPE_BIN); +static gboolean update_misspelled_words (gpointer data); + static void chat_get_property (GObject *object, guint param_id, @@ -1838,6 +1840,123 @@ chat_spelling_build_menu (EmpathyChatSpell *chat_spell) return menu; } +typedef struct { + EmpathyChat *chat; + gchar *word; + gchar *code; +} EmpathyChatWord; + +static EmpathyChatWord * +chat_word_new (EmpathyChat *chat, + const gchar *word, + const gchar *code) +{ + EmpathyChatWord *chat_word; + + chat_word = g_slice_new0 (EmpathyChatWord); + + chat_word->chat = g_object_ref (chat); + chat_word->word = g_strdup (word); + chat_word->code = g_strdup (code); + + return chat_word; +} + +static void +chat_word_free (EmpathyChatWord *chat_word) +{ + g_object_unref (chat_word->chat); + g_free (chat_word->word); + g_free (chat_word->code); + g_slice_free (EmpathyChatWord, chat_word); +} + +static void +chat_add_to_dictionary_activate_cb (GtkMenuItem *menu_item, + EmpathyChatWord *chat_word) +{ + EmpathyChatPriv *priv = GET_PRIV (chat_word->chat); + + empathy_spell_add_to_dictionary (chat_word->code, + chat_word->word); + priv->update_misspelled_words_id = + g_idle_add (update_misspelled_words, chat_word->chat); +} + +static GtkWidget * +chat_spelling_build_add_to_dictionary_item (EmpathyChatSpell *chat_spell) +{ + GtkWidget *menu, *item, *lang_item, *image; + GList *codes, *l; + gchar *label; + const gchar *code, *name; + EmpathyChatWord *chat_word; + + codes = empathy_spell_get_enabled_language_codes (); + g_assert (codes != NULL); + if (g_list_length (codes) > 1) { + /* translators: %s is the selected word */ + label = g_strdup_printf(_("Add '%s' to Dictionary"), + chat_spell->word); + item = gtk_image_menu_item_new_with_mnemonic (label); + g_free (label); + image = gtk_image_new_from_icon_name (GTK_STOCK_ADD, + GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), + image); + + menu = gtk_menu_new (); + + for (l = codes; l; l = l->next) { + code = l->data; + name = empathy_spell_get_language_name (code); + if (name == NULL) + continue; + + lang_item = gtk_image_menu_item_new_with_label (name); + + chat_word= chat_word_new (chat_spell->chat, + chat_spell->word, code); + g_object_set_data_full (G_OBJECT (lang_item), + "chat-word", chat_word, + (GDestroyNotify) chat_word_free); + + g_signal_connect (G_OBJECT (lang_item), "activate", + G_CALLBACK (chat_add_to_dictionary_activate_cb), + chat_word); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), lang_item); + } + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu); + } else { + code = codes->data; + name = empathy_spell_get_language_name (code); + g_assert (name != NULL); + /* translators: first %s is the selected word, + * second %s is the language name of the target dictionary */ + label = g_strdup_printf(_("Add '%s' to %s Dictionary"), + chat_spell->word, name); + item = gtk_image_menu_item_new_with_mnemonic (label); + g_free (label); + image = gtk_image_new_from_icon_name (GTK_STOCK_ADD, + GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + + chat_word = chat_word_new (chat_spell->chat, chat_spell->word, + code); + g_object_set_data_full (G_OBJECT (item), "chat-word", chat_word, + (GDestroyNotify) chat_word_free); + + g_signal_connect (G_OBJECT (item), "activate", + G_CALLBACK (chat_add_to_dictionary_activate_cb), + chat_word); + } + g_list_free (codes); + + gtk_widget_show_all (item); + + return item; +} + static void chat_text_send_cb (GtkMenuItem *menuitem, EmpathyChat *chat) @@ -1860,6 +1979,7 @@ chat_input_populate_popup_cb (GtkTextView *view, gchar *str = NULL; EmpathyChatSpell *chat_spell; GtkWidget *spell_menu; + GtkWidget *spell_item; EmpathySmileyManager *smiley_manager; GtkWidget *smiley_menu; GtkWidget *image; @@ -1917,13 +2037,14 @@ chat_input_populate_popup_cb (GtkTextView *view, if (!EMP_STR_EMPTY (str)) { chat_spell = chat_spell_new (chat, str, start, end); g_object_set_data_full (G_OBJECT (menu), - "chat_spell", chat_spell, + "chat-spell", chat_spell, (GDestroyNotify) chat_spell_free); item = gtk_separator_menu_item_new (); gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); + /* Spelling suggestions */ item = gtk_image_menu_item_new_with_mnemonic (_("_Spelling Suggestions")); image = gtk_image_new_from_icon_name (GTK_STOCK_SPELL_CHECK, GTK_ICON_SIZE_MENU); @@ -1932,6 +2053,17 @@ chat_input_populate_popup_cb (GtkTextView *view, spell_menu = chat_spelling_build_menu (chat_spell); gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), spell_menu); + + spell_item = gtk_separator_menu_item_new (); + gtk_menu_shell_append (GTK_MENU_SHELL (spell_menu), spell_item); + gtk_widget_show (spell_item); + + /* Add to dictionary */ + spell_item = chat_spelling_build_add_to_dictionary_item (chat_spell); + + gtk_menu_shell_append (GTK_MENU_SHELL (spell_menu), spell_item); + gtk_widget_show (spell_item); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); } diff --git a/libempathy-gtk/empathy-spell.c b/libempathy-gtk/empathy-spell.c index b9abcd5..dcbbaf8 100644 --- a/libempathy-gtk/empathy-spell.c +++ b/libempathy-gtk/empathy-spell.c @@ -359,7 +359,8 @@ empathy_spell_check (const gchar *word) } GList * -empathy_spell_get_suggestions (const gchar *code, const gchar *word) +empathy_spell_get_suggestions (const gchar *code, + const gchar *word) { gint len; GList *suggestion_list = NULL; @@ -409,6 +410,26 @@ empathy_spell_supported (void) return TRUE; } +void +empathy_spell_add_to_dictionary (const gchar *code, + const gchar *word) +{ + SpellLanguage *lang; + + g_return_if_fail (code != NULL); + g_return_if_fail (word != NULL); + + spell_setup_languages (); + if (languages == NULL) + return; + + lang = g_hash_table_lookup (languages, code); + if (lang == NULL) + return; + + enchant_dict_add_to_pwl (lang->speller, word, strlen (word)); +} + #else /* not HAVE_ENCHANT */ gboolean @@ -454,6 +475,14 @@ empathy_spell_free_language_codes (GList *codes) { } +void +empathy_spell_add_to_dictionary (const gchar *code, + const gchar *word) +{ + DEBUG ("Support disabled, could not expand the dictionary"); +} + + #endif /* HAVE_ENCHANT */ diff --git a/libempathy-gtk/empathy-spell.h b/libempathy-gtk/empathy-spell.h index aa2a3e5..ebce1ae 100644 --- a/libempathy-gtk/empathy-spell.h +++ b/libempathy-gtk/empathy-spell.h @@ -37,6 +37,8 @@ gboolean empathy_spell_check (const gchar *word); GList * empathy_spell_get_suggestions (const gchar *code, const gchar *word); void empathy_spell_free_suggestions (GList *suggestions); +void empathy_spell_add_to_dictionary (const gchar *code, + const gchar *word); G_END_DECLS