[gedit/wip/use-tagged-entry: 2/2] ViewFrame: use the custom GdTaggedEntry



commit 01fb2ea14ab5e1d2478326b044e23e934ff1f896
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sat Jul 13 14:58:51 2013 +0200

    ViewFrame: use the custom GdTaggedEntry
    
    There are several problems:
    - the entry is resized all the time, it should have a fixed size
      instead;
    
    - the tag disappear and reappear almost at each character
      insertion/deletion in the search entry. Which doesn't help the first
      point. The problem is that during the scanning of the buffer, the
      search-occurrences-count is 0. We don't know if the scan is finished
      and there are no occurrences, or if the scan is not finished. It
      should instead return -1 when the scan is not finished (-1 means "not
      yet known", like for the search-occurrence-position).

 gedit/gedit-view-frame.c  |  130 +++++++++++++++++++++++++++++++++++++++++----
 gedit/gedit-view-frame.ui |    2 +-
 2 files changed, 121 insertions(+), 11 deletions(-)
---
diff --git a/gedit/gedit-view-frame.c b/gedit/gedit-view-frame.c
index 172623e..1775062 100644
--- a/gedit/gedit-view-frame.c
+++ b/gedit/gedit-view-frame.c
@@ -28,6 +28,7 @@
 #include "gedit-view-frame.h"
 #include "gedit-debug.h"
 #include "gedit-utils.h"
+#include "gd-tagged-entry.h"
 
 #include <gtksourceview/gtksource.h>
 #include <gdk/gdkkeysyms.h>
@@ -63,7 +64,7 @@ struct _GeditViewFramePrivate
        gchar       *old_search_text;
 
        GtkRevealer *slider;
-       GtkEntry    *search_entry;
+       GdTaggedEntry *search_entry;
        GtkWidget   *go_up_button;
        GtkWidget   *go_down_button;
 
@@ -71,6 +72,7 @@ struct _GeditViewFramePrivate
        glong        view_scroll_event_id;
        glong        search_entry_focus_out_id;
        glong        search_entry_changed_id;
+       guint        idle_update_entry_tag_id;
 
        guint        disable_popdown : 1;
 
@@ -125,6 +127,12 @@ gedit_view_frame_dispose (GObject *object)
                frame->priv->typeselect_flush_timeout = 0;
        }
 
+       if (frame->priv->idle_update_entry_tag_id != 0)
+       {
+               g_source_remove (frame->priv->idle_update_entry_tag_id);
+               frame->priv->idle_update_entry_tag_id = 0;
+       }
+
        G_OBJECT_CLASS (gedit_view_frame_parent_class)->dispose (object);
 }
 
