Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/glade3/ChangeLog,v
retrieving revision 1.322.2.3
diff -u -p -r1.322.2.3 ChangeLog
--- ChangeLog	18 Nov 2004 06:25:34 -0000	1.322.2.3
+++ ChangeLog	30 Nov 2004 18:40:16 -0000
@@ -1,3 +1,64 @@
+2004-11-30  Tristan Van Berkom  <tristan.van.berkom@gmail.com>
+
+	* src/glade-catalog.c: pallet_name is no longer "required" in the catalog,
+	  if it is present, then the widget goes in the pallet, if there is a generic
+	  name, it will be used in the case of non-widgets.
+
+	* src/glade-command.c: glade_command_create no longer nescesitates a placeholder
+	  and now has a "parent" argument for the case of (!toplevel && non-widget)
+	  (surrounding code adjusted to work with non-widgets, glade_command_delete stuff
+	  included).
+	
+	* src/glade-editor.c: 
+	    - Widget page is now called General page
+	    - Name field not appended to non-widgets
+	    - Adjusted text inputs to only set properties on TAB or ENTER
+	      (or focus changes in the case of multi line entries)
+              This heavily reduces spamming of the property system as properties
+	      dont get synchronized for every single charachter change.
+	
+	* src/glade-gtk.c: GtkFixed code fixed to not needlessly create placeholders
+	  at child create time (go directly to glade_command_create() without passing
+	  go or collecting 200 dollars).
+	  (Also fixed name of enum type glade_gtk_stock_get_type)
+	
+	* src/glade-placeholder.c: Use new glade_command_create ()
+
+	* src/glade-popup.c: 
+	    - Added code needed for addition of non-widgets.
+	    - Added "add_children" arg to glade_popup_widget_pop ()
+	
+	* src/glade-project-view.c:
+	    - fixed bug 145299.
+	    - Added popup code to treeview.
+
+	* src/glade-project-window.c: Fixed some error messages, used new 
+	  glade_command_create()
+
+	* src/glade-property.c: Fixed a bug in rebuilding of widgets
+	  (project list needs to be searched to find out if the widget is
+	  actualy in the project).
+
+	* src/glade-property-class.c: Made custom props load tooltips from pspec
+	  blurbs as well as the xml file.
+	
+	* src/glade-utils.c: 
+	    - glade_utils_draw_nodes_idle(), dont try to draw nodes on non-widgets.
+            - added glade_util_widget_pastable()
+	    - added glade_util_gtkcontainer_relation()
+	
+	* src/glade-widget-class.[ch]: 
+	    - added glade_widget_class_get_by_type ()
+            - added glade_widget_class_get_derived_types ()
+
+	* src/glade-widget.c: 
+	    - added glade_widget_sync_packing_props ()
+	    - added glade_widget_set_parent ().
+	    - Made widgets parent a property of widget
+	    - glade_widget_new() now takes a "parent" argument.
+	    - removed glade_widget_update_parent() which was more confusing
+	      than anything else.
+	
 2004-11-16  Tristan Van Berkom  <tristan.van.berkom@gmail.com>
 
 	* Replaced `GtkWidget *' with `GObject *' throughout the code
