Hello, this patch adds radio menu item support altough you can not set
the group.
It also fixes the order of menu items using a position property :)
The menu editor is not modal any more so I will need help to find new
glitches.

Greetings

Juan Pablo


Index: src/glade-gtk.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-gtk.c,v
retrieving revision 1.90
diff -u -r1.90 glade-gtk.c
--- src/glade-gtk.c	15 Dec 2005 03:57:19 -0000	1.90
+++ src/glade-gtk.c	27 Dec 2005 20:51:19 -0000
@@ -1906,6 +1906,94 @@
 
 /* GtkMenu Support */
 
+void GLADEGTK_API
+glade_gtk_menu_shell_add_item (GObject *object, GObject *child)
+{
+	
+	g_return_if_fail (GTK_IS_MENU_SHELL (object));
+	g_return_if_fail (GTK_IS_MENU_ITEM (child));
+
+	gtk_menu_shell_append (GTK_MENU_SHELL (object), GTK_WIDGET (child));
+}
+
+
+void GLADEGTK_API
+glade_gtk_menu_shell_remove_item (GObject *object, GObject *child)
+{
+	g_return_if_fail (GTK_IS_MENU_SHELL (object));
+	g_return_if_fail (GTK_IS_MENU_ITEM (child));
+	
+	gtk_container_remove (GTK_CONTAINER (object), GTK_WIDGET (child));
+}
+
+static gint
+glade_gtk_menu_shell_get_item_position (GObject *container, GObject *child)
+{
+	gint position = 0;
+	GList *list = GTK_MENU_SHELL (container)->children;
+	
+	while (list)
+	{
+		if (G_OBJECT (list->data) == child) break;
+		
+		list = list->next;
+		position++;
+	}
+	
+	return position;
+}
+
+void GLADEGTK_API
+glade_gtk_menu_shell_get_child_property (GObject *container,
+					 GObject *child,
+					 const gchar *property_name,
+					 GValue *value)
+{
+	gint position;
+	
+	g_return_if_fail (GTK_IS_MENU_SHELL (container));
+	g_return_if_fail (GTK_IS_MENU_ITEM (child));
+	
+	if (strcmp (property_name, "position")) return;
+		
+	position = glade_gtk_menu_shell_get_item_position (container, child);
+	
+	g_value_set_int (value, position);
+	
+}
+
+void GLADEGTK_API
+glade_gtk_menu_shell_set_child_property (GObject *container,
+					 GObject *child,
+					 const gchar *property_name,
+					 GValue *value)
+{
+	GladeWidget *gitem;
+	gint position;
+	
+	g_return_if_fail (GTK_IS_MENU_SHELL (container));
+	g_return_if_fail (GTK_IS_MENU_ITEM (child));
+	
+	if (strcmp (property_name, "position")) return;
+		
+	gitem = glade_widget_get_from_gobject (child);
+	g_return_if_fail (GLADE_IS_WIDGET (gitem));
+	
+	position = g_value_get_int (value);
+	
+	if (position < 0)
+	{
+		position = glade_gtk_menu_shell_get_item_position (container, child);
+		glade_widget_property_set (gitem, "position", position);
+		return;
+	}
+	
+	g_object_ref (child);
+	gtk_container_remove (GTK_CONTAINER (container), GTK_WIDGET (child));
+	gtk_menu_shell_insert (GTK_MENU_SHELL (container), GTK_WIDGET (child), position);
+	g_object_unref (child);
+}
+
 GList * GLADEGTK_API
 glade_gtk_menu_item_get_submenu (GObject *object)
 {
@@ -1945,27 +2033,54 @@
 	gtk_menu_item_remove_submenu (GTK_MENU_ITEM (object));
 }
 
-void GLADEGTK_API
-glade_gtk_menu_add_item (GObject *object, GObject *child)
+#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_radio_menu_item_group_changed (GladeProperty *prop,
+					 GValue *value,
+					 GladeProject *project)
 {
-	g_return_if_fail (GTK_IS_MENU (object));
-	g_return_if_fail (GTK_IS_MENU_ITEM (child));
+	const gchar *name;
 
-	gtk_menu_shell_append (GTK_MENU_SHELL (object), GTK_WIDGET (child));
-}
+	if ((name = g_value_get_string (value)) == NULL)
+		return;
+	
+	if (glade_project_get_widget_by_name (project, name) == NULL)
+	{
+		GValue val = {0, };
+		
+		g_value_init (&val, G_TYPE_STRING);
+		g_value_set_string (&val, NULL);
+		glade_property_set_value (prop, &val);
+	}
 
-void GLADEGTK_API
-glade_gtk_menu_remove_item (GObject *object, GObject *child)
+}
+	
+static gboolean 
+glade_gtk_radio_menu_item_load_idle (gpointer data)
 {
-	g_return_if_fail (GTK_IS_MENU (object));
-	g_return_if_fail (GTK_IS_MENU_ITEM (child));
+	GladeProject *project;
+	GladeProperty *prop;
+	gboolean changed;
+	gchar *name;
+		
+	project = glade_widget_get_project (data);
+	changed = project->changed;
+	
+	prop = glade_widget_get_property (data, "group");
+	g_signal_connect (prop, "value_changed",
+			  G_CALLBACK (glade_gtk_radio_menu_item_group_changed),
+			  project);
+	
+	glade_widget_property_get (data, "group", &name);
+	glade_widget_property_set (data, "group", name);
 
-	gtk_container_remove (GTK_CONTAINER (object), GTK_WIDGET (child));
+	project->changed = changed;
+	
+	return FALSE;
 }
 
