glade3 r2006 - in trunk: . gladeui plugins/gtk+



Author: tvb
Date: Tue Oct 28 05:07:30 2008
New Revision: 2006
URL: http://svn.gnome.org/viewvc/glade3?rev=2006&view=rev

Log:

	* plugins/gtk+/gtk+.xml.in, plugins/gtk+/glade-gtk.c: 
	Reimplemented GtkMenuItem and subclasses from top to bottom

	* plugins/gtk+/glade-image-item-editor.[ch], plugins/gtk+/Makefile.am:
	New GtkImageMenuItem editor (that embeds the child image editor when needed)

	* gladeui/glade-command.[ch]: Added glade_command_[un]protect_widget()

	* gladeui/glade-widget.[ch]: Added glade_widget_[un]protect()
	protected widgets come with a message and cannot be manually deleted
	from the project.

	* plugins/gtk+/glade-image-editor.c, plugins/gtk+/glade-button-editor.c,
	plugins/gtk+/glade-tool-button-editor.c, gladeui/glade-editor-table.c:
	Fixed to:
	- not reffer to child editables in finalize
	- always removed external signals and weak references from finalize

	* gladeui/glade-base-editor.c: Fixed to allow properties expand/fill
	in both label and entry.



Added:
   trunk/plugins/gtk+/glade-image-item-editor.c
   trunk/plugins/gtk+/glade-image-item-editor.h
Modified:
   trunk/ChangeLog
   trunk/gladeui/glade-base-editor.c
   trunk/gladeui/glade-command.c
   trunk/gladeui/glade-command.h
   trunk/gladeui/glade-editor-property.c
   trunk/gladeui/glade-editor-table.c
   trunk/gladeui/glade-widget-adaptor.c
   trunk/gladeui/glade-widget.c
   trunk/gladeui/glade-widget.h
   trunk/plugins/gtk+/Makefile.am
   trunk/plugins/gtk+/glade-button-editor.c
   trunk/plugins/gtk+/glade-gtk.c
   trunk/plugins/gtk+/glade-image-editor.c
   trunk/plugins/gtk+/glade-tool-button-editor.c
   trunk/plugins/gtk+/glade-tool-button-editor.h
   trunk/plugins/gtk+/gtk+.xml.in

Modified: trunk/gladeui/glade-base-editor.c
==============================================================================
--- trunk/gladeui/glade-base-editor.c	(original)
+++ trunk/gladeui/glade-base-editor.c	Tue Oct 28 05:07:30 2008
@@ -319,14 +319,14 @@
 	if (child1)
 	{
 		gtk_table_attach (table, child1, 0, 1, row, row + 1,
-				  GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 0);
+				  GTK_EXPAND | GTK_FILL, GTK_FILL, 2, 0);
 		gtk_widget_show (child1);
 	}
 	
 	if (child2)
 	{
 		gtk_table_attach (table, child2, 1, 2, row, row + 1,
-				  GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 0);
+				  GTK_EXPAND | GTK_FILL, GTK_FILL, 2, 0);
 		gtk_widget_show (child2);
 	}
 	
@@ -378,7 +378,8 @@
 glade_base_editor_update_properties_idle (gpointer data)
 {
 	GladeBaseEditor *editor = (GladeBaseEditor *)data;
-	glade_base_editor_treeview_cursor_changed (NULL, editor);
+	glade_base_editor_treeview_cursor_changed
+		(GTK_TREE_VIEW (editor->priv->treeview), editor);
 	editor->priv->properties_idle = 0;
 	return FALSE;
 }
@@ -1709,16 +1710,13 @@
 glade_base_editor_add_editable (GladeBaseEditor *editor,
 				GladeWidget     *gchild)
 {
-	GladeEditorProperty *eprop;
-	GladeEditable       *editable;
-	va_list args;
-	gchar *property;
+	GladeEditable  *editable;
 	gint row;
 	
 	g_return_if_fail (GLADE_IS_BASE_EDITOR (editor));
 	g_return_if_fail (GLADE_IS_WIDGET (gchild));
 
-	editable = (GtkWidget *)glade_widget_adaptor_create_editable (gchild->adaptor, GLADE_PAGE_GENERAL);
+	editable = glade_widget_adaptor_create_editable (gchild->adaptor, GLADE_PAGE_GENERAL);
 	glade_editable_set_show_name (editable, FALSE);
 	glade_editable_load (editable, gchild);
 	gtk_widget_show (GTK_WIDGET (editable));
@@ -1758,8 +1756,9 @@
 	
 	gtk_label_set_markup (GTK_LABEL (label), markup);
 	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
+	gtk_misc_set_padding (GTK_MISC (label), 0, 6);
 	gtk_table_attach (GTK_TABLE (editor->priv->table), label, 0, 2, row, row + 1,
-			  GTK_FILL, GTK_EXPAND | GTK_FILL, 2, 0);
+			  GTK_FILL, GTK_FILL, 2, 0);
 	gtk_widget_show (label);
 	editor->priv->row++;
 	

Modified: trunk/gladeui/glade-command.c
==============================================================================
--- trunk/gladeui/glade-command.c	(original)
+++ trunk/gladeui/glade-command.c	Tue Oct 28 05:07:30 2008
@@ -1106,6 +1106,12 @@
 					       _("You cannot remove a widget internal to a composite widget."));
 			return;
 		}
+		if (widget->protection)
+		{
+			glade_util_ui_message (glade_app_get_window(),	
+					       GLADE_UI_WARN, NULL, widget->protection);
+			return;
+		}
 	}
 
 	me->project = glade_widget_get_project (widget);
@@ -1618,6 +1624,7 @@
 /**
  * glade_command_create:
  * @adaptor:		A #GladeWidgetAdaptor
+ * @parent:             the parent #GladeWidget to add the new widget to.
  * @placeholder:	the placeholder which will be substituted by the widget
  * @project:            the project his widget belongs to.
  *
@@ -2529,3 +2536,154 @@
 
 
 
+/******************************************************************************
+ * 
+ * This command sets protection warnings on widgets
+ * 
+ *****************************************************************************/
+
+typedef struct {
+	GladeCommand   parent;
+	GladeWidget   *widget;
+	gchar         *warning;
+	gboolean       protecting;
+} GladeCommandProtect;
+
+
+GLADE_MAKE_COMMAND (GladeCommandProtect, glade_command_protect);
+#define GLADE_COMMAND_PROTECT_TYPE			(glade_command_protect_get_type ())
+#define GLADE_COMMAND_PROTECT(o)	  		(G_TYPE_CHECK_INSTANCE_CAST ((o), GLADE_COMMAND_PROTECT_TYPE, GladeCommandProtect))
+#define GLADE_COMMAND_PROTECT_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST ((k), GLADE_COMMAND_PROTECT_TYPE, GladeCommandProtectClass))
+#define GLADE_IS_COMMAND_PROTECT(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GLADE_COMMAND_PROTECT_TYPE))
+#define GLADE_IS_COMMAND_PROTECT_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GLADE_COMMAND_PROTECT_TYPE))
+
+static gboolean
+glade_command_protect_execute(GladeCommand *cmd)
+{
+	GladeCommandProtect *me = (GladeCommandProtect *)cmd;
+
+	/* set the new policy */
+	if (me->protecting)
+		glade_widget_protect (me->widget, me->warning);
+	else
+		glade_widget_unprotect (me->widget);
+
+	/* swap the current values with the old values to prepare for undo */
+	me->protecting = !me->protecting;
+	
+	return TRUE;
+}
+
+static gboolean
+glade_command_protect_undo(GladeCommand *cmd)
+{
+	return glade_command_protect_execute(cmd);
+}
+
+static void
+glade_command_protect_finalize(GObject *obj)
+{
+ 	GladeCommandProtect *me = (GladeCommandProtect *)obj;
+	
+	g_object_unref (me->widget);
+	
+	glade_command_finalize(obj);
+}
+
+static gboolean
+glade_command_protect_unifies (GladeCommand *this_cmd, GladeCommand *other_cmd)
+{
+/* 	GladeCommandProtect *cmd1; */
+/* 	GladeCommandProtect *cmd2; */
+	/* No point here, this command undoubtedly always runs in groups */
+	return FALSE;
+}
+
+static void
+glade_command_protect_collapse (GladeCommand *this_cmd, GladeCommand *other_cmd)
+{
+	/* this command is the one that will be used for an undo of the sequence of like commands */
+	//GladeCommandProtect *this = GLADE_COMMAND_PROTECT (this_cmd);
+	
+	/* the other command contains the values that will be used for a redo */
+	//GladeCommandProtect *other = GLADE_COMMAND_PROTECT (other_cmd);
+
+	g_return_if_fail (GLADE_IS_COMMAND_PROTECT (this_cmd) && GLADE_IS_COMMAND_PROTECT (other_cmd));
+
+	/* no unify/collapse */
+}
+
+/**
+ * glade_command_protect_widget:
+ * @widget: A #GladeWidget
+ * @warning: the warning to print when a user tries to delete this widget
+ *
+ * Sets the protection status and @warning on @widget
+ */
+void
+glade_command_protect_widget (GladeWidget  *widget,
+			      const gchar  *warning)
+
+{
+	GladeCommandProtect *me;
+	
+	g_return_if_fail (GLADE_IS_WIDGET (widget));
+	g_return_if_fail (widget->protection == NULL);
+	g_return_if_fail (warning && warning[0]);
+
+	/* load up the command */
+	me             = g_object_new(GLADE_COMMAND_PROTECT_TYPE, NULL);
+	me->widget     = g_object_ref (widget);
+	me->protecting = TRUE;
+	me->warning    = g_strdup (warning);
+
+	GLADE_COMMAND(me)->description = g_strdup_printf(_("Protecting %s"), widget->name);
+	
+	glade_command_check_group(GLADE_COMMAND(me));
+		
+	/* execute the command and push it on the stack if successful 
+	 * this sets the actual policy
+	 */
+	if (glade_command_protect_execute(GLADE_COMMAND(me)))
+		glade_project_push_undo(glade_app_get_project(), GLADE_COMMAND(me));
+	else
+		g_object_unref(G_OBJECT(me));
+
+}
+
+
+/**
+ * glade_command_unprotect_widget:
+ * @widget: A #GladeWidget
+ *
+ * Unsets the protection status of @widget
+ */
+void
+glade_command_unprotect_widget (GladeWidget  *widget)
+
+{
+	GladeCommandProtect *me;
+	
+	g_return_if_fail (GLADE_IS_WIDGET (widget));
+	g_return_if_fail (widget->protection && widget->protection[0]);
+
+	/* load up the command */
+	me             = g_object_new(GLADE_COMMAND_PROTECT_TYPE, NULL);
+	me->widget     = g_object_ref (widget);
+	me->protecting = FALSE;
+	me->warning    = g_strdup (widget->protection);
+
+	GLADE_COMMAND(me)->description = g_strdup_printf(_("Unprotecting %s"), widget->name);
+	
+	glade_command_check_group(GLADE_COMMAND(me));
+		
+	/* execute the command and push it on the stack if successful 
+	 * this sets the actual policy
+	 */
+	if (glade_command_protect_execute(GLADE_COMMAND(me)))
+		glade_project_push_undo(glade_app_get_project(), GLADE_COMMAND(me));
+	else
+		g_object_unref(G_OBJECT(me));
+
+}
+

