[gtksourceview] Better management of view/buffer for gutters



commit 43778a3551c0a3a4e3d9c6c838681ded6f506635
Author: Jesse van den Kieboom <jesse vandenkieboom epfl ch>
Date:   Sat Dec 18 13:28:02 2010 +0100

    Better management of view/buffer for gutters
    
    https://bugzilla.gnome.org/show_bug.cgi?id=636409

 gtksourceview/gtksourcegutter.c              |    5 +-
 gtksourceview/gtksourcegutterrenderer.c      |   92 ++++++++++++++--
 gtksourceview/gtksourcegutterrenderer.h      |    6 +
 gtksourceview/gtksourcegutterrendererlines.c |  151 ++++++++++----------------
 gtksourceview/gtksourcegutterrenderermarks.c |   19 ++--
 5 files changed, 157 insertions(+), 116 deletions(-)
---
diff --git a/gtksourceview/gtksourcegutter.c b/gtksourceview/gtksourcegutter.c
index 86f7754..cab9eb1 100644
--- a/gtksourceview/gtksourcegutter.c
+++ b/gtksourceview/gtksourcegutter.c
@@ -216,7 +216,10 @@ renderer_free (Renderer *renderer)
 	g_signal_handler_disconnect (renderer->renderer,
 	                             renderer->notify_ypad_handler);
 
-	_gtk_source_gutter_renderer_unset_view (renderer->renderer);
+	_gtk_source_gutter_renderer_set_view (renderer->renderer,
+	                                      NULL,
+	                                      GTK_TEXT_WINDOW_PRIVATE);
+
 	g_object_unref (renderer->renderer);
 	g_slice_free (Renderer, renderer);
 }
diff --git a/gtksourceview/gtksourcegutterrenderer.c b/gtksourceview/gtksourcegutterrenderer.c
index 0141125..1dee8ab 100644
--- a/gtksourceview/gtksourcegutterrenderer.c
+++ b/gtksourceview/gtksourcegutterrenderer.c
@@ -41,6 +41,7 @@ enum
 struct _GtkSourceGutterRendererPrivate
 {
 	GtkTextView *view;
+	GtkTextBuffer *buffer;
 	GtkTextWindowType window_type;
 
 	gint xpad;
@@ -87,6 +88,57 @@ gtk_source_gutter_renderer_finalize (GObject *object)
 	G_OBJECT_CLASS (gtk_source_gutter_renderer_parent_class)->finalize (object);
 }
 
+static void
+on_buffer_changed (GtkTextView             *view,
+                   GParamSpec              *spec,
+                   GtkSourceGutterRenderer *renderer)
+{
+	if (GTK_SOURCE_GUTTER_RENDERER_GET_CLASS (renderer)->change_buffer)
+	{
+		GTK_SOURCE_GUTTER_RENDERER_GET_CLASS (renderer)->change_buffer (renderer,
+		                                                                renderer->priv->buffer);
+	}
+
+	renderer->priv->buffer = gtk_text_view_get_buffer (view);
+}
+
+static void
+renderer_change_view_impl (GtkSourceGutterRenderer *renderer,
+                           GtkTextView             *old_view)
+{
+	if (old_view)
+	{
+		g_signal_handlers_disconnect_by_func (old_view,
+		                                      G_CALLBACK (on_buffer_changed),
+		                                      renderer);
+	}
+
+	if (renderer->priv->view)
+	{
+		g_signal_connect (renderer->priv->view,
+		                  "notify::buffer",
+		                  G_CALLBACK (on_buffer_changed),
+		                  renderer);
+	}
+}
+
+static void
+gtk_source_gutter_renderer_dispose (GObject *object)
+{
+	GtkSourceGutterRenderer *renderer;
+
+	renderer = GTK_SOURCE_GUTTER_RENDERER (object);
+
+	if (renderer->priv->view)
+	{
+		_gtk_source_gutter_renderer_set_view (renderer,
+		                                      NULL,
+		                                      GTK_TEXT_WINDOW_PRIVATE);
+	}
+
+	G_OBJECT_CLASS (gtk_source_gutter_renderer_parent_class)->dispose (object);
+}
+
 static gboolean
 set_visible (GtkSourceGutterRenderer *renderer,
              gboolean                 visible)