-#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)))
-	
 void GLADEGTK_API
 glade_gtk_menu_item_post_create (GObject *object, GladeCreateReason reason)
 {
@@ -2015,6 +2130,10 @@
 			}
 		}
 	}
+	if (GTK_IS_RADIO_MENU_ITEM (object) && reason == GLADE_CREATE_LOAD)
+	{
+		g_idle_add (glade_gtk_radio_menu_item_load_idle, gitem);
+	}
 }
 
 void GLADEGTK_API
@@ -2182,25 +2301,6 @@
 
 /* GtkMenuBar */
 
-void GLADEGTK_API
-glade_gtk_menu_bar_add_item (GObject *object, GObject *child)
-{
-	g_return_if_fail (GTK_IS_MENU_BAR (object));
-	g_return_if_fail (GTK_IS_MENU_ITEM (child));
-
-	gtk_menu_shell_append (GTK_MENU_SHELL (object), GTK_WIDGET (child));
-}
-
-
-void GLADEGTK_API
-glade_gtk_menu_bar_remove_item (GObject *object, GObject *child)
-{
-	g_return_if_fail (GTK_IS_MENU_BAR (object));
-	g_return_if_fail (GTK_IS_MENU_ITEM (child));
-	
-	gtk_container_remove (GTK_CONTAINER (object), GTK_WIDGET (child));
-}
-
 static GladeWidget * 
 glade_gtk_menu_bar_append_new_submenu (GladeWidget *parent, GladeProject *project)
 {
@@ -2300,6 +2400,7 @@
 struct _GladeGtkMenuEditor
 {
 	GtkWidget *window, *popup, *table, *child_table, *treeview;
+	GtkWidget *remove_button, *undo_button, *redo_button;
 	GtkTreeStore *store;
 	GladeWidget *gmenubar;
 	GladeSignalEditor *signal_editor;
@@ -2307,7 +2408,7 @@
 	
 	/* Temporal variables used in idle functions */
 	GtkTreeIter iter;
-	gboolean row_inserted;
+	gboolean row_inserted, not_reordering_row;
 };
 
 static const gchar *
@@ -2322,6 +2423,9 @@
 		
 	if (type == GTK_TYPE_CHECK_MENU_ITEM)
 		return _("Check");
+
+	if (type == GTK_TYPE_RADIO_MENU_ITEM)
+		return _("Radio");
 	
 	if (type == GTK_TYPE_SEPARATOR_MENU_ITEM)
 		return _("Separator");
@@ -2423,6 +2527,12 @@
 				    GLADEGTK_MENU_ITEM_CLASS, glade_widget_class_get_by_type (GTK_TYPE_CHECK_MENU_ITEM),
 				    GLADEGTK_MENU_ITEM_NAME, glade_gtk_menu_editor_type_name (GTK_TYPE_CHECK_MENU_ITEM),
 				    -1);
+
+		gtk_list_store_append (store, &iter);
+		gtk_list_store_set (store, &iter,
+				    GLADEGTK_MENU_ITEM_CLASS, glade_widget_class_get_by_type (GTK_TYPE_RADIO_MENU_ITEM),
+				    GLADEGTK_MENU_ITEM_NAME, glade_gtk_menu_editor_type_name (GTK_TYPE_RADIO_MENU_ITEM),
+				    -1);
 		
 		gtk_list_store_append (store, &iter);
 		gtk_list_store_set (store, &iter,
@@ -2607,12 +2717,15 @@
 }
 
 static void
-glade_gtk_menu_editor_clear_properties (GladeGtkMenuEditor *e)
+glade_gtk_menu_editor_clear (GladeGtkMenuEditor *e)
 {
 	gtk_container_foreach (GTK_CONTAINER (e->table),
 			       glade_gtk_menu_editor_remove_widget, e->table);
 	gtk_container_foreach (GTK_CONTAINER (e->child_table),
 			       glade_gtk_menu_editor_remove_widget, e->child_table);
+
+	gtk_widget_set_sensitive (e->remove_button, FALSE);
+	glade_signal_editor_load_widget (e->signal_editor, NULL);
 }
 
 static void
@@ -2632,7 +2745,8 @@
 	if (! glade_gtk_menu_editor_get_item_selected (e, &iter))
 		return;
 
-	glade_gtk_menu_editor_clear_properties (e);
+	glade_gtk_menu_editor_clear (e);
+	gtk_widget_set_sensitive (e->remove_button, TRUE);
 	
 	gtk_tree_model_get (GTK_TREE_MODEL (e->store), &iter,
 			    GLADEGTK_MENU_GWIDGET, &gitem,
@@ -2728,14 +2842,25 @@
 		eprop = glade_editor_property_new_from_widget (gitem, "active", TRUE);
 		if (eprop)
 			glade_gtk_menu_editor_table_attach (e->table, eprop->eventbox, GTK_WIDGET (eprop), &row);
-		
-		eprop = glade_editor_property_new_from_widget (gitem, "draw-as-radio", TRUE);
-		if (eprop)
-			glade_gtk_menu_editor_table_attach (e->table, eprop->eventbox, GTK_WIDGET (eprop), &row);
 	
-		eprop = glade_editor_property_new_from_widget (gitem, "inconsistent", TRUE);
-		if (eprop)
-			glade_gtk_menu_editor_table_attach (e->table, eprop->eventbox, GTK_WIDGET (eprop), &row);
+		if (GTK_IS_RADIO_MENU_ITEM (item))
+		{
+			/* Coming Soon...
+			eprop = glade_editor_property_new_from_widget (gitem, "group", TRUE);
+			if (eprop)
+				glade_gtk_menu_editor_table_attach (e->table, eprop->eventbox, GTK_WIDGET (eprop), &row);
+			*/
+		}
+		else
+		{
+			eprop = glade_editor_property_new_from_widget (gitem, "draw-as-radio", TRUE);
+			if (eprop)
+				glade_gtk_menu_editor_table_attach (e->table, eprop->eventbox, GTK_WIDGET (eprop), &row);
+	
+			eprop = glade_editor_property_new_from_widget (gitem, "inconsistent", TRUE);
+			if (eprop)
+				glade_gtk_menu_editor_table_attach (e->table, eprop->eventbox, GTK_WIDGET (eprop), &row);
+		}
 	}
 	
 	/* Update Signal Editor*/
