diff options
author | Alexander Larsson <alexl@redhat.com> | 2009-06-25 19:39:54 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2009-06-25 21:00:38 +0200 |
commit | b548be8088f83b8cdeb66198e6092edfa518613d (patch) | |
tree | 3cf60da1073aa50915b084702d95c4c79ab214b4 /client/gdaemonfileenumerator.c | |
parent | 2eb9e35ccf5112a6f01225c97b05e90eca8c7ea9 (diff) |
Implement metadata setting for remote locations
Diffstat (limited to 'client/gdaemonfileenumerator.c')
-rw-r--r-- | client/gdaemonfileenumerator.c | 78 |
1 files changed, 74 insertions, 4 deletions
diff --git a/client/gdaemonfileenumerator.c b/client/gdaemonfileenumerator.c index b650eafb..7d5053af 100644 --- a/client/gdaemonfileenumerator.c +++ b/client/gdaemonfileenumerator.c @@ -30,6 +30,8 @@ #include <gio/gio.h> #include <gvfsdaemondbus.h> #include <gvfsdaemonprotocol.h> +#include "gdaemonfile.h" +#include "metatree.h" #define OBJ_PATH_PREFIX "/org/gtk/vfs/client/enumerator/" @@ -55,6 +57,9 @@ struct _GDaemonFileEnumerator gulong cancelled_tag; guint timeout_tag; GSimpleAsyncResult *async_res; + + GFileAttributeMatcher *matcher; + MetaTree *metadata_tree; }; G_DEFINE_TYPE (GDaemonFileEnumerator, g_daemon_file_enumerator, G_TYPE_FILE_ENUMERATOR) @@ -107,6 +112,10 @@ g_daemon_file_enumerator_finalize (GObject *object) free_info_list (daemon->infos); + g_file_attribute_matcher_unref (daemon->matcher); + if (daemon->metadata_tree) + meta_tree_unref (daemon->metadata_tree); + if (daemon->sync_connection) dbus_connection_unref (daemon->sync_connection); @@ -145,17 +154,73 @@ g_daemon_file_enumerator_init (GDaemonFileEnumerator *daemon) } GDaemonFileEnumerator * -g_daemon_file_enumerator_new (GFile *file) +g_daemon_file_enumerator_new (GFile *file, + const char *attributes) { GDaemonFileEnumerator *daemon; + char *treename; daemon = g_object_new (G_TYPE_DAEMON_FILE_ENUMERATOR, "container", file, NULL); - + + daemon->matcher = g_file_attribute_matcher_new (attributes); + if (g_file_attribute_matcher_enumerate_namespace (daemon->matcher, "metadata") || + g_file_attribute_matcher_enumerate_next (daemon->matcher) != NULL) + { + treename = g_mount_spec_to_string (G_DAEMON_FILE (file)->mount_spec); + daemon->metadata_tree = meta_tree_lookup_by_name (treename, FALSE); + g_free (treename); + } + return daemon; } +static gboolean +enumerate_keys_callback (const char *key, + MetaKeyType type, + gpointer value, + gpointer user_data) +{ + GFileInfo *info = user_data; + char *attr; + + attr = g_strconcat ("metadata::", key, NULL); + + if (type == META_KEY_TYPE_STRING) + g_file_info_set_attribute_string (info, attr, (char *)value); + else + g_file_info_set_attribute_stringv (info, attr, (char **)value); + + g_free (attr); + + return TRUE; +} + +static void +add_metadata (GFileInfo *info, + GDaemonFileEnumerator *daemon) +{ + GFile *container; + const char *name; + char *path; + + if (!daemon->metadata_tree) + return; + + name = g_file_info_get_name (info); + container = g_file_enumerator_get_container (G_FILE_ENUMERATOR (daemon)); + path = g_build_filename (G_DAEMON_FILE (container)->path, name, NULL); + + g_file_info_set_attribute_mask (info, daemon->matcher); + meta_tree_enumerate_keys (daemon->metadata_tree, path, + enumerate_keys_callback, info); + g_file_info_unset_attribute_mask (info); + + g_free (path); +} + + /* Called with infos lock held */ static void trigger_async_done (GDaemonFileEnumerator *daemon, gboolean ok) @@ -187,7 +252,9 @@ trigger_async_done (GDaemonFileEnumerator *daemon, gboolean ok) rest->prev = NULL; } daemon->infos = rest; - + + g_list_foreach (l, add_metadata, daemon); + g_simple_async_result_set_op_res_gpointer (daemon->async_res, l, (GDestroyNotify)free_info_list); @@ -301,7 +368,10 @@ g_daemon_file_enumerator_next_file (GFileEnumerator *enumerator, done = TRUE; info = daemon->infos->data; if (info) - g_assert (G_IS_FILE_INFO (info)); + { + g_assert (G_IS_FILE_INFO (info)); + add_metadata (G_FILE_INFO (info), daemon); + } daemon->infos = g_list_delete_link (daemon->infos, daemon->infos); } else if (daemon->done) |