[gnome-text-editor] spellcheck: update menu when showing context menu



commit 183385f2b803e0735c47c8ac57ce750c355d4b7e
Author: Christian Hergert <chergert redhat com>
Date:   Thu Jul 1 17:40:43 2021 -0700

    spellcheck: update menu when showing context menu

 src/editor-source-view.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 89 insertions(+), 3 deletions(-)
---
diff --git a/src/editor-source-view.c b/src/editor-source-view.c
index c7e83de..8a07a94 100644
--- a/src/editor-source-view.c
+++ b/src/editor-source-view.c
@@ -28,6 +28,7 @@
 struct _EditorSourceView
 {
   GtkSourceView parent_instance;
+  GMenuModel *spelling_menu;
 };
 
 G_DEFINE_TYPE (EditorSourceView, editor_source_view, GTK_SOURCE_TYPE_VIEW)
@@ -98,6 +99,71 @@ tweak_gutter_spacing (GtkSourceView *view)
     }
 }
 
+static void
+on_click_pressed_cb (GtkGestureClick  *click,
+                     int               n_press,
+                     double            x,
+                     double            y,
+                     EditorSourceView *self)
+{
+  GdkEventSequence *sequence;
+  GdkEvent *event;
+
+  g_assert (EDITOR_IS_SOURCE_VIEW (self));
+  g_assert (GTK_IS_GESTURE_CLICK (click));
+
+  sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (click));
+  event = gtk_gesture_get_last_event (GTK_GESTURE (click), sequence);
+
+  if (n_press == 1 && gdk_event_triggers_context_menu (event))
+    {
+      g_autofree char *word = NULL;
+      GtkTextBuffer *buffer;
+      GtkTextIter iter, begin, end;
+      int buf_x, buf_y;
+
+      editor_spell_menu_set_corrections (self->spelling_menu, NULL);
+
+      /* Move the cursor position to where the click occurred so that
+       * the context menu will be useful for the click location.
+       */
+      buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self));
+      if (gtk_text_buffer_get_selection_bounds (buffer, &begin, &end))
+        return;
+
+      gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (self),
+                                             GTK_TEXT_WINDOW_WIDGET,
+                                             x, y, &buf_x, &buf_y);
+      gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (self), &iter, buf_x, buf_y);
+      gtk_text_buffer_select_range (buffer, &iter, &iter);
+
+      /* Get the word under the cursor */
+      gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
+      begin = iter;
+      if (!gtk_text_iter_starts_word (&begin))
+        gtk_text_iter_backward_word_start (&begin);
+      end = begin;
+      if (!gtk_text_iter_ends_word (&end))
+        gtk_text_iter_forward_word_end (&end);
+      if (!gtk_text_iter_equal (&begin, &end) &&
+          gtk_text_iter_compare (&begin, &iter) <= 0 &&
+          gtk_text_iter_compare (&iter, &end) <= 0)
+        {
+          word = gtk_text_iter_get_slice (&begin, &end);
+
+          if (!_editor_document_check_spelling (EDITOR_DOCUMENT (buffer), word))
+            {
+              g_auto(GStrv) corrections = _editor_document_list_corrections (EDITOR_DOCUMENT (buffer), word);
+#if 0
+              gtk_text_buffer_select_range (buffer, &begin, &end);
+#endif
+              editor_spell_menu_set_corrections (self->spelling_menu,
+                                                 (const char * const *)corrections);
+            }
+        }
+    }
+}
+
 static void
 on_notify_buffer_cb (EditorSourceView *self,
                      GParamSpec       *pspec,
@@ -113,15 +179,27 @@ on_notify_buffer_cb (EditorSourceView *self,
     _editor_document_attach_actions (EDITOR_DOCUMENT (buffer), GTK_WIDGET (self));
 }
 
+static void
+editor_source_view_finalize (GObject *object)
+{
+  EditorSourceView *self = (EditorSourceView *)object;
+
+  g_clear_object (&self->spelling_menu);
+
+  G_OBJECT_CLASS (editor_source_view_parent_class)->finalize (object);
+}
+
 static void
 editor_source_view_class_init (EditorSourceViewClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = editor_source_view_finalize;
 }
 
 static void
 editor_source_view_init (EditorSourceView *self)
 {
-  g_autoptr(GMenuModel) spelling_menu = NULL;
   g_autoptr(EditorJoinedMenu) joined = NULL;
   GtkEventController *controller;
   GMenuModel *extra_menu;
@@ -138,14 +216,22 @@ editor_source_view_init (EditorSourceView *self)
                     self);
   gtk_widget_add_controller (GTK_WIDGET (self), controller);
 
+  controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ());
+  gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (controller), 0);
+  g_signal_connect (controller,
+                    "pressed",
+                    G_CALLBACK (on_click_pressed_cb),
+                    self);
+  gtk_widget_add_controller (GTK_WIDGET (self), controller);
+
   tweak_gutter_spacing (GTK_SOURCE_VIEW (self));
 
   joined = editor_joined_menu_new ();
   extra_menu = gtk_text_view_get_extra_menu (GTK_TEXT_VIEW (self));
   editor_joined_menu_append_menu (joined, extra_menu);
 
-  spelling_menu = editor_spell_menu_new ();
-  editor_joined_menu_append_menu (joined, spelling_menu);
+  self->spelling_menu = editor_spell_menu_new ();
+  editor_joined_menu_append_menu (joined, self->spelling_menu);
 
   gtk_text_view_set_extra_menu (GTK_TEXT_VIEW (self), G_MENU_MODEL (joined));
 }


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