[gspell/wip/choose-language-context-menu] text-view: add :language-menu boolean property



commit be914210f3050ce344ec822f4dd46bbe5e8fcc84
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sun May 8 17:59:25 2016 +0200

    text-view: add :language-menu boolean property
    
    https://bugzilla.gnome.org/show_bug.cgi?id=758415

 docs/reference/gspell-1.0-sections.txt     |    2 +
 gspell/gspell-inline-checker-text-buffer.c |   18 +---
 gspell/gspell-inline-checker-text-buffer.h |    4 +
 gspell/gspell-text-view.c                  |  186 +++++++++++++++++++++++++++-
 gspell/gspell-text-view.h                  |    5 +
 tests/test-spell.c                         |    2 +
 6 files changed, 201 insertions(+), 16 deletions(-)
---
diff --git a/docs/reference/gspell-1.0-sections.txt b/docs/reference/gspell-1.0-sections.txt
index 7217eb3..7e9feba 100644
--- a/docs/reference/gspell-1.0-sections.txt
+++ b/docs/reference/gspell-1.0-sections.txt
@@ -58,6 +58,8 @@ gspell_text_view_get_from_gtk_text_view
 gspell_text_view_get_view
 gspell_text_view_get_inline_spell_checking
 gspell_text_view_set_inline_spell_checking
+gspell_text_view_get_enable_language_menu
+gspell_text_view_set_enable_language_menu
 <SUBSECTION Standard>
 GSPELL_TYPE_TEXT_VIEW
 GspellTextViewClass
diff --git a/gspell/gspell-inline-checker-text-buffer.c b/gspell/gspell-inline-checker-text-buffer.c
index 9fcfe78..7709c24 100644
--- a/gspell/gspell-inline-checker-text-buffer.c
+++ b/gspell/gspell-inline-checker-text-buffer.c
@@ -876,10 +876,9 @@ get_suggestion_menu (GspellInlineCheckerTextBuffer *spell,
        return top_menu;
 }
 