Index: src/glade-catalog.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-catalog.c,v
retrieving revision 1.22.2.1
diff -u -p -r1.22.2.1 glade-catalog.c
--- src/glade-catalog.c	18 Nov 2004 06:19:21 -0000	1.22.2.1
+++ src/glade-catalog.c	30 Nov 2004 18:40:17 -0000
@@ -124,11 +124,8 @@ glade_catalog_load (const char *base_cat
 
 		/* get the specific library to the widget class, if any */
 		base_widget_class_library = glade_xml_get_property_string (widget_node, "library");
-
 		generic_name = glade_xml_get_property_string (widget_node, "generic_name");
-		palette_name = NULL;
-		if (generic_name != NULL)
-			palette_name = glade_xml_get_property_string_required (widget_node, "palette_name", name);
+		palette_name = glade_xml_get_property_string (widget_node, "palette_name");
 		
 		base_filename = glade_xml_get_property_string (widget_node, "filename");
 
Index: src/glade-command.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-command.c,v
retrieving revision 1.34.2.1
diff -u -p -r1.34.2.1 glade-command.c
--- src/glade-command.c	18 Nov 2004 06:25:34 -0000	1.34.2.1
+++ src/glade-command.c	30 Nov 2004 18:40:17 -0000
@@ -547,11 +547,11 @@ glade_command_set_name (GladeWidget *wid
 typedef struct {
 	GladeCommand parent;
 
-	GladeWidget *widget;
+	GladeWidget      *parent_widget;
+	GladeWidget      *widget;
 	GladePlaceholder *placeholder;
-	gboolean create;
-
-	gulong  handler_id;
+	
+	gboolean          create;
 } GladeCommandCreateDelete;
 
 GLADE_MAKE_COMMAND (GladeCommandCreateDelete, glade_command_create_delete);
@@ -571,13 +571,23 @@ static gboolean
 glade_command_create_execute (GladeCommandCreateDelete *me)
 {
 	GladeWidget      *widget      = me->widget;
+	GladeWidget      *parent      = me->parent_widget;
 	GladePlaceholder *placeholder = me->placeholder;
 
-	if (!GTK_WIDGET_TOPLEVEL (widget->object))
-		glade_widget_replace
-			(glade_placeholder_get_parent (placeholder),
-			 G_OBJECT (placeholder), widget->object);
-
+	if (parent)
+	{
+		if (placeholder)
+			glade_widget_replace
+				(parent, G_OBJECT (placeholder), widget->object);
+		else
+		{
+			glade_widget_class_container_add (parent->widget_class,
+							  parent->object,
+							  widget->object);
+			glade_widget_set_parent (widget, parent);
+		}
+	}
+	
 	glade_project_add_object    (widget->project, widget->object);
 	glade_project_selection_set (widget->project, widget->object, TRUE);
 
@@ -591,22 +601,20 @@ static gboolean
 glade_command_delete_execute (GladeCommandCreateDelete *me)
 {
 	GladeWidget *widget = me->widget;
-	GladeWidget *parent;
+	GladeWidget *parent = me->parent_widget;
 
 	g_return_val_if_fail (widget != NULL, TRUE);
 
 	parent = glade_widget_get_parent (widget);
 	if (parent)
 	{
-		if (me->placeholder == NULL)
-		{
-			me->placeholder = GLADE_PLACEHOLDER (glade_placeholder_new ());
-			g_object_ref (G_OBJECT (me->placeholder));
-		}
-
-		glade_widget_replace
-			(glade_widget_get_parent (widget),
-			 widget->object, G_OBJECT (me->placeholder));
+		if (me->placeholder)
+			glade_widget_replace
+				(parent, widget->object, G_OBJECT (me->placeholder));
+		else
+			glade_widget_class_container_remove (parent->widget_class,
+							     parent->object,
+							     widget->object);
 	}
 
 	if (GTK_IS_WIDGET (widget->object))
@@ -670,9 +678,10 @@ glade_command_create_delete_collapse (Gl
  * Placeholder arg may be NULL for toplevel widgets
  */
 static void
-glade_command_create_delete_common (GladeWidget *widget,
+glade_command_create_delete_common (GladeWidget      *widget,
+				    GladeWidget      *parent,
 				    GladePlaceholder *placeholder,
-				    gboolean create)
+				    gboolean          create)
 {
 	GladeCommandCreateDelete *me;
 	GladeCommand *cmd;
@@ -680,10 +689,11 @@ glade_command_create_delete_common (Glad
  	me = g_object_new (GLADE_COMMAND_CREATE_DELETE_TYPE, NULL);
  	cmd = GLADE_COMMAND (me);
 
- 	me->widget       = g_object_ref(widget);
- 	me->create       = create;
-	me->placeholder  = placeholder;
-	cmd->description =
+ 	me->widget        = g_object_ref(widget);
+ 	me->create        = create;
+	me->placeholder   = placeholder;
+	me->parent_widget = parent;
+	cmd->description  =
 		g_strdup_printf (_("%s %s"), create ?
 				 "Create" : "Delete", widget->name);
 	
@@ -709,7 +719,8 @@ glade_command_delete (GladeWidget *widge
 	if (widget->internal)
 		return;
 
-	glade_command_create_delete_common (widget, NULL, FALSE);
+	glade_command_create_delete_common (widget, glade_widget_get_parent (widget),
+					    NULL, FALSE);
 }
 
 /**
@@ -728,36 +739,40 @@ glade_command_delete (GladeWidget *widge
  */
 void
 glade_command_create (GladeWidgetClass *class,
+		      GladeWidget      *parent,
 		      GladePlaceholder *placeholder,
-		      GladeProject *project)
+		      GladeProject     *project)
 {
-	GladeProjectWindow *gpw;
-	GladeWidget *widget;
-	GladeWidget *parent = NULL;
+	GladeProjectWindow *gpw = glade_project_window_get ();
+	GladeWidget        *widget;
 
 	g_return_if_fail (GLADE_IS_WIDGET_CLASS (class));
-	g_return_if_fail (placeholder != NULL || GLADE_IS_PROJECT (project));
 
-	gpw = glade_project_window_get ();
+	/* Need either a parent or a placeholder or a project
+	 */
+	g_return_if_fail (parent      != NULL ||
+			  placeholder != NULL ||
+			  GLADE_IS_PROJECT (project));
+	g_assert         (gpw != NULL);
 	g_return_if_fail (GLADE_IS_PALETTE (gpw->palette));
 
-	/* AFAIK Only GtkWindow and derivaitves can be toplevels. */
-	if (g_type_is_a (class->type, GTK_TYPE_WINDOW) == FALSE)
+	if (g_type_is_a (class->type, GTK_TYPE_WINDOW) == FALSE && !parent)
 	{
-		parent = glade_placeholder_get_parent (placeholder);
-		g_return_if_fail (parent != NULL);
+		g_return_if_fail (placeholder != NULL);
+		g_return_if_fail ((parent = glade_placeholder_get_parent (placeholder)));
+		if (!project) project = parent->project;
 	}
+	else if (parent) project = parent->project;
 	
-	if (!project)
-		project = parent->project;
+	g_return_if_fail (project != NULL);
 
-	widget = glade_widget_new (class, project);
+	widget = glade_widget_new (parent, class, project);
 
 	/* widget may be null, e.g. the user clicked cancel on a query */
 	if (widget == NULL)
 		return;
 
-	glade_command_create_delete_common (widget, placeholder, TRUE);
+	glade_command_create_delete_common (widget, parent, placeholder, TRUE);
 
 	/* reset the palette */
 	glade_palette_unselect_widget (gpw->palette);
@@ -778,10 +793,10 @@ typedef enum {
 typedef struct {
 	GladeCommand parent;
 
-	GladeClipboard *clipboard;
-	GladeWidget *widget;
-	GladePlaceholder *placeholder;
-	GladeCutCopyPasteType type;
+	GladeWidget            *parent_widget;
+	GladeWidget            *widget;
+	GladePlaceholder       *placeholder;
+	GladeCutCopyPasteType   type;
 } GladeCommandCutCopyPaste;
 
 
@@ -795,31 +810,34 @@ GLADE_MAKE_COMMAND (GladeCommandCutCopyP
 static gboolean
 glade_command_paste_execute (GladeCommandCutCopyPaste *me)
 {
-	GladeWidget *glade_widget = me->widget;
-	GladePlaceholder *placeholder = me->placeholder;
-	GladeWidget *parent;
-	GladeProject *project;
+	GladeProjectWindow *gpw = glade_project_window_get ();
 
-	g_return_val_if_fail (g_list_find (me->clipboard->widgets, glade_widget), TRUE);
+	g_return_val_if_fail (g_list_find (gpw->clipboard->widgets, me->widget), TRUE);
 
-	parent  = glade_placeholder_get_parent (placeholder);
-	project = parent->project;
-
-	if (!GTK_WIDGET_TOPLEVEL (glade_widget->object))
+	if (me->parent_widget != NULL)
 	{
-		g_object_ref (G_OBJECT (placeholder));
-		glade_widget_replace
-			(glade_placeholder_get_parent (placeholder),
-			 G_OBJECT (placeholder), glade_widget->object);
+		if (me->placeholder)
+			glade_widget_replace
+				(me->parent_widget,
+				 G_OBJECT (me->placeholder),
+				 me->widget->object);
+		else
+		{
+			glade_widget_class_container_add
+				(me->parent_widget->widget_class,
+				 me->parent_widget->object,
+				 me->widget->object);
+			glade_widget_set_parent (me->widget, me->parent_widget);
+		}
 	}
 
-	glade_project_add_object    (project,               glade_widget->object);
-	glade_project_selection_set (glade_widget->project, glade_widget->object, TRUE);
+	glade_project_add_object    (me->widget->project, me->widget->object);
+	glade_project_selection_set (me->widget->project, me->widget->object, TRUE);
 
-	if (GTK_IS_WIDGET (glade_widget->object))
-		gtk_widget_show_all (GTK_WIDGET (glade_widget->object));
+	if (GTK_IS_WIDGET (me->widget->object))
+		gtk_widget_show_all (GTK_WIDGET (me->widget->object));
 
-	glade_clipboard_remove (me->clipboard, glade_widget);
+	glade_clipboard_remove (gpw->clipboard, me->widget);
 
 	return TRUE;
 }
@@ -827,29 +845,32 @@ glade_command_paste_execute (GladeComman
 static gboolean
 glade_command_cut_execute (GladeCommandCutCopyPaste *me)
 {
-	GladeWidget *glade_widget = me->widget;
+	GladeProjectWindow *gpw = glade_project_window_get ();
 
-	g_return_val_if_fail (glade_widget != NULL, TRUE);
+	g_return_val_if_fail (me->widget != NULL, TRUE);
 
-	glade_clipboard_add (me->clipboard, glade_widget);
+	glade_clipboard_add (gpw->clipboard, me->widget);
 
-	if (glade_widget_get_parent (glade_widget))
+	if (me->parent_widget)
 	{
-		if (me->placeholder == NULL)
-		{
-			me->placeholder = GLADE_PLACEHOLDER (glade_placeholder_new ());
-			g_object_ref (G_OBJECT (me->placeholder));
-		}
-
-		glade_widget_replace
-			(glade_widget_get_parent (glade_widget),
-			 glade_widget->object, G_OBJECT (me->placeholder));
+		if (me->placeholder)
+			glade_widget_replace
+				(me->parent_widget,
+				 me->widget->object,
+				 G_OBJECT (me->placeholder));
+		else
+			glade_widget_class_container_remove
+				(me->parent_widget->widget_class,
+				 me->parent_widget->object,
+				 me->widget->object);
 	}
+	
+	if (GTK_IS_WIDGET (me->widget->object))
+		gtk_widget_hide (GTK_WIDGET (me->widget->object));
 
-	if (GTK_IS_WIDGET (glade_widget->object))
-		gtk_widget_hide (GTK_WIDGET (glade_widget->object));
-
-	glade_project_remove_object (glade_widget->project, glade_widget->object);
+	/* This doesn't NULLify the widget->project pointer.
+	 */
+	glade_project_remove_object (me->widget->project, me->widget->object);
 
 	return TRUE;
 }
@@ -857,14 +878,16 @@ glade_command_cut_execute (GladeCommandC
 static gboolean
 glade_command_copy_execute (GladeCommandCutCopyPaste *me)
 {
-	glade_clipboard_add (me->clipboard, me->widget);
+	GladeProjectWindow *gpw = glade_project_window_get ();
+	glade_clipboard_add (gpw->clipboard, me->widget);
 	return TRUE;
 }
 
 static gboolean
 glade_command_copy_undo (GladeCommandCutCopyPaste *me)
 {
-	glade_clipboard_remove (me->clipboard, me->widget);
+	GladeProjectWindow *gpw = glade_project_window_get ();
+	glade_clipboard_remove (gpw->clipboard, me->widget);
 	return TRUE;
 }
 
@@ -944,31 +967,33 @@ glade_command_cut_copy_paste_collapse (G
 }
 
 static void
-glade_command_cut_copy_paste_common (GladeWidget *widget,
-				     GladePlaceholder *placeholder,
-				     GladeProject *project,
-				     GladeCutCopyPasteType type)
+glade_command_cut_copy_paste_common (GladeWidget           *widget,
+				     GladeWidget           *parent,
+				     GladePlaceholder      *placeholder,
+				     GladeProject          *project,
+				     GladeCutCopyPasteType  type,
+				     gboolean               needs_placeholder)
 {
 	GladeCommandCutCopyPaste *me;
 	GladeCommand *cmd;
-	GladeProjectWindow *gpw;
 
 	me = (GladeCommandCutCopyPaste *) g_object_new (GLADE_COMMAND_CUT_COPY_PASTE_TYPE, NULL);
 	cmd = (GladeCommand *) me;
-	
-	gpw = glade_project_window_get ();
 
-	me->type        = type;
-	me->widget      =
+	me->type           = type;
+	me->widget         =
 		(type == GLADE_COPY) ?
 		glade_widget_dup (widget) :
 		g_object_ref (widget);
-	me->placeholder = placeholder;
-	me->clipboard   = gpw->clipboard;
+	me->parent_widget  = parent;
 
-	if (me->placeholder)
-		g_object_ref (G_OBJECT (me->placeholder));
+	me->placeholder    =
+		(placeholder != NULL) ? placeholder :
+		(needs_placeholder    ?
+		 (GtkWidget *) glade_placeholder_new () : NULL);
 
+	if (me->placeholder) g_object_ref (placeholder);
+	
 	switch (type) {
 	case GLADE_CUT:
 		cmd->description = g_strdup_printf (_("Cut %s"), widget->name);
@@ -997,27 +1022,19 @@ glade_command_cut_copy_paste_common (Gla
  * TODO: write me
  */
 void
-glade_command_paste (GladePlaceholder *placeholder)
+glade_command_paste (GladeWidget *parent, GladePlaceholder *placeholder)
 {
 	GladeProjectWindow *gpw;
 	GladeWidget *widget;
-	GladeWidget *parent;
 
 	gpw = glade_project_window_get ();
 
-	if (!placeholder) {
-		glade_util_ui_warn (gpw->window, _("Placeholder not selected!"));
-		return;
-	}
-
-	g_return_if_fail (GLADE_IS_PLACEHOLDER (placeholder));
-
 	widget = gpw->clipboard->curr;
 	if (widget == NULL)
 		return;
 
-	parent = glade_placeholder_get_parent (placeholder);
-	glade_command_cut_copy_paste_common (widget, placeholder, parent->project, GLADE_PASTE);
+	glade_command_cut_copy_paste_common (widget, parent, placeholder,
+					     parent->project, GLADE_PASTE, FALSE);
 }
 
 /**
@@ -1027,24 +1044,17 @@ glade_command_paste (GladePlaceholder *p
  * TODO: write me
  */
 void
-glade_command_cut (GladeWidget *widget)
+glade_command_cut (GladeWidget *widget, gboolean needs_placeholder)
 {
-	GladeProjectWindow *gpw;
-
-	gpw = glade_project_window_get ();
-
-	if (!widget) {
-		glade_util_ui_warn (gpw->window, _("No widget selected!"));
-		return;
-	}
-
 	g_return_if_fail (GLADE_IS_WIDGET (widget));
 
 	/* internal children cannot be cut. Should we notify the user? */
 	if (widget->internal)
 		return;
 
-	glade_command_cut_copy_paste_common (widget, NULL, widget->project, GLADE_CUT);
+	glade_command_cut_copy_paste_common (widget, glade_widget_get_parent (widget),
+					     NULL, widget->project, GLADE_CUT,
+					     needs_placeholder);
 }
 
 /**
@@ -1056,14 +1066,6 @@ glade_command_cut (GladeWidget *widget)
 void
 glade_command_copy (GladeWidget *widget)
 {
-	GladeProjectWindow *gpw;
-
-	gpw = glade_project_window_get ();
-
-	if (!widget) {
-		glade_util_ui_warn (gpw->window, _("No widget selected!"));
-		return;
-	}
 
 	g_return_if_fail (GLADE_IS_WIDGET (widget));
 
@@ -1071,7 +1073,8 @@ glade_command_copy (GladeWidget *widget)
 	if (widget->internal)
 		return;
 
-	glade_command_cut_copy_paste_common (widget, NULL, widget->project, GLADE_COPY);
+	glade_command_cut_copy_paste_common (widget, glade_widget_get_parent (widget),
+					     NULL, widget->project, GLADE_COPY, FALSE);
 }
 
 /*********************************************************/
Index: src/glade-command.h
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-command.h,v
retrieving revision 1.11
diff -u -p -r1.11 glade-command.h
--- src/glade-command.h	5 Nov 2004 19:44:21 -0000	1.11
+++ src/glade-command.h	30 Nov 2004 18:40:17 -0000
@@ -48,11 +48,14 @@ void glade_command_set_property		(GladeP
 void glade_command_set_name		(GladeWidget *glade_widget, const gchar *name);
 
 void glade_command_delete		(GladeWidget *glade_widget);
-void glade_command_create		(GladeWidgetClass *widget_class, GladePlaceholder *placeholder, GladeProject *project);
+void glade_command_create		(GladeWidgetClass *widget_class,
+					 GladeWidget      *parent,
+					 GladePlaceholder *placeholder,
+					 GladeProject     *project);
 
-void glade_command_cut			(GladeWidget *glade_widget);
+void glade_command_cut                  (GladeWidget *widget, gboolean needs_placeholder);
 void glade_command_copy			(GladeWidget *glade_widget);
-void glade_command_paste		(GladePlaceholder *placeholder);
+void glade_command_paste		(GladeWidget *parent, GladePlaceholder *placeholder);
 
 void glade_command_add_signal		(GladeWidget *glade_widget, const GladeSignal *signal);
 void glade_command_remove_signal	(GladeWidget *glade_widget, const GladeSignal *signal);
Index: src/glade-editor.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-editor.c,v
retrieving revision 1.61.2.1
diff -u -p -r1.61.2.1 glade-editor.c
--- src/glade-editor.c	18 Nov 2004 06:25:34 -0000	1.61.2.1
+++ src/glade-editor.c	30 Nov 2004 18:40:17 -0000
@@ -159,14 +159,16 @@ glade_editor_notebook_page (const gchar 
 static void
 glade_editor_init (GladeEditor *editor)
 {
-	editor->tooltips = gtk_tooltips_new ();
-
-	editor->vbox_widget  = glade_editor_notebook_page (_("Widget"), GTK_WIDGET (editor));
+	editor->vbox_widget  = glade_editor_notebook_page (_("General"), GTK_WIDGET (editor));
 	editor->vbox_packing = glade_editor_notebook_page (_("Packing"), GTK_WIDGET (editor));
 	editor->vbox_common  = glade_editor_notebook_page (_("Common"), GTK_WIDGET (editor));
 	editor->vbox_signals = glade_editor_notebook_page (_("Signals"), GTK_WIDGET (editor));
 	editor->widget_tables = NULL;
 	editor->loading = FALSE;
+
+	/* Common page is removed for non-widgets.
+	 */
+	g_object_ref (G_OBJECT (editor->vbox_common));
 }
 
 /**
@@ -246,30 +248,34 @@ glade_editor_property_changed_text (GtkW
 	glade_editor_property_load (property, property->property->widget);
 }
 
-static void
-glade_editor_property_changed_text_view (GtkTextBuffer *buffer,
-					 GladeEditorProperty *property)
+static gboolean
+glade_editor_text_view_focus_out (GtkTextView *view,
+				  GdkEventFocus *event,
+				  GladeEditorProperty *property)
 {
-	GtkTextIter start;
-	GtkTextIter end;
 	gchar *text;
-
-	g_return_if_fail (property != NULL);
+	GtkTextBuffer *buffer;
+	GtkTextIter    start, end;
+	
+	g_return_val_if_fail (property != NULL, FALSE);
 
 	if (property->property->loading)
-		return;
+		return FALSE;
+
+	buffer = gtk_text_view_get_buffer (view);
 
 	gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
 	gtk_text_buffer_get_iter_at_offset (buffer, &end,
 					    gtk_text_buffer_get_char_count (buffer));
 
 	text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
-
+	
 	glade_editor_property_changed_text_common (property->property, text);
 
 	g_free (text);
-
+	
 	glade_editor_property_load (property, property->property->widget);
+	return FALSE;
 }
 
 static void
@@ -734,25 +740,24 @@ glade_editor_create_input_text (GladeEdi
 		
 		entry = gtk_entry_new ();
 
-		g_signal_connect (G_OBJECT (entry), "changed",
+		g_signal_connect (G_OBJECT (entry), "activate",
 				  G_CALLBACK (glade_editor_property_changed_text),
 				  property);
 
 		return entry;
 	} else {
+		GtkTextView   *view;
 		GtkTextBuffer *buffer;
-		GtkWidget *view;
 
-		view = gtk_text_view_new ();
-		gtk_text_view_set_editable (GTK_TEXT_VIEW (view), TRUE);
+		view = GTK_TEXT_VIEW (gtk_text_view_new ());
+		buffer = gtk_text_view_get_buffer (view);
 
-		buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+		gtk_text_view_set_editable (view, TRUE);
 
-		g_signal_connect_data (G_OBJECT (buffer), "changed",
-				       G_CALLBACK (glade_editor_property_changed_text_view),
-				       property, NULL, 0);
-		
-		return view;
+		g_signal_connect (G_OBJECT (view), "focus-out-event",
+				  G_CALLBACK (glade_editor_text_view_focus_out),
+				  property);
+		return GTK_WIDGET (view);
 	}
 
 	return NULL;
@@ -937,7 +942,7 @@ glade_editor_table_append_item (GladeEdi
 }
 
 static void
-glade_editor_table_append_standard_fields (GladeEditorTable *table)
+glade_editor_table_append_name_field (GladeEditorTable *table)
 {
 	GtkWidget *gtk_table;
 	GtkWidget *label;
@@ -957,6 +962,16 @@ glade_editor_table_append_standard_field
 	glade_editor_table_attach (gtk_table, label, 0, table->rows);
 	glade_editor_table_attach (gtk_table, entry, 1, table->rows);
 	table->rows++;
+}
+
+static void
+glade_editor_table_append_class_field (GladeEditorTable *table)
+{
+	GtkWidget *gtk_table;
+	GtkWidget *label;
+	GtkWidget *entry;
+
+	gtk_table = table->table_widget;
 	
 	/* Class */
 	label = gtk_label_new (_("Class :"));
@@ -995,7 +1010,9 @@ glade_editor_table_append_items (GladeEd
 			continue;
 		else if (type == TABLE_TYPE_COMMON && property_class->common == FALSE)
 			continue;
-
+		else if (type == TABLE_TYPE_GENERAL && property_class->common == TRUE)
+			continue;
+		
 		property = glade_editor_table_append_item (table, property_class);
 		if (property != NULL)
 			new_list = g_list_prepend (new_list, property);
@@ -1060,8 +1077,15 @@ glade_editor_table_create (GladeEditor *
 	table->editor = editor;
 	table->glade_widget_class = class;
 	table->type = type;
+
 	if (type == TABLE_TYPE_GENERAL)
-		glade_editor_table_append_standard_fields (table);
+	{
+		if (g_type_is_a (class->type, GTK_TYPE_WIDGET))
+			glade_editor_table_append_name_field (table);
+		
+		glade_editor_table_append_class_field (table);
+	}
+
 	if (!glade_editor_table_append_items (table, class,
 					      &table->properties, type))
 		return NULL;
@@ -1503,7 +1527,10 @@ glade_editor_load_packing_page (GladeEdi
 
 	/* Free the old structs */
 	if (old)
+	{
+		g_object_unref (G_OBJECT (old->table_widget));
 		g_free (old);
+	}
 	for (list = old_props; list; list = list->next)
 		g_free (list->data);
 	old_props = NULL;
@@ -1576,8 +1603,9 @@ glade_editor_load_widget (GladeEditor *e
 	editor->loading = TRUE;
 
 	/* Load each GladeEditorProperty */
-	table = glade_editor_get_table_from_class (editor, class, FALSE);
-	gtk_entry_set_text (GTK_ENTRY (table->name_entry), widget->name);
+	table = glade_editor_get_table_from_class (editor, class, TABLE_TYPE_GENERAL);
+	if (table->name_entry)
+		gtk_entry_set_text (GTK_ENTRY (table->name_entry), widget->name);
 
 	for (list = table->properties; list; list = list->next)
 	{
@@ -1586,7 +1614,7 @@ glade_editor_load_widget (GladeEditor *e
 	}
 
 	/* Load each GladeEditorProperty for the common tab */
-	table = glade_editor_get_table_from_class (editor, class, TRUE);
+	table = glade_editor_get_table_from_class (editor, class, TABLE_TYPE_COMMON);
 	for (list = table->properties; list; list = list->next)
 	{
 		property = list->data;
@@ -1608,10 +1636,10 @@ glade_editor_load_widget (GladeEditor *e
 void
 glade_editor_add_signal (GladeEditor *editor,
 			 guint signal_id,
-			 const char *callback_name)
+			 const gchar *callback_name)
 {
-	const char *widget_name;
-	const char *signal_name;
+	const gchar *widget_name;
+	const gchar *signal_name;
 	GType widget_type;
 
 	g_return_if_fail (GLADE_IS_EDITOR (editor));
Index: src/glade-editor.h
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-editor.h,v
retrieving revision 1.17.2.1
diff -u -p -r1.17.2.1 glade-editor.h
--- src/glade-editor.h	18 Nov 2004 06:25:34 -0000	1.17.2.1
+++ src/glade-editor.h	30 Nov 2004 18:40:17 -0000
@@ -22,7 +22,6 @@ typedef struct _GladeEditorTable     Gla
 typedef struct _GladeEditorProperty  GladeEditorProperty;
 typedef enum   _GladeEditorTableType GladeEditorTableType;
 
-
 enum _GladeEditorTableType
 {
 	TABLE_TYPE_GENERAL,
@@ -61,13 +60,6 @@ struct _GladeEditor
 					 * when we switch from widgets of the
 					 * same class
 					 */
-	GtkTooltips *tooltips;   /* The tooltips for the editor. This are not
-				  * beeing used ATM. I wonder if they should
-				  * go into GladeWidgetClass since they are
-				  * different for each class or if this
-				  * will point to the tooltips for that
-				  * class. Oh well, we'll see
-				  */
 	GtkWidget *vbox_widget;  /* The editor has (at this moment) four tabs
 				  * this are pointers to the vboxes inside
 				  * each tab. The vboxes are wrapped into a
Index: src/glade-gtk.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-gtk.c,v
retrieving revision 1.60.2.1
diff -u -p -r1.60.2.1 glade-gtk.c
--- src/glade-gtk.c	18 Nov 2004 06:25:34 -0000	1.60.2.1
+++ src/glade-gtk.c	30 Nov 2004 18:40:17 -0000
@@ -79,7 +79,7 @@ glade_gtk_stock_get_type (void)
 			{ 4,   "Close",  "gtk-close"  },
 			{ 0, NULL, NULL }
 		};
-		etype = g_enum_register_static ("GtkTtScrollType", values);
+		etype = g_enum_register_static ("GladeGtkStockType", values);
 	}
 	return etype;
 }
@@ -1047,23 +1047,16 @@ glade_gtk_fixed_button_press (GtkWidget 
 		gpw = glade_project_window_get ();
 		if (gpw->add_class != NULL)
 		{
-			GtkWidget     *placeholder = glade_placeholder_new ();
 			GtkWidget     *new_widget;
 			GladeWidget   *new_gwidget;
+			GladeWidget   *fixed_gwidget;
 			GladeProperty *property;
 			GList         *selection;
 			GValue         value = { 0, };
 
-			/* A widget type is selected in the palette.
-			 * Create a placeholder at the mouse position and
-			 * add a new widget of that type with a default
-			 * size request.
-			 */
-			gtk_fixed_put(GTK_FIXED(widget), placeholder,
-				      (gint)event->x, (gint)event->y);
-
-			glade_command_create (gpw->add_class,
-					      GLADE_PLACEHOLDER(placeholder), NULL);
+			fixed_gwidget = glade_widget_get_from_gobject (widget);
+			
+			glade_command_create (gpw->add_class, fixed_gwidget, NULL, NULL);
 
 			selection = glade_project_selection_get
 				(glade_project_window_get_active_project(gpw));
@@ -1073,6 +1066,16 @@ glade_gtk_fixed_button_press (GtkWidget 
 			
 			g_value_init (&value, G_TYPE_INT);
 
+			property = glade_widget_get_property (new_gwidget, "x");
+			property->enabled = TRUE;
+			g_value_set_int (&value, event->x);
+			glade_property_set (property, &value);
+
+			property = glade_widget_get_property (new_gwidget, "y");
+			property->enabled = TRUE;
+			g_value_set_int (&value, event->y);
+			glade_property_set (property, &value);
+			
 			property = glade_widget_get_property (new_gwidget, "width-request");
 			property->enabled = TRUE;
 			g_value_set_int (&value, FIXED_DEFAULT_CHILD_WIDTH);
@@ -1086,7 +1089,8 @@ glade_gtk_fixed_button_press (GtkWidget 
 			/* We need to resync the editor so that width-request/height-request
 			 * are actualy enabled in the editor
 			 */
-			glade_editor_load_widget (gpw->editor, gpw->editor->loaded_widget);
+			glade_editor_load_widget (gpw->editor, NULL);
+			glade_editor_load_widget (gpw->editor, new_gwidget);
 			
 		}
 		return TRUE;
Index: src/glade-placeholder.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-placeholder.c,v
retrieving revision 1.56.2.1
diff -u -p -r1.56.2.1 glade-placeholder.c
--- src/glade-placeholder.c	18 Nov 2004 06:25:34 -0000	1.56.2.1
+++ src/glade-placeholder.c	30 Nov 2004 18:40:17 -0000
@@ -312,7 +312,7 @@ glade_placeholder_button_press (GtkWidge
 			/* A widget type is selected in the palette.
 			 * Add a new widget of that type.
 			 */
-			glade_command_create (gpw->add_class, placeholder, NULL);
+			glade_command_create (gpw->add_class, NULL, placeholder, NULL);
 		}
 		else
 		{
Index: src/glade-popup.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-popup.c,v
retrieving revision 1.17.2.1
diff -u -p -r1.17.2.1 glade-popup.c
--- src/glade-popup.c	18 Nov 2004 06:25:34 -0000	1.17.2.1
+++ src/glade-popup.c	30 Nov 2004 18:40:17 -0000
@@ -41,23 +41,49 @@ glade_popup_select_cb (GtkMenuItem *item
 static void
 glade_popup_cut_cb (GtkMenuItem *item, GladeWidget *widget)
 {
-	glade_command_cut (widget);
+	GladeWidget *parent;
+	gboolean need_placeholder = FALSE;
+
+	if (!widget)
+	{
+		GladeProjectWindow *gpw = glade_project_window_get ();
+		glade_util_ui_warn (gpw->window, _("No widget selected!"));
+		return;
+	}
+
+	/* If this widget is parented through the GtkContainer interface,
+	 * a placeholder will be needed.
+	 */
+	if ((parent = glade_widget_get_parent (widget)) != NULL)
+		need_placeholder =
+			glade_util_gtkcontainer_relation (parent, widget);
+	glade_command_cut (widget, need_placeholder);
 }
 
 static void
 glade_popup_copy_cb (GtkMenuItem *item, GladeWidget *widget)
 {
+	if (!widget)
+	{
+		GladeProjectWindow *gpw = glade_project_window_get ();
+		glade_util_ui_warn (gpw->window, _("No widget selected!"));
+		return;
+	}
+
 	glade_command_copy (widget);
 }
 
 static void
 glade_popup_paste_cb (GtkMenuItem *item, GladeWidget *widget)
 {
-	glade_implement_me ();
-	/*
-	 * look in glade-placeholder.c (glade_placeholder_on_button_press_event
-	 * for the "paste" operation code.
-	 */
+	if (!widget)
+	{
+		GladeProjectWindow *gpw = glade_project_window_get ();
+		glade_util_ui_warn (gpw->window, _("No widget selected!"));
+		return;
+	}
+
+	glade_command_paste (widget, NULL);
 }
 
 static void
@@ -70,17 +96,24 @@ static void
 glade_popup_placeholder_paste_cb (GtkMenuItem *item,
 				  GladePlaceholder *placeholder)
 {
-	glade_command_paste (placeholder);
+	if (!placeholder)
+	{
+		GladeProjectWindow *gpw = glade_project_window_get ();
+		glade_util_ui_warn (gpw->window, _("No placeholder selected!"));
+		return;
+	}
+	glade_command_paste (glade_placeholder_get_parent (placeholder),
+			     placeholder);
 }
 
 static void
 glade_popup_add_item_cb (GtkMenuItem *item,
 			 GladeWidget *widget)
 {
-	GladeSupportedChild *support =
-		g_object_get_data (G_OBJECT (item), "support");
-
-	/* XXX finish me !!! */
+	GladeWidgetClass    *class;
+	if ((class =
+	     g_object_get_data (G_OBJECT (item), "widget_class")) != 0)
+		glade_command_create (class, widget, NULL, NULL);
 }
 
 /*
@@ -145,14 +178,11 @@ glade_popup_add_children (GtkWidget* pop
 	GtkWidget *menu_item =
 		gtk_image_menu_item_new_from_stock (GTK_STOCK_ADD, NULL);
 	GtkWidget *add_menu  = gtk_menu_new ();
-	GtkWidget *seperator = gtk_menu_item_new ();
-	GList     *list;
+	GList     *list, *types, *l;
 
 	gtk_widget_show (menu_item);
-	gtk_widget_show (seperator);
 	gtk_widget_show (add_menu);
 
-	gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), seperator);
 	gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);
 	gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), add_menu);
 		
@@ -160,19 +190,29 @@ glade_popup_add_children (GtkWidget* pop
 	     list && list->data; list = list->next)
 	{
 		GladeSupportedChild *support = list->data;
-		GtkWidget           *item;
 		
 		if (g_type_is_a (support->type, GTK_TYPE_WIDGET))
 			continue;
 
-		item = glade_popup_append_item (add_menu, NULL, g_type_name (support->type),
-						TRUE, glade_popup_add_item_cb, widget);
-
-		g_object_set_data (G_OBJECT (item), "support", support);
+		if ((types =
+		     glade_widget_class_get_derived_types (support->type)) != NULL)
+		{
+			for (l = types; l && l->data; l = l->next)
+			{
+				GladeWidgetClass *class = l->data;
+				GtkWidget        *item =
+					glade_popup_append_item
+					(add_menu, NULL, g_type_name (class->type),
+					 TRUE, glade_popup_add_item_cb, widget);
+				g_object_set_data (G_OBJECT (item),
+						   "widget_class", class);
+
+			}
+			g_list_free (types);
+		}
 	}
 }
 
-
 static GtkWidget *
 glade_popup_create_menu (GladeWidget *widget, gboolean add_childs)
 {
@@ -186,8 +226,12 @@ glade_popup_create_menu (GladeWidget *wi
 				 glade_popup_cut_cb, widget);
 	glade_popup_append_item (popup_menu, GTK_STOCK_COPY, NULL, TRUE,
 				 glade_popup_copy_cb, widget);
-	glade_popup_append_item (popup_menu, GTK_STOCK_PASTE, NULL, TRUE,
-				 glade_popup_paste_cb, widget);
+
+
+	if (glade_util_widget_pastable (widget))
+		glade_popup_append_item (popup_menu, GTK_STOCK_PASTE, NULL, TRUE,
+					 glade_popup_paste_cb, widget);
+	
 	glade_popup_append_item (popup_menu, GTK_STOCK_DELETE, NULL, TRUE,
 				 glade_popup_delete_cb, widget);
 
@@ -225,11 +269,12 @@ glade_popup_create_placeholder_menu (Gla
  * glade_popup_widget_pop:
  * @widget:
  * @event:
+ * @add_children:
  *
  * TODO: write me
  */
 void
-glade_popup_widget_pop (GladeWidget *widget, GdkEventButton *event)
+glade_popup_widget_pop (GladeWidget *widget, GdkEventButton *event, gboolean add_children)
 {
 	GtkWidget *popup_menu;
 	gint button;
@@ -237,7 +282,7 @@ glade_popup_widget_pop (GladeWidget *wid
 
 	g_return_if_fail (GLADE_IS_WIDGET (widget));
 
-	popup_menu = glade_popup_create_menu (widget, TRUE);
+	popup_menu = glade_popup_create_menu (widget, add_children);
 
 	if (event)
 	{
Index: src/glade-popup.h
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-popup.h,v
retrieving revision 1.3
diff -u -p -r1.3 glade-popup.h
--- src/glade-popup.h	23 Jan 2004 12:05:26 -0000	1.3
+++ src/glade-popup.h	30 Nov 2004 18:40:17 -0000
@@ -4,7 +4,7 @@
 
 G_BEGIN_DECLS
 
-void glade_popup_widget_pop (GladeWidget *widget, GdkEventButton *event);
+void glade_popup_widget_pop (GladeWidget *widget, GdkEventButton *event, gboolean add_children);
 void glade_popup_placeholder_pop (GladePlaceholder *placeholder, GdkEventButton *event);
 
 G_END_DECLS
Index: src/glade-project-view.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-project-view.c,v
retrieving revision 1.40.2.1
diff -u -p -r1.40.2.1 glade-project-view.c
--- src/glade-project-view.c	18 Nov 2004 06:25:34 -0000	1.40.2.1
+++ src/glade-project-view.c	30 Nov 2004 18:40:17 -0000
@@ -25,6 +25,7 @@
 #include "glade-project.h"
 #include "glade-widget-class.h"
 #include "glade-project-view.h"
+#include "glade-popup.h"
 
 enum
 {
@@ -129,22 +130,44 @@ glade_project_view_find_iter_by_widget (
 					GladeWidget *findme)
 {
 	GtkTreeIter iter;
-	GtkTreeIter *retval;
 
 	if (!gtk_tree_model_get_iter_root (model, &iter))
 	{
-		g_warning ("Could not find first widget.");
 		return NULL;
 	}
+	return glade_project_view_find_iter (model, &iter, findme);
+}
 
-	retval = glade_project_view_find_iter (model, &iter, findme);
-
-	if (!retval)
-		g_warning ("Could not find iterator for %s\n", findme->name);
+static GList *
+glade_project_view_list_child_iters (GtkTreeStore *model,
+				     GladeWidget  *parent)
+{
+	GList *children, *l, *child_iters = NULL;
 
-	return retval;
+	if ((children = glade_widget_class_container_get_all_children
+	     (parent->widget_class, parent->object)) != NULL)
+	{
+		for (l = children; l && l->data; l = l->next)
+		{
+			GObject     *object = l->data;
+			GladeWidget *gwidget;
+			if ((gwidget = glade_widget_get_from_gobject (object)) != NULL)
+			{
+				GtkTreeIter *iter;
+
+				if ((iter = glade_project_view_find_iter_by_widget
+				     (GTK_TREE_MODEL (model), gwidget)) != NULL)
+				{
+					child_iters = g_list_prepend (child_iters, iter);
+				}
+			}
+		}
+		g_list_free (children);
+	}
+	return g_list_reverse (child_iters);
 }
 
+
 static void
 glade_project_view_widget_name_changed (GladeProjectView *view,
 					GladeWidget *findme)
@@ -178,8 +201,8 @@ glade_project_view_populate_model_real (
 					GtkTreeIter *parent_iter,
 					gboolean add_childs)
 {
-	GList *list;
-	GtkTreeIter iter;
+	GList *children, *list;
+	GtkTreeIter       iter;
 
 	list = g_list_copy (widgets);
 	list = g_list_reverse (list);
@@ -187,28 +210,26 @@ glade_project_view_populate_model_real (
 	{
 		GladeWidget *widget;
 
-		widget = glade_widget_get_from_gobject (list->data);
-		if (widget)
+		if ((widget = glade_widget_get_from_gobject (list->data)) != NULL)
 		{
 			gtk_tree_store_append (model, &iter, parent_iter);
-			gtk_tree_store_set (model, &iter,
-					    WIDGET_COLUMN, widget,
-					    -1);
-		}
+			gtk_tree_store_set (model, &iter, WIDGET_COLUMN, widget, -1);
 
-		if (add_childs && GTK_IS_CONTAINER (list->data))
-		{
-			GList *children;
-			GtkTreeIter *copy = NULL;
+			if (add_childs &&
+			    (children = glade_widget_class_container_get_all_children
+			     (widget->widget_class, widget->object)) != NULL)
+			{
+				GtkTreeIter *copy = NULL;
+
+				copy = gtk_tree_iter_copy (&iter);
+				glade_project_view_populate_model_real
+					(model, children, copy, TRUE);
+				gtk_tree_iter_free (copy);
 
-			copy = gtk_tree_iter_copy (&iter);
-			children = gtk_container_get_children (GTK_CONTAINER (list->data));
-			glade_project_view_populate_model_real (model, children, copy, TRUE);
-			gtk_tree_iter_free (copy);
-			g_list_free (children);
+				g_list_free (children);
+			}
 		}
 	}
-
 	g_list_free (list);
 }
 
@@ -227,7 +248,7 @@ glade_project_view_populate_model (Glade
 	for (list = project->objects; list; list = list->next)
 	{
 		GObject *object = G_OBJECT (list->data);
-		if (GTK_WIDGET_TOPLEVEL (object))
+		if (GTK_IS_WIDGET (object) && GTK_WIDGET_TOPLEVEL (object))
 			toplevels = g_list_append (toplevels, object);
 	}
 
@@ -243,11 +264,12 @@ glade_project_view_add_item (GladeProjec
 			     GladeWidget *widget)
 {
 	GladeWidgetClass *class;
-	GladeWidget *parent;
+	GladeWidget  *parent;
 	GtkTreeStore *model;
-	GtkTreeIter iter;
-	GtkTreeIter *parent_iter = NULL;
-
+	GtkTreeIter   iter;
+	GtkTreeIter  *parent_iter = NULL, *child_iter;
+	GList        *child_iters, *children, *l;
+	
 	g_return_if_fail (widget != NULL);
 
 	class = glade_widget_get_class (widget);
@@ -265,11 +287,25 @@ glade_project_view_add_item (GladeProjec
 	gtk_tree_store_append (model, &iter, parent_iter);
 	gtk_tree_store_set (model, &iter, WIDGET_COLUMN, widget, -1);
 
-	
-	/*
-	  XXX Add find any children and shuffle them around in the tree view.
-	*/
+	/* Remove all children */
+	if ((child_iters = 
+	     glade_project_view_list_child_iters (model, widget)) != NULL)
+	{
+		for (l = child_iters; l && l->data; l = l->next)
+		{
+			child_iter = l->data;
+			gtk_tree_store_remove (model, child_iter);
+		}
+	}
 
+	/* Repopulate these children properly.
+	 */
+	if ((children = glade_widget_class_container_get_all_children
+	     (widget->widget_class, widget->object)) != NULL)
+	{
+		glade_project_view_populate_model_real (model, children, &iter, TRUE);
+		g_list_free (children);
+	}
 	
 	view->updating_selection = TRUE;
 	glade_project_selection_set (widget->project,
@@ -292,8 +328,8 @@ glade_project_view_remove_item (GladePro
 	
 	model = GTK_TREE_MODEL (view->model);
 
-	iter = glade_project_view_find_iter_by_widget (model, widget);
-	gtk_tree_store_remove (view->model, iter);
+	if ((iter = glade_project_view_find_iter_by_widget (model, widget)) != NULL)
+		gtk_tree_store_remove (view->model, iter);
 }      
 
 /**
@@ -430,6 +466,42 @@ glade_project_view_item_activated_cb (Gt
 	}
 }
 
+static gint
+glade_project_view_button_press_cb (GtkWidget        *widget,
+				    GdkEventButton   *event,
+				    GladeProjectView *view)
+{
+	GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
+	GtkTreePath *path = NULL;
+
+	if (event->button == 3 &&
+	    event->window == gtk_tree_view_get_bin_window (tree_view))
+	{
+		if (gtk_tree_view_get_path_at_pos
+		    (tree_view, event->x, event->y,
+		     &path, NULL, NULL, NULL) && path != NULL)
+		{
+			GtkTreeIter  iter;
+			GladeWidget *widget = NULL;
+			if (gtk_tree_model_get_iter (GTK_TREE_MODEL (view->model),
+						     &iter, path))
+			{
+				/* Alright, now we can obtain the widget from the iter.
+				 */
+				gtk_tree_model_get (GTK_TREE_MODEL (view->model), &iter,
+						    WIDGET_COLUMN, &widget, -1);
+				if (widget != NULL)
+				{
+					glade_popup_widget_pop (widget, event, FALSE);
+				}
+			}
+			gtk_tree_path_free (path);
+		}
+		return TRUE;
+	}
+	return FALSE;
+}
+
 static void
 glade_project_view_cell_function (GtkTreeViewColumn *tree_column,
 				  GtkCellRenderer *cell,
@@ -517,6 +589,9 @@ glade_project_view_init (GladeProjectVie
 			       G_CALLBACK (glade_project_view_selection_changed_cb),
 			       view, NULL, 0);
 
+	g_signal_connect (G_OBJECT (view->tree_view), "button-press-event",
+			  G_CALLBACK (glade_project_view_button_press_cb), view);
+	
 	view->updating_selection = FALSE;
 }
 
Index: src/glade-project-window.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-project-window.c,v
retrieving revision 1.86.2.2
diff -u -p -r1.86.2.2 glade-project-window.c
--- src/glade-project-window.c	18 Nov 2004 06:25:34 -0000	1.86.2.2
+++ src/glade-project-window.c	30 Nov 2004 18:40:17 -0000
@@ -331,7 +331,7 @@ do_close (GladeProjectWindow *gpw, Glade
 	for (list = project->objects; list; list = list->next)
 	{
 		GObject *object = list->data;
-		if (GTK_WIDGET_TOPLEVEL (object))
+		if (GTK_IS_WIDGET (object) && GTK_WIDGET_TOPLEVEL (object))
 			gtk_widget_destroy (GTK_WIDGET(object));
 	}
 
@@ -439,13 +439,26 @@ gpw_cut_cb (void)
 
 	gpw = glade_project_window_get ();
 	list = glade_project_selection_get (gpw->active_project);
+
 	/* TODO: support multiple selected items */
 	if (list != NULL && list->next == NULL)
 	{
 		GladeWidget *widget = glade_widget_get_from_gobject (GTK_WIDGET (list->data));
+		GladeWidget *parent;
 
-		if (widget)
-			glade_command_cut (widget);
+		gboolean need_placeholder = FALSE;
+
+		if (!widget)
+		{
+			GladeProjectWindow *gpw = glade_project_window_get ();
+			glade_util_ui_warn (gpw->window, _("No widget selected!"));
+			return;
+		}
+
+		if ((parent = glade_widget_get_parent (widget)) != NULL)
+			need_placeholder =
+				glade_util_gtkcontainer_relation (parent, widget);
+		glade_command_cut (widget, need_placeholder);
 	}
 }
 
@@ -453,13 +466,39 @@ static void
 gpw_paste_cb (void)
 {
 	GladeProjectWindow *gpw;
-	GList *selection;
+	GList *list;
 
 	gpw = glade_project_window_get ();
+	list = glade_project_selection_get (gpw->active_project);
+
+	/* TODO: support multiple selected items */
+	if (list != NULL && list->next == NULL)
+	{
+		GladePlaceholder *placeholder = NULL;
+		GladeWidget      *widget;
 
-	selection = glade_project_selection_get (gpw->active_project);
-	if (selection != NULL && selection->next == NULL && GLADE_IS_PLACEHOLDER (selection->data))
-		glade_command_paste (GLADE_PLACEHOLDER (selection->data));
+
+		if (GLADE_IS_PLACEHOLDER (list->data))
+		{
+			placeholder = list->data;
+			widget = glade_placeholder_get_parent (placeholder);
+		}
+		else
+		{
+			widget = glade_widget_get_from_gobject (G_OBJECT (list->data));
+		}
+		
+		if (!widget)
+		{
+			GladeProjectWindow *gpw = glade_project_window_get ();
+			glade_util_ui_warn (gpw->window,
+					    _("No widget or placeholder selected!"));
+			return;
+		}
+
+		if (glade_util_widget_pastable (widget))
+			glade_command_paste (widget, placeholder);
+	}
 }
 
 static void
@@ -542,7 +581,7 @@ gpw_palette_button_clicked (GladePalette
 	/* class may be NULL if the selector was pressed */
 	if (class && g_type_is_a (class->type, GTK_TYPE_WINDOW))
 	{
-		glade_command_create (class, NULL, gpw->active_project);
+		glade_command_create (class, NULL, NULL, gpw->active_project);
 		gpw->add_class = NULL;
 	}
 	else
@@ -1317,9 +1356,9 @@ gpw_project_selection_changed_cb (GladeP
 		list = glade_project_selection_get (project);
 		num = g_list_length (list);
 		if (num == 1 && !GLADE_IS_PLACEHOLDER (list->data))
-			glade_editor_load_widget (gpw->editor,
-						  glade_widget_get_from_gobject
-						  (GTK_WIDGET (list->data)));
+			glade_editor_load_widget
+				(gpw->editor,
+				 glade_widget_get_from_gobject (list->data));
 		else
 			glade_editor_load_widget (gpw->editor, NULL);
 	}
@@ -1454,7 +1493,7 @@ glade_project_window_change_menu_label (
 	
 	bin = GTK_BIN (gtk_item_factory_get_item (gpw->item_factory, path));
 	label = GTK_LABEL (gtk_bin_get_child (bin));
-	
+
 	if (prefix == NULL)
 	{
 		gtk_label_set_text_with_mnemonic (label, suffix);
Index: src/glade-property-class.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-property-class.c,v
retrieving revision 1.63.2.1
diff -u -p -r1.63.2.1 glade-property-class.c
--- src/glade-property-class.c	18 Nov 2004 06:25:34 -0000	1.63.2.1
+++ src/glade-property-class.c	30 Nov 2004 18:40:17 -0000
@@ -409,7 +409,7 @@ glade_property_class_make_gvalue_from_st
 	GValue *value = g_new0 (GValue, 1);
 
 	g_value_init (value, property_class->pspec->value_type);
-
+	
 	if (G_IS_PARAM_SPEC_ENUM(property_class->pspec))
 	{
 		gint eval = glade_property_class_make_enum_from_string
@@ -591,6 +591,10 @@ glade_property_class_update_from_node (G
 	{
 		class->pspec = glade_utils_get_pspec_from_funcname (buff);
  		g_free (buff);
+
+		/* ... get the tooltip from the pspec ... */
+		if (class->pspec)
+			class->tooltip = g_strdup (g_param_spec_get_blurb (class->pspec));
 	}
 
 	/* ...and the tooltip */
@@ -623,7 +627,7 @@ glade_property_class_update_from_node (G
 	class->common   = glade_xml_get_property_boolean (node, GLADE_TAG_COMMON,  FALSE);
 	class->optional = glade_xml_get_property_boolean (node, GLADE_TAG_OPTIONAL, FALSE);
 	class->query    = glade_xml_get_property_boolean (node, GLADE_TAG_QUERY, FALSE);
-
+	
 	if (class->optional)
 		class->optional_default =
 			glade_xml_get_property_boolean (node, GLADE_TAG_OPTIONAL_DEFAULT, FALSE);
Index: src/glade-property.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-property.c,v
retrieving revision 1.54.2.2
diff -u -p -r1.54.2.2 glade-property.c
--- src/glade-property.c	18 Nov 2004 06:25:34 -0000	1.54.2.2
+++ src/glade-property.c	30 Nov 2004 18:40:17 -0000
@@ -216,8 +216,15 @@ glade_property_sync (GladeProperty *prop
 		 * updating the selection if the widget was selected.
 		 */
 		GList    *selection;
-		gboolean  reselect = FALSE;
-		if (property->widget->project)
+		gboolean  reselect  = FALSE;
+		gboolean  inproject =
+			property->widget->project ?
+			(glade_project_get_widget_by_name
+			 (property->widget->project,
+			  property->widget->name) ? TRUE : FALSE) : FALSE;
+
+		
+		if (inproject)
 		{
 			if ((selection =
 			     glade_project_selection_get (property->widget->project)) != NULL &&
@@ -235,7 +242,7 @@ glade_property_sync (GladeProperty *prop
 
 		glade_widget_rebuild (property->widget);
 
-		if (property->widget->project)
+		if (inproject)
 		{
 			glade_project_add_object (property->widget->project,
 						  glade_widget_get_object (property->widget));
Index: src/glade-utils.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-utils.c,v
retrieving revision 1.35.2.1
diff -u -p -r1.35.2.1 glade-utils.c
--- src/glade-utils.c	18 Nov 2004 06:25:34 -0000	1.35.2.1
+++ src/glade-utils.c	30 Nov 2004 18:40:17 -0000
@@ -27,6 +27,7 @@
 #include <gmodule.h>
 #include "glade.h"
 #include "glade-project.h"
+#include "glade-project-window.h"
 #include "glade-command.h"
 #include "glade-debug.h"
 #include "glade-placeholder.h"
@@ -34,6 +35,7 @@
 #include "glade-widget-class.h"
 #include "glade-property.h"
 #include "glade-property-class.h"
+#include "glade-clipboard.h"
 
 #define GLADE_UTIL_HAS_NODES "glade_util_has_nodes"
 #define GLADE_UTIL_SELECTION_NODE_SIZE 7
@@ -712,13 +714,19 @@ glade_util_draw_nodes_idle (GdkWindow *e
 
 	/* Step through all the selected widgets in the project. */
 	for (elem = expose_gwidget->project->selection; elem; elem = elem->next) {
+
 		GtkWidget *sel_widget;
 		GdkWindow *sel_win, *sel_toplevel;
 		gint sel_x, sel_y, x, y, w, h;
 
 		sel_widget = elem->data;
-		sel_win = glade_util_get_window_positioned_in (sel_widget);
 
+		if (!GTK_IS_WIDGET (sel_widget))
+			continue;
+		
+		if ((sel_win = glade_util_get_window_positioned_in (sel_widget)) == NULL)
+			continue;
+		
 		/* Calculate the offset of the selected widget's window
 		   within its toplevel. */
 		glade_util_calculate_window_offset (sel_win, &sel_x, &sel_y,
@@ -776,7 +784,7 @@ glade_util_queue_draw_nodes (GdkWindow *
 
 
 /**
- * glade_util_add_nodes:
+ * glade_util_add_selection:
  * @widget: a #GtkWidget
  *
  * TODO: write me
@@ -791,7 +799,7 @@ glade_util_add_selection (GObject *objec
 }
 
 /**
- * glade_util_remove_nodes:
+ * glade_util_remove_selection:
  * @widget: a #GtkWidget
  *
  * TODO: write me
@@ -810,7 +818,7 @@ glade_util_remove_selection (GObject *ob
 }
 
 /**
- * glade_util_has_nodes:
+ * glade_util_has_selectoin:
  * @widget: a #GtkWidget
  *
  * Returns: %TRUE if @widget has nodes, %FALSE otherwise
@@ -962,29 +970,45 @@ glade_util_uri_list_parse (const gchar *
 }
 
 /**
- * glade_util_object_set_property:
- * @object: a #GObject
- * @property: a #GladeProperty
+ * glade_util_gtkcontainer_relation:
+ * @widget: a GladeWidget
+ * @parent: a GladeWidget
  *
- * TODO: write me
+ *
+ * Returns whether this widget is parented by a GtkContainer
+ * and that it is parented through the GtkContainer interface.
  */
-void
-glade_util_object_set_property (GObject *object, GladeProperty *property)
+gboolean
+glade_util_gtkcontainer_relation (GladeWidget *parent, GladeWidget *widget)
 {
-	GValue void_string = {0,};
-	GValue *value = property->value;
-	
-	if (G_VALUE_HOLDS_STRING (property->value) &&
-	    g_value_get_string (property->value) == NULL)
-	{
-		g_value_init (&void_string, G_TYPE_STRING);
-		g_value_set_static_string (&void_string, "");
-		value = &void_string;
-	}
-
-	if (property->class->set_function)
-		property->class->set_function (object, value);
-	else
-		g_object_set_property (object, property->class->id, value);
+	GladeSupportedChild *support;
+	return (GTK_IS_CONTAINER (parent->object)                      &&
+		(support = glade_widget_class_get_child_support
+		 (parent->widget_class, widget->widget_class->type))   &&
+		(support->type == GTK_TYPE_WIDGET));
 }
 
+/**
+ * glade_util_widget_pastable:
+ * @widget: a GladeWidget
+ *
+ * Returns whether it is appropriate to paste the clipbooard widget to
+ * this widget.
+ */
+gboolean
+glade_util_widget_pastable (GladeWidget *parent)
+{
+	GladeProjectWindow *gpw;
+	GladeClipboard     *clipboard;
+	GladeWidget        *clip_widget;
+	
+	gpw         = glade_project_window_get ();
+	clipboard   = gpw->clipboard;
+	clip_widget = clipboard->curr;
+
+	if (clip_widget)
+		return (glade_widget_class_get_child_support
+			(parent->widget_class,
+			 clip_widget->widget_class->type) != NULL) ? TRUE : FALSE;
+	return FALSE;
+}
Index: src/glade-utils.h
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-utils.h,v
retrieving revision 1.25.2.1
diff -u -p -r1.25.2.1 glade-utils.h
--- src/glade-utils.h	18 Nov 2004 06:25:34 -0000	1.25.2.1
+++ src/glade-utils.h	30 Nov 2004 18:40:17 -0000
@@ -26,18 +26,20 @@ void		glade_util_flash_message	(GtkWidge
 
 /* This is a GCompareFunc for comparing the labels of 2 stock items, ignoring
    any '_' characters. It isn't particularly efficient. */
-gint		glade_util_compare_stock_labels (gconstpointer a, gconstpointer b);
+gint            glade_util_compare_stock_labels (gconstpointer a, gconstpointer b);
 
-void		glade_util_hide_window		(GtkWindow *window);
-gchar		*glade_util_gtk_combo_func	(gpointer data);
+void            glade_util_hide_window		(GtkWindow *window);
+gchar          *glade_util_gtk_combo_func	(gpointer data);
 gpointer	glade_util_gtk_combo_find	(GtkCombo *combo);
 
-GtkWidget       *glade_util_file_dialog_new (const gchar *title, GtkWindow *parent, GladeUtilFileDialogType action);
-gchar           *glade_util_file_dialog_get_filename (GtkWidget *file_dialog);
-void             glade_util_file_dialog_set_filename (GtkWidget *file_dialog, gchar *filename);
+GtkWidget      *glade_util_file_dialog_new (const gchar *title,
+					    GtkWindow *parent,
+					    GladeUtilFileDialogType action);
+gchar          *glade_util_file_dialog_get_filename (GtkWidget *file_dialog);
+void            glade_util_file_dialog_set_filename (GtkWidget *file_dialog, gchar *filename);
 
-void		glade_util_replace (char *str, char a, char b);
-char		*glade_util_duplicate_underscores (const char *name);
+void            glade_util_replace (char *str, char a, char b);
+gchar          *glade_util_duplicate_underscores (const char *name);
 
 void		glade_util_delete_selection (GladeProject *project);
 
@@ -46,12 +48,13 @@ void		glade_util_remove_selection (GObje
 gboolean	glade_util_has_selection    (GObject   *object);
 void		glade_util_queue_draw_nodes (GdkWindow *window);
 
-GladeWidget	*glade_util_get_parent (GtkWidget *w);
-GList           *glade_util_container_get_all_children (GtkContainer *container);
-void		glade_util_object_set_property (GObject *object, GladeProperty *property);
+GladeWidget    *glade_util_get_parent (GtkWidget *w);
+GList          *glade_util_container_get_all_children (GtkContainer *container);
 
-GList           *glade_util_uri_list_parse (const gchar* uri_list);
+GList          *glade_util_uri_list_parse (const gchar* uri_list);
 
+gboolean        glade_util_gtkcontainer_relation (GladeWidget *parent, GladeWidget *widget);
+gboolean        glade_util_widget_pastable (GladeWidget *parent);
 
 G_END_DECLS
 
Index: src/glade-widget-class.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-widget-class.c,v
retrieving revision 1.65.2.2
diff -u -p -r1.65.2.2 glade-widget-class.c
--- src/glade-widget-class.c	18 Nov 2004 06:25:34 -0000	1.65.2.2
+++ src/glade-widget-class.c	30 Nov 2004 18:40:17 -0000
@@ -244,7 +244,7 @@ glade_widget_class_list_signals (GladeWi
 	g_return_val_if_fail (class->type != 0, NULL);
 
 	type = class->type;
-	while (g_type_is_a (type, GTK_TYPE_OBJECT))
+	while (g_type_is_a (type, G_TYPE_OBJECT))
 	{
 		if (G_TYPE_IS_INSTANTIATABLE (type) || G_TYPE_IS_INTERFACE (type))
 		{
@@ -286,10 +286,9 @@ glade_widget_class_create_icon (GladeWid
 static void
 glade_widget_class_update_properties_from_node (GladeXmlNode *node,
 						GladeWidgetClass *widget_class,
-						GList **pproperties)
+						GList **properties)
 {
 	GladeXmlNode *child;
-	GList *properties = *pproperties;
 
 	for (child = glade_xml_node_get_children (node);
 	     child; child = glade_xml_node_next (child))
@@ -308,12 +307,14 @@ glade_widget_class_update_properties_fro
 			continue;
 
 		/* find the property in our list, if not found append a new property */
-		for (list = properties; list; list = list->next)
+		for (list = *properties; list && list->data; list = list->next)
 		{
-			gchar *tmp = GLADE_PROPERTY_CLASS (list->data)->id;
-			if (!g_ascii_strcasecmp (id, tmp))
+			property_class = GLADE_PROPERTY_CLASS (list->data);
+			if (property_class->id != NULL &&
+			    g_ascii_strcasecmp (id, property_class->id) == 0)
 				break;
 		}
+
 		if (list)
 		{
 			property_class = GLADE_PROPERTY_CLASS (list->data);
@@ -322,8 +323,8 @@ glade_widget_class_update_properties_fro
 		{
 			property_class = glade_property_class_new ();
 			property_class->id = g_strdup (id);
-			properties = g_list_append (properties, property_class);
-			list = g_list_last (properties);
+			*properties = g_list_append (*properties, property_class);
+			list = g_list_last (*properties);
 		}
 
 		updated = glade_property_class_update_from_node
@@ -338,7 +339,7 @@ glade_widget_class_update_properties_fro
 
 		/* the property has Disabled=TRUE ... */
 		if (!property_class)
-			properties = g_list_delete_link (properties, list);
+			*properties = g_list_delete_link (*properties, list);
 
 		g_free (id);
 	}
@@ -407,7 +408,7 @@ glade_widget_class_update_children_from_
 		}
 		else
 		{
-			child                  = g_new (GladeSupportedChild, 1);
+			child                  = g_new0 (GladeSupportedChild, 1);
 			child->type            = type;
 			widget_class->children = g_list_append (widget_class->children, child);
 		}
@@ -537,6 +538,61 @@ glade_widget_class_get_by_name (const ch
 		return NULL;
 }
 
+typedef struct
+{
+	GType              type;
+	GladeWidgetClass  *class;
+} GladeClassSearchPair;
+
+static void
+search_class_by_type (gchar                *name,
+		      GladeWidgetClass     *class,
+		      GladeClassSearchPair *pair)
+{
+	if (class->type == pair->type)
+		pair->class = class;
+}
+
+GladeWidgetClass *
+glade_widget_class_get_by_type (GType type)
+{
+	GladeClassSearchPair pair = { type, NULL };
+	
+	if (widget_classes != NULL)
+	{
+		g_hash_table_foreach (widget_classes, (GHFunc)search_class_by_type, &pair);
+	}
+	return pair.class;
+}
+
+typedef struct
+{
+	GType  type;
+	GList *list;
+} GladeClassAccumPair;
+
+static void
+accum_class_by_type (gchar                *name,
+		     GladeWidgetClass     *class,
+		     GladeClassAccumPair  *pair)
+{
+	if (g_type_is_a (class->type, pair->type))
+		pair->list = g_list_prepend (pair->list, class);
+}
+
+GList *
+glade_widget_class_get_derived_types  (GType type)
+{
+	GladeClassAccumPair pair = { type, NULL };
+
+		if (widget_classes != NULL)
+	{
+		g_hash_table_foreach (widget_classes, (GHFunc)accum_class_by_type, &pair);
+	}
+	return pair.list;
+}
+
+
 /**
  * glade_widget_class_merge_properties:
  * @widget_properties: Pointer to the list of properties in the widget.
@@ -832,7 +888,7 @@ glade_widget_class_new (const char *name
 	widget_class->generic_name = generic_name ? g_strdup (generic_name) : NULL;
 	widget_class->palette_name = palette_name ? g_strdup (palette_name) : NULL;
 	widget_class->name = g_strdup (name);
-	widget_class->in_palette = generic_name ? TRUE : FALSE;
+	widget_class->in_palette = palette_name ? TRUE : FALSE;
 
 	widget_class->type = glade_util_get_type_from_name (widget_class->name);
 	if (widget_class->type == 0)
Index: src/glade-widget-class.h
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-widget-class.h,v
retrieving revision 1.35.2.1
diff -u -p -r1.35.2.1 glade-widget-class.h
--- src/glade-widget-class.h	18 Nov 2004 06:25:34 -0000	1.35.2.1
+++ src/glade-widget-class.h	30 Nov 2004 18:40:17 -0000
@@ -148,6 +148,8 @@ GladeWidgetClass    *glade_widget_class_
 GladeWidgetClass    *glade_widget_class_new_from_node      (GladeXmlNode     *node);
 void                 glade_widget_class_free               (GladeWidgetClass *widget_class);
 GladeWidgetClass    *glade_widget_class_get_by_name        (const char       *name);
+GladeWidgetClass    *glade_widget_class_get_by_type        (GType             type);
+GList               *glade_widget_class_get_derived_types  (GType             type);
 GType 	             glade_widget_class_get_type           (GladeWidgetClass *class);
 void                 glade_widget_class_dump_param_specs   (GladeWidgetClass *class);
 GladePropertyClass  *glade_widget_class_get_property_class (GladeWidgetClass *class,
Index: src/glade-widget.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-widget.c,v
retrieving revision 1.122.2.2
diff -u -p -r1.122.2.2 glade-widget.c
--- src/glade-widget.c	18 Nov 2004 06:25:34 -0000	1.122.2.2
+++ src/glade-widget.c	30 Nov 2004 18:40:17 -0000
@@ -81,7 +81,8 @@ enum
 	PROP_OBJECT,
 	PROP_CLASS,
 	PROP_PROJECT,
-	PROP_PROPERTIES
+	PROP_PROPERTIES,
+	PROP_PARENT
 };
 
 static guint glade_widget_signals[LAST_SIGNAL] = {0};
@@ -184,8 +185,12 @@ glade_widget_class_init (GladeWidgetKlas
 				       G_PARAM_READWRITE |
 				       G_PARAM_CONSTRUCT_ONLY));
 
-
-
+	g_object_class_install_property
+		(object_class, 	PROP_PARENT,
+		 g_param_spec_pointer ("parent", _("Parent"),
+				       _("A pointer to the parenting GladeWidget"),
+				       G_PARAM_READWRITE |
+				       G_PARAM_CONSTRUCT_ONLY));
 	
 	glade_widget_signals[ADD_SIGNAL_HANDLER] =
 		g_signal_new ("add_signal_handler",
@@ -316,32 +321,24 @@ glade_widget_copy_packing_props (GladeWi
 }
 
 static void
-glade_widget_copy_custom_props (GladeWidget *widget,
-				GladeWidget *template)
+glade_widget_sync_custom_props (GladeWidget *widget)
 {
 	GList *l;
 	for (l = widget->properties; l && l->data; l = l->next)
 	{
-		GladeProperty *dup_prop  = GLADE_PROPERTY(l->data);
-		GladeProperty *orig_prop;
-		if (dup_prop->class->set_function)
-		{
-			orig_prop = glade_widget_get_property (template, dup_prop->class->id);
-			
-			glade_property_set (dup_prop, orig_prop->value);
-		}
+		GladeProperty *prop  = GLADE_PROPERTY(l->data);
+		if (prop->class->set_function)
+			glade_property_sync (prop);
 	}
 }
 
 static void
-glade_widget_sync_custom_props (GladeWidget *widget)
+glade_widget_sync_packing_props (GladeWidget *widget)
 {
 	GList *l;
-	for (l = widget->properties; l && l->data; l = l->next)
-	{
+	for (l = widget->packing_properties; l && l->data; l = l->next) {
 		GladeProperty *prop  = GLADE_PROPERTY(l->data);
-		if (prop->class->set_function)
-			glade_property_sync (prop);
+		glade_property_sync (prop);
 	}
 }
 
@@ -493,37 +490,30 @@ glade_widget_build_object (GladeWidgetCl
 }
 
 static GladeWidget *
-glade_widget_internal_new (GladeWidgetClass *klass, GladeProject *project, GladeWidget *template)
+glade_widget_internal_new (GladeWidget      *parent,
+			   GladeWidgetClass *klass,
+			   GladeProject     *project,
+			   GladeWidget      *template)
 {
 	GObject *object;
 	GObject *glade_widget;
-	GList   *properties;
+	GList   *properties = NULL;
 	gchar   *widget_name;
 	
 	object      = glade_widget_build_object(klass, template);
 	widget_name = glade_project_new_widget_name (project, klass->generic_name);
 
 	if (template)
-	{
 		properties = glade_widget_dup_properties (template->properties);
-		glade_widget = g_object_new (GLADE_TYPE_WIDGET,
-					     "properties", properties,
-					     "class", klass,
-					     "project", project,
-					     "name", widget_name,
-					     "object", object,
-					     NULL);
-	}
-	else
-	{
-		glade_widget = g_object_new (GLADE_TYPE_WIDGET,
-					     "class", klass,
-					     "project", project,
-					     "name", widget_name,
-					     "object", object,
-					     NULL);
-	}
 
+	glade_widget = g_object_new (GLADE_TYPE_WIDGET,
+				     "parent", parent,
+				     "properties", properties,
+				     "class", klass,
+				     "project", project,
+				     "name", widget_name,
+				     "object", object,
+				     NULL);
 	g_free (widget_name);
 
 	return (GladeWidget *) glade_widget;
@@ -539,11 +529,11 @@ glade_widget_internal_new (GladeWidgetCl
  * Returns:
  */
 GladeWidget *
-glade_widget_new (GladeWidgetClass *klass, GladeProject *project)
+glade_widget_new (GladeWidget *parent, GladeWidgetClass *klass, GladeProject *project)
 {
 	GladeWidget *widget;
 
-	if ((widget = glade_widget_internal_new (klass, project, NULL)) != NULL)
+	if ((widget = glade_widget_internal_new (parent, klass, project, NULL)) != NULL)
 	{
 		glade_widget_class_container_fill_empty (klass, widget->object);
 
@@ -570,13 +560,14 @@ glade_widget_new (GladeWidgetClass *klas
  * Returns:
  */
 static GladeWidget *
-glade_widget_dup_internal (GladeWidget *template)
+glade_widget_dup_internal (GladeWidget *parent, GladeWidget *template)
 {
 	GladeWidget *gwidget;
 	GList       *list, *children;
 	
 	g_return_val_if_fail (template != NULL && GLADE_IS_WIDGET(template), NULL);
-	gwidget = glade_widget_internal_new (template->widget_class,
+	gwidget = glade_widget_internal_new (parent,
+					     template->widget_class,
 					     template->project,
 					     template);
 
@@ -594,9 +585,7 @@ glade_widget_dup_internal (GladeWidget *
 
 			if (child_gwidget->internal == NULL)
 			{
-				child_dup = glade_widget_dup_internal (child_gwidget);
-
-				child_dup->parent = gwidget;
+				child_dup = glade_widget_dup_internal (gwidget, child_gwidget);
 
 				glade_widget_class_container_add (gwidget->widget_class,
 								  gwidget->object,
@@ -630,8 +619,8 @@ glade_widget_dup_internal (GladeWidget *
 		}
 		g_list_free (children);
 	}
-	
-	glade_widget_copy_custom_props (gwidget, template);
+
+	glade_widget_sync_custom_props (gwidget);
 
 	if (GTK_IS_WIDGET (gwidget->object) && !GTK_WIDGET_TOPLEVEL(gwidget->object))
 		gtk_widget_show_all (GTK_WIDGET (gwidget->object));
@@ -642,7 +631,7 @@ glade_widget_dup_internal (GladeWidget *
 GladeWidget *
 glade_widget_dup (GladeWidget *template)
 {
-	GladeWidget *widget = glade_widget_dup_internal (template);
+	GladeWidget *widget = glade_widget_dup_internal (NULL, template);
 	if (widget)
 		glade_widget_fill_all_empty (widget);
 	return widget;
@@ -677,7 +666,11 @@ glade_widget_rebuild (GladeWidget *glade
 	/* Custom properties aren't transfered in build_object, since build_object
 	 * is only concerned with object creation.
 	 */
-	glade_widget_sync_custom_props (glade_widget);
+	glade_widget_sync_custom_props  (glade_widget);
+
+	/* Sync packing.
+	 */
+	glade_widget_sync_packing_props (glade_widget);
 	
 	if (g_type_is_a (klass->type, GTK_TYPE_WIDGET))
 	{
@@ -712,16 +705,13 @@ glade_widget_new_for_internal_child (Gla
 	GladeProject *project = glade_widget_get_project (parent);
 	gchar *widget_name    = glade_project_new_widget_name (project, klass->generic_name);
 	GladeWidget *widget   = g_object_new (GLADE_TYPE_WIDGET,
+					      "parent", parent,
 					      "class", klass,
 					      "project", project,
 					      "name", widget_name,
 					      "internal", internal_name,
 					      "object", internal_object, NULL);
 	g_free (widget_name);
-
-	widget->parent = parent;
-	
-	glade_widget_set_packing_properties (widget, parent);
 	return widget;
 }
 
@@ -857,6 +847,9 @@ glade_widget_set_real_property (GObject 
 	case PROP_PROPERTIES:
 		glade_widget_set_properties (widget, (GList *)g_value_get_pointer (value));
 		break;
+	case PROP_PARENT:
+		glade_widget_set_parent (widget, GLADE_WIDGET (g_value_get_pointer (value)));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -892,6 +885,10 @@ glade_widget_get_real_property (GObject 
 		break;
 	case PROP_PROPERTIES:
 		g_value_set_pointer (value, widget->properties);
+		break;
+	case PROP_PARENT:
+		g_value_set_pointer (value, widget->parent);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -1005,8 +1002,8 @@ glade_widget_set_class (GladeWidget *wid
 			property_class = GLADE_PROPERTY_CLASS(list->data);
 			property = glade_property_new (property_class, widget, NULL);
 			if (!property) {
-				g_print ("Failed to create [%s] property.\n",
-					 property_class->id);
+				g_warning ("Failed to create [%s] property",
+					   property_class->id);
 				continue;
 			}
 
@@ -1106,7 +1103,7 @@ glade_widget_popup_menu (GtkWidget *widg
 	g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
 
 	glade_widget = glade_widget_get_from_gobject (widget);
-	glade_popup_widget_pop (glade_widget, NULL);
+	glade_popup_widget_pop (glade_widget, NULL, TRUE);
 
 	return TRUE;
 }
@@ -1212,7 +1209,9 @@ glade_widget_button_press (GtkWidget *wi
 	{
 		/* if it's already selected don't stop default handlers, e.g. toggle button */
 		if (glade_util_has_selection (G_OBJECT(widget)))
+		{
 			return FALSE;
+		}
 
 		glade_project_selection_set (glade_widget->project, G_OBJECT(widget), TRUE);
 
@@ -1220,7 +1219,7 @@ glade_widget_button_press (GtkWidget *wi
 	}
 	else if (event->button == 3)
 	{
-		glade_popup_widget_pop (glade_widget, event);
+		glade_popup_widget_pop (glade_widget, event, TRUE);
 		return TRUE;
 	}
 
@@ -1326,8 +1325,8 @@ glade_widget_transport_children (GladeWi
 	{
 		for (list = children; list && list->data; list = list->next)
 		{
-			GObject *child = G_OBJECT(list->data);
-			
+			GObject     *child  = G_OBJECT(list->data);
+			GladeWidget *gchild = glade_widget_get_from_gobject (child);
 			/* If this widget is a container, all children get a temporary
 			 * reference and are moved from the old container, to the new
 			 * container and thier child properties are applied.
@@ -1337,8 +1336,7 @@ glade_widget_transport_children (GladeWi
 							     from_container, child);
 			glade_widget_class_container_add    (gwidget->widget_class,
 							     to_container, child);
-			glade_widget_set_packing_properties
-				(glade_widget_get_from_gobject (child), gwidget);
+			glade_widget_sync_packing_props     (gchild);
 			g_object_unref(child);
 		}
 		g_list_free (children);
@@ -1346,35 +1344,6 @@ glade_widget_transport_children (GladeWi
 }
 
 /**
- * glade_widget_update_parent:
- * @widget: A #GladeWidget
- * @old_object: A #GObject
- * @new_object: A #GObject
- *
- * Finds @widget's parent #GladeWidget and calls the replace_child func
- * and takes care of packing
- *
- * Returns: whether this widget had a parent.
- */
-static gboolean
-glade_widget_update_parent(GladeWidget *parent, GObject *old_object, GObject *new_object)
-{
-	if (old_object)
-	{
-		glade_widget_class_container_replace_child (parent->widget_class,
-							    parent->object,
-							    old_object, new_object);
-
-		if (GLADE_IS_PLACEHOLDER(new_object) == FALSE)
-			glade_widget_set_packing_properties
-				(glade_widget_get_from_gobject (new_object), parent);
-
-		return TRUE;
-	}
-	return FALSE;
-}
-
-/**
  * glade_widget_set_object:
  * @gwidget:
  * @new_widget:
@@ -1385,7 +1354,6 @@ void
 glade_widget_set_object (GladeWidget *gwidget, GObject *new_object)
 {
 	GladeWidgetClass *klass;
-	GladeWidget      *parent;
 	GObject          *old_object;
 	
 	g_return_if_fail (GLADE_IS_WIDGET (gwidget));
@@ -1428,13 +1396,21 @@ glade_widget_set_object (GladeWidget *gw
 			glade_widget_connect_signal_handlers (GTK_WIDGET(new_object), NULL);
 		}
 		
-		if ((parent = glade_widget_get_parent (gwidget)) != NULL)
-			glade_widget_update_parent(parent, old_object, new_object);
-
+		/* Take care of hierarchy here
+		 */
+		if (old_object)
+		{
+			if (gwidget->parent)
+			{
+				glade_widget_class_container_replace_child
+					(gwidget->parent->widget_class,
+					 gwidget->parent->object,
+					 old_object, new_object);
+			}
+			glade_widget_transport_children (gwidget, old_object, new_object);
+		}
 	}
 
-	if (old_object)
-		glade_widget_transport_children (gwidget, old_object, new_object);
 
 	/* Remove internal reference to old widget */
 	if (old_object) {
@@ -1555,6 +1531,23 @@ glade_widget_get_parent (GladeWidget *wi
 	return widget->parent;
 }
 
+void
+glade_widget_set_parent (GladeWidget *widget,
+			 GladeWidget *parent)
+{
+	GladeWidget *old_parent = widget->parent;
+	widget->parent = parent;
+
+	if (widget->object &&
+	    (old_parent == NULL || widget->packing_properties == NULL ||
+	     old_parent->widget_class->type != parent->widget_class->type))
+		glade_widget_set_packing_properties (widget, parent);
+	else
+		glade_widget_sync_packing_props (widget);
+	
+	g_object_notify (G_OBJECT (widget), "parent");
+}
+
 /**
  * Returns a list of GladeProperties from a list for the correct
  * child type for this widget of this container.
@@ -1643,16 +1636,26 @@ glade_widget_replace (GladeWidget *paren
 	gnew_widget = glade_widget_get_from_gobject (new_object);
 	gold_widget = glade_widget_get_from_gobject (old_object);
 
-	if (gnew_widget) {
+	if (gnew_widget)
+	{
 		real_new_object = glade_widget_get_object (gnew_widget);
 		gnew_widget->parent = parent;
 	}
-	if (gold_widget) {
+
+	if (gold_widget)
+	{
 		real_old_object = glade_widget_get_object (gold_widget);
 		gold_widget->parent = NULL;
 	}
 
-	glade_widget_update_parent(parent, real_old_object, real_new_object);
+	glade_widget_class_container_replace_child (parent->widget_class,
+						    parent->object,
+						    real_old_object,
+						    real_new_object);
+
+	if (gnew_widget)
+		glade_widget_set_packing_properties (gnew_widget, parent);
+
 }
 
 /* XML Serialization */
@@ -1824,7 +1827,7 @@ glade_widget_value_from_prop_info (Glade
 
 	id = g_strdup (info->name);
 	glade_util_replace (id, '_', '-');
-	
+
 	if (info->name && info->value &&
 	    (pclass = glade_widget_class_get_property_class (class, id)) != NULL)
 		gvalue = glade_property_class_make_gvalue_from_string (pclass,
@@ -1983,10 +1986,11 @@ glade_widget_properties_from_widget_info
 		/* If there is a value in the XML, initialize property with it,
 		 * otherwise initialize property to default.
 		 */
-		value      = glade_widget_get_property_from_widget_info
+		value             = glade_widget_get_property_from_widget_info
 			(class, info, pclass->id);
-		property   = glade_property_new (pclass, NULL, value);
-		properties = g_list_prepend (properties, property);
+		property          = glade_property_new (pclass, NULL, value);
+		property->enabled = value ? TRUE : property->enabled;
+		properties        = g_list_prepend (properties, property);
 	}
 	return g_list_reverse (properties);
 }
@@ -2094,6 +2098,7 @@ glade_widget_new_from_widget_info (Glade
 	
 	widget_name = glade_project_new_widget_name (project, klass->generic_name);
 	widget = g_object_new (GLADE_TYPE_WIDGET,
+			       "parent", parent,
 			       "properties", properties,
 			       "class", klass,
 			       "project", project,
Index: src/glade-widget.h
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-widget.h,v
retrieving revision 1.37.2.2
diff -u -p -r1.37.2.2 glade-widget.h
--- src/glade-widget.h	18 Nov 2004 06:25:34 -0000	1.37.2.2
+++ src/glade-widget.h	30 Nov 2004 18:40:17 -0000
@@ -81,7 +81,8 @@ struct _GladeWidgetKlass
 };
 
 GType			glade_widget_get_type		    (void);
-GladeWidget *		glade_widget_new		    (GladeWidgetClass *klass,
+GladeWidget *		glade_widget_new		    (GladeWidget      *widget,
+							     GladeWidgetClass *klass,
 							     GladeProject     *project);
 GladeWidget *		glade_widget_new_for_internal_child (GladeWidgetClass *klass,
 							     GladeWidget      *parent,
@@ -134,6 +135,8 @@ GladeWidget            *glade_widget_rea
     g_object_get_data (G_OBJECT (w), "GladeWidgetDataTag")
 
 GladeWidget            *glade_widget_get_parent             (GladeWidget      *widget);
+void                    glade_widget_set_parent             (GladeWidget      *widget,
+							     GladeWidget      *parent);
 
 
 G_END_DECLS
