[gtksourceview] tag: add a property to draw spaces



commit 8c51a6a3fc268b5c0fd7f32c94fac526b51560f4
Author: Sébastien Wilmet <sebastien wilmet uclouvain be>
Date:   Tue Sep 8 14:43:19 2015 +0200

    tag: add a property to draw spaces
    
    https://bugzilla.gnome.org/show_bug.cgi?id=744179

 gtksourceview/gtksourcetag.c  |  107 +++++++++++++++++++++++-
 gtksourceview/gtksourceview.c |  188 +++++++++++++++++++++++++++++++----------
 2 files changed, 249 insertions(+), 46 deletions(-)
---
diff --git a/gtksourceview/gtksourcetag.c b/gtksourceview/gtksourcetag.c
index d09bb9e..e85569a 100644
--- a/gtksourceview/gtksourcetag.c
+++ b/gtksourceview/gtksourcetag.c
@@ -37,15 +37,118 @@ typedef struct _GtkSourceTagPrivate GtkSourceTagPrivate;
 
 struct _GtkSourceTagPrivate
 {
-       gint something;
+       guint draw_spaces : 1;
+       guint draw_spaces_set : 1;
+};
+
+enum
+{
+       PROP_0,
+       PROP_DRAW_SPACES,
+       PROP_DRAW_SPACES_SET,
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceTag, gtk_source_tag, GTK_TYPE_TEXT_TAG)
 
 static void
+gtk_source_tag_get_property (GObject    *object,
+                            guint       prop_id,
+                            GValue     *value,
+                            GParamSpec *pspec)
+{
+       GtkSourceTagPrivate *priv;
+
+       priv = gtk_source_tag_get_instance_private (GTK_SOURCE_TAG (object));
+
+       switch (prop_id)
+       {
+               case PROP_DRAW_SPACES:
+                       g_value_set_boolean (value, priv->draw_spaces);
+                       break;
+
+               case PROP_DRAW_SPACES_SET:
+                       g_value_set_boolean (value, priv->draw_spaces_set);
+                       break;
+
+               default:
+                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                       break;
+       }
+}
+
+static void
+gtk_source_tag_set_property (GObject      *object,
+                            guint         prop_id,
+                            const GValue *value,
+                            GParamSpec   *pspec)
+{
+       GtkSourceTagPrivate *priv;
+
+       priv = gtk_source_tag_get_instance_private (GTK_SOURCE_TAG (object));
+
+       switch (prop_id)
+       {
+               case PROP_DRAW_SPACES:
+                       priv->draw_spaces = g_value_get_boolean (value);
+                       priv->draw_spaces_set = TRUE;
+                       g_object_notify (object, "draw-spaces-set");
+                       break;
+
+               case PROP_DRAW_SPACES_SET:
+                       priv->draw_spaces_set = g_value_get_boolean (value);
+                       break;
+
+               default:
+                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                       break;
+       }
+}
+
+static void
 gtk_source_tag_class_init (GtkSourceTagClass *klass)
 {
-       /*GObjectClass *object_class = G_OBJECT_CLASS (klass);*/
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->get_property = gtk_source_tag_get_property;
+       object_class->set_property = gtk_source_tag_set_property;
+
+       /**
+        * GtkSourceTag:draw-spaces:
+        *
+        * Whether to draw spaces. This property takes precedence over the value
+        * defined by the GtkSourceView's #GtkSourceView:draw-spaces property
+        * (only where the tag is applied).
+        *
+        * Setting this property also changes #GtkSourceTag:draw-spaces-set to
+        * %TRUE.
+        *
+        * Since: 3.20
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_DRAW_SPACES,
+                                        g_param_spec_boolean ("draw-spaces",
+                                                              "Draw Spaces",
+                                                              "",
+                                                              FALSE,
+                                                              G_PARAM_READWRITE |
+                                                              G_PARAM_STATIC_STRINGS));
+
+       /**
+        * GtkSourceTag:draw-spaces-set:
+        *
+        * Whether the #GtkSourceTag:draw-spaces property is set and must be
+        * taken into account.
+        *
+        * Since: 3.20
+        */
+       g_object_class_install_property (object_class,
+                                        PROP_DRAW_SPACES_SET,
+                                        g_param_spec_boolean ("draw-spaces-set",
+                                                              "Draw Spaces Set",
+                                                              "",
+                                                              FALSE,
+                                                              G_PARAM_READWRITE |
+                                                              G_PARAM_STATIC_STRINGS));
 }
 
 static void
