glade3 r1985 - in trunk: . gladeui



Author: tvb
Date: Tue Oct 21 18:05:14 2008
New Revision: 1985
URL: http://svn.gnome.org/viewvc/glade3?rev=1985&view=rev

Log:

	* gladeui/glade-widget.c: Implement property lookups with a hash table, fixed mem leaks

	* gladeui/glade-property.c: Read properties from the passed node directly, fixed mem leaks

	* gladeui/glade-widget-adaptor.c: Read properties in the order they are listed in the file, 
	not by the order of the properties in the object (helps load performance).

	* gladeui/glade-project.c: Fixed mem leaks, release widget property references before
	destroying all the glade widgets.



Modified:
   trunk/ChangeLog
   trunk/gladeui/glade-project.c
   trunk/gladeui/glade-property.c
   trunk/gladeui/glade-widget-adaptor.c
   trunk/gladeui/glade-widget.c
   trunk/gladeui/glade-widget.h

Modified: trunk/gladeui/glade-project.c
==============================================================================
--- trunk/gladeui/glade-project.c	(original)
+++ trunk/gladeui/glade-project.c	Tue Oct 21 18:05:14 2008
@@ -242,9 +242,10 @@
 static void
 glade_project_dispose (GObject *object)
 {
-	GladeProject *project = GLADE_PROJECT (object);
-	GList        *list;
-	GladeWidget  *gwidget;
+	GladeProject  *project = GLADE_PROJECT (object);
+	GList         *list;
+	GladeWidget   *gwidget;
+	GladeProperty *property;
 	
 	/* Emit close signal */
 	g_signal_emit (object, glade_project_signals [CLOSE], 0);
@@ -268,13 +269,19 @@
 						    gwidget->parent->object,
 						    gwidget->object))
 			glade_widget_remove_child (gwidget->parent, gwidget);
+
+		/* Release references by way of object properties... */
+		while (gwidget->prop_refs)
+		{
+			property = GLADE_PROPERTY (gwidget->prop_refs->data);
+			glade_property_set (property, NULL);
+		}
 	}
 
 	/* Remove objects from the project */
 	for (list = project->priv->objects; list; list = list->next)
 	{
 		gwidget = glade_widget_get_from_gobject (list->data);
-
 		g_object_unref (G_OBJECT (list->data)); /* Remove the GladeProject reference */
 		g_object_unref (G_OBJECT (gwidget));  /* Remove the overall "Glade" reference */
 	}

Modified: trunk/gladeui/glade-property.c
==============================================================================
--- trunk/gladeui/glade-property.c	(original)
+++ trunk/gladeui/glade-property.c	Tue Oct 21 18:05:14 2008
@@ -488,6 +488,12 @@
 	}
 	if (property->i18n_comment)
 		g_free (property->i18n_comment);