Modified: trunk/gladeui/glade-command.h
==============================================================================
--- trunk/gladeui/glade-command.h	(original)
+++ trunk/gladeui/glade-command.h	Tue Oct 28 05:07:30 2008
@@ -114,6 +114,13 @@
 void           glade_command_set_name      (GladeWidget       *glade_widget, const gchar  *name);
 
 
+/************************ protection ******************************/
+
+void           glade_command_protect_widget   (GladeWidget   *widget, 
+					       const gchar   *warning);
+
+void           glade_command_unprotect_widget (GladeWidget   *widget);
+
 /************************ create/delete ******************************/
 
 void           glade_command_delete        (GList              *widgets);

Modified: trunk/gladeui/glade-editor-property.c
==============================================================================
--- trunk/gladeui/glade-editor-property.c	(original)
+++ trunk/gladeui/glade-editor-property.c	Tue Oct 28 05:07:30 2008
@@ -431,18 +431,7 @@
 glade_editor_property_load_common (GladeEditorProperty *eprop, 
 				   GladeProperty       *property)
 {
-	/* Hide properties that are removed for some particular widgets. 
-	 */
-	if (property)
-	{
-		gtk_widget_show (GTK_WIDGET (eprop));
-		gtk_widget_show (eprop->item_label);
-	}
-	else
-	{
-		gtk_widget_hide (GTK_WIDGET (eprop));
-		gtk_widget_hide (eprop->item_label);
-	}
+	/* NOTE THIS CODE IS FINALIZE SAFE */
 
 	/* disconnect anything from previously loaded property */
 	if (eprop->property != property && eprop->property != NULL) 

Modified: trunk/gladeui/glade-editor-table.c
==============================================================================
--- trunk/gladeui/glade-editor-table.c	(original)
+++ trunk/gladeui/glade-editor-table.c	Tue Oct 28 05:07:30 2008
@@ -59,6 +59,12 @@
 
 	table->properties =
 		(g_list_free (table->properties), NULL);
+
+	/* the entry is finalized anyway, just avoid setting
+	 * text in it from _load();
+	 */
+	table->name_entry = NULL;
+
 	glade_editable_load (GLADE_EDITABLE (table), NULL);
 
 	G_OBJECT_CLASS (glade_editor_table_parent_class)->finalize (object);
@@ -69,7 +75,7 @@
 {
 	GladeEditorTable *editor_table = GLADE_EDITOR_TABLE (widget);
 	
-	if (editor_table->name_entry)
+	if (editor_table->name_entry && GTK_WIDGET_MAPPED (editor_table->name_entry))
 		gtk_widget_grab_focus (editor_table->name_entry);
 	else if (editor_table->properties)
 		gtk_widget_grab_focus (GTK_WIDGET (editor_table->properties->data));
@@ -322,9 +328,11 @@
 	table->name_label = gtk_label_new (_("Name:"));
 	gtk_misc_set_alignment (GTK_MISC (table->name_label), 0.0, 0.5);
 	gtk_widget_show (table->name_label);
+	gtk_widget_set_no_show_all (table->name_label, TRUE);
 
 	table->name_entry = gtk_entry_new ();
 	gtk_widget_show (table->name_entry);
+	gtk_widget_set_no_show_all (table->name_entry, TRUE);
 
 	gtk_widget_set_tooltip_text (table->name_label, text);
 	gtk_widget_set_tooltip_text (table->name_entry, text);

Modified: trunk/gladeui/glade-widget-adaptor.c
==============================================================================
--- trunk/gladeui/glade-widget-adaptor.c	(original)
+++ trunk/gladeui/glade-widget-adaptor.c	Tue Oct 28 05:07:30 2008
@@ -954,7 +954,7 @@
 			GladeWidget *child = glade_widget_get_from_gobject (l->data);
 
 			if (child) 
-				glade_widget_write_child (child, context, node);
+				glade_widget_write_child (widget, child, context, node);
 			else if (GLADE_IS_PLACEHOLDER (l->data))
 				glade_widget_write_placeholder (widget, 
 								G_OBJECT (l->data),
@@ -2269,6 +2269,7 @@
  *                     outside of the hierarchy.
  * @internal_object:   the #GObject
  * @internal_name:     a string identifier for this internal widget.
+ * @parent_name:       the generic name of the parent used for fancy child names.
  * @anarchist:         Whether or not this widget is a widget outside
  *                     of the parent's hierarchy (like a popup window)
  * @reason:            The #GladeCreateReason for which this internal widget
@@ -2296,7 +2297,7 @@
 	g_return_val_if_fail (GLADE_IS_WIDGET (parent), NULL);
 	project = glade_widget_get_project (parent);
 
-        if ((adaptor = glade_widget_adaptor_get_by_name 
+        if ((adaptor = glade_widget_adaptor_get_by_name
 	     (G_OBJECT_TYPE_NAME (internal_object))) == NULL)
 	{
 		g_critical ("Unable to find widget class for type %s", 

Modified: trunk/gladeui/glade-widget.c
==============================================================================
--- trunk/gladeui/glade-widget.c	(original)
+++ trunk/gladeui/glade-widget.c	Tue Oct 28 05:07:30 2008
@@ -3633,7 +3633,8 @@
 
 /**
  * glade_widget_write_child:
- * @widget: The #GladeWidget
+ * @widget: A #GladeWidget
+ * @child: The child #GladeWidget to write
  * @context: A #GladeXmlContext
  * @node: A #GladeXmlNode
  *
@@ -3642,13 +3643,16 @@
  */
 void
 glade_widget_write_child (GladeWidget     *widget,
+			  GladeWidget     *child,
 			  GladeXmlContext *context,
 			  GladeXmlNode    *node)
 {
-	g_return_if_fail (widget->parent);
+	g_return_if_fail (GLADE_IS_WIDGET (widget));
+	g_return_if_fail (GLADE_IS_WIDGET (child));
+	g_return_if_fail (child->parent == widget);
 
-	glade_widget_adaptor_write_child (widget->parent->adaptor,
-					  widget, context, node);
+	glade_widget_adaptor_write_child (widget->adaptor,
+					  child, context, node);
 }
 
 
@@ -4161,3 +4165,25 @@
 
 	g_object_notify (G_OBJECT (widget), "support-warning");
 }
+
+void
+glade_widget_protect (GladeWidget      *widget,
+		      const gchar      *warning)
+{
+	g_return_if_fail (GLADE_IS_WIDGET (widget));
+	g_return_if_fail (warning && warning[0]);
+	
+	if (widget->protection)
+		g_free (widget->protection);
+	widget->protection = g_strdup (warning);
+}
+
+void
+glade_widget_unprotect (GladeWidget    *widget)
+{
+	g_return_if_fail (GLADE_IS_WIDGET (widget));
+	
+	if (widget->protection)
+		g_free (widget->protection);
+	widget->protection = NULL;
+}

Modified: trunk/gladeui/glade-widget.h
==============================================================================
--- trunk/gladeui/glade-widget.h	(original)
+++ trunk/gladeui/glade-widget.h	Tue Oct 28 05:07:30 2008
@@ -41,6 +41,12 @@
 				 * in this widget
 				 */
 	
+	gchar *protection; /* custom editors are allowed to add protected widgets that
+			    * cannot be deleted by the user in normal ways.
+			    * (this is a message to be displayed in the dialog
+			    * when the user tries to delete it).
+			    */
+
 	gchar *internal; /* If the widget is an internal child of 
 			  * another widget this is the name of the 
 			  * internal child, otherwise is NULL.
@@ -224,6 +230,7 @@
 							     GladeXmlNode    *node);
 
 void                    glade_widget_write_child            (GladeWidget     *widget,
+							     GladeWidget     *child,
 							     GladeXmlContext *context,
 							     GladeXmlNode    *node);
 
@@ -403,6 +410,10 @@
 void                    glade_widget_set_support_warning    (GladeWidget      *widget,
 							     const gchar      *warning);
 
+void                    glade_widget_protect                (GladeWidget      *widget,
+							     const gchar      *warning);
+void                    glade_widget_unprotect              (GladeWidget      *widget);
+
 G_END_DECLS
 
 #endif /* __GLADE_WIDGET_H__ */

Modified: trunk/plugins/gtk+/Makefile.am
==============================================================================
--- trunk/plugins/gtk+/Makefile.am	(original)
+++ trunk/plugins/gtk+/Makefile.am	Tue Oct 28 05:07:30 2008
@@ -25,7 +25,8 @@
 
 libgladegtk_la_SOURCES     = glade-gtk.c glade-accels.c glade-attributes.c glade-convert.c fixed-bg.xpm \
 	glade-column-types.c  glade-model-data.c glade-text-button.c glade-cell-renderer-button.c \
-	glade-icon-sources.c glade-button-editor.c glade-tool-button-editor.c glade-image-editor.c
+	glade-icon-sources.c glade-button-editor.c glade-tool-button-editor.c glade-image-editor.c \
+	glade-image-item-editor.c
 
 libgladegtk_la_LDFLAGS     = -module -avoid-version $(AM_LDFLAGS)
 libgladegtk_la_LIBADD      = $(libgladeui) $(GTK_LIBS)
@@ -33,7 +34,7 @@
 libgladegtkincludedir= $(includedir)/libgladeui-1.0/gladeui
 libgladegtkinclude_HEADERS = glade-gtk.h glade-accels.h glade-attributes.h glade-column-types.h glade-model-data.h \
 	glade-text-button.h glade-cell-renderer-button.h glade-icon-sources.h glade-button-editor.h \
-	glade-tool-button-editor.h glade-image-editor.h
+	glade-tool-button-editor.h glade-image-editor.h glade-image-item-editor.h
 
 if PLATFORM_WIN32
 libgladegtk_la_LDFLAGS += -no-undefined

Modified: trunk/plugins/gtk+/glade-button-editor.c
==============================================================================
--- trunk/plugins/gtk+/glade-button-editor.c	(original)
+++ trunk/plugins/gtk+/glade-button-editor.c	Tue Oct 28 05:07:30 2008
@@ -121,7 +121,8 @@
 	}
 
 	/* load the embedded editable... */
-	glade_editable_load (GLADE_EDITABLE (button_editor->embed), widget);
+	if (button_editor->embed)
+		glade_editable_load (GLADE_EDITABLE (button_editor->embed), widget);
 
 	for (l = button_editor->properties; l; l = l->next)
 		glade_editor_property_load_by_widget (GLADE_EDITOR_PROPERTY (l->data), widget);
@@ -190,6 +191,10 @@
 
 	if (button_editor->properties)
 		g_list_free (button_editor->properties);
+	button_editor->properties = NULL;
+	button_editor->embed      = NULL;
+
+	glade_editable_load (GLADE_EDITABLE (object), NULL);
 
 	G_OBJECT_CLASS (glade_button_editor_parent_class)->finalize (object);
 }

Modified: trunk/plugins/gtk+/glade-gtk.c
==============================================================================
--- trunk/plugins/gtk+/glade-gtk.c	(original)
+++ trunk/plugins/gtk+/glade-gtk.c	Tue Oct 28 05:07:30 2008
@@ -34,6 +34,7 @@
 #include "glade-button-editor.h"
 #include "glade-tool-button-editor.h"
 #include "glade-image-editor.h"
+#include "glade-image-item-editor.h"
 
 #include <gladeui/glade-editor-property.h>
 #include <gladeui/glade-base-editor.h>
@@ -5389,7 +5390,7 @@
 	GladeEditable *editable;
 
 	/* Get base editable */
-	editable = GWA_GET_CLASS (GTK_TYPE_CONTAINER)->create_editable (adaptor, type);
+	editable = GWA_GET_CLASS (GTK_TYPE_WIDGET)->create_editable (adaptor, type);
 
 	if (type == GLADE_PAGE_GENERAL)
 		return (GladeEditable *)glade_image_editor_new (adaptor, editable);
@@ -5648,6 +5649,21 @@
 {
 	GObject *child = glade_widget_get_object (gchild);
 	
+	/* Delete the internal image of an image menu item before going ahead and changing types. */
+	if (GTK_IS_IMAGE_MENU_ITEM (child))
+	{
+		GList list = { 0, };
+		GtkWidget   *image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (child));
+		GladeWidget *widget;
+
+		if (image && (widget = glade_widget_get_from_gobject (image)))
+		{
+			list.data = widget;
+			glade_command_unprotect_widget (widget);
+			glade_command_delete (&list);
+		}
+	}
+
 	if (type == GTK_TYPE_SEPARATOR_MENU_ITEM &&
 	    gtk_menu_item_get_submenu (GTK_MENU_ITEM (child)))
 		return TRUE;
@@ -5668,31 +5684,20 @@
 	glade_base_editor_add_default_properties (editor, gchild);
 	
 	if (GTK_IS_SEPARATOR_MENU_ITEM (child)) return;
-	
+
 	glade_base_editor_add_label (editor, "Properties");
-	
-	glade_base_editor_add_properties (editor, gchild, FALSE, "label", "tooltip", NULL);
 
-	if (type == GTK_TYPE_IMAGE_MENU_ITEM)
-	{
-		GtkWidget *image;
-		GladeWidget *internal;
+	if (glade_project_get_format (gchild->project) == GLADE_PROJECT_FORMAT_LIBGLADE)
+		glade_base_editor_add_properties (editor, gchild, FALSE, "tooltip", NULL);
+	else
+		glade_base_editor_add_properties (editor, gchild, FALSE, "tooltip-text", NULL);
 
-		glade_base_editor_add_properties (editor, gchild, FALSE, "stock", NULL);
-		
-		if ((image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (child))))
-		{
-			if ((internal = glade_widget_get_from_gobject (image)) &&
-				internal->internal)
-			{
-				glade_base_editor_add_label
-					(editor, "Internal Image Properties");
-				glade_base_editor_add_properties
-					(editor, internal, FALSE, "glade-type", "pixbuf", 
-					 "glade-stock", "icon-name", NULL);
-			}
-		}
-	}
+
+	if (type != GTK_TYPE_IMAGE_MENU_ITEM)
+		glade_base_editor_add_properties (editor, gchild, FALSE, "label", "tooltip", NULL);
+
+	if (type == GTK_TYPE_IMAGE_MENU_ITEM)
+		glade_base_editor_add_editable (editor, gchild);
 	else if (type == GTK_TYPE_CHECK_MENU_ITEM)
 		glade_base_editor_add_properties (editor, gchild, FALSE,
 						  "active", "draw-as-radio",
@@ -5759,7 +5764,34 @@
 								     action_path);
 }
 
-/* ----------------------------- GtkMenuItem(s) ------------------------------ */
+/* ----------------------------- GtkMenuItem ------------------------------ */
+void
+glade_gtk_menu_item_action_activate (GladeWidgetAdaptor *adaptor,
+				     GObject *object,
+				     const gchar *action_path)
+{
+	if (strcmp (action_path, "launch_editor") == 0)
+	{
+		GladeWidget *w = glade_widget_get_from_gobject (object);
+		
+		while ((w = glade_widget_get_parent (w)))
+		{
+			GObject *obj = glade_widget_get_object (w);
+			if (GTK_IS_MENU_SHELL (obj)) object = obj;
+		}
+		
+		if (GTK_IS_MENU_BAR (object))
+			glade_gtk_menu_shell_launch_editor (object, _("Edit Menu Bar"));
+		else if (GTK_IS_MENU (object))
+			glade_gtk_menu_shell_launch_editor (object, _("Edit Menu"));
+	}
+	else
+		GWA_GET_CLASS (GTK_TYPE_CONTAINER)->action_activate (adaptor,
+								     object,
+								     action_path);
+}
+
+
 GObject *
 glade_gtk_menu_item_constructor (GType                  type,
 				 guint                  n_construct_properties,
@@ -5778,6 +5810,27 @@
 
 	return ret_obj;
 }
+	
+void
+glade_gtk_menu_item_post_create (GladeWidgetAdaptor *adaptor, 
+				 GObject            *object, 
+				 GladeCreateReason   reason)
+{
+	GladeWidget  *gitem;
+
+	g_return_if_fail (GTK_IS_MENU_ITEM (object));
+	gitem = glade_widget_get_from_gobject (object);
+	g_return_if_fail (GLADE_IS_WIDGET (gitem));
+	
+	if (GTK_IS_SEPARATOR_MENU_ITEM (object)) return;
+	
+	if (gtk_bin_get_child (GTK_BIN (object)) == NULL)
+	{
+		GtkWidget *label = gtk_label_new ("");
+		gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+		gtk_container_add (GTK_CONTAINER (object), label);
+	}
+}
 
 GList *
 glade_gtk_menu_item_get_children (GladeWidgetAdaptor *adaptor,
@@ -5790,10 +5843,6 @@
 	
 	if ((child = gtk_menu_item_get_submenu (GTK_MENU_ITEM (object))))
 		list = g_list_append (list, child);
-	
-	if (GTK_IS_IMAGE_MENU_ITEM (object) &&
-	    (child = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (object))))
-		list = g_list_append (list, child);
 
 	return list;
 }
@@ -5824,180 +5873,227 @@
 	gtk_menu_item_remove_submenu (GTK_MENU_ITEM (object));
 }
 
