[gedit/wip/search: 2/2] Fix sensitivity of search menu actions



commit 85dd592a6d258705515db661988c43583109065b
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Tue Aug 13 16:33:48 2013 +0200

    Fix sensitivity of search menu actions
    
    For the find prev, find next and clear highlight menu actions. They
    relied on the "search-text" buffer property. But now the "search-text"
    property is in the SearchSettings. And the SearchSettings is accessible
    via a SearchContext. And GeditDocument can have two different
    SearchContext (from GeditViewFrame and from the search and replace).
    
    So it is a little more difficult to implement.

 gedit/gedit-document.c |  110 +++++++++++++++++++++++++++++++++++++++++++++--
 gedit/gedit-document.h |    2 +
 gedit/gedit-window.c   |   17 ++++----
 3 files changed, 116 insertions(+), 13 deletions(-)
---
diff --git a/gedit/gedit-document.c b/gedit/gedit-document.c
index 7cace58..2998f97 100644
--- a/gedit/gedit-document.c
+++ b/gedit/gedit-document.c
@@ -138,6 +138,12 @@ struct _GeditDocumentPrivate
        guint language_set_by_user : 1;
        guint stop_cursor_moved_emission : 1;
        guint dispose_has_run : 1;
+
+       /* The search is empty if there is no search context, or if the
+        * search text is empty. It is used for the sensitivity of some menu
+        * actions.
+        */
+       guint empty_search : 1;
 };
 
 enum {
@@ -152,7 +158,8 @@ enum {
        PROP_CAN_SEARCH_AGAIN,
        PROP_ENABLE_SEARCH_HIGHLIGHTING,
        PROP_NEWLINE_TYPE,
-       PROP_COMPRESSION_TYPE
+       PROP_COMPRESSION_TYPE,
+       PROP_EMPTY_SEARCH
 };
 
 enum {
@@ -366,6 +373,9 @@ gedit_document_get_property (GObject    *object,
                case PROP_COMPRESSION_TYPE:
                        g_value_set_enum (value, doc->priv->compression_type);
                        break;
+               case PROP_EMPTY_SEARCH:
+                       g_value_set_boolean (value, doc->priv->empty_search);
+                       break;
                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                        break;
@@ -592,6 +602,22 @@ gedit_document_class_init (GeditDocumentClass *klass)
                                                            G_PARAM_STATIC_NAME |
                                                            G_PARAM_STATIC_BLURB));
 
+       /**
+        * GeditDocument:empty-search:
+        *
+        * <warning>
+        * The property is used internally by gedit. It must not be used in a
+        * gedit plugin. The property can be modified or removed at any time.
+        * </warning>
+        */
+       g_object_class_install_property (object_class, PROP_EMPTY_SEARCH,
+                                        g_param_spec_boolean ("empty-search",
+                                                              "Empty search",
+                                                              "Whether the search is empty",
+                                                              TRUE,
+                                                              G_PARAM_READABLE |
+                                                              G_PARAM_STATIC_STRINGS));
+
        /* This signal is used to update the cursor position is the statusbar,
         * it's emitted either when the insert mark is moved explicitely or
         * when the buffer changes (insert/delete).
@@ -994,6 +1020,8 @@ gedit_document_init (GeditDocument *doc)
        priv->last_save_was_manually = TRUE;
        priv->language_set_by_user = FALSE;
 
+       priv->empty_search = TRUE;
+
        priv->dispose_has_run = FALSE;
 
        priv->mtime.tv_sec = 0;
@@ -2990,24 +3018,88 @@ _gedit_document_apply_error_style (GeditDocument *doc,
                                   end);
 }
 
+static void
+update_empty_search (GeditDocument *doc)
+{
+       gboolean new_value;
+
+       if (doc->priv->search_context == NULL)
+       {
+               new_value = TRUE;
+       }
+       else
+       {
+               GtkSourceSearchSettings *search_settings;
+
+               search_settings = gtk_source_search_context_get_settings (doc->priv->search_context);
+
+               new_value = gtk_source_search_settings_get_search_text (search_settings) == NULL;
+       }
+
+       if (doc->priv->empty_search != new_value)
+       {
+               doc->priv->empty_search = new_value;
+               g_object_notify (G_OBJECT (doc), "empty-search");
+       }
+}
+
+static void
+connect_search_settings (GeditDocument *doc)
+{
+       GtkSourceSearchSettings *search_settings;
+
+       search_settings = gtk_source_search_context_get_settings (doc->priv->search_context);
+
+       /* Note: the signal handler is never disconnected. If the search context
+        * changes its search settings, the old search settings will most
+        * probably be destroyed, anyway. So it shouldn't cause performance
+        * problems.
+        */
+       g_signal_connect_object (search_settings,
+                                "notify::search-text",
+                                G_CALLBACK (update_empty_search),
+                                doc,
+                                G_CONNECT_SWAPPED);
+}
+
 void
 _gedit_document_set_search_context (GeditDocument          *doc,
                                    GtkSourceSearchContext *search_context)
 {
        g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 
-       g_clear_object (&doc->priv->search_context);
+       if (doc->priv->search_context != NULL)
+       {
+               g_signal_handlers_disconnect_by_func (doc->priv->search_context,
+                                                     connect_search_settings,
+                                                     doc);
+
+               g_object_unref (doc->priv->search_context);
+       }
+
        doc->priv->search_context = search_context;
 
        if (search_context != NULL)
        {
-               gboolean highlight = g_settings_get_boolean (doc->priv->editor_settings,
-                                                            GEDIT_SETTINGS_SEARCH_HIGHLIGHTING);
+               gboolean highlight;
+
+               g_object_ref (search_context);
+
+               highlight = g_settings_get_boolean (doc->priv->editor_settings,
+                                                   GEDIT_SETTINGS_SEARCH_HIGHLIGHTING);
 
                gtk_source_search_context_set_highlight (search_context, highlight);
 
-               g_object_ref (search_context);
+               g_signal_connect_object (search_context,
+                                        "notify::settings",
+                                        G_CALLBACK (connect_search_settings),
+                                        doc,
+                                        G_CONNECT_SWAPPED);
+
+               connect_search_settings (doc);
        }
+
+       update_empty_search (doc);
 }
 
 GtkSourceSearchContext *