@@ -372,11 +424,13 @@ gtk_source_gutter_renderer_class_init (GtkSourceGutterRendererClass *klass)
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
 	object_class->finalize = gtk_source_gutter_renderer_finalize;
+	object_class->dispose = gtk_source_gutter_renderer_dispose;
 
 	object_class->get_property = gtk_source_gutter_renderer_get_property;
 	object_class->set_property = gtk_source_gutter_renderer_set_property;
 
 	klass->draw = renderer_draw_impl;
+	klass->change_view = renderer_change_view_impl;
 
 	g_type_class_add_private (object_class, sizeof (GtkSourceGutterRendererPrivate));
 
@@ -1227,19 +1281,35 @@ _gtk_source_gutter_renderer_set_view (GtkSourceGutterRenderer *renderer,
                                       GtkTextView             *view,
                                       GtkTextWindowType        window_type)
 {
-	g_return_if_fail (renderer->priv->view == NULL);
+	GtkTextView *old_view;
+
+	g_return_if_fail (GTK_IS_SOURCE_GUTTER_RENDERER (renderer));
+	g_return_if_fail (view == NULL || GTK_IS_TEXT_VIEW (view));
+
+	old_view = renderer->priv->view;
 
-	renderer->priv->view = g_object_ref (view);
 	renderer->priv->window_type = window_type;
-}
 
-void
-_gtk_source_gutter_renderer_unset_view (GtkSourceGutterRenderer *renderer)
-{
-	g_return_if_fail (renderer->priv->view != NULL);
+	if (view)
+	{
+		renderer->priv->view = g_object_ref (view);
+	}
+	else
+	{
+		renderer->priv->view = NULL;
+	}
 
-	g_object_unref (renderer->priv->view);
-	renderer->priv->view = NULL;
-	renderer->priv->window_type = GTK_TEXT_WINDOW_PRIVATE;
-}
+	if (GTK_SOURCE_GUTTER_RENDERER_GET_CLASS (renderer)->change_view)
+	{
+		GTK_SOURCE_GUTTER_RENDERER_GET_CLASS (renderer)->change_view (renderer,
+		                                                              old_view);
+	}
 
+	if (old_view)
+	{
+		g_object_unref (old_view);
+	}
+
+	g_object_notify (G_OBJECT (renderer), "view");
+	g_object_notify (G_OBJECT (renderer), "window_type");
+}
diff --git a/gtksourceview/gtksourcegutterrenderer.h b/gtksourceview/gtksourcegutterrenderer.h
index 4a83e2c..eeca471 100644
--- a/gtksourceview/gtksourcegutterrenderer.h
+++ b/gtksourceview/gtksourcegutterrenderer.h
@@ -97,6 +97,12 @@ struct _GtkSourceGutterRendererClass
 
 	void (*end)                 (GtkSourceGutterRenderer      *renderer);
 