-#define glade_return_if_re_entrancy(o,p,v) \
-	if ((v) == GPOINTER_TO_INT (g_object_get_data (G_OBJECT (o), p))) return; g_object_set_data (G_OBJECT (o), p, GINT_TO_POINTER ((v)))
+static void
+glade_gtk_menu_item_set_label (GObject *object, const GValue *value)
+{
+	GladeWidget *gitem;
+	GtkWidget   *label;
+	gboolean     use_underline;
+
+	gitem = glade_widget_get_from_gobject (object);
+
+	label = gtk_bin_get_child (GTK_BIN (object));
+	gtk_label_set_text (GTK_LABEL (label), g_value_get_string (value));
+
+	/* Update underline incase... */
+	glade_widget_property_get (gitem, "use-underline", &use_underline);
+	gtk_label_set_use_underline (GTK_LABEL (label), use_underline);
+}
+
+static void
+glade_gtk_menu_item_set_use_underline (GObject *object, const GValue *value)
+{
+	GtkWidget   *label;
+
+	label = gtk_bin_get_child (GTK_BIN (object));
+	gtk_label_set_use_underline (GTK_LABEL (label), g_value_get_boolean (value));
+}
+
+void
+glade_gtk_menu_item_set_property (GladeWidgetAdaptor *adaptor,
+				  GObject            *object, 
+				  const gchar        *id,
+				  const GValue       *value)
+{
+	if (!strcmp (id, "use-underline"))
+		glade_gtk_menu_item_set_use_underline (object, value);
+	else if (!strcmp (id, "label"))
+		glade_gtk_menu_item_set_label (object, value);
+	else
+		GWA_GET_CLASS (GTK_TYPE_CONTAINER)->set_property (adaptor, object,
+								  id, value);
+}
+
+/* ----------------------------- GtkImageMenuItem ------------------------------ */
+GList *
+glade_gtk_image_menu_item_get_children (GladeWidgetAdaptor *adaptor,
+					GObject *object)
+{
+	GList *list = NULL;
+	GtkWidget *child;
+	
+	g_return_val_if_fail (GTK_IS_MENU_ITEM (object), NULL);
+	
+	if ((child = gtk_menu_item_get_submenu (GTK_MENU_ITEM (object))))
+		list = g_list_append (list, child);
 	
+	if (GTK_IS_IMAGE_MENU_ITEM (object) &&
+	    (child = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (object))))
+		list = g_list_append (list, child);
+
+	return list;
+}
+
 void