+	if (property->i18n_context)
+		g_free (property->i18n_context);
+	if (property->support_warning)
+		g_free (property->support_warning);
+	if (property->insensitive_tooltip)
+		g_free (property->insensitive_tooltip);
 
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -992,152 +998,79 @@
 void
 glade_property_read (GladeProperty      *property, 
 		     GladeProject       *project,
-		     GladeXmlNode       *node)
+		     GladeXmlNode       *prop)
 {
 	GladeProjectFormat fmt;
-	GladeXmlNode *prop;
 	GValue       *gvalue = NULL;
-	gchar        *id, *name, *value;
+	gchar        /* *id, *name, */ *value;
 	const gchar  *search_name;
+	gint translatable, has_context;
+	gchar *comment = NULL, *context = NULL;
 
 	g_return_if_fail (GLADE_IS_PROPERTY (property));
 	g_return_if_fail (GLADE_IS_PROJECT (project));
-	g_return_if_fail (node != NULL);
+	g_return_if_fail (prop != NULL);
 
 	fmt = glade_project_get_format (project);
 
-	/* This code should work the same for <packing> and <widget> */
-	if (!(glade_xml_node_verify_silent (node, GLADE_XML_TAG_PACKING) ||
-	      glade_xml_node_verify_silent
-	      (node, GLADE_XML_TAG_WIDGET (fmt))))
+	if (!glade_xml_node_verify (prop, GLADE_XML_TAG_PROPERTY))
 		return;
 
-	for (prop = glade_xml_node_get_children (node); 
-	     prop; prop = glade_xml_node_next (prop))
-	{
-		search_name = property->klass->id;
+	if (!(value = glade_xml_get_content (prop)))
+		return;
 
-		if (!glade_xml_node_verify_silent (prop, GLADE_XML_TAG_PROPERTY))
-			continue;
+	if (glade_property_class_is_object (property->klass, fmt))
+	{
+		/* we must synchronize this directly after loading this project
+		 * (i.e. lookup the actual objects after they've been parsed and
+		 * are present).
+		 */
+		g_object_set_data_full (G_OBJECT (property), 
+					"glade-loaded-object", 
+					g_strdup (value), g_free);
+	}
+	else
+	{
+		gvalue = glade_property_class_make_gvalue_from_string
+			(property->klass, value, project, property->widget);
 
-		if (!(name = glade_xml_get_property_string_required
-		      (prop, GLADE_XML_TAG_NAME, NULL)))
-			continue;
+		GLADE_PROPERTY_GET_KLASS
+			(property)->set_value (property, gvalue);
 
-		if (!(value = glade_xml_get_content (prop)))
-		{
-			/* XXX should be glade_xml_get_content_required()... */
-			g_free (name);
-			g_free (value);
-			continue;
-		}
+		g_value_unset (gvalue);
+		g_free (gvalue);
 
-		/* Switch up the values if we are using GtkIconFactory in builder
-		 * to load some hacked out legacy pixbufs
+		/* If an optional property is specified in the
+		 * glade file, its enabled
 		 */
-		if (fmt == GLADE_PROJECT_FORMAT_GTKBUILDER)
-		{
-			gboolean is_loaded_value = 
-				glade_project_is_loaded_factory_file (project, value);
+		property->enabled = TRUE;
+	}
 
-			if (property->klass->factory_stock_id && is_loaded_value)
-				search_name = property->klass->factory_stock_id;
-			/* If this property was loaded via another property, skip it... */
-			else if (glade_widget_has_factory_stock_id
-				 (property->widget, property->klass->id) && is_loaded_value)
-			{
-				/* really ?... */
-				g_free (value);
-				g_free (name);
-				break;
-			}
+	translatable = glade_xml_get_property_boolean
+		(prop, GLADE_TAG_TRANSLATABLE, FALSE);
+	comment = glade_xml_get_property_string
+		(prop, GLADE_TAG_COMMENT);
 	
-		}
-
-		/* Make sure we are working with dashes and
-		 * not underscores ... 
-		 */
-		id = glade_util_read_prop_name (name);
-		g_free (name);
-
-		if (!strcmp (id, search_name))
-		{
-			if (property && glade_property_class_is_object (property->klass, fmt))
-			{
-				/* we must synchronize this directly after loading this project
-				 * (i.e. lookup the actual objects after they've been parsed and
-				 * are present).
-				 */
-				g_object_set_data_full (G_OBJECT (property), 
-							"glade-loaded-object", 
-							g_strdup (value), g_free);
-			}
-			else
-			{
-				if (fmt == GLADE_PROJECT_FORMAT_GTKBUILDER &&
-				    search_name == property->klass->factory_stock_id)
-				{
-					gchar *filename =
-						glade_util_icon_name_to_filename (value);
-					g_free (value);
-					value = filename;
-				}
-
-				gvalue = glade_property_class_make_gvalue_from_string
-					(property->klass, value, project, property->widget);
-
-				if (property) 
-				{
-					GLADE_PROPERTY_GET_KLASS
-						(property)->set_value (property, gvalue);
-				}
-
-				g_value_unset (gvalue);
-				g_free (gvalue);
-
-				/* If an optional property is specified in the
-				 * glade file, its enabled
-				 */
-				property->enabled = TRUE;
-			}
-
-			if (property)
-			{
-				gint translatable, has_context;
-				gchar *comment = NULL, *context = NULL;
-
-				translatable = glade_xml_get_property_boolean
-					(prop, GLADE_TAG_TRANSLATABLE, FALSE);
-				comment = glade_xml_get_property_string
-					(prop, GLADE_TAG_COMMENT);
-
-				if (fmt == GLADE_PROJECT_FORMAT_LIBGLADE)
-					has_context = glade_xml_get_property_boolean
-						(prop, GLADE_TAG_HAS_CONTEXT, FALSE);
-				else
-					context = glade_xml_get_property_string
-						(prop, GLADE_TAG_CONTEXT);
-
-				glade_property_i18n_set_translatable (property, translatable);
-				glade_property_i18n_set_comment (property, comment);
-
-				if (fmt == GLADE_PROJECT_FORMAT_LIBGLADE)
-					glade_property_i18n_set_has_context
-						(property, has_context);
-				else
-					glade_property_i18n_set_context
-						(property, context);
-
-				g_free (comment);
-				g_free (context);
-			}
-
-			g_free (value);
-			g_free (id);
-			break;
-		}
-		g_free (id);
-	}
+	if (fmt == GLADE_PROJECT_FORMAT_LIBGLADE)
+		has_context = glade_xml_get_property_boolean
+			(prop, GLADE_TAG_HAS_CONTEXT, FALSE);
+	else
+		context = glade_xml_get_property_string
+			(prop, GLADE_TAG_CONTEXT);
+	
+	glade_property_i18n_set_translatable (property, translatable);
+	glade_property_i18n_set_comment (property, comment);
+	
+	if (fmt == GLADE_PROJECT_FORMAT_LIBGLADE)
+		glade_property_i18n_set_has_context
+			(property, has_context);
+	else
+		glade_property_i18n_set_context
+			(property, context);
+	
+	g_free (comment);
+	g_free (context);
+ 	g_free (value);
 }
 
 

