[evince] libview: Add inline spell check for annotations



commit 719f7dccdb34f45caf6214ed45fd22fdad158c8a
Author: Will Hawkins <hawkinsw borlaugic com>
Date:   Sun Apr 1 20:22:22 2018 -0400

    libview: Add inline spell check for annotations
    
    For highlight annotations and text annotations,
    add support for inline spell checking of the contents.
    Uses gspell 1.0 to accomplish spell check.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=772622

 configure.ac                         |   20 +++++++++++--
 data/org.gnome.Evince.gschema.xml.in |    3 ++
 libview/ev-annotation-window.c       |   46 ++++++++++++++++++++++++++++++
 libview/ev-annotation-window.h       |    4 ++-
 libview/ev-view-private.h            |    1 +
 libview/ev-view.c                    |   52 ++++++++++++++++++++++++++++++++-
 libview/ev-view.h                    |    3 ++
 shell/ev-window.c                    |   35 +++++++++++++++++++++++
 shell/evince-menus.ui                |    6 ++++
 9 files changed, 164 insertions(+), 6 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 9b818da..0f7bc62 100644
--- a/configure.ac
+++ b/configure.ac
@@ -129,6 +129,7 @@ LIBSECRET_REQUIRED=0.5
 GTK_REQUIRED=3.16.0
 NAUTILUS_REQUIRED=2.91.4
 GDK_PIXBUF_REQUIRED=2.36.5
+GSPELL_REQUIRED=1.6.0
 
 AC_SUBST([GLIB_REQUIRED])
 AC_SUBST([GTK_REQUIRED])
@@ -286,6 +287,19 @@ if test "$with_keyring" = "yes"; then
         PKG_CHECK_MODULES(LIBSECRET, libsecret-1 >= $LIBSECRET_REQUIRED)
         AC_DEFINE([WITH_KEYRING],[1],[Define if KEYRING support is enabled])
 fi
+# *******************
+# Gspell
+# *******************
+
+AC_ARG_WITH(gspell,
+       [AS_HELP_STRING([--without-gspell],
+                       [Disable the gpell support])],
+       [],
+       [with_gspell=yes])
+if test "$with_gspell" = "yes"; then
+       PKG_CHECK_MODULES(GSPELL, gspell-1 >= $GSPELL_REQUIRED)
+       AC_DEFINE([WITH_GSPELL],[1],[Define if GSPELL support is enabled])
+fi
 
 # ****
 # DBUS
@@ -393,8 +407,8 @@ LIBDOCUMENT_LIBS="$LIBDOCUMENT_LIBS"
 AC_SUBST(LIBDOCUMENT_CFLAGS)
 AC_SUBST(LIBDOCUMENT_LIBS)
 
-LIBVIEW_CFLAGS="$LIBVIEW_CFLAGS $GTKUNIXPRINT_CFLAGS $GSTREAMER_CFLAGS $DEBUG_FLAGS"
-LIBVIEW_LIBS="$LIBVIEW_LIBS $GTKUNIXPRINT_LIBS $GSTREAMER_LIBS -lm"
+LIBVIEW_CFLAGS="$LIBVIEW_CFLAGS $GTKUNIXPRINT_CFLAGS $GSTREAMER_CFLAGS $GSPELL_CFLAGS $DEBUG_FLAGS"
+LIBVIEW_LIBS="$LIBVIEW_LIBS $GTKUNIXPRINT_LIBS $GSTREAMER_LIBS $GSPELL_LIBS -lm"
 AC_SUBST(LIBVIEW_CFLAGS)
 AC_SUBST(LIBVIEW_LIBS)
 
@@ -1018,5 +1032,5 @@ Keyring integration ......:  $with_keyring
 GTK+ Unix Print ..........:  $with_gtk_unix_print
 Thumbnail cache ..........:  $enable_gnome_desktop
 Multimedia ...............:  $enable_multimedia
-
+Spell Checker.............:  $with_gspell
 ])