-glade_gtk_menu_item_post_create (GladeWidgetAdaptor *adaptor, 
-				 GObject            *object, 
-				 GladeCreateReason   reason)
+glade_gtk_image_menu_item_add_child (GladeWidgetAdaptor *adaptor,
+				     GObject *object, GObject *child)
 {
-	GladeWidget  *gitem, *gimage;
+	g_return_if_fail (GTK_IS_MENU_ITEM (object));
 
+	if (GTK_IS_IMAGE (child))
+		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (object), GTK_WIDGET (child));
+	else
+ 		GWA_GET_CLASS (GTK_TYPE_MENU_ITEM)->add (adaptor, object, child);
+}
+
+void
+glade_gtk_image_menu_item_remove_child (GladeWidgetAdaptor *adaptor,
+					GObject *object, GObject *child)
+{
 	g_return_if_fail (GTK_IS_MENU_ITEM (object));
-	gitem = glade_widget_get_from_gobject (object);
-	g_return_if_fail (GLADE_IS_WIDGET (gitem));
 	
-	if (GTK_IS_SEPARATOR_MENU_ITEM (object)) return;
-	
-	if (gtk_bin_get_child (GTK_BIN (object)) == NULL)
-	{
-		GtkWidget *label = gtk_label_new ("");
-		gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-		gtk_container_add (GTK_CONTAINER (object), label);
-	}
+	if (GTK_IS_IMAGE (child))
+		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (object), NULL);
+	else
+ 		GWA_GET_CLASS (GTK_TYPE_MENU_ITEM)->remove (adaptor, object, child);
+}
 
-	if (GTK_IS_IMAGE_MENU_ITEM (object))
-	{
-		gboolean use_stock;
+static void
+glade_gtk_image_menu_item_set_use_stock (GObject *object, const GValue *value)
+{
+	GladeWidget  *widget = glade_widget_get_from_gobject (object);
+	gboolean      use_stock;
 	
-		glade_widget_property_get (gitem, "use-stock", &use_stock);
-		if (use_stock)
-		{
-			GEnumClass *eclass;
-			GEnumValue *eval;
-			gchar *label;
-			
-			glade_widget_property_get (gitem, "label", &label);
-			
-			eclass = g_type_class_ref (GLADE_TYPE_STOCK);
-			eval = g_enum_get_value_by_nick (eclass, label);
-			if (eval)
-				glade_widget_property_set(gitem, "stock", eval->value);
-			
-			glade_widget_property_set (gitem, "use-underline", TRUE);
-		}
-		else
-		{
-			if (reason == GLADE_CREATE_USER)
-			{
-				GtkWidget *image = gtk_image_new ();
+	use_stock = g_value_get_boolean (value);
+
+	/* Set some things */
+	if (use_stock)
+		glade_widget_property_set_sensitive (widget, "stock", TRUE, NULL);
+	else
+		glade_widget_property_set_sensitive (widget, "stock", FALSE, _("Property not selected"));
 
-				gimage = glade_widget_adaptor_create_internal
-					(gitem, G_OBJECT (image),
-					 "image", "menu-item", FALSE, reason);
-				gtk_image_menu_item_set_image
-					(GTK_IMAGE_MENU_ITEM (object), image);
-			}
-		}
-	}
 }
 
 static void
-glade_gtk_menu_item_set_label (GObject *object, const GValue *value)
+glade_gtk_image_menu_item_set_label (GObject *object, const GValue *value)
 {
 	GladeWidget *gitem;
 	GtkWidget *label;
-	gboolean use_underline, use_stock;
-	const gchar *label_str, *last_label_str;
+	gboolean use_underline = FALSE, use_stock = FALSE;
+	gchar *text;
 
-	g_return_if_fail (GTK_IS_MENU_ITEM (object));
 	gitem = glade_widget_get_from_gobject (object);
-	g_return_if_fail (GLADE_IS_WIDGET (gitem));
-	
-	if (GTK_IS_SEPARATOR_MENU_ITEM (object)) return;
+	label = gtk_bin_get_child (GTK_BIN (object));
 
-	label_str = g_value_get_string (value);
-	
-	last_label_str = g_object_get_data (G_OBJECT (gitem), "label");
-	if (last_label_str)
-		if (strcmp(label_str, last_label_str) == 0) return;
-	g_object_set_data_full (G_OBJECT (gitem), "label", g_strdup(label_str), g_free);
+	glade_widget_property_get (gitem, "use-stock", &use_stock);
+	glade_widget_property_get (gitem, "use-underline", &use_underline);
+	text = g_value_get_string (value);
 
-	if (GTK_IS_IMAGE_MENU_ITEM (object))
+	/* In "use-stock" mode we dont have a GladeWidget child image */
+	if (use_stock)
 	{
-		glade_widget_property_get (gitem, "use-stock", &use_stock);
-		
-		if (use_stock)
-		{
-			GtkWidget *image;
-			GEnumClass *eclass;
-			GEnumValue *eval;
-			
-			eclass = g_type_class_ref (GLADE_TYPE_STOCK);
-			eval = g_enum_get_value_by_nick (eclass, label_str);
-			
-			if (eval)
-			{
-				label_str = eval->value_name;
-			
-				image = gtk_image_new_from_stock (eval->value_nick, GTK_ICON_SIZE_MENU);
-				gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (object), image);
-			}
-			
-			g_type_class_unref (eclass);
-		}
-	}
-	
-	label = gtk_bin_get_child (GTK_BIN (object));
-	gtk_label_set_text (GTK_LABEL (label), label_str);
-	
-	glade_widget_property_get (gitem, "use-underline", &use_underline);
+		GtkWidget *image;
+		GtkStockItem item;
+
+		image = gtk_image_new_from_stock (g_value_get_string (value), GTK_ICON_SIZE_MENU);
+		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (object), image);
+
+		/* Get the label string... */
+		if (text && gtk_stock_lookup (text, &item))
+			gtk_label_set_text (GTK_LABEL (label), item.label);
+		else
+			gtk_label_set_text (GTK_LABEL (label), text);
+
+		/* Just for display purposes, real stock menuitems dont need the underline property,
+		 * but do have mnemonic label. */
+		gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
+	} 
+	else 
+		gtk_label_set_text (GTK_LABEL (label), g_value_get_string (value));
+
+	/* Update underline incase... */
 	gtk_label_set_use_underline (GTK_LABEL (label), use_underline);
 }
 
 static void
-glade_gtk_menu_item_set_use_underline (GObject *object, const GValue *value)
+glade_gtk_image_menu_item_set_stock (GObject *object, const GValue *value)
 {
-	GtkMenuItem *item;
-	GtkWidget *label;
+	/* Forward the work along to the label handler...  */
+	glade_gtk_image_menu_item_set_label (object, value);
+}
 
-	g_return_if_fail (GTK_IS_MENU_ITEM (object));
+void
+glade_gtk_image_menu_item_set_property (GladeWidgetAdaptor *adaptor,
+					GObject            *object, 
+					const gchar        *id,
+					const GValue       *value)
+{
+	if (!strcmp (id, "stock"))
+		glade_gtk_image_menu_item_set_stock (object, value);
+	else if (!strcmp (id, "use-stock"))
+		glade_gtk_image_menu_item_set_use_stock (object, value);
+	else if (!strcmp (id, "label"))
+		glade_gtk_image_menu_item_set_label (object, value);
+	else
+		GWA_GET_CLASS (GTK_TYPE_MENU_ITEM)->set_property (adaptor, object,
+								  id, value);
+}
 
-	item = GTK_MENU_ITEM (object);
+static GladeWidget *
+glade_gtk_image_menu_item_create_image (GladeWidget *gitem)
+{
+	GladeWidget *gimage;
+	gchar *protection;
 
-	if (GTK_IS_SEPARATOR_MENU_ITEM (item)) return;
+	gimage = glade_widget_adaptor_create_widget 
+		(glade_widget_adaptor_get_by_type (GTK_TYPE_IMAGE), FALSE,
+		 "parent", gitem, 
+		 "project", glade_widget_get_project (gitem), 
+		 NULL);
 	
-	label = gtk_bin_get_child (GTK_BIN (item));
+	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (gitem->object), 
+				       GTK_WIDGET (gimage->object));
 
-	gtk_label_set_use_underline (GTK_LABEL (label), g_value_get_boolean (value));
-}
+	protection = g_strdup_printf (_("Cannot delete %s because it is used by %s, "
+					"try editing %s instead."),
+				      gimage->name, gitem->name, gitem->name);
+	glade_widget_protect (gimage, protection);
+	g_free (protection);
 
-GObject *
-glade_gtk_image_menu_item_get_internal_child (GladeWidgetAdaptor *adaptor,
-					      GObject            *parent,
-					      const gchar        *name);
+	return gimage;
+}
 
 static void