Modified: trunk/gladeui/glade-widget-adaptor.c
==============================================================================
--- trunk/gladeui/glade-widget-adaptor.c	(original)
+++ trunk/gladeui/glade-widget-adaptor.c	Tue Oct 21 18:05:14 2008
@@ -848,38 +848,54 @@
 					 GladeWidget        *widget,
 					 GladeXmlNode       *node)
 {
-	GladeXmlNode *sig_node, *child_node;
+	GladeXmlNode *iter_node;
 	GList *props;
 	GladeSignal *signal;
+	GladeProperty *property;
+	gchar *name, *prop_name;
 
 	/* Read in the properties */
-	for (props = widget->properties; 
-	     props; props = props->next)
-       	{
-		GladeProperty *property = props->data;
-		glade_property_read
-			(property, widget->project, node);
+	for (iter_node = glade_xml_node_get_children (node); 
+	     iter_node; iter_node = glade_xml_node_next (iter_node))
+	{
+		if (!glade_xml_node_verify_silent (iter_node, GLADE_XML_TAG_PROPERTY))
+			continue;
+
+		/* Get prop name from node and lookup property ...*/
+		if (!(name = glade_xml_get_property_string_required
+		      (iter_node, GLADE_XML_TAG_NAME, NULL)))
+			continue;
+
+		prop_name = glade_util_read_prop_name (name);
+
+		/* Some properties may be special child type of custom, just leave them for the adaptor */
+		if ((property = glade_widget_get_property (widget, prop_name)) != NULL)
+			glade_property_read (property, widget->project, iter_node);
+
+		g_free (prop_name);
+		g_free (name);
 	}
+
 	
 	/* Read in the signals */
-	for (sig_node = glade_xml_node_get_children (node); 
-	     sig_node; sig_node = glade_xml_node_next (sig_node))
+	for (iter_node = glade_xml_node_get_children (node); 
+	     iter_node; iter_node = glade_xml_node_next (iter_node))
 	{
-		if (!glade_xml_node_verify_silent (sig_node, GLADE_XML_TAG_SIGNAL))
+		if (!glade_xml_node_verify_silent (iter_node, GLADE_XML_TAG_SIGNAL))
 			continue;
 		
-		if (!(signal = glade_signal_read (sig_node)))
+		if (!(signal = glade_signal_read (iter_node)))
 			continue;
 
 		glade_widget_add_signal_handler (widget, signal);
 	}
 
 	/* Read in children */
-	for (child_node = glade_xml_node_get_children (node); 
-	     child_node; child_node = glade_xml_node_next (child_node))
+	for (iter_node = glade_xml_node_get_children (node); 
+	     iter_node; iter_node = glade_xml_node_next (iter_node))
 	{
-		if (glade_xml_node_verify_silent (child_node, GLADE_XML_TAG_CHILD))
-			glade_widget_read_child (widget, child_node);
+		if (glade_xml_node_verify_silent (iter_node, GLADE_XML_TAG_CHILD))
+			glade_widget_read_child (widget, iter_node);
 	}
 }
 
@@ -952,10 +968,12 @@
 					GladeWidget        *widget,
 					GladeXmlNode       *node)
 {
-	GladeXmlNode *widget_node, *packing_node;
+	GladeXmlNode *widget_node, *packing_node, *iter_node;
 	GladeWidget  *child_widget;
 	GList        *packing;
 	gchar        *internal_name;
+	gchar        *name, *prop_name;
+	GladeProperty *property;
 
 	if (!glade_xml_node_verify (node, GLADE_XML_TAG_CHILD))
 		return;
@@ -986,15 +1004,28 @@
 			     glade_xml_search_child
 			     (node, GLADE_XML_TAG_PACKING)) != NULL)
 			{
-				
-				/* Get the packing properties */
-				for (packing = child_widget->packing_properties; 
-				     packing; packing = packing->next)
+
+				/* Read in the properties */
+				for (iter_node = glade_xml_node_get_children (packing_node); 
+				     iter_node; iter_node = glade_xml_node_next (iter_node))
 				{
-					GladeProperty *property = packing->data;
-					glade_property_read (property, 
-							     child_widget->project, 
-							     packing_node);
+					if (!glade_xml_node_verify_silent (iter_node, GLADE_XML_TAG_PROPERTY))
+						continue;
+
+					/* Get prop name from node and lookup property ...*/
+					if (!(name = glade_xml_get_property_string_required
+					      (iter_node, GLADE_XML_TAG_NAME, NULL)))
+						continue;
+
+					prop_name = glade_util_read_prop_name (name);
+
+					/* Some properties may be special child type of custom, 
+					 * just leave them for the adaptor */
+					if ((property = glade_widget_get_pack_property (child_widget, prop_name)) != NULL)
+						glade_property_read (property, child_widget->project, iter_node);
+					
+					g_free (prop_name);
+					g_free (name);
 				}
 			}
 		}

