[gtksourceview] tag: add a property to draw spaces
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview] tag: add a property to draw spaces
- Date: Sun, 11 Oct 2015 09:53:02 +0000 (UTC)
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]