diff --git a/data/org.gnome.Evince.gschema.xml.in b/data/org.gnome.Evince.gschema.xml.in
index 1817a05..093d6f0 100644
--- a/data/org.gnome.Evince.gschema.xml.in
+++ b/data/org.gnome.Evince.gschema.xml.in
@@ -42,6 +42,9 @@
   </schema>
 
   <schema id="org.gnome.Evince.Default" path="/org/gnome/evince/default/" gettext-domain="evince">
+    <key name="enable-spellchecking" type="b">
+      <default>true</default>
+    </key>
     <key name="show-toolbar" type="b">
       <default>true</default>
     </key>
diff --git a/libview/ev-annotation-window.c b/libview/ev-annotation-window.c
index fcdaa98..f405460 100644
--- a/libview/ev-annotation-window.c
+++ b/libview/ev-annotation-window.c
@@ -28,6 +28,11 @@
 #include "ev-view-marshal.h"
 #include "ev-document-misc.h"
 
+#if WITH_GSPELL
+#include <glib/gi18n.h>
+#include <gspell/gspell.h>
+#endif
+
 enum {
        PROP_0,
        PROP_ANNOTATION,
@@ -60,6 +65,11 @@ struct _EvAnnotationWindow {
        gint          y;
        gint          orig_x;
        gint          orig_y;
+
+#if WITH_GSPELL
+       GspellTextView *spellcheck_view;
+       gboolean      enable_spellchecking;
+#endif
 };
 
 struct _EvAnnotationWindowClass {
@@ -354,6 +364,13 @@ ev_annotation_window_init (EvAnnotationWindow *window)
        /* Contents */
        swindow = gtk_scrolled_window_new (NULL, NULL);
        window->text_view = gtk_text_view_new ();
+
+#if WITH_GSPELL
+       window->spellcheck_view = NULL;
+       window->spellcheck_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (window->text_view));
+       gspell_text_view_basic_setup (window->spellcheck_view);
+#endif
+
        gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (window->text_view), GTK_WRAP_WORD);
        g_signal_connect (window->text_view, "state-flags-changed",
                          G_CALLBACK (text_view_state_flags_changed),
@@ -488,6 +505,9 @@ ev_annotation_window_constructor (GType                  type,
                          G_CALLBACK (ev_annotation_window_opacity_changed),
                          window);
 
+#if WITH_GSPELL
+        gspell_text_view_set_inline_spell_checking (window->spellcheck_view, 
ev_annotation_window_get_enable_spellchecking (window));
+#endif
        return object;
 }
 
@@ -694,3 +714,29 @@ ev_annotation_window_ungrab_focus (EvAnnotationWindow *window)
 
        ev_annotation_window_sync_contents (window);
 }
+
+void
+ev_annotation_window_set_enable_spellchecking (EvAnnotationWindow *window,
+                                               gboolean enable_spellchecking)
+{
+        g_return_if_fail (EV_IS_ANNOTATION_WINDOW (window));
+
+#if WITH_GSPELL
+        if (enable_spellchecking == ev_annotation_window_get_enable_spellchecking (window))
+                return;
+
+        window->enable_spellchecking = enable_spellchecking;
+        gspell_text_view_set_inline_spell_checking (window->spellcheck_view, enable_spellchecking);
+#endif
+}
+
+gboolean
+ev_annotation_window_get_enable_spellchecking (EvAnnotationWindow *window)
+{
+        g_return_val_if_fail (EV_IS_ANNOTATION_WINDOW (window), FALSE);
+#if WITH_GSPELL
+        return window->enable_spellchecking;
+#else
+        return FALSE;
+#endif
+}
diff --git a/libview/ev-annotation-window.h b/libview/ev-annotation-window.h
index b9ba4f1..02d8022 100644
--- a/libview/ev-annotation-window.h
+++ b/libview/ev-annotation-window.h
@@ -51,7 +51,9 @@ void          ev_annotation_window_set_rectangle  (EvAnnotationWindow *window,
                                                   const EvRectangle  *rect);
 void          ev_annotation_window_grab_focus     (EvAnnotationWindow *window);
 void          ev_annotation_window_ungrab_focus   (EvAnnotationWindow *window);