-glade_gtk_menu_item_set_stock_item (GObject *object, const GValue *value)
-{
-	GladeWidget *gitem, *gimage;
-	GEnumClass *eclass;
-	GEnumValue *eval;
-	gint val;
-	gchar *label, *icon;
-	GObject *image;
-	gboolean is_image_item;
+glade_gtk_image_menu_item_fix_stock_item (GladeWidget *widget)
+{
+	GladeWidget *gimage;
+	GEnumClass  *eclass;
+	GEnumValue  *eval;
+	gint         val = GNOMEUIINFO_MENU_NONE;
+	gchar       *label = NULL, *icon = NULL;
 	
-	g_return_if_fail (GTK_IS_MENU_ITEM (object));
-
-	if ((val = g_value_get_enum (value)) == GNOMEUIINFO_MENU_NONE)
-		return;
+	glade_widget_property_get (widget, "stock-item", &val);
+	if (val == GNOMEUIINFO_MENU_NONE) return;
 	
-	eclass = g_type_class_ref (G_VALUE_TYPE (value));
+	/* Get the GEnumValue ... */
+	eclass = g_type_class_ref (glade_gtk_gnome_ui_info_get_type ());
 	if ((eval = g_enum_get_value (eclass, val)) == NULL)
 	{
 		g_type_class_unref (eclass);
 		return;
 	}
-
 	g_type_class_unref (eclass);
 	
 	/* set use-underline */
-	gitem = glade_widget_get_from_gobject (object);
-	glade_widget_property_set (gitem, "use-underline", TRUE);
-	
-	is_image_item = GTK_IS_IMAGE_MENU_ITEM (object);
+	glade_widget_property_set (widget, "use-underline", TRUE);
 	
-	/* If its a GtkImageMenuItem */
-	if (is_image_item && eval->value_nick)
+	if (eval->value_nick)
 	{
-		glade_widget_property_set (gitem, "use-stock", TRUE);
-		glade_widget_property_set (gitem, "label", eval->value_nick);		
+		glade_widget_property_set (widget, "use-stock", TRUE);
+		glade_widget_property_set (widget, "label", eval->value_nick);		
 		return;
 	}
 	
-	icon = NULL;
 	switch (val)
 	{
 		case GNOMEUIINFO_MENU_PRINT_SETUP_ITEM:
@@ -6072,152 +6168,134 @@
 		break;
 	}
 
-	if (is_image_item && icon)
+	if (icon)
 	{
-		eclass = g_type_class_ref (GLADE_TYPE_STOCK);
-		eval = g_enum_get_value_by_nick (eclass, icon);
-		g_type_class_unref (eclass);
-	
-		image = glade_gtk_image_menu_item_get_internal_child
-			(gitem->adaptor, object, "image");
-
-		gimage = glade_widget_get_from_gobject (image);
+		gimage = glade_gtk_image_menu_item_create_image	(widget);
+		glade_widget_property_set (gimage, "stock", icon);
 		glade_widget_property_set (gimage, "icon-size", GTK_ICON_SIZE_MENU);
-		glade_widget_property_set (gimage, "glade-stock", eval->value);
 	}
 	
-	glade_widget_property_set (gitem, "label", label);
+	glade_widget_property_set (widget, "label", label);
 }
 
 void
-glade_gtk_menu_item_set_property (GladeWidgetAdaptor *adaptor,
-				  GObject            *object, 
-				  const gchar        *id,
-				  const GValue       *value)
+glade_gtk_image_menu_item_read_widget (GladeWidgetAdaptor *adaptor,
+				       GladeWidget        *widget,
+				       GladeXmlNode       *node)
 {
-	if (!strcmp (id, "use-underline"))
-		glade_gtk_menu_item_set_use_underline (object, value);
-	else if (!strcmp (id, "label"))
-		glade_gtk_menu_item_set_label (object, value);
-	else if (!strcmp (id, "stock-item"))
-		glade_gtk_menu_item_set_stock_item (object, value);
-	else
-		GWA_GET_CLASS (GTK_TYPE_CONTAINER)->set_property (adaptor, object,
-								  id, value);
-}
+	gboolean use_stock;
 
-GObject *
-glade_gtk_image_menu_item_get_internal_child (GladeWidgetAdaptor *adaptor,
-					      GObject            *parent,
-					      const gchar        *name)
-{
-	GtkWidget *image;
-	GObject   *child = NULL;
+	if (!glade_xml_node_verify 
+	    (node, GLADE_XML_TAG_WIDGET (glade_project_get_format (widget->project))))
+		return;
 
-	if (GTK_IS_IMAGE_MENU_ITEM (parent) && strcmp (name, "image") == 0)
-	{
-		image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (parent));
-		if (image == NULL)
-		{
-			GladeWidget  *gitem, *gimage;
-			
-			gitem = glade_widget_get_from_gobject (parent);
-			image = gtk_image_new ();
+	/* First chain up and read in all the normal properties.. */
+        GWA_GET_CLASS (G_TYPE_OBJECT)->read_widget (adaptor, widget, node);
 
-			gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (parent), image);
-			
-			gimage = glade_widget_adaptor_create_internal
-				(gitem, G_OBJECT (image), "image", "menu-item",
-				 FALSE, GLADE_CREATE_LOAD);
-		}
-		child = G_OBJECT (image);
+	/* Read in the internal images as normal ones !
+	 */
+
+
+	/* This will read legacy "stock-item" properties and make them usable */
+	glade_gtk_image_menu_item_fix_stock_item (widget);
+
+	glade_widget_property_get (widget, "use-stock", &use_stock);
+	if (use_stock)
+	{
+		gchar *label = NULL;
+		glade_widget_property_get (widget, "label", &label);
+		glade_widget_property_set (widget, "stock", label);
 	}
 
-	return child;
 }
 
-static void
-glade_gtk_image_menu_item_set_use_stock (GObject *object, const GValue *value)
+void
+glade_gtk_image_menu_item_read_child (GladeWidgetAdaptor *adaptor,
+				      GladeWidget        *widget,
+				      GladeXmlNode       *node)
 {
-	GladeWidget  *gitem, *gimage;
-	gboolean      use_stock;
-	GtkWidget    *image;
-	
-	g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (object));
-	gitem = glade_widget_get_from_gobject (object);
-	g_return_if_fail (GLADE_IS_WIDGET (gitem));
+	GladeXmlNode *widget_node;
+	GladeWidget  *child_widget;
+	gchar        *internal_name;
 
-	use_stock = g_value_get_boolean (value);
-	
-	glade_return_if_re_entrancy (gitem, "use-stock", use_stock);
+	if (!glade_xml_node_verify (node, GLADE_XML_TAG_CHILD))
+		return;
 
-	if ((image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (object))))
-		if(glade_widget_get_from_gobject (G_OBJECT(image)))
-		{
-			glade_project_remove_object (glade_widget_get_project (gitem), G_OBJECT(image));
-			gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (object), NULL);
-		}
+	internal_name = 
+		glade_xml_get_property_string 
+		(node, GLADE_XML_TAG_INTERNAL_CHILD);
 	
-	if (use_stock)
-	{
-		glade_widget_property_set_sensitive (gitem, "label", FALSE,
-					_("This does not apply with stock items"));
-	}
-	else
+	if ((widget_node = 
+	     glade_xml_search_child
+	     (node, GLADE_XML_TAG_WIDGET(glade_project_get_format(widget->project)))) != NULL)
 	{
-		image = gtk_image_new ();
-		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (object), image);
-		gimage = glade_widget_adaptor_create_internal
-			(gitem, G_OBJECT (image), "image", "menu-item", FALSE,
-			 GLADE_CREATE_LOAD);
-		glade_project_add_object (glade_widget_get_project (gitem), 
-					  NULL, G_OBJECT (image));
-
-		glade_widget_property_set_sensitive (gitem, "label", TRUE, NULL);
+		/* Menu item children have no packing to take care of, just
+		 * need to treat images a little different. */		
+		if ((child_widget = glade_widget_read (widget->project, 
+						       widget, widget_node, 
+						       NULL)) != NULL)
+		{
+			if (GTK_IS_IMAGE (child_widget->object) &&
+			    internal_name && strcmp (internal_name, "image") == 0)
+			{
+				gchar *protection = 
+					g_strdup_printf (_("Cannot delete %s because it is used by %s, "
+							   "try editing %s instead."),
+							 child_widget->name, widget->name, widget->name);
+				glade_widget_protect (child_widget, protection);
+				g_free (protection);
+			}
+			glade_widget_add_child (widget, child_widget, FALSE);
+		}
 	}
+	g_free (internal_name);
 }
 
-static void
-glade_gtk_image_menu_item_set_stock (GObject *object, const GValue *value)
+void
+glade_gtk_image_menu_item_write_child (GladeWidgetAdaptor *adaptor,
+				       GladeWidget        *widget,
+				       GladeXmlContext    *context,
+				       GladeXmlNode       *node)
 {
-	GladeWidget *gitem;
-	GEnumClass *eclass;
-	GEnumValue *eval;
-	gint val;
-	
-	g_return_if_fail (GTK_IS_IMAGE_MENU_ITEM (object));
-	gitem = glade_widget_get_from_gobject (object);
-	g_return_if_fail (GLADE_IS_WIDGET (gitem));
-	
-	val = g_value_get_enum (value);
-	
-	glade_return_if_re_entrancy (gitem, "stock", val);
-	
-	glade_widget_property_set (gitem, "use-stock", val);
-		
-	eclass = g_type_class_ref (GLADE_TYPE_STOCK);
-	eval = g_enum_get_value (eclass, val);
-	if (eval && val)
-		glade_widget_property_set (gitem, "label", eval->value_nick);
-	
-	g_type_class_unref (eclass);
+	GladeXmlNode *child_node;
+
+	if (!GTK_IS_IMAGE (widget->object))
+	{
+		GWA_GET_CLASS (G_TYPE_OBJECT)->write_child (adaptor, widget, context, node);
+		return;
+	}
+
+	child_node = glade_xml_node_new (context, GLADE_XML_TAG_CHILD);
+	glade_xml_node_append_child (node, child_node);
+
+	/* Set fake internal child here */
+	glade_xml_node_set_property_string (child_node, GLADE_XML_TAG_INTERNAL_CHILD, "image");
+
+	/* Write out the widget (no packing properties) */
+	glade_widget_write (widget, context, child_node);
 }
 
-void
-glade_gtk_image_menu_item_set_property (GladeWidgetAdaptor *adaptor,
-					GObject            *object, 
-					const gchar        *id,
-					const GValue       *value)
+
+/* We need write_widget to write child images as internal, in builder, they are
+ * attached as a property
+ */
+
+GladeEditable *
+glade_gtk_image_menu_item_create_editable  (GladeWidgetAdaptor  *adaptor,
+					    GladeEditorPageType  type)
 {
-	if (!strcmp (id, "stock"))
-		glade_gtk_image_menu_item_set_stock (object, value);
-	else if (!strcmp (id, "use-stock"))
-		glade_gtk_image_menu_item_set_use_stock (object, value);
-	else
-		GWA_GET_CLASS (GTK_TYPE_MENU_ITEM)->set_property (adaptor, object,
-								  id, value);
+	GladeEditable *editable;
+
+	/* Get base editable */
+	editable = GWA_GET_CLASS (GTK_TYPE_MENU_ITEM)->create_editable (adaptor, type);
+
+	if (type == GLADE_PAGE_GENERAL)
+		return (GladeEditable *)glade_image_item_editor_new (adaptor, editable);
+
+	return editable;
 }
 