Modified: trunk/gladeui/glade-widget.c
==============================================================================
--- trunk/gladeui/glade-widget.c	(original)
+++ trunk/gladeui/glade-widget.c	Tue Oct 21 18:05:14 2008
@@ -746,8 +746,14 @@
 
 	g_free (widget->name);
 	g_free (widget->internal);
+	g_free (widget->support_warning);
 	g_hash_table_destroy (widget->signals);
 
+	if (widget->props_hash)
+		g_hash_table_destroy (widget->props_hash);
+	if (widget->pack_props_hash)
+		g_hash_table_destroy (widget->pack_props_hash);
+
 	G_OBJECT_CLASS(glade_widget_parent_class)->finalize(object);
 }
 
@@ -761,6 +767,9 @@
 	/* We do not keep a reference to internal widgets */
 	if (widget->internal == NULL)
 	{
+		g_print ("Destroying internal object (gtkobject %d), ref count %d\n", 
+			 GTK_IS_OBJECT (widget->object), widget->object->ref_count);
+		
 		if (GTK_IS_OBJECT (widget->object))
 			gtk_object_destroy (GTK_OBJECT (widget->object));
 		else 
@@ -1616,13 +1625,18 @@
 			g_list_foreach (widget->properties, (GFunc)g_object_unref, NULL);
 			g_list_free (widget->properties);
 		}
+		if (widget->props_hash)
+			g_hash_table_destroy (widget->props_hash);
+
 		widget->properties = properties;
-		
+		widget->props_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
 		for (list = properties; list; list = list->next)
 		{
 			property = list->data;
-
 			property->widget = widget;
+
+			g_hash_table_insert (widget->props_hash, property->klass->id, property);
 		}
 	}
 }
@@ -1649,7 +1663,7 @@
 {
 	GladePropertyClass *property_class;
 	GladeProperty *property;
-	GList *list;
+	GList *list, *properties = NULL;
 
 	g_return_if_fail (GLADE_IS_WIDGET (widget));
 	g_return_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor));
@@ -1672,10 +1686,9 @@
 					   property_class->id);
 				continue;
 			}
-
-			widget->properties = g_list_prepend (widget->properties, property);
+			properties = g_list_prepend (properties, property);
 		}
-		widget->properties = g_list_reverse (widget->properties);
+		glade_widget_set_properties (widget, g_list_reverse (properties));
 	}
 	
 	/* Create actions from adaptor */