-static void
-populate_popup_cb (GtkTextView                   *view,
-                  GtkMenu                       *menu,
-                  GspellInlineCheckerTextBuffer *spell)
+void
+_gspell_inline_checker_text_buffer_populate_popup (GspellInlineCheckerTextBuffer *spell,
+                                                  GtkMenu                       *menu)
 {
        GtkWidget *menu_item;
        GtkTextIter start;
@@ -896,11 +895,6 @@ populate_popup_cb (GtkTextView                   *view,
                return;
        }
 
-       /* Prepend separator */
-       menu_item = gtk_separator_menu_item_new ();
-       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
-       gtk_widget_show (menu_item);
-
        /* Prepend suggestions */
        menu_item = gtk_menu_item_new_with_mnemonic (_("_Spelling Suggestions..."));
        gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
@@ -1410,12 +1404,6 @@ _gspell_inline_checker_text_buffer_attach_view (GspellInlineCheckerTextBuffer *s
                                 0);
 
        g_signal_connect_object (view,
-                                "populate-popup",
-                                G_CALLBACK (populate_popup_cb),
-                                spell,
-                                0);
-
-       g_signal_connect_object (view,
                                 "draw",
                                 G_CALLBACK (draw_cb),
                                 spell,
diff --git a/gspell/gspell-inline-checker-text-buffer.h b/gspell/gspell-inline-checker-text-buffer.h
index 10063a6..988041b 100644
--- a/gspell/gspell-inline-checker-text-buffer.h
+++ b/gspell/gspell-inline-checker-text-buffer.h
@@ -48,6 +48,10 @@ G_GNUC_INTERNAL
 void   _gspell_inline_checker_text_buffer_detach_view          (GspellInlineCheckerTextBuffer *spell,
                                                                 GtkTextView                   *view);
 
+G_GNUC_INTERNAL
+void   _gspell_inline_checker_text_buffer_populate_popup       (GspellInlineCheckerTextBuffer *spell,
+                                                                GtkMenu                       *menu);
+
 /* For unit tests */
 
 G_GNUC_INTERNAL
diff --git a/gspell/gspell-text-view.c b/gspell/gspell-text-view.c
index 62386da..07a7280 100644
--- a/gspell/gspell-text-view.c
+++ b/gspell/gspell-text-view.c
@@ -17,8 +17,13 @@
  * along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "config.h"
 #include "gspell-text-view.h"
+#include <glib/gi18n-lib.h>
 #include "gspell-inline-checker-text-buffer.h"
+#include "gspell-checker.h"
+#include "gspell-language.h"
+#include "gspell-text-buffer.h"
 
 /**
  * SECTION:text-view
@@ -53,6 +58,7 @@ struct _GspellTextViewPrivate
 {
        GtkTextView *view;
        GspellInlineCheckerTextBuffer *inline_checker;
+       guint enable_language_menu : 1;
 };
 
 enum
@@ -60,9 +66,11 @@ enum
        PROP_0,
        PROP_VIEW,
        PROP_INLINE_SPELL_CHECKING,
+       PROP_ENABLE_LANGUAGE_MENU,
 };
 
-#define GSPELL_TEXT_VIEW_KEY "gspell-text-view-key"
+#define GSPELL_TEXT_VIEW_KEY   "gspell-text-view-key"
+#define LANGUAGE_KEY           "gspell-language-key"
 
 G_DEFINE_TYPE_WITH_PRIVATE (GspellTextView, gspell_text_view, G_TYPE_OBJECT)
 
@@ -121,6 +129,101 @@ notify_buffer_cb (GtkTextView    *gtk_view,
 }
 
 static void
+activate_language_cb (GtkWidget      *menu_item,
+                     GspellTextView *gspell_view)
+{
+       GspellTextViewPrivate *priv;
+       const GspellLanguage *lang;
+       GtkTextBuffer *gtk_buffer;
+       GspellTextBuffer *gspell_buffer;
+       GspellChecker *checker;
+
+       priv = gspell_text_view_get_instance_private (gspell_view);
+
+       lang = g_object_get_data (G_OBJECT (menu_item), LANGUAGE_KEY);
+       if (lang == NULL)
+       {
+               g_return_if_reached ();
+       }
+
+       gtk_buffer = gtk_text_view_get_buffer (priv->view);
+       gspell_buffer = gspell_text_buffer_get_from_gtk_text_buffer (gtk_buffer);
+       checker = gspell_text_buffer_get_spell_checker (gspell_buffer);
+
+       gspell_checker_set_language (checker, lang);
+}
+
+static GtkWidget *
+get_language_menu (GspellTextView *gspell_view)
+{
+       GtkWidget *menu;
+       const GList *languages;
+       const GList *l;
+
+       menu = gtk_menu_new ();
+
+       languages = gspell_language_get_available ();
+       for (l = languages; l != NULL; l = l->next)
+       {
+               GtkWidget *menu_item;
+               const GspellLanguage *lang = l->data;
+
+               menu_item = gtk_menu_item_new_with_label (gspell_language_get_name (lang));
+               gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+
+               g_object_set_data (G_OBJECT (menu_item),
+                                  LANGUAGE_KEY,
+                                  (gpointer) lang);
+
+               g_signal_connect_object (menu_item,
+                                        "activate",
+                                        G_CALLBACK (activate_language_cb),
+                                        gspell_view,
+                                        0);
+       }
+
+       return menu;
+}
+
+static void
+populate_popup_cb (GtkTextView    *gtk_view,
+                  GtkMenu        *menu,
+                  GspellTextView *gspell_view)
+{
+       GspellTextViewPrivate *priv;
+       GtkWidget *menu_item;
+
+       priv = gspell_text_view_get_instance_private (gspell_view);
+
+       if (!priv->enable_language_menu &&
+           priv->inline_checker == NULL)
+       {
+               return;
+       }
+
+       /* Prepend separator */
+       menu_item = gtk_separator_menu_item_new ();
+       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
+       gtk_widget_show (menu_item);
+
+       if (priv->enable_language_menu)
+       {
+               /* Prepend language sub-menu */
+               menu_item = gtk_menu_item_new_with_mnemonic (_("_Language"));
+               gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
+               gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item),
+                                          get_language_menu (gspell_view));
+               gtk_widget_show_all (menu_item);
+       }
+
+       if (priv->inline_checker != NULL)
+       {
+               /* Prepend suggestions */
+               _gspell_inline_checker_text_buffer_populate_popup (priv->inline_checker, menu);
+       }
+}
+
+static void
 set_view (GspellTextView *gspell_view,
          GtkTextView    *gtk_view)
 {
@@ -141,6 +244,12 @@ set_view (GspellTextView *gspell_view,
                                 gspell_view,
                                 0);
 
+       g_signal_connect_object (priv->view,
+                                "populate-popup",
+                                G_CALLBACK (populate_popup_cb),
+                                gspell_view,
+                                0);
+
        g_object_notify (G_OBJECT (gspell_view), "view");
 }
 