+/* ----------------------------- GtkRadioMenuItem ------------------------------ */
 static void
 glade_gtk_radio_menu_item_set_group (GObject *object, const GValue *value)
 {
@@ -6248,32 +6326,6 @@
 								  id, value);
 }
 
-void
-glade_gtk_menu_item_action_activate (GladeWidgetAdaptor *adaptor,
-				     GObject *object,
-				     const gchar *action_path)
-{
-	if (strcmp (action_path, "launch_editor") == 0)
-	{
-		GladeWidget *w = glade_widget_get_from_gobject (object);
-		
-		while ((w = glade_widget_get_parent (w)))
-		{
-			GObject *obj = glade_widget_get_object (w);
-			if (GTK_IS_MENU_SHELL (obj)) object = obj;
-		}
-		
-		if (GTK_IS_MENU_BAR (object))
-			glade_gtk_menu_shell_launch_editor (object, _("Edit Menu Bar"));
-		else if (GTK_IS_MENU (object))
-			glade_gtk_menu_shell_launch_editor (object, _("Edit Menu"));
-	}
-	else
-		GWA_GET_CLASS (GTK_TYPE_CONTAINER)->action_activate (adaptor,
-								     object,
-								     action_path);
-}
-
 /* ----------------------------- GtkMenuBar ------------------------------ */
 static GladeWidget * 
 glade_gtk_menu_bar_append_new_submenu (GladeWidget *parent, GladeProject *project)
@@ -6285,10 +6337,10 @@
 		submenu_adaptor = glade_widget_adaptor_get_by_type (GTK_TYPE_MENU);
 
 	gsubmenu = glade_widget_adaptor_create_widget (submenu_adaptor, FALSE,
-						     "parent", parent, 
-						     "project", project, 
-						     NULL);
-
+						       "parent", parent, 
+						       "project", project, 
+						       NULL);
+	
 	glade_widget_add_child (parent, gsubmenu, FALSE);
 
 	return gsubmenu;
@@ -6313,36 +6365,26 @@
 	if (label)
 	{
 		gitem = glade_widget_adaptor_create_widget ((use_stock) ? image_item_adaptor : item_adaptor,
-							  FALSE, "parent", parent,
-							  "project", project, 
-							  NULL);
+							    FALSE, "parent", parent,
+							    "project", project, 
+							    NULL);
 
 		glade_widget_property_set (gitem, "use-underline", TRUE);
 	
 		if (use_stock)
 		{
-			GEnumClass *eclass;
-			GEnumValue *eval;
-		
-			eclass = g_type_class_ref (GLADE_TYPE_STOCK);
-			eval = g_enum_get_value_by_nick (eclass, label);
-		
-			if (eval)
-				glade_widget_property_set (gitem, "stock", eval->value);
-		
-			g_type_class_unref (eclass);
+			glade_widget_property_set (gitem, "use-stock", TRUE);
+			glade_widget_property_set (gitem, "stock", label);
 		}
 		else
-		{
 			glade_widget_property_set (gitem, "label", label);
-		}
 	}
 	else
 	{
 		gitem = glade_widget_adaptor_create_widget (separator_adaptor,
-							  FALSE, "parent", parent,
-							  "project", project, 
-							  NULL);
+							    FALSE, "parent", parent,
+							    "project", project, 
+							    NULL);
 	}
 	
 	glade_widget_add_child (parent, gitem, FALSE);
@@ -6557,28 +6599,10 @@
 	glade_base_editor_add_default_properties (editor, gchild);
 	
 	glade_base_editor_add_label (editor, "Properties");
-	
-
 	glade_base_editor_add_editable (editor, gchild);
-/* 	glade_base_editor_add_properties (editor, gchild, FALSE, */
-/* 					  "visible-horizontal", */
-/* 					  "visible-vertical", */
-/* 					  NULL); */
 	
 	if (type == GTK_TYPE_SEPARATOR_TOOL_ITEM) return;
 
-/* 	if (GTK_IS_TOOL_BUTTON (child)) */
-/* 		glade_base_editor_add_properties (editor, gchild, FALSE, */
-/* 						  "label",  */
-/* 						  "icon", */
-/* 						  "stock-id", */
-/* 						  "icon-name", */
-/* 						  NULL); */
-	
-/* 	if (type == GTK_TYPE_RADIO_TOOL_BUTTON) */
-/* 		glade_base_editor_add_properties (editor, gchild, FALSE, */
-/* 						  "group", "active", NULL);	 */
-
 	glade_base_editor_add_label (editor, "Packing");
 	glade_base_editor_add_properties (editor, gchild, TRUE,
 					  "expand", "homogeneous", NULL);
@@ -6685,7 +6709,6 @@
 	return editable;
 }
 
-
 static void
 glade_gtk_tool_button_set_image_mode (GObject *object, const GValue *value)
 {

Modified: trunk/plugins/gtk+/glade-image-editor.c
==============================================================================
--- trunk/plugins/gtk+/glade-image-editor.c	(original)
+++ trunk/plugins/gtk+/glade-image-editor.c	Tue Oct 28 05:07:30 2008
@@ -119,12 +119,12 @@
 	}
 
 	/* load the embedded editable... */
-	glade_editable_load (GLADE_EDITABLE (image_editor->embed), widget);
+	if (image_editor->embed)
+		glade_editable_load (GLADE_EDITABLE (image_editor->embed), widget);
 
 	for (l = image_editor->properties; l; l = l->next)
 		glade_editor_property_load_by_widget (GLADE_EDITOR_PROPERTY (l->data), widget);
 
-
 	if (widget)
 	{
 		glade_widget_property_get (widget, "image-mode", &image_mode);
@@ -170,6 +170,10 @@
 
 	if (image_editor->properties)
 		g_list_free (image_editor->properties);
+	image_editor->properties = NULL;
+	image_editor->embed      = NULL;
+
+	glade_editable_load (GLADE_EDITABLE (object), NULL);
 
 	G_OBJECT_CLASS (glade_image_editor_parent_class)->finalize (object);
 }

