#include "gtkaccelmapprivate.h"
#include "gtkactionhelper.h"
-#include "gtkmodelmenu.h"
+#include "gtkwidgetprivate.h"
+#include "gtkaccellabel.h"
struct _GtkModelMenuItem
{
}
}
+static void
+gtk_model_menu_item_submenu_shown (GtkWidget *widget,
+ gpointer user_data)
+{
+ const gchar *action_name = user_data;
+ GActionMuxer *muxer;
+
+ muxer = _gtk_widget_get_action_muxer (widget);
+ g_action_group_change_action_state (G_ACTION_GROUP (muxer), action_name, g_variant_new_boolean (TRUE));
+}
+
+static void
+gtk_model_menu_item_submenu_hidden (GtkWidget *widget,
+ gpointer user_data)
+{
+ const gchar *action_name = user_data;
+ GActionMuxer *muxer;
+
+ muxer = _gtk_widget_get_action_muxer (widget);
+ g_action_group_change_action_state (G_ACTION_GROUP (muxer), action_name, g_variant_new_boolean (FALSE));
+}
+
static void
gtk_model_menu_item_setup (GtkModelMenuItem *item,
GMenuModel *model,
gint item_index,
- const gchar *action_namespace,
- GtkAccelGroup *accels)
+ const gchar *action_namespace)
{
GMenuAttributeIter *iter;
GMenuModel *submenu;
GtkWidget *menu;
g_menu_model_get_item_attribute (model, item_index, "action-namespace", "s", §ion_namespace);
+ menu = gtk_menu_new ();
if (action_namespace)
{
gchar *namespace = g_strjoin (".", action_namespace, section_namespace, NULL);
- menu = gtk_model_menu_create_menu (submenu, namespace, accels);
+ gtk_menu_shell_bind_model (GTK_MENU_SHELL (menu), submenu, namespace, TRUE);
g_free (namespace);
}
else
- {
- menu = gtk_model_menu_create_menu (submenu, section_namespace, accels);
- }
+ gtk_menu_shell_bind_model (GTK_MENU_SHELL (menu), submenu, section_namespace, TRUE);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
if (g_str_equal (key, "label") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
gtk_menu_item_set_label (GTK_MENU_ITEM (item), g_variant_get_string (value, NULL));
+ else if (g_str_equal (key, "accel") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+ {
+ GdkModifierType modifiers;
+ guint key;
+
+ gtk_accelerator_parse (g_variant_get_string (value, NULL), &key, &modifiers);
+
+ if (key)
+ {
+ GtkAccelLabel *accel_label;
+
+ /* Ensure that the GtkAccelLabel has been created... */
+ (void) gtk_menu_item_get_label (GTK_MENU_ITEM (item));
+ accel_label = GTK_ACCEL_LABEL (gtk_bin_get_child (GTK_BIN (item)));
+ g_assert (accel_label);
+
+ gtk_accel_label_set_accel (accel_label, key, modifiers);
+ }
+ }
+
else if (g_str_equal (key, "action") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
gtk_actionable_set_namespaced_action_name (GTK_ACTIONABLE (item), action_namespace,
g_variant_get_string (value, NULL));
else if (g_str_equal (key, "target"))
gtk_actionable_set_action_target_value (GTK_ACTIONABLE (item), value);
+ else if (g_str_equal (key, "submenu-action") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+ {
+ GtkWidget *submenu;
+
+ submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (item));
+
+ if (submenu != NULL)
+ {
+ const gchar *action = g_variant_get_string (value, NULL);
+ gchar *full_action;
+
+ if (action_namespace)
+ full_action = g_strjoin (".", action_namespace, action, NULL);
+ else
+ full_action = g_strdup (action);
+
+ g_object_set_data_full (G_OBJECT (submenu), "gtkmodelmenu-visibility-action", full_action, g_free);
+ g_signal_connect (submenu, "show", G_CALLBACK (gtk_model_menu_item_submenu_shown), full_action);
+ g_signal_connect (submenu, "hide", G_CALLBACK (gtk_model_menu_item_submenu_hidden), full_action);
+ }
+ }
+
g_variant_unref (value);
}
g_object_unref (iter);
GtkMenuItem *
gtk_model_menu_item_new (GMenuModel *model,
gint item_index,
- const gchar *action_namespace,
- GtkAccelGroup *accels)
+ const gchar *action_namespace)
{
GtkModelMenuItem *item;
item = g_object_new (GTK_TYPE_MODEL_MENU_ITEM, NULL);
- gtk_model_menu_item_setup (item, model, item_index, action_namespace, accels);
+ gtk_model_menu_item_setup (item, model, item_index, action_namespace);
return GTK_MENU_ITEM (item);
}