@@ -2750,23 +2875,23 @@
 					GtkTreeModel *model,
 					GtkTreeIter *child)
 {
-	GObject *item;
+	GladeWidget *gitem;
 	GtkTreeIter parent, iter;
-
+        GValue val = {0, };
+	gint position = 0;
+	
 	if (gtk_tree_model_iter_parent (model, &parent, child))
 		gtk_tree_model_iter_children (model, &iter, &parent);
 	else
 		gtk_tree_model_get_iter_first (model, &iter);
 	
+        g_value_init (&val, G_TYPE_INT);
+
 	do
 	{
-		gtk_tree_model_get (model, &iter, GLADEGTK_MENU_OBJECT, &item, -1);
-		
-		g_object_ref (item);
-		gtk_container_remove (GTK_CONTAINER (menushell), GTK_WIDGET (item));
-		gtk_container_add (GTK_CONTAINER (menushell), GTK_WIDGET (item));
-		g_object_unref (item);
-		
+		gtk_tree_model_get (model, &iter, GLADEGTK_MENU_GWIDGET, &gitem, -1);
+                g_value_set_int (&val, position++);
+                glade_command_set_property (glade_widget_get_property (gitem, "position"), &val);
 	} while (gtk_tree_model_iter_next (model, &iter));
 }
 
@@ -2778,7 +2903,7 @@
 {
 	GladeWidget *parent, *gitem, *gitem_new;
 	GObject *item, *item_new;
-	gchar *name, *label, *tooltip;
+	gchar *name, *label, *tooltip, *desc;
 	GtkWidget *submenu;
 	GList list = {0, };
 	
@@ -2792,6 +2917,12 @@
 	parent = glade_widget_get_parent (gitem);
 	name = g_strdup (glade_widget_get_name (gitem));
 	submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (item));
+
+	/* Start of glade-command */
+	desc = g_strdup_printf (_("Setting menu item type on %s to %s"),
+				name, klass_name);
+	glade_command_push_group (desc);
+	g_free (desc);
 	
 	/* Create new widget */
 	gitem_new = glade_command_create (klass, parent, NULL, e->project);
@@ -2845,6 +2976,9 @@
 	g_free (name);
 	g_free (label);
 	g_free (tooltip);
+	
+	/* End of glade-command */
+	glade_command_pop_group ();
 }
 
 static void
@@ -2912,19 +3046,25 @@
 }
 
 static void
-glade_gtk_menu_editor_reorder (GtkTreeModel *model, GtkTreeIter *iter)
+glade_gtk_menu_editor_reorder (GladeGtkMenuEditor *e, GtkTreeIter *iter)
 {
 	GladeWidget *gitem, *gparent;
-	GtkTreeIter parent_iter, child;
+	GtkTreeIter parent_iter;
 	GObject *parent;
 	GList list = {0, };
+	gchar *desc;
 	
-	gtk_tree_model_get (model, iter, GLADEGTK_MENU_GWIDGET, &gitem, -1);
+	desc = g_strdup_printf (_("Reorder %s's children"),
+				glade_widget_get_name (e->gmenubar));
+	glade_command_push_group (desc);
+	g_free (desc);
 	
-	if (gtk_tree_model_iter_parent (model, &parent_iter, iter))
+	gtk_tree_model_get (GTK_TREE_MODEL (e->store), iter, GLADEGTK_MENU_GWIDGET, &gitem, -1);
+	
+	if (gtk_tree_model_iter_parent (GTK_TREE_MODEL (e->store), &parent_iter, iter))
 	{
 		GtkWidget *submenu;
-		gtk_tree_model_get (model, &parent_iter,
+		gtk_tree_model_get (GTK_TREE_MODEL (e->store), &parent_iter,
 				    GLADEGTK_MENU_OBJECT, &parent,
 				    GLADEGTK_MENU_GWIDGET, &gparent, -1);
 
@@ -2932,37 +3072,34 @@
 			gparent = glade_widget_get_from_gobject (submenu);
 		else
 			gparent = glade_command_create (glade_widget_class_get_by_type (GTK_TYPE_MENU),
-							gparent, NULL, glade_widget_get_project (gparent));
+							gparent, NULL, e->project);
 	}
 	else
 		gparent = glade_widget_get_parent (gitem);
-	
-	do
-	{
-		gtk_tree_model_get (model, iter, GLADEGTK_MENU_GWIDGET, &gitem, -1);
-		list.data = gitem;
-		
-		glade_command_cut (&list);
-		glade_command_paste (&list, gparent, NULL);
-		
-	} while (gtk_tree_model_iter_next (model, iter));
 
-	if (gtk_tree_model_iter_children (model, &child, iter))
-		glade_gtk_menu_editor_reorder (model, &child);
+	list.data = gitem;
+	glade_command_cut (&list);
+	glade_command_paste (&list, gparent, NULL);
+
+	glade_gtk_menu_editor_reorder_children (GTK_WIDGET (glade_widget_get_object (gparent)),
+						GTK_TREE_MODEL (e->store), iter);
+
+	glade_command_pop_group ();
 }
 
 static gboolean 
 glade_gtk_menu_editor_drag_and_drop_idle (gpointer data)
 {
 	GladeGtkMenuEditor *e = (GladeGtkMenuEditor *) data;
-	GtkTreeIter iter, first_child;
+	
+	e->not_reordering_row = FALSE;
 
-	if (gtk_tree_model_iter_parent (GTK_TREE_MODEL (e->store), &iter, &e->iter))
-		gtk_tree_model_iter_children (GTK_TREE_MODEL (e->store), &first_child, &iter);
-	else
-		gtk_tree_model_get_iter_first (GTK_TREE_MODEL (e->store), &first_child);
+	glade_gtk_menu_editor_reorder (e, &e->iter);
+	glade_gtk_menu_editor_clear (e);
+	
+	e->row_inserted = FALSE;
 	
-	glade_gtk_menu_editor_reorder (GTK_TREE_MODEL (e->store), &first_child);
+	e->not_reordering_row = TRUE;
 
 	return FALSE;
 }