Added: trunk/plugins/gtk+/glade-image-item-editor.c
==============================================================================
--- (empty file)
+++ trunk/plugins/gtk+/glade-image-item-editor.c	Tue Oct 28 05:07:30 2008
@@ -0,0 +1,411 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Tristan Van Berkom.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ *   Tristan Van Berkom <tvb gnome org>
+ */
+
+#include <config.h>
+#include <gladeui/glade.h>
+#include <glib/gi18n-lib.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "glade-image-item-editor.h"
+
+
+static void glade_image_item_editor_finalize        (GObject              *object);
+
+static void glade_image_item_editor_editable_init   (GladeEditableIface *iface);
+
+static void glade_image_item_editor_grab_focus      (GtkWidget            *widget);
+
+
+G_DEFINE_TYPE_WITH_CODE (GladeImageItemEditor, glade_image_item_editor, GTK_TYPE_VBOX,
+                         G_IMPLEMENT_INTERFACE (GLADE_TYPE_EDITABLE,
+                                                glade_image_item_editor_editable_init));
+
+
+static void
+glade_image_item_editor_class_init (GladeImageItemEditorClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+	object_class->finalize     = glade_image_item_editor_finalize;
+	widget_class->grab_focus   = glade_image_item_editor_grab_focus;
+}
+
+static void
+glade_image_item_editor_init (GladeImageItemEditor *self)
+{
+}
+
+static void
+project_changed (GladeProject      *project,
+		 GladeCommand      *command,
+		 gboolean           execute,
+		 GladeImageItemEditor *item_editor)
+{
+	if (item_editor->modifying ||
+	    !GTK_WIDGET_MAPPED (item_editor))
+		return;
+
+	/* Reload on all commands */
+	glade_editable_load (GLADE_EDITABLE (item_editor), item_editor->loaded_widget);
+}
+
+
+static void
+project_finalized (GladeImageItemEditor *item_editor,
+		   GladeProject       *where_project_was)
+{
+	item_editor->loaded_widget = NULL;
+
+	glade_editable_load (GLADE_EDITABLE (item_editor), NULL);
+}
+
+static GladeWidget *
+get_image_widget (GladeWidget *widget)
+{
+	GtkWidget *image;
+	image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (widget->object));
+	return image ? glade_widget_get_from_gobject (image) : NULL;
+}
+
+static void
+glade_image_item_editor_load (GladeEditable *editable,
+			       GladeWidget   *widget)
+{
+	GladeImageItemEditor     *item_editor = GLADE_IMAGE_ITEM_EDITOR (editable);
+	GladeWidget              *image_widget;
+	GList                    *l;
+	gboolean                  use_stock = FALSE;
+
+	item_editor->loading = TRUE;
+
+	/* Since we watch the project*/
+	if (item_editor->loaded_widget)
+	{
+		g_signal_handlers_disconnect_by_func (G_OBJECT (item_editor->loaded_widget->project),
+						      G_CALLBACK (project_changed), item_editor);
+
+		/* The widget could die unexpectedly... */
+		g_object_weak_unref (G_OBJECT (item_editor->loaded_widget->project),
+				     (GWeakNotify)project_finalized,
+				     item_editor);
+	}
+
+	/* Mark our widget... */
+	item_editor->loaded_widget = widget;
+
+	if (item_editor->loaded_widget)
+	{
+		/* This fires for undo/redo */
+		g_signal_connect (G_OBJECT (item_editor->loaded_widget->project), "changed",
+				  G_CALLBACK (project_changed), item_editor);
+
+		/* The widget/project could die unexpectedly... */
+		g_object_weak_ref (G_OBJECT (item_editor->loaded_widget->project),
+				   (GWeakNotify)project_finalized,
+				   item_editor);
+	}
+
+	/* load the embedded editable... */
+	if (item_editor->embed)
+		glade_editable_load (GLADE_EDITABLE (item_editor->embed), widget);
+
+	if (item_editor->embed_image) 
+	{
+		/* Finalize safe code here... */
+		if (widget && (image_widget = get_image_widget (widget)))
+			glade_editable_load (GLADE_EDITABLE (item_editor->embed_image), image_widget);
+		else
+			glade_editable_load (GLADE_EDITABLE (item_editor->embed_image), NULL);
+	}
+	for (l = item_editor->properties; l; l = l->next)
+		glade_editor_property_load_by_widget (GLADE_EDITOR_PROPERTY (l->data), widget);
+
+	if (widget)
+	{
+		glade_widget_property_get (widget, "use-stock", &use_stock);
+
+		gtk_widget_set_sensitive (item_editor->embed_frame, !use_stock);
+		gtk_widget_set_sensitive (item_editor->label_frame, !use_stock);
+
+		if (use_stock)
+			gtk_toggle_button_set_active
+				(GTK_TOGGLE_BUTTON (item_editor->stock_radio), TRUE);
+		else
+			gtk_toggle_button_set_active
+				(GTK_TOGGLE_BUTTON (item_editor->custom_radio), TRUE);
+	}
+	item_editor->loading = FALSE;
+}
+
+static void
+glade_image_item_editor_set_show_name (GladeEditable *editable,
+					gboolean       show_name)
+{
+	GladeImageItemEditor *item_editor = GLADE_IMAGE_ITEM_EDITOR (editable);
+
+	glade_editable_set_show_name (GLADE_EDITABLE (item_editor->embed), show_name);
+}
+
+static void
+glade_image_item_editor_editable_init (GladeEditableIface *iface)
+{
+	iface->load = glade_image_item_editor_load;
+	iface->set_show_name = glade_image_item_editor_set_show_name;
+}
+
+static void
+glade_image_item_editor_finalize (GObject *object)
+{
+	GladeImageItemEditor *item_editor = GLADE_IMAGE_ITEM_EDITOR (object);
+
+	if (item_editor->properties)
+		g_list_free (item_editor->properties);
+	item_editor->properties  = NULL;
+	item_editor->embed_image = NULL;
+	item_editor->embed       = NULL;
+
+	glade_editable_load (GLADE_EDITABLE (object), NULL);
+
+	G_OBJECT_CLASS (glade_image_item_editor_parent_class)->finalize (object);
+}
+
+static void
+glade_image_item_editor_grab_focus (GtkWidget *widget)
+{
+	GladeImageItemEditor *item_editor = GLADE_IMAGE_ITEM_EDITOR (widget);
+
+	gtk_widget_grab_focus (item_editor->embed);
+}
+
+
+
+static void
+stock_toggled (GtkWidget            *widget,
+	       GladeImageItemEditor *item_editor)
+{
+	GladeProperty     *property;
+	GladeWidget       *image;
+
+	if (item_editor->loading || !item_editor->loaded_widget)
+		return;
+
+	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (item_editor->stock_radio)))
+		return;
+
+	item_editor->modifying = TRUE;
+
+	glade_command_push_group (_("Setting %s to use a stock item"), item_editor->loaded_widget->name);
+
+	property = glade_widget_get_property (item_editor->loaded_widget, "label");
+	glade_command_set_property (property, NULL);
+	property = glade_widget_get_property (item_editor->loaded_widget, "use-underline");
+	glade_command_set_property (property, FALSE);
+
+	/* Delete image... */
+	if ((image = get_image_widget (item_editor->loaded_widget)) != NULL)
+	{
+		GList list = { 0, };
+		list.data = image;
+		glade_command_unprotect_widget (image);
+		glade_command_delete (&list);
+	}
+
+	property = glade_widget_get_property (item_editor->loaded_widget, "use-stock");
+	glade_command_set_property (property, TRUE);
+
+	glade_command_pop_group ();
+
+	item_editor->modifying = FALSE;
+
+	/* reload buttons and sensitivity and stuff... */
+	glade_editable_load (GLADE_EDITABLE (item_editor), 
+			     item_editor->loaded_widget);
+}
+
+static void
+custom_toggled (GtkWidget            *widget,
+		GladeImageItemEditor *item_editor)
+{
+	GladeProperty     *property;
+
+	if (item_editor->loading || !item_editor->loaded_widget)
+		return;
+
+	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (item_editor->custom_radio)))
+		return;
+
+	item_editor->modifying = TRUE;
+
+	glade_command_push_group (_("Setting %s to use a label and image"), item_editor->loaded_widget->name);
+
+	/* First clear stock...  */
+	property = glade_widget_get_property (item_editor->loaded_widget, "stock");
+	glade_command_set_property (property, NULL);
+	property = glade_widget_get_property (item_editor->loaded_widget, "use-stock");
+	glade_command_set_property (property, FALSE);
+
+	/* Now setup default label and create image... */
+	property = glade_widget_get_property (item_editor->loaded_widget, "label");
+	glade_command_set_property (property, item_editor->loaded_widget->adaptor->generic_name);
+	property = glade_widget_get_property (item_editor->loaded_widget, "use-underline");
+	glade_command_set_property (property, FALSE);
+
+	/* There shouldnt be an image widget here... */
+	if (!get_image_widget (item_editor->loaded_widget))
+	{
+		GladeWidget *image =
+			glade_command_create (glade_widget_adaptor_get_by_type (GTK_TYPE_IMAGE),
+					      item_editor->loaded_widget, NULL, 
+					      glade_widget_get_project (item_editor->loaded_widget));
+		gchar *protection = g_strdup_printf (_("Cannot delete %s because it is used by %s, "
+						       "try editing %s instead."),
+						       image->name, item_editor->loaded_widget->name,
+						       item_editor->loaded_widget->name);
+		glade_command_protect_widget (image, protection);
+		g_free (protection);
+	}
+	glade_command_pop_group ();
+
+	item_editor->modifying = FALSE;
+
+	/* reload buttons and sensitivity and stuff... */
+	glade_editable_load (GLADE_EDITABLE (item_editor), 
+			     item_editor->loaded_widget);
+}
+
+
+static void
+table_attach (GtkWidget *table, 
+	      GtkWidget *child, 
+	      gint pos, gint row)
+{
+	gtk_table_attach (GTK_TABLE (table), child,
+			  pos, pos+1, row, row +1,
+			  GTK_EXPAND | GTK_FILL,
+			  GTK_EXPAND | GTK_FILL,
+			  3, 1);
+}
+
+GtkWidget *
+glade_image_item_editor_new (GladeWidgetAdaptor *adaptor,
+			     GladeEditable      *embed)
+{
+	GladeImageItemEditor    *item_editor;
+	GladeEditorProperty     *eprop;
+	GtkWidget               *label, *alignment, *frame, *table, *vbox;
+	gchar                   *str;
+
+	g_return_val_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor), NULL);
+	g_return_val_if_fail (GLADE_IS_EDITABLE (embed), NULL);
+
+	item_editor = g_object_new (GLADE_TYPE_IMAGE_ITEM_EDITOR, NULL);
+	item_editor->embed = GTK_WIDGET (embed);
+
+	/* Pack the parent on top... */
+	gtk_box_pack_start (GTK_BOX (item_editor), GTK_WIDGET (embed), FALSE, FALSE, 0);
+
+	/* Put a stock property in a radio button (in a table) here on top... */
+	table = gtk_table_new (0, 0, FALSE);
+	gtk_box_pack_start (GTK_BOX (item_editor), table, FALSE, FALSE, 8);
+
+	eprop = glade_widget_adaptor_create_eprop_by_name (adaptor, "stock", FALSE, TRUE);
+	item_editor->stock_radio = gtk_radio_button_new (NULL);
+	gtk_container_add (GTK_CONTAINER (item_editor->stock_radio), eprop->item_label);
+	table_attach (table, item_editor->stock_radio, 0, 0);
+	table_attach (table, GTK_WIDGET (eprop), 1, 0);
+	item_editor->properties = g_list_prepend (item_editor->properties, eprop);
+
+	/* Now put a radio button in the same table for the custom image editing */
+	item_editor->custom_radio = gtk_radio_button_new_with_label_from_widget
+		(GTK_RADIO_BUTTON (item_editor->stock_radio),
+		 _("Custom label and image:"));
+	table_attach (table, item_editor->custom_radio, 0, 1);
+	vbox = gtk_vbox_new (FALSE, 0);
+	gtk_table_attach (GTK_TABLE (table), vbox,
+			  0, 2, /* left and right */ 
+			  2, 3, /* top and bottom */
+			  GTK_EXPAND | GTK_FILL,
+			  GTK_EXPAND | GTK_FILL,
+			  3, 6);
+
+	/* Label area frame... */
+	str = g_strdup_printf ("<b>%s</b>", _("Edit Label"));
+	label = gtk_label_new (str);
+	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+	g_free (str);
+	frame = gtk_frame_new (NULL);
+	gtk_frame_set_label_widget (GTK_FRAME (frame), label);
+	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
+	gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 12);
+	item_editor->label_frame = frame;
+
+	alignment = gtk_alignment_new (0.5F, 0.5F, 1.0F, 1.0F);
+	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 12, 0);
+	gtk_container_add (GTK_CONTAINER (frame), alignment);
+
+	table = gtk_table_new (0, 0, FALSE);
+	gtk_container_add (GTK_CONTAINER (alignment), table);
+
+	/* The menu label... */
+	eprop = glade_widget_adaptor_create_eprop_by_name (adaptor, "label", FALSE, TRUE);
+	table_attach (table, eprop->item_label, 0, 0);
+	table_attach (table, GTK_WIDGET (eprop), 1, 0);
+	item_editor->properties = g_list_prepend (item_editor->properties, eprop);
+
+	/* Whether to use-underline... */
+	eprop = glade_widget_adaptor_create_eprop_by_name (adaptor, "use-underline", FALSE, TRUE);
+	table_attach (table, eprop->item_label, 0, 1);
+	table_attach (table, GTK_WIDGET (eprop), 1, 1);
+	item_editor->properties = g_list_prepend (item_editor->properties, eprop);
+
+	/* Internal Image area... */
+	str = g_strdup_printf ("<b>%s</b>", _("Edit Image"));
+	label = gtk_label_new (str);
+	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+	g_free (str);
+	frame = gtk_frame_new (NULL);
+	gtk_frame_set_label_widget (GTK_FRAME (frame), label);
+	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
+	gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 12);
+	item_editor->embed_frame = frame;
+
+	alignment = gtk_alignment_new (0.5F, 0.5F, 1.0F, 1.0F);
+	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 12, 0);
+	gtk_container_add (GTK_CONTAINER (frame), alignment);
+
+	item_editor->embed_image = (GtkWidget *)glade_widget_adaptor_create_editable 
+		(glade_widget_adaptor_get_by_type (GTK_TYPE_IMAGE), GLADE_PAGE_GENERAL);
+	glade_editable_set_show_name (GLADE_EDITABLE (item_editor->embed_image), FALSE);
+	gtk_container_add (GTK_CONTAINER (alignment), item_editor->embed_image);
+
+	/* Now hook up to our signals... */
+	g_signal_connect (G_OBJECT (item_editor->stock_radio), "toggled",
+			  G_CALLBACK (stock_toggled), item_editor);
+	g_signal_connect (G_OBJECT (item_editor->custom_radio), "toggled",
+			  G_CALLBACK (custom_toggled), item_editor);
+
+
+	gtk_widget_show_all (GTK_WIDGET (item_editor));
+
+	return GTK_WIDGET (item_editor);
+}