-
+void          ev_annotation_window_set_enable_spellchecking (EvAnnotationWindow *window,
+                                                             gboolean spellcheck);
+gboolean      ev_annotation_window_get_enable_spellchecking (EvAnnotationWindow *window);
 G_END_DECLS
 
 #endif /* EV_ANNOTATION_WINDOW_H */
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index 2a387d0..f77a39d 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -229,6 +229,7 @@ struct _EvView {
        AddingAnnotInfo    adding_annot_info;
        MovingAnnotInfo    moving_annot_info;
        GHashTable        *annot_window_map;
+       gboolean           enable_spellchecking;
 
        /* Focus */
        EvMapping *focused_element;
diff --git a/libview/ev-view.c b/libview/ev-view.c
index f4a28f1..e99ee5d 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -3155,7 +3155,7 @@ ev_view_create_annotation_window (EvView       *view,
        ev_view_window_child_put (view, window, page,
                                  view_rect.x, view_rect.y,
                                  doc_rect.x1, doc_rect.y1);
-
+        ev_annotation_window_set_enable_spellchecking (EV_ANNOTATION_WINDOW (window), 
ev_view_get_enable_spellchecking (view));
        return window;
 }
 
@@ -3879,7 +3879,6 @@ ev_view_set_caret_cursor_position (EvView *view,
                        gtk_widget_queue_draw (GTK_WIDGET (view));
        }
 }
-
 /*** GtkWidget implementation ***/
 
 static void
@@ -5718,6 +5717,55 @@ ev_view_add_text_markup_annotation_for_selected_text (EvView  *view)
        return TRUE;
 }
 
+void
+ev_view_set_enable_spellchecking (EvView *view,
+                                  gboolean enabled)
+{
+        EvMappingList *annots;
+        GList         *l;
+        gint           n_pages = 0;
+        gint           current_page;
+
+        g_return_if_fail (EV_IS_VIEW (view));
+
+        view->enable_spellchecking = enabled;
+
+        if (view->document)
+                n_pages = ev_document_get_n_pages (view->document);
+
+        for (current_page = 0; current_page < n_pages; current_page++) {
+                annots = ev_page_cache_get_annot_mapping (view->page_cache, current_page);
+
+                for (l = ev_mapping_list_get_list (annots); l && l->data; l = g_list_next (l)) {
+                        EvAnnotation      *annot;
+                        GtkWidget         *window;
+
+                        annot = ((EvMapping *)(l->data))->data;
+
+                        if (!EV_IS_ANNOTATION_MARKUP (annot))
+                                continue;
+
+                        window = get_window_for_annot (view, annot);
+
+                        if (window) {
+                                ev_annotation_window_set_enable_spellchecking (EV_ANNOTATION_WINDOW 
(window), view->enable_spellchecking);
+                        }
+                }
+        }
+}
+
+gboolean
+ev_view_get_enable_spellchecking (EvView *view)
+{
+        g_return_val_if_fail (EV_IS_VIEW (view), FALSE);
+
+#ifdef WITH_GSPELL
+        return view->enable_spellchecking;
+#else
+        return FALSE;
+#endif
+}
+
 static gboolean
 ev_view_button_release_event (GtkWidget      *widget,
                              GdkEventButton *event)
diff --git a/libview/ev-view.h b/libview/ev-view.h
index d458df0..bf13b9f 100644
--- a/libview/ev-view.h
+++ b/libview/ev-view.h
@@ -127,6 +127,9 @@ void           ev_view_cancel_add_annotation (EvView          *view);
 void           ev_view_remove_annotation     (EvView          *view,
                                              EvAnnotation    *annot);
 gboolean       ev_view_add_text_markup_annotation_for_selected_text (EvView  *view);
+void           ev_view_set_enable_spellchecking (EvView *view,
+                                                 gboolean spellcheck);
+gboolean       ev_view_get_enable_spellchecking (EvView *view);
 
 /* Caret navigation */
 gboolean       ev_view_supports_caret_navigation    (EvView  *view);
diff --git a/shell/ev-window.c b/shell/ev-window.c
index e2ba86a..519865d 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -533,6 +533,11 @@ ev_window_update_actions_sensitivity (EvWindow *ev_window)
                                      !recent_view_mode);
        ev_window_set_action_enabled (ev_window, "inverted-colors",
                                      has_pages && !recent_view_mode);
