summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Pablo Ugarte <jpu@src.gnome.org>2007-05-23 19:38:46 +0000
committerJuan Pablo Ugarte <jpu@src.gnome.org>2007-05-23 19:38:46 +0000
commitb9d029623faf79fd9cb70bed9653f5dffa4ec0ad (patch)
treefcb4b97d636ba45ecf440498f6c7cecc0f9d5b35
parent4e6685d2bb46ad9e9848ce21f93932d7e02b14ea (diff)
downloadglade-b9d029623faf79fd9cb70bed9653f5dffa4ec0ad.tar.gz
added gladeui/glade-widget-action.[ch]
* gladeui/Makefile.am: added gladeui/glade-widget-action.[ch] * gladeui/glade-popup.[ch]: - added glade_popup_action_populate_menu() - adapted popup code to reflect action changes. * gladeui/glade-widget-action.[ch]: GladeWidgetAction GObject sources. * gladeui/glade-widget-adaptor.[ch]: - action-activated signal removed - added GladeActionActivateFunc - added glade_widget_adaptor_action_add() and glade_widget_adaptor_action_remove() - glade_widget_adaptor_action_activate() reworked. - load symbol and other catalog stuff in gwa_derived_class_init() - added the posibility to override GObject constructor from the catalog. This is a good place to add/remove actions, use GWA_GET_OCLASS() to chain up. * gladeui/glade-widget.[ch]: - removed action-activated signal - added glade_widget_get_action (), glade_widget_remove_action() and glade_widget_create_action_menu() * gladeui/glade-xml-utils.h: added GLADE_TAG_ACTION_ACTIVATE_FUNCTION and GLADE_TAG_CONSTRUCTOR_FUNCTION tags * plugins/gtk+/glade-gtk.c: - added glade_gtk_menu_shell_action_activate() glade_gtk_menu_item_action_activate() and glade_gtk_toolbar_action_activate() - removed glade_gtk_menu_post_create() and glade_gtk_menu_launch_editor_action() * plugins/gtk+/gtk+.xml.in: - glade_gtk_menu_post_create() removed - added action-activate-function for MenuShell MenuItem and Toolbar. svn path=/trunk/; revision=1325
-rw-r--r--ChangeLog46
-rw-r--r--gladeui/Makefile.am4
-rw-r--r--gladeui/glade-popup.c94
-rw-r--r--gladeui/glade-popup.h1
-rw-r--r--gladeui/glade-widget-action.c254
-rw-r--r--gladeui/glade-widget-action.h78
-rw-r--r--gladeui/glade-widget-adaptor.c688
-rw-r--r--gladeui/glade-widget-adaptor.h52
-rw-r--r--gladeui/glade-widget.c139
-rw-r--r--gladeui/glade-widget.h13
-rw-r--r--gladeui/glade-xml-utils.h2
-rw-r--r--plugins/gtk+/glade-gtk.c102
-rw-r--r--plugins/gtk+/gtk+.xml.in5
13 files changed, 1024 insertions, 454 deletions
diff --git a/ChangeLog b/ChangeLog
index 70c21c79..2dfeb72f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,49 @@
+2007-05-23 Juan Pablo Ugarte <juanpablougarte@gmail.com>
+
+ * gladeui/Makefile.am: added gladeui/glade-widget-action.[ch]
+
+ * gladeui/glade-popup.[ch]:
+ - added glade_popup_action_populate_menu()
+
+ - adapted popup code to reflect action changes.
+
+ * gladeui/glade-widget-action.[ch]: GladeWidgetAction GObject sources.
+
+ * gladeui/glade-widget-adaptor.[ch]:
+
+ - action-activated signal removed
+
+ - added GladeActionActivateFunc
+
+ - added glade_widget_adaptor_action_add() and glade_widget_adaptor_action_remove()
+
+ - glade_widget_adaptor_action_activate() reworked.
+
+ - load symbol and other catalog stuff in gwa_derived_class_init()
+
+ - added the posibility to override GObject constructor from the catalog.
+ This is a good place to add/remove actions, use GWA_GET_OCLASS() to chain up.
+
+ * gladeui/glade-widget.[ch]:
+ - removed action-activated signal
+
+ - added glade_widget_get_action (), glade_widget_remove_action() and
+ glade_widget_create_action_menu()
+
+ * gladeui/glade-xml-utils.h: added GLADE_TAG_ACTION_ACTIVATE_FUNCTION and
+ GLADE_TAG_CONSTRUCTOR_FUNCTION tags
+
+ * plugins/gtk+/glade-gtk.c:
+ - added glade_gtk_menu_shell_action_activate() glade_gtk_menu_item_action_activate()
+ and glade_gtk_toolbar_action_activate()
+
+ - removed glade_gtk_menu_post_create() and glade_gtk_menu_launch_editor_action()
+
+ * plugins/gtk+/gtk+.xml.in:
+ - glade_gtk_menu_post_create() removed
+
+ - added action-activate-function for MenuShell MenuItem and Toolbar.
+
2007-05-18 Juan Pablo Ugarte <juanpablougarte@gmail.com>
* Patch reaplied with the missing '}' :S (bug 435912)
diff --git a/gladeui/Makefile.am b/gladeui/Makefile.am
index 70653447..33f7adca 100644
--- a/gladeui/Makefile.am
+++ b/gladeui/Makefile.am
@@ -63,7 +63,8 @@ libgladeui_1_la_SOURCES = \
glade-popup.h \
glade-catalog.h \
glade-marshallers.h \
- glade-accumulators.h
+ glade-accumulators.h \
+ glade-widget-action.c
libgladeui_1_la_CPPFLAGS = \
$(common_defines) \
@@ -113,6 +114,7 @@ libgladeuiinclude_HEADERS = \
glade-parser.h \
glade-signal.h \
glade-cursor.h \
+ glade-widget-action.h \
fixed_bg.xpm
diff --git a/gladeui/glade-popup.c b/gladeui/glade-popup.c
index 6a7ac0c8..dcf61b71 100644
--- a/gladeui/glade-popup.c
+++ b/gladeui/glade-popup.c
@@ -176,62 +176,81 @@ glade_popup_append_item (GtkWidget *popup_menu,
static void
-glade_popup_menuitem_activated (GtkMenuItem *item, GladeWidget *widget)
+glade_popup_menuitem_activated (GtkMenuItem *item, const gchar *action_path)
{
- gchar *detail;
+ GladeWidget *widget;
- if ((detail = g_object_get_data (G_OBJECT (item), "menuitem_detail")))
- glade_widget_adaptor_action_activate (widget, detail);
+ if ((widget = g_object_get_data (G_OBJECT (item), "glade-widget")))
+ glade_widget_adaptor_action_activate (widget->adaptor,
+ widget->object,
+ action_path);
}
-static void
-glade_popup_add_actions_recurse (GtkWidget *menu, GladeWidget *widget, GList *actions)
+static gint
+glade_popup_action_populate_menu_real (GtkWidget *menu,
+ GladeWidget *widget,
+ GladeWidgetAction *action)
{
- GList *list;
GtkWidget *item;
+ GList *list;
+ gint n = 0;
- for (list = widget->adaptor->actions; list; list = g_list_next (list))
+ for (list = (action) ? action->actions : widget->actions;
+ list;
+ list = g_list_next (list))
{
- GWAAction *action = list->data;
+ GladeWidgetAction *a = list->data;
GtkWidget *submenu = NULL;
-
- if (action->actions)
+
+ if (a->actions)
{
submenu = gtk_menu_new ();
- glade_popup_add_actions_recurse (submenu, widget, action->actions);
+ n += glade_popup_action_populate_menu (submenu, widget, a);
}
-
- if (action->is_a_group && submenu == NULL) continue;
-
+
item = glade_popup_append_item (menu,
- action->stock,
- action->label, TRUE,
- (action->is_a_group) ? NULL : glade_popup_menuitem_activated,
- (action->is_a_group) ? NULL : widget);
-
- if (action->is_a_group == FALSE)
- g_object_set_data (G_OBJECT (item), "menuitem_detail", action->id);
+ a->klass->stock,
+ a->klass->label, TRUE,
+ (a->actions) ? NULL : glade_popup_menuitem_activated,
+ (a->actions) ? NULL : a->klass->path);
+
+ g_object_set_data (G_OBJECT (item), "glade-widget", widget);
+ gtk_widget_set_sensitive (item, a->sensitive);
if (submenu)
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
+
+ n++;
}
+ return n;
}
-static void
-glade_popup_add_actions (GtkWidget *menu, GladeWidget *widget)
+/*
+ * glade_popup_action_populate_menu:
+ * @menu: a GtkMenu to put the actions menu items.
+ * @widget: A #GladeWidget
+ * @action: a @widget subaction or NULL to include all actions.
+ *
+ * Populate a GtkMenu with widget's actions
+ *
+ * Returns the number of action appended to the menu.
+ */
+gint
+glade_popup_action_populate_menu (GtkWidget *menu,
+ GladeWidget *widget,
+ GladeWidgetAction *action)
{
- GtkWidget *separator;
-
- if (widget->adaptor->actions)
+ g_return_val_if_fail (GTK_IS_MENU (menu), 0);
+ g_return_val_if_fail (GLADE_IS_WIDGET (widget), 0);
+ if (action)
{
- separator = gtk_menu_item_new ();
- gtk_widget_show (separator);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu),
- separator);
-
- glade_popup_add_actions_recurse (menu, widget, widget->adaptor->actions);
+ g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (action), 0);
+ if (action != glade_widget_get_action (widget, action->klass->path))
+ return 0;
}
+
+ return glade_popup_action_populate_menu_real (menu, widget, action);
}
static GtkWidget *
@@ -256,7 +275,14 @@ glade_popup_create_menu (GladeWidget *widget)
glade_popup_append_item (popup_menu, GTK_STOCK_DELETE, NULL, TRUE,
glade_popup_delete_cb, widget);
- glade_popup_add_actions (popup_menu, widget);
+ if (widget->actions)
+ {
+ GtkWidget *separator = gtk_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), separator);
+ gtk_widget_show (separator);
+
+ glade_popup_action_populate_menu (popup_menu, widget, NULL);
+ }
return popup_menu;
}
diff --git a/gladeui/glade-popup.h b/gladeui/glade-popup.h
index 5844878a..8a1025ef 100644
--- a/gladeui/glade-popup.h
+++ b/gladeui/glade-popup.h
@@ -7,6 +7,7 @@ G_BEGIN_DECLS
void glade_popup_widget_pop (GladeWidget *widget, GdkEventButton *event);
void glade_popup_placeholder_pop (GladePlaceholder *placeholder, GdkEventButton *event);
void glade_popup_clipboard_pop (GladeWidget *widget, GdkEventButton *event);
+gint glade_popup_action_populate_menu (GtkWidget *menu, GladeWidget *widget, GladeWidgetAction *action);
G_END_DECLS
diff --git a/gladeui/glade-widget-action.c b/gladeui/glade-widget-action.c
new file mode 100644
index 00000000..97889af5
--- /dev/null
+++ b/gladeui/glade-widget-action.c
@@ -0,0 +1,254 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Juan Pablo Ugarte.
+ *
+ * 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:
+ * Juan Pablo Ugarte <juanpablougarte@gmail.com>
+ */
+
+#include "glade-widget-action.h"
+
+enum
+{
+ PROP_0,
+
+ PROP_KLASS,
+ PROP_SENSITIVE
+};
+
+
+static GObjectClass* parent_class = NULL;
+
+G_DEFINE_TYPE (GladeWidgetAction, glade_widget_action, G_TYPE_OBJECT);
+
+static void
+glade_widget_action_init (GladeWidgetAction *object)
+{
+ object->sensitive = TRUE;
+ object->actions = NULL;
+}
+
+static void
+glade_widget_action_finalize (GObject *object)
+{
+ GladeWidgetAction *action = GLADE_WIDGET_ACTION (object);
+
+ if (action->actions)
+ {
+ g_list_foreach (action->actions, (GFunc)g_object_unref, NULL);
+ g_list_free (action->actions);
+ }
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static GObject *
+glade_widget_action_constructor(GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GladeWidgetAction *action;
+ GObject *object;
+ GList *l;
+
+ object = G_OBJECT_CLASS (parent_class)->constructor (type,
+ n_construct_properties,
+ construct_properties);
+ action = GLADE_WIDGET_ACTION (object);
+
+ if (action->klass == NULL)
+ {
+ g_warning ("GLadeWidgetAction constructed without klass properties");
+ return object;
+ }
+
+ for (l = action->klass->actions; l; l = g_list_next (l))
+ {
+ GWActionClass *action_class = l->data;
+ GObject *obj = g_object_new (GLADE_TYPE_WIDGET_ACTION,
+ "klass", action_class,
+ NULL);
+
+ action->actions = g_list_prepend (action->actions,
+ GLADE_WIDGET_ACTION (obj));
+ }
+
+ action->actions = g_list_reverse (action->actions);
+
+ return object;
+}
+
+static void
+glade_widget_action_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GladeWidgetAction *action = GLADE_WIDGET_ACTION (object);
+
+ g_return_if_fail (GLADE_IS_WIDGET_ACTION (object));
+
+ switch (prop_id)
+ {
+ case PROP_KLASS:
+ action->klass = g_value_get_pointer (value);
+ break;
+ case PROP_SENSITIVE:
+ action->sensitive = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+glade_widget_action_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GladeWidgetAction *action = GLADE_WIDGET_ACTION (object);
+
+ g_return_if_fail (GLADE_IS_WIDGET_ACTION (object));
+
+ switch (prop_id)
+ {
+ case PROP_KLASS:
+ g_value_set_pointer (value, action->klass);
+ break;
+ case PROP_SENSITIVE:
+ g_value_set_boolean (value, action->sensitive);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+glade_widget_action_class_init (GladeWidgetActionClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+ parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
+
+ object_class->constructor = glade_widget_action_constructor;
+ object_class->finalize = glade_widget_action_finalize;
+ object_class->set_property = glade_widget_action_set_property;
+ object_class->get_property = glade_widget_action_get_property;
+
+ g_object_class_install_property (object_class,
+ PROP_KLASS,
+ g_param_spec_pointer ("klass",
+ "class",
+ "GladeWidgetActionClass",
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_SENSITIVE,
+ g_param_spec_boolean ("sensitive",
+ "Sensitive",
+ "Wheater or not this action is sensitive",
+ TRUE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+}
+
+/**
+ * glade_widegt_action_class_free:
+ * @action: a GWActionClass
+ *
+ * Frees a GWActionClass.
+ */
+void
+glade_widget_action_class_free (GWActionClass *action)
+{
+ if (action->actions)
+ g_list_foreach (action->actions, (GFunc)glade_widget_action_class_free, NULL);
+
+ /*Dont free id since it points to path*/
+ g_free (action->path);
+ g_free (action->label);
+ g_free (action->stock);
+ g_free (action);
+}
+
+/**
+ * glade_widget_action_class_clone:
+ * @action: a GWActionClass
+ *
+ * Returns: a newlly allocated copy of @action.
+ */
+GWActionClass *
+glade_widget_action_class_clone (GWActionClass *action)
+{
+ GWActionClass *copy;
+ GList *l;
+
+ g_return_val_if_fail (action != NULL, NULL);
+
+ copy = g_new0 (GWActionClass, 1);
+ copy->id = g_strdup (action->id);
+ copy->label = g_strdup (action->label);
+ copy->stock = g_strdup (action->stock);
+
+ for (l = action->actions; l; l = g_list_next (l))
+ {
+ GWActionClass *child = glade_widget_action_class_clone (l->data);
+ copy->actions = g_list_append (copy->actions, child);
+ }
+
+ return copy;
+}
+
+/**
+ * glade_widget_action_remove:
+ * @action: a #GladeWidgetAction
+ * @child: a #GladeWidgetAction
+ *
+ * Remove an action.
+ *
+ * Returns: whether or not @child was removed from @action.
+ */
+gboolean
+glade_widget_action_remove (GladeWidgetAction *action,
+ GladeWidgetAction *child)
+{
+ GList *l;
+
+ g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (action), FALSE);
+ g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (child), FALSE);
+
+ for (l = action->actions; l; l = g_list_next (l))
+ {
+ if (child == l->data)
+ {
+ action->actions = g_list_remove (action->actions, child);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * glade_widget_action_set_sensitive:
+ * @action: a #GladeWidgetAction
+ * @sensitive:
+ *
+ * Set whether or not this action is sensitive.
+ *
+ */
+void
+glade_widget_action_set_sensitive (GladeWidgetAction *action, gboolean sensitive)
+{
+ g_return_if_fail (GLADE_IS_WIDGET_ACTION (action));
+ g_object_set (G_OBJECT (action), "sensitive", sensitive, NULL);
+}
diff --git a/gladeui/glade-widget-action.h b/gladeui/glade-widget-action.h
new file mode 100644
index 00000000..aae3484d
--- /dev/null
+++ b/gladeui/glade-widget-action.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Juan Pablo Ugarte.
+ *
+ * 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:
+ * Juan Pablo Ugarte <juanpablougarte@gmail.com>
+ */
+
+#ifndef _GLADE_WIDGET_ACTION_H_
+#define _GLADE_WIDGET_ACTION_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GLADE_TYPE_WIDGET_ACTION (glade_widget_action_get_type ())
+#define GLADE_WIDGET_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_WIDGET_ACTION, GladeWidgetAction))
+#define GLADE_WIDGET_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_WIDGET_ACTION, GladeWidgetActionClass))
+#define GLADE_IS_WIDGET_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_WIDGET_ACTION))
+#define GLADE_IS_WIDGET_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_WIDGET_ACTION))
+#define GLADE_WIDGET_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_TYPE_WIDGET_ACTION, GladeWidgetActionClass))
+
+typedef struct _GladeWidgetActionClass GladeWidgetActionClass;
+typedef struct _GladeWidgetAction GladeWidgetAction;
+typedef struct _GWActionClass GWActionClass;
+
+struct _GWActionClass
+{
+ gchar *id; /* The identifier of this action in the action tree */
+ gchar *path; /* Full action path */
+ gchar *label; /* A translated label to show in the UI for this action */
+ gchar *stock; /* If set, this stock item will be shown in the UI along side
+ * the label */
+ GList *actions; /* Recursive list of child actions */
+};
+
+struct _GladeWidgetActionClass
+{
+ GObjectClass parent_class;
+};
+
+struct _GladeWidgetAction
+{
+ GObject parent_instance;
+
+ GWActionClass *klass; /* The action class */
+
+ gboolean sensitive; /* If this action is sensitive or not */
+
+ GList *actions; /* List of actions */
+};
+
+GType glade_widget_action_get_type (void) G_GNUC_CONST;
+
+void glade_widget_action_class_free (GWActionClass *action);
+
+GWActionClass *glade_widget_action_class_clone (GWActionClass *action);
+
+gboolean glade_widget_action_remove (GladeWidgetAction *action,
+ GladeWidgetAction *child);
+
+G_END_DECLS
+
+#endif /* _GLADE_WIDGET_ACTION_H_ */
diff --git a/gladeui/glade-widget-adaptor.c b/gladeui/glade-widget-adaptor.c
index 3f3dc165..32abba43 100644
--- a/gladeui/glade-widget-adaptor.c
+++ b/gladeui/glade-widget-adaptor.c
@@ -79,16 +79,8 @@ enum {
PROP_CURSOR
};
-enum
-{
- SIGNAL_ACTION_ACTIVATED,
- LAST_SIGNAL
-};
-
typedef struct _GladeChildPacking GladeChildPacking;
-static guint gwa_signals [LAST_SIGNAL] = {0,};
-
static GObjectClass *parent_class = NULL;
static GHashTable *adaptor_hash = NULL;
@@ -481,40 +473,6 @@ gwa_inherit_child_packing (GladeWidgetAdaptor *adaptor)
return child_packings;
}
-static GList *
-gwa_action_copy (GList *src)
-{
- GList *l, *list = NULL;
-
- for (l = src; l; l = g_list_next (l))
- {
- GWAAction *action = l->data, *copy = g_new0 (GWAAction, 1);
-
- copy->id = g_strdup (action->id);
- copy->label = g_strdup (action->label);
- copy->stock = g_strdup (action->stock);
- copy->is_a_group = action->is_a_group;
-
- list = g_list_append (list, l->data);
-
- if (action->actions)
- copy->actions = gwa_action_copy (action->actions);
- }
-
- return list;
-}
-
-static void
-gwa_action_setup (GladeWidgetAdaptor *adaptor)
-{
- GladeWidgetAdaptor *parent = gwa_get_parent_adaptor (adaptor);
-
- if (parent && parent->actions)
- adaptor->actions = gwa_action_copy (parent->actions);
- else
- adaptor->actions = NULL;
-}
-
static GObject *
glade_widget_adaptor_constructor (GType type,
guint n_construct_properties,
@@ -564,7 +522,18 @@ glade_widget_adaptor_constructor (GType type,
parent_adaptor->priv->special_child_type ?
g_strdup (parent_adaptor->priv->special_child_type) : NULL;
- gwa_action_setup (adaptor);
+ /* Copy parent actions */
+ if (parent_adaptor && parent_adaptor->actions)
+ {
+ GList *l;
+ for (l = parent_adaptor->actions; l; l = g_list_next (l))
+ {
+ GWActionClass *child = glade_widget_action_class_clone (l->data);
+ adaptor->actions = g_list_append (adaptor->actions, child);
+ }
+ }
+ else
+ adaptor->actions = NULL;
return ret_obj;
}
@@ -586,25 +555,6 @@ gwa_child_packing_free (GladeChildPacking *packing)
g_list_free (packing->packing_defaults);
}
-static void
-gwa_actions_free (GList *actions)
-{
- GList *l;
-
- for (l = actions; l; l = g_list_next (l))
- {
- GWAAction *action = l->data;
-
- if (action->actions) gwa_actions_free (action->actions);
-
- g_free (action->id);
- g_free (action->label);
- g_free (action->stock);
- g_free (action);
- }
- g_list_free (actions);
-}
-
static void
glade_widget_adaptor_finalize (GObject *object)
{
@@ -640,7 +590,10 @@ glade_widget_adaptor_finalize (GObject *object)
if (adaptor->title) g_free (adaptor->title);
if (adaptor->icon_name) g_free (adaptor->icon_name);
- if (adaptor->actions) gwa_actions_free (adaptor->actions);
+ if (adaptor->actions)
+ g_list_foreach (adaptor->actions,
+ (GFunc) glade_widget_action_class_free,
+ NULL);
g_free (adaptor->priv);
@@ -747,6 +700,14 @@ glade_widget_adaptor_object_get_property (GladeWidgetAdaptor *adaptor,
g_object_get_property (object, property_name, value);
}
+static void
+glade_widget_adaptor_object_action_activate (GladeWidgetAdaptor *adaptor,
+ GObject *object,
+ const gchar *action_id)
+{
+ g_message ("No action_activate() support in adaptor %s for action '%s'",
+ adaptor->name, action_id);
+}
/*******************************************************************************
GladeWidgetAdaptor type registration and class initializer
@@ -757,23 +718,6 @@ glade_widget_adaptor_init (GladeWidgetAdaptor *adaptor)
adaptor->priv = GLADE_WIDGET_ADAPTOR_GET_PRIVATE (adaptor);
}
-static gboolean
-gwa_action_activated_impl (GladeWidgetAdaptor *adaptor,
- GladeWidget *widget,
- const gchar *action_id)
-{
- static guint signal = 0;
- gboolean retval;
-
- if (signal == 0)
- signal = g_signal_lookup ("action-activated", GLADE_TYPE_WIDGET);
-
- g_signal_emit (widget, signal, g_quark_from_string (action_id),
- action_id, &retval);
-
- return retval;
-}
-
static void
glade_widget_adaptor_class_init (GladeWidgetAdaptorClass *adaptor_class)
{
@@ -801,8 +745,7 @@ glade_widget_adaptor_class_init (GladeWidgetAdaptorClass *adaptor_class)
adaptor_class->get_children = NULL;
adaptor_class->child_set_property = NULL;
adaptor_class->child_get_property = NULL;
-
- adaptor_class->action_activated = gwa_action_activated_impl;
+ adaptor_class->action_activate = glade_widget_adaptor_object_action_activate;
/* Base defaults here */
adaptor_class->fixed = FALSE;
@@ -811,26 +754,6 @@ glade_widget_adaptor_class_init (GladeWidgetAdaptorClass *adaptor_class)
adaptor_class->default_width = -1;
adaptor_class->default_height = -1;
- /**
- * GladeWidgetAdaptor::action-activated:
- * @adaptor: the GladeWidgetAdaptor which received the signal.
- * @widget: the action's GladeWidget or NULL.
- * @action_id: the action id (signal detail) or NULL.
- *
- * Use this to catch up actions.
- *
- * Returns TRUE to stop others handlers being invoked.
- *
- */
- gwa_signals [SIGNAL_ACTION_ACTIVATED] =
- g_signal_new ("action-activated",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
- G_STRUCT_OFFSET (GladeWidgetAdaptorClass, action_activated),
- glade_boolean_handled_accumulator, NULL,
- glade_marshal_BOOLEAN__OBJECT_STRING,
- G_TYPE_BOOLEAN, 2, GLADE_TYPE_WIDGET, G_TYPE_STRING);
-
/* Properties */
g_object_class_install_property
(object_class, PROP_NAME,
@@ -903,7 +826,7 @@ glade_widget_adaptor_class_init (GladeWidgetAdaptorClass *adaptor_class)
("cursor", _("Cursor"),
_("A cursor for inserting widgets in the UI"),
G_PARAM_READABLE));
-
+
g_type_class_add_private (adaptor_class, sizeof (GladeWidgetAdaptorPrivate));
}
@@ -959,26 +882,163 @@ glade_create_reason_get_type (void)
/*******************************************************************************
Synthetic Object Derivation
*******************************************************************************/
+typedef struct
+{
+ GladeXmlNode *node;
+ GModule *module;
+} GWADerivedClassData;
+
static void
-gwa_derived_init (GladeWidgetAdaptor *adaptor)
+gwa_derived_init (GladeWidgetAdaptor *adaptor, gpointer g_class)
{
}
static void
-gwa_derived_class_init (GladeWidgetAdaptorClass *adaptor_class)
+gwa_extend_with_node_load_sym (GladeWidgetAdaptorClass *klass,
+ GladeXmlNode *node,
+ GModule *module)
{
+ GladeWidgetAdaptorClass *parent_class = g_type_class_peek_parent (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ gpointer symbol;
+
+ /*
+ * We use a temporary variable to avoid a bogus gcc warning.
+ * the thing it that g_module_symbol() should use a function pointer
+ * instead of a gpointer!
+ */
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_CONSTRUCTOR_FUNCTION,
+ &symbol))
+ object_class->constructor = symbol;
+ else
+ /* Chain up with parent, this way GWA_GET_OCLASS can work */
+ object_class->constructor = ((GObjectClass*)parent_class)->constructor;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_POST_CREATE_FUNCTION,
+ &symbol))
+ klass->post_create = symbol;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_GET_INTERNAL_CHILD_FUNCTION,
+ &symbol))
+ klass->get_internal_child = symbol;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_SET_FUNCTION,
+ &symbol))
+ klass->set_property = symbol;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_GET_FUNCTION,
+ &symbol))
+ klass->get_property = symbol;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_VERIFY_FUNCTION,
+ &symbol))
+ klass->verify_property = symbol;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_ADD_CHILD_FUNCTION,
+ &symbol))
+ klass->add = symbol;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_REMOVE_CHILD_FUNCTION,
+ &symbol))
+ klass->remove = symbol;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_GET_CHILDREN_FUNCTION,
+ &symbol))
+ klass->get_children = symbol;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_CHILD_SET_PROP_FUNCTION,
+ &symbol))
+ klass->child_set_property = symbol;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_CHILD_GET_PROP_FUNCTION,
+ &symbol))
+ klass->child_get_property = symbol;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_CHILD_VERIFY_FUNCTION,
+ &symbol))
+ klass->child_verify_property = symbol;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_REPLACE_CHILD_FUNCTION,
+ &symbol))
+ klass->replace_child = symbol;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_ACTION_ACTIVATE_FUNCTION,
+ &symbol))
+ klass->action_activate = symbol;
+ else
+ /* Chain up with parent */
+ klass->action_activate = parent_class->action_activate;
+}
+
+static void
+gwa_derived_class_init (GladeWidgetAdaptorClass *adaptor_class,
+ GWADerivedClassData *data)
+{
+ GladeXmlNode *node = data->node;
+ GModule *module = data->module;
+
+ /* Load catalog symbols from module */
+ if (module) gwa_extend_with_node_load_sym (adaptor_class, node, module);
+
+ adaptor_class->fixed =
+ glade_xml_get_property_boolean
+ (node, GLADE_TAG_FIXED, adaptor_class->fixed);
+
+ /* Check if this class is toplevel */
+ adaptor_class->toplevel =
+ glade_xml_get_property_boolean
+ (node, GLADE_TAG_TOPLEVEL, adaptor_class->toplevel);
+
+ /* Check if this class uses placeholders for child widgets */
+ adaptor_class->use_placeholders =
+ glade_xml_get_property_boolean
+ (node, GLADE_TAG_USE_PLACEHOLDERS, adaptor_class->use_placeholders);
+
+ /* Check default size when used as a toplevel in the GladeDesignView */
+ adaptor_class->default_width =
+ glade_xml_get_property_int
+ (node, GLADE_TAG_DEFAULT_WIDTH, adaptor_class->default_width);
+ adaptor_class->default_height =
+ glade_xml_get_property_int
+ (node, GLADE_TAG_DEFAULT_HEIGHT, adaptor_class->default_height);
}
static GType
-gwa_derive_adaptor_for_type (GType object_type)
+gwa_derive_adaptor_for_type (GType object_type, GWADerivedClassData *data)
{
GladeWidgetAdaptor *adaptor;
GType iter_type, derived_type;
GType parent_type = GLADE_TYPE_WIDGET_ADAPTOR;
gchar *type_name;
-
+ GTypeInfo adaptor_info =
+ {
+ sizeof (GladeWidgetAdaptorClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gwa_derived_class_init,
+ (GClassFinalizeFunc) NULL,
+ data, /* class_data */
+ sizeof (GladeWidgetAdaptor),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gwa_derived_init,
+ };
+
for (iter_type = g_type_parent (object_type);
iter_type > 0;
iter_type = g_type_parent (iter_type))
@@ -995,12 +1055,9 @@ gwa_derive_adaptor_for_type (GType object_type)
* to the type system
*/
type_name = g_strdup_printf ("Glade%sAdaptor", g_type_name (object_type));
- derived_type =
- g_type_register_static_simple (parent_type, type_name,
- sizeof (GladeWidgetAdaptorClass),
- (GClassInitFunc)gwa_derived_class_init,
- sizeof (GladeWidgetAdaptor),
- (GInstanceInitFunc)gwa_derived_init, 0);
+ derived_type = g_type_register_static (parent_type, type_name,
+ &adaptor_info, 0);
+
return derived_type;
}
@@ -1226,83 +1283,13 @@ gwa_update_properties_from_node (GladeWidgetAdaptor *adaptor,
}
}
-static GList **
-gwa_action_lookup (GList **actions, const gchar *id, gboolean only_group)
-{
- GList **group = actions, *l;
-
- for (l = *actions; l; l = g_list_next (l))
- {
- GWAAction *action = l->data;
-
- if (only_group && action->is_a_group == FALSE) continue;
-
- if (strcmp (action->id, id) == 0)
- return (only_group) ? &action->actions : group;
-
- if (action->is_a_group && action->actions &&
- (group = gwa_action_lookup (&action->actions, id, only_group)))
- return group;
- }
-
- return NULL;
-}
-
-/*
- * gwa_action_append:
- *
- * @adaptor: the GladeWidgetAdaptor.
- * @group_id: the group id weater to append this action or NULL.
- * @id: the id of the action.
- * @label: the label of the action or NULL.
- * @stock: the stock id of the action or NULL (ie: "gtk-delete").
- * @is_a_group: if this is an action group.
- *
- * Append a new GWAAction to @adaptor.
- *
- * Returns weater or not the action wass appended
- *
- */
-static gboolean
-gwa_action_append (GladeWidgetAdaptor *adaptor,
- const gchar *group_id,
- const gchar *id,
- const gchar *label,
- const gchar *stock,
- gboolean is_a_group)
-{
- GList **group;
- GWAAction *action;
-
- g_return_val_if_fail (id != NULL, FALSE);
-
- if (group_id)
- {
- group = gwa_action_lookup (&adaptor->actions, group_id, TRUE);
- if (group == NULL) return FALSE;
- }
- else group = &adaptor->actions;
-
- if (gwa_action_lookup (&adaptor->actions, id, FALSE)) return FALSE;
-
- action = g_new0 (GWAAction, 1);
- action->id = g_strdup (id);
- action->label = (label) ? g_strdup (label) : NULL;
- action->stock = (stock) ? g_strdup (stock) : NULL;
- action->is_a_group = is_a_group;
-
- *group = g_list_prepend (*group, action);
-
- return TRUE;
-}
-
static void
-gwa_update_actions (GladeWidgetAdaptor *adaptor,
- GladeXmlNode *node,
- gchar *group_id)
+gwa_action_update_from_node (GladeWidgetAdaptor *adaptor,
+ GladeXmlNode *node,
+ gchar *group_path)
{
GladeXmlNode *child;
- gchar *id, *label, *stock;
+ gchar *id, *label, *stock, *action_path;
gboolean group;
for (child = glade_xml_node_get_children (node);
@@ -1317,128 +1304,33 @@ gwa_update_actions (GladeWidgetAdaptor *adaptor,
if (id == NULL)
continue;
+ if (group_path)
+ action_path = g_strdup_printf ("%s/%s", group_path, id);
+ else
+ action_path = id;
+
label = glade_xml_get_property_string (child, GLADE_TAG_NAME);
stock = glade_xml_get_property_string (child, GLADE_TAG_STOCK);
- gwa_action_append (adaptor, group_id, id,
- (label == NULL && stock == NULL) ? id : label,
- stock, group);
- if (group) gwa_update_actions (adaptor, child, id);
-
+ glade_widget_adaptor_action_add (adaptor, action_path, label, stock);
+
+ if (group) gwa_action_update_from_node (adaptor, child, action_path);
+
g_free (id);
g_free (label);
g_free (stock);
+ if (group_path) g_free (action_path);
}
}
-static void
-gwa_extend_with_node_load_sym (GladeWidgetAdaptorClass *klass,
- GladeXmlNode *node,
- GModule *module)
-{
- gpointer symbol;
-
- /*
- * We use a temporary variable to avoid a bogus gcc warning.
- * the thing it that g_module_symbol() should use a function pointer
- * instead of a gpointer!
- */
-
- if (glade_xml_load_sym_from_node (node, module,
- GLADE_TAG_POST_CREATE_FUNCTION,
- &symbol))
- klass->post_create = symbol;
-
- if (glade_xml_load_sym_from_node (node, module,
- GLADE_TAG_GET_INTERNAL_CHILD_FUNCTION,
- &symbol))
- klass->get_internal_child = symbol;
-
- if (glade_xml_load_sym_from_node (node, module,
- GLADE_TAG_SET_FUNCTION,
- &symbol))
- klass->set_property = symbol;
-
- if (glade_xml_load_sym_from_node (node, module,
- GLADE_TAG_GET_FUNCTION,
- &symbol))
- klass->get_property = symbol;
-
- if (glade_xml_load_sym_from_node (node, module,
- GLADE_TAG_VERIFY_FUNCTION,
- &symbol))
- klass->verify_property = symbol;
-
- if (glade_xml_load_sym_from_node (node, module,
- GLADE_TAG_ADD_CHILD_FUNCTION,
- &symbol))
- klass->add = symbol;
-
- if (glade_xml_load_sym_from_node (node, module,
- GLADE_TAG_REMOVE_CHILD_FUNCTION,
- &symbol))
- klass->remove = symbol;
-
- if (glade_xml_load_sym_from_node (node, module,
- GLADE_TAG_GET_CHILDREN_FUNCTION,
- &symbol))
- klass->get_children = symbol;
-
- if (glade_xml_load_sym_from_node (node, module,
- GLADE_TAG_CHILD_SET_PROP_FUNCTION,
- &symbol))
- klass->child_set_property = symbol;
-
- if (glade_xml_load_sym_from_node (node, module,
- GLADE_TAG_CHILD_GET_PROP_FUNCTION,
- &symbol))
- klass->child_get_property = symbol;
-
- if (glade_xml_load_sym_from_node (node, module,
- GLADE_TAG_CHILD_VERIFY_FUNCTION,
- &symbol))
- klass->child_verify_property = symbol;
-
- if (glade_xml_load_sym_from_node (node, module,
- GLADE_TAG_REPLACE_CHILD_FUNCTION,
- &symbol))
- klass->replace_child = symbol;
-}
-
static gboolean
gwa_extend_with_node (GladeWidgetAdaptor *adaptor,
GladeXmlNode *node,
GModule *module,
const gchar *domain)
{
- GladeWidgetAdaptorClass *adaptor_class = GLADE_WIDGET_ADAPTOR_GET_CLASS (adaptor);
GladeXmlNode *child;
gchar *child_type;
-
- /* Load catalog symbols from module */
- if (module) gwa_extend_with_node_load_sym (adaptor_class, node, module);
-
- adaptor_class->fixed =
- glade_xml_get_property_boolean
- (node, GLADE_TAG_FIXED, adaptor_class->fixed);
-
- /* Check if this class is toplevel */
- adaptor_class->toplevel =
- glade_xml_get_property_boolean
- (node, GLADE_TAG_TOPLEVEL, adaptor_class->toplevel);
-
- /* Check if this class uses placeholders for child widgets */
- adaptor_class->use_placeholders =
- glade_xml_get_property_boolean
- (node, GLADE_TAG_USE_PLACEHOLDERS, adaptor_class->use_placeholders);
-
- /* Check default size when used as a toplevel in the GladeDesignView */
- adaptor_class->default_width =
- glade_xml_get_property_int
- (node, GLADE_TAG_DEFAULT_WIDTH, adaptor_class->default_width);
- adaptor_class->default_height =
- glade_xml_get_property_int
- (node, GLADE_TAG_DEFAULT_HEIGHT, adaptor_class->default_height);
/* Override the special-child-type here */
if ((child_type =
@@ -1462,9 +1354,9 @@ gwa_extend_with_node (GladeWidgetAdaptor *adaptor,
if ((child =
glade_xml_search_child (node, GLADE_TAG_PACKING_DEFAULTS)) != NULL)
gwa_set_packing_defaults_from_node (adaptor, child);
-
- /* Search for actions */
- gwa_update_actions (adaptor, node, NULL);
+
+ /* Update actions from node */
+ gwa_action_update_from_node (adaptor, node, NULL);
return TRUE;
}
@@ -1539,7 +1431,8 @@ glade_widget_adaptor_from_catalog (GladeXmlNode *class_node,
GladeWidgetAdaptor *adaptor = NULL;
gchar *name, *generic_name, *icon_name, *adaptor_icon_name, *adaptor_name, *func_name;
GType object_type, adaptor_type, parent_type;
-
+ GWADerivedClassData data;
+
if (!glade_xml_node_verify (class_node, GLADE_TAG_GLADE_WIDGET_CLASS))
{
g_warning ("Widget class node is not '%s'",
@@ -1575,7 +1468,16 @@ glade_widget_adaptor_from_catalog (GladeXmlNode *class_node,
if ((adaptor_name = glade_xml_get_property_string (class_node, GLADE_TAG_ADAPTOR)))
adaptor_type = g_type_from_name (adaptor_name);
else
- adaptor_type = gwa_derive_adaptor_for_type (object_type);
+ {
+ /*
+ * We use this struct pointer to pass data to
+ * gwa_derived_class_init() because we must override constructor()
+ * from the catalog before calling g_object_new() :P
+ */
+ data.node = class_node;
+ data.module = module;
+ adaptor_type = gwa_derive_adaptor_for_type (object_type, &data);
+ }
if (adaptor_type == 0)
{
@@ -2410,60 +2312,182 @@ glade_widget_adaptor_get_packing_default (GladeWidgetAdaptor *child_adaptor,
return NULL;
}
-/*
- * glade_widget_adaptor_action_activate:
- *
- * @widget: the GladeWidget.
- * @action_id: The action id (detail of GladeWidgetAdaptor's action-activated signal).
+/**
+ * glade_widget_adaptor_is_container:
+ * @adaptor: A #GladeWidgetAdaptor
*
- * Emit @widget's adaptor action-activated::@action_id signal.
- * GladeWidget's action-activated proxy signal is also emited.
+ * Checks whether or not this adaptor has support
+ * to interface with child objects.
*
+ * Returns whether or not @adaptor is a container
*/
-void
-glade_widget_adaptor_action_activate (GladeWidget *widget, const gchar *action_id)
+gboolean
+glade_widget_adaptor_is_container (GladeWidgetAdaptor *adaptor)
{
- GladeWidgetAdaptor *adaptor;
- GQuark detail;
- guint signal;
- gboolean retval;
+
+ g_return_val_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor), FALSE);
+
+ /* A GWA container must at least implement add/remove/get_children
+ */
+ return (GLADE_WIDGET_ADAPTOR_GET_CLASS (adaptor)->add &&
+ GLADE_WIDGET_ADAPTOR_GET_CLASS (adaptor)->remove &&
+ GLADE_WIDGET_ADAPTOR_GET_CLASS (adaptor)->get_children);
+}
+
+static const gchar *
+gwa_action_path_get_id (const gchar *action_path)
+{
+ const gchar *id;
- g_return_if_fail (GLADE_IS_WIDGET (widget) && action_id);
+ if ((id = g_strrstr (action_path, "/")) && id[1] != '\0')
+ return &id[1];
+ else
+ return action_path;
+}
- signal = gwa_signals [SIGNAL_ACTION_ACTIVATED];
- detail = g_quark_from_string (action_id);
+static GWActionClass *
+gwa_action_lookup (GList *actions, const gchar *action_id)
+{
+ GList *l;
- for (adaptor = widget->adaptor;
- adaptor;
- adaptor = gwa_get_parent_adaptor (adaptor))
+ for (l = actions; l; l = g_list_next (l))
{
- if (gwa_action_lookup (&adaptor->actions, action_id, FALSE))
- g_signal_emit (adaptor, signal, detail, widget,
- action_id, &retval);
- else
- return;
+ GWActionClass *action = l->data;
+ if (strcmp (action->id, action_id) == 0)
+ return action;
}
+
+ return NULL;
}
+static GWActionClass *
+gwa_action_get_last_group (GladeWidgetAdaptor *adaptor,
+ const gchar *action_path)
+{
+ gchar **tokens = g_strsplit (action_path, "/", 0);
+ GList *list = adaptor->actions;
+ GWActionClass *group = NULL;
+ gint i;
+
+ for (i = 0; tokens[i] && tokens[i+1]; i++)
+ {
+ if ((group = gwa_action_lookup (list, tokens[i])) == NULL)
+ {
+ g_strfreev (tokens);
+ return NULL;
+ }
+ list = group->actions;
+ }
+
+ g_strfreev (tokens);
+ return group;
+}
/**
- * glade_widget_adaptor_is_container:
+ * glade_widget_adaptor_action_add:
* @adaptor: A #GladeWidgetAdaptor
+ * @action_path: The identifier of this action in the action tree
+ * @label: A translated label to show in the UI for this action
+ * @stock: If set, this stock item will be shown in the UI along side the label.
*
- * Checks whether or not this adaptor has support
- * to interface with child objects.
+ * Add an action to @adaptor.
+ * If the action is present then it overrides label and stock
*
- * Returns whether or not @adaptor is a container
+ * Returns: whether or not the action was added/updated.
*/
gboolean
-glade_widget_adaptor_is_container (GladeWidgetAdaptor *adaptor)
-{
+glade_widget_adaptor_action_add (GladeWidgetAdaptor *adaptor,
+ const gchar *action_path,
+ const gchar *label,
+ const gchar *stock)
+{
+ GWActionClass *action, *group;
+ const gchar *id;
+ GList **list;
+
+ g_return_val_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor), FALSE);
+ g_return_val_if_fail (action_path != NULL, FALSE);
+
+ id = gwa_action_path_get_id (action_path);
+
+ if ((group = gwa_action_get_last_group (adaptor, action_path)))
+ list = &group->actions;
+ else
+ list = &adaptor->actions;
+
+ if ((action = gwa_action_lookup (*list, id)))
+ {
+ if (action->label) g_free (action->label);
+ if (action->stock) g_free (action->stock);
+ }
+ else
+ {
+ action = g_new0 (GWActionClass, 1);
+ action->path = g_strdup (action_path);
+ action->id = (gchar*) gwa_action_path_get_id (action->path);
+ }
+
+ action->label = (label) ? g_strdup (label) : NULL;
+ action->stock = (stock) ? g_strdup (stock) : NULL;
+
+ *list = g_list_prepend (*list, action);
+
+ return TRUE;
+}
+/**
+ * glade_widget_adaptor_action_remove:
+ * @adaptor: A #GladeWidgetAdaptor
+ * @action_path: The identifier of this action in the action tree
+ *
+ * Remove an @adaptor's action.
+ *
+ * Returns: whether or not the action was removed.
+ */
+gboolean
+glade_widget_adaptor_action_remove (GladeWidgetAdaptor *adaptor,
+ const gchar *action_path)
+{
+ GWActionClass *action, *group;
+ const gchar *id;
+ GList **list;
+
g_return_val_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor), FALSE);
+ g_return_val_if_fail (action_path != NULL, FALSE);
+
+ id = gwa_action_path_get_id (action_path);
+
+ if ((group = gwa_action_get_last_group (adaptor, action_path)))
+ list = &group->actions;
+ else
+ list = &adaptor->actions;
- /* A GWA container must at least implement add/remove/get_children
- */
- return (GLADE_WIDGET_ADAPTOR_GET_CLASS (adaptor)->add &&
- GLADE_WIDGET_ADAPTOR_GET_CLASS (adaptor)->remove &&
- GLADE_WIDGET_ADAPTOR_GET_CLASS (adaptor)->get_children);
+ if ((action = gwa_action_lookup (*list, id)) == NULL) return FALSE;
+
+ *list = g_list_remove (*list, action);
+
+ glade_widget_action_class_free (action);
+
+ return TRUE;
+}
+
+/**
+ * glade_widget_adaptor_action_activate:
+ * @adaptor: A #GladeWidgetAdaptor
+ * @object: The #GObject
+ * @action_path: The action identifier in the action tree
+ *
+ * An adaptor function to be called on widget actions.
+ */
+void
+glade_widget_adaptor_action_activate (GladeWidgetAdaptor *adaptor,
+ GObject *object,
+ const gchar *action_path)
+{
+ g_return_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor));
+ g_return_if_fail (G_IS_OBJECT (object));
+ g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), adaptor->type));
+
+ if (GLADE_WIDGET_ADAPTOR_GET_CLASS (adaptor)->action_activate)
+ GLADE_WIDGET_ADAPTOR_GET_CLASS (adaptor)->action_activate (adaptor, object, action_path);
}
diff --git a/gladeui/glade-widget-adaptor.h b/gladeui/glade-widget-adaptor.h
index 32c24470..acafb579 100644
--- a/gladeui/glade-widget-adaptor.h
+++ b/gladeui/glade-widget-adaptor.h
@@ -26,7 +26,6 @@ typedef struct _GladeWidgetAdaptor GladeWidgetAdaptor;
typedef struct _GladeWidgetAdaptorPrivate GladeWidgetAdaptorPrivate;
typedef struct _GladeWidgetAdaptorClass GladeWidgetAdaptorClass;
typedef struct _GladeSignalClass GladeSignalClass;
-typedef struct _GWAAction GWAAction;
/**
* GWA_IS_FIXED:
@@ -92,6 +91,14 @@ typedef struct _GWAAction GWAAction;
(GladeWidgetAdaptorClass *)g_type_class_peek (GLADE_TYPE_WIDGET_ADAPTOR) : \
GLADE_WIDGET_ADAPTOR_GET_CLASS (glade_widget_adaptor_get_by_type(type)))
+/**
+ * GWA_GET_OCLASS:
+ * @type: A #GType.
+ *
+ * Same as GWA_GET_CLASS but casted to GObjectClass
+ */
+#define GWA_GET_OCLASS(type) ((GObjectClass*)GWA_GET_CLASS(type))
+
#define GLADE_VALID_CREATE_REASON(reason) (reason >= 0 && reason < GLADE_CREATE_REASONS)
@@ -302,6 +309,18 @@ typedef GObject *(* GladeGetInternalFunc) (GladeWidgetAdaptor *adaptor,
GObject *parent,
const gchar *name);
+/**
+ * GladeActionActivatedFunc:
+ * @adaptor: A #GladeWidgetAdaptor
+ * @object: The #GObject
+ * @action_id: The action identifier
+ *
+ * This delagate function is used to catch actions from the core.
+ *
+ */
+typedef void (* GladeActionActivateFunc) (GladeWidgetAdaptor *adaptor,
+ GObject *object,
+ const gchar *action_id);
/* GladeSignalClass contains all the info we need for a given signal, such as
* the signal name, and maybe more in the future
@@ -316,17 +335,6 @@ struct _GladeSignalClass
};
-struct _GWAAction
-{
- gchar *id; /* The identifier of this action in the action tree */
- gchar *label; /* A translated label to show in the UI for this action */
- gchar *stock; /* If set, this stock item will be shown in the UI along side
- * the label */
- gboolean is_a_group; /* Marks whether this action is a group and can have children */
-
- GList *actions; /* Recursive list of child actions */
-};
-
/* Note that everything that must be processed at the creation of
* every instance is managed on the instance structure, and everywhere
* that we want to take advantage of inheritance is handled in the class
@@ -369,7 +377,7 @@ struct _GladeWidgetAdaptor
GList *child_packings; /* Default packing property values */
- GList *actions; /* A list of GWAAction */
+ GList *actions; /* A list of GWActionClass */
GladeWidgetAdaptorPrivate *priv;
@@ -442,8 +450,8 @@ struct _GladeWidgetAdaptorClass
* replace a placeholder with
* a widget and viceversa.
*/
- /* Signals */
- gboolean (*action_activated) (GladeWidgetAdaptor *, GladeWidget *, const gchar *);
+
+ GladeActionActivateFunc action_activate; /* This method is used to catch actions */
};
#define glade_widget_adaptor_create_widget(adaptor, query, ...) \
@@ -564,13 +572,19 @@ gchar *glade_widget_adaptor_get_packing_default(GladeWidgetAdaptor
GladeWidgetAdaptor *parent_adaptor,
const gchar *propert_id);
-void glade_widget_adaptor_action_activate (GladeWidget *widget,
- const gchar *action_id);
-
-
gboolean glade_widget_adaptor_is_container (GladeWidgetAdaptor *adaptor);
+gboolean glade_widget_adaptor_action_add (GladeWidgetAdaptor *adaptor,
+ const gchar *action_path,
+ const gchar *label,
+ const gchar *stock);
+gboolean glade_widget_adaptor_action_remove (GladeWidgetAdaptor *adaptor,
+ const gchar *action_path);
+
+void glade_widget_adaptor_action_activate (GladeWidgetAdaptor *adaptor,
+ GObject *object,
+ const gchar *action_path);
G_END_DECLS
#endif /* __GLADE_WIDGET_ADAPTOR_H__ */
diff --git a/gladeui/glade-widget.c b/gladeui/glade-widget.c
index f0325a44..d8118b11 100644
--- a/gladeui/glade-widget.c
+++ b/gladeui/glade-widget.c
@@ -45,6 +45,7 @@
#include "glade-editor.h"
#include "glade-app.h"
#include "glade-design-view.h"
+#include "glade-widget-action.h"
@@ -74,7 +75,6 @@ enum
BUTTON_PRESS_EVENT,
BUTTON_RELEASE_EVENT,
MOTION_NOTIFY_EVENT,
- ACTION_ACTIVATED,
LAST_SIGNAL
};
@@ -754,6 +754,12 @@ glade_widget_dispose (GObject *object)
g_list_foreach (widget->packing_properties, (GFunc)g_object_unref, NULL);
g_list_free (widget->packing_properties);
}
+
+ if (widget->actions)
+ {
+ g_list_foreach (widget->actions, (GFunc)g_object_unref, NULL);
+ g_list_free (widget->actions);
+ }
if (G_OBJECT_CLASS(parent_class)->dispose)
G_OBJECT_CLASS(parent_class)->dispose(object);
@@ -1149,27 +1155,6 @@ glade_widget_class_init (GladeWidgetClass *klass)
glade_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
-
- /**
- * GladeWidget::action-activated:
- * @widget: the #GladeWidget which received the signal.
- * @action_id: the action id (signal detail) or NULL.
- *
- * Use this to catch up actions. This signal is proxied from
- * GladeWidgetAdaptor's "action-emited" signal default handler.
- *
- * Returns TRUE to stop others handlers being invoked.
- *
- */
- glade_widget_signals [ACTION_ACTIVATED] =
- g_signal_new ("action-activated",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
- G_STRUCT_OFFSET (GladeWidgetClass, action_activated),
- glade_boolean_handled_accumulator, NULL,
- glade_marshal_BOOLEAN__STRING,
- G_TYPE_BOOLEAN, 1, G_TYPE_STRING);
}
GType
@@ -1642,6 +1627,23 @@ glade_widget_set_properties (GladeWidget *widget, GList *properties)
}
static void
+glade_widget_set_actions (GladeWidget *widget, GladeWidgetAdaptor *adaptor)
+{
+ GList *l;
+
+ for (l = adaptor->actions; l; l = g_list_next (l))
+ {
+ GWActionClass *action = l->data;
+ GObject *obj = g_object_new (GLADE_TYPE_WIDGET_ACTION,
+ "klass", action, NULL);
+
+ widget->actions = g_list_prepend (widget->actions,
+ GLADE_WIDGET_ACTION (obj));
+ }
+ widget->actions = g_list_reverse (widget->actions);
+}
+
+static void
glade_widget_set_adaptor (GladeWidget *widget, GladeWidgetAdaptor *adaptor)
{
GladePropertyClass *property_class;
@@ -1674,6 +1676,9 @@ glade_widget_set_adaptor (GladeWidget *widget, GladeWidgetAdaptor *adaptor)
}
widget->properties = g_list_reverse (widget->properties);
}
+
+ /* Create actions from adaptor */
+ glade_widget_set_actions (widget, adaptor);
}
/* Connects a signal handler to the 'event' signal for a widget and
@@ -3809,6 +3814,96 @@ glade_widget_placeholder_relation (GladeWidget *parent,
GWA_USE_PLACEHOLDERS (parent->adaptor));
}
+static GladeWidgetAction *
+glade_widget_action_lookup (GList **actions, const gchar *path, gboolean remove)
+{
+ GList *l;
+
+ for (l = *actions; l; l = g_list_next (l))
+ {
+ GladeWidgetAction *action = l->data;
+
+ if (strcmp (action->klass->path, path) == 0)
+ {
+ if (remove)
+ {
+ *actions = g_list_remove (*actions, action);
+ g_object_unref (action);
+ return NULL;
+ }
+ return action;
+ }
+
+ if (action->actions &&
+ g_str_has_prefix (path, action->klass->path) &&
+ (action = glade_widget_action_lookup (&action->actions, path, remove)))
+ return action;
+ }
+
+ return NULL;
+}
+
+/**
+ * glade_widget_get_action:
+ * @widget: a #GladeWidget
+ * @action_path: a full action path including groups
+ *
+ * Returns a #GladeWidgetAction object indentified by @action_path.
+ *
+ * Returns: the action or NULL if not found.
+ */
+GladeWidgetAction *
+glade_widget_get_action (GladeWidget *widget, const gchar *action_path)
+{
+ g_return_val_if_fail (GLADE_IS_WIDGET (widget), NULL);
+ g_return_val_if_fail (action_path == NULL, NULL);
+
+ return glade_widget_action_lookup (&widget->actions, action_path, FALSE);
+}
+
+/**
+ * glade_widget_remove_action:
+ * @widget: a #GladeWidget
+ * @action_path: a full action path including groups
+ *
+ * Remove an action.
+ */
+void
+glade_widget_remove_action (GladeWidget *widget, const gchar *action_path)
+{
+ g_return_if_fail (GLADE_IS_WIDGET (widget));
+ g_return_if_fail (action_path != NULL);
+
+ glade_widget_action_lookup (&widget->actions, action_path, TRUE);
+}
+
+/**
+ * glade_widget_create_action_menu:
+ * @widget: a #GladeWidget
+ * @action_path: an action path or NULL to include every @widget action.
+ *
+ * Create a new GtkMenu with every action in it.
+ *
+ */
+GtkWidget *
+glade_widget_create_action_menu (GladeWidget *widget, const gchar *action_path)
+{
+ GladeWidgetAction *action = NULL;
+ GtkWidget *menu;
+
+ g_return_val_if_fail (GLADE_IS_WIDGET (widget), NULL);
+
+ if (action_path)
+ action = glade_widget_action_lookup (&widget->actions, action_path, FALSE);
+
+ menu = gtk_menu_new ();
+ if (glade_popup_action_populate_menu (menu, widget, action))
+ return menu;
+
+ g_object_unref (G_OBJECT (menu));
+
+ return NULL;
+}
/*******************************************************************************
* Toplevel GladeWidget Embedding *
diff --git a/gladeui/glade-widget.h b/gladeui/glade-widget.h
index c10d1a40..9e792b85 100644
--- a/gladeui/glade-widget.h
+++ b/gladeui/glade-widget.h
@@ -3,6 +3,7 @@
#define __GLADE_WIDGET_H__
#include <gladeui/glade-widget-adaptor.h>
+#include <gladeui/glade-widget-action.h>
#include <gladeui/glade-signal.h>
#include <gladeui/glade-property.h>
@@ -88,6 +89,8 @@ struct _GladeWidget
gint height; /* usefull for parentless widgets in the
* GladeDesignLayout */
+ GList *actions; /* A GladeWidgetAction list */
+
/* Construct parameters: */
GladeWidget *construct_template;
GladeWidgetInfo *construct_info;
@@ -106,7 +109,6 @@ struct _GladeWidgetClass
void (*add_signal_handler) (GladeWidget *, GladeSignal *);
void (*remove_signal_handler) (GladeWidget *, GladeSignal *);
void (*change_signal_handler) (GladeWidget *, GladeSignal *, GladeSignal *);
- gboolean (*action_activated) (GladeWidget *, const gchar *);
gint (*button_press_event) (GladeWidget *, GdkEvent *);
gint (*button_release_event) (GladeWidget *, GdkEvent *);
@@ -190,6 +192,15 @@ gboolean glade_widget_event (GladeWidget *g
gboolean glade_widget_placeholder_relation (GladeWidget *parent,
GladeWidget *widget);
+GladeWidgetAction * glade_widget_get_action (GladeWidget *widget,
+ const gchar *action_path);
+
+void glade_widget_remove_action (GladeWidget *widget,
+ const gchar *action_path);
+
+GtkWidget * glade_widget_create_action_menu (GladeWidget *widget,
+ const gchar *action_path);
+
/*******************************************************************************
Project, object property references
*******************************************************************************/
diff --git a/gladeui/glade-xml-utils.h b/gladeui/glade-xml-utils.h
index 26ac14a0..297cee51 100644
--- a/gladeui/glade-xml-utils.h
+++ b/gladeui/glade-xml-utils.h
@@ -55,6 +55,8 @@ typedef struct _GladeXmlDoc GladeXmlDoc;
#define GLADE_TAG_CHILD_SET_PROP_FUNCTION "child-set-property-function"
#define GLADE_TAG_CHILD_GET_PROP_FUNCTION "child-get-property-function"
#define GLADE_TAG_CHILD_VERIFY_FUNCTION "child-verify-function"
+#define GLADE_TAG_CONSTRUCTOR_FUNCTION "constructor-function"
+#define GLADE_TAG_ACTION_ACTIVATE_FUNCTION "action-activate-function"
#define GLADE_TAG_PROPERTIES "properties"
#define GLADE_TAG_PACKING_PROPERTIES "packing-properties"
#define GLADE_TAG_PROPERTY "property"
diff --git a/plugins/gtk+/glade-gtk.c b/plugins/gtk+/glade-gtk.c
index 944f7eac..e8f1ee0e 100644
--- a/plugins/gtk+/glade-gtk.c
+++ b/plugins/gtk+/glade-gtk.c
@@ -3905,26 +3905,6 @@ glade_gtk_image_set_property (GladeWidgetAdaptor *adaptor,
id, value);
}
-/* ----------------------------- menu callbacks ------------------------------ */
-static void glade_gtk_menu_shell_launch_editor (GObject *object, gchar *title);
-
-static gboolean
-glade_gtk_menu_launch_editor_action (GladeWidget *gwidget, const gchar *data)
-{
- GladeWidget *iter = gwidget;
-
- while (!GTK_IS_MENU_BAR (iter->object) &&
- /* Make sure we support menus inside toolbars */
- iter->parent && GTK_IS_MENU_SHELL (iter->parent->object))
- iter = iter->parent;
-
- glade_gtk_menu_shell_launch_editor (iter->object,
- GTK_IS_MENU_BAR (iter->object) ?
- _("Menu Bar Editor") : _("Menu Editor"));
- return TRUE;
-}
-
-
/* ----------------------------- GtkMenuShell ------------------------------ */
void
glade_gtk_menu_shell_add_item (GladeWidgetAdaptor *adaptor,
@@ -4248,6 +4228,24 @@ glade_gtk_menu_shell_launch_editor (GObject *object, gchar *title)
gtk_widget_show (window);
}
+void
+glade_gtk_menu_shell_action_activate (GladeWidgetAdaptor *adaptor,
+ GObject *object,
+ const gchar *action_path)
+{
+ if (strcmp (action_path, "launch_editor") == 0)
+ {
+ 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);
+}
+
/* ----------------------------- GtkMenuItem(s) ------------------------------ */
GList *
glade_gtk_menu_item_get_children (GladeWidgetAdaptor *adaptor,
@@ -4307,9 +4305,6 @@ glade_gtk_menu_item_post_create (GladeWidgetAdaptor *adaptor,
g_return_if_fail (GTK_IS_MENU_ITEM (object));
gitem = glade_widget_get_from_gobject (object);
g_return_if_fail (GLADE_IS_WIDGET (gitem));
-
- /* hook the launch_editor action signal for all items */
- g_signal_connect (gitem, "action-activated::launch_editor", G_CALLBACK (glade_gtk_menu_launch_editor_action), NULL);
if (GTK_IS_SEPARATOR_MENU_ITEM (object)) return;
@@ -4721,6 +4716,31 @@ glade_gtk_radio_menu_item_set_property (GladeWidgetAdaptor *adaptor,
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 *
@@ -4810,9 +4830,6 @@ glade_gtk_menu_bar_post_create (GladeWidgetAdaptor *adaptor,
gmenubar = glade_widget_get_from_gobject (object);
g_return_if_fail (GLADE_IS_WIDGET (gmenubar));
- /* hook the launch_editor action signal for all reasons */
- g_signal_connect (gmenubar, "action-activated::launch_editor", G_CALLBACK (glade_gtk_menu_launch_editor_action), NULL);
-
if (reason != GLADE_CREATE_USER) return;
project = glade_widget_get_project (gmenubar);
@@ -4844,23 +4861,6 @@ glade_gtk_menu_bar_post_create (GladeWidgetAdaptor *adaptor,
glade_gtk_menu_bar_append_new_item (gsubmenu, project, "gtk-about", TRUE);
}
-/* ------------------------------ GtkMenu -------------------------------- */
-void
-glade_gtk_menu_post_create (GladeWidgetAdaptor *adaptor,
- GObject *object,
- GladeCreateReason reason)
-{
- GladeWidget *gmenu;
-
- g_return_if_fail (GTK_IS_MENU (object));
- gmenu = glade_widget_get_from_gobject (object);
- g_return_if_fail (GLADE_IS_WIDGET (gmenu));
-
- /* hook the launch_editor action signal for all reasons */
- g_signal_connect (gmenu, "action-activated::launch_editor", G_CALLBACK (glade_gtk_menu_launch_editor_action), NULL);
-
-}
-
/* ----------------------------- GtkToolBar ------------------------------ */
void
glade_gtk_toolbar_get_child_property (GladeWidgetAdaptor *adaptor,
@@ -5012,7 +5012,6 @@ glade_gtk_toolbar_child_selected (GladeBaseEditor *editor,
"group", "active", NULL);
}
-/* XXX Must reintegrate this code with actions when ready */
void
glade_gtk_toolbar_launch_editor (GladeWidgetAdaptor *adaptor,
GObject *toolbar)
@@ -5047,6 +5046,21 @@ glade_gtk_toolbar_launch_editor (GladeWidgetAdaptor *adaptor,
gtk_widget_show (window);
}
+void
+glade_gtk_toolbar_action_activate (GladeWidgetAdaptor *adaptor,
+ GObject *object,
+ const gchar *action_path)
+{
+ if (strcmp (action_path, "launch_editor") == 0)
+ {
+ glade_gtk_toolbar_launch_editor (adaptor, object);
+ }
+ else
+ GWA_GET_CLASS (GTK_TYPE_CONTAINER)->action_activate (adaptor,
+ object,
+ action_path);
+}
+
/* ----------------------------- GtkToolItem ------------------------------ */
void
glade_gtk_tool_item_post_create (GladeWidgetAdaptor *adaptor,
diff --git a/plugins/gtk+/gtk+.xml.in b/plugins/gtk+/gtk+.xml.in
index 0be483fd..93ac58ea 100644
--- a/plugins/gtk+/gtk+.xml.in
+++ b/plugins/gtk+/gtk+.xml.in
@@ -292,6 +292,7 @@ embedded in another object</_tooltip>
<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>
+ <action-activate-function>glade_gtk_menu_shell_action_activate</action-activate-function>
<packing-properties>
<property id="position" _name="Position" default="-1" save="False">
<spec>glade_standard_int_spec</spec>
@@ -307,6 +308,7 @@ embedded in another object</_tooltip>
<set-property-function>glade_gtk_menu_item_set_property</set-property-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>
+ <action-activate-function>glade_gtk_menu_item_action_activate</action-activate-function>
<properties>
<property id="label" _name="Label" translatable="True">
<_tooltip>The text of the menu item</_tooltip>
@@ -399,6 +401,7 @@ embedded in another object</_tooltip>
<remove-child-function>glade_gtk_toolbar_remove_child</remove-child-function>
<child-set-property-function>glade_gtk_toolbar_set_child_property</child-set-property-function>
<child-get-property-function>glade_gtk_toolbar_get_child_property</child-get-property-function>
+ <action-activate-function>glade_gtk_toolbar_action_activate</action-activate-function>
<properties>
<property id="orientation">
@@ -1023,7 +1026,7 @@ embedded in another object</_tooltip>
<glade-widget-class name="GtkMenu" generic-name="menu" _title="Popup Menu" toplevel="True">
<action id="launch_editor" _name="Edit Menu" stock="gtk-edit"/>
<!-- We do not want glade_gtk_container_post_create be executed -->
- <post-create-function>glade_gtk_menu_post_create</post-create-function>
+ <post-create-function>empty</post-create-function>
</glade-widget-class>
<glade-widget-class name="GtkHScrollbar" generic-name="hscrollbar" _title="Horizontal Scrollbar"/>