[glib/wip/menuitem-api: 4/4] GMenuItem: add constructor to copy from model



commit 91f4daca92819122fc5439f6759ccc1766afbe6c
Author: Ryan Lortie <desrt desrt ca>
Date:   Sat Aug 18 14:24:46 2012 -0400

    GMenuItem: add constructor to copy from model
    
    Add g_menu_item_new_from_model() for constructing a GMenuItem that is a
    copy of a menu item that's in a GMenuModel.

 docs/reference/gio/gio-sections.txt |    1 +
 gio/gio.symbols                     |    1 +
 gio/gmenu.c                         |   87 +++++++++++++++++++++++++++++++++++
 gio/gmenu.h                         |    4 ++
 4 files changed, 93 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index afae789..0fc8576 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 f9d4d42..05b6bfc 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 5c0e836..d0b4130 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 472118f..4159eb2 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);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]