summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2012-08-18 14:24:46 -0400
committerRyan Lortie <desrt@desrt.ca>2012-08-18 17:38:30 -0400
commit91f4daca92819122fc5439f6759ccc1766afbe6c (patch)
tree0277c08d5589577ed815da433fc95cb2fb8f76b2
parentaa5f1232d9881c23f3fd5554b5114fc9557f22f0 (diff)
downloadglib-wip/menuitem-api.tar.gz
GMenuItem: add constructor to copy from modelwip/menuitem-api
Add g_menu_item_new_from_model() for constructing a GMenuItem that is a copy of a menu item that's in a GMenuModel.
-rw-r--r--docs/reference/gio/gio-sections.txt1
-rw-r--r--gio/gio.symbols1
-rw-r--r--gio/gmenu.c87
-rw-r--r--gio/gmenu.h4
4 files changed, 93 insertions, 0 deletions
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index afae7895d..0fc8576d1 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -3744,6 +3744,7 @@ GMenuItem
g_menu_item_new
g_menu_item_new_section
g_menu_item_new_submenu
+g_menu_item_new_from_model
<SUBSECTION>
g_menu_item_set_label
diff --git a/gio/gio.symbols b/gio/gio.symbols
index f9d4d42f9..05b6bfc03 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -1686,6 +1686,7 @@ g_menu_item_get_attribute_value
g_menu_item_get_link
g_menu_item_get_type
g_menu_item_new
+g_menu_item_new_from_model
g_menu_item_new_section
g_menu_item_new_submenu
g_menu_item_set_action_and_target
diff --git a/gio/gmenu.c b/gio/gmenu.c
index 5c0e8362d..d0b41303e 100644
--- a/gio/gmenu.c
+++ b/gio/gmenu.c
@@ -1247,3 +1247,90 @@ g_menu_item_new_section (const gchar *label,
return menu_item;
}
+
+/**
+ * g_menu_item_new_from_model:
+ * @model: a #GMenuModel
+ * @item_index: the index of an item in @model
+ *
+ * Creates a #GMenuItem as an exact copy of an existing menu item in a
+ * #GMenuModel.
+ *
+ * @item_index must be valid (ie: be sure to call
+ * g_menu_model_get_n_items() first).
+ *
+ * Returns: a new #GMenuItem.
+ *
+ * Since: 2.34
+ */
+GMenuItem *
+g_menu_item_new_from_model (GMenuModel *model,
+ gint item_index)
+{
+ GMenuModelClass *class = G_MENU_MODEL_GET_CLASS (model);
+ GMenuItem *menu_item;
+
+ menu_item = g_object_new (G_TYPE_MENU_ITEM, NULL);
+
+ /* With some trickery we can be pretty efficient.
+ *
+ * A GMenuModel must either implement iterate_item_attributes() or
+ * get_item_attributes(). If it implements get_item_attributes() then
+ * we are in luck -- we can just take a reference on the returned
+ * hashtable and mark ourselves as copy-on-write.
+ *
+ * In the case that the model is based on get_item_attributes (which
+ * is the case for both GMenu and GDBusMenuModel) then this is
+ * basically just g_hash_table_ref().
+ */
+ if (class->get_item_attributes)
+ {
+ GHashTable *attributes = NULL;
+
+ class->get_item_attributes (model, item_index, &attributes);
+ if (attributes)
+ {
+ g_hash_table_unref (menu_item->attributes);
+ menu_item->attributes = attributes;
+ menu_item->cow = TRUE;
+ }
+ }
+ else
+ {
+ GMenuAttributeIter *iter;
+ const gchar *attribute;
+ GVariant *value;
+
+ iter = g_menu_model_iterate_item_attributes (model, item_index);
+ while (g_menu_attribute_iter_get_next (iter, &attribute, &value))
+ g_hash_table_insert (menu_item->attributes, g_strdup (attribute), value);
+ g_object_unref (iter);
+ }
+
+ /* Same story for the links... */
+ if (class->get_item_links)
+ {
+ GHashTable *links = NULL;
+
+ class->get_item_links (model, item_index, &links);
+ if (links)
+ {
+ g_hash_table_unref (menu_item->links);
+ menu_item->links = links;
+ menu_item->cow = TRUE;
+ }
+ }
+ else
+ {
+ GMenuLinkIter *iter;
+ const gchar *link;
+ GMenuModel *value;
+
+ iter = g_menu_model_iterate_item_links (model, item_index);
+ while (g_menu_link_iter_get_next (iter, &link, &value))
+ g_hash_table_insert (menu_item->links, g_strdup (link), value);
+ g_object_unref (iter);
+ }
+
+ return menu_item;
+}
diff --git a/gio/gmenu.h b/gio/gmenu.h
index 472118f70..4159eb20a 100644
--- a/gio/gmenu.h
+++ b/gio/gmenu.h
@@ -96,6 +96,10 @@ GType g_menu_item_get_type (void) G_GNUC_CONST;
GMenuItem * g_menu_item_new (const gchar *label,
const gchar *detailed_action);
+GLIB_AVAILABLE_IN_2_34
+GMenuItem * g_menu_item_new_from_model (GMenuModel *model,
+ gint item_index);
+
GMenuItem * g_menu_item_new_submenu (const gchar *label,
GMenuModel *submenu);