[anjuta] sourceview: Correcly unref the buffer



commit 46999d972992c10ea973accc9e183957ba796644
Author: Johannes Schmid <jhs gnome org>
Date:   Sun Mar 11 21:51:14 2012 +0100

    sourceview: Correcly unref the buffer
    
    This was causing weird bugs (like rh#801403) because the GSettings object bind to the document was not destroyed and as such was trying to access document and view when settings changed.

 plugins/sourceview/anjuta-view.c      |  102 ++++++++++++++-------------------
 plugins/sourceview/sourceview-prefs.c |   15 +++--
 plugins/sourceview/sourceview.c       |   61 ++++++++++----------
 3 files changed, 81 insertions(+), 97 deletions(-)
---
diff --git a/plugins/sourceview/anjuta-view.c b/plugins/sourceview/anjuta-view.c
index a672a9d..ad8c69c 100644
--- a/plugins/sourceview/anjuta-view.c
+++ b/plugins/sourceview/anjuta-view.c
@@ -61,20 +61,20 @@
 
 enum
 {
-	ANJUTA_VIEW_POPUP = 1
+	ANJUTA_VIEW_POPUP = 1,
+	ANJUTA_VIEW_SOURCEVIEW
 };
 
 struct _AnjutaViewPrivate
 {
 	GtkWidget* popup;
 	guint scroll_idle;
-  Sourceview* sv;
+	Sourceview* sv;
 };
 
 static void	anjuta_view_dispose	(GObject       *object);
-static void	anjuta_view_finalize (GObject         *object);
-static gint     anjuta_view_focus_out (GtkWidget       *widget,
-		                              GdkEventFocus   *event);
+static gint anjuta_view_focus_out (GtkWidget       *widget,
+                                   GdkEventFocus   *event);
 
 static gboolean	anjuta_view_draw (GtkWidget       *widget,
 	                              cairo_t* cr);
@@ -105,8 +105,8 @@ scroll_to_cursor_real (AnjutaView *view)
 
 static void
 anjuta_view_set_property (GObject * object,
-			   guint property_id,
-			   const GValue * value, GParamSpec * pspec)
+                          guint property_id,
+                          const GValue * value, GParamSpec * pspec)
 {
 	AnjutaView *self = ANJUTA_VIEW (object);
 	g_return_if_fail(value != NULL);
@@ -126,6 +126,11 @@ anjuta_view_set_property (GObject * object,
 			gtk_menu_attach_to_widget(GTK_MENU(self->priv->popup), GTK_WIDGET(self), NULL);
 			break;
 		}
+		case ANJUTA_VIEW_SOURCEVIEW:
+		{
+			self->priv->sv = g_value_get_object (value);
+			break;
+		}
 		default:
 		{
 			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
@@ -136,8 +141,8 @@ anjuta_view_set_property (GObject * object,
 
 static void
 anjuta_view_get_property (GObject * object,
-			   guint property_id,
-			   GValue * value, GParamSpec * pspec)
+                          guint property_id,
+                          GValue * value, GParamSpec * pspec)
 {
 	AnjutaView *self = ANJUTA_VIEW (object);
 	
@@ -151,6 +156,11 @@ anjuta_view_get_property (GObject * object,
 			g_value_set_object (value, self->priv->popup);
 			break;
 		}
+		case ANJUTA_VIEW_SOURCEVIEW:
+		{
+			g_value_set_object (value, self->priv->sv);
+			break;
+		}
 		default:
 		{
 			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
@@ -305,11 +315,8 @@ anjuta_view_class_init (AnjutaViewClass *klass)
 {
 	GObjectClass     *object_class = G_OBJECT_CLASS (klass);
 	GtkWidgetClass   *widget_class = GTK_WIDGET_CLASS (klass);
-	GtkBindingSet    *binding_set;
-	GParamSpec *anjuta_view_spec_popup;
 
 	object_class->dispose = anjuta_view_dispose;
-	object_class->finalize = anjuta_view_finalize;
 	object_class->set_property = anjuta_view_set_property;
 	object_class->get_property = anjuta_view_get_property;	
 
@@ -322,17 +329,21 @@ anjuta_view_class_init (AnjutaViewClass *klass)
 	widget_class->drag_motion = anjuta_view_drag_motion;
 
 	g_type_class_add_private (klass, sizeof (AnjutaViewPrivate));
-	
-	anjuta_view_spec_popup = g_param_spec_object ("popup",
-						       "Popup menu",
-						       "The popup-menu to show",
-						       GTK_TYPE_WIDGET,
-						       G_PARAM_READWRITE);
+
 	g_object_class_install_property (object_class,
-					 ANJUTA_VIEW_POPUP,
-					 anjuta_view_spec_popup);
-	
-	binding_set = gtk_binding_set_by_class (klass);	
+	                                 ANJUTA_VIEW_POPUP,
+	                                 g_param_spec_object ("popup",
+	                                                      "Popup menu",
+	                                                      "The popup-menu to show",
+	                                                      GTK_TYPE_WIDGET,
+	                                                      G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+	                                 ANJUTA_VIEW_SOURCEVIEW,
+	                                 g_param_spec_object ("sourceview",
+	                                                      "Sourceview object",
+	                                                      "",
+	                                                      ANJUTA_TYPE_SOURCEVIEW,
+	                                                      G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void 
@@ -356,30 +367,20 @@ static void
 anjuta_view_dispose (GObject *object)
 {
 	AnjutaView *view;
-
+	
 	view = ANJUTA_VIEW (object);
 	
 	if (view->priv->scroll_idle > 0)
-				g_source_remove (view->priv->scroll_idle);
-		
-	(* G_OBJECT_CLASS (anjuta_view_parent_class)->dispose) (object);
-}
-
-static void
-anjuta_view_finalize (GObject *object)
-{
-	AnjutaView *view;
-
-	view = ANJUTA_VIEW (object);
+		g_source_remove (view->priv->scroll_idle);
 
 	if (view->priv->popup != NULL) 
 	{
 	    GtkWidget* widget = gtk_menu_get_attach_widget (GTK_MENU (view->priv->popup));
 	    if (widget != NULL)
-		gtk_menu_detach (GTK_MENU (view->priv->popup));
+            gtk_menu_detach (GTK_MENU (view->priv->popup));
 	}
-		
-	(* G_OBJECT_CLASS (anjuta_view_parent_class)->finalize) (object);
+	
+	(* G_OBJECT_CLASS (anjuta_view_parent_class)->dispose) (object);
 }
 
 static gint
@@ -413,26 +414,16 @@ GtkWidget *
 anjuta_view_new (Sourceview *sv)
 {
 	GtkWidget *view;
-
+	
 	/* Create widget with sane defaults */
-	view = GTK_WIDGET (g_object_new (ANJUTA_TYPE_VIEW, 
+	view = GTK_WIDGET (g_object_new (ANJUTA_TYPE_VIEW,
+	                                 "buffer", GTK_TEXT_BUFFER (sv->priv->document),
+	                                 "sourceview", sv,
 	                                 "wrap-mode", FALSE,
-	                                 "show-line-numbers", TRUE,
-	                                 "auto-indent", TRUE,
-	                                 "tab-width", 4,
-	                                 "insert-spaces-instead-of-tabs", FALSE,
-	                                 "highlight-current-line", TRUE, 
 	                                 "indent-on-tab", TRUE, /* Fix #388727 */
 	                                 "smart-home-end", GTK_SOURCE_SMART_HOME_END_BEFORE,
 	                                 NULL));
 	
-	gtk_text_view_set_buffer (GTK_TEXT_VIEW (view),
-				  GTK_TEXT_BUFFER (sv->priv->document));
-
-	gtk_widget_show_all (view);
-
-	ANJUTA_VIEW(view)->priv->sv = sv;
-  
 	return view;
 }
 
@@ -599,13 +590,9 @@ static gboolean
 anjuta_view_draw (GtkWidget      *widget,
                   cairo_t *cr)
 {
-	GtkTextView *text_view;
-	GtkTextBuffer *doc;
-	
+	GtkTextView *text_view;	
 	text_view = GTK_TEXT_VIEW (widget);
 	
-	doc = gtk_text_view_get_buffer (text_view);
-	
 	if (gtk_cairo_should_draw_window (cr, gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT)))
 	{
 		GdkRectangle visible_rect;
@@ -626,12 +613,9 @@ anjuta_view_draw (GtkWidget      *widget,
 static gboolean
 anjuta_view_key_press_event		(GtkWidget *widget, GdkEventKey       *event)
 {
-	GtkTextBuffer *buffer;
 	AnjutaView* view = ANJUTA_VIEW(widget);
 	AssistTip* assist_tip;
 	
-	buffer  = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-	
 	assist_tip = view->priv->sv->priv->assist_tip;
     switch (event->keyval)
     {
diff --git a/plugins/sourceview/sourceview-prefs.c b/plugins/sourceview/sourceview-prefs.c
index fa6aacb..def8e34 100644
--- a/plugins/sourceview/sourceview-prefs.c
+++ b/plugins/sourceview/sourceview-prefs.c
@@ -264,7 +264,7 @@ sourceview_prefs_init(Sourceview* sv)
 	 */
 	sv->priv->settings = g_settings_new (PREF_SCHEMA);
 	sv->priv->msgman_settings = g_settings_new (MSGMAN_PREF_SCHEMA);
-
+    
 	/* Bind simple options to GSettings */
 	g_settings_bind (sv->priv->settings, HIGHLIGHT_SYNTAX,
 			 sv->priv->document, "highlight-syntax",
@@ -294,7 +294,7 @@ sourceview_prefs_init(Sourceview* sv)
 	g_settings_bind (sv->priv->settings, VIEW_LINENUMBERS,
 			 sv->priv->view, "show-line-numbers",
 			 G_SETTINGS_BIND_GET);
-
+	
 	/* Init non-simple options */
 	gtk_source_view_set_indent_width(GTK_SOURCE_VIEW(sv->priv->view), -1); /* Same as tab width */
 	gtk_source_view_set_insert_spaces_instead_of_tabs(GTK_SOURCE_VIEW(sv->priv->view),
@@ -337,10 +337,11 @@ sourceview_prefs_init(Sourceview* sv)
 void sourceview_prefs_destroy(Sourceview* sv)
 {
 	if (sv->priv->settings)
-		g_object_unref (sv->priv->settings);
+	{
+		g_clear_object(&sv->priv->settings);
+	}
 	if (sv->priv->msgman_settings)
-		g_object_unref (sv->priv->msgman_settings);
-
-	sv->priv->settings = NULL;
-	sv->priv->msgman_settings = NULL;
+	{
+		g_clear_object (&sv->priv->msgman_settings);
+	}
 }
diff --git a/plugins/sourceview/sourceview.c b/plugins/sourceview/sourceview.c
index 161f188..ab9b33c 100644
--- a/plugins/sourceview/sourceview.c
+++ b/plugins/sourceview/sourceview.c
@@ -76,7 +76,6 @@
 
 static void sourceview_class_init(SourceviewClass *klass);
 static void sourceview_instance_init(Sourceview *sv);
-static void sourceview_finalize(GObject *object);
 static void sourceview_dispose(GObject *object);
 
 static GObjectClass *parent_class = NULL;
@@ -799,13 +798,13 @@ sourceview_adjustment_changed(GtkAdjustment* ad, Sourceview* sv)
 		gtk_widget_destroy (GTK_WIDGET (sv->priv->assist_tip));
 }
 
-/* Construction/Deconstruction */
-
 static void
 sourceview_instance_init(Sourceview* sv)
 
 {
-	sv->priv = g_slice_new0 (SourceviewPrivate);
+	sv->priv = G_TYPE_INSTANCE_GET_PRIVATE (sv,
+	                                        ANJUTA_TYPE_SOURCEVIEW,
+	                                        SourceviewPrivate);
 	sv->priv->io = sourceview_io_new (sv);
 	g_signal_connect (sv->priv->io, "changed", G_CALLBACK (on_file_changed), sv);
 	g_signal_connect (sv->priv->io, "deleted", G_CALLBACK (on_file_deleted), sv);
@@ -820,6 +819,7 @@ sourceview_instance_init(Sourceview* sv)
 
 	/* Create buffer */
 	sv->priv->document = gtk_source_buffer_new(NULL);
+	
 	g_signal_connect_after(G_OBJECT(sv->priv->document), "modified-changed",
 					 G_CALLBACK(on_document_modified_changed), sv);
 	g_signal_connect_after(G_OBJECT(sv->priv->document), "mark-set",
@@ -830,11 +830,15 @@ sourceview_instance_init(Sourceview* sv)
 	                  G_CALLBACK(on_delete_range), sv);
 	g_signal_connect_after (G_OBJECT(sv->priv->document), "delete-range",
 	                  G_CALLBACK(on_delete_range_after), sv);
+
 	g_signal_connect (G_OBJECT (sv->priv->document), "notify::cursor-position",
 	                  G_CALLBACK (on_cursor_position_changed), sv);
-
+	
 	/* Create View instance */
 	sv->priv->view = ANJUTA_VIEW(anjuta_view_new(sv));
+	/* The view doesn't take a reference on the buffer, we have to unref it */
+	g_object_unref (sv->priv->document);
+	
 	g_signal_connect_after (G_OBJECT(sv->priv->view), "toggle-overwrite",
 					  G_CALLBACK(on_overwrite_toggled), sv);
 	g_signal_connect (G_OBJECT(sv->priv->view), "query-tooltip",
@@ -843,14 +847,13 @@ sourceview_instance_init(Sourceview* sv)
 					 G_CALLBACK(on_backspace),sv);
 
 	g_object_set (G_OBJECT (sv->priv->view), "has-tooltip", TRUE, NULL);
-
+	
 	/* Apply Preferences */
 	sourceview_prefs_init(sv);
-
-
+	
 	/* Create Markers */
 	sourceview_create_markers(sv);
-
+	
 	/* Create Higlight Tag */
 	sourceview_create_highlight_indic(sv);
 }
@@ -862,11 +865,8 @@ sourceview_class_init(SourceviewClass *klass)
 
 	parent_class = g_type_class_peek_parent(klass);
 	object_class->dispose = sourceview_dispose;
-	object_class->finalize = sourceview_finalize;
 
-	/* Create signals here:
-	   sourceview_signals[SIGNAL_TYPE_EXAMPLE] = g_signal_new(...)
- 	*/
+	g_type_class_add_private (klass, sizeof (SourceviewPrivate));
 }
 
 static void
@@ -874,33 +874,32 @@ sourceview_dispose(GObject *object)
 {
 	Sourceview *cobj = ANJUTA_SOURCEVIEW(object);
 	GSList* node;
-	if (cobj->priv->assist_tip)
-		gtk_widget_destroy(GTK_WIDGET(cobj->priv->assist_tip));
-	g_object_unref (cobj->priv->io);
-
-	if (cobj->priv->tooltip_cell)
-		g_object_unref (cobj->priv->tooltip_cell);
 
 	for (node = cobj->priv->idle_sources; node != NULL; node = g_slist_next (node))
 	{
 		g_source_remove (GPOINTER_TO_UINT (node->data));
 	}
 	g_slist_free (cobj->priv->idle_sources);
+	cobj->priv->idle_sources = NULL;	
 
-	sourceview_prefs_destroy(cobj);
-
-	G_OBJECT_CLASS (parent_class)->dispose (object);
-}
+	if (cobj->priv->assist_tip)
+	{
+		gtk_widget_destroy(GTK_WIDGET(cobj->priv->assist_tip));
+		cobj->priv->assist_tip = NULL;
+	}
+	if (cobj->priv->io)
+	{
+		g_clear_object (&cobj->priv->io);
+	}
 
-static void
-sourceview_finalize(GObject *object)
-{
-	Sourceview *cobj;
-	cobj = ANJUTA_SOURCEVIEW(object);
+	if (cobj->priv->tooltip_cell)
+	{
+		g_clear_object (&cobj->priv->tooltip_cell);
+	}
 
-	g_slice_free(SourceviewPrivate, cobj->priv);
-	G_OBJECT_CLASS(parent_class)->finalize(object);
-	DEBUG_PRINT("%s", "=========== finalise =============");
+	sourceview_prefs_destroy(cobj);
+	
+	G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
 /* Create a new sourceview instance. If uri is valid,



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