diff --git a/gtksourceview/gtksourceview.c b/gtksourceview/gtksourceview.c
index cd34ecc..d1ffdaa 100644
--- a/gtksourceview/gtksourceview.c
+++ b/gtksourceview/gtksourceview.c
@@ -48,6 +48,7 @@
 #include "gtksourcegutterrendererlines.h"
 #include "gtksourcegutterrenderermarks.h"
 #include "gtksourceiter.h"
+#include "gtksourcetag.h"
 
 /**
  * SECTION:view
@@ -627,6 +628,9 @@ gtk_source_view_class_init (GtkSourceViewClass *klass)
         *
         * Set if and how the spaces should be visualized.
         *
+        * For a finer-grained method, there is also the GtkSourceTag's
+        * #GtkSourceTag:draw-spaces property.
+        *
         * Since: 2.4
         */
        g_object_class_install_property (object_class,
@@ -2447,13 +2451,144 @@ draw_spaces_at_iter (cairo_t     *cr,
        }
 }
 
+static void
+draw_spaces_tag_foreach (GtkTextTag *tag,
+                        gboolean   *found)
+{
+       if (GTK_SOURCE_IS_TAG (tag))
+       {
+               gboolean draw_spaces_set;
+
+               g_object_get (tag,
+                             "draw-spaces-set", &draw_spaces_set,
+                             NULL);
+
+               if (draw_spaces_set)
+               {
+                       *found = TRUE;
+               }
+       }
+}
+
+static gboolean
+buffer_has_draw_spaces_tag (GtkSourceBuffer *buffer)
+{
+       GtkTextTagTable *table;
+       gboolean found = FALSE;
+
+       table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (buffer));
+       gtk_text_tag_table_foreach (table,
+                                   (GtkTextTagTableForeach) draw_spaces_tag_foreach,
+                                   &found);
+
+       return found;
+}
+
+static void
+space_needs_drawing_according_to_tag (const GtkTextIter *iter,
+                                     gboolean          *has_tag,
+                                     gboolean          *needs_drawing)
+{
+       GSList *tags;
+       GSList *l;
+
+       *has_tag = FALSE;
+       *needs_drawing = FALSE;
+
+       tags = gtk_text_iter_get_tags (iter);
+       tags = g_slist_reverse (tags);
+
+       for (l = tags; l != NULL; l = l->next)
+       {
+               GtkTextTag *tag = l->data;
+
+               if (GTK_SOURCE_IS_TAG (tag))
+               {
+                       gboolean draw_spaces_set;
+                       gboolean draw_spaces;
+
+                       g_object_get (tag,
+                                     "draw-spaces-set", &draw_spaces_set,
+                                     "draw-spaces", &draw_spaces,
+                                     NULL);
+
+                       if (draw_spaces_set)
+                       {
+                               *has_tag = TRUE;
+                               *needs_drawing = draw_spaces;
+                               break;
+                       }
+               }
+       }
+
+       g_slist_free (tags);
+}
+
+static gboolean
+check_location (GtkSourceView     *view,
+               const GtkTextIter *iter,
+               const GtkTextIter *leading,
+               const GtkTextIter *trailing)
+{
+       gint flags = 0;
+       gint location = view->priv->draw_spaces & (GTK_SOURCE_DRAW_SPACES_LEADING |
+                                                  GTK_SOURCE_DRAW_SPACES_TEXT |
+                                                  GTK_SOURCE_DRAW_SPACES_TRAILING);
+
+       /* Draw all by default */
+       if (location == 0)
+       {
+               return TRUE;
+       }
+
+       if (gtk_text_iter_compare (iter, trailing) >= 0)
+       {
+               flags |= GTK_SOURCE_DRAW_SPACES_TRAILING;
+       }
+
+       if (gtk_text_iter_compare (iter, leading) < 0)
+       {
+               flags |= GTK_SOURCE_DRAW_SPACES_LEADING;
+       }
+
+       if (flags == 0)
+       {
+               /* Neither leading nor trailing, must be in text */
+               return location & GTK_SOURCE_DRAW_SPACES_TEXT;
+       }
+       else
+       {
+               return location & flags;
+       }
+}
+
 static gboolean
