[gspell/wip/entry-context-menu: 3/3] TextView: make suggestions context menu re-usable
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gspell/wip/entry-context-menu: 3/3] TextView: make suggestions context menu re-usable
- Date: Sat, 26 Nov 2016 13:39:02 +0000 (UTC)
commit 689dfaab778c31832ed784eb66b3d7a2f5154662
Author: Sébastien Wilmet <swilmet gnome org>
Date: Sat Nov 26 13:47:19 2016 +0100
TextView: make suggestions context menu re-usable
gspell/gspell-context-menu.c | 217 +++++++++++++++++++++++++++++++++++++++++-
gspell/gspell-context-menu.h | 10 ++
2 files changed, 226 insertions(+), 1 deletions(-)
---
diff --git a/gspell/gspell-context-menu.c b/gspell/gspell-context-menu.c
index 46cc587..1e4d55f 100644
--- a/gspell/gspell-context-menu.c
+++ b/gspell/gspell-context-menu.c
@@ -22,8 +22,11 @@
#include <glib/gi18n-lib.h>
#define LANGUAGE_DATA_KEY "gspell-language-data-key"
+#define SUGGESTION_DATA_KEY "gspell-suggestion-data-key"
+
+typedef struct _LanguageData LanguageData;
+typedef struct _SuggestionData SuggestionData;
-typedef struct _LanguageData LanguageData;
struct _LanguageData
{
const GspellLanguage *lang;
@@ -31,6 +34,30 @@ struct _LanguageData
gpointer user_data;
};
+struct _SuggestionData
+{
+ GspellChecker *checker;
+ gchar *misspelled_word;
+
+ gchar *suggested_word;
+ GspellSuggestionActivatedCallback callback;
+ gpointer user_data;
+};
+
+static void
+suggestion_data_free (gpointer data)
+{
+ SuggestionData *suggestion_data = data;
+
+ if (suggestion_data != NULL)
+ {
+ g_clear_object (&suggestion_data->checker);
+ g_free (suggestion_data->misspelled_word);
+ g_free (suggestion_data->suggested_word);
+ g_free (suggestion_data);
+ }
+}
+
static void
activate_language_cb (GtkWidget *menu_item)
{
@@ -126,4 +153,192 @@ _gspell_context_menu_get_language_menu_item (const GspellLanguage *cu
return menu_item;
}
+static void
+activate_suggestion_cb (GtkWidget *menu_item)
+{
+ SuggestionData *data;
+
+ data = g_object_get_data (G_OBJECT (menu_item), SUGGESTION_DATA_KEY);
+ g_return_if_fail (data != NULL);
+
+ if (data->callback != NULL)
+ {
+ data->callback (data->suggested_word, data->user_data);
+ }
+}
+
+static void
+ignore_all_cb (GtkWidget *menu_item)
+{
+ SuggestionData *data;
+
+ data = g_object_get_data (G_OBJECT (menu_item), SUGGESTION_DATA_KEY);
+ g_return_if_fail (data != NULL);
+
+ gspell_checker_add_word_to_session (data->checker,
+ data->misspelled_word,
+ -1);
+}
+
+static void
+add_to_dictionary_cb (GtkWidget *menu_item)
+{
+ SuggestionData *data;
+
+ data = g_object_get_data (G_OBJECT (menu_item), SUGGESTION_DATA_KEY);
+ g_return_if_fail (data != NULL);
+
+ gspell_checker_add_word_to_personal (data->checker,
+ data->misspelled_word,
+ -1);
+}
+
+static GtkWidget *
+get_suggestion_menu (GspellChecker *checker,
+ const gchar *misspelled_word,
+ GspellSuggestionActivatedCallback callback,
+ gpointer user_data)
+{
+ GtkWidget *top_menu;
+ GtkWidget *menu_item;
+ GSList *suggestions = NULL;
+ SuggestionData *data;
+
+ top_menu = gtk_menu_new ();
+
+ suggestions = gspell_checker_get_suggestions (checker, misspelled_word, -1);
+
+ if (suggestions == NULL)
+ {
+ /* No suggestions. Put something in the menu anyway... */
+ menu_item = gtk_menu_item_new_with_label (_("(no suggested words)"));
+ gtk_widget_set_sensitive (menu_item, FALSE);
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (top_menu), menu_item);
+ }
+ else
+ {
+ GtkWidget *menu = top_menu;
+ gint count = 0;
+ GSList *l;
+
+ /* Build a set of menus with suggestions. */
+ for (l = suggestions; l != NULL; l = l->next)
+ {
+ gchar *suggested_word = l->data;
+ GtkWidget *label;
+ gchar *label_text;
+
+ if (count == 10)
+ {
+ /* Separator */
+ menu_item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+
+ menu_item = gtk_menu_item_new_with_mnemonic (_("_More…"));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+
+ menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu);
+ count = 0;
+ }
+
+ label_text = g_strdup_printf ("<b>%s</b>", suggested_word);
+
+ label = gtk_label_new (label_text);
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+
+ menu_item = gtk_menu_item_new ();
+ gtk_container_add (GTK_CONTAINER (menu_item), label);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+
+ data = g_new0 (SuggestionData, 1);
+ data->suggested_word = g_strdup (suggested_word);
+ data->callback = callback;
+ data->user_data = user_data;
+
+ g_object_set_data_full (G_OBJECT (menu_item),
+ SUGGESTION_DATA_KEY,
+ data,
+ suggestion_data_free);
+
+ g_signal_connect (menu_item,
+ "activate",
+ G_CALLBACK (activate_suggestion_cb),
+ NULL);
+
+ g_free (label_text);
+ count++;
+ }
+ }
+
+ g_slist_free_full (suggestions, g_free);
+
+ /* Separator */
+ menu_item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (top_menu), menu_item);
+
+ /* Ignore all */
+ menu_item = gtk_menu_item_new_with_mnemonic (_("_Ignore All"));
+ gtk_menu_shell_append (GTK_MENU_SHELL (top_menu), menu_item);
+
+ data = g_new0 (SuggestionData, 1);
+ data->checker = g_object_ref (checker);
+ data->misspelled_word = g_strdup (misspelled_word);
+
+ g_object_set_data_full (G_OBJECT (menu_item),
+ SUGGESTION_DATA_KEY,
+ data,
+ suggestion_data_free);
+
+ g_signal_connect (menu_item,
+ "activate",
+ G_CALLBACK (ignore_all_cb),
+ NULL);
+
+ /* Add to Dictionary */
+ menu_item = gtk_menu_item_new_with_mnemonic (_("_Add"));
+ gtk_menu_shell_append (GTK_MENU_SHELL (top_menu), menu_item);
+
+ data = g_new0 (SuggestionData, 1);
+ data->checker = g_object_ref (checker);
+ data->misspelled_word = g_strdup (misspelled_word);
+
+ g_object_set_data_full (G_OBJECT (menu_item),
+ SUGGESTION_DATA_KEY,
+ data,
+ suggestion_data_free);
+
+ g_signal_connect (menu_item,
+ "activate",
+ G_CALLBACK (add_to_dictionary_cb),
+ NULL);
+
+ return top_menu;
+}
+
+GtkMenuItem *
+_gspell_context_menu_get_suggestions_menu_item (GspellChecker *checker,
+ const gchar *misspelled_word,
+ GspellSuggestionActivatedCallback callback,
+ gpointer user_data)
+{
+ GtkWidget *suggestion_menu;
+ GtkMenuItem *menu_item;
+
+ g_return_val_if_fail (GSPELL_IS_CHECKER (checker), NULL);
+ g_return_val_if_fail (misspelled_word != NULL, NULL);
+
+ suggestion_menu = get_suggestion_menu (checker,
+ misspelled_word,
+ callback,
+ user_data);
+
+ menu_item = GTK_MENU_ITEM (gtk_menu_item_new_with_mnemonic (_("_Spelling Suggestions…")));
+ gtk_menu_item_set_submenu (menu_item, suggestion_menu);
+ gtk_widget_show_all (GTK_WIDGET (menu_item));
+
+ return menu_item;
+}
+
/* ex:set ts=8 noet: */
diff --git a/gspell/gspell-context-menu.h b/gspell/gspell-context-menu.h
index 5359e15..ee2e430 100644
--- a/gspell/gspell-context-menu.h
+++ b/gspell/gspell-context-menu.h
@@ -21,6 +21,7 @@
#define GSPELL_CONTEXT_MENU_H
#include <gtk/gtk.h>
+#include "gspell-checker.h"
#include "gspell-language.h"
G_BEGIN_DECLS
@@ -28,11 +29,20 @@ G_BEGIN_DECLS
typedef void (*GspellLanguageActivatedCallback) (const GspellLanguage *lang,
gpointer user_data);
+typedef void (*GspellSuggestionActivatedCallback) (const gchar *suggested_word,
+ gpointer user_data);
+
G_GNUC_INTERNAL
GtkMenuItem * _gspell_context_menu_get_language_menu_item (const GspellLanguage
*current_language,
GspellLanguageActivatedCallback callback,
gpointer user_data);
+G_GNUC_INTERNAL
+GtkMenuItem * _gspell_context_menu_get_suggestions_menu_item (GspellChecker *checker,
+ const gchar
*misspelled_word,
+ GspellSuggestionActivatedCallback callback,
+ gpointer
user_data);
+
G_END_DECLS
#endif /* GSPELL_CONTEXT_MENU_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]