+#if WITH_GSPELL
+       ev_window_set_action_enabled (ev_window, "enable-spellchecking", TRUE);
+#else
+       ev_window_set_action_enabled (ev_window, "enable-spellchecking", FALSE);
+#endif
 
        /* Bookmarks menu */
        ev_window_set_action_enabled (ev_window, "add-bookmark",
@@ -1412,6 +1417,20 @@ ev_window_setup_default (EvWindow *ev_window)
        ev_document_model_set_sizing_mode (model, g_settings_get_enum (settings, "sizing-mode"));
        if (ev_document_model_get_sizing_mode (model) == EV_SIZING_FREE)
                ev_document_model_set_scale (model, g_settings_get_double (settings, "zoom"));
+
+       g_simple_action_set_state (
+               G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (ev_window),
+                                                            "enable-spellchecking")),
+               g_variant_new_boolean (
+#ifdef WITH_GSPELL
+               g_settings_get_boolean (settings, "enable-spellchecking")
+#else
+               FALSE
+#endif
+               )
+       );
+       ev_view_set_enable_spellchecking (EV_VIEW (ev_window->priv->view),
+               g_settings_get_boolean (settings, "enable-spellchecking"));
 }
 
 static void
@@ -4554,11 +4573,24 @@ ev_window_cmd_view_inverted_colors (GSimpleAction *action,
 }
 
 static void
+ev_window_cmd_view_enable_spellchecking (GSimpleAction *action,
+                                   GVariant      *state,
+                                   gpointer       user_data)
+{
+       EvWindow *ev_window = user_data;
+
+       ev_view_set_enable_spellchecking (EV_VIEW (ev_window->priv->view),
+       g_variant_get_boolean (state));
+       g_simple_action_set_state (action, state);
+}
+
+static void
 ev_window_cmd_edit_save_settings (GSimpleAction *action,
                                  GVariant      *state,
                                  gpointer       user_data)
 {
        EvWindow        *ev_window = user_data;
+       EvView          *ev_view = EV_VIEW (ev_window->priv->view);
        EvWindowPrivate *priv = ev_window->priv;
        EvDocumentModel *model = priv->model;
        GSettings       *settings = priv->default_settings;
@@ -4588,6 +4620,8 @@ ev_window_cmd_edit_save_settings (GSimpleAction *action,
                            gtk_paned_get_position (GTK_PANED (priv->hpaned)));
        g_settings_set_string (settings, "sidebar-page",
                               ev_window_sidebar_get_current_page_id (ev_window));
+       g_settings_set_boolean (settings, "enable-spellchecking",
+                               ev_view_get_enable_spellchecking (ev_view));
        g_settings_apply (settings);
 }
 
@@ -5748,6 +5782,7 @@ static const GActionEntry actions[] = {
        { "dual-odd-left", NULL, NULL, "false", ev_window_cmd_dual_odd_pages_left },
        { "show-side-pane", NULL, NULL, "false", ev_window_view_cmd_toggle_sidebar },
        { "inverted-colors", NULL, NULL, "false", ev_window_cmd_view_inverted_colors },
+       { "enable-spellchecking", NULL, NULL, "false", ev_window_cmd_view_enable_spellchecking },
        { "fullscreen", NULL, NULL, "false", ev_window_cmd_view_fullscreen },
        { "presentation", NULL, NULL, "false", ev_window_cmd_view_presentation },
        { "rotate-left", ev_window_cmd_edit_rotate_left },
diff --git a/shell/evince-menus.ui b/shell/evince-menus.ui
index e9b01d5..50285ed 100644
--- a/shell/evince-menus.ui
+++ b/shell/evince-menus.ui
@@ -123,6 +123,12 @@
         <attribute name="action">win.reload</attribute>
       </item>
     </section>
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">Enable Spellchecking</attribute>
+        <attribute name="action">win.enable-spellchecking</attribute>
+      </item>
+    </section>
   </menu>
 
   <menu id="action-menu">


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