-space_needs_drawing (GtkSourceView *view,
-                    GtkTextIter   *iter)
+space_needs_drawing (GtkSourceView     *view,
+                    const GtkTextIter *iter,
+                    const GtkTextIter *leading,
+                    const GtkTextIter *trailing)
 {
-       gint draw_spaces = view->priv->draw_spaces;
+       gboolean has_tag;
+       gboolean needs_drawing;
+       gint draw_spaces;
        gunichar c;
 
+       /* Check the GtkSourceTag:draw-spaces property */
+
+       space_needs_drawing_according_to_tag (iter, &has_tag, &needs_drawing);
+       if (has_tag)
+       {
+               return needs_drawing;
+       }
+
+       /* Check the GtkSourceView:draw-spaces property */
+
+       if (!check_location (view, iter, leading, trailing))
+       {
+               return FALSE;
+       }
+
+       draw_spaces = view->priv->draw_spaces;
        c = gtk_text_iter_get_char (iter);
 
        return ((draw_spaces & GTK_SOURCE_DRAW_SPACES_TAB && c == '\t') ||
@@ -2517,44 +2652,6 @@ get_leading_trailing (const GtkTextIter *iter,
        }
 }
 
-static gboolean
-check_location (GtkSourceView *view,
-               GtkTextIter   *iter,
-               GtkTextIter   *leading,
-               GtkTextIter   *trailing)
-{
-       gint flags = 0;
-       gint location = view->priv->draw_spaces & (GTK_SOURCE_DRAW_SPACES_LEADING |
-                                                  GTK_SOURCE_DRAW_SPACES_TEXT |
-                                                  GTK_SOURCE_DRAW_SPACES_TRAILING);
-
-       /* Draw all by default */
-       if (location == 0)
-       {
-               return TRUE;
-       }
-
-       if (gtk_text_iter_compare (iter, trailing) >= 0)
-       {
-               flags |= GTK_SOURCE_DRAW_SPACES_TRAILING;
-       }
-
-       if (gtk_text_iter_compare (iter, leading) < 0)
-       {
-               flags |= GTK_SOURCE_DRAW_SPACES_LEADING;
-       }
-
-       if (flags == 0)
-       {
-               /* Neither leading nor trailing, must be in text */
-               return location & GTK_SOURCE_DRAW_SPACES_TEXT;
-       }
-       else
-       {
-               return location & flags;
-       }
-}
-
 static void
 get_end_iter (GtkTextView *text_view,
              GtkTextIter *start_iter,
@@ -2669,8 +2766,7 @@ draw_tabs_and_spaces (GtkSourceView *view,
        while (TRUE)
        {
                gint ly;
-               if (check_location (view, &s, &leading, &trailing) &&
-                   space_needs_drawing (view, &s))
+               if (space_needs_drawing (view, &s, &leading, &trailing))
                {
                        draw_spaces_at_iter (cr, text_view, &s);
                }
@@ -2939,7 +3035,8 @@ gtk_source_view_draw_layer (GtkTextView      *text_view,
                        gtk_source_view_paint_right_margin (view, cr);
                }
 
-               if (view->priv->draw_spaces != 0)
+               if (view->priv->draw_spaces != 0 ||
+                   buffer_has_draw_spaces_tag (view->priv->source_buffer))
                {
                        draw_tabs_and_spaces (view, cr);
                }
@@ -4723,6 +4820,9 @@ gtk_source_view_get_smart_home_end (GtkSourceView *view)
  *
  * Set if and how the spaces should be visualized. Specifying @flags as 0 will
  * disable display of spaces.
+ *
+ * For a finer-grained method, there is also the GtkSourceTag's
+ * #GtkSourceTag:draw-spaces property.
  */
 void
 gtk_source_view_set_draw_spaces (GtkSourceView            *view,


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