[glade3] * gladeui/glade-popup.c: Allow adding new actions to action groups from the palette ("Add widget he



commit f232b9789a4e67c42d1827d3b8a0a6c23cdfd4e5
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Mon Mar 29 19:58:17 2010 -0400

    	* gladeui/glade-popup.c: Allow adding new actions to action groups from the palette ("Add widget here").
    
    	* plugins/gtk+/glade-accels.[ch]: Moved individual accelerator [de]serialization here, special integration
    	  for action types, for actions only show one accelerator and dont load/save the "activate" signal name.
    
    	* plugins/gtk+/glade-gtk.c, plugins/gtk+/gtk+.xml.in: Added support for GtkActionGroup <--> GtkAction
    	  relationships and support for editing/loading/saving of accelerators which can be associated with
    	  actions inside an action group.

 ChangeLog                   |   11 ++-
 gladeui/glade-popup.c       |   43 +++++-
 plugins/gtk+/glade-accels.c |  254 ++++++++++++++++++++++++++++++-
 plugins/gtk+/glade-accels.h |   15 ++
 plugins/gtk+/glade-gtk.c    |  353 ++++++++++++++++++-------------------------
 plugins/gtk+/gtk+.xml.in    |   27 +++-
 6 files changed, 485 insertions(+), 218 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 8727b97..4d942a1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -25,7 +25,16 @@
 
 	* gladeui/glade-widget.c: GladeWidget takes a new "support-changed" to broadcast support changes
 	  on the widget.
-	
+
+	* gladeui/glade-popup.c: Allow adding new actions to action groups from the palette ("Add widget here").
+
+	* plugins/gtk+/glade-accels.[ch]: Moved individual accelerator [de]serialization here, special integration
+	  for action types, for actions only show one accelerator and dont load/save the "activate" signal name.
+
+	* plugins/gtk+/glade-gtk.c, plugins/gtk+/gtk+.xml.in: Added support for GtkActionGroup <--> GtkAction
+	  relationships and support for editing/loading/saving of accelerators which can be associated with
+	  actions inside an action group.
+
 2010-03-28  Tristan Van Berkom <tvb gnome org>
 
 	* gladeui/Makefile.am, gladeui/glade-cell-renderer-icon.[ch]: Added activatable pixbuf renderer
diff --git a/gladeui/glade-popup.c b/gladeui/glade-popup.c
index 0163065..5c8679f 100644
--- a/gladeui/glade-popup.c
+++ b/gladeui/glade-popup.c
@@ -100,6 +100,20 @@ glade_popup_placeholder_add_cb (GtkMenuItem *item, GladePlaceholder *placeholder
 }
 
 static void
+glade_popup_action_add_cb (GtkMenuItem *item, GladeWidget *group)
+{
+	GladeWidgetAdaptor *adaptor;
+
+	adaptor = glade_palette_get_current_item (glade_app_get_palette ());
+	g_return_if_fail (adaptor != NULL);
+
+	glade_command_create (adaptor, group,
+			      NULL, glade_widget_get_project (group));
+	
+	glade_palette_deselect_current_item (glade_app_get_palette(), TRUE);
+}
+
+static void
 glade_popup_root_add_cb (GtkMenuItem *item, gpointer *user_data)
 {
 	GladeWidgetAdaptor *adaptor = (GladeWidgetAdaptor *)user_data;
@@ -423,6 +437,7 @@ glade_popup_create_menu (GladeWidget      *widget,
 			 gboolean          packing)
 {
 	GladeProjectFormat fmt;
+	GladeWidgetAdaptor *current_item;
 	GladeProject *project;
 	GtkWidget *popup_menu;
 	GtkWidget *separator;
@@ -431,7 +446,7 @@ glade_popup_create_menu (GladeWidget      *widget,
 	GladePlaceholder *tmp_placeholder;
 	gchar     *book;
 
-	sensitive = glade_palette_get_current_item (glade_app_get_palette ()) != NULL;
+	sensitive = (current_item = glade_palette_get_current_item (glade_app_get_palette ())) != NULL;
 
 	/* Resolve project format first... */
 	project = widget ? glade_widget_get_project (widget) :
@@ -441,13 +456,27 @@ glade_popup_create_menu (GladeWidget      *widget,
 
 	popup_menu = gtk_menu_new ();
 	
-	if (sensitive)
+	if (current_item)
 	{		
-		tmp_placeholder = placeholder;
-		if (!tmp_placeholder && widget)
-			tmp_placeholder = find_placeholder (glade_widget_get_object (widget));
-		glade_popup_append_item (popup_menu, NULL, _("_Add widget here"), NULL, tmp_placeholder != NULL,
-					 glade_popup_placeholder_add_cb, tmp_placeholder);
+		
+		/* Special case for GtkAction accelerators  */
+		if (widget && GTK_IS_ACTION_GROUP (widget->object) &&
+		    (current_item->type == GTK_TYPE_ACTION ||
+		     g_type_is_a (current_item->type, GTK_TYPE_ACTION)))
+		{
+			glade_popup_append_item (popup_menu, NULL, _("_Add widget here"), NULL, TRUE,
+						 glade_popup_action_add_cb, widget);
+		}
+		else
+		{
+			tmp_placeholder = placeholder;
+			if (!tmp_placeholder && widget)
+				tmp_placeholder = find_placeholder (glade_widget_get_object (widget));
+			
+			glade_popup_append_item (popup_menu, NULL, _("_Add widget here"), NULL, tmp_placeholder != NULL,
+						 glade_popup_placeholder_add_cb, tmp_placeholder);
+		}
+
 		glade_popup_append_item (popup_menu, NULL, _("Add widget as _toplevel"), NULL, 
 					 fmt != GLADE_PROJECT_FORMAT_LIBGLADE,
 					 glade_popup_root_add_cb, NULL);
diff --git a/plugins/gtk+/glade-accels.c b/plugins/gtk+/glade-accels.c
index 59a70ab..44bcc75 100644
--- a/plugins/gtk+/glade-accels.c
+++ b/plugins/gtk+/glade-accels.c
@@ -218,8 +218,16 @@ glade_eprop_accel_populate_view (GladeEditorProperty *eprop,
 	{
 		sclass = list->data;
 
+		/* Special case for GtkAction accelerators  */
+		if (adaptor->type == GTK_TYPE_ACTION ||
+		    g_type_is_a (adaptor->type, GTK_TYPE_ACTION))
+		{
+			if (g_strcmp0 (sclass->type, "GtkAction") != 0 ||
+			    g_strcmp0 (sclass->name, "activate") != 0)
+				continue;
+		}
 		/* Only action signals have accelerators. */
-		if ((sclass->query.signal_flags & G_SIGNAL_ACTION) == 0)
+		else if ((sclass->query.signal_flags & G_SIGNAL_ACTION) == 0)
 			continue;
 
 		if (g_list_find_custom (eprop_accel->parent_iters, 
@@ -249,8 +257,16 @@ glade_eprop_accel_populate_view (GladeEditorProperty *eprop,
 	{
 		sclass = list->data;
 
+		/* Special case for GtkAction accelerators  */
+		if (adaptor->type == GTK_TYPE_ACTION ||
+		    g_type_is_a (adaptor->type, GTK_TYPE_ACTION))
+		{
+			if (g_strcmp0 (sclass->type, "GtkAction") != 0 ||
+			    g_strcmp0 (sclass->name, "activate") != 0)
+				continue;
+		}
 		/* Only action signals have accelerators. */
-		if ((sclass->query.signal_flags & G_SIGNAL_ACTION) == 0)
+		else if ((sclass->query.signal_flags & G_SIGNAL_ACTION) == 0)
 			continue;
 
 		if ((found = g_list_find_custom (eprop_accel->parent_iters, 
@@ -289,6 +305,12 @@ glade_eprop_accel_populate_view (GladeEditorProperty *eprop,
 				g_free (accel_text);
 			}
 
+			/* Special case for GtkAction accelerators  */
+			if ((adaptor->type == GTK_TYPE_ACTION ||
+			     g_type_is_a (adaptor->type, GTK_TYPE_ACTION)) &&
+			    g_list_length (accelerators) > 0)
+				continue;
+
 			/* Append a new empty slot at the end */
 			gtk_tree_store_append (model, &iter, parent_tab->iter);
 			gtk_tree_store_set    
@@ -321,11 +343,17 @@ accel_edited (GtkCellRendererAccel *accel,
 	gboolean         key_was_set;
 	GtkTreeIter      iter, parent_iter, new_iter;
 	gchar           *accel_text;
+	GladeWidgetAdaptor *adaptor = 
+		glade_widget_adaptor_from_pclass (GLADE_EDITOR_PROPERTY (eprop_accel)->klass);
+	gboolean         is_action;
 
 	if (!gtk_tree_model_get_iter_from_string (eprop_accel->model,
 						  &iter, path_string))
 		return;
 
+	is_action = (adaptor->type == GTK_TYPE_ACTION ||
+		     g_type_is_a (adaptor->type, GTK_TYPE_ACTION));
+
 	gtk_tree_model_get (eprop_accel->model, &iter,
 			    ACCEL_COLUMN_KEY_ENTERED, &key_was_set,
 			    -1);
@@ -346,7 +374,7 @@ accel_edited (GtkCellRendererAccel *accel,
 
 	/* Append a new one if needed
 	 */
-	if (key_was_set == FALSE &&
+	if (is_action == FALSE && key_was_set == FALSE &&
 	    gtk_tree_model_iter_parent (eprop_accel->model,
 					&parent_iter, &iter))
 	{	
@@ -601,3 +629,223 @@ glade_eprop_accel_create_input (GladeEditorProperty *eprop)
 
 	return hbox;
 }
+
+
+static GdkModifierType
+glade_gtk_parse_modifiers (const gchar *string)
+{
+	const gchar     *pos = string;
+	GdkModifierType	 modifiers = 0;
+
+	while (pos && pos[0])
+	{
+		if (!strncmp(pos, "GDK_", 4)) {
+			pos += 4;
+			if (!strncmp(pos, "SHIFT_MASK", 10)) {
+				modifiers |= GDK_SHIFT_MASK;
+				pos += 10;
+			} else if (!strncmp(pos, "LOCK_MASK", 9)) {
+				modifiers |= GDK_LOCK_MASK;
+				pos += 9;
+			} else if (!strncmp(pos, "CONTROL_MASK", 12)) {
+				modifiers |= GDK_CONTROL_MASK;
+				pos += 12;
+			} else if (!strncmp(pos, "MOD", 3) &&
+				   !strncmp(pos+4, "_MASK", 5)) {
+				switch (pos[3]) {
+				case '1':
+					modifiers |= GDK_MOD1_MASK; break;
+				case '2':
+					modifiers |= GDK_MOD2_MASK; break;
+				case '3':
+					modifiers |= GDK_MOD3_MASK; break;
+				case '4':
+					modifiers |= GDK_MOD4_MASK; break;
+				case '5':
+					modifiers |= GDK_MOD5_MASK; break;
+				}
+				pos += 9;
+			} else if (!strncmp(pos, "BUTTON", 6) &&
+				   !strncmp(pos+7, "_MASK", 5)) {
+				switch (pos[6]) {
+				case '1':
+					modifiers |= GDK_BUTTON1_MASK; break;
+				case '2':
+					modifiers |= GDK_BUTTON2_MASK; break;
+				case '3':
+					modifiers |= GDK_BUTTON3_MASK; break;
+				case '4':
+					modifiers |= GDK_BUTTON4_MASK; break;
+				case '5':
+					modifiers |= GDK_BUTTON5_MASK; break;
+				}
+				pos += 12;
+			} else if (!strncmp(pos, "RELEASE_MASK", 12)) {
+				modifiers |= GDK_RELEASE_MASK;
+				pos += 12;
+			} else
+				pos++;
+		} else
+			pos++;
+	}
+	return modifiers;
+}
+
+
+static gchar *
+glade_gtk_modifier_string_from_bits (GdkModifierType modifiers)
+{
+    GString *string = g_string_new ("");
+
+    if (modifiers & GDK_SHIFT_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_SHIFT_MASK");
+    }
+
+    if (modifiers & GDK_LOCK_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_LOCK_MASK");
+    }
+
+    if (modifiers & GDK_CONTROL_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_CONTROL_MASK");
+    }
+
+    if (modifiers & GDK_MOD1_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_MOD1_MASK");
+    }
+
+    if (modifiers & GDK_MOD2_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_MOD2_MASK");
+    }
+
+    if (modifiers & GDK_MOD3_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_MOD3_MASK");
+    }
+
+    if (modifiers & GDK_MOD4_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_MOD4_MASK");
+    }
+
+    if (modifiers & GDK_MOD5_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_MOD5_MASK");
+    }
+
+    if (modifiers & GDK_BUTTON1_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_BUTTON1_MASK");
+    }
+
+    if (modifiers & GDK_BUTTON2_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_BUTTON2_MASK");
+    }
+
+    if (modifiers & GDK_BUTTON3_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_BUTTON3_MASK");
+    }
+
+    if (modifiers & GDK_BUTTON4_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_BUTTON4_MASK");
+    }
+
+    if (modifiers & GDK_BUTTON5_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_BUTTON5_MASK");
+    }
+
+    if (modifiers & GDK_RELEASE_MASK) {
+	if (string->len > 0)
+	    g_string_append (string, " | ");
+	g_string_append (string, "GDK_RELEASE_MASK");
+    }
+
+    if (string->len > 0)
+	return g_string_free (string, FALSE);
+
+    g_string_free (string, TRUE);
+    return NULL;
+}
+
+GladeAccelInfo *
+glade_accel_read (GladeXmlNode     *node,
+		  gboolean          require_signal)
+{
+	GladeAccelInfo *ainfo;
+	gchar *key, *modifiers, *signal;
+
+	g_return_val_if_fail (node != NULL, NULL);
+	
+	if (!glade_xml_node_verify (node, GLADE_TAG_ACCEL))
+		return NULL;
+
+	/* Get from xml... */
+	key = glade_xml_get_property_string_required
+		(node, GLADE_TAG_ACCEL_KEY, NULL);
+	if (require_signal)
+		signal = glade_xml_get_property_string_required (node, GLADE_TAG_ACCEL_SIGNAL, NULL);
+	else
+		signal = glade_xml_get_property_string (node, GLADE_TAG_ACCEL_SIGNAL);
+
+	modifiers = glade_xml_get_property_string (node, GLADE_TAG_ACCEL_MODIFIERS);
+	
+	/* translate to GladeAccelInfo... */
+	ainfo = g_new0 (GladeAccelInfo, 1);
+	ainfo->key = gdk_keyval_from_name(key);
+	ainfo->signal = signal; /* take string ownership... */
+	ainfo->modifiers = glade_gtk_parse_modifiers (modifiers);
+
+	g_free (modifiers);
+
+	return ainfo;
+}
+
+GladeXmlNode *
+glade_accel_write (GladeAccelInfo   *accel,
+		   GladeXmlContext  *context,
+		   gboolean          write_signal)
+{
+	GladeXmlNode  *accel_node;
+	gchar         *modifiers;
+
+	g_return_val_if_fail (accel != NULL, NULL);
+	g_return_val_if_fail (context != NULL, NULL);
+
+	accel_node = glade_xml_node_new (context, GLADE_TAG_ACCEL);
+	modifiers  = glade_gtk_modifier_string_from_bits (accel->modifiers);
+
+	glade_xml_node_set_property_string (accel_node, GLADE_TAG_ACCEL_KEY,
+					    gdk_keyval_name(accel->key));
+
+	if (write_signal)
+		glade_xml_node_set_property_string (accel_node, GLADE_TAG_ACCEL_SIGNAL,
+						    accel->signal);
+	glade_xml_node_set_property_string (accel_node, GLADE_TAG_ACCEL_MODIFIERS,
+					    modifiers);
+
+	g_free (modifiers);
+
+	return accel_node;
+}
+
diff --git a/plugins/gtk+/glade-accels.h b/plugins/gtk+/glade-accels.h
index 99103a4..2ff33f6 100644
--- a/plugins/gtk+/glade-accels.h
+++ b/plugins/gtk+/glade-accels.h
@@ -11,6 +11,15 @@ G_BEGIN_DECLS
 #define GLADE_TYPE_EPROP_ACCEL         (glade_eprop_accel_get_type())
 
 
+#define GLADE_TAG_ACCEL             "accelerator"
+#define GLADE_TAG_ACCEL_KEY         "key"
+#define GLADE_TAG_ACCEL_MODIFIERS   "modifiers"
+#define GLADE_TAG_ACCEL_SIGNAL      "signal"
+
+#define GLADE_TAG_ACCEL_GROUPS "accel-groups"
+#define GLADE_TAG_ACCEL_GROUP  "group"
+
+
 typedef struct _GladeKey                GladeKey;
 typedef struct _GladeAccelInfo          GladeAccelInfo;
 
@@ -40,6 +49,12 @@ void         glade_accel_list_free         (GList         *accels);
 
 gchar       *glade_accels_make_string      (GList *accels);
 
+GladeAccelInfo *glade_accel_read           (GladeXmlNode     *node,
+					    gboolean          require_signal);
+GladeXmlNode   *glade_accel_write          (GladeAccelInfo   *accel_info,
+					    GladeXmlContext  *context,
+					    gboolean          write_signal);
+
 G_END_DECLS
 
 #endif   /* __GLADE_ACCELS_H__ */
diff --git a/plugins/gtk+/glade-gtk.c b/plugins/gtk+/glade-gtk.c
index 381bf74..1560239 100644
--- a/plugins/gtk+/glade-gtk.c
+++ b/plugins/gtk+/glade-gtk.c
@@ -235,17 +235,14 @@ glade_gtk_widget_depends (GladeWidgetAdaptor *adaptor,
 			  GladeWidget        *widget,
 			  GladeWidget        *another)
 {
-	if (GTK_IS_ICON_FACTORY (another->object))
+	if (GTK_IS_ICON_FACTORY (another->object) ||
+	    GTK_IS_ACTION       (another->object) ||
+	    GTK_IS_ACTION_GROUP (another->object))
 		return TRUE; 
 
 	return GWA_GET_CLASS (G_TYPE_OBJECT)->depends (adaptor, widget, another);
 }
 
-#define GLADE_TAG_ACCEL             "accelerator"
-#define GLADE_TAG_ACCEL_KEY         "key"
-#define GLADE_TAG_ACCEL_MODIFIERS   "modifiers"
-#define GLADE_TAG_ACCEL_SIGNAL      "signal"
-
 #define GLADE_TAG_A11Y_A11Y         "accessibility"
 #define GLADE_TAG_A11Y_ACTION_NAME  "action_name" /* We should make -/_ synonymous */
 #define GLADE_TAG_A11Y_DESC         "description"
@@ -296,69 +293,10 @@ static const gchar *atk_relations_list[] = {
 	NULL
 };
 
-static GdkModifierType
-glade_gtk_parse_modifiers (const gchar *string)
-{
-	const gchar     *pos = string;
-	GdkModifierType	 modifiers = 0;
-
-	while (pos && pos[0])
-	{
-		if (!strncmp(pos, "GDK_", 4)) {
-			pos += 4;
-			if (!strncmp(pos, "SHIFT_MASK", 10)) {
-				modifiers |= GDK_SHIFT_MASK;
-				pos += 10;
-			} else if (!strncmp(pos, "LOCK_MASK", 9)) {
-				modifiers |= GDK_LOCK_MASK;
-				pos += 9;
-			} else if (!strncmp(pos, "CONTROL_MASK", 12)) {
-				modifiers |= GDK_CONTROL_MASK;
-				pos += 12;
-			} else if (!strncmp(pos, "MOD", 3) &&
-				   !strncmp(pos+4, "_MASK", 5)) {
-				switch (pos[3]) {
-				case '1':
-					modifiers |= GDK_MOD1_MASK; break;
-				case '2':
-					modifiers |= GDK_MOD2_MASK; break;
-				case '3':
-					modifiers |= GDK_MOD3_MASK; break;
-				case '4':
-					modifiers |= GDK_MOD4_MASK; break;
-				case '5':
-					modifiers |= GDK_MOD5_MASK; break;
-				}
-				pos += 9;
-			} else if (!strncmp(pos, "BUTTON", 6) &&
-				   !strncmp(pos+7, "_MASK", 5)) {
-				switch (pos[6]) {
-				case '1':
-					modifiers |= GDK_BUTTON1_MASK; break;
-				case '2':
-					modifiers |= GDK_BUTTON2_MASK; break;
-				case '3':
-					modifiers |= GDK_BUTTON3_MASK; break;
-				case '4':
-					modifiers |= GDK_BUTTON4_MASK; break;
-				case '5':
-					modifiers |= GDK_BUTTON5_MASK; break;
-				}
-				pos += 12;
-			} else if (!strncmp(pos, "RELEASE_MASK", 12)) {
-				modifiers |= GDK_RELEASE_MASK;
-				pos += 12;
-			} else
-				pos++;
-		} else
-			pos++;
-	}
-	return modifiers;
-}
-
 static void
-glade_gtk_widget_read_accels (GladeWidget  *widget,
-			      GladeXmlNode *node)
+glade_gtk_read_accels (GladeWidget  *widget,
+		       GladeXmlNode *node,
+		       gboolean      require_signal)
 {
 	GladeProperty  *property;
 	GladeXmlNode   *prop;
@@ -369,27 +307,11 @@ glade_gtk_widget_read_accels (GladeWidget  *widget,
 	for (prop = glade_xml_node_get_children (node); 
 	     prop; prop = glade_xml_node_next (prop))
 	{
-		gchar *key, *modifiers, *signal;
-
-
 		if (!glade_xml_node_verify_silent (prop, GLADE_TAG_ACCEL))
 			continue;
 
-		/* Get from xml... */
-		key = glade_xml_get_property_string_required
-			(prop, GLADE_TAG_ACCEL_KEY, NULL);
-		signal = glade_xml_get_property_string_required
-			(prop, GLADE_TAG_ACCEL_SIGNAL, NULL);
-		modifiers = glade_xml_get_property_string (prop, GLADE_TAG_ACCEL_MODIFIERS);
-
-		/* translate to GladeAccelInfo... */
-		ainfo = g_new0 (GladeAccelInfo, 1);
-		ainfo->key = gdk_keyval_from_name(key);
-		ainfo->signal = signal; /* take string ownership... */
-		ainfo->modifiers = glade_gtk_parse_modifiers (modifiers);
-
-		accels = g_list_prepend (accels, ainfo);
-		g_free (modifiers);
+		if ((ainfo = glade_accel_read (prop, require_signal)) != NULL)
+			accels = g_list_prepend (accels, ainfo);
 	}
 
 	if (accels)
@@ -636,7 +558,7 @@ glade_gtk_widget_read_widget (GladeWidgetAdaptor *adaptor,
         GWA_GET_CLASS (G_TYPE_OBJECT)->read_widget (adaptor, widget, node);
 
 	/* Read in accelerators */
-	glade_gtk_widget_read_accels (widget, node);
+	glade_gtk_read_accels (widget, node, TRUE);
 
 	/* Read in atk props */
 	glade_gtk_widget_read_atk_props (widget, node);
@@ -870,107 +792,11 @@ glade_gtk_widget_write_atk_props (GladeWidget        *widget,
 		glade_gtk_widget_write_atk_properties_gtkbuilder (widget, context, node);
 }
 
-static gchar *
-glade_gtk_modifier_string_from_bits (GdkModifierType modifiers)
-{
-    GString *string = g_string_new ("");
-
-    if (modifiers & GDK_SHIFT_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_SHIFT_MASK");
-    }
-
-    if (modifiers & GDK_LOCK_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_LOCK_MASK");
-    }
-
-    if (modifiers & GDK_CONTROL_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_CONTROL_MASK");
-    }
-
-    if (modifiers & GDK_MOD1_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_MOD1_MASK");
-    }
-
-    if (modifiers & GDK_MOD2_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_MOD2_MASK");
-    }
-
-    if (modifiers & GDK_MOD3_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_MOD3_MASK");
-    }
-
-    if (modifiers & GDK_MOD4_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_MOD4_MASK");
-    }
-
-    if (modifiers & GDK_MOD5_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_MOD5_MASK");
-    }
-
-    if (modifiers & GDK_BUTTON1_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_BUTTON1_MASK");
-    }
-
-    if (modifiers & GDK_BUTTON2_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_BUTTON2_MASK");
-    }
-
-    if (modifiers & GDK_BUTTON3_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_BUTTON3_MASK");
-    }
-
-    if (modifiers & GDK_BUTTON4_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_BUTTON4_MASK");
-    }
-
-    if (modifiers & GDK_BUTTON5_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_BUTTON5_MASK");
-    }
-
-    if (modifiers & GDK_RELEASE_MASK) {
-	if (string->len > 0)
-	    g_string_append (string, " | ");
-	g_string_append (string, "GDK_RELEASE_MASK");
-    }
-
-    if (string->len > 0)
-	return g_string_free (string, FALSE);
-
-    g_string_free (string, TRUE);
-    return NULL;
-}
-
-
 static void
-glade_gtk_widget_write_accels (GladeWidget        *widget,
-			       GladeXmlContext    *context,
-			       GladeXmlNode       *node)
+glade_gtk_write_accels (GladeWidget        *widget,
+			GladeXmlContext    *context,
+			GladeXmlNode       *node,
+			gboolean            write_signal)
 {
 	GladeXmlNode  *accel_node;
 	GladeProperty *property;
@@ -984,22 +810,10 @@ glade_gtk_widget_write_accels (GladeWidget        *widget,
 	     list; list = list->next)
 	{
 		GladeAccelInfo *accel = list->data;
-		gchar *modifiers = glade_gtk_modifier_string_from_bits (accel->modifiers);
 
-		accel_node = glade_xml_node_new (context, GLADE_TAG_ACCEL);
+		accel_node = glade_accel_write (accel, context, write_signal);
 		glade_xml_node_append_child (node, accel_node);
-
-		glade_xml_node_set_property_string (accel_node, GLADE_TAG_ACCEL_KEY,
-						    gdk_keyval_name(accel->key));
-		glade_xml_node_set_property_string (accel_node, GLADE_TAG_ACCEL_SIGNAL,
-						    accel->signal);
-		glade_xml_node_set_property_string (accel_node, GLADE_TAG_ACCEL_MODIFIERS,
-						    modifiers);
-
-		g_free (modifiers);
 	}
-
-
 }
 
 void
@@ -1027,10 +841,10 @@ glade_gtk_widget_write_widget (GladeWidgetAdaptor *adaptor,
 	{
  		glade_gtk_widget_write_atk_props (widget, context, node);
 		glade_widget_write_signals (widget, context, node);
-		glade_gtk_widget_write_accels (widget, context, node);
+		glade_gtk_write_accels (widget, context, node, TRUE);
 	} else {
 		/* The core takes care of signals in GtkBuilder format */
-		glade_gtk_widget_write_accels (widget, context, node);		
+		glade_gtk_write_accels (widget, context, node, TRUE);		
  		glade_gtk_widget_write_atk_props (widget, context, node);
 	}
 }
@@ -5191,9 +5005,6 @@ glade_gtk_window_deep_post_create (GladeWidgetAdaptor *adaptor,
 	g_signal_connect (object, "delete-event", G_CALLBACK (glade_gtk_widget_show_on_delete), NULL);
 }
 
-#define GLADE_TAG_ACCEL_GROUPS "accel-groups"
-#define GLADE_TAG_ACCEL_GROUP  "group"
-
 static void
 glade_gtk_window_read_accel_groups (GladeWidget  *widget,
 				    GladeXmlNode *node)
@@ -11747,3 +11558,135 @@ glade_gtk_adjustment_write_widget (GladeWidgetAdaptor *adaptor,
 
         GWA_GET_CLASS (G_TYPE_OBJECT)->write_widget (adaptor, widget, context, node);
 }
+
+
+/*--------------------------- GtkAction ---------------------------------*/
+void
+glade_gtk_action_post_create (GladeWidgetAdaptor *adaptor, 
+			      GObject            *object, 
+			      GladeCreateReason   reason)
+{
+	GladeWidget *gwidget = glade_widget_get_from_gobject (object);
+
+	if (reason == GLADE_CREATE_REBUILD)
+		return;
+
+	if (!gtk_action_get_name (GTK_ACTION (object)))
+		glade_widget_property_set (gwidget, "name", "untitled");
+
+}
+
+/*--------------------------- GtkActionGroup ---------------------------------*/
+void
+glade_gtk_action_group_add_child (GladeWidgetAdaptor *adaptor,
+				  GObject            *container,
+				  GObject            *child)
+{
+	if (GTK_IS_ACTION (child))
+	{
+		/* Dont really add/remove actions (because name conflicts inside groups)
+		 */
+		GladeWidget *ggroup  = glade_widget_get_from_gobject (container);
+		GladeWidget *gaction = glade_widget_get_from_gobject (child);
+		GList       *actions = g_object_get_data (G_OBJECT (ggroup), "glade-actions");
+
+		actions = g_list_copy (actions);
+		actions = g_list_prepend (actions, child);
+
+		g_object_set_data_full (G_OBJECT (ggroup), "glade-actions", actions, 
+					(GDestroyNotify)g_list_free);
+
+		glade_widget_property_set_sensitive (gaction, "accelerator", TRUE, NULL);
+	}
+}
+
+void
+glade_gtk_action_group_remove_child (GladeWidgetAdaptor *adaptor,
+				     GObject            *container,
+				     GObject            *child)
+{
+	if (GTK_IS_ACTION (child))
+	{
+		/* Dont really add/remove actions (because name conflicts inside groups)
+		 */
+		const gchar *insensitive_msg = _("The accelerator can only be set when inside an Action Group.");
+		GladeWidget *ggroup = glade_widget_get_from_gobject (container);
+		GladeWidget *gaction = glade_widget_get_from_gobject (child);
+		GList       *actions = g_object_get_data (G_OBJECT (ggroup), "glade-actions");
+
+		actions = g_list_copy (actions);
+		actions = g_list_remove (actions, child);
+
+		g_object_set_data_full (G_OBJECT (ggroup), "glade-actions", actions, 
+					(GDestroyNotify)g_list_free);
+
+		glade_widget_property_set_sensitive (gaction, "accelerator", FALSE, insensitive_msg);
+	}
+}
+
+void
+glade_gtk_action_group_replace_child (GladeWidgetAdaptor *adaptor,
+				      GObject            *container,
+				      GObject            *current,
+				      GObject            *new_action)
+{
+	glade_gtk_action_group_remove_child (adaptor, container, current);
+	glade_gtk_action_group_add_child (adaptor, container, new_action);
+}
+
+GList *
+glade_gtk_action_group_get_children (GladeWidgetAdaptor  *adaptor,
+				     GObject        *container)
+{
+	GladeWidget *ggroup  = glade_widget_get_from_gobject (container);
+	GList       *actions = g_object_get_data (G_OBJECT (ggroup), "glade-actions");
+
+	return g_list_copy (actions);
+}
+
+
+void
+glade_gtk_action_group_read_child (GladeWidgetAdaptor *adaptor,
+				   GladeWidget        *widget,
+				   GladeXmlNode       *node)
+{
+	GladeXmlNode *widget_node;
+	GladeWidget  *child_widget;
+
+	if (!glade_xml_node_verify (node, GLADE_XML_TAG_CHILD))
+		return;
+	
+	if ((widget_node = 
+	     glade_xml_search_child
+	     (node, GLADE_XML_TAG_WIDGET(glade_project_get_format(widget->project)))) != NULL)
+	{
+		if ((child_widget = glade_widget_read (widget->project, 
+						       widget, widget_node, 
+						       NULL)) != NULL)
+		{
+			glade_widget_add_child (widget, child_widget, FALSE);
+
+			/* Read in accelerator */
+			glade_gtk_read_accels (child_widget, node, FALSE);
+		}
+	}
+}
+
+
+void
+glade_gtk_action_group_write_child (GladeWidgetAdaptor *adaptor,
+				    GladeWidget        *widget,
+				    GladeXmlContext    *context,
+				    GladeXmlNode       *node)
+{
+	GladeXmlNode *child_node;
+
+	child_node = glade_xml_node_new (context, GLADE_XML_TAG_CHILD);
+	glade_xml_node_append_child (node, child_node);
+
+	/* Write out the widget */
+	glade_widget_write (widget, context, child_node);
+
+	/* Write accelerator here  */
+	glade_gtk_write_accels (widget, context, child_node, FALSE);		
+}
diff --git a/plugins/gtk+/gtk+.xml.in b/plugins/gtk+/gtk+.xml.in
index 8682b0a..db92135 100644
--- a/plugins/gtk+/gtk+.xml.in
+++ b/plugins/gtk+/gtk+.xml.in
@@ -1951,8 +1951,12 @@ embedded in another object</_tooltip>
     </glade-widget-class>
 
     <glade-widget-class name="GtkAction" generic-name="action" _title="Action" 
-			libglade-unsupported="True" toplevel="True">
+			libglade-unsupported="True">
+      <post-create-function>glade_gtk_action_post_create</post-create-function>
+      <create-editor-property-function>glade_gtk_widget_create_eprop</create-editor-property-function>
+      <string-from-value-function>glade_gtk_widget_string_from_value</string-from-value-function>
       <properties>
+	<property id="name" disabled="True"/>
 	<property id="label" translatable="True"/>
 	<property id="short-label" translatable="True"/>
 	<property id="tooltip" translatable="True"/>
@@ -1961,6 +1965,16 @@ embedded in another object</_tooltip>
 	<property id="gicon" disabled="True" since="2.16"/>
 	<property id="action-group" disabled="True"/>
 	<property id="always-show-image" since="2.20"/>
+
+	<!-- Accelerator -->
+	<property id="accelerator" _name="Accelerator" ignore="True" 
+		  common="False" save="False" weight="2.0">
+	  <parameter-spec>
+	    <type>GParamBoxed</type>
+	    <value-type>GladeAccelGList</value-type>
+	  </parameter-spec>
+	  <_tooltip>An accelerator key for this action</_tooltip>
+	</property>
       </properties>
     </glade-widget-class>
 
@@ -1970,8 +1984,17 @@ embedded in another object</_tooltip>
 			libglade-unsupported="True"/>
     <glade-widget-class name="GtkRecentAction" generic-name="recentaction" _title="Recent Action" 
 			libglade-unsupported="True" since="2.12"/>
+
     <glade-widget-class name="GtkActionGroup" generic-name="actiongroup" _title="Action Group" 
-			libglade-unsupported="True" toplevel="True"/>
+			libglade-unsupported="True" toplevel="True" use-placeholders="False">
+      <add-child-function>glade_gtk_action_group_add_child</add-child-function>
+      <remove-child-function>glade_gtk_action_group_remove_child</remove-child-function>
+      <get-children-function>glade_gtk_action_group_get_children</get-children-function>
+      <replace-child-function>glade_gtk_action_group_replace_child</replace-child-function>
+      <read-child-function>glade_gtk_action_group_read_child</read-child-function>
+      <write-child-function>glade_gtk_action_group_write_child</write-child-function>
+    </glade-widget-class>
+
     <glade-widget-class name="GtkEntryCompletion" generic-name="entrycompletion" _title="Entry Completion" 
 			libglade-unsupported="True" toplevel="True"/>
     <glade-widget-class name="GtkUIManager" generic-name="uimanager" _title="UI Manager" 



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