@@ -162,6 +271,10 @@ gspell_text_view_get_property (GObject    *object,
                        g_value_set_boolean (value, gspell_text_view_get_inline_spell_checking (gspell_view));
                        break;
 
+               case PROP_ENABLE_LANGUAGE_MENU:
+                       g_value_set_boolean (value, gspell_text_view_get_enable_language_menu (gspell_view));
+                       break;
+
                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                        break;
@@ -186,6 +299,10 @@ gspell_text_view_set_property (GObject      *object,
                        gspell_text_view_set_inline_spell_checking (gspell_view, g_value_get_boolean (value));
                        break;
 
+               case PROP_ENABLE_LANGUAGE_MENU:
+                       gspell_text_view_set_enable_language_menu (gspell_view, g_value_get_boolean (value));
+                       break;
+
                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                        break;
@@ -248,6 +365,23 @@ gspell_text_view_class_init (GspellTextViewClass *klass)
                                                               FALSE,
                                                               G_PARAM_READWRITE |
                                                               G_PARAM_STATIC_STRINGS));
+
+       /**
+        * GspellTextView:enable-language-menu:
+        *
+        * When the context menu is shown, whether to add a sub-menu to select
+        * the language for the spell checking.
+        *
+        * Since: 1.2
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_ENABLE_LANGUAGE_MENU,
+                                        g_param_spec_boolean ("enable-language-menu",
+                                                              "Enable Language Menu",
+                                                              "",
+                                                              FALSE,
+                                                              G_PARAM_READWRITE |
+                                                              G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -355,4 +489,54 @@ gspell_text_view_set_inline_spell_checking (GspellTextView *gspell_view,
        g_object_notify (G_OBJECT (gspell_view), "inline-spell-checking");
 }
 
+/**
+ * gspell_text_view_get_enable_language_menu:
+ * @gspell_view: a #GspellTextView.
+ *
+ * Returns: whether the language context menu is enabled.
+ * Since: 1.2
+ */
+gboolean
+gspell_text_view_get_enable_language_menu (GspellTextView *gspell_view)
+{
+       GspellTextViewPrivate *priv;
+
+       g_return_val_if_fail (GSPELL_IS_TEXT_VIEW (gspell_view), FALSE);
+
+       priv = gspell_text_view_get_instance_private (gspell_view);
+       return priv->enable_language_menu;
+}
+
+/**
+ * gspell_text_view_set_enable_language_menu:
+ * @gspell_view: a #GspellTextView.
+ * @enable_language_menu: whether to enable the language context menu.
+ *
+ * Sets whether to enable the language context menu. If enabled, doing a right
+ * click on the #GtkTextView will show a sub-menu to choose the language for the
+ * spell checking. If another language is chosen, it changes the
+ * #GspellChecker:language property of the #GspellTextBuffer:spell-checker of
+ * the #GtkTextView:buffer of the #GspellTextView:view.
+ *
+ * Since: 1.2
+ */
+void
+gspell_text_view_set_enable_language_menu (GspellTextView *gspell_view,
+                                          gboolean        enable_language_menu)
+{
+       GspellTextViewPrivate *priv;
+
+       g_return_if_fail (GSPELL_IS_TEXT_VIEW (gspell_view));
+
+       priv = gspell_text_view_get_instance_private (gspell_view);
+
+       enable_language_menu = enable_language_menu != FALSE;
+
+       if (priv->enable_language_menu != enable_language_menu)
+       {
+               priv->enable_language_menu = enable_language_menu;
+               g_object_notify (G_OBJECT (gspell_view), "enable-language-menu");
+       }
+}
+
 /* ex:set ts=8 noet: */
diff --git a/gspell/gspell-text-view.h b/gspell/gspell-text-view.h
index b11e554..be764f6 100644
--- a/gspell/gspell-text-view.h
+++ b/gspell/gspell-text-view.h
@@ -50,6 +50,11 @@ gboolean             gspell_text_view_get_inline_spell_checking      (GspellTextView 
*gspell_vie
 void                   gspell_text_view_set_inline_spell_checking      (GspellTextView *gspell_view,
                                                                         gboolean        enable);
 
+gboolean               gspell_text_view_get_enable_language_menu       (GspellTextView *gspell_view);
+
+void                   gspell_text_view_set_enable_language_menu       (GspellTextView *gspell_view,
+                                                                        gboolean        
enable_language_menu);
+
 G_END_DECLS
 
 #endif /* GSPELL_TEXT_VIEW_H */
diff --git a/tests/test-spell.c b/tests/test-spell.c
index d079021..2b19544 100644
--- a/tests/test-spell.c
+++ b/tests/test-spell.c
@@ -142,6 +142,8 @@ get_sidebar (TestSpell *spell)
                           highlight_checkbutton);
 
        gspell_view = gspell_text_view_get_from_gtk_text_view (spell->view);
+       gspell_text_view_set_enable_language_menu (gspell_view, TRUE);
+
        g_object_bind_property (highlight_checkbutton, "active",
                                gspell_view, "inline-spell-checking",
                                G_BINDING_DEFAULT);


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