Added: trunk/plugins/gtk+/glade-image-item-editor.h
==============================================================================
--- (empty file)
+++ trunk/plugins/gtk+/glade-image-item-editor.h	Tue Oct 28 05:07:30 2008
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Tristan Van Berkom.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ *   Tristan Van Berkom <tvb gnome org>
+ */
+#ifndef _GLADE_IMAGE_BUTTON_EDITOR_H_
+#define _GLADE_IMAGE_BUTTON_EDITOR_H_
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GLADE_TYPE_IMAGE_ITEM_EDITOR	            (glade_image_item_editor_get_type ())
+#define GLADE_IMAGE_ITEM_EDITOR(obj)		    (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_IMAGE_ITEM_EDITOR, GladeImageItemEditor))
+#define GLADE_IMAGE_ITEM_EDITOR_CLASS(klass)	    (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_IMAGE_ITEM_EDITOR, GladeImageItemEditorClass))
+#define GLADE_IS_IMAGE_ITEM_EDITOR(obj)	    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_IMAGE_ITEM_EDITOR))
+#define GLADE_IS_IMAGE_ITEM_EDITOR_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_IMAGE_ITEM_EDITOR))
+#define GLADE_IMAGE_ITEM_EDITOR_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_TYPE_IMAGE_ITEM_EDITOR, GladeImageItemEditorClass))
+
+typedef struct _GladeImageItemEditor        GladeImageItemEditor;
+typedef struct _GladeImageItemEditorClass   GladeImageItemEditorClass;
+
+struct _GladeImageItemEditor
+{
+	GtkVBox  parent;
+
+	GladeWidget *loaded_widget; /* A handy pointer to the loaded widget ... */
+
+	GtkWidget *embed;           /* Embedded parent class editor */
+	GtkWidget *embed_image;     /* Embedded GladeEditable for the image */
+
+	GtkWidget *stock_radio;     /* Use a stock-item for the menu */
+	GtkWidget *custom_radio;    /* Set a widget to be placed as the image item's label */
+	GtkWidget *embed_frame;     /* Use to set the whole image area insensitive */
+	GtkWidget *label_frame;     /* Use to set the whole custom label area insensitive */
+
+	GList *properties;         /* A list of eprops to update at load() time */
+
+	gboolean loading;          /* Loading flag for loading widgets in the editor */
+	gboolean modifying;        /* Flag for monitoring project changes */
+};
+
+struct _GladeImageItemEditorClass
+{
+	GtkVBoxClass parent;
+};
+
+GType            glade_image_item_editor_get_type (void);
+GtkWidget       *glade_image_item_editor_new      (GladeWidgetAdaptor *adaptor,
+						   GladeEditable      *editable);
+
+G_END_DECLS
+
+#endif  /* _GLADE_IMAGE_ITEM_EDITOR_H_ */

Modified: trunk/plugins/gtk+/glade-tool-button-editor.c
==============================================================================
--- trunk/plugins/gtk+/glade-tool-button-editor.c	(original)
+++ trunk/plugins/gtk+/glade-tool-button-editor.c	Tue Oct 28 05:07:30 2008
@@ -118,7 +118,8 @@
 	}
 
 	/* load the embedded editable... */
-	glade_editable_load (GLADE_EDITABLE (button_editor->embed), widget);
+	if (button_editor->embed)
+		glade_editable_load (GLADE_EDITABLE (button_editor->embed), widget);
 
 	for (l = button_editor->properties; l; l = l->next)
 		glade_editor_property_load_by_widget (GLADE_EDITOR_PROPERTY (l->data), widget);
@@ -383,6 +384,10 @@
 
 	if (button_editor->properties)
 		g_list_free (button_editor->properties);
+	button_editor->properties = NULL;
+	button_editor->embed      = NULL;
+
+	glade_editable_load (GLADE_EDITABLE (object), NULL);
 
 	G_OBJECT_CLASS (glade_tool_button_editor_parent_class)->finalize (object);
 }

Modified: trunk/plugins/gtk+/glade-tool-button-editor.h
==============================================================================
--- trunk/plugins/gtk+/glade-tool-button-editor.h	(original)
+++ trunk/plugins/gtk+/glade-tool-button-editor.h	Tue Oct 28 05:07:30 2008
@@ -78,4 +78,4 @@
 
 G_END_DECLS
 
-#endif  /* _GLADE_BUTTON_EDITOR_H_ */
+#endif  /* _GLADE_TOOL_BUTTON_EDITOR_H_ */

Modified: trunk/plugins/gtk+/gtk+.xml.in
==============================================================================
--- trunk/plugins/gtk+/gtk+.xml.in	(original)
+++ trunk/plugins/gtk+/gtk+.xml.in	Tue Oct 28 05:07:30 2008
@@ -372,12 +372,12 @@
         <action id="launch_editor" _name="Edit&#8230;" stock="gtk-edit" important="True"/>
       </actions>
       <properties>
-        <property id="submenu" since="2.12" disabled="True"/>
         <property id="label" _name="Label" translatable="True">
 	  <_tooltip>The text of the menu item</_tooltip>
           <spec>glade_standard_string_spec</spec>
         </property>
         <property id="use-underline" _name="Use Underline">
+	  <_tooltip>If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key</_tooltip>
           <spec>glade_standard_boolean_spec</spec>
         </property>
 	<!-- Atk click property -->
@@ -386,12 +386,36 @@
 	  <spec>glade_standard_string_spec</spec>
 	  <visible-lines>2</visible-lines>
 	</property>
+        <property id="submenu" since="2.12" disabled="True"/>
+      </properties>
+    </glade-widget-class>
+
+    <glade-widget-class name="GtkImageMenuItem" generic-name="imagemenuitem" _title="Image Menu Item">
+      <read-widget-function>glade_gtk_image_menu_item_read_widget</read-widget-function>
+      <read-child-function>glade_gtk_image_menu_item_read_child</read-child-function>
+      <write-child-function>glade_gtk_image_menu_item_write_child</write-child-function>
+      <set-property-function>glade_gtk_image_menu_item_set_property</set-property-function>
+      <get-children-function>glade_gtk_image_menu_item_get_children</get-children-function>
+      <add-child-function>glade_gtk_image_menu_item_add_child</add-child-function>
+      <remove-child-function>glade_gtk_image_menu_item_remove_child</remove-child-function>
+      <create-editable-function>glade_gtk_image_menu_item_create_editable</create-editable-function>
+      <properties>
+        <property id="use-stock" visible="False">
+	  <spec>glade_standard_boolean_spec</spec>
+        </property>
+	<property id="stock" stock="True" _name="Stock Item" save="False" custom-layout="True">
+	  <_tooltip>The stock item for this menu item</_tooltip>
+	  <spec>glade_standard_string_spec</spec>
+	</property>
+        <property id="label" custom-layout="True"/>
+        <property id="use-underline" custom-layout="True"/>
+	<property id="image" disabled="True" />
 	<!--
 	This property is added by glade2 gnome support and makes reference to
-	GNOMEUIINFO_MENU_* macros. The set-property-function maps these properties to 
-	existing non deprecated gtk ones
+	GNOMEUIINFO_MENU_* macros. The read-widget-funcion maps these properties to 
+	existing non deprecated gtk ones at load time.
 	-->
-        <property id="stock-item" visible="False" save="False">
+        <property id="stock-item" ignore="True" visible="False" save="False">
           <spec>glade_gtk_gnome_ui_info_spec</spec>
         </property>
       </properties>
@@ -407,25 +431,10 @@
       </properties>
     </glade-widget-class>
 
-    <glade-widget-class name="GtkImageMenuItem" generic-name="imagemenuitem" _title="Image Menu Item">
-      <get-internal-child-function>glade_gtk_image_menu_item_get_internal_child</get-internal-child-function>
-      <set-property-function>glade_gtk_image_menu_item_set_property</set-property-function>
-      <properties>
-        <property id="use-stock" visible="False">
-	  <spec>glade_standard_boolean_spec</spec>
-        </property>
-	<property id="stock" _name="Stock Item" save="False">
-	  <_tooltip>A stock item, select None to choose a custom image and label</_tooltip>
-	  <spec>glade_standard_stock_spec</spec>
-	</property>
-	<property id="image" disabled="True" />
-      </properties>
-    </glade-widget-class>
-
     <glade-widget-class name="GtkSeparatorMenuItem" generic-name="separatormenuitem" _title="Separator Menu Item">
       <properties>
-        <property id="label" visible="False"/>
-        <property id="use-underline" visible="False"/>
+        <property id="label" disabled="True"/>
+        <property id="use-underline" disabled="True"/>
       </properties>
     </glade-widget-class>
 



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