aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-glib
diff options
context:
space:
mode:
authorTed Gould <ted@canonical.com>2009-04-27 17:13:34 -0500
committerTed Gould <ted@canonical.com>2009-04-27 17:13:34 -0500
commit16e308694476a616ecea6a9e44b0713906832785 (patch)
tree97f029b6ced2d84d5d96bdcc06868b18dcd9e164 /libdbusmenu-glib
parenta641c011fd1a697b08b26284a4ed5ec02e0bd13d (diff)
downloadlibdbusmenu-16e308694476a616ecea6a9e44b0713906832785.tar.gz
libdbusmenu-16e308694476a616ecea6a9e44b0713906832785.tar.bz2
libdbusmenu-16e308694476a616ecea6a9e44b0713906832785.zip
Okay, it think we're syncing the two XML hierarchies. Whew.
Diffstat (limited to 'libdbusmenu-glib')
-rw-r--r--libdbusmenu-glib/client.c52
-rw-r--r--libdbusmenu-glib/menuitem.h2
2 files changed, 51 insertions, 3 deletions
diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c
index f0eb408..d49b8db 100644
--- a/libdbusmenu-glib/client.c
+++ b/libdbusmenu-glib/client.c
@@ -216,13 +216,58 @@ build_proxies (DbusmenuClient * client)
return;
}
+/* Get the ID attribute of the node, parse it and
+ return it. Also we're checking to ensure the node
+ is a 'menu' here. */
+static guint
+parse_node_get_id (xmlNodePtr node)
+{
+ if (g_strcmp0((gchar *)node->name, "menu") != 0) {
+ /* This kills some nodes early */
+ return 0;
+ }
+
+ xmlAttrPtr attrib;
+ for (attrib = node->properties; node != NULL; node = node->next) {
+ if (g_strcmp0((gchar *)node->name, "id") == 0) {
+ if (node->children != NULL) {
+ return (guint)g_ascii_strtoull((gchar *)attrib->children->content, NULL, 10);
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+
/* Parse recursively through the XML and make it into
objects as need be */
-static gboolean
+static DbusmenuMenuitem *
parse_layout_xml(xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent)
{
+ guint id = parse_node_get_id(node);
+ if (item == NULL || dbusmenu_menuitem_get_id(item) != id) {
+ if (item != NULL) {
+ if (parent != NULL) {
+ dbusmenu_menuitem_child_delete(parent, item);
+ }
+ g_object_unref(G_OBJECT(item));
+ }
+
+ /* Build a new item */
+ item = dbusmenu_menuitem_new_with_id(id);
+ }
+
+ xmlNodePtr children;
+ guint position;
+ for (children = node->children, position = 0; children != NULL; children = children->next, position++) {
+ guint childid = parse_node_get_id(children);
+ DbusmenuMenuitem * childmi = dbusmenu_menuitem_child_find(item, childid);
+ childmi = parse_layout_xml(children, childmi, item);
+ dbusmenu_menuitem_child_add_position(item, childmi, position);
+ }
- return FALSE;
+ return item;
}
/* Take the layout passed to us over DBus and turn it into
@@ -238,7 +283,8 @@ parse_layout (DbusmenuClient * client, const gchar * layout)
xmlNodePtr root = xmlDocGetRootElement(xmldoc);
- if (!parse_layout_xml(root, priv->root, NULL)) {
+ priv->root = parse_layout_xml(root, priv->root, NULL);
+ if (priv->root == NULL) {
g_warning("Unable to parse layout on client %s object %s", priv->dbus_name, priv->dbus_object);
}
diff --git a/libdbusmenu-glib/menuitem.h b/libdbusmenu-glib/menuitem.h
index daeee50..c4057dd 100644
--- a/libdbusmenu-glib/menuitem.h
+++ b/libdbusmenu-glib/menuitem.h
@@ -44,6 +44,7 @@ struct _DbusmenuMenuitem
GType dbusmenu_menuitem_get_type (void);
DbusmenuMenuitem * dbusmenu_menuitem_new (void);
+DbusmenuMenuitem * dbusmenu_menuitem_new_with_id (guint id);
guint dbusmenu_menuitem_get_id (DbusmenuMenuitem * mi);
GList * dbusmenu_menuitem_get_children (DbusmenuMenuitem * mi);
@@ -52,6 +53,7 @@ guint dbusmenu_menuitem_get_position (DbusmenuMenuitem * mi, DbusmenuMenuitem *
gboolean dbusmenu_menuitem_child_append (DbusmenuMenuitem * mi, DbusmenuMenuitem * child);
gboolean dbusmenu_menuitem_child_delete (DbusmenuMenuitem * mi, DbusmenuMenuitem * child);
gboolean dbusmenu_menuitem_child_add_position (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position);
+DbusmenuMenuitem * dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, guint id);
gboolean dbusmenu_menuitem_property_set (DbusmenuMenuitem * mi, const gchar * property, const gchar * value);
const gchar * dbusmenu_menuitem_property_get (DbusmenuMenuitem * mi, const gchar * property);