@@ -236,7 +244,7 @@ static void
 finish_search (GeditViewFrame    *frame,
               gboolean           found)
 {
-       const gchar *entry_text = gtk_entry_get_text (frame->priv->search_entry);
+       const gchar *entry_text = gtk_entry_get_text (GTK_ENTRY (frame->priv->search_entry));
 
        if (found || (*entry_text == '\0'))
        {
@@ -527,6 +535,69 @@ search_widget_key_press_event (GtkWidget      *widget,
 }
 
 static void
+update_entry_tag (GeditViewFrame *frame)
+{
+       GtkTextBuffer *buffer;
+       GtkTextIter select_start;
+       GtkTextIter select_end;
+       guint count;
+       gint pos;
+
+       gd_tagged_entry_remove_tag (frame->priv->search_entry, "search-occurrences");
+
+       if (frame->priv->search_mode == GOTO_LINE)
+       {
+               return;
+       }
+
+       buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (frame->priv->view));
+
+       count = gtk_source_buffer_get_search_occurrences_count (GTK_SOURCE_BUFFER (buffer));
+
+       gtk_text_buffer_get_selection_bounds (buffer, &select_start, &select_end);
+
+       pos = gtk_source_buffer_get_search_occurrence_position (GTK_SOURCE_BUFFER (buffer),
+                                                               &select_start,
+                                                               &select_end);
+
+       if (pos > 0)
+       {
+               /* Translators: %d is the position of the current search occurrence,
+                * and %u is the total number of search occurrences.
+                */
+               gchar *label = g_strdup_printf (_("%d of %u"), pos, count);
+
+               gd_tagged_entry_append_tag_styled (frame->priv->search_entry,
+                                                  "search-occurrences",
+                                                  label,
+                                                  "gedit-search-entry-occurrences-tag",
+                                                  FALSE);
+
+               g_free (label);
+       }
+}
+
+static gboolean
+update_entry_tag_idle_cb (GeditViewFrame *frame)
+{
+       frame->priv->idle_update_entry_tag_id = 0;
+
+       update_entry_tag (frame);
+
+       return G_SOURCE_REMOVE;
+}
+
+static void
+install_update_entry_tag_idle (GeditViewFrame *frame)
+{
+       if (frame->priv->idle_update_entry_tag_id == 0)
+       {
+               frame->priv->idle_update_entry_tag_id = g_idle_add ((GSourceFunc)update_entry_tag_idle_cb,
+                                                                   frame);
+       }
+}
+
+static void
 update_search (GeditViewFrame *frame)
 {
        GtkSourceBuffer *buffer;
@@ -535,7 +606,7 @@ update_search (GeditViewFrame *frame)
 
        buffer = GTK_SOURCE_BUFFER (gedit_view_frame_get_document (frame));
 
-       entry_text = gtk_entry_get_text (frame->priv->search_entry);
+       entry_text = gtk_entry_get_text (GTK_ENTRY (frame->priv->search_entry));
        unescaped_entry_text = gtk_source_utils_unescape_search_text (entry_text);
 
        gtk_source_buffer_set_search_text (buffer, unescaped_entry_text);
@@ -849,7 +920,7 @@ customize_for_search_mode (GeditViewFrame *frame)
                gtk_widget_hide (frame->priv->go_down_button);
        }
 
-       gtk_entry_set_icon_from_gicon (frame->priv->search_entry,
+       gtk_entry_set_icon_from_gicon (GTK_ENTRY (frame->priv->search_entry),
                                       GTK_ENTRY_ICON_PRIMARY,
                                       icon);
 
@@ -858,6 +929,7 @@ customize_for_search_mode (GeditViewFrame *frame)
 
 static void
 search_init (GtkWidget      *entry,
+            GParamSpec     *pspec,
              GeditViewFrame *frame)
 {
        const gchar *entry_text;
@@ -978,8 +1050,40 @@ on_go_down_button_clicked (GtkWidget      *button,
 }
 
 static void
+mark_set_cb (GtkTextBuffer  *buffer,
+            GtkTextIter    *location,
+            GtkTextMark    *mark,
+            GeditViewFrame *frame)
+{
+       GtkTextMark *insert;
+       GtkTextMark *selection_bound;
+
+       insert = gtk_text_buffer_get_insert (buffer);
+       selection_bound = gtk_text_buffer_get_selection_bound (buffer);
+
+       if (mark == insert || mark == selection_bound)
+       {
+               install_update_entry_tag_idle (frame);
+       }
+}
+
+static void
 setup_search_widget (GeditViewFrame *frame)
 {
+       GtkTextBuffer *buffer;
+
+       buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (frame->priv->view));
+
+       g_signal_connect (buffer,
+                         "mark-set",
+                         G_CALLBACK (mark_set_cb),
+                         frame);
+
+       g_signal_connect_swapped (buffer,
+                                 "notify::search-occurrences-count",
+                                 G_CALLBACK (install_update_entry_tag_idle),
+                                 frame);
+
        g_signal_connect (frame->priv->slider,
                          "key-press-event",
                          G_CALLBACK (search_widget_key_press_event),
@@ -1010,9 +1114,13 @@ setup_search_widget (GeditViewFrame *frame)
                          G_CALLBACK (search_entry_insert_text),
                          frame);
 
+       /* Use the "notify::text" signal, because the "changed" signal is
+        * delayed with a GtkSearchEntry.
+        * See https://bugzilla.gnome.org/show_bug.cgi?id=700229
+        */
        frame->priv->search_entry_changed_id =
                g_signal_connect (frame->priv->search_entry,
-                                 "changed",
+                                 "notify::text",
                                  G_CALLBACK (search_init),
                                  frame);
 
@@ -1088,7 +1196,7 @@ init_search_entry (GeditViewFrame *frame)
 
                line_str = g_strdup_printf ("%d", line + 1);
 
-               gtk_entry_set_text (frame->priv->search_entry, line_str);
+               gtk_entry_set_text (GTK_ENTRY (frame->priv->search_entry), line_str);
 
                gtk_editable_select_region (GTK_EDITABLE (frame->priv->search_entry),
                                            0, -1);
@@ -1120,7 +1228,7 @@ init_search_entry (GeditViewFrame *frame)
 
                if (selection_exists && (search_text != NULL) && (selection_len <= 160))
                {
-                       gtk_entry_set_text (frame->priv->search_entry, search_text);
+                       gtk_entry_set_text (GTK_ENTRY (frame->priv->search_entry), search_text);
 
                        gtk_editable_set_position (GTK_EDITABLE (frame->priv->search_entry),
                                                   -1);
@@ -1132,7 +1240,7 @@ init_search_entry (GeditViewFrame *frame)
                        g_signal_handler_block (frame->priv->search_entry,
                                                frame->priv->search_entry_changed_id);
 
-                       gtk_entry_set_text (frame->priv->search_entry, old_search_text);
+                       gtk_entry_set_text (GTK_ENTRY (frame->priv->search_entry), old_search_text);
 
                        gtk_editable_select_region (GTK_EDITABLE (frame->priv->search_entry),
                                                    0, -1);
@@ -1192,7 +1300,7 @@ start_interactive_search_real (GeditViewFrame *frame)
        g_signal_handler_block (frame->priv->search_entry,
                                frame->priv->search_entry_changed_id);
 
-       gtk_entry_set_text (frame->priv->search_entry, "");
+       gtk_entry_set_text (GTK_ENTRY (frame->priv->search_entry), "");
 
        g_signal_handler_unblock (frame->priv->search_entry,
                                  frame->priv->search_entry_changed_id);
@@ -1212,6 +1320,8 @@ start_interactive_search_real (GeditViewFrame *frame)
                g_timeout_add_seconds (GEDIT_VIEW_FRAME_SEARCH_TIMEOUT,
                                       (GSourceFunc) search_entry_flush_timeout,
                                       frame);
+
+       install_update_entry_tag_idle (frame);
 }
 
 static void
@@ -1355,7 +1465,7 @@ gedit_view_frame_clear_search (GeditViewFrame *frame)
        g_signal_handler_block (frame->priv->search_entry,
                                frame->priv->search_entry_changed_id);
 
-       gtk_entry_set_text (frame->priv->search_entry, "");
+       gtk_entry_set_text (GTK_ENTRY (frame->priv->search_entry), "");
 
        g_signal_handler_unblock (frame->priv->search_entry,
                                  frame->priv->search_entry_changed_id);
diff --git a/gedit/gedit-view-frame.ui b/gedit/gedit-view-frame.ui
index f6d44e6..4757a22 100644
--- a/gedit/gedit-view-frame.ui
+++ b/gedit/gedit-view-frame.ui
@@ -45,7 +45,7 @@
                   <class name="linked"/>
                 </style>
                 <child>
-                  <object class="GtkEntry" id="search_entry">
+                  <object class="GdTaggedEntry" id="search_entry">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="width_chars">25</property>


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