+	void (*change_view)         (GtkSourceGutterRenderer      *renderer,
+	                             GtkTextView                  *old_view);
+
+	void (*change_buffer)       (GtkSourceGutterRenderer      *renderer,
+	                             GtkTextBuffer                *old_buffer);
+
 	/* Signal handlers */
 	gboolean (*query_activatable) (GtkSourceGutterRenderer      *renderer,
 	                               GtkTextIter                  *iter,
diff --git a/gtksourceview/gtksourcegutterrendererlines.c b/gtksourceview/gtksourcegutterrendererlines.c
index 1feeb36..8e4f86e 100644
--- a/gtksourceview/gtksourcegutterrendererlines.c
+++ b/gtksourceview/gtksourcegutterrendererlines.c
@@ -26,8 +26,6 @@
 
 struct _GtkSourceGutterRendererLinesPrivate
 {
-	GtkTextBuffer *buffer;
-
 	gint num_line_digits;
 
 	guint changed_handler_id;
@@ -42,14 +40,27 @@ gtk_source_gutter_renderer_lines_finalize (GObject *object)
 	G_OBJECT_CLASS (gtk_source_gutter_renderer_lines_parent_class)->finalize (object);
 }
 
+static GtkTextBuffer *
+get_buffer (GtkSourceGutterRendererLines *renderer)
+{
+	GtkTextView *view;
+
+	view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (renderer));
+
+	return gtk_text_view_get_buffer (view);
+}
+
 static void
 recalculate_size (GtkSourceGutterRendererLines *renderer)
 {
 	gint num_lines;
 	gint num_digits = 0;
 	gint num;
+	GtkTextBuffer *buffer;
+
+	buffer = get_buffer (renderer);
 
-	num_lines = gtk_text_buffer_get_line_count (renderer->priv->buffer);
+	num_lines = gtk_text_buffer_get_line_count (buffer);
 
 	num = num_lines;
 
@@ -90,43 +101,38 @@ on_buffer_changed (GtkSourceBuffer              *buffer,
 }
 
 static void
-buffer_notify (GtkSourceGutterRendererLines *renderer,
-               gpointer                      where_the_object_was)
+gutter_renderer_change_buffer (GtkSourceGutterRenderer *renderer,
+                               GtkTextBuffer           *old_buffer)
 {
-	renderer->priv->buffer = NULL;
-}
-
-static void
-set_buffer (GtkSourceGutterRendererLines *renderer,
-            GtkTextBuffer                *buffer)
-{
-	if (renderer->priv->buffer)
-	{
-		g_signal_handler_disconnect (renderer->priv->buffer,
-		                             renderer->priv->changed_handler_id);
+	GtkTextView *view;
+	GtkSourceGutterRendererLines *lines;
 
-		g_object_weak_unref (G_OBJECT (renderer->priv->buffer),
-		                     (GWeakNotify)buffer_notify,
-		                     renderer);
+	lines = GTK_SOURCE_GUTTER_RENDERER_LINES (renderer);
 
-		renderer->priv->buffer = NULL;
+	if (old_buffer)
+	{
+		g_signal_handler_disconnect (old_buffer,
+		                             lines->priv->changed_handler_id);
 	}
 
-	if (buffer)
+	view = gtk_source_gutter_renderer_get_view (renderer);
+
+	if (view)
 	{
-		renderer->priv->buffer = buffer;
+		GtkTextBuffer *buffer;
 
-		renderer->priv->changed_handler_id =
-			g_signal_connect (renderer->priv->buffer,
-			                  "changed",
-			                  G_CALLBACK (on_buffer_changed),
-			                  renderer);
+		buffer = gtk_text_view_get_buffer (view);
 
-		g_object_weak_ref (G_OBJECT (renderer->priv->buffer),
-		                   (GWeakNotify)buffer_notify,
-		                   renderer);
+		if (buffer)
+		{
+			lines->priv->changed_handler_id =
+				g_signal_connect (buffer,
+				                  "changed",
+				                  G_CALLBACK (on_buffer_changed),
+				                  lines);
 
-		recalculate_size (renderer);
+			recalculate_size (lines);
+		}
 	}
 }
 
@@ -162,47 +168,19 @@ gutter_renderer_query_data (GtkSourceGutterRenderer      *renderer,
 }
 
 static void
-on_buffer_notify (GtkTextView                  *view,
-                  GParamSpec                   *spec,
-                  GtkSourceGutterRendererLines *renderer)
-{
-	set_buffer (renderer, gtk_text_view_get_buffer (view));
-}
-
-static void
-gtk_source_gutter_renderer_lines_dispose (GObject *object)
-{
-	GtkSourceGutterRenderer *renderer;
-	GtkSourceGutterRendererLines *lines;
-	GtkTextView *view;
-
-	renderer = GTK_SOURCE_GUTTER_RENDERER (object);
-	lines = GTK_SOURCE_GUTTER_RENDERER_LINES (object);
-
-	view = gtk_source_gutter_renderer_get_view (renderer);
-
-	if (view != NULL && lines->priv->buffer_notify_handler_id != 0)
-	{
-		g_signal_handler_disconnect (view,
-		                             lines->priv->buffer_notify_handler_id);
-
-		lines->priv->buffer_notify_handler_id = 0;
-	}
-
-	set_buffer (lines, NULL);
-
-	G_OBJECT_CLASS (gtk_source_gutter_renderer_lines_parent_class)->dispose (object);
-}
-
-static void
 extend_selection_to_line (GtkSourceGutterRendererLines *renderer,
                           GtkTextIter                  *line_start)
 {
 	GtkTextIter start;
 	GtkTextIter end;
 	GtkTextIter line_end;
+	GtkTextBuffer *buffer;
+
+	buffer = get_buffer (renderer);
 
-	gtk_text_buffer_get_selection_bounds (renderer->priv->buffer, &start, &end);
+	gtk_text_buffer_get_selection_bounds (buffer,
+	                                      &start,
+	                                      &end);
 
 	line_end = *line_start;
 
@@ -213,7 +191,7 @@ extend_selection_to_line (GtkSourceGutterRendererLines *renderer,
 
 	if (gtk_text_iter_compare (&start, line_start) < 0)
 	{
-		gtk_text_buffer_select_range (renderer->priv->buffer,
+		gtk_text_buffer_select_range (buffer,
 		                              &start,
 		                              &line_end);
 	}
@@ -221,13 +199,13 @@ extend_selection_to_line (GtkSourceGutterRendererLines *renderer,
 	{
 		/* if the selection is in this line, extend
 		 * the selection to the whole line */
-		gtk_text_buffer_select_range (renderer->priv->buffer,
+		gtk_text_buffer_select_range (buffer,
 		                              &line_end,
 		                              line_start);
 	}
 	else
 	{
-		gtk_text_buffer_select_range (renderer->priv->buffer,
+		gtk_text_buffer_select_range (buffer,
 		                              &end,
 		                              line_start);
 	}
@@ -238,6 +216,9 @@ select_line (GtkSourceGutterRendererLines *renderer,
              GtkTextIter                  *line_start)
 {
 	GtkTextIter iter;
+	GtkTextBuffer *buffer;
+
+	buffer = get_buffer (renderer);
 
 	iter = *line_start;
 
@@ -247,7 +228,7 @@ select_line (GtkSourceGutterRendererLines *renderer,
 	}
 
 	/* Select the line, put the cursor at the end of the line */
-	gtk_text_buffer_select_range (renderer->priv->buffer, &iter, line_start);
+	gtk_text_buffer_select_range (buffer, &iter, line_start);
 }
 
 static void
@@ -262,6 +243,10 @@ gutter_renderer_activate (GtkSourceGutterRenderer *renderer,
 
 	if (event->type == GDK_BUTTON_PRESS && (event->button.button == 1))
 	{
+		GtkTextBuffer *buffer;
+
+		buffer = get_buffer (lines);
+
 		if ((event->button.state & GDK_CONTROL_MASK) != 0)
 		{
 			/* Single click + Ctrl -> select the line */
@@ -275,7 +260,7 @@ gutter_renderer_activate (GtkSourceGutterRenderer *renderer,
 		}
 		else
 		{
-			gtk_text_buffer_place_cursor (lines->priv->buffer, iter);
+			gtk_text_buffer_place_cursor (buffer, iter);
 		}
 	}
 	else if (event->type == GDK_2BUTTON_PRESS && (event->button.button == 1))
@@ -290,28 +275,7 @@ gutter_renderer_query_activatable (GtkSourceGutterRenderer *renderer,
                                    GdkRectangle            *area,
                                    GdkEvent                *event)
 {
-	return GTK_SOURCE_GUTTER_RENDERER_LINES (renderer)->priv->buffer != NULL;
-}
-
-static void
-gtk_source_gutter_renderer_lines_constructed (GObject *gobject)
-{
-	GtkSourceGutterRendererLines *lines;
-	GtkSourceGutterRenderer *renderer;
-	GtkTextView *view;
-
-	renderer = GTK_SOURCE_GUTTER_RENDERER (gobject);
-	lines = GTK_SOURCE_GUTTER_RENDERER_LINES (gobject);
-
-	view = gtk_source_gutter_renderer_get_view (renderer);
-
-	lines->priv->buffer_notify_handler_id =
-		g_signal_connect (view,
-		                  "notify::buffer",
-		                  G_CALLBACK (on_buffer_notify),
-		                  lines);
-
-	set_buffer (lines, gtk_text_view_get_buffer (view));
+	return get_buffer (GTK_SOURCE_GUTTER_RENDERER_LINES (renderer)) != NULL;
 }
 
 static void
@@ -321,12 +285,11 @@ gtk_source_gutter_renderer_lines_class_init (GtkSourceGutterRendererLinesClass *
 	GtkSourceGutterRendererClass *renderer_class = GTK_SOURCE_GUTTER_RENDERER_CLASS (klass);
 
 	object_class->finalize = gtk_source_gutter_renderer_lines_finalize;
-	object_class->dispose = gtk_source_gutter_renderer_lines_dispose;
-	object_class->constructed = gtk_source_gutter_renderer_lines_constructed;
 
 	renderer_class->query_data = gutter_renderer_query_data;
 	renderer_class->query_activatable = gutter_renderer_query_activatable;
 	renderer_class->activate = gutter_renderer_activate;
+	renderer_class->change_buffer = gutter_renderer_change_buffer;
 
 	g_type_class_add_private (object_class, sizeof(GtkSourceGutterRendererLinesPrivate));
 }
diff --git a/gtksourceview/gtksourcegutterrenderermarks.c b/gtksourceview/gtksourcegutterrenderermarks.c
index cc9be95..f1e1c69 100644
--- a/gtksourceview/gtksourcegutterrenderermarks.c
+++ b/gtksourceview/gtksourcegutterrenderermarks.c
@@ -410,19 +410,18 @@ gutter_renderer_query_activatable (GtkSourceGutterRenderer *renderer,
 }
 
 static void
-gtk_source_gutter_renderer_marks_constructed (GObject *object)
+gutter_renderer_change_view (GtkSourceGutterRenderer *renderer,
+                             GtkTextView             *old_view)
 {
-	GtkSourceGutterRendererMarks *renderer;
 	GtkSourceView *view;
-	GtkSourceGutterRenderer *r;
 
-	renderer = GTK_SOURCE_GUTTER_RENDERER_MARKS (object);
-	r = GTK_SOURCE_GUTTER_RENDERER (renderer);
-
-	view = GTK_SOURCE_VIEW (gtk_source_gutter_renderer_get_view (r));
+	view = GTK_SOURCE_VIEW (gtk_source_gutter_renderer_get_view (renderer));
 
-	gtk_source_gutter_renderer_set_size (r,
-	                                     measure_line_height (view));
+	if (view != NULL)
+	{
+		gtk_source_gutter_renderer_set_size (renderer,
+		                                     measure_line_height (view));
+	}
 }
 
 static void
@@ -432,11 +431,11 @@ gtk_source_gutter_renderer_marks_class_init (GtkSourceGutterRendererMarksClass *
 	GtkSourceGutterRendererClass *renderer_class = GTK_SOURCE_GUTTER_RENDERER_CLASS (klass);
 
 	object_class->finalize = gtk_source_gutter_renderer_marks_finalize;
-	object_class->constructed = gtk_source_gutter_renderer_marks_constructed;
 
 	renderer_class->query_data = gutter_renderer_query_data;
 	renderer_class->query_tooltip = gutter_renderer_query_tooltip;
 	renderer_class->query_activatable = gutter_renderer_query_activatable;
+	renderer_class->change_view = gutter_renderer_change_view;
 
 	/*g_type_class_add_private (object_class, sizeof (GtkSourceGutterRendererMarksPrivate));*/
 }



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