diff options
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtkactiongroup.c | 179 | ||||
-rw-r--r-- | gtk/gtkactiongroup.h | 52 | ||||
-rw-r--r-- | gtk/gtkradioaction.c | 160 | ||||
-rw-r--r-- | gtk/gtkradioaction.h | 12 | ||||
-rw-r--r-- | gtk/gtktoolbar.c | 2 | ||||
-rw-r--r-- | gtk/gtkuimanager.c | 181 |
6 files changed, 420 insertions, 166 deletions
diff --git a/gtk/gtkactiongroup.c b/gtk/gtkactiongroup.c index 500a49efd7..32cb7bfa6e 100644 --- a/gtk/gtkactiongroup.c +++ b/gtk/gtkactiongroup.c @@ -280,6 +280,7 @@ gtk_action_group_list_actions (GtkActionGroup *action_group) * @action_group: the action group * @entries: an array of action descriptions * @n_entries: the number of entries + * @user_data: data to pass to the action callbacks * * This is a convenience routine to create a number of actions and add * them to the action group. Each member of the array describes an @@ -288,9 +289,36 @@ gtk_action_group_list_actions (GtkActionGroup *action_group) * Since: 2.4 */ void -gtk_action_group_add_actions (GtkActionGroup *action_group, - GtkActionGroupEntry *entries, - guint n_entries) +gtk_action_group_add_actions (GtkActionGroup *action_group, + GtkActionEntry *entries, + guint n_entries, + gpointer user_data) +{ + gtk_action_group_add_actions_full (action_group, + entries, n_entries, + user_data, NULL); +} + + +/** + * gtk_action_group_add_actions_full: + * @action_group: the action group + * @entries: an array of action descriptions + * @n_entries: the number of entries + * @user_data: data to pass to the action callbacks + * @destroy: destroy notification callback for @user_data + * + * This variant of gtk_action_group_add_actions() adds a #GDestroyNotify + * callback for @user_data. + * + * Since: 2.4 + */ +void +gtk_action_group_add_actions_full (GtkActionGroup *action_group, + GtkActionEntry *entries, + guint n_entries, + gpointer user_data, + GDestroyNotify destroy) { guint i; GtkTranslateFunc translate_func; @@ -309,20 +337,10 @@ gtk_action_group_add_actions (GtkActionGroup *action_group, gchar *label; gchar *tooltip; - switch (entries[i].entry_type) { - case GTK_ACTION_NORMAL: - action_type = GTK_TYPE_ACTION; - break; - case GTK_ACTION_TOGGLE: + if (entries[i].is_toggle) action_type = GTK_TYPE_TOGGLE_ACTION; - break; - case GTK_ACTION_RADIO: - action_type = GTK_TYPE_RADIO_ACTION; - break; - default: - g_warning ("unsupported action type"); + else action_type = GTK_TYPE_ACTION; - } if (translate_func) { @@ -342,27 +360,118 @@ gtk_action_group_add_actions (GtkActionGroup *action_group, "stock_id", entries[i].stock_id, NULL); - if (entries[i].entry_type == GTK_ACTION_RADIO && - entries[i].extra_data != NULL) + if (entries[i].callback) + g_signal_connect_data (action, "activate", + entries[i].callback, + user_data, (GClosureNotify)destroy, 0); + + /* set the accel path for the menu item */ + accel_path = g_strconcat ("<Actions>/", action_group->private_data->name, "/", + entries[i].name, NULL); + if (entries[i].accelerator) { - GtkAction *radio_action; - GSList *group; - - radio_action = - gtk_action_group_get_action (GTK_ACTION_GROUP (action_group), - entries[i].extra_data); - if (radio_action) - { - group = gtk_radio_action_get_group (GTK_RADIO_ACTION (radio_action)); - gtk_radio_action_set_group (GTK_RADIO_ACTION (action), group); - } - else - g_warning (G_STRLOC " could not look up `%s'", entries[i].extra_data); + guint accel_key = 0; + GdkModifierType accel_mods; + + gtk_accelerator_parse (entries[i].accelerator, &accel_key, + &accel_mods); + if (accel_key) + gtk_accel_map_add_entry (accel_path, accel_key, accel_mods); } - if (entries[i].callback) - g_signal_connect (action, "activate", - entries[i].callback, entries[i].user_data); + gtk_action_set_accel_path (action, accel_path); + g_free (accel_path); + + gtk_action_group_add_action (action_group, action); + g_object_unref (action); + } +} + +/** + * gtk_action_group_add_radio_actions: + * @action_group: the action group + * @entries: an array of radio action descriptions + * @n_entries: the number of entries + * @on_change: the callback to connect to the changed signal + * @user_data: data to pass to the action callbacks + * + * This is a convenience routine to create a group of radio actions and + * add them to the action group. Each member of the array describes a + * radio action to create. + * + * Since: 2.4 + * + **/ +void +gtk_action_group_add_radio_actions (GtkActionGroup *action_group, + GtkRadioActionEntry *entries, + guint n_entries, + GCallback on_change, + gpointer user_data) +{ + gtk_action_group_add_radio_actions_full (action_group, + entries, n_entries, + on_change, user_data, NULL); +} + +void +gtk_action_group_add_radio_actions_full (GtkActionGroup *action_group, + GtkRadioActionEntry *entries, + guint n_entries, + GCallback on_change, + gpointer user_data, + GDestroyNotify destroy) +{ + guint i; + GtkTranslateFunc translate_func; + gpointer translate_data; + GtkRadioAction *radio_action; + + g_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); + + translate_func = action_group->private_data->translate_func; + translate_data = action_group->private_data->translate_data; + + for (i = 0; i < n_entries; i++) + { + GtkAction *action; + gchar *accel_path; + gchar *label; + gchar *tooltip; + + if (translate_func) + { + label = translate_func (entries[i].label, translate_data); + tooltip = translate_func (entries[i].tooltip, translate_data); + } + else + { + label = entries[i].label; + tooltip = entries[i].tooltip; + } + + action = g_object_new (GTK_TYPE_RADIO_ACTION, + "name", entries[i].name, + "label", label, + "tooltip", tooltip, + "stock_id", entries[i].stock_id, + "value", entries[i].value, + NULL); + + if (i == 0) + { + radio_action = GTK_RADIO_ACTION (action); + + if (on_change) + g_signal_connect_data (radio_action, "changed", + on_change, user_data, + (GClosureNotify)destroy, 0); + } + else + { + GSList *group = gtk_radio_action_get_group (radio_action); + gtk_radio_action_set_group (GTK_RADIO_ACTION (action), group); + } /* set the accel path for the menu item */ accel_path = g_strconcat ("<Actions>/", action_group->private_data->name, "/", @@ -380,7 +489,7 @@ gtk_action_group_add_actions (GtkActionGroup *action_group, gtk_action_set_accel_path (action, accel_path); g_free (accel_path); - + gtk_action_group_add_action (action_group, action); g_object_unref (action); } @@ -431,7 +540,7 @@ dgettext_swapped (const gchar *msgid, * @domain: the translation domain to use for dgettext() calls * * Sets the translation domain and uses dgettext() for translating the - * @label and @tooltip of #GtkActionGroupEntry<!-- -->s added by + * @label and @tooltip of #GtkActionEntry<!-- -->s added by * gtk_action_group_add_actions(). * * If you're not using gettext() for localization, see diff --git a/gtk/gtkactiongroup.h b/gtk/gtkactiongroup.h index 6036f2e0e7..f3a01b5375 100644 --- a/gtk/gtkactiongroup.h +++ b/gtk/gtkactiongroup.h @@ -43,7 +43,8 @@ typedef struct _GtkActionGroup GtkActionGroup; typedef struct _GtkActionGroupPrivate GtkActionGroupPrivate; typedef struct _GtkActionGroupClass GtkActionGroupClass; -typedef struct _GtkActionGroupEntry GtkActionGroupEntry; +typedef struct _GtkActionEntry GtkActionEntry; +typedef struct _GtkRadioActionEntry GtkRadioActionEntry; struct _GtkActionGroup { @@ -68,26 +69,28 @@ struct _GtkActionGroupClass void (*_gtk_reserved4) (void); }; -typedef enum -{ - GTK_ACTION_NORMAL, - GTK_ACTION_TOGGLE, - GTK_ACTION_RADIO -} GtkActionGroupEntryType; - -struct _GtkActionGroupEntry +struct _GtkActionEntry { gchar *name; - gchar *label; gchar *stock_id; + gchar *label; gchar *accelerator; gchar *tooltip; GCallback callback; - gpointer user_data; - GtkActionGroupEntryType entry_type; - gchar *extra_data; + gboolean is_toggle; +}; + +struct _GtkRadioActionEntry +{ + gchar *name; + gchar *stock_id; + gchar *label; + gchar *accelerator; + gchar *tooltip; + + gint value; }; GType gtk_action_group_get_type (void); @@ -103,9 +106,26 @@ void gtk_action_group_add_action (GtkActionGroup *action_grou void gtk_action_group_remove_action (GtkActionGroup *action_group, GtkAction *action); -void gtk_action_group_add_actions (GtkActionGroup *action_group, - GtkActionGroupEntry *entries, - guint n_entries); +void gtk_action_group_add_actions (GtkActionGroup *action_group, + GtkActionEntry *entries, + guint n_entries, + gpointer user_data); +void gtk_action_group_add_radio_actions (GtkActionGroup *action_group, + GtkRadioActionEntry *entries, + guint n_entries, + GCallback on_change, + gpointer user_data); +void gtk_action_group_add_actions_full (GtkActionGroup *action_group, + GtkActionEntry *entries, + guint n_entries, + gpointer user_data, + GDestroyNotify destroy); +void gtk_action_group_add_radio_actions_full (GtkActionGroup *action_group, + GtkRadioActionEntry *entries, + guint n_entries, + GCallback on_change, + gpointer user_data, + GDestroyNotify destroy); void gtk_action_group_set_translate_func (GtkActionGroup *action_group, GtkTranslateFunc func, diff --git a/gtk/gtkradioaction.c b/gtk/gtkradioaction.c index e0ea5f1f9b..52a03d36a4 100644 --- a/gtk/gtkradioaction.c +++ b/gtk/gtkradioaction.c @@ -31,17 +31,43 @@ #include <config.h> #include "gtkradioaction.h" +#include "gtkradiomenuitem.h" #include "gtktoggleactionprivate.h" +#include "gtkintl.h" #define GTK_RADIO_ACTION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_RADIO_ACTION, GtkRadioActionPrivate)) struct _GtkRadioActionPrivate { GSList *group; + gint value; }; -static void gtk_radio_action_init (GtkRadioAction *action); -static void gtk_radio_action_class_init (GtkRadioActionClass *class); +enum +{ + CHANGED, + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_VALUE +}; + +static void gtk_radio_action_init (GtkRadioAction *action); +static void gtk_radio_action_class_init (GtkRadioActionClass *class); +static void gtk_radio_action_finalize (GObject *object); +static void gtk_radio_action_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gtk_radio_action_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void gtk_radio_action_activate (GtkAction *action); + GType gtk_radio_action_get_type (void) @@ -71,10 +97,8 @@ gtk_radio_action_get_type (void) return type; } -static void gtk_radio_action_finalize (GObject *object); -static void gtk_radio_action_activate (GtkAction *action); - static GObjectClass *parent_class = NULL; +static guint radio_action_signals[LAST_SIGNAL] = { 0 }; static void gtk_radio_action_class_init (GtkRadioActionClass *klass) @@ -87,9 +111,51 @@ gtk_radio_action_class_init (GtkRadioActionClass *klass) action_class = GTK_ACTION_CLASS (klass); gobject_class->finalize = gtk_radio_action_finalize; + gobject_class->set_property = gtk_radio_action_set_property; + gobject_class->get_property = gtk_radio_action_get_property; action_class->activate = gtk_radio_action_activate; + /** + * GtkRadioAction:value: + * + * The value is an arbitrary integer which can be used as a + * convenient way to determine which action in the group is + * currently active in an ::activate or ::changed signal handler. + * See gtk_radio_action_get_current_value() and #GtkRadioActionEntry + * for convenient ways to get and set this property. + * + * Since: 2.4 + */ + g_object_class_install_property (gobject_class, + PROP_VALUE, + g_param_spec_int ("value", + _("The value"), + _("The value returned by gtk_radio_action_get_current_value() when this action is the current action of its group."), + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + /** + * GtkRadioAction::changed: + * @action: the action on which the signal is emitted + * @current: the member of @action<!-- -->s group which has just been activated + * + * The ::changed signal is emitted on every member of a radio group when the + * active member is changed. The signal gets emitted after the ::activate signals + * for the previous and current active members. + * + * Since: 2.4 + */ + radio_action_signals[CHANGED] = + g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET (GtkRadioActionClass, changed), NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, GTK_TYPE_RADIO_ACTION); + g_type_class_add_private (gobject_class, sizeof (GtkRadioActionPrivate)); } @@ -98,6 +164,7 @@ gtk_radio_action_init (GtkRadioAction *action) { action->private_data = GTK_RADIO_ACTION_GET_PRIVATE (action); action->private_data->group = g_slist_prepend (NULL, action); + action->private_data->value = 0; } static void @@ -125,6 +192,48 @@ gtk_radio_action_finalize (GObject *object) } static void +gtk_radio_action_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkRadioAction *radio_action; + + radio_action = GTK_RADIO_ACTION (object); + + switch (prop_id) + { + case PROP_VALUE: + radio_action->private_data->value = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gtk_radio_action_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkRadioAction *radio_action; + + radio_action = GTK_RADIO_ACTION (object); + + switch (prop_id) + { + case PROP_VALUE: + g_value_set_int (value, radio_action->private_data->value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void gtk_radio_action_activate (GtkAction *action) { GtkRadioAction *radio_action; @@ -167,6 +276,15 @@ gtk_radio_action_activate (GtkAction *action) break; } } + + tmp_list = radio_action->private_data->group; + while (tmp_list) + { + tmp_action = tmp_list->data; + tmp_list = tmp_list->next; + + g_signal_emit (tmp_action, radio_action_signals[CHANGED], 0, radio_action); + } } gtk_toggle_action_toggled (toggle_action); @@ -238,3 +356,35 @@ gtk_radio_action_set_group (GtkRadioAction *action, gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE); } } + +/** + * gtk_radio_action_get_current_value: + * @action: a #GtkRadioAction + * + * Obtains the value property of the the currently active member of + * the group to which @action belongs. + * + * Return value: The value of the currently active group member + * + * Since: 2.4 + **/ +gint +gtk_radio_action_get_current_value (GtkRadioAction *action) +{ + GSList *slist; + + g_return_val_if_fail (GTK_IS_RADIO_ACTION (action), 0); + + if (action->private_data->group) + { + for (slist = action->private_data->group; slist; slist = slist->next) + { + GtkToggleAction *toggle_action = slist->data; + + if (toggle_action->private_data->active) + return GTK_RADIO_ACTION (toggle_action)->private_data->value; + } + } + + return action->private_data->value; +} diff --git a/gtk/gtkradioaction.h b/gtk/gtkradioaction.h index 51db941106..bfeba215e4 100644 --- a/gtk/gtkradioaction.h +++ b/gtk/gtkradioaction.h @@ -56,6 +56,8 @@ struct _GtkRadioActionClass { GtkToggleActionClass parent_class; + void (* changed) (GtkRadioAction *action, GtkRadioAction *current); + /* Padding for future expansion */ void (*_gtk_reserved1) (void); void (*_gtk_reserved2) (void); @@ -63,11 +65,11 @@ struct _GtkRadioActionClass void (*_gtk_reserved4) (void); }; -GType gtk_radio_action_get_type (void); - -GSList *gtk_radio_action_get_group (GtkRadioAction *action); -void gtk_radio_action_set_group (GtkRadioAction *action, - GSList *group); +GType gtk_radio_action_get_type (void); +GSList *gtk_radio_action_get_group (GtkRadioAction *action); +void gtk_radio_action_set_group (GtkRadioAction *action, + GSList *group); +gint gtk_radio_action_get_current_value (GtkRadioAction *action); #endif /* __GTK_RADIO_ACTION_H__ */ diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c index adaac5ed8d..5ead9f7045 100644 --- a/gtk/gtktoolbar.c +++ b/gtk/gtktoolbar.c @@ -3001,7 +3001,7 @@ gtk_toolbar_append_element (GtkToolbar *toolbar, * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element. * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine * the radio group for the new element. In all other cases, @widget must - * *be %NULL. + * be %NULL. * * Return value: the new toolbar element as a #GtkWidget. **/ diff --git a/gtk/gtkuimanager.c b/gtk/gtkuimanager.c index 3932b8e3ba..cc0199f8d9 100644 --- a/gtk/gtkuimanager.c +++ b/gtk/gtkuimanager.c @@ -51,7 +51,7 @@ typedef enum GTK_UI_MANAGER_TOOLBAR, GTK_UI_MANAGER_MENU_PLACEHOLDER, GTK_UI_MANAGER_TOOLBAR_PLACEHOLDER, - GTK_UI_MANAGER_POPUPS, + GTK_UI_MANAGER_POPUP, GTK_UI_MANAGER_MENUITEM, GTK_UI_MANAGER_TOOLITEM, GTK_UI_MANAGER_SEPARATOR, @@ -215,9 +215,6 @@ gtk_ui_manager_init (GtkUIManager *self) node = get_child_node (self, NULL, "ui", 4, GTK_UI_MANAGER_ROOT, TRUE, FALSE); gtk_ui_manager_node_prepend_ui_reference (NODE_INFO (node), merge_id, 0); - node = get_child_node (self, self->private_data->root_node, "popups", 6, - GTK_UI_MANAGER_POPUPS, TRUE, FALSE); - gtk_ui_manager_node_prepend_ui_reference (NODE_INFO (node), merge_id, 0); } @@ -333,8 +330,9 @@ gtk_ui_manager_get_accel_group (GtkUIManager *self) * * Looks up a widget by following a path. The path consists of the names specified * in the XML description of the UI. separated by '/'. Elements which don't have - * a name attribute in the XML (e.g. <popups>) can be addressed by their - * XML element name (e.g. "popups"). + * a name attribute in the XML (e.g. <popup>) can be addressed by their + * XML element name (e.g. "popup"). The root element (<ui>) can be omitted in + * the path. * * Return value: the widget found by following the path, or %NULL if no widget * was found. @@ -535,7 +533,6 @@ typedef enum STATE_ROOT, STATE_MENU, STATE_TOOLBAR, - STATE_POPUPS, STATE_MENUITEM, STATE_TOOLITEM, STATE_END @@ -567,15 +564,15 @@ start_element_handler (GMarkupParseContext *context, gint i; const gchar *node_name; + const gchar *action; GQuark action_quark; gboolean top; gboolean raise_error = TRUE; gchar *error_attr = NULL; - /* work out a name for this node. Either the name attribute, or - * element name */ - node_name = element_name; + node_name = NULL; + action = NULL; action_quark = 0; top = FALSE; for (i = 0; attribute_names[i] != NULL; i++) @@ -586,6 +583,7 @@ start_element_handler (GMarkupParseContext *context, } else if (!strcmp (attribute_names[i], "action")) { + action = attribute_values[i]; action_quark = g_quark_from_string (attribute_values[i]); } else if (!strcmp (attribute_names[i], "pos")) @@ -593,9 +591,16 @@ start_element_handler (GMarkupParseContext *context, top = !strcmp (attribute_values[i], "top"); } } - /* if no action, then set it to the node's name */ - if (action_quark == 0) - action_quark = g_quark_from_string (node_name); + + /* Work out a name for this node. Either the name attribute, or + * the action, or the element name */ + if (node_name == NULL) + { + if (action != NULL) + node_name = action; + else + node_name = element_name; + } switch (element_name[0]) { @@ -663,26 +668,12 @@ start_element_handler (GMarkupParseContext *context, } break; case 'p': - if (ctx->state == STATE_ROOT && !strcmp (element_name, "popups")) - { - ctx->state = STATE_POPUPS; - ctx->current = get_child_node (self, ctx->current, - node_name, strlen (node_name), - GTK_UI_MANAGER_POPUPS, - TRUE, FALSE); - - gtk_ui_manager_node_prepend_ui_reference (NODE_INFO (ctx->current), - ctx->merge_id, action_quark); - NODE_INFO (ctx->current)->dirty = TRUE; - - raise_error = FALSE; - } - else if (ctx->state == STATE_POPUPS && !strcmp (element_name, "popup")) + if (ctx->state == STATE_ROOT && !strcmp (element_name, "popup")) { ctx->state = STATE_MENU; ctx->current = get_child_node (self, ctx->current, node_name, strlen (node_name), - GTK_UI_MANAGER_MENU, + GTK_UI_MANAGER_POPUP, TRUE, FALSE); if (NODE_INFO (ctx->current)->action_name == 0) NODE_INFO (ctx->current)->action_name = action_quark; @@ -823,10 +814,8 @@ end_element_handler (GMarkupParseContext *context, break; case STATE_MENU: ctx->current = ctx->current->parent; - if (NODE_INFO (ctx->current)->type == GTK_UI_MANAGER_ROOT) /* menubar */ + if (NODE_INFO (ctx->current)->type == GTK_UI_MANAGER_ROOT) ctx->state = STATE_ROOT; - else if (NODE_INFO (ctx->current)->type == GTK_UI_MANAGER_POPUPS) /* popup */ - ctx->state = STATE_POPUPS; /* else, stay in STATE_MENU state */ break; case STATE_TOOLBAR: @@ -837,10 +826,6 @@ end_element_handler (GMarkupParseContext *context, ctx->state = STATE_ROOT; /* else, stay in STATE_TOOLBAR state */ break; - case STATE_POPUPS: - ctx->current = ctx->current->parent; - ctx->state = STATE_ROOT; - break; case STATE_MENUITEM: ctx->state = STATE_MENU; break; @@ -1089,6 +1074,7 @@ find_menu_position (GNode *node, pos = 0; break; case GTK_UI_MANAGER_MENU: + case GTK_UI_MANAGER_POPUP: menushell = NODE_INFO (parent)->proxy; if (GTK_IS_MENU_ITEM (menushell)) menushell = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menushell)); @@ -1281,62 +1267,59 @@ update_node (GtkUIManager *self, g_signal_emit (self, merge_signals[ADD_WIDGET], 0, info->proxy); } break; - case GTK_UI_MANAGER_MENU: - if (NODE_INFO (node->parent)->type == GTK_UI_MANAGER_POPUPS) - { - if (info->proxy == NULL) - { - GtkWidget *menu; - menu = gtk_menu_new (); - gtk_menu_set_accel_group (GTK_MENU (menu), self->private_data->accel_group); - info->proxy = menu; - } - } - else + case GTK_UI_MANAGER_POPUP: + if (info->proxy == NULL) { - GtkWidget *prev_submenu = NULL; - /* remove the proxy if it is of the wrong type ... */ - if (info->proxy && G_OBJECT_TYPE (info->proxy) != - GTK_ACTION_GET_CLASS (info->action)->menu_item_type) - { - prev_submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (info->proxy)); - if (prev_submenu) - { - g_object_ref (prev_submenu); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy),NULL); - } - gtk_container_remove (GTK_CONTAINER (info->proxy->parent), - info->proxy); - info->proxy = NULL; - } - /* create proxy if needed ... */ - if (info->proxy == NULL) - { - GtkWidget *menushell; - gint pos; - - if (find_menu_position (node, &menushell, &pos)) - { - GtkWidget *menu; - info->proxy = gtk_action_create_menu_item (info->action); - menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), menu); - gtk_menu_set_accel_group (GTK_MENU (menu), self->private_data->accel_group); - gtk_menu_shell_insert (GTK_MENU_SHELL (menushell), info->proxy, pos); - } - } - else - { - gtk_action_connect_proxy (info->action, info->proxy); - } - if (prev_submenu) - { - gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), - prev_submenu); - g_object_unref (prev_submenu); - } + info->proxy = gtk_menu_new (); + gtk_menu_set_accel_group (GTK_MENU (info->proxy), + self->private_data->accel_group); } break; + case GTK_UI_MANAGER_MENU: + { + GtkWidget *prev_submenu = NULL; + /* remove the proxy if it is of the wrong type ... */ + if (info->proxy && G_OBJECT_TYPE (info->proxy) != + GTK_ACTION_GET_CLASS (info->action)->menu_item_type) + { + prev_submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (info->proxy)); + if (prev_submenu) + { + g_object_ref (prev_submenu); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy),NULL); + } + gtk_container_remove (GTK_CONTAINER (info->proxy->parent), + info->proxy); + info->proxy = NULL; + } + /* create proxy if needed ... */ + if (info->proxy == NULL) + { + GtkWidget *menushell; + gint pos; + + if (find_menu_position (node, &menushell, &pos)) + { + GtkWidget *menu; + info->proxy = gtk_action_create_menu_item (info->action); + menu = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), menu); + gtk_menu_set_accel_group (GTK_MENU (menu), self->private_data->accel_group); + gtk_menu_shell_insert (GTK_MENU_SHELL (menushell), info->proxy, pos); + } + } + else + { + gtk_action_connect_proxy (info->action, info->proxy); + } + if (prev_submenu) + { + gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), + prev_submenu); + g_object_unref (prev_submenu); + } + } + break; case GTK_UI_MANAGER_UNDECIDED: g_warning ("found 'undecided node!"); break; @@ -1414,8 +1397,6 @@ update_node (GtkUIManager *self, } } break; - case GTK_UI_MANAGER_POPUPS: - break; case GTK_UI_MANAGER_MENUITEM: /* remove the proxy if it is of the wrong type ... */ if (info->proxy && G_OBJECT_TYPE (info->proxy) != @@ -1609,15 +1590,14 @@ static const gchar *open_tag_format[] = { "%*s<UNDECIDED>\n", "%*s<ui>\n", "%*s<menubar name=\"%s\">\n", - "%*s<menu name=\"%s\" action=\"%s\">\n", + "%*s<menu name='%s' action=\"%s\">\n", "%*s<toolbar name=\"%s\">\n", "%*s<placeholder name=\"%s\">\n", "%*s<placeholder name=\"%s\">\n", - "%*s<popups>\n", + "%*s<popup name='%s' action=\"%s\">\n", "%*s<menuitem name=\"%s\" action=\"%s\"/>\n", "%*s<toolitem name=\"%s\" action=\"%s\"/>\n", "%*s<separator/>\n", - "%*s<popup name=\"%s\">\n" }; static const gchar *close_tag_format[] = { @@ -1628,11 +1608,10 @@ static const gchar *close_tag_format[] = { "%*s</toolbar>\n", "%*s</placeholder>\n", "%*s</placeholder>\n", - "%*s</popups>\n", + "%*s</popup>\n", "", "", "", - "%*s</popup>\n" }; static void @@ -1643,16 +1622,10 @@ print_node (GtkUIManager *self, { GtkUIManagerNode *mnode; GNode *child; - guint type; mnode = node->data; - if (mnode->type == GTK_UI_MANAGER_MENU && - NODE_INFO (node->parent)->type == GTK_UI_MANAGER_POPUPS) - type = GTK_UI_MANAGER_SEPARATOR + 1; - else - type = mnode->type; - g_string_append_printf (buffer, open_tag_format[type], + g_string_append_printf (buffer, open_tag_format[mnode->type], indent_level, "", mnode->name, g_quark_to_string (mnode->action_name)); @@ -1660,7 +1633,7 @@ print_node (GtkUIManager *self, for (child = node->children; child != NULL; child = child->next) print_node (self, child, indent_level + 2, buffer); - g_string_append_printf (buffer, close_tag_format[type], + g_string_append_printf (buffer, close_tag_format[mnode->type], indent_level, ""); } |