@@ -3018,4 +3110,12 @@ _gedit_document_get_search_context (GeditDocument *doc)
        return doc->priv->search_context;
 }
 
+gboolean
+_gedit_document_get_empty_search (GeditDocument *doc)
+{
+       g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), TRUE);
+
+       return doc->priv->empty_search;
+}
+
 /* ex:set ts=8 noet: */
diff --git a/gedit/gedit-document.h b/gedit/gedit-document.h
index e5965e0..7ce4d3a 100644
--- a/gedit/gedit-document.h
+++ b/gedit/gedit-document.h
@@ -381,6 +381,8 @@ void                         _gedit_document_set_search_context     (GeditDocument        
  *doc,
 
 GtkSourceSearchContext *_gedit_document_get_search_context     (GeditDocument          *doc);
 
+gboolean                _gedit_document_get_empty_search       (GeditDocument          *doc);
+
 G_END_DECLS
 
 #endif /* __GEDIT_DOCUMENT_H__ */
diff --git a/gedit/gedit-window.c b/gedit/gedit-window.c
index f4a088c..c8f5c40 100644
--- a/gedit/gedit-window.c
+++ b/gedit/gedit-window.c
@@ -62,6 +62,7 @@
 #include "gedit-status-menu-button.h"
 #include "gedit-settings.h"
 #include "gedit-marshal.h"
+#include "gedit-document.h"
 
 #define LANGUAGE_NONE (const gchar *)"LangNone"
 #define TAB_WIDTH_DATA "GeditWindowTabWidthData"
@@ -789,7 +790,7 @@ set_sensitivity_according_to_tab (GeditWindow *window,
                                  state_normal &&
                                  editable);
 
-       b = TRUE;
+       b = !_gedit_document_get_empty_search (doc);
        action = gtk_action_group_get_action (window->priv->action_group,
                                              "SearchFindNext");
        gtk_action_set_sensitive (action,
@@ -2863,9 +2864,9 @@ fullscreen_controls_build (GeditWindow *window)
 }
 
 static void
-search_text_notify_cb (GeditDocument *doc,
-                      GParamSpec    *pspec,
-                      GeditWindow   *window)
+empty_search_notify_cb (GeditDocument *doc,
+                       GParamSpec    *pspec,
+                       GeditWindow   *window)
 {
        gboolean sensitive;
        GtkAction *action;
@@ -2873,7 +2874,7 @@ search_text_notify_cb (GeditDocument *doc,
        if (doc != gedit_window_get_active_document (window))
                return;
 
-       sensitive = TRUE;
+       sensitive = !_gedit_document_get_empty_search (doc);
 
        action = gtk_action_group_get_action (window->priv->action_group,
                                              "SearchFindNext");
@@ -3089,8 +3090,8 @@ on_tab_added (GeditMultiNotebook *multi,
                          G_CALLBACK (update_cursor_position_statusbar),
                          window);
        g_signal_connect (doc,
-                         "notify::search-text",
-                         G_CALLBACK (search_text_notify_cb),
+                         "notify::empty-search",
+                         G_CALLBACK (empty_search_notify_cb),
                          window);
        g_signal_connect (doc,
                          "notify::can-undo",
@@ -3167,7 +3168,7 @@ on_tab_removed (GeditMultiNotebook *multi,
                                              G_CALLBACK (update_cursor_position_statusbar),
                                              window);
        g_signal_handlers_disconnect_by_func (doc,
-                                             G_CALLBACK (search_text_notify_cb),
+                                             G_CALLBACK (empty_search_notify_cb),
                                              window);
        g_signal_handlers_disconnect_by_func (doc,
                                              G_CALLBACK (can_undo),


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