@@ -2486,22 +2499,16 @@
 GladeProperty *
 glade_widget_get_property (GladeWidget *widget, const gchar *id_property)
 {
-	static gchar   id_buffer[GPC_PROPERTY_NAMELEN] = { 0, };
 	GList         *list;
 	GladeProperty *property;
 
 	g_return_val_if_fail (GLADE_IS_WIDGET (widget), NULL);
 	g_return_val_if_fail (id_property != NULL, NULL);
 
-	/* "-1" to always leave a trailing '\0' charachter */
-	strncpy (id_buffer, id_property, GPC_PROPERTY_NAMELEN - 1);
-	glade_util_replace (id_buffer, '_', '-');
-		
-	for (list = widget->properties; list; list = list->next) {
-		property = list->data;
-		if (strcmp (property->klass->id, id_buffer) == 0)
-			return property;
-	}
+	if (widget->props_hash && 
+	    (property = g_hash_table_lookup (widget->props_hash, id_property)))
+		return property;
+
 	return glade_widget_get_pack_property (widget, id_property);
 }
 
@@ -2515,22 +2522,16 @@
 GladeProperty *
 glade_widget_get_pack_property (GladeWidget *widget, const gchar *id_property)
 {
-	static gchar   id_buffer[GPC_PROPERTY_NAMELEN] = { 0, };
 	GList         *list;
 	GladeProperty *property;
 
 	g_return_val_if_fail (GLADE_IS_WIDGET (widget), NULL);
 	g_return_val_if_fail (id_property != NULL, NULL);
 
-	/* "-1" to always leave a trailing '\0' charachter */
-	strncpy (id_buffer, id_property, GPC_PROPERTY_NAMELEN - 1);
-	glade_util_replace (id_buffer, '_', '-');
-
-	for (list = widget->packing_properties; list; list = list->next) {
-		property = list->data;
-		if (strcmp (property->klass->id, id_buffer) == 0)
-			return property;
-	}
+	if (widget->pack_props_hash && 
+	    (property = g_hash_table_lookup (widget->pack_props_hash, id_property)))
+		return property;
+
 	return NULL;
 }
 
@@ -3179,8 +3180,11 @@
 	/* Add internal reference to new widget if its not internal */
 	if (gwidget->internal)
 		gwidget->object = G_OBJECT(new_object);
-	else
+	else if (GTK_IS_OBJECT (new_object))
 		gwidget->object = g_object_ref (G_OBJECT(new_object));
+	else
+		/* If this is a base GObject; assume ownership of the initial ref count */
+		gwidget->object = new_object;
 	
 	g_object_set_qdata (G_OBJECT (new_object), glade_widget_name_quark, gwidget);
 
@@ -3312,6 +3316,10 @@
 	g_list_free (widget->packing_properties);
 	widget->packing_properties = NULL;
 
+	if (widget->pack_props_hash)
+		g_hash_table_destroy (widget->pack_props_hash);
+	widget->pack_props_hash = NULL;
+
 	/* We have to detect whether this is an anarchist child of a composite
 	 * widget or not, in otherwords; whether its really a direct child or
 	 * a child of a popup window created on the composite widget's behalf.
@@ -3319,6 +3327,16 @@
 	if (widget->anarchist) return;
 
 	widget->packing_properties = glade_widget_create_packing_properties (container, widget);
+	widget->pack_props_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+	/* update the quick reference hash table */
+	for (list = widget->packing_properties;
+	     list && list->data;
+	     list = list->next)
+	{
+		GladeProperty *property = list->data;
+		g_hash_table_insert (widget->pack_props_hash, property->klass->id, property);
+	}
 
 	/* Dont introspect on properties that are not parented yet.
 	 */

Modified: trunk/gladeui/glade-widget.h
==============================================================================
--- trunk/gladeui/glade-widget.h	(original)
+++ trunk/gladeui/glade-widget.h	Tue Oct 21 18:05:14 2008
@@ -74,7 +74,12 @@
 				    * See also child_properties of 
 				    * GladeWidgetClass.
 				    */
-	
+
+	GHashTable *props_hash; /* A Quick reference table to speed up calls to glade_widget_get_property()
+				 */	
+	GHashTable *pack_props_hash; /* A Quick reference table to speed up calls to glade_widget_get_pack_property()
+				      */
+
 	GHashTable *signals; /* A table with a GPtrArray of GladeSignals (signal handlers),
 			      * indexed by its name */
 



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