@@ -2973,8 +3110,11 @@
 				    GtkTreeIter *iter,
 				    GladeGtkMenuEditor *e)
 {
-	e->row_inserted = TRUE;
-	e->iter = *iter;
+	if (! e->row_inserted)
+	{
+		e->iter = *iter;
+		e->row_inserted = TRUE;
+	}
 }
 
 static void
@@ -2983,10 +3123,7 @@
 				   GladeGtkMenuEditor *e)
 {
 	if (e->row_inserted)
-	{
-		e->row_inserted = FALSE;
 		g_idle_add (glade_gtk_menu_editor_drag_and_drop_idle, e);
-	}
 }
 
 static void
@@ -2998,6 +3135,11 @@
 	GladeWidget *gparent, *gitem_new;
 	GValue val = {0, };
 	const gchar *name;
+	gchar *desc;
+
+	desc = g_strdup_printf (_("Create a %s item"), glade_gtk_menu_editor_type_name (type));
+	glade_command_push_group (desc);
+	g_free (desc);
 
 	gparent = e->gmenubar;
 	
@@ -3030,7 +3172,10 @@
 		gtk_tree_store_append (GTK_TREE_STORE (e->store), &new_iter, NULL);
 	
 	if (GTK_IS_SEPARATOR_MENU_ITEM (glade_widget_get_object (gparent)))
+	{
+		glade_command_pop_group ();
 		return;
+	}
 	
 	gitem_new = glade_command_create (glade_widget_class_get_by_type (type),
 					  gparent, NULL, e->project);
@@ -3046,7 +3191,7 @@
 		g_value_set_string (&val, name);
 		glade_command_set_property (glade_widget_get_property (gitem_new, "label"), &val);
 	}		
-		
+	
 	gtk_tree_store_set (GTK_TREE_STORE (e->store), &new_iter, 
 			    GLADEGTK_MENU_GWIDGET, gitem_new,
 			    GLADEGTK_MENU_OBJECT, glade_widget_get_object (gitem_new),
@@ -3058,6 +3203,9 @@
 	glade_gtk_menu_editor_reorder_children (GTK_WIDGET (glade_widget_get_object (gparent)),
 						GTK_TREE_MODEL (e->store),
 						&new_iter);
+
+	glade_command_pop_group ();
+	
 	/* This flags is used to know if the row was inserted by drag and drop */
 	e->row_inserted = FALSE;
 }
@@ -3097,7 +3245,7 @@
 		gtk_tree_store_remove (e->store, &iter);
 		glade_command_delete (&list);
 		
-		glade_gtk_menu_editor_clear_properties (e);
+		glade_gtk_menu_editor_clear (e);
 	}
 }
 
@@ -3142,6 +3290,146 @@
 	gtk_widget_destroy (dialog);
 }
 
+static void
+glade_gtk_menu_editor_find_child_real (GladeGtkMenuEditor *e,
+				       GladeWidget *child,
+				       GtkTreeIter *iter,
+				       gboolean select)
+{
+	GtkTreeModel *model = GTK_TREE_MODEL (e->store);
+	GtkTreeIter parent;
+	GladeWidget *item;
+	
+	do
+	{
+		gtk_tree_model_get (model, iter, GLADEGTK_MENU_GWIDGET, &item, -1);
+	
+		if (item == child)
+		{
+			if (select)
+			{
+				GtkTreePath *path = gtk_tree_model_get_path (model, iter);
+				gtk_tree_view_set_cursor (GTK_TREE_VIEW (e->treeview), path, NULL, FALSE);
+				gtk_tree_path_free (path);
+			}
+			return;
+		}
+	}
+	while (gtk_tree_model_iter_next (model, iter));
+	
+	if (gtk_tree_model_iter_children (model, iter, &parent))
+		glade_gtk_menu_editor_find_child_real (e, child, &parent, select);
+	
+	return;
+}
+
+static void
+glade_gtk_menu_editor_select_child (GladeGtkMenuEditor *e,
+				    GladeWidget *child)
+{
+	GtkTreeModel *model = GTK_TREE_MODEL (e->store);
+	GtkTreeIter iter;
+	
+	gtk_tree_model_get_iter_first (model, &iter);
+	
+	glade_gtk_menu_editor_find_child_real (e, child, &iter, TRUE);
+}
+
+static gboolean
+glade_gtk_menu_editor_is_child (GladeGtkMenuEditor *e, GladeWidget *item)
+{
+	while ((item = glade_widget_get_parent (item)))
+		if (item == e->gmenubar) return TRUE;
+
+	return FALSE;
+}
+
+static gboolean
+glade_gtk_menu_editor_update_treeview_idle (gpointer data)
+{
+	GladeGtkMenuEditor *e = (GladeGtkMenuEditor *) data;
+	GList *selection = glade_project_selection_get (e->project);
+	GladeWidget *widget;
+	
+	gtk_tree_store_clear (e->store);
+	glade_gtk_menu_editor_fill_store (GTK_WIDGET (glade_widget_get_object (e->gmenubar)),
+					  e->store, NULL);
+	glade_gtk_menu_editor_clear (e);
+	e->row_inserted = FALSE;
+
+	if (selection)
+	{
+		widget = glade_widget_get_from_gobject (G_OBJECT (selection->data)); 
+		if (glade_gtk_menu_editor_is_child (e, widget))
+			glade_gtk_menu_editor_select_child (e, widget);
+	}
+
+	return FALSE;
+}
+
+static void
+glade_gtk_menu_editor_project_remove_widget (GladeProject *project,
+					     GladeWidget  *widget,
+					     GladeGtkMenuEditor *e)
+{
+	if (widget == e->gmenubar)
+	{
+		gtk_widget_destroy (e->window);
+		return;
+	}
+	
+	if (glade_gtk_menu_editor_is_child (e, widget) && e->not_reordering_row)
+		g_idle_add (glade_gtk_menu_editor_update_treeview_idle, e);
+
+}
+
+static void
+glade_gtk_menu_editor_project_add_widget (GladeProject *project,
+					  GladeWidget  *widget,
+					  GladeGtkMenuEditor *e)
+{
+	if (glade_gtk_menu_editor_is_child (e, widget) && e->not_reordering_row)
+		g_idle_add (glade_gtk_menu_editor_update_treeview_idle, e);
+
+}
+
+static void
+glade_gtk_menu_editor_project_widget_name_changed (GladeProject *project,
+						   GladeWidget  *widget,
+						   GladeGtkMenuEditor *e)
+{
+	glade_gtk_menu_editor_select_child (e, widget);
+}
+
+static void
+glade_gtk_menu_editor_project_weak_notify (gpointer data, GObject *object)
+{
+	GladeGtkMenuEditor *e = (GladeGtkMenuEditor *) data;
+	gtk_widget_destroy (GTK_WIDGET (e->window));
+	e->project = NULL;
+}
+
+static void
+glade_gtk_menu_editor_destroyed (GtkWidget *window, GladeGtkMenuEditor *e)
+{
+	g_signal_handlers_disconnect_by_func (e->project,
+					      glade_gtk_menu_editor_project_remove_widget,
+					      e);
+	g_signal_handlers_disconnect_by_func (e->project,
+					      glade_gtk_menu_editor_project_add_widget,
+					      e);
+	g_signal_handlers_disconnect_by_func (e->project,
+					      glade_gtk_menu_editor_project_widget_name_changed,
+					      e);
+	
+	if (e->project)
+		g_object_weak_unref (G_OBJECT (e->project),
+				     glade_gtk_menu_editor_project_weak_notify,
+				     e);
+	
+	g_free (e);
+}
+
 static
 GladeGtkMenuEditor *
 glade_gtk_menu_editor_new (GObject *menubar)
@@ -3149,44 +3437,55 @@
 	GladeGtkMenuEditor *e;
 	GtkCellRenderer *renderer;
 	GtkTreeViewColumn *column;
-	GtkTreeStore *store;
-	GladeWidget *gmenubar;
-	GladeSignalEditor *signal_editor;
-	GladeProject *project;
-	GtkWidget *window, *vbox, *signal_editor_w, *popup, *table, *child_table, *treeview;
-	GtkWidget *paned, *hbox, *prop_vbox, *label, *scroll, *item, *button, *buttonbox;
+	GtkWidget *vbox, *signal_editor_w, *paned, *hbox, *prop_vbox;
+	GtkWidget *label, *scroll, *item, *button, *buttonbox;
 	gchar *title;
 
 	/* Editor's struct */
 	e = g_malloc0 (sizeof (GladeGtkMenuEditor));
 
-	gmenubar = glade_widget_get_from_gobject (menubar);
-	project = glade_widget_get_project (gmenubar);
+	e->gmenubar = glade_widget_get_from_gobject (menubar);
 	
+	e->project = glade_widget_get_project (e->gmenubar);
+	g_object_weak_ref (G_OBJECT (e->project),
+			   glade_gtk_menu_editor_project_weak_notify,
+			   e);
+	
+	g_signal_connect (e->project, "remove-widget",
+			  G_CALLBACK (glade_gtk_menu_editor_project_remove_widget),
+			  e);
+	g_signal_connect (e->project, "add-widget",
+			  G_CALLBACK (glade_gtk_menu_editor_project_add_widget),
+			  e);
+	g_signal_connect (e->project, "widget-name-changed",
+			  G_CALLBACK (glade_gtk_menu_editor_project_widget_name_changed),
+			  e);
+			  
 	/* Store */
-	store = gtk_tree_store_new (GLADEGTK_MENU_N_COLUMNS,
-				    G_TYPE_OBJECT,
-				    G_TYPE_OBJECT,
-				    G_TYPE_STRING,
-				    G_TYPE_STRING,
-				    G_TYPE_STRING,
-				    G_TYPE_BOOLEAN);
-    	glade_gtk_menu_editor_fill_store (GTK_WIDGET (menubar), store, NULL);
-	g_signal_connect (store, "row-deleted", G_CALLBACK (glade_gtk_menu_editor_row_deleted), e);
-  	g_signal_connect (store, "row-inserted", G_CALLBACK (glade_gtk_menu_editor_row_inserted), e);
+	e->store = gtk_tree_store_new (GLADEGTK_MENU_N_COLUMNS,
+				       G_TYPE_OBJECT,
+				       G_TYPE_OBJECT,
+				       G_TYPE_STRING,
+				       G_TYPE_STRING,
+				       G_TYPE_STRING,
+				       G_TYPE_BOOLEAN);
+    	glade_gtk_menu_editor_fill_store (GTK_WIDGET (menubar), e->store, NULL);
+	g_signal_connect (e->store, "row-deleted", G_CALLBACK (glade_gtk_menu_editor_row_deleted), e);
+	g_signal_connect (e->store, "row-inserted", G_CALLBACK (glade_gtk_menu_editor_row_inserted), e);
 		
 	/* Window */
-	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-	gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DIALOG);
+	e->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+	gtk_window_set_type_hint (GTK_WINDOW (e->window), GDK_WINDOW_TYPE_HINT_DIALOG);
+	g_signal_connect (e->window, "destroy", G_CALLBACK (glade_gtk_menu_editor_destroyed), e);
 
-	title = g_strdup_printf ("%s - %s", _("Menu Bar Editor"), glade_widget_get_name (gmenubar));
-	gtk_window_set_title (GTK_WINDOW (window), title);
+	title = g_strdup_printf ("%s - %s", _("Menu Bar Editor"), glade_widget_get_name (e->gmenubar));
+	gtk_window_set_title (GTK_WINDOW (e->window), title);
 	g_free (title);
 	
 	/* Vbox */
 	vbox = gtk_vbox_new (FALSE, 8);
 	gtk_container_set_border_width (GTK_CONTAINER (vbox), GLADE_GENERIC_BORDER_WIDTH);
-	gtk_container_add (GTK_CONTAINER (window), vbox);
+	gtk_container_add (GTK_CONTAINER (e->window), vbox);
 
 	/* Paned */
 	paned = gtk_vpaned_new ();
@@ -3200,25 +3499,25 @@
 	scroll = gtk_scrolled_window_new (NULL, NULL);
 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
-	gtk_box_pack_start (GTK_BOX (hbox), scroll, FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), scroll, FALSE, TRUE, 0);
 
 	/* TreeView */
-	treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
-	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
-	gtk_tree_view_expand_all (GTK_TREE_VIEW (treeview));
-	gtk_tree_view_set_reorderable (GTK_TREE_VIEW (treeview), TRUE);
+	e->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (e->store));
+	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (e->treeview), TRUE);
+	gtk_tree_view_expand_all (GTK_TREE_VIEW (e->treeview));
+	gtk_tree_view_set_reorderable (GTK_TREE_VIEW (e->treeview), TRUE);
 
-	gtk_widget_add_events (treeview, GDK_KEY_PRESS_MASK);
-	g_signal_connect (treeview, "key-press-event",
+	gtk_widget_add_events (e->treeview, GDK_KEY_PRESS_MASK);
+	g_signal_connect (e->treeview, "key-press-event",
 			  G_CALLBACK (glade_gtk_menu_editor_treeview_key_press_event), e);
 
-	g_signal_connect (treeview, "cursor_changed",
+	g_signal_connect (e->treeview, "cursor_changed",
 			  G_CALLBACK (glade_gtk_menu_editor_treeview_cursor_changed), e);
 
 	renderer = gtk_cell_renderer_text_new ();
 	column = gtk_tree_view_column_new_with_attributes (_("Label"), renderer,
 						"text", GLADEGTK_MENU_LABEL, NULL);
-	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (e->treeview), column);
 	
 	renderer = gtk_cell_renderer_combo_new ();
 	g_object_set (renderer,
@@ -3230,40 +3529,40 @@
 	g_signal_connect (renderer, "edited", G_CALLBACK (glade_gtk_menu_editor_item_type_edited), e);
 	column = gtk_tree_view_column_new_with_attributes (_("Type"), renderer,
 						"text", GLADEGTK_MENU_TYPE_NAME, NULL);
-	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (e->treeview), column);
 
-	gtk_container_add (GTK_CONTAINER (scroll), treeview);
+	gtk_container_add (GTK_CONTAINER (scroll), e->treeview);
 	
 	/* PopUp */
-	popup = gtk_menu_new ();
+	e->popup = gtk_menu_new ();
 	
 	item = gtk_menu_item_new_with_label (_("Add Item"));
 	g_signal_connect (item, "activate", G_CALLBACK (glade_gtk_menu_editor_add_item_activate), e);
-	gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
+	gtk_menu_shell_append (GTK_MENU_SHELL (e->popup), item);
 	
 	item = gtk_menu_item_new_with_label (_("Add Child Item"));
 	g_signal_connect (item, "activate", G_CALLBACK (glade_gtk_menu_editor_add_child_item_activate), e);
-	gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
+	gtk_menu_shell_append (GTK_MENU_SHELL (e->popup), item);
 
 	item = gtk_menu_item_new_with_label (_("Add Separator"));
 	g_signal_connect (item, "activate", G_CALLBACK (glade_gtk_menu_editor_add_separator_activate), e);
-	gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
+	gtk_menu_shell_append (GTK_MENU_SHELL (e->popup), item);
 
 	item = gtk_separator_menu_item_new();
-	gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
+	gtk_menu_shell_append (GTK_MENU_SHELL (e->popup), item);
 
 	item = gtk_menu_item_new_with_label (_("Expand All"));
-	g_signal_connect_swapped (item, "activate", G_CALLBACK (gtk_tree_view_expand_all), treeview);
-	gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
+	g_signal_connect_swapped (item, "activate", G_CALLBACK (gtk_tree_view_expand_all), e->treeview);
+	gtk_menu_shell_append (GTK_MENU_SHELL (e->popup), item);
 
 	item = gtk_menu_item_new_with_label (_("Collapse All"));
-	g_signal_connect_swapped (item, "activate", G_CALLBACK (gtk_tree_view_collapse_all), treeview);
-	gtk_menu_shell_append (GTK_MENU_SHELL (popup), item);
+	g_signal_connect_swapped (item, "activate", G_CALLBACK (gtk_tree_view_collapse_all), e->treeview);
+	gtk_menu_shell_append (GTK_MENU_SHELL (e->popup), item);
 	
-	gtk_widget_show_all (popup);
-	g_signal_connect (treeview, "button_press_event", G_CALLBACK (glade_gtk_menu_editor_popup_handler), e);
+	gtk_widget_show_all (e->popup);
+	g_signal_connect (e->treeview, "button_press_event", G_CALLBACK (glade_gtk_menu_editor_popup_handler), e);
 	
-	/* Porperties Vbox */
+	/* Properties Vbox */
 	prop_vbox = gtk_vbox_new (FALSE, 8);
 	gtk_box_pack_start (GTK_BOX (hbox), prop_vbox, TRUE, TRUE, 0);
 	
@@ -3274,17 +3573,17 @@
 	gtk_box_pack_start (GTK_BOX (prop_vbox), label, FALSE, TRUE, 0);
 
 	/* Tables */
-	table = gtk_table_new (1, 2, FALSE);
-	gtk_table_set_row_spacings (GTK_TABLE (table), 4);
-	gtk_box_pack_start (GTK_BOX (prop_vbox), table, FALSE, TRUE, 0);
-
-	child_table = gtk_table_new (1, 2, FALSE);
-	gtk_table_set_row_spacings (GTK_TABLE (child_table), 4);
-	gtk_box_pack_start (GTK_BOX (prop_vbox), child_table, FALSE, TRUE, 0);
+	e->table = gtk_table_new (1, 2, FALSE);
+	gtk_table_set_row_spacings (GTK_TABLE (e->table), 4);
+	gtk_box_pack_start (GTK_BOX (prop_vbox), e->table, FALSE, TRUE, 0);
+
+	e->child_table = gtk_table_new (1, 2, FALSE);
+	gtk_table_set_row_spacings (GTK_TABLE (e->child_table), 4);
+	gtk_box_pack_start (GTK_BOX (prop_vbox), e->child_table, FALSE, TRUE, 0);
 
 	/* Signal Editor */
-	signal_editor = glade_signal_editor_new (NULL);
-	signal_editor_w = glade_signal_editor_get_widget (signal_editor);
+	e->signal_editor = glade_signal_editor_new (NULL);
+	signal_editor_w = glade_signal_editor_get_widget (e->signal_editor);
 	gtk_widget_set_size_request (signal_editor_w, -1, 96);
 	gtk_paned_pack2 (GTK_PANED (paned), signal_editor_w, FALSE, FALSE);
 	
@@ -3298,33 +3597,21 @@
 	g_signal_connect (button, "clicked", G_CALLBACK (glade_gtk_menu_editor_add_item_activate), e);
 	gtk_container_add (GTK_CONTAINER (buttonbox), button);
 
-	button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
+	e->remove_button = button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
 	g_signal_connect (button, "clicked", G_CALLBACK (glade_gtk_menu_editor_delete_item_activate), e);
 	gtk_container_add (GTK_CONTAINER (buttonbox), button);
 
 	button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
-	g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
+	g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), e->window);
 	gtk_container_add (GTK_CONTAINER (buttonbox), button);
 
 	button = gtk_button_new_from_stock (GTK_STOCK_HELP);
-	g_signal_connect (button, "clicked", G_CALLBACK (glade_gtk_menu_editor_help), window);
+	g_signal_connect (button, "clicked", G_CALLBACK (glade_gtk_menu_editor_help), e->window);
 	gtk_container_add (GTK_CONTAINER (buttonbox), button);
 	gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (buttonbox), button, TRUE);
 
 	gtk_widget_show_all (vbox);
-
-	/* Setup struct values */
-	e->window = window;
-	e->popup = popup;
-	e->table = table;
-	e->child_table = child_table;
-	e->treeview = treeview;
-	
-	e->store = store;
-	e->gmenubar = gmenubar;
-	e->signal_editor= signal_editor;
-	e->project = project;
-
+	
 	return e;
 }
 
@@ -3336,8 +3623,6 @@
 	editor = glade_gtk_menu_editor_new (menubar);
 
 	gtk_window_set_default_size (GTK_WINDOW (editor->window), 600, 440);
-	gtk_window_set_modal (GTK_WINDOW (editor->window), TRUE);
-	g_signal_connect_swapped (editor->window, "destroy", G_CALLBACK (g_free), editor);
 	
 	gtk_widget_show (editor->window);
 }
Index: src/glade-widget-class.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-widget-class.c,v
retrieving revision 1.83
diff -u -r1.83 glade-widget-class.c
--- src/glade-widget-class.c	15 Dec 2005 21:17:23 -0000	1.83
+++ src/glade-widget-class.c	27 Dec 2005 20:51:23 -0000
@@ -736,6 +736,8 @@
 		}
 	}
 
+	/* Let it leak (as in glade_widget_class_list_properties) */
+	g_type_class_ref (parent_type);
 
 	/* Remove any properties found in widget_properties not found in parent_properties
 	 * if parent_properties should have it through introspection
Index: widgets/gtk+.xml
===================================================================
RCS file: /cvs/gnome/glade3/widgets/gtk+.xml,v
retrieving revision 1.27
diff -u -r1.27 gtk+.xml
--- widgets/gtk+.xml	15 Dec 2005 03:57:20 -0000	1.27
+++ widgets/gtk+.xml	27 Dec 2005 20:51:27 -0000
@@ -162,6 +162,24 @@
       </properties>
     </glade-widget-class>
 
+    <glade-widget-class name="GtkMenuShell">
+      <children>
+	<child>
+	  <type>GtkMenuItem</type>
+  	  <add-child-function>glade_gtk_menu_shell_add_item</add-child-function>
+	  <remove-child-function>glade_gtk_menu_shell_remove_item</remove-child-function>
+	  <child-set-property-function>glade_gtk_menu_shell_set_child_property</child-set-property-function>	  
+	  <child-get-property-function>glade_gtk_menu_shell_get_child_property</child-get-property-function>
+          <properties>
+            <property id="position" _name="Position" default="-1" save="False">
+              <spec>glade_standard_int_spec</spec>
+              <_tooltip>The position of the menu item in the menu shell</_tooltip>
+            </property>
+          </properties>
+	</child>
+      </children>
+    </glade-widget-class>
+
     <glade-widget-class name="GtkMenuItem" generic-name="menuitem" _title="Menu Item">
       <post-create-function>glade_gtk_menu_item_post_create</post-create-function>
 	<properties>
@@ -181,13 +199,20 @@
 	  <get-all-children-function>glade_gtk_menu_item_get_submenu</get-all-children-function>
 	  <get-children-function>glade_gtk_menu_item_get_submenu</get-children-function>
 	  <add-child-function>glade_gtk_menu_item_add_submenu</add-child-function>
-	  <remove-child-function>glade_gtk_menu_item_remove_submenu</remove-child-function>
+          <remove-child-function>glade_gtk_menu_item_remove_submenu</remove-child-function>
 	</child>
       </children>
     </glade-widget-class>
 
     <glade-widget-class name="GtkCheckMenuItem" generic-name="checkmenuitem" _title="Check Menu Item"/>
 
+    <glade-widget-class name="GtkRadioMenuItem" generic-name="radiomenuitem" _title="Radio Menu Item">
+      <properties>
+        <property id="draw-as-radio"  visible="False" save="False" default="True"/>
+	<property id="inconsistent" visible="False" save="False" default="False"/>
+      </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>
       <properties>
@@ -219,13 +244,6 @@
 	  <child-property id="expand" default="false"/>
 	</parent-class>
       </packing-defaults>
-      <children>
-	<child>
-	  <type>GtkMenuItem</type>
-	  <add-child-function>glade_gtk_menu_bar_add_item</add-child-function>
-	  <remove-child-function>glade_gtk_menu_bar_remove_item</remove-child-function>
-	</child>
-      </children>
     </glade-widget-class>
       
     <glade-widget-class name="GtkToolbar" generic-name="toolbar" _title="Tool Bar">
@@ -485,12 +503,11 @@
 	<property id="file" disabled="True"/>
 	<property id="pixbuf" _name="File Name" translatable="False"/>
 	<property id="glade-stock" _name="Stock Image" save="False">
-	  <tooltip>A builtin stock image</tooltip>
+	  <_tooltip>A builtin stock image</_tooltip>
 	  <spec>glade_standard_stock_spec</spec>
-	  <_tooltip>The stock item for this image</_tooltip>
 	  <set-function>glade_gtk_image_set_stock</set-function>
 	</property>
-	<property id="icon-name" translatable="False">
+	<property id="icon-name" _name="Icon Name" translatable="False">
 	  <set-function>glade_gtk_image_set_icon_name</set-function>
 	</property>
       </properties>
@@ -673,16 +690,10 @@
     <glade-widget-class name="GtkCalendar" generic-name="calendar" _title="Calendar"/>
     
     <glade-widget-class name="GtkMenu" generic-name="menu" _title="Popup Menu">
+      <!-- We do not want glade_gtk_container_post_create be executed -->
       <post-create-function>empty</post-create-function>
-      <children>
-	<child>
-	  <type>GtkMenuItem</type>
-	  <add-child-function>glade_gtk_menu_add_item</add-child-function>
-	  <remove-child-function>glade_gtk_menu_remove_item</remove-child-function>
-	</child>
-      </children>
     </glade-widget-class>
-     
+    
     <glade-widget-class name="GtkHScrollbar" generic-name="hscrollbar" _title="Horizontal Scrollbar"/>
 
     <glade-widget-class name="GtkVScrollbar" generic-name="vscrollbar" _title="Vertical Scrollbar"/>
_______________________________________________
Glade-devel maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/glade-devel

Reply via email to