static void gtk_application_window_update_shell_shows_menubar (GtkApplicationWindow *window, GtkSettings *settings) { gboolean shown_by_shell; g_object_get (settings, "gtk-shell-shows-menubar", &shown_by_shell, NULL); if (shown_by_shell) { /* the shell shows it, so don't show it locally */ if (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->menubar_section)) != 0) g_menu_remove (window->priv->menubar_section, 0); } else { /* the shell does not show it, so make sure we show it */ if (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->menubar_section)) == 0) { GMenuModel *menubar; menubar = gtk_application_get_menubar (gtk_window_get_application (GTK_WINDOW (window))); if (menubar != NULL) g_menu_append_section (window->priv->menubar_section, NULL, menubar); } } }
void gw_application_set_win_menubar (GwApplication *application, GMenuModel *menumodel) { //Sanity checks g_return_if_fail (application != NULL); g_return_if_fail (menumodel != NULL); if (g_menu_model_get_n_items (menumodel) == 0) return; //Declarations GMenuModel *menubar; gint length; //Initializations menubar = gtk_application_get_menubar (GTK_APPLICATION (application)); g_return_if_fail (menubar != NULL); length = g_menu_model_get_n_items (menubar); //Clear the menubar while (length-- > 0) g_menu_remove (G_MENU (menubar), 0); //Add the menuitem linking the menus { GMenuItem *menuitem = g_menu_item_new_section (NULL, menumodel); if (menuitem != NULL) { g_menu_append_item (G_MENU (menubar), menuitem); g_object_unref (menuitem); menuitem = NULL; } gw_application_add_accelerators (application, menubar); } }
static void gtk_application_window_update_shell_shows_app_menu (GtkApplicationWindow *window, GtkSettings *settings) { gboolean shown_by_shell; gboolean shown_by_titlebar; g_object_get (settings, "gtk-shell-shows-app-menu", &shown_by_shell, NULL); shown_by_titlebar = _gtk_window_titlebar_shows_app_menu (GTK_WINDOW (window)); if (shown_by_shell || shown_by_titlebar) { /* the shell shows it, so don't show it locally */ if (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->app_menu_section)) != 0) g_menu_remove (window->priv->app_menu_section, 0); } else { /* the shell does not show it, so make sure we show it */ if (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->app_menu_section)) == 0) { GMenuModel *app_menu = NULL; if (gtk_window_get_application (GTK_WINDOW (window)) != NULL) app_menu = gtk_application_get_app_menu (gtk_window_get_application (GTK_WINDOW (window))); if (app_menu != NULL) { const gchar *app_name; gchar *name; app_name = g_get_application_name (); if (app_name != g_get_prgname ()) { /* the app has set its application name, use it */ name = g_strdup (app_name); } else { /* get the name from .desktop file */ name = gtk_application_window_get_app_desktop_name (); if (name == NULL) name = g_strdup (_("Application")); } g_menu_append_submenu (window->priv->app_menu_section, name, app_menu); g_free (name); } } } }
static GMenuModel * find_gmenu_model (GMenuModel *model, const gchar *model_id) { gint i, n_items; GMenuModel *insertion_model = NULL; n_items = g_menu_model_get_n_items (model); for (i = 0; i < n_items && !insertion_model; i++) { gchar *id = NULL; if (g_menu_model_get_item_attribute (model, i, "id", "s", &id) && g_strcmp0 (id, model_id) == 0) { insertion_model = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION); if (!insertion_model) insertion_model = g_menu_model_get_item_link (model, i, G_MENU_LINK_SUBMENU); } else { GMenuModel *submodel; GMenuModel *submenu; gint j, j_items; submodel = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION); if (!submodel) submodel = g_menu_model_get_item_link (model, i, G_MENU_LINK_SUBMENU); if (!submodel) continue; j_items = g_menu_model_get_n_items (submodel); for (j = 0; j < j_items; j++) { submenu = g_menu_model_get_item_link (submodel, j, G_MENU_LINK_SUBMENU); if (submenu) { insertion_model = find_gmenu_model (submenu, model_id); g_object_unref (submenu); } if (insertion_model) break; } g_object_unref (submodel); } g_free (id); } return insertion_model; }
static void connect_to_items_changed (GMenuModel *model, GCallback callback, gpointer data) { gint i; GMenuModel *m; GMenuLinkIter *iter; if (!g_object_get_data (G_OBJECT (model), "handler-connected")) { g_signal_connect (model, "items-changed", callback, data); g_object_set_data (G_OBJECT (model), "handler-connected", GINT_TO_POINTER (1)); } for (i = 0; i < g_menu_model_get_n_items (model); i++) { iter = g_menu_model_iterate_item_links (model, i); while (g_menu_link_iter_next (iter)) { m = g_menu_link_iter_get_value (iter); connect_to_items_changed (m, callback, data); g_object_unref (m); } g_object_unref (iter); } }
static void impl_deactivate (EogWindowActivatable *activatable) { EogPostrPlugin *plugin = EOG_POSTR_PLUGIN (activatable); GMenu *menu; GMenuModel *model; gint i; eog_debug (DEBUG_PLUGINS); menu = eog_window_get_gear_menu_section (plugin->window, "plugins-section"); g_return_if_fail (G_IS_MENU (menu)); /* Remove menu entry */ model = G_MENU_MODEL (menu); for (i = 0; i < g_menu_model_get_n_items (model); i++) { gchar *id; if (g_menu_model_get_item_attribute (model, i, "id", "s", &id)) { const gboolean found = (g_strcmp0 (id, EOG_POSTR_PLUGIN_MENU_ID) == 0); g_free (id); if (found) { g_menu_remove (menu, i); break; } } } /* Finally remove action */ g_action_map_remove_action (G_ACTION_MAP (plugin->window), EOG_POSTR_PLUGIN_ACTION); }
static void toggle_italic (GtkToggleButton *button, gpointer data) { GMenuModel *model; GActionGroup *group; GSimpleAction *action; gboolean adding; GMenuModel *m; GtkTreeView *tv = data; GtkTreeModel *store; model = g_object_get_data (G_OBJECT (button), "model"); group = g_object_get_data (G_OBJECT (button), "group"); store = gtk_tree_view_get_model (tv); adding = gtk_toggle_button_get_active (button); m = g_menu_model_get_item_link (model, g_menu_model_get_n_items (model) - 1, G_MENU_LINK_SECTION); if (adding) { action = g_simple_action_new_stateful ("italic", NULL, g_variant_new_boolean (FALSE)); g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action)); g_signal_connect (action, "activate", G_CALLBACK (activate_toggle), NULL); g_object_unref (action); action_list_add (store, "italic"); g_menu_insert (G_MENU (m), 1, "Italic", "italic"); } else { g_action_map_remove_action (G_ACTION_MAP (group), "italic"); action_list_remove (store, "italic"); g_menu_remove (G_MENU (m), 1); } }
/* * The original GMenu is modified adding to the section @submodel_name * the items in @gmenu_to_merge. * @gmenu_to_merge should be a list of menu items. */ void nautilus_gmenu_merge (GMenu *original, GMenu *gmenu_to_merge, const gchar *submodel_name, gboolean prepend) { gint i, n_items; GMenuModel *submodel; GMenuItem *item; g_return_if_fail (G_IS_MENU (original)); g_return_if_fail (G_IS_MENU (gmenu_to_merge)); submodel = find_gmenu_model (G_MENU_MODEL (original), submodel_name); g_return_if_fail (submodel != NULL); n_items = g_menu_model_get_n_items (G_MENU_MODEL (gmenu_to_merge)); for (i = 0; i < n_items; i++) { item = g_menu_item_new_from_model (G_MENU_MODEL (gmenu_to_merge), i); if (prepend) { g_menu_prepend_item (G_MENU (submodel), item); } else { g_menu_append_item (G_MENU (submodel), item); } g_object_unref (item); } g_object_unref (submodel); }
static void disable_plugin (const gchar *name) { GMenuModel *plugin_menu; g_print ("Disabling '%s' plugin\n", name); plugin_menu = find_plugin_menu (); if (plugin_menu) { const gchar *id; gint i; for (i = 0; i < g_menu_model_get_n_items (plugin_menu); i++) { if (g_menu_model_get_item_attribute (plugin_menu, i, "id", "s", &id) && g_strcmp0 (id, name) == 0) { g_menu_remove (G_MENU (plugin_menu), i); g_print ("Menus of '%s' plugin removed\n", name); } } } else g_warning ("Plugin menu not found\n"); g_action_map_remove_action (G_ACTION_MAP (g_application_get_default ()), name); g_print ("Actions of '%s' plugin removed\n", name); if (g_strcmp0 (name, "red") == 0) is_red_plugin_enabled = FALSE; else is_black_plugin_enabled = FALSE; }
static void toggle_sumerian (GtkToggleButton *button, gpointer data) { GMenuModel *model; gboolean adding; GMenuModel *m; model = g_object_get_data (G_OBJECT (button), "model"); adding = gtk_toggle_button_get_active (button); m = g_menu_model_get_item_link (model, g_menu_model_get_n_items (model) - 1, G_MENU_LINK_SECTION); m = g_menu_model_get_item_link (m, g_menu_model_get_n_items (m) - 1, G_MENU_LINK_SUBMENU); if (adding) g_menu_append (G_MENU (m), "Sumerian", "lang::sumerian"); else g_menu_remove (G_MENU (m), g_menu_model_get_n_items (m) - 1); }
static GMenuModel * find_extension_point_section (GMenuModel *model, const gchar *extension_point) { gint i, n_items; GMenuModel *section = NULL; n_items = g_menu_model_get_n_items (model); for (i = 0; i < n_items && !section; i++) { gchar *id = NULL; if (g_menu_model_get_item_attribute (model, i, "id", "s", &id) && strcmp (id, extension_point) == 0) { section = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION); } else { GMenuModel *subsection; GMenuModel *submenu; gint j, j_items; subsection = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION); j_items = g_menu_model_get_n_items (subsection); for (j = 0; j < j_items && !section; j++) { submenu = g_menu_model_get_item_link (subsection, j, G_MENU_LINK_SUBMENU); if (submenu) { section = find_extension_point_section (submenu, extension_point); } } } g_free (id); } return section; }
static void toggle_speed (GtkToggleButton *button, gpointer data) { GMenuModel *model; GActionGroup *group; GSimpleAction *action; gboolean adding; GMenuModel *m; GMenu *submenu; GtkTreeView *tv = data; GtkTreeModel *store; model = g_object_get_data (G_OBJECT (button), "model"); group = g_object_get_data (G_OBJECT (button), "group"); store = gtk_tree_view_get_model (tv); adding = gtk_toggle_button_get_active (button); m = g_menu_model_get_item_link (model, 1, G_MENU_LINK_SECTION); if (adding) { action = g_simple_action_new ("faster", NULL); g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action)); g_signal_connect (action, "activate", G_CALLBACK (activate_action), NULL); g_object_unref (action); action = g_simple_action_new ("slower", NULL); g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (action)); g_signal_connect (action, "activate", G_CALLBACK (activate_action), NULL); g_object_unref (action); action_list_add (store, "faster"); action_list_add (store, "slower"); submenu = g_menu_new (); g_menu_append (submenu, "Faster", "faster"); g_menu_append (submenu, "Slower", "slower"); g_menu_append_submenu (G_MENU (m), "Speed", G_MENU_MODEL (submenu)); } else { g_action_map_remove_action (G_ACTION_MAP (group), "faster"); g_action_map_remove_action (G_ACTION_MAP (group), "slower"); action_list_remove (store, "faster"); action_list_remove (store, "slower"); g_menu_remove (G_MENU (m), g_menu_model_get_n_items (m) - 1); } }
static void gtk_application_window_update_menubar (GtkApplicationWindow *window) { gboolean should_have_menubar; gboolean have_menubar; have_menubar = window->priv->menubar != NULL; should_have_menubar = window->priv->show_menubar && (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->app_menu_section)) || g_menu_model_get_n_items (G_MENU_MODEL (window->priv->menubar_section))); if (have_menubar && !should_have_menubar) { gtk_widget_unparent (window->priv->menubar); window->priv->menubar = NULL; gtk_widget_queue_resize (GTK_WIDGET (window)); } if (!have_menubar && should_have_menubar) { GMenu *combined; combined = g_menu_new (); g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->app_menu_section)); g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->menubar_section)); window->priv->menubar = gtk_menu_bar_new_from_model (G_MENU_MODEL (combined)); gtk_widget_set_parent (window->priv->menubar, GTK_WIDGET (window)); gtk_widget_show_all (window->priv->menubar); g_object_unref (combined); gtk_widget_queue_resize (GTK_WIDGET (window)); } }
static void g_menu_exporter_menu_prepare (GMenuExporterMenu *menu) { gint n_items; g_assert (menu->item_links == NULL); if (g_menu_model_is_mutable (menu->model)) menu->handler_id = g_signal_connect (menu->model, "items-changed", G_CALLBACK (g_menu_exporter_menu_items_changed), menu); menu->item_links = g_sequence_new (g_menu_exporter_link_free); n_items = g_menu_model_get_n_items (menu->model); if (n_items) g_menu_exporter_menu_items_changed (menu->model, 0, 0, n_items, menu); }
static void eog_reload_plugin_deactivate (EogWindowActivatable *activatable) { const gchar * const empty_accels[1] = { NULL }; EogReloadPlugin *plugin = EOG_RELOAD_PLUGIN (activatable); GMenu *menu; GMenuModel *model; gint i; eog_debug (DEBUG_PLUGINS); menu = eog_window_get_gear_menu_section (plugin->window, "plugins-section"); g_return_if_fail (G_IS_MENU (menu)); /* Remove menu entry */ model = G_MENU_MODEL (menu); for (i = 0; i < g_menu_model_get_n_items (model); i++) { gchar *id; if (g_menu_model_get_item_attribute (model, i, "id", "s", &id)) { const gboolean found = (g_strcmp0 (id, EOG_RELOAD_PLUGIN_MENU_ID) == 0); g_free (id); if (found) { g_menu_remove (menu, i); break; } } } /* Unset accelerator */ gtk_application_set_accels_for_action(GTK_APPLICATION (EOG_APP), "win." EOG_RELOAD_PLUGIN_ACTION, empty_accels); /* Disconnect selection-changed handler as the thumbview would * otherwise still cause callbacks during its own disposal */ g_signal_handlers_disconnect_by_func (eog_window_get_thumb_view (plugin->window), _selection_changed_cb, plugin); /* Finally remove action */ g_action_map_remove_action (G_ACTION_MAP (plugin->window), EOG_RELOAD_PLUGIN_ACTION); }
void gw_menumodel_set_links (GMenuModel *menumodel, const gchar *LABEL, const gchar *NEW_LABEL, const gchar *LINK_TYPE, GMenuModel *link) { //Sanity checks g_return_if_fail (menumodel != NULL); g_return_if_fail (LABEL != NULL); g_return_if_fail (LINK_TYPE != NULL); //Declarations gint total_items; gint index; gchar *label; gboolean valid; GMenuItem *menuitem; GMenuModel *sublink; //Initializations total_items = g_menu_model_get_n_items (menumodel); for (index = 0; index < total_items; index++) { valid = g_menu_model_get_item_attribute (menumodel, index, G_MENU_ATTRIBUTE_LABEL, "s", &label, NULL); if (valid == TRUE && label != NULL) { if (label != NULL && strcmp (label, LABEL) == 0) { menuitem = g_menu_item_new (NEW_LABEL, NULL); g_menu_item_set_link (menuitem, LINK_TYPE, link); g_menu_remove (G_MENU (menumodel), index); g_menu_insert_item (G_MENU (menumodel), index, menuitem); g_object_unref (menuitem); menuitem = NULL; } g_free (label); label = NULL; } //Recursive work sublink = g_menu_model_get_item_link (menumodel, index, G_MENU_LINK_SUBMENU); if (sublink != NULL) gw_menumodel_set_links (sublink, LABEL, NEW_LABEL, LINK_TYPE, link); sublink = g_menu_model_get_item_link (menumodel, index, G_MENU_LINK_SECTION); if (sublink != NULL) gw_menumodel_set_links (sublink, LABEL, NEW_LABEL, LINK_TYPE, link); } }
void gw_application_remove_accelerators (GwApplication *application, GMenuModel *menumodel) { //Sanity checks g_return_if_fail (application != NULL); g_return_if_fail (menumodel != NULL); //Declarations gint total_items; gint index; gchar *accel = NULL; gchar *action = NULL; gchar *detail = NULL; GMenuModel *sublink = NULL; //Initializations total_items = g_menu_model_get_n_items (menumodel); for (index = 0; index < total_items; index++) { g_menu_model_get_item_attribute (menumodel, index, "accel", "s", &accel, NULL); g_menu_model_get_item_attribute (menumodel, index, G_MENU_ATTRIBUTE_ACTION, "s", &action, NULL); g_menu_model_get_item_attribute (menumodel, index, G_MENU_ATTRIBUTE_TARGET, "s", &detail, NULL); if (accel != NULL && action != NULL) { if (detail != NULL) gtk_application_remove_accelerator (GTK_APPLICATION (application), action, g_variant_new_string (detail)); else gtk_application_remove_accelerator (GTK_APPLICATION (application), action, NULL); } if (accel != NULL) g_free (accel); accel = NULL; if (action != NULL) g_free (action); action = NULL; if (detail != NULL) g_free (detail); detail = NULL; //Recursive work sublink = g_menu_model_get_item_link (menumodel, index, G_MENU_LINK_SUBMENU); if (sublink != NULL) gw_application_remove_accelerators (application, sublink); sublink = g_menu_model_get_item_link (menumodel, index, G_MENU_LINK_SECTION); if (sublink != NULL) gw_application_remove_accelerators (application, sublink); } }
static void extract_accels_from_menu(GMenuModel * model, GActionMap * action_map, GtkAccelGroup * accel_group) { gint i, n = g_menu_model_get_n_items(model); GMenuLinkIter *iter; const gchar *key; GMenuModel *m; for (i = 0; i < n; i++) { extract_accel_from_menu_item(model, i, action_map, accel_group); iter = g_menu_model_iterate_item_links(model, i); while (g_menu_link_iter_get_next(iter, &key, &m)) { extract_accels_from_menu(m, action_map, accel_group); g_object_unref(m); } g_object_unref(iter); } }
static void add_accelerators_from_menu (GtkWindow *window, GtkAccelGroup *accel_group, GMenuModel *model) { int i; GMenuLinkIter *iter; const char *key; GMenuModel *m; for (i = 0; i < g_menu_model_get_n_items (model); i++) { add_accelerators_from_menu_item (window, accel_group, model, i); iter = g_menu_model_iterate_item_links (model, i); while (g_menu_link_iter_get_next (iter, &key, &m)) { add_accelerators_from_menu (window, accel_group, m); g_object_unref (m); } g_object_unref (iter); } }
static void impl_deactivate (EogWindowActivatable *activatable) { const gchar * const empty_accels[1] = { NULL }; EogFitToWidthPlugin *plugin = EOG_FIT_TO_WIDTH_PLUGIN (activatable); GMenu *menu; GMenuModel *model; gint i; menu = eog_window_get_gear_menu_section (plugin->window, "plugins-section"); g_return_if_fail (G_IS_MENU (menu)); /* Remove menu entry */ model = G_MENU_MODEL (menu); for (i = 0; i < g_menu_model_get_n_items (model); i++) { gchar *id; if (g_menu_model_get_item_attribute (model, i, "id", "s", &id)) { const gboolean found = (g_strcmp0 (id, EOG_FIT_TO_WIDTH_PLUGIN_MENU_ID) == 0); g_free (id); if (found) { g_menu_remove (menu, i); break; } } } /* Unset accelerator */ gtk_application_set_accels_for_action(GTK_APPLICATION (EOG_APP), "win." EOG_FIT_TO_WIDTH_PLUGIN_ACTION, empty_accels); /* Finally remove action */ g_action_map_remove_action (G_ACTION_MAP (plugin->window), EOG_FIT_TO_WIDTH_PLUGIN_ACTION); }
void nautilus_gmenu_replace_section (GMenu *menu, const gchar *section_id, GMenuModel *section) { GMenuModel *orig_section; GMenuItem *item; gint idx; orig_section = find_gmenu_model (G_MENU_MODEL (menu), section_id); g_return_if_fail (orig_section != NULL); g_menu_remove_all (G_MENU (orig_section)); for (idx = 0; idx < g_menu_model_get_n_items (section); idx++) { item = g_menu_item_new_from_model (section, idx); g_menu_append_item (G_MENU (orig_section), item); g_object_unref (item); } g_object_unref (orig_section); }
GeditMenuExtension * gedit_window_activatable_extend_gear_menu (GeditWindowActivatable *activatable, const gchar *extension_point) { GeditMenuExtension *menu = NULL; GeditWindow *window; GMenuModel *model; gint i, n_items; g_return_val_if_fail (GEDIT_IS_WINDOW_ACTIVATABLE (activatable), NULL); g_return_val_if_fail (extension_point != NULL, NULL); g_object_get (G_OBJECT (activatable), "window", &window, NULL); model = _gedit_window_get_gear_menu (window); g_object_unref (window); n_items = g_menu_model_get_n_items (model); for (i = 0; i < n_items; i++) { gchar *id = NULL; if (g_menu_model_get_item_attribute (model, i, "id", "s", &id) && strcmp (id, extension_point) == 0) { GMenuModel *section; section = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION); menu = _gedit_menu_extension_new (G_MENU (section)); } g_free (id); } return menu; }
static gboolean append_menu (RBButtonBar *bar, GMenuModel *menu, gboolean need_separator) { int i; gulong id; id = g_signal_connect (menu, "items-changed", G_CALLBACK (items_changed_cb), bar); g_hash_table_insert (bar->priv->handlers, (gpointer)id, g_object_ref (menu)); for (i = 0; i < g_menu_model_get_n_items (menu); i++) { char *label_text; char *accel; GtkWidget *button; GtkWidget *label; GMenuModel *submenu; /* recurse into sections */ submenu = g_menu_model_get_item_link (menu, i, G_MENU_LINK_SECTION); if (submenu != NULL) { need_separator = append_menu (bar, submenu, TRUE); continue; } /* if this item and the previous item are in different sections, add * a separator between them. this may not be a good idea. */ if (need_separator) { GtkWidget *sep; if (bar->priv->position > 0) { sep = gtk_separator_new (GTK_ORIENTATION_VERTICAL); gtk_widget_show (sep); g_object_set (sep, "margin-start", 6, "margin-end", 6, NULL); gtk_grid_attach (GTK_GRID (bar), sep, bar->priv->position++, 0, 1, 1); } need_separator = FALSE; } button = NULL; /* submenus become menu buttons, normal items become buttons */ submenu = g_menu_model_get_item_link (menu, i, G_MENU_LINK_SUBMENU); if (submenu != NULL) { button = gtk_menu_button_new (); gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), submenu); g_object_set_data_full (G_OBJECT (button), "rb-menu-model", g_object_ref (submenu), (GDestroyNotify)g_object_unref); } else { GMenuAttributeIter *iter; const char *name; GVariant *value; char *str; guint signal_id; /* we can't do more than one of action and rb-property-bind * and rb-signal-bind, so just do whichever turns up first * in the iterator */ iter = g_menu_model_iterate_item_attributes (menu, i); while (g_menu_attribute_iter_get_next (iter, &name, &value)) { if (g_str_equal (name, "action")) { button = gtk_button_new (); g_variant_get (value, "s", &str, NULL); gtk_actionable_set_action_name (GTK_ACTIONABLE (button), str); /* action target too somehow? */ g_free (str); break; } else if (g_str_equal (name, "rb-property-bind")) { /* property has to be a boolean, can't do inverts, etc. etc. */ button = gtk_toggle_button_new (); g_variant_get (value, "s", &str, NULL); g_object_bind_property (bar->priv->target, str, button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); g_free (str); break; } else if (g_str_equal (name, "rb-signal-bind")) { button = gtk_button_new (); g_variant_get (value, "s", &str, NULL); signal_id = g_signal_lookup (str, G_OBJECT_TYPE (bar->priv->target)); if (signal_id != 0) { g_object_set_data (G_OBJECT (button), "rb-signal-bind-id", GUINT_TO_POINTER (signal_id)); g_signal_connect (button, "clicked", G_CALLBACK (signal_button_clicked_cb), bar); } g_free (str); break; } } g_object_unref (iter); } if (button == NULL) { g_warning ("no idea what's going on here"); continue; } gtk_widget_set_hexpand (button, FALSE); gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); label_text = NULL; g_menu_model_get_item_attribute (menu, i, "label", "s", &label_text); label = gtk_label_new (g_dgettext (NULL, label_text)); g_object_set (label, "margin-left", 6, "margin-right", 6, NULL); gtk_container_add (GTK_CONTAINER (button), label); if (g_menu_model_get_item_attribute (menu, i, "accel", "s", &accel)) { g_object_set_data_full (G_OBJECT (button), "rb-accel", accel, (GDestroyNotify) g_free); } gtk_widget_show_all (button); gtk_size_group_add_widget (bar->priv->size_group, button); gtk_grid_attach (GTK_GRID (bar), button, bar->priv->position++, 0, 1, 1); g_free (label_text); } return need_separator; }
static void gtk_model_menu_binding_append_model (GtkModelMenuBinding *binding, GMenuModel *model, gboolean with_separators) { gint n, i; g_signal_connect (model, "items-changed", G_CALLBACK (gtk_model_menu_binding_items_changed), binding); binding->connected = g_slist_prepend (binding->connected, g_object_ref (model)); /* Deciding if we should show a separator is a bit difficult. There * are two types of separators: * * - section headings (when sections have 'label' property) * * - normal separators automatically put between sections * * The easiest way to think about it is that a section usually has a * separator (or heading) immediately before it. * * There are three exceptions to this general rule: * * - empty sections don't get separators or headings * * - sections only get separators and headings at the toplevel of a * menu (ie: no separators on nested sections or in menubars) * * - the first section in the menu doesn't get a normal separator, * but it can get a header (if it's not empty) * * Unfortunately, we cannot simply check the size of the section in * order to determine if we should place a header: the section may * contain other sections that are themselves empty. Instead, we need * to append the section, and check if we ended up with any actual * content. If we did, then we need to insert before that content. * We use 'our_position' to keep track of this. */ n = g_menu_model_get_n_items (model); for (i = 0; i < n; i++) { gint our_position = binding->n_items; gchar *heading = NULL; gtk_model_menu_binding_append_item (binding, model, i, &heading); if (with_separators && our_position < binding->n_items) { GtkWidget *separator = NULL; if (heading) { separator = gtk_menu_item_new_with_label (heading); gtk_widget_set_sensitive (separator, FALSE); } else if (our_position > 0) separator = gtk_separator_menu_item_new (); if (separator) { gtk_menu_shell_insert (binding->shell, separator, our_position); gtk_widget_show (separator); binding->n_items++; } } g_free (heading); } }
static GString * g_menu_markup_print_string (GString *string, GMenuModel *model, gint indent, gint tabstop) { gboolean need_nl = FALSE; gint i, n; if G_UNLIKELY (string == NULL) string = g_string_new (NULL); n = g_menu_model_get_n_items (model); for (i = 0; i < n; i++) { GMenuAttributeIter *attr_iter; GMenuLinkIter *link_iter; GString *contents; GString *attrs; attr_iter = g_menu_model_iterate_item_attributes (model, i); link_iter = g_menu_model_iterate_item_links (model, i); contents = g_string_new (NULL); attrs = g_string_new (NULL); while (g_menu_attribute_iter_next (attr_iter)) { const char *name = g_menu_attribute_iter_get_name (attr_iter); GVariant *value = g_menu_attribute_iter_get_value (attr_iter); if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) { gchar *str; str = g_markup_printf_escaped (" %s='%s'", name, g_variant_get_string (value, NULL)); g_string_append (attrs, str); g_free (str); } else { gchar *printed; gchar *str; const gchar *type; printed = g_variant_print (value, TRUE); type = g_variant_type_peek_string (g_variant_get_type (value)); str = g_markup_printf_escaped ("<attribute name='%s' type='%s'>%s</attribute>\n", name, type, printed); indent_string (contents, indent + tabstop); g_string_append (contents, str); g_free (printed); g_free (str); } g_variant_unref (value); } g_object_unref (attr_iter); while (g_menu_link_iter_next (link_iter)) { const gchar *name = g_menu_link_iter_get_name (link_iter); GMenuModel *menu = g_menu_link_iter_get_value (link_iter); gchar *str; if (contents->str[0]) g_string_append_c (contents, '\n'); str = g_markup_printf_escaped ("<link name='%s'>\n", name); indent_string (contents, indent + tabstop); g_string_append (contents, str); g_free (str); g_menu_markup_print_string (contents, menu, indent + 2 * tabstop, tabstop); indent_string (contents, indent + tabstop); g_string_append (contents, "</link>\n"); g_object_unref (menu); } g_object_unref (link_iter); if (contents->str[0]) { indent_string (string, indent); g_string_append_printf (string, "<item%s>\n", attrs->str); g_string_append (string, contents->str); indent_string (string, indent); g_string_append (string, "</item>\n"); need_nl = TRUE; } else { if (need_nl) g_string_append_c (string, '\n'); indent_string (string, indent); g_string_append_printf (string, "<item%s/>\n", attrs->str); need_nl = FALSE; } g_string_free (contents, TRUE); g_string_free (attrs, TRUE); } return string; }
static void append_items_from_model (GtkWidget *menu, GMenuModel *model, GActionGroup *group, gboolean *need_separator, const gchar *heading) { gint n; gint i; GtkWidget *w; GtkWidget *menuitem; GtkWidget *submenu; GMenuModel *m; gchar *label; n = g_menu_model_get_n_items (model); if (*need_separator && n > 0) { w = gtk_separator_menu_item_new (); gtk_widget_show (w); gtk_menu_shell_append (GTK_MENU_SHELL (menu), w); *need_separator = FALSE; } if (heading != NULL) { w = gtk_menu_item_new_with_label (heading); gtk_widget_show (w); gtk_widget_set_sensitive (w, FALSE); gtk_menu_shell_append (GTK_MENU_SHELL (menu), w); } for (i = 0; i < n; i++) { if ((m = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION))) { label = NULL; g_menu_model_get_item_attribute (model, i, G_MENU_ATTRIBUTE_LABEL, "s", &label); append_items_from_model (menu, m, group, need_separator, label); g_object_unref (m); g_free (label); if (*need_separator) { w = gtk_separator_menu_item_new (); gtk_widget_show (w); gtk_menu_shell_append (GTK_MENU_SHELL (menu), w); *need_separator = FALSE; } continue; } menuitem = create_menuitem_from_model (model, i, group); if ((m = g_menu_model_get_item_link (model, i, G_MENU_LINK_SUBMENU))) { submenu = create_menu_from_model (m, group); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu); g_object_unref (m); } gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); *need_separator = TRUE; } }