[gnome-menus/wip/gobject-rebase2: 8/13] Add explicit gmenu_tree_load_sync()
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-menus/wip/gobject-rebase2: 8/13] Add explicit gmenu_tree_load_sync()
- Date: Mon, 18 Apr 2011 18:37:25 +0000 (UTC)
commit 00702aaa8c8a7f207780426028b223307d9523d3
Author: Colin Walters <walters verbum org>
Date: Sun Apr 17 09:31:34 2011 -0400
Add explicit gmenu_tree_load_sync()
Rather than having _get_root_directory() be lazy, require users
to explicitly load via this function (or in the future, an
async variant).
https://bugzilla.gnome.org/show_bug.cgi?id=647968
libmenu/gmenu-tree.c | 74 ++++++++++++++++++++++++++++++++++++++++--------
libmenu/gmenu-tree.h | 3 ++
util/test-menu-spec.c | 16 ++++++++++
3 files changed, 80 insertions(+), 13 deletions(-)
---
diff --git a/libmenu/gmenu-tree.c b/libmenu/gmenu-tree.c
index fa70eb0..c738796 100644
--- a/libmenu/gmenu-tree.c
+++ b/libmenu/gmenu-tree.c
@@ -59,7 +59,10 @@ struct _GMenuTree
MenuLayoutNode *layout;
GMenuTreeDirectory *root;
+ GError *load_error;
+
guint canonical : 1;
+ guint loaded : 1;
};
G_DEFINE_TYPE (GMenuTree, gmenu_tree, G_TYPE_OBJECT)
@@ -138,7 +141,7 @@ struct GMenuTreeAlias
static void gmenu_tree_load_layout (GMenuTree *tree);
static void gmenu_tree_force_reload (GMenuTree *tree);
-static void gmenu_tree_build_from_layout (GMenuTree *tree);
+static gboolean gmenu_tree_build_from_layout (GMenuTree *tree, GError **error);
static void gmenu_tree_force_rebuild (GMenuTree *tree);
static void gmenu_tree_resolve_files (GMenuTree *tree,
GHashTable *loaded_menu_files,
@@ -489,6 +492,8 @@ gmenu_tree_finalize (GObject *object)
g_free (tree->canonical_path);
tree->canonical_path = NULL;
+ g_clear_error (&(tree->load_error));
+
G_OBJECT_CLASS (gmenu_tree_parent_class)->finalize (object);
}
@@ -572,18 +577,50 @@ gmenu_tree_get_menu_file (GMenuTree *tree)
return ugly_result_cache;
}
-GMenuTreeDirectory *
-gmenu_tree_get_root_directory (GMenuTree *tree)
+/**
+ * gmenu_tree_load_sync:
+ * @tree: a #GMenuTree
+ * @error: a #GError
+ *
+ * Synchronously load the menu contents. This function
+ * performs a significant amount of blocking I/O if the
+ * tree has not been loaded yet.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ */
+gboolean
+gmenu_tree_load_sync (GMenuTree *tree,
+ GError **error)
{
- g_return_val_if_fail (tree != NULL, NULL);
-
- if (!tree->root)
+ if (!tree->loaded)
{
- gmenu_tree_build_from_layout (tree);
+ g_clear_error (&tree->load_error);
+ gmenu_tree_build_from_layout (tree, &tree->load_error);
+ tree->loaded = TRUE;
+ }
- if (!tree->root)
- return NULL;
+ if (tree->load_error)
+ {
+ g_propagate_error (error, tree->load_error);
+ return FALSE;
}
+ return TRUE;
+}
+
+/**
+ * gmenu_tree_get_root_directory:
+ * @tree: a #GMenuTree
+ *
+ * Get the root directory; you must have loaded the tree first (at
+ * least once) via gmenu_tree_load_sync() or a variant thereof.
+ *
+ * Returns: (transfer full): Root of the tree
+ */
+GMenuTreeDirectory *
+gmenu_tree_get_root_directory (GMenuTree *tree)
+{
+ g_return_val_if_fail (tree != NULL, NULL);
+ g_return_val_if_fail (tree->loaded, NULL);
return gmenu_tree_item_ref (tree->root);
}
@@ -4085,17 +4122,24 @@ handle_entries_changed (MenuLayoutNode *layout,
}
}
-static void
-gmenu_tree_build_from_layout (GMenuTree *tree)
+static gboolean
+gmenu_tree_build_from_layout (GMenuTree *tree,
+ GError **error)
{
DesktopEntrySet *allocated;
if (tree->root)
- return;
+ return TRUE;
gmenu_tree_load_layout (tree);
if (!tree->layout)
- return;
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Failed to load layout");
+ return FALSE;
+ }
menu_verbose ("Building menu tree from layout\n");
@@ -4125,6 +4169,8 @@ gmenu_tree_build_from_layout (GMenuTree *tree)
}
desktop_entry_set_unref (allocated);
+
+ return TRUE;
}
static void
@@ -4135,6 +4181,8 @@ gmenu_tree_force_rebuild (GMenuTree *tree)
gmenu_tree_directory_set_tree (tree->root, NULL);
gmenu_tree_item_unref (tree->root);
tree->root = NULL;
+ g_clear_error (&tree->load_error);
+ tree->loaded = FALSE;
g_assert (tree->layout != NULL);
diff --git a/libmenu/gmenu-tree.h b/libmenu/gmenu-tree.h
index 4cbf61a..19e4784 100644
--- a/libmenu/gmenu-tree.h
+++ b/libmenu/gmenu-tree.h
@@ -91,6 +91,9 @@ GType gmenu_tree_flags_get_type (void);
GMenuTree *gmenu_tree_new (const char *menu_file,
GMenuTreeFlags flags);
+gboolean gmenu_tree_load_sync (GMenuTree *tree,
+ GError **error);
+
const char *gmenu_tree_get_menu_file (GMenuTree *tree);
GMenuTreeDirectory *gmenu_tree_get_root_directory (GMenuTree *tree);
GMenuTreeDirectory *gmenu_tree_get_directory_from_path (GMenuTree *tree,
diff --git a/util/test-menu-spec.c b/util/test-menu-spec.c
index d21f78d..9748a13 100644
--- a/util/test-menu-spec.c
+++ b/util/test-menu-spec.c
@@ -22,6 +22,7 @@
#include "gmenu-tree.h"
#include <string.h>
+#include <stdlib.h>
/* This is only a test program, so we don't need translations. Still keep the
* infrastructure in place in case we suddenly decide we want to localize this
@@ -166,9 +167,17 @@ static void
handle_tree_changed (GMenuTree *tree)
{
GMenuTreeDirectory *root;
+ GError *error = NULL;
g_print (_("\n\n\n==== Menu changed, reloading ====\n\n\n"));
+ if (!gmenu_tree_load_sync (tree, &error))
+ {
+ g_printerr ("Failed to load tree: %s\n", error->message);
+ g_clear_error (&error);
+ return;
+ }
+
root = gmenu_tree_get_root_directory (tree);
if (root == NULL)
{
@@ -187,6 +196,7 @@ main (int argc, char **argv)
GMenuTree *tree;
GMenuTreeDirectory *root;
GMenuTreeFlags flags;
+ GError *error = NULL;
g_type_init ();
@@ -211,6 +221,12 @@ main (int argc, char **argv)
tree = gmenu_tree_new (menu_file ? menu_file : "applications.menu", flags);
g_assert (tree != NULL);
+ if (!gmenu_tree_load_sync (tree, &error))
+ {
+ g_printerr ("Failed to load tree: %s\n", error->message);
+ exit (1);
+ }
+
root = gmenu_tree_get_root_directory (tree);
if (root != NULL)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]