Index: configure.in
===================================================================
RCS file: /cvs/gnome/glade3/configure.in,v
retrieving revision 1.33
diff -p -u -r1.33 configure.in
--- configure.in	5 Nov 2004 19:33:36 -0000	1.33
+++ configure.in	7 Nov 2004 17:21:32 -0000
@@ -36,7 +36,7 @@ AM_GLIB_GNU_GETTEXT
 dnl ================================================================
 dnl Start of pkg-config checks
 dnl ================================================================
-PKG_CHECK_MODULES(GLADE, gtk+-2.0 >= 2.2.0  libxml-2.0 >= 2.4.0)
+PKG_CHECK_MODULES(GLADE, gtk+-2.0 >= 2.2.0  libglade-2.0 >= 2.4.0  libxml-2.0 >= 2.4.0)
 GLADE_LIBS="${GLADE_LIBS}"
 AC_SUBST(GLADE_LIBS)
 AC_SUBST(GLADE_CFLAGS)
Index: src/glade-editor.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-editor.c,v
retrieving revision 1.60
diff -p -u -r1.60 glade-editor.c
--- src/glade-editor.c	3 Nov 2004 05:53:04 -0000	1.60
+++ src/glade-editor.c	7 Nov 2004 17:21:42 -0000
@@ -1469,7 +1469,12 @@ glade_editor_property_load (GladeEditorP
 	else if (G_IS_PARAM_SPEC_UNICHAR(class->pspec))
 		glade_editor_property_load_unichar (property);
 	else
+#ifndef _MSC_VER
 		g_warning ("%s : type %s not implemented (%s)\n", __FUNCTION__,
+#else
+		g_warning ("%s %d : type %s not implemented (%s)\n", __FILE__,
+			   __LINE__,
+#endif
 			   class->name, g_type_name (class->pspec->value_type));
 
 	glade_editor_property_set_tooltips (property);
Index: src/glade-gtk.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-gtk.c,v
retrieving revision 1.58
diff -p -u -r1.58 glade-gtk.c
--- src/glade-gtk.c	3 Nov 2004 05:53:04 -0000	1.58
+++ src/glade-gtk.c	7 Nov 2004 17:21:48 -0000
@@ -84,7 +84,7 @@ glade_gtk_stock_get_type (void)
 	return etype;
 }
 
-GParamSpec *GLADEGTK_API
+GLADEGTK_API GParamSpec *
 glade_gtk_stock_spec (void)
 {
 	return g_param_spec_enum ("stock", "stock", "stock",
@@ -92,7 +92,7 @@ glade_gtk_stock_spec (void)
 				  0, G_PARAM_READWRITE);
 }
 
-GParamSpec *GLADEGTK_API
+GLADEGTK_API GParamSpec *
 glade_gtk_standard_int_spec (void)
 {
 	static GParamSpec *int_spec = NULL;
@@ -103,7 +103,7 @@ glade_gtk_standard_int_spec (void)
 	return int_spec;
 }
 
-GParamSpec *GLADEGTK_API
+GLADEGTK_API GParamSpec *
 glade_gtk_standard_string_spec (void)
 {
 	static GParamSpec *str_spec = NULL;
@@ -113,7 +113,7 @@ glade_gtk_standard_string_spec (void)
 	return str_spec;
 }
 
-GParamSpec *GLADEGTK_API
+GLADEGTK_API GParamSpec *
 glade_gtk_standard_float_spec (void)
 {
 	static GParamSpec *float_spec = NULL;
@@ -362,6 +362,33 @@ glade_gtk_box_get_size (GObject *object,
 	g_value_set_int (value, g_list_length (box->children));
 }
 
+static gint
+glade_gtk_box_get_first_blank (GtkBox *box)
+{
+	GList       *child;
+	GladeWidget *gwidget;
+	gint         position;
+
+	for (child = box->children, position = 0;
+	     child && child->data;
+	     child = child->next, position++)
+	{
+		GtkWidget *widget = ((GtkBoxChild *) (child->data))->widget;
+
+		if ((gwidget = glade_widget_get_from_gtk_widget (widget)) != NULL)
+		{
+			gint gwidget_position;
+			GladeProperty *property =
+			glade_widget_get_property (gwidget, "position");
+			gwidget_position = g_value_get_int (property->value);
+
+			if ((gwidget_position - position) > 0)
+				return position;
+		}
+	}
+	return position;
+}
+
 /**
  * glade_gtk_box_set_size:
  * @object:
@@ -372,27 +399,28 @@ glade_gtk_box_get_size (GObject *object,
 void GLADEGTK_API
 glade_gtk_box_set_size (GObject *object, GValue *value)
 {
-	GladeWidget *widget;
-	GtkBox *box;
-	GList *child;
+	GtkBox      *box;
+	GList       *child;
 	gint new_size, old_size, i;
 
 	box = GTK_BOX (object);
 	g_return_if_fail (GTK_IS_BOX (box));
 
-	widget = glade_widget_get_from_gtk_widget (GTK_WIDGET (box));
-	g_return_if_fail (widget != NULL);
-
 	old_size = g_list_length (box->children);
 	new_size = g_value_get_int (value);
 
 	/* Ensure placeholders first...
-	 */
+	*/
 	for (i = 0; i < new_size; i++)
 	{
 		if (g_list_length(box->children) < (i + 1))
-			gtk_container_add (GTK_CONTAINER (box),
-					   GTK_WIDGET (glade_placeholder_new ()));
+		{
+			GtkWidget *placeholder = glade_placeholder_new ();
+			gint       blank       = glade_gtk_box_get_first_blank (box);
+
+			gtk_container_add (GTK_CONTAINER (box), placeholder);
+			gtk_box_reorder_child (box, placeholder, blank);
+		}
 	}
 
 	/* The box has shrunk. Remove the widgets that are on those slots */
@@ -401,10 +429,9 @@ glade_gtk_box_set_size (GObject *object,
 	     child = g_list_last (box->children), old_size--)
 	{
 		GtkWidget *child_widget = ((GtkBoxChild *) (child->data))->widget;
-		GladeWidget *glade_widget;
 
-		if ((glade_widget = glade_widget_get_from_gtk_widget (child_widget)) != NULL)
-			/* In this case, refuse to shrink */
+		if (glade_widget_get_from_gtk_widget (child_widget))
+		/* In this case, refuse to shrink */
 			break;
 
 		gtk_container_remove (GTK_CONTAINER (box), child_widget);
Index: src/glade-menu-editor.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-menu-editor.c,v
retrieving revision 1.14
diff -p -u -r1.14 glade-menu-editor.c
--- src/glade-menu-editor.c	5 Nov 2004 19:33:36 -0000	1.14
+++ src/glade-menu-editor.c	7 Nov 2004 17:22:22 -0000
@@ -184,7 +184,11 @@ glade_menu_editor_destroy (GtkObject *ob
 	g_slist_free (menued->stock_items);
 	menued->stock_items = NULL;
 
+#ifdef _MSC_VER
+#pragma message ("This should probably chain up to parent's destroy.")
+#else
 #warning "This should probably chain up to parent's destroy."
+#endif
 }
 
 /**
Index: src/glade-project.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-project.c,v
retrieving revision 1.57
diff -p -u -r1.57 glade-project.c
--- src/glade-project.c	5 Nov 2004 19:44:21 -0000	1.57
+++ src/glade-project.c	7 Nov 2004 17:22:34 -0000
@@ -683,25 +683,29 @@ glade_project_selection_get (GladeProjec
 
 /**
  * glade_project_write:
- * @context: a #GladeXmlContext
  * @project: a #GladeProject
  * 
- * Returns: the root node of a newly created xml representation of the
+ * Returns: a libglade's GladeInterface representation of the
  *          project and its contents
  */
-static GladeXmlNode *
-glade_project_write (GladeXmlContext *context, const GladeProject *project)
+static GladeInterface *
+glade_project_write (const GladeProject *project)
 {
-	GladeXmlNode *node;
-	GList *list;
+	GladeInterface *interface;
+	GList *list, *tops = NULL;
+	guint i;
+
+	interface = g_new0 (GladeInterface, 1);
+	interface->names = g_hash_table_new (g_str_hash, g_str_equal);
+	interface->strings = g_hash_table_new_full (g_str_hash,
+						    g_str_equal,
+						    (GDestroyNotify)g_free,
+						    NULL);
 
-	node = glade_xml_node_new (context, GLADE_XML_TAG_PROJECT);
-	if (!node)
-		return NULL;
-
-	for (list = project->widgets; list; list = list->next) {
+        for (i = 0, list = project->widgets; list; list = list->next)
+	{
 		GladeWidget *widget;
-		GladeXmlNode *child;
+		GladeWidgetInfo *info;
 
 		widget = glade_widget_get_from_gtk_widget (list->data);
 
@@ -709,54 +713,52 @@ glade_project_write (GladeXmlContext *co
 		 * Append toplevel widgets. Each widget then takes
 		 * care of appending its children.
 		 */
-		if (g_type_is_a
-		    (widget->widget_class->type, GTK_TYPE_WINDOW)) {
-			child = glade_widget_write (widget, context);
-			if (!child)
+		if (g_type_is_a (widget->widget_class->type, GTK_TYPE_WINDOW))
+		{
+			info = glade_widget_write (widget, interface);
+			if (!info)
 				return NULL;
 
-			glade_xml_node_append_child (node, child);
+			tops = g_list_prepend (tops, info);
+                        ++i;
 		}
 	}
+	interface->n_toplevels = i;
+        interface->toplevels = (GladeWidgetInfo **) g_new (GladeWidgetInfo *, i);
+        for (i = 0, list = tops; list; list = list->next, ++i)
+            interface->toplevels[i] = list->data;
 
-	return node;
+	g_list_free (tops);
+
+	return interface;
 }
 
 static GladeProject *
-glade_project_new_from_node (GladeXmlNode *node)
+glade_project_new_from_interface (GladeInterface *interface)
 {
 	GladeProject *project;
-	GladeXmlNode *child;
 	GladeWidget *widget;
-
-	if (!glade_xml_node_verify  (node, GLADE_XML_TAG_PROJECT))
-		return NULL;
+	guint i;
 
 	project = glade_project_new (FALSE);
 	project->changed = FALSE;
 	project->selection = NULL;
 	project->widgets = NULL;
 
-	child = glade_xml_node_get_children (node);
-	for (; child; child = glade_xml_node_next (child)) {
-		if (!glade_xml_node_verify_silent (child, GLADE_XML_TAG_REQUIRES))
-			continue;
+	if (interface->n_requires)
 		g_warning ("We currently do not support projects requiring additional libs");
-	}
 
-	child = glade_xml_node_get_children (node);
-	for (; child; child = glade_xml_node_next (child)) {
-		if (!glade_xml_node_verify_silent (child, GLADE_XML_TAG_WIDGET))
-			continue;
-		widget = glade_widget_read (project, child);
-		if (!widget) {
+	for (i = 0; i < interface->n_toplevels; ++i)
+	{
+		widget = glade_widget_read (project, interface->toplevels[i]);
+		if (!widget)
+                {
 			g_warning ("Failed to read a <widget> tag");
 			continue;
 		}
-		project->widgets = g_list_append (project->widgets, widget->widget);
+		project->widgets = g_list_prepend (project->widgets, widget->widget);
 		g_object_ref (widget->widget);
 	}
-	project->widgets = g_list_reverse (project->widgets);
 
 	return project;	
 }
@@ -773,18 +775,19 @@ glade_project_new_from_node (GladeXmlNod
 GladeProject *
 glade_project_open (const gchar *path)
 {
-	GladeXmlContext *context;
-	GladeXmlDoc *doc;
 	GladeProject *project;
-
-	context = glade_xml_context_new_from_path (path, NULL, GLADE_XML_TAG_PROJECT);
-	if (!context)
+	GladeInterface *interface;
+	
+	interface = glade_parser_parse_file (path, NULL);
+	if (!interface)
 		return NULL;
-	doc = glade_xml_context_get_doc (context);
-	project = glade_project_new_from_node (glade_xml_doc_get_root (doc));
-	glade_xml_context_free (context);
 
-	if (project) {
+	project = glade_project_new_from_interface (interface);
+	
+	glade_interface_destroy (interface);
+
+	if (project)
+        {
 		project->path = g_strdup_printf ("%s", path);
 		g_free (project->name);
 		project->name = g_path_get_basename (project->path);
@@ -806,32 +809,19 @@ glade_project_open (const gchar *path)
 gboolean
 glade_project_save (GladeProject *project, const gchar *path)
 {
-	GladeXmlContext *context;
-	GladeXmlNode *root;
-	GladeXmlDoc *xml_doc;
-	gboolean ret;
+	GladeInterface *interface;
 
-	xml_doc = glade_xml_doc_new ();
-	if (!xml_doc)
+	interface = glade_project_write (project);
+	if (!interface)
 	{
-		g_warning ("Could not create xml document\n");
+		g_warning ("Could not write glade document\n");
 		return FALSE;
 	}
+	glade_interface_dump (interface, path);
+	glade_interface_destroy (interface);
 
-	context = glade_xml_context_new (xml_doc, NULL);
-	root = glade_project_write (context, project);
-	glade_xml_context_destroy (context);
-	if (!root)
-		return FALSE;
-
-	glade_xml_doc_set_root (xml_doc, root);
-	ret = glade_xml_doc_save (xml_doc, path);
-	glade_xml_doc_free (xml_doc);
-
-	if (ret < 0)
-		return FALSE;
-
-	if (path != project->path) {
+	if (path != project->path)
+        {
 		g_free (project->path);
 		project->path = g_strdup_printf ("%s", path);
 	}
Index: src/glade-property-class.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-property-class.c,v
retrieving revision 1.62
diff -p -u -r1.62 glade-property-class.c
--- src/glade-property-class.c	3 Nov 2004 05:53:04 -0000	1.62
+++ src/glade-property-class.c	7 Nov 2004 17:22:35 -0000
@@ -411,9 +411,13 @@ glade_property_class_make_gvalue_from_st
 	else if (G_IS_PARAM_SPEC_ULONG(property_class->pspec))
 		g_value_set_ulong (value, strtoul (string, NULL, 10));
 	else if (G_IS_PARAM_SPEC_INT64(property_class->pspec))
+#ifndef G_OS_WIN32
 		g_value_set_int64 (value, strtoll (string, NULL, 10));
+#else
+		g_value_set_int64 (value, _atoi64 (string));
+#endif
 	else if (G_IS_PARAM_SPEC_UINT64(property_class->pspec))
-		g_value_set_uint64 (value, strtoull (string, NULL, 10));
+		g_value_set_uint64 (value, g_ascii_strtoull (string, NULL, 10));
 	else if (G_IS_PARAM_SPEC_FLOAT(property_class->pspec))
 		g_value_set_float (value, (float) atof (string));
 	else if (G_IS_PARAM_SPEC_DOUBLE(property_class->pspec))
Index: src/glade-property.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-property.c,v
retrieving revision 1.54
diff -p -u -r1.54 glade-property.c
--- src/glade-property.c	3 Nov 2004 05:53:05 -0000	1.54
+++ src/glade-property.c	7 Nov 2004 17:22:37 -0000
@@ -221,44 +221,48 @@ glade_property_sync (GladeProperty *prop
 
 /**
  * glade_property_write:
- * @context: a #GladeXmlContext
- * @property: a #GladeProperty:
+ * @props: a GArray of #GladePropInfo
+ * @property: a #GladeProperty
+ * @interface: a #GladeInterface
  *
  * TODO: write me
  *
  * Returns:
  */
-GladeXmlNode *
-glade_property_write (GladeXmlContext *context, GladeProperty *property)
+gboolean
+glade_property_write (GArray *props, GladeProperty *property, GladeInterface *interface)
 {
-	GladeXmlNode *node;
+	GladePropInfo info = { 0 };
 	gchar *tmp;
 	gchar *default_str = NULL;
 
 	if (!property->enabled)
-		return NULL;
+		return FALSE;
 
 	if (!glade_property_class_is_visible (property->class,
 					      glade_widget_get_class (property->widget)))
-		return NULL;
-
-	node = glade_xml_node_new (context, GLADE_XML_TAG_PROPERTY);
-	if (!node)
-		return NULL;
+		return FALSE;
 
 	/* we should change each '-' by '_' on the name of the property 
          * (<property name="...">) */
 	tmp = g_strdup (property->class->id);
 	if (!tmp)
-	{
-		glade_xml_node_delete (node);
-		return NULL;
-	}
+		return FALSE;
 	glade_util_replace (tmp, '-', '_');
 
 	/* put the name="..." part on the <property ...> tag */
-	glade_xml_node_set_property_string (node, GLADE_XML_TAG_NAME, tmp);
-
+	info.name = alloc_propname(interface, tmp);
+ 	/*if (state->translate_prop && state->content->str[0] != '\0') {
+	    if (state->context_prop) 
+		info.value = alloc_string(state->interface,
+					  g_strip_context(state->content->str,
+							   dgettext(state->domain, state->content->str)));
+	    else
+		info.value = alloc_string(state->interface,
+					  dgettext(state->domain, state->content->str));
+ 	} else {
+ 	    info.value = alloc_string(state->interface, state->content->str);
+  	}*/
 	g_free (tmp);
 
 	/* convert the value of this property to a string, and put it between
@@ -266,10 +270,7 @@ glade_property_write (GladeXmlContext *c
 	tmp = glade_property_class_make_string_from_gvalue (property->class,
 							    property->value);
 	if (!tmp)
-	{
-		glade_xml_node_delete (node);
-		return NULL;
-	}
+		return FALSE;
 
 	if (property->class->def)
 	{
@@ -280,14 +281,14 @@ glade_property_write (GladeXmlContext *c
 		{
 			g_free (tmp);
 			g_free (default_str);
-			glade_xml_node_delete (node);
-			return NULL;
+			return FALSE;
 		}
 	}
 
-	glade_xml_set_content (node, tmp);
+	info.value = alloc_string(interface, tmp);
+	g_array_append_val (props, info);
 	g_free (tmp);
 	g_free (default_str);
 
-	return node;
+	return TRUE;
 }
Index: src/glade-property.h
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-property.h,v
retrieving revision 1.29
diff -p -u -r1.29 glade-property.h
--- src/glade-property.h	28 Oct 2004 18:35:30 -0000	1.29
+++ src/glade-property.h	7 Nov 2004 17:22:41 -0000
@@ -48,7 +48,8 @@ void glade_property_set (GladeProperty *
 
 void glade_property_sync (GladeProperty *property);
 
-GladeXmlNode *glade_property_write (GladeXmlContext *context, GladeProperty *property);
+gboolean glade_property_write (GArray *props, GladeProperty *property,
+                                GladeInterface *interface);
 
 
 G_END_DECLS
Index: src/glade-signal.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-signal.c,v
retrieving revision 1.9
diff -p -u -r1.9 glade-signal.c
--- src/glade-signal.c	4 Oct 2004 15:45:22 -0000	1.9
+++ src/glade-signal.c	7 Nov 2004 17:22:41 -0000
@@ -103,44 +103,40 @@ glade_signal_clone (const GladeSignal *s
 
 /**
  * glade_signal_write:
- * @context: a #GladeXmlContext
- * @signal: a #GladeSignal
+ * @info:
+ * @signal:
+ * @interface:
  *
- * Returns: a new #GladeXmlNode in @context for @signal
+ * Returns: TRUE if succeed
  */
-GladeXmlNode *
-glade_signal_write (GladeXmlContext *context, GladeSignal *signal)
+gboolean
+glade_signal_write (GladeSignalInfo *info, GladeSignal *signal,
+		     GladeInterface *interface)
 {
-	GladeXmlNode *node;
-		
-	node = glade_xml_node_new (context, GLADE_XML_TAG_SIGNAL);
-
-	glade_xml_node_set_property_string (node, GLADE_XML_TAG_NAME, signal->name);
-	glade_xml_node_set_property_string (node, GLADE_XML_TAG_HANDLER, signal->handler);
-	glade_xml_node_set_property_boolean (node, GLADE_XML_TAG_AFTER, signal->after);
+	info->name = alloc_string(interface, signal->name);
+	info->handler = alloc_string(interface, signal->name);
+	info->after = signal->after;
 
-	return node;
+	return TRUE;
 }
 
 /**
- * glade_signal_new_from_node:
- * @node: a #GladeXmlNode
+ * glade_signal_new_from_signal_info:
+ * @node: a #GladeSignalInfo
  *
  * Returns: a new #GladeSignal with the attributes defined in @node, %NULL if
  *          there is an error
  */
-GladeSignal *
-glade_signal_new_from_node (GladeXmlNode *node)
+GladeSignal *glade_signal_new_from_signal_info (GladeSignalInfo *info)
 {
 	GladeSignal *signal;
 
-	if (!glade_xml_node_verify (node, GLADE_XML_TAG_SIGNAL))
-		return NULL;
+	g_return_val_if_fail (info != NULL, NULL);
 
 	signal = g_new0 (GladeSignal, 1);
-	signal->name    = glade_xml_get_property_string_required (node, GLADE_XML_TAG_NAME, NULL);
-	signal->handler = glade_xml_get_property_string_required (node, GLADE_XML_TAG_HANDLER, NULL);
-	signal->after   = glade_xml_get_property_boolean (node, GLADE_XML_TAG_AFTER, FALSE);
+	signal->name = g_strdup (info->name);
+	signal->handler = g_strdup (info->handler);
+	signal->after = info->after;
 
 	if (!signal->name)
 		return NULL;
Index: src/glade-signal.h
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-signal.h,v
retrieving revision 1.7
diff -p -u -r1.7 glade-signal.h
--- src/glade-signal.h	21 Apr 2004 21:03:40 -0000	1.7
+++ src/glade-signal.h	7 Nov 2004 17:22:41 -0000
@@ -24,9 +24,10 @@ void glade_signal_free (GladeSignal *sig
 
 gboolean glade_signal_equal (GladeSignal *sig1, GladeSignal *sig2);
 
-GladeXmlNode *glade_signal_write (GladeXmlContext *context, GladeSignal *signal);
+gboolean glade_signal_write (GladeSignalInfo *info, GladeSignal *signal,
+			      GladeInterface *interface);
 
-GladeSignal *glade_signal_new_from_node (GladeXmlNode *node);
+GladeSignal *glade_signal_new_from_signal_info (GladeSignalInfo *info);
 
 
 G_END_DECLS
Index: src/glade-types.h
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-types.h,v
retrieving revision 1.9
diff -p -u -r1.9 glade-types.h
--- src/glade-types.h	5 Nov 2003 08:56:56 -0000	1.9
+++ src/glade-types.h	7 Nov 2004 17:22:41 -0000
@@ -35,5 +35,6 @@ typedef struct _GladeXmlContext GladeXml
 typedef struct _GladeXmlNode    GladeXmlNode;
 typedef struct _GladeXmlDoc     GladeXmlDoc;
 
+#include <glade/glade-parser.h>
 
 #endif /* __GLADE_TYPES_H__ */
Index: src/glade-widget.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-widget.c,v
retrieving revision 1.120
diff -p -u -r1.120 glade-widget.c
--- src/glade-widget.c	5 Nov 2004 19:44:21 -0000	1.120
+++ src/glade-widget.c	7 Nov 2004 17:22:47 -0000
@@ -1559,178 +1559,190 @@ glade_widget_replace (GtkWidget *old_wid
 }
 
 /* XML Serialization */
-static GladeXmlNode *
-glade_widget_write_child (GladeXmlContext *context, GtkWidget *gtk_widget);
+static gboolean
+glade_widget_write_child (GArray *children, GtkWidget *gtk_widget, GladeInterface *interface);
 
 typedef struct _WriteSignalsContext
 {
-	GladeXmlContext *context;
-	GladeXmlNode *node;
+	GladeInterface *interface;
+	GArray *signals;
 } WriteSignalsContext;
 
 static void
 glade_widget_write_signals (gpointer key, gpointer value, gpointer user_data)
 {
-	WriteSignalsContext *write_signals_context = (WriteSignalsContext *) user_data;
-	GladeXmlNode *child;
+	WriteSignalsContext *write_signals_context;
+        GPtrArray *signals;
 	size_t i;
 
-	GPtrArray *signals = (GPtrArray *) value;
+	write_signals_context = (WriteSignalsContext *) user_data;
+	signals = (GPtrArray *) value;
 	for (i = 0; i < signals->len; i++)
 	{
 		GladeSignal *signal = g_ptr_array_index (signals, i);
-		child = glade_signal_write (write_signals_context->context, signal);
-		if (!child)
-			continue;
+		GladeSignalInfo signalinfo;
 
-		glade_xml_node_append_child (write_signals_context->node, child);
+		glade_signal_write (&signalinfo, signal,
+				     write_signals_context->interface);
+		g_array_append_val (write_signals_context->signals, 
+				    signalinfo);
 	}
 }
 
 /**
  * glade_widget_write:
- * @widget:
- * @context:
+ * @widget: a #GladeWidget
+ * @interface: a #GladeInterface
  *
  * TODO: write me
  *
  * Returns: 
  */
-GladeXmlNode *
-glade_widget_write (GladeWidget *widget, GladeXmlContext *context)
+GladeWidgetInfo*
+glade_widget_write (GladeWidget *widget, GladeInterface *interface)
 {
-	GladeXmlNode *node;
-	GladeXmlNode *child;
 	WriteSignalsContext write_signals_context;
+	GladeWidgetInfo *info;
+	GArray *props, *children;
 	GList *list;
 
-	g_return_val_if_fail (GLADE_XML_IS_CONTEXT (context), NULL);
 	g_return_val_if_fail (GLADE_IS_WIDGET (widget), NULL);
 
-	node = glade_xml_node_new (context, GLADE_XML_TAG_WIDGET);
+	info = g_new0 (GladeWidgetInfo, 1);
 
-	glade_xml_node_set_property_string (node, GLADE_XML_TAG_CLASS,
-					    widget->widget_class->name);
-	glade_xml_node_set_property_string (node, GLADE_XML_TAG_ID, widget->name);
+	info->classname = alloc_string (interface, widget->widget_class->name);
+	info->name = alloc_string (interface, widget->name);
 
 	/* Write the properties */
 	list = widget->properties;
+	props = g_array_new (FALSE, FALSE,
+			     sizeof (GladePropInfo));
 	for (; list; list = list->next)
 	{
 		GladeProperty *property = list->data;
-		if (property->class->packing)
-			continue;
 
-		child = glade_property_write (context, property);
-		if (!child)
+		if (property->class->packing)
 			continue;
 
-		glade_xml_node_append_child (node, child);
+		glade_property_write (props, property, interface);
 	}
+	info->properties = (GladePropInfo *) props->data;
+	info->n_properties = props->len;
+	g_array_free(props, FALSE);
 
 	/* Signals */
-	write_signals_context.node = node;
-	write_signals_context.context = context;
+	write_signals_context.interface = interface;
+	write_signals_context.signals = g_array_new (FALSE, FALSE,
+	                                              sizeof (GladeSignalInfo));
 	g_hash_table_foreach (widget->signals,
 			      glade_widget_write_signals,
 			      &write_signals_context);
+	info->signals = (GladeSignalInfo *)
+				write_signals_context.signals->data;
+	info->n_signals = write_signals_context.signals->len;
+	g_array_free (write_signals_context.signals, FALSE);
 
 	/* Children */
 	if (GTK_IS_CONTAINER (widget->widget)) {
 		list = glade_util_container_get_all_children (GTK_CONTAINER (widget->widget));
+		children = g_array_new (FALSE, FALSE,
+	                                sizeof (GladeChildInfo));
 		for (; list; list = list->next) {
 			GtkWidget *child_widget;
 			child_widget = GTK_WIDGET (list->data);
-			child = glade_widget_write_child (context, child_widget);
-			if (!child)
-				continue;
-
-			glade_xml_node_append_child (node, child);
+			glade_widget_write_child (children,
+						   child_widget,
+						   interface);
 	 	}
+		info->children = (GladeChildInfo *) children->data;
+		info->n_children = children->len;
+		g_array_free (children, FALSE);
 	}
 
-	return node;
+	g_hash_table_insert(interface->names, info->name, info);
+
+	return info;
 }
 
-static GladeXmlNode *
-glade_widget_write_child (GladeXmlContext *context, GtkWidget *gtk_widget)
+gboolean
+glade_widget_write_child (GArray *children, GtkWidget *gtk_widget, GladeInterface *interface)
 {
+	GladeChildInfo info = { 0 };
 	GladeWidget *child_widget;
-	GladeXmlNode *child_tag; /* this is the <child> tag */
-	GladeXmlNode *child;     /* this is the <widget> under <child> */
-	GladeXmlNode *packing;
 	GList *list;
+	GArray *props;
 
-	child_tag = glade_xml_node_new (context, GLADE_XML_TAG_CHILD);
-
-	if (GLADE_IS_PLACEHOLDER (gtk_widget)) {
-		child = glade_xml_node_new (context, GLADE_XML_TAG_PLACEHOLDER);
-		glade_xml_node_append_child (child_tag, child);
+	/* if (GLADE_IS_PLACEHOLDER (gtk_widget))
+	{
+		g_array_append_val (children, info);
 
-		return child_tag;
-	}
+		return TRUE;
+	} */
 
 	child_widget = glade_widget_get_from_gtk_widget (gtk_widget);
 	if (!child_widget)
-		return NULL;
+		return FALSE;
 
 	if (child_widget->internal)
-		glade_xml_node_set_property_string
-			(child_tag, GLADE_XML_TAG_INTERNAL_CHILD, child_widget->internal);
+		info.internal_child = alloc_string(interface, child_widget->internal);
 
-	child = glade_widget_write (child_widget, context);
-	if (!child)
+	info.child = glade_widget_write (child_widget, interface);
+	if (!info.child)
 	{
 		g_warning ("Failed to write child widget");
-		return NULL;
+		return FALSE;
 	}
-	glade_xml_node_append_child (child_tag, child);
 
 	/* Append the packing properties */
 	if (child_widget->packing_properties != NULL) {
-		packing = glade_xml_node_new (context, GLADE_XML_TAG_PACKING);
-		glade_xml_node_append_child (child_tag, packing);
 		list = child_widget->packing_properties;
+		props = g_array_new (FALSE, FALSE,
+				     sizeof (GladePropInfo));
 		for (; list; list = list->next) {
 			GladeProperty *property;
-			GladeXmlNode *packing_property;
+
 			property = list->data;
 			g_assert (property->class->packing == TRUE);
-			packing_property = glade_property_write (context, property);
-			if (!packing_property)
-				continue;
-			glade_xml_node_append_child (packing, packing_property);
+			glade_property_write (props, property, interface);
 		}
+		info.properties = (GladePropInfo *) props->data;
+		info.n_properties = props->len;
+		g_array_free(props, FALSE);
 	}
+	g_array_append_val (children, info);
 
-	return child_tag;
+	return TRUE;
 }
 
 static gboolean
-glade_widget_apply_property_from_node (GladeXmlNode *node,
-				       GladeWidget *widget,
-				       gboolean packing)
+glade_widget_apply_property_from_prop_info (GladePropInfo *info,
+					    GladeWidget *widget,
+					    gboolean packing)
 {
 	GladeProperty *property;
 	GValue *gvalue;
-	gchar *value;
 	gchar *id;
 
-	id = glade_xml_get_property_string_required (node, GLADE_XML_TAG_NAME, NULL);
-	value = glade_xml_get_content (node);
-	if (!value || !id)
+	g_return_val_if_fail (info != NULL, FALSE);
+	g_return_val_if_fail (widget != NULL, FALSE);
+
+	if (!info->name || !info->value)
 		return FALSE;
 
+	id = g_strdup (info->name);
+
 	glade_util_replace (id, '_', '-');
 	property = glade_widget_get_property (widget, id);
 	if (!property)
 		return FALSE;
 
-	gvalue = glade_property_class_make_gvalue_from_string (property->class, value);
+	if (!strcmp(id, "use-underline") && !strcmp(widget->name, "btnExit"))
+		id = id;
+
+	gvalue = glade_property_class_make_gvalue_from_string (property->class, info->value);
 	glade_property_set (property, gvalue);
 		
 	g_free (id);
-	g_free (value);
 	g_value_unset (gvalue);
 	g_free (gvalue);
 
@@ -1738,44 +1750,26 @@ glade_widget_apply_property_from_node (G
 }
 
 static gboolean
-glade_widget_new_child_from_node (GladeXmlNode *node,
-				  GladeProject *project,
-				  GladeWidget *parent);
+glade_widget_new_child_from_child_info (GladeChildInfo *info,
+					GladeProject *project,
+					GladeWidget *parent);
 
 static void
-glade_widget_fill_from_node (GladeXmlNode *node, GladeWidget *widget)
+glade_widget_fill_from_widget_info (GladeWidgetInfo *info, GladeWidget *widget)
 {
-	GladeXmlNode *child;
-	gchar *class_name;
-	gchar *widget_name;
+	guint i;
 
 	g_return_if_fail (GLADE_IS_WIDGET (widget));
+	g_return_if_fail (info != NULL);
 
-	if (!glade_xml_node_verify (node, GLADE_XML_TAG_WIDGET))
-		return;
-
-	class_name = glade_xml_get_property_string_required (node, GLADE_XML_TAG_CLASS, NULL);
-	if (!class_name)
-		return;
-
-	widget_name = glade_xml_get_property_string_required (node, GLADE_XML_TAG_ID, NULL);
-	if (!widget_name) {
-		g_free (class_name);
-		return;
-	}
-
-	g_assert (strcmp (class_name, widget->widget_class->name) == 0);
-	glade_widget_set_name (widget, widget_name);
-	g_free (class_name);
-	g_free (widget_name);
+	g_assert (strcmp (info->classname, widget->widget_class->name) == 0);
+	glade_widget_set_name (widget, info->name);
 
 	/* Children */
-	child =	glade_xml_node_get_children (node);
-	for (; child; child = glade_xml_node_next (child)) {
-		if (!glade_xml_node_verify_silent (child, GLADE_XML_TAG_CHILD))
-			continue;
-
-		if (!glade_widget_new_child_from_node (child, widget->project, widget)) {
+	for (i = 0; i < info->n_children; ++i)
+	{
+		if (!glade_widget_new_child_from_child_info (info->children + i, widget->project, widget))
+		{
 			g_warning ("Failed to read child of %s",
 				   glade_widget_get_name (widget));
 			continue;
@@ -1783,15 +1777,13 @@ glade_widget_fill_from_node (GladeXmlNod
 	}
 
 	/* Signals */
-	child =	glade_xml_node_get_children (node);
-	for (; child; child = glade_xml_node_next (child)) {
+	for (i = 0; i < info->n_signals; ++i)
+	{
 		GladeSignal *signal;
 
-		if (!glade_xml_node_verify_silent (child, GLADE_XML_TAG_SIGNAL))
-			continue;
-
-		signal = glade_signal_new_from_node (child);
-		if (!signal) {
+		signal = glade_signal_new_from_signal_info (info->signals + i);
+		if (!signal)
+		{
 			g_warning ("Failed to read signal");
 			continue;
 		}
@@ -1799,43 +1791,36 @@ glade_widget_fill_from_node (GladeXmlNod
 	}
 
 	/* Properties */
-	child =	glade_xml_node_get_children (node);
-	for (; child; child = glade_xml_node_next (child)) {
-		if (!glade_xml_node_verify_silent (child, GLADE_XML_TAG_PROPERTY))
-			continue;
-
-		if (!glade_widget_apply_property_from_node (child, widget, FALSE)) {
+	for (i = 0; i < info->n_properties; ++i)
+	{
+		if (!glade_widget_apply_property_from_prop_info (info->properties + i, widget, FALSE))
+		{
 			g_warning ("Failed to apply property");
 			continue;
 		}
 	}
+	glade_widget_sync_custom_props (widget);
 }
 
 static GladeWidget *
-glade_widget_new_from_node_real (GladeXmlNode *node,
-				 GladeProject *project,
-				 GladeWidget *parent)
+glade_widget_new_from_widget_info (GladeWidgetInfo *info,
+                                   GladeProject *project,
+                                   GladeWidget *parent)
 {
 	GladeWidgetClass *klass;
 	GladeWidget *widget;
-	gchar *class_name;
 	GObject *widget_gtk;
 	gchar *widget_name;
 
-	if (!glade_xml_node_verify (node, GLADE_XML_TAG_WIDGET))
-		return NULL;
+	g_return_val_if_fail (info != NULL, NULL);
+	g_return_val_if_fail (project != NULL, NULL);
 
-	class_name = glade_xml_get_property_string_required (node, GLADE_XML_TAG_CLASS, NULL);
-	if (!class_name)
-		return NULL;
-
-	klass = glade_widget_class_get_by_name (class_name);
-	if (!klass) {
-		g_warning ("Widget class %s unknown.", class_name);
-		g_free (class_name);
+	klass = glade_widget_class_get_by_name (info->classname);
+	if (!klass)
+	{
+		g_warning ("Widget class %s unknown.", info->classname);
 		return NULL;
 	}
-	g_free (class_name);
 
 	widget_gtk = g_object_new (klass->type, NULL);
 
@@ -1853,7 +1838,7 @@ glade_widget_new_from_node_real (GladeXm
 		widget->packing_properties =
 			glade_widget_create_packing_properties (parent, widget);
 
-	glade_widget_fill_from_node (node, widget);
+	glade_widget_fill_from_widget_info (info, widget);
 
 	gtk_widget_show_all (widget->widget);
 
@@ -1865,7 +1850,7 @@ glade_widget_new_from_node_real (GladeXm
  */
 static GtkWidget *
 glade_widget_get_internal_child (GladeWidget *parent,
-				 const gchar *internal)
+				 const gchar *internal)                
 {
 	while (parent)
 	{
@@ -1883,72 +1868,66 @@ glade_widget_get_internal_child (GladeWi
 }
 
 static gboolean
-glade_widget_new_child_from_node (GladeXmlNode *node,
-				  GladeProject *project,
-				  GladeWidget *parent)
+glade_widget_new_child_from_child_info (GladeChildInfo *info,
+					GladeProject *project,
+					GladeWidget *parent)
 {
-	gchar *internalchild;
-	GladeXmlNode *child_node;
 	GladeWidget *child;
+        guint i;
 
-	if (!glade_xml_node_verify (node, GLADE_XML_TAG_CHILD))
-		return FALSE;
+	g_return_val_if_fail (info != NULL, FALSE);
+	g_return_val_if_fail (project != NULL, FALSE);
 
 	/* is it a placeholder? */
-	child_node = glade_xml_search_child (node, GLADE_XML_TAG_PLACEHOLDER);
-	if (child_node)
+	if (!info->child)
 	{
-		gtk_container_add (GTK_CONTAINER (parent->widget), glade_placeholder_new ());
+		/* gtk_container_add (GTK_CONTAINER (parent->widget), glade_placeholder_new ()); */
+
 		return TRUE;
 	}
 
-	/* then it must be a widget */
-	child_node = glade_xml_search_child_required (node, GLADE_XML_TAG_WIDGET);
-	if (!child_node)
-		return FALSE;
-
 	/* is it an internal child? */
-	internalchild = glade_xml_get_property_string (node, GLADE_XML_TAG_INTERNAL_CHILD);
-	if (internalchild)
+	if (info->internal_child)
 	{
-		GtkWidget *child_gtk = glade_widget_get_internal_child (parent, internalchild);
+		GtkWidget *child_gtk = glade_widget_get_internal_child (parent, info->internal_child);
 		GladeWidgetClass *child_class;
 
-		if (!child_gtk) {
+		if (!child_gtk)
+                {
 			g_warning ("Failed to locate internal child %s of %s",
-				   internalchild, glade_widget_get_name (parent));
+				   info->internal_child, glade_widget_get_name (parent));
 			return FALSE;
 		}
 		child_class = glade_widget_class_get_by_name (G_OBJECT_TYPE_NAME (child_gtk));
 		child = glade_widget_new_for_internal_child (child_class, parent,
-							     child_gtk, internalchild);
-		g_free (internalchild);
-		glade_widget_fill_from_node (child_node, child);
-	} else {
-		child = glade_widget_new_from_node_real (child_node, project, parent);
+							     child_gtk, info->internal_child);
+		glade_widget_fill_from_widget_info (info->child, child);
+	}
+        else
+        {
+		child = glade_widget_new_from_widget_info (info->child, project, parent);
 		if (!child)
 			return FALSE;
+
+                if (GTK_IS_BIN (parent->widget))
+                {
+                    GtkWidget *child;
+
+                    child = gtk_bin_get_child ((GtkBin *) parent->widget);
+                    if (GLADE_IS_PLACEHOLDER (child))
+                        gtk_container_remove ((GtkContainer *) parent->widget, child);
+                }
+
 		gtk_container_add (GTK_CONTAINER (parent->widget), child->widget);
 	}
 
 	/* Get the packing properties */
-	child_node = glade_xml_search_child (node, GLADE_XML_TAG_PACKING);
-	if (child_node)
+	for (i = 0; i < info->n_properties; ++i)
 	{
-		GladeXmlNode *property_node;
-
-		property_node = glade_xml_node_get_children (child_node);
-		for (; property_node; property_node = glade_xml_node_next (property_node))
+		if (!glade_widget_apply_property_from_prop_info (info->properties + i, child, TRUE))
 		{
-			/* we should be on a <property ...> tag */
-			if (!glade_xml_node_verify (property_node, GLADE_XML_TAG_PROPERTY))
-				continue;
-
-			if (!glade_widget_apply_property_from_node (property_node, child, TRUE))
-			{
-				g_warning ("Failed to apply packing property");
-				continue;
-			}
+                        g_warning ("Failed to apply packing property");
+			continue;
 		}
 	}
 
@@ -1959,15 +1938,15 @@ glade_widget_new_child_from_node (GladeX
 /**
  * glade_widget_read:
  * @project: a #GladeProject
- * @node: a #GladeXmlNode
+ * @info: a #GladeWidgetInfo
  *
  * Returns: a new #GladeWidget in @project, based off the contents of @node
  */
 GladeWidget *
-glade_widget_read (GladeProject *project, GladeXmlNode *node)
+glade_widget_read (GladeProject *project, GladeWidgetInfo *info)
 {
 	GladeWidget *widget =
-		glade_widget_new_from_node_real (node, project, NULL);
+		glade_widget_new_from_widget_info (info, project, NULL);
 	glade_widget_debug (widget);
 	return widget;
 }
Index: src/glade-widget.h
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-widget.h,v
retrieving revision 1.37
diff -p -u -r1.37 glade-widget.h
--- src/glade-widget.h	5 Nov 2004 19:44:21 -0000	1.37
+++ src/glade-widget.h	7 Nov 2004 17:22:47 -0000
@@ -103,8 +103,8 @@ void			glade_widget_change_signal_handle
 GPtrArray *		glade_widget_list_signal_handlers	(GladeWidget *widget, const char *signal_name); /* array of GladeSignal* */
 
 /* serialization */
-GladeXmlNode *		glade_widget_write			(GladeWidget *widget, GladeXmlContext *context);
-GladeWidget *		glade_widget_read			(GladeProject *project, GladeXmlNode *node);
+GladeWidgetInfo *	glade_widget_write			(GladeWidget *widget, GladeInterface *interface);
+GladeWidget *		glade_widget_read			(GladeProject *project, GladeWidgetInfo *info);
 
 /* helper functions */
 #define			glade_widget_get_from_gtk_widget(w)	g_object_get_data (G_OBJECT (w), "GladeWidgetDataTag")
Index: src/glade-xml-utils.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-xml-utils.c,v
retrieving revision 1.22
diff -p -u -r1.22 glade-xml-utils.c
--- src/glade-xml-utils.c	6 Oct 2004 18:32:46 -0000	1.22
+++ src/glade-xml-utils.c	7 Nov 2004 17:22:52 -0000
@@ -704,3 +704,37 @@ glade_xml_doc_get_root (GladeXmlDoc *doc
 
 	return (GladeXmlNode *)node;
 }
+
+gchar *
+alloc_string(GladeInterface *interface, const gchar *string)
+{
+    gchar *s;
+
+    s = g_hash_table_lookup(interface->strings, string);
+    if (!s)
+	{
+		s = g_strdup(string);
+		g_hash_table_insert(interface->strings, s, s);
+    }
+
+    return s;
+}
+
+gchar *
+alloc_propname(GladeInterface *interface, const gchar *string)
+{
+    static GString *norm_str;
+    guint i;
+
+    if (!norm_str)
+	norm_str = g_string_new_len(NULL, 64);
+
+    /* assign the string to norm_str */
+    g_string_assign(norm_str, string);
+    /* convert all dashes to underscores */
+    for (i = 0; i < norm_str->len; i++)
+	if (norm_str->str[i] == '-')
+	    norm_str->str[i] = '_';
+
+    return alloc_string(interface, norm_str->str);
+}
Index: src/glade-xml-utils.h
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-xml-utils.h,v
retrieving revision 1.12
diff -p -u -r1.12 glade-xml-utils.h
--- src/glade-xml-utils.h	28 Nov 2003 12:05:59 -0000	1.12
+++ src/glade-xml-utils.h	7 Nov 2004 17:22:52 -0000
@@ -67,6 +67,9 @@ GladeXmlContext * glade_xml_context_new_
 						   const gchar *root_name);
 GladeXmlDoc *     glade_xml_context_get_doc (GladeXmlContext *context);
 
+gchar *		alloc_string(GladeInterface *interface, const gchar *string);
+gchar *		alloc_propname(GladeInterface *interface, const gchar *string);
+
 
 G_END_DECLS
 
Index: src/glade_plugin.def
===================================================================
RCS file: /cvs/gnome/glade3/src/glade_plugin.def,v
retrieving revision 1.6
diff -p -u -r1.6 glade_plugin.def
--- src/glade_plugin.def	3 Nov 2004 05:30:27 -0000	1.6
+++ src/glade_plugin.def	7 Nov 2004 17:22:52 -0000
@@ -3,6 +3,7 @@ EXPORTS
    glade_catalog_load_all
    glade_command_create
    glade_cursor_init
+   glade_editor_load_widget
    glade_placeholder_get_type
    glade_placeholder_new
    glade_project_get_tooltips
Index: widgets/gtkwidget.xml
===================================================================
RCS file: /cvs/gnome/glade3/widgets/gtkwidget.xml,v
retrieving revision 1.7
diff -p -u -r1.7 gtkwidget.xml
--- widgets/gtkwidget.xml	3 Nov 2004 05:53:05 -0000	1.7
+++ widgets/gtkwidget.xml	7 Nov 2004 17:22:52 -0000
@@ -10,7 +10,7 @@
 
 	<Property Common="True" Optional="True" OptionalDefault="False" Default="0" Id="height-request"/>
 
-    <Property Common="True" Id="tooltip" Name="Tooltip" Visible="glade_gtk_widget_condition">
+    <Property Common="True" Id="tooltip" Name="Tooltip" Visible="glade_gtk_widget_condition" Default="">
       <Spec>glade_gtk_standard_string_spec</Spec>
       <SetFunction>glade_gtk_widget_set_tooltip</SetFunction>
       <GetFunction>glade_gtk_widget_get_tooltip</GetFunction>
