2 * Copyright © 2011 Canonical Ltd.
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * licence, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 * Author: Ryan Lortie <desrt@desrt.ca>
31 * @short_description: A simple implementation of GMenuModel
33 * #GMenu is a simple implementation of #GMenuModel.
34 * You populate a #GMenu by adding #GMenuItem instances to it.
36 * There are some convenience functions to allow you to directly
37 * add items (avoiding #GMenuItem) for the common cases. To add
38 * a regular item, use g_menu_insert(). To add a section, use
39 * g_menu_insert_section(). To add a submenu, use
40 * g_menu_insert_submenu().
46 * #GMenu is an opaque structure type. You must access it using the
55 * #GMenuItem is an opaque structure type. You must access it using the
63 GObject parent_instance;
65 GHashTable *attributes;
70 typedef GObjectClass GMenuItemClass;
74 GMenuModel parent_instance;
80 typedef GMenuModelClass GMenuClass;
82 G_DEFINE_TYPE (GMenu, g_menu, G_TYPE_MENU_MODEL)
83 G_DEFINE_TYPE (GMenuItem, g_menu_item, G_TYPE_OBJECT)
87 GHashTable *attributes;
92 g_menu_is_mutable (GMenuModel *model)
94 GMenu *menu = G_MENU (model);
100 g_menu_get_n_items (GMenuModel *model)
102 GMenu *menu = G_MENU (model);
104 return menu->items->len;
108 g_menu_get_item_attributes (GMenuModel *model,
112 GMenu *menu = G_MENU (model);
114 *table = g_hash_table_ref (g_array_index (menu->items, struct item, position).attributes);
118 g_menu_get_item_links (GMenuModel *model,
122 GMenu *menu = G_MENU (model);
124 *table = g_hash_table_ref (g_array_index (menu->items, struct item, position).links);
128 * g_menu_insert_item:
130 * @position: the position at which to insert the item
131 * @item: the #GMenuItem to insert
133 * Inserts @item into @menu.
135 * The "insertion" is actually done by copying all of the attribute and
136 * link values of @item and using them to form a new item within @menu.
137 * As such, @item itself is not really inserted, but rather, a menu item
138 * that is exactly the same as the one presently described by @item.
140 * This means that @item is essentially useless after the insertion
141 * occurs. Any changes you make to it are ignored unless it is inserted
142 * again (at which point its updated values will be copied).
144 * You should probably just free @item once you're done.
146 * There are many convenience functions to take care of common cases.
147 * See g_menu_insert(), g_menu_insert_section() and
148 * g_menu_insert_submenu() as well as "prepend" and "append" variants of
149 * each of these functions.
154 g_menu_insert_item (GMenu *menu,
158 struct item new_item;
160 g_return_if_fail (G_IS_MENU (menu));
161 g_return_if_fail (G_IS_MENU_ITEM (item));
163 if (position < 0 || position > menu->items->len)
164 position = menu->items->len;
166 new_item.attributes = g_hash_table_ref (item->attributes);
167 new_item.links = g_hash_table_ref (item->links);
170 g_array_insert_val (menu->items, position, new_item);
171 g_menu_model_items_changed (G_MENU_MODEL (menu), position, 0, 1);
175 * g_menu_prepend_item:
177 * @item: a #GMenuItem to prepend
179 * Prepends @item to the start of @menu.
181 * See g_menu_insert_item() for more information.
186 g_menu_prepend_item (GMenu *menu,
189 g_menu_insert_item (menu, 0, item);
193 * g_menu_append_item:
195 * @item: a #GMenuItem to append
197 * Appends @item to the end of @menu.
199 * See g_menu_insert_item() for more information.
204 g_menu_append_item (GMenu *menu,
207 g_menu_insert_item (menu, -1, item);
214 * Marks @menu as frozen.
216 * After the menu is frozen, it is an error to attempt to make any
217 * changes to it. In effect this means that the #GMenu API must no
220 * This function causes g_menu_model_is_mutable() to begin returning
221 * %FALSE, which has some positive performance implications.
226 g_menu_freeze (GMenu *menu)
228 g_return_if_fail (G_IS_MENU (menu));
230 menu->mutable = FALSE;
236 * Creates a new #GMenu.
238 * The new menu has no items.
240 * Returns: a new #GMenu
247 return g_object_new (G_TYPE_MENU, NULL);
253 * @position: the position at which to insert the item
254 * @label: (allow-none): the section label, or %NULL
255 * @detailed_action: (allow-none): the detailed action string, or %NULL
257 * Convenience function for inserting a normal menu item into @menu.
258 * Combine g_menu_item_new() and g_menu_insert_item() for a more flexible
264 g_menu_insert (GMenu *menu,
267 const gchar *detailed_action)
269 GMenuItem *menu_item;
271 menu_item = g_menu_item_new (label, detailed_action);
272 g_menu_insert_item (menu, position, menu_item);
273 g_object_unref (menu_item);
279 * @label: (allow-none): the section label, or %NULL
280 * @detailed_action: (allow-none): the detailed action string, or %NULL
282 * Convenience function for prepending a normal menu item to the start
283 * of @menu. Combine g_menu_item_new() and g_menu_insert_item() for a more
284 * flexible alternative.
289 g_menu_prepend (GMenu *menu,
291 const gchar *detailed_action)
293 g_menu_insert (menu, 0, label, detailed_action);
299 * @label: (allow-none): the section label, or %NULL
300 * @detailed_action: (allow-none): the detailed action string, or %NULL
302 * Convenience function for appending a normal menu item to the end of
303 * @menu. Combine g_menu_item_new() and g_menu_insert_item() for a more
304 * flexible alternative.
309 g_menu_append (GMenu *menu,
311 const gchar *detailed_action)
313 g_menu_insert (menu, -1, label, detailed_action);
317 * g_menu_insert_section:
319 * @position: the position at which to insert the item
320 * @label: (allow-none): the section label, or %NULL
321 * @section: a #GMenuModel with the items of the section
323 * Convenience function for inserting a section menu item into @menu.
324 * Combine g_menu_item_new_section() and g_menu_insert_item() for a more
325 * flexible alternative.
330 g_menu_insert_section (GMenu *menu,
335 GMenuItem *menu_item;
337 menu_item = g_menu_item_new_section (label, section);
338 g_menu_insert_item (menu, position, menu_item);
339 g_object_unref (menu_item);
344 * g_menu_prepend_section:
346 * @label: (allow-none): the section label, or %NULL
347 * @section: a #GMenuModel with the items of the section
349 * Convenience function for prepending a section menu item to the start
350 * of @menu. Combine g_menu_item_new_section() and g_menu_insert_item() for
351 * a more flexible alternative.
356 g_menu_prepend_section (GMenu *menu,
360 g_menu_insert_section (menu, 0, label, section);
364 * g_menu_append_section:
366 * @label: (allow-none): the section label, or %NULL
367 * @section: a #GMenuModel with the items of the section
369 * Convenience function for appending a section menu item to the end of
370 * @menu. Combine g_menu_item_new_section() and g_menu_insert_item() for a
371 * more flexible alternative.
376 g_menu_append_section (GMenu *menu,
380 g_menu_insert_section (menu, -1, label, section);
384 * g_menu_insert_submenu:
386 * @position: the position at which to insert the item
387 * @label: (allow-none): the section label, or %NULL
388 * @submenu: a #GMenuModel with the items of the submenu
390 * Convenience function for inserting a submenu menu item into @menu.
391 * Combine g_menu_item_new_submenu() and g_menu_insert_item() for a more
392 * flexible alternative.
397 g_menu_insert_submenu (GMenu *menu,
402 GMenuItem *menu_item;
404 menu_item = g_menu_item_new_submenu (label, submenu);
405 g_menu_insert_item (menu, position, menu_item);
406 g_object_unref (menu_item);
410 * g_menu_prepend_submenu:
412 * @label: (allow-none): the section label, or %NULL
413 * @submenu: a #GMenuModel with the items of the submenu
415 * Convenience function for prepending a submenu menu item to the start
416 * of @menu. Combine g_menu_item_new_submenu() and g_menu_insert_item() for
417 * a more flexible alternative.
422 g_menu_prepend_submenu (GMenu *menu,
426 g_menu_insert_submenu (menu, 0, label, submenu);
430 * g_menu_append_submenu:
432 * @label: (allow-none): the section label, or %NULL
433 * @submenu: a #GMenuModel with the items of the submenu
435 * Convenience function for appending a submenu menu item to the end of
436 * @menu. Combine g_menu_item_new_submenu() and g_menu_insert_item() for a
437 * more flexible alternative.
442 g_menu_append_submenu (GMenu *menu,
446 g_menu_insert_submenu (menu, -1, label, submenu);
450 g_menu_clear_item (struct item *item)
452 if (item->attributes != NULL)
453 g_hash_table_unref (item->attributes);
454 if (item->links != NULL)
455 g_hash_table_unref (item->links);
461 * @position: the position of the item to remove
463 * Removes an item from the menu.
465 * @position gives the index of the item to remove.
467 * It is an error if position is not in range the range from 0 to one
468 * less than the number of items in the menu.
470 * It is not possible to remove items by identity since items are added
471 * to the menu simply by copying their links and attributes (ie:
472 * identity of the item itself is not preserved).
477 g_menu_remove (GMenu *menu,
480 g_return_if_fail (G_IS_MENU (menu));
481 g_return_if_fail (0 <= position && position < menu->items->len);
483 g_menu_clear_item (&g_array_index (menu->items, struct item, position));
484 g_array_remove_index (menu->items, position);
485 g_menu_model_items_changed (G_MENU_MODEL (menu), position, 1, 0);
489 g_menu_finalize (GObject *object)
491 GMenu *menu = G_MENU (object);
496 n_items = menu->items->len;
497 items = (struct item *) g_array_free (menu->items, FALSE);
498 for (i = 0; i < n_items; i++)
499 g_menu_clear_item (&items[i]);
502 G_OBJECT_CLASS (g_menu_parent_class)
507 g_menu_init (GMenu *menu)
509 menu->items = g_array_new (FALSE, FALSE, sizeof (struct item));
510 menu->mutable = TRUE;
514 g_menu_class_init (GMenuClass *class)
516 GMenuModelClass *model_class = G_MENU_MODEL_CLASS (class);
517 GObjectClass *object_class = G_OBJECT_CLASS (class);
519 object_class->finalize = g_menu_finalize;
521 model_class->is_mutable = g_menu_is_mutable;
522 model_class->get_n_items = g_menu_get_n_items;
523 model_class->get_item_attributes = g_menu_get_item_attributes;
524 model_class->get_item_links = g_menu_get_item_links;
529 g_menu_item_clear_cow (GMenuItem *menu_item)
538 new = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
539 g_hash_table_iter_init (&iter, menu_item->attributes);
540 while (g_hash_table_iter_next (&iter, &key, &val))
541 g_hash_table_insert (new, g_strdup (key), g_variant_ref (val));
542 g_hash_table_unref (menu_item->attributes);
543 menu_item->attributes = new;
545 new = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref);
546 g_hash_table_iter_init (&iter, menu_item->links);
547 while (g_hash_table_iter_next (&iter, &key, &val))
548 g_hash_table_insert (new, g_strdup (key), g_object_ref (val));
549 g_hash_table_unref (menu_item->links);
550 menu_item->links = new;
552 menu_item->cow = FALSE;
557 g_menu_item_finalize (GObject *object)
559 GMenuItem *menu_item = G_MENU_ITEM (object);
561 g_hash_table_unref (menu_item->attributes);
562 g_hash_table_unref (menu_item->links);
564 G_OBJECT_CLASS (g_menu_item_parent_class)
569 g_menu_item_init (GMenuItem *menu_item)
571 menu_item->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
572 menu_item->links = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
573 menu_item->cow = FALSE;
577 g_menu_item_class_init (GMenuItemClass *class)
579 class->finalize = g_menu_item_finalize;
582 /* We treat attribute names the same as GSettings keys:
583 * - only lowercase ascii, digits and '-'
584 * - must start with lowercase
585 * - must not end with '-'
586 * - no consecutive '-'
587 * - not longer than 1024 chars
590 valid_attribute_name (const gchar *name)
594 if (!g_ascii_islower (name[0]))
597 for (i = 1; name[i]; i++)
599 if (name[i] != '-' &&
600 !g_ascii_islower (name[i]) &&
601 !g_ascii_isdigit (name[i]))
604 if (name[i] == '-' && name[i + 1] == '-')
608 if (name[i - 1] == '-')
618 * g_menu_item_set_attribute_value:
619 * @menu_item: a #GMenuItem
620 * @attribute: the attribute to set
621 * @value: (allow-none): a #GVariant to use as the value, or %NULL
623 * Sets or unsets an attribute on @menu_item.
625 * The attribute to set or unset is specified by @attribute. This
626 * can be one of the standard attribute names %G_MENU_ATTRIBUTE_LABEL,
627 * %G_MENU_ATTRIBUTE_ACTION, %G_MENU_ATTRIBUTE_TARGET, or a custom
629 * Attribute names are restricted to lowercase characters, numbers
630 * and '-'. Furthermore, the names must begin with a lowercase character,
631 * must not end with a '-', and must not contain consecutive dashes.
633 * must consist only of lowercase
634 * ASCII characters, digits and '-'.
636 * If @value is non-%NULL then it is used as the new value for the
637 * attribute. If @value is %NULL then the attribute is unset. If
638 * the @value #GVariant is floating, it is consumed.
640 * See also g_menu_item_set_attribute() for a more convenient way to do
646 g_menu_item_set_attribute_value (GMenuItem *menu_item,
647 const gchar *attribute,
650 g_return_if_fail (G_IS_MENU_ITEM (menu_item));
651 g_return_if_fail (attribute != NULL);
652 g_return_if_fail (valid_attribute_name (attribute));
654 g_menu_item_clear_cow (menu_item);
657 g_hash_table_insert (menu_item->attributes, g_strdup (attribute), g_variant_ref_sink (value));
659 g_hash_table_remove (menu_item->attributes, attribute);
663 * g_menu_item_set_attribute:
664 * @menu_item: a #GMenuItem
665 * @attribute: the attribute to set
666 * @format_string: (allow-none): a #GVariant format string, or %NULL
667 * @...: positional parameters, as per @format_string
669 * Sets or unsets an attribute on @menu_item.
671 * The attribute to set or unset is specified by @attribute. This
672 * can be one of the standard attribute names %G_MENU_ATTRIBUTE_LABEL,
673 * %G_MENU_ATTRIBUTE_ACTION, %G_MENU_ATTRIBUTE_TARGET, or a custom
675 * Attribute names are restricted to lowercase characters, numbers
676 * and '-'. Furthermore, the names must begin with a lowercase character,
677 * must not end with a '-', and must not contain consecutive dashes.
679 * If @format_string is non-%NULL then the proper position parameters
680 * are collected to create a #GVariant instance to use as the attribute
681 * value. If it is %NULL then the positional parameterrs are ignored
682 * and the named attribute is unset.
684 * See also g_menu_item_set_attribute_value() for an equivalent call
685 * that directly accepts a #GVariant.
690 g_menu_item_set_attribute (GMenuItem *menu_item,
691 const gchar *attribute,
692 const gchar *format_string,
697 if (format_string != NULL)
701 va_start (ap, format_string);
702 value = g_variant_new_va (format_string, NULL, &ap);
708 g_menu_item_set_attribute_value (menu_item, attribute, value);
712 * g_menu_item_set_link:
713 * @menu_item: a #GMenuItem
714 * @link: type of link to establish or unset
715 * @model: (allow-none): the #GMenuModel to link to (or %NULL to unset)
717 * Creates a link from @menu_item to @model if non-%NULL, or unsets it.
719 * Links are used to establish a relationship between a particular menu
720 * item and another menu. For example, %G_MENU_LINK_SUBMENU is used to
721 * associate a submenu with a particular menu item, and %G_MENU_LINK_SECTION
722 * is used to create a section. Other types of link can be used, but there
723 * is no guarantee that clients will be able to make sense of them.
724 * Link types are restricted to lowercase characters, numbers
725 * and '-'. Furthermore, the names must begin with a lowercase character,
726 * must not end with a '-', and must not contain consecutive dashes.
731 g_menu_item_set_link (GMenuItem *menu_item,
735 g_return_if_fail (G_IS_MENU_ITEM (menu_item));
736 g_return_if_fail (link != NULL);
737 g_return_if_fail (valid_attribute_name (link));
739 g_menu_item_clear_cow (menu_item);
742 g_hash_table_insert (menu_item->links, g_strdup (link), g_object_ref (model));
744 g_hash_table_remove (menu_item->links, link);
748 * g_menu_item_get_attribute_value:
749 * @menu_item: a #GMenuItem
750 * @attribute: the attribute name to query
751 * @expected_type: (allow-none): the expected type of the attribute
753 * Queries the named @attribute on @menu_item.
755 * If @expected_type is specified and the attribute does not have this
756 * type, %NULL is returned. %NULL is also returned if the attribute
757 * simply does not exist.
759 * Returns: (transfer full): the attribute value, or %NULL
764 g_menu_item_get_attribute_value (GMenuItem *menu_item,
765 const gchar *attribute,
766 const GVariantType *expected_type)
770 g_return_val_if_fail (G_IS_MENU_ITEM (menu_item), NULL);
771 g_return_val_if_fail (attribute != NULL, NULL);
773 value = g_hash_table_lookup (menu_item->attributes, attribute);
777 if (expected_type == NULL || g_variant_is_of_type (value, expected_type))
778 g_variant_ref (value);
787 * g_menu_item_get_attribute:
788 * @menu_item: a #GMenuItem
789 * @attribute: the attribute name to query
790 * @format_string: a #GVariant format string
791 * @...: positional parameters, as per @format_string
793 * Queries the named @attribute on @menu_item.
795 * If the attribute exists and matches the #GVariantType corresponding
796 * to @format_string then @format_string is used to deconstruct the
797 * value into the positional parameters and %TRUE is returned.
799 * If the attribute does not exist, or it does exist but has the wrong
800 * type, then the positional parameters are ignored and %FALSE is
803 * Returns: %TRUE if the named attribute was found with the expected
809 g_menu_item_get_attribute (GMenuItem *menu_item,
810 const gchar *attribute,
811 const gchar *format_string,
817 g_return_val_if_fail (G_IS_MENU_ITEM (menu_item), FALSE);
818 g_return_val_if_fail (attribute != NULL, FALSE);
819 g_return_val_if_fail (format_string != NULL, FALSE);
821 value = g_hash_table_lookup (menu_item->attributes, attribute);
826 if (!g_variant_check_format_string (value, format_string, FALSE))
829 va_start (ap, format_string);
830 g_variant_get_va (value, format_string, NULL, &ap);
837 * g_menu_item_get_link:
838 * @menu_item: a #GMenuItem
839 * @link: the link name to query
841 * Queries the named @link on @menu_item.
843 * Returns: (transfer full): the link, or %NULL
848 g_menu_item_get_link (GMenuItem *menu_item,
853 g_return_val_if_fail (G_IS_MENU_ITEM (menu_item), NULL);
854 g_return_val_if_fail (link != NULL, NULL);
855 g_return_val_if_fail (valid_attribute_name (link), NULL);
857 model = g_hash_table_lookup (menu_item->links, link);
860 g_object_ref (model);
866 * g_menu_item_set_label:
867 * @menu_item: a #GMenuItem
868 * @label: (allow-none): the label to set, or %NULL to unset
870 * Sets or unsets the "label" attribute of @menu_item.
872 * If @label is non-%NULL it is used as the label for the menu item. If
873 * it is %NULL then the label attribute is unset.
878 g_menu_item_set_label (GMenuItem *menu_item,
884 value = g_variant_new_string (label);
888 g_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_LABEL, value);
892 * g_menu_item_set_submenu:
893 * @menu_item: a #GMenuItem
894 * @submenu: (allow-none): a #GMenuModel, or %NULL
896 * Sets or unsets the "submenu" link of @menu_item to @submenu.
898 * If @submenu is non-%NULL, it is linked to. If it is %NULL then the
901 * The effect of having one menu appear as a submenu of another is
902 * exactly as it sounds.
907 g_menu_item_set_submenu (GMenuItem *menu_item,
910 g_menu_item_set_link (menu_item, G_MENU_LINK_SUBMENU, submenu);
914 * g_menu_item_set_section:
915 * @menu_item: a #GMenuItem
916 * @section: (allow-none): a #GMenuModel, or %NULL
918 * Sets or unsets the "section" link of @menu_item to @section.
920 * The effect of having one menu appear as a section of another is
921 * exactly as it sounds: the items from @section become a direct part of
922 * the menu that @menu_item is added to. See g_menu_item_new_section()
923 * for more information about what it means for a menu item to be a
929 g_menu_item_set_section (GMenuItem *menu_item,
932 g_menu_item_set_link (menu_item, G_MENU_LINK_SECTION, section);
936 * g_menu_item_set_action_and_target_value:
937 * @menu_item: a #GMenuItem
938 * @action: (allow-none): the name of the action for this item
939 * @target_value: (allow-none): a #GVariant to use as the action target
941 * Sets or unsets the "action" and "target" attributes of @menu_item.
943 * If @action is %NULL then both the "action" and "target" attributes
944 * are unset (and @target_value is ignored).
946 * If @action is non-%NULL then the "action" attribute is set. The
947 * "target" attribute is then set to the value of @target_value if it is
948 * non-%NULL or unset otherwise.
950 * Normal menu items (ie: not submenu, section or other custom item
951 * types) are expected to have the "action" attribute set to identify
952 * the action that they are associated with. The state type of the
953 * action help to determine the disposition of the menu item. See
954 * #GAction and #GActionGroup for an overview of actions.
956 * In general, clicking on the menu item will result in activation of
957 * the named action with the "target" attribute given as the parameter
958 * to the action invocation. If the "target" attribute is not set then
959 * the action is invoked with no parameter.
961 * If the action has no state then the menu item is usually drawn as a
962 * plain menu item (ie: with no additional decoration).
964 * If the action has a boolean state then the menu item is usually drawn
965 * as a toggle menu item (ie: with a checkmark or equivalent
966 * indication). The item should be marked as 'toggled' or 'checked'
967 * when the boolean state is %TRUE.
969 * If the action has a string state then the menu item is usually drawn
970 * as a radio menu item (ie: with a radio bullet or equivalent
971 * indication). The item should be marked as 'selected' when the string
972 * state is equal to the value of the @target property.
974 * See g_menu_item_set_action_and_target() or
975 * g_menu_item_set_detailed_action() for two equivalent calls that are
976 * probably more convenient for most uses.
981 g_menu_item_set_action_and_target_value (GMenuItem *menu_item,
983 GVariant *target_value)
985 GVariant *action_value;
989 action_value = g_variant_new_string (action);
997 g_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_ACTION, action_value);
998 g_menu_item_set_attribute_value (menu_item, G_MENU_ATTRIBUTE_TARGET, target_value);
1002 * g_menu_item_set_action_and_target:
1003 * @menu_item: a #GMenuItem
1004 * @action: (allow-none): the name of the action for this item
1005 * @format_string: (allow-none): a GVariant format string
1006 * @...: positional parameters, as per @format_string
1008 * Sets or unsets the "action" and "target" attributes of @menu_item.
1010 * If @action is %NULL then both the "action" and "target" attributes
1011 * are unset (and @format_string is ignored along with the positional
1014 * If @action is non-%NULL then the "action" attribute is set.
1015 * @format_string is then inspected. If it is non-%NULL then the proper
1016 * position parameters are collected to create a #GVariant instance to
1017 * use as the target value. If it is %NULL then the positional
1018 * parameters are ignored and the "target" attribute is unset.
1020 * See also g_menu_item_set_action_and_target_value() for an equivalent
1021 * call that directly accepts a #GVariant. See
1022 * g_menu_item_set_detailed_action() for a more convenient version that
1023 * works with string-typed targets.
1025 * See also g_menu_item_set_action_and_target_value() for a
1026 * description of the semantics of the action and target attributes.
1031 g_menu_item_set_action_and_target (GMenuItem *menu_item,
1032 const gchar *action,
1033 const gchar *format_string,
1038 if (format_string != NULL)
1042 va_start (ap, format_string);
1043 value = g_variant_new_va (format_string, NULL, &ap);
1049 g_menu_item_set_action_and_target_value (menu_item, action, value);
1053 * g_menu_item_set_detailed_action:
1054 * @menu_item: a #GMenuItem
1055 * @detailed_action: the "detailed" action string
1057 * Sets the "action" and possibly the "target" attribute of @menu_item.
1059 * If @detailed_action contains a double colon ("::") then it is used as
1060 * a separator between an action name and a target string. In this
1061 * case, this call is equivalent to calling
1062 * g_menu_item_set_action_and_target() with the part before the "::" and
1063 * with a string-type #GVariant containing the part following the "::".
1065 * If @detailed_action doesn't contain "::" then the action is set to
1066 * the given string (verbatim) and the target value is unset.
1068 * See g_menu_item_set_action_and_target() or
1069 * g_menu_item_set_action_and_target_value() for more flexible (but
1070 * slightly less convenient) alternatives.
1072 * See also g_menu_item_set_action_and_target_value() for a description of
1073 * the semantics of the action and target attributes.
1078 g_menu_item_set_detailed_action (GMenuItem *menu_item,
1079 const gchar *detailed_action)
1083 sep = strstr (detailed_action, "::");
1089 action = g_strndup (detailed_action, sep - detailed_action);
1090 g_menu_item_set_action_and_target (menu_item, action, "s", sep + 2);
1095 g_menu_item_set_action_and_target_value (menu_item, detailed_action, NULL);
1100 * @label: (allow-none): the section label, or %NULL
1101 * @detailed_action: (allow-none): the detailed action string, or %NULL
1103 * Creates a new #GMenuItem.
1105 * If @label is non-%NULL it is used to set the "label" attribute of the
1108 * If @detailed_action is non-%NULL it is used to set the "action" and
1109 * possibly the "target" attribute of the new item. See
1110 * g_menu_item_set_detailed_action() for more information.
1112 * Returns: a new #GMenuItem
1117 g_menu_item_new (const gchar *label,
1118 const gchar *detailed_action)
1120 GMenuItem *menu_item;
1122 menu_item = g_object_new (G_TYPE_MENU_ITEM, NULL);
1125 g_menu_item_set_label (menu_item, label);
1127 if (detailed_action != NULL)
1128 g_menu_item_set_detailed_action (menu_item, detailed_action);
1134 * g_menu_item_new_submenu:
1135 * @label: (allow-none): the section label, or %NULL
1136 * @submenu: a #GMenuModel with the items of the submenu
1138 * Creates a new #GMenuItem representing a submenu.
1140 * This is a convenience API around g_menu_item_new() and
1141 * g_menu_item_set_submenu().
1143 * Returns: a new #GMenuItem
1148 g_menu_item_new_submenu (const gchar *label,
1149 GMenuModel *submenu)
1151 GMenuItem *menu_item;
1153 menu_item = g_object_new (G_TYPE_MENU_ITEM, NULL);
1156 g_menu_item_set_label (menu_item, label);
1158 g_menu_item_set_submenu (menu_item, submenu);
1164 * g_menu_item_new_section:
1165 * @label: (allow-none): the section label, or %NULL
1166 * @section: a #GMenuModel with the items of the section
1168 * Creates a new #GMenuItem representing a section.
1170 * This is a convenience API around g_menu_item_new() and
1171 * g_menu_item_set_section().
1173 * The effect of having one menu appear as a section of another is
1174 * exactly as it sounds: the items from @section become a direct part of
1175 * the menu that @menu_item is added to.
1177 * Visual separation is typically displayed between two non-empty
1178 * sections. If @label is non-%NULL then it will be encorporated into
1179 * this visual indication. This allows for labeled subsections of a
1182 * As a simple example, consider a typical "Edit" menu from a simple
1183 * program. It probably contains an "Undo" and "Redo" item, followed by
1184 * a separator, followed by "Cut", "Copy" and "Paste".
1186 * This would be accomplished by creating three #GMenu instances. The
1187 * first would be populated with the "Undo" and "Redo" items, and the
1188 * second with the "Cut", "Copy" and "Paste" items. The first and
1189 * second menus would then be added as submenus of the third. In XML
1190 * format, this would look something like the following:
1192 * <informalexample><programlisting><![CDATA[
1193 * <menu id='edit-menu'>
1195 * <item label='Undo'/>
1196 * <item label='Redo'/>
1199 * <item label='Cut'/>
1200 * <item label='Copy'/>
1201 * <item label='Paste'/>
1204 * ]]></programlisting></informalexample>
1206 * The following example is exactly equivalent. It is more illustrative
1207 * of the exact relationship between the menus and items (keeping in
1208 * mind that the 'link' element defines a new menu that is linked to the
1209 * containing one). The style of the second example is more verbose and
1210 * difficult to read (and therefore not recommended except for the
1211 * purpose of understanding what is really going on).
1213 * <informalexample><programlisting><![CDATA[
1214 * <menu id='edit-menu'>
1216 * <link name='section'>
1217 * <item label='Undo'/>
1218 * <item label='Redo'/>
1222 * <link name='section'>
1223 * <item label='Cut'/>
1224 * <item label='Copy'/>
1225 * <item label='Paste'/>
1229 * ]]></programlisting></informalexample>
1231 * Returns: a new #GMenuItem
1236 g_menu_item_new_section (const gchar *label,
1237 GMenuModel *section)
1239 GMenuItem *menu_item;
1241 menu_item = g_object_new (G_TYPE_MENU_ITEM, NULL);
1244 g_menu_item_set_label (menu_item, label);
1246 g_menu_item_set_section (menu_item, section);