summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarin Adler <darin@src.gnome.org>2000-05-16 22:36:34 +0000
committerDarin Adler <darin@src.gnome.org>2000-05-16 22:36:34 +0000
commitf135aeadde705baebbe5313e3129aac070583df0 (patch)
tree5c1304b91657654c2bc6fef27fcd47c22e5f398b
parent1b44ea3bb0a8d6aea8df07895854a149d5ecf89d (diff)
downloadnautilus-f135aeadde705baebbe5313e3129aac070583df0.tar.gz
Factored out code that's common to failure and success and made it call
* libnautilus-extensions/nautilus-directory-async.c: (metafile_read_done), (metafile_read_failed), (metafile_read_complete): Factored out code that's common to failure and success and made it call the new nautilus_directory_metafile_apply_pending_changes function to take care of changes made while reading the metafile. * libnautilus-extensions/nautilus-directory-metafile.h: * libnautilus-extensions/nautilus-directory-metafile.c: (get_metadata_list_from_node), (get_file_node), (get_metadata_string_from_metafile), (get_metadata_list_from_metafile), (set_metadata_string_in_metafile), (set_metadata_list_in_metafile), (set_metadata_in_metafile), (get_metadata_string_from_table), (get_metadata_list_from_table), (str_or_null_hash), (str_or_null_equal), (set_metadata_eat_value), (free_file_table_entry), (free_directory_table_entry), (destroy_metadata_changes_hash_table), (nautilus_directory_get_metadata), (nautilus_directory_get_file_metadata), (nautilus_directory_get_metadata_list), (nautilus_directory_get_file_metadata_list), (nautilus_directory_set_metadata), (nautilus_directory_set_file_metadata), (nautilus_directory_set_file_metadata_list), (nautilus_directory_update_file_metadata), (apply_one_change), (apply_file_changes), (nautilus_directory_metafile_apply_pending_changes), (nautilus_directory_get_boolean_metadata), (nautilus_directory_set_boolean_metadata), (nautilus_directory_get_integer_metadata), (nautilus_directory_set_integer_metadata): Redid everything to use two hash tables to hold metadata before the metafile is read in. * libnautilus-extensions/nautilus-directory-private.h: Made the "NAME" XML tag be private again. It's now only used inside the nautilus-directory-metafile.c code. * libnautilus-extensions/nautilus-file.c: (rename_update_info_and_metafile): Moved the code for this inside the nautilus-directory-metafile.c code. * libnautilus-extensions/nautilus-glib-extensions.c: (nautilus_g_ptr_array_sort): Took out a FIXME comment now that my question about the code is answered. We can't use qsort because it does not take a context pointer. * libnautilus-extensions/nautilus-string.h: Formatting.
-rw-r--r--ChangeLog52
-rw-r--r--libnautilus-extensions/nautilus-directory-async.c46
-rw-r--r--libnautilus-extensions/nautilus-directory-metafile.c831
-rw-r--r--libnautilus-extensions/nautilus-directory-metafile.h48
-rw-r--r--libnautilus-extensions/nautilus-directory-private.h2
-rw-r--r--libnautilus-extensions/nautilus-file.c14
-rw-r--r--libnautilus-extensions/nautilus-glib-extensions.c2
-rw-r--r--libnautilus-extensions/nautilus-string.h50
-rw-r--r--libnautilus-private/nautilus-directory-async.c46
-rw-r--r--libnautilus-private/nautilus-directory-metafile.c831
-rw-r--r--libnautilus-private/nautilus-directory-metafile.h48
-rw-r--r--libnautilus-private/nautilus-directory-private.h2
-rw-r--r--libnautilus-private/nautilus-file.c14
-rw-r--r--libnautilus-private/nautilus-glib-extensions.c2
-rw-r--r--libnautilus-private/nautilus-string.h50
15 files changed, 1200 insertions, 838 deletions
diff --git a/ChangeLog b/ChangeLog
index 62094c6ff..8f044d76a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,55 @@
+2000-05-16 Darin Adler <darin@eazel.com>
+
+ * libnautilus-extensions/nautilus-directory-async.c:
+ (metafile_read_done), (metafile_read_failed),
+ (metafile_read_complete): Factored out code that's common to failure
+ and success and made it call the new
+ nautilus_directory_metafile_apply_pending_changes function to take
+ care of changes made while reading the metafile.
+
+ * libnautilus-extensions/nautilus-directory-metafile.h:
+ * libnautilus-extensions/nautilus-directory-metafile.c:
+ (get_metadata_list_from_node), (get_file_node),
+ (get_metadata_string_from_metafile),
+ (get_metadata_list_from_metafile),
+ (set_metadata_string_in_metafile), (set_metadata_list_in_metafile),
+ (set_metadata_in_metafile), (get_metadata_string_from_table),
+ (get_metadata_list_from_table), (str_or_null_hash),
+ (str_or_null_equal), (set_metadata_eat_value),
+ (free_file_table_entry), (free_directory_table_entry),
+ (destroy_metadata_changes_hash_table),
+ (nautilus_directory_get_metadata),
+ (nautilus_directory_get_file_metadata),
+ (nautilus_directory_get_metadata_list),
+ (nautilus_directory_get_file_metadata_list),
+ (nautilus_directory_set_metadata),
+ (nautilus_directory_set_file_metadata),
+ (nautilus_directory_set_file_metadata_list),
+ (nautilus_directory_update_file_metadata), (apply_one_change),
+ (apply_file_changes),
+ (nautilus_directory_metafile_apply_pending_changes),
+ (nautilus_directory_get_boolean_metadata),
+ (nautilus_directory_set_boolean_metadata),
+ (nautilus_directory_get_integer_metadata),
+ (nautilus_directory_set_integer_metadata):
+ Redid everything to use two hash tables to hold metadata before the
+ metafile is read in.
+
+ * libnautilus-extensions/nautilus-directory-private.h:
+ Made the "NAME" XML tag be private again. It's now only used inside
+ the nautilus-directory-metafile.c code.
+
+ * libnautilus-extensions/nautilus-file.c:
+ (rename_update_info_and_metafile): Moved the code for this inside the
+ nautilus-directory-metafile.c code.
+
+ * libnautilus-extensions/nautilus-glib-extensions.c:
+ (nautilus_g_ptr_array_sort): Took out a FIXME comment now that my
+ question about the code is answered. We can't use qsort because it
+ does not take a context pointer.
+
+ * libnautilus-extensions/nautilus-string.h: Formatting.
+
2000-05-16 Eskil Heyn Olsen <eskil@eazel.om>
* components/services/trilobite/src/trilobite-service-public.h:
diff --git a/libnautilus-extensions/nautilus-directory-async.c b/libnautilus-extensions/nautilus-directory-async.c
index 9775b5259..0888bd071 100644
--- a/libnautilus-extensions/nautilus-directory-async.c
+++ b/libnautilus-extensions/nautilus-directory-async.c
@@ -25,6 +25,7 @@
#include <config.h>
#include "nautilus-directory-private.h"
+#include "nautilus-directory-metafile.h"
#include "nautilus-file-private.h"
#include "nautilus-file-attributes.h"
@@ -140,8 +141,26 @@ nautilus_metafile_read_cancel (NautilusDirectory *directory)
}
static void
+metafile_read_done (NautilusDirectory *directory)
+{
+ g_free (directory->details->metafile_read_state);
+
+ directory->details->metafile_read = TRUE;
+ directory->details->metafile_read_state = NULL;
+
+ /* Move over the changes to the metafile that were in the hash table. */
+ nautilus_directory_metafile_apply_pending_changes (directory);
+
+ /* Let the callers that were waiting for the metafile know. */
+ state_changed (directory);
+}
+
+static void
metafile_read_failed (NautilusDirectory *directory)
{
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
+ g_assert (directory->details->metafile == NULL);
+
g_free (directory->details->metafile_read_state->buffer);
if (directory->details->use_alternate_metafile) {
@@ -153,13 +172,7 @@ metafile_read_failed (NautilusDirectory *directory)
return;
}
- g_free (directory->details->metafile_read_state);
-
- directory->details->metafile_read = TRUE;
- directory->details->metafile_read_state = NULL;
-
- /* Let the callers that were waiting for the metafile know. */
- state_changed (directory);
+ metafile_read_done (directory);
}
static void
@@ -169,16 +182,7 @@ metafile_read_complete (NautilusDirectory *directory)
int size;
g_assert (NAUTILUS_IS_DIRECTORY (directory));
-
- /* FIXME bugzilla.eazel.com 720:
- * The following assertion shouldn't be disabled, but
- * it gets in the way when you set metadata before the
- * metafile is completely read. Currently, the old metadata
- * in the file will be lost. One way to test this is to
- * remove the metafile from your home directory and the
- * ~/Nautilus directory and then start the program.
- */
- /* g_assert (directory->details->metafile == NULL); */
+ g_assert (directory->details->metafile == NULL);
/* The gnome-xml parser requires a zero-terminated array. */
size = directory->details->metafile_read_state->bytes_read;
@@ -187,13 +191,7 @@ metafile_read_complete (NautilusDirectory *directory)
directory->details->metafile = xmlParseMemory (buffer, size);
g_free (buffer);
- g_free (directory->details->metafile_read_state);
-
- directory->details->metafile_read = TRUE;
- directory->details->metafile_read_state = NULL;
-
- /* Let the callers that were waiting for the metafile know. */
- state_changed (directory);
+ metafile_read_done (directory);
}
static void
diff --git a/libnautilus-extensions/nautilus-directory-metafile.c b/libnautilus-extensions/nautilus-directory-metafile.c
index 09ef0a81c..3f441a36c 100644
--- a/libnautilus-extensions/nautilus-directory-metafile.c
+++ b/libnautilus-extensions/nautilus-directory-metafile.c
@@ -35,12 +35,6 @@
#define METAFILE_XML_VERSION "1.0"
typedef struct {
- char *file_name;
- char *key;
- char *subkey;
-} MetadataKey;
-
-typedef struct {
gboolean is_list;
union {
char *string;
@@ -49,23 +43,6 @@ typedef struct {
char *default_value;
} MetadataValue;
-#if 0
-static MetadataValue *get_metadata (NautilusDirectory *directory,
- const MetadataKey *key);
-#endif
-static char * get_metadata_from_node (xmlNode *node,
- const char *key,
- const char *default_metadata);
-static GList * get_metadata_list_from_node (xmlNode *node,
- const char *list_key,
- const char *list_subkey);
-static gboolean set_metadata_eat_parameters (NautilusDirectory *directory,
- MetadataKey *key,
- MetadataValue *value);
-static gboolean set_metadata_in_metafile (NautilusDirectory *directory,
- const MetadataKey *key,
- const MetadataValue *value);
-
static char *
get_metadata_from_node (xmlNode *node,
const char *key,
@@ -88,17 +65,11 @@ get_metadata_from_node (xmlNode *node,
return result;
}
-
static GList *
get_metadata_list_from_node (xmlNode *node,
const char *list_key,
const char *list_subkey)
{
- g_return_val_if_fail (list_key != NULL, NULL);
- g_return_val_if_fail (list_key[0] != '\0', NULL);
- g_return_val_if_fail (list_subkey != NULL, NULL);
- g_return_val_if_fail (list_subkey[0] != '\0', NULL);
-
return nautilus_xml_get_property_for_children
(node, list_key, list_subkey);
}
@@ -120,136 +91,14 @@ create_metafile_root (NautilusDirectory *directory)
return root;
}
-char *
-nautilus_directory_get_metadata (NautilusDirectory *directory,
- const char *key,
- const char *default_metadata)
-{
- /* It's legal to call this on a NULL directory. */
- if (directory == NULL) {
- return g_strdup (default_metadata);
- }
-
- g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
-
- /* The root itself represents the directory. */
- return get_metadata_from_node
- (xmlDocGetRootElement (directory->details->metafile),
- key, default_metadata);
-}
-
-GList *
-nautilus_directory_get_metadata_list (NautilusDirectory *directory,
- const char *list_key,
- const char *list_subkey)
-{
- /* It's legal to call this on a NULL directory. */
- if (directory == NULL) {
- return NULL;
- }
-
- g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
-
- /* The root itself represents the directory. */
- return get_metadata_list_from_node
- (xmlDocGetRootElement (directory->details->metafile),
- list_key, list_subkey);
-}
-
-gboolean
-nautilus_directory_get_boolean_metadata (NautilusDirectory *directory,
- const char *key,
- gboolean default_metadata)
-{
- char *result_as_string;
- gboolean result;
-
- result_as_string = nautilus_directory_get_metadata
- (directory, key,
- default_metadata ? "true" : "false");
-
- g_strdown (result_as_string);
- if (strcmp (result_as_string, "true") == 0) {
- result = TRUE;
- } else if (strcmp (result_as_string, "false") == 0) {
- result = FALSE;
- } else {
- if (result_as_string != NULL) {
- g_warning ("boolean metadata with value other than true or false");
- }
- result = default_metadata;
- }
-
- g_free (result_as_string);
- return result;
-}
-
-void
-nautilus_directory_set_boolean_metadata (NautilusDirectory *directory,
- const char *key,
- gboolean default_metadata,
- gboolean metadata)
-{
- nautilus_directory_set_metadata
- (directory, key,
- default_metadata ? "true" : "false",
- metadata ? "true" : "false");
-}
-
-int
-nautilus_directory_get_integer_metadata (NautilusDirectory *directory,
- const char *key,
- int default_metadata)
-{
- char *result_as_string;
- char *default_as_string;
- int result;
-
- default_as_string = g_strdup_printf ("%d", default_metadata);
- result_as_string = nautilus_directory_get_metadata
- (directory, key, default_as_string);
-
- /* Handle oddball case of non-existent directory */
- if (result_as_string == NULL) {
- result = default_metadata;
- } else {
- result = atoi (result_as_string);
- g_free (result_as_string);
- }
-
- g_free (default_as_string);
- return result;
-
-}
-
-void
-nautilus_directory_set_integer_metadata (NautilusDirectory *directory,
- const char *key,
- int default_metadata,
- int metadata)
-{
- char *value_as_string;
- char *default_as_string;
-
- value_as_string = g_strdup_printf ("%d", metadata);
- default_as_string = g_strdup_printf ("%d", default_metadata);
-
- nautilus_directory_set_metadata
- (directory, key,
- default_as_string, value_as_string);
-
- g_free (value_as_string);
- g_free (default_as_string);
-}
-
-xmlNode *
-nautilus_directory_get_file_metadata_node (NautilusDirectory *directory,
- const char *file_name,
- gboolean create)
+static xmlNode *
+get_file_node (NautilusDirectory *directory,
+ const char *file_name,
+ gboolean create)
{
xmlNode *root, *child;
- g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
/* The root itself represents the directory.
* The children represent the files.
@@ -260,52 +109,60 @@ nautilus_directory_get_file_metadata_node (NautilusDirectory *directory,
* in memory at all.
*/
child = nautilus_xml_get_root_child_by_name_and_property
- (directory->details->metafile,
- "FILE", METADATA_NODE_NAME_FOR_FILE_NAME, file_name);
+ (directory->details->metafile, "FILE", "NAME", file_name);
if (child != NULL) {
return child;
- }
+ }
/* Create if necessary. */
if (create) {
root = create_metafile_root (directory);
child = xmlNewChild (root, NULL, "FILE", NULL);
- xmlSetProp (child, METADATA_NODE_NAME_FOR_FILE_NAME, file_name);
+ xmlSetProp (child, "NAME", file_name);
return child;
}
return NULL;
}
-char *
-nautilus_directory_get_file_metadata (NautilusDirectory *directory,
- const char *file_name,
- const char *key,
- const char *default_metadata)
+static char *
+get_metadata_string_from_metafile (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *default_metadata)
{
- return get_metadata_from_node
- (nautilus_directory_get_file_metadata_node (directory, file_name, FALSE),
- key, default_metadata);
-}
+ xmlNode *node;
+ if (file_name == NULL) {
+ node = xmlDocGetRootElement (directory->details->metafile);
+ } else {
+ node = get_file_node (directory, file_name, FALSE);
+ }
+ return get_metadata_from_node (node, key, default_metadata);
+}
-GList *
-nautilus_directory_get_file_metadata_list (NautilusDirectory *directory,
- const char *file_name,
- const char *list_key,
- const char *list_subkey)
+static GList *
+get_metadata_list_from_metafile (NautilusDirectory *directory,
+ const char *file_name,
+ const char *list_key,
+ const char *list_subkey)
{
- return get_metadata_list_from_node
- (nautilus_directory_get_file_metadata_node (directory, file_name, FALSE),
- list_key, list_subkey);
+ xmlNode *node;
+
+ if (file_name == NULL) {
+ node = xmlDocGetRootElement (directory->details->metafile);
+ } else {
+ node = get_file_node (directory, file_name, FALSE);
+ }
+ return get_metadata_list_from_node (node, list_key, list_subkey);
}
static gboolean
-real_set_metadata (NautilusDirectory *directory,
- const char *file_name,
- const char *key,
- const char *default_metadata,
- const char *metadata)
+set_metadata_string_in_metafile (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *default_metadata,
+ const char *metadata)
{
char *old_metadata;
gboolean old_metadata_matches;
@@ -340,8 +197,7 @@ real_set_metadata (NautilusDirectory *directory,
if (file_name == NULL) {
node = create_metafile_root (directory);
} else {
- node = nautilus_directory_get_file_metadata_node
- (directory, file_name, value != NULL);
+ node = get_file_node (directory, file_name, value != NULL);
}
/* Add or remove a property node. */
@@ -358,11 +214,11 @@ real_set_metadata (NautilusDirectory *directory,
}
static gboolean
-real_set_metadata_list (NautilusDirectory *directory,
- const char *file_name,
- const char *list_key,
- const char *list_subkey,
- GList *list)
+set_metadata_list_in_metafile (NautilusDirectory *directory,
+ const char *file_name,
+ const char *list_key,
+ const char *list_subkey,
+ GList *list)
{
xmlNode *node, *child, *next;
gboolean changed;
@@ -373,8 +229,7 @@ real_set_metadata_list (NautilusDirectory *directory,
if (file_name == NULL) {
node = create_metafile_root (directory);
} else {
- node = nautilus_directory_get_file_metadata_node
- (directory, file_name, list != NULL);
+ node = get_file_node (directory, file_name, list != NULL);
}
/* Work with the list. */
@@ -420,72 +275,6 @@ real_set_metadata_list (NautilusDirectory *directory,
return TRUE;
}
-static MetadataKey *
-metadata_key_new (const char *file_name,
- const char *key_string,
- const char *subkey)
-{
- MetadataKey *key;
-
- key = g_new0 (MetadataKey, 1);
- key->file_name = g_strdup (file_name);
- key->key = g_strdup (key_string);
- key->subkey = g_strdup (subkey);
-
- return key;
-}
-
-static void
-metadata_key_destroy (MetadataKey *key)
-{
- if (key == NULL) {
- return;
- }
-
- g_free (key->file_name);
- g_free (key->key);
- g_free (key->subkey);
- g_free (key);
-}
-
-static guint
-metadata_key_hash (gconstpointer key_pointer)
-{
- const MetadataKey *key;
- guint hash;
-
- key = key_pointer;
- hash = 0;
-
- if (key->file_name != NULL) {
- hash = g_str_hash (key->file_name);
- }
-
- hash <<= 4;
- hash ^= g_str_hash (key->key);
-
- if (key->subkey != NULL) {
- hash <<= 4;
- hash ^= g_str_hash (key->subkey);
- }
-
- return hash;
-}
-
-static gboolean
-metadata_key_hash_equal (gconstpointer key_pointer_a,
- gconstpointer key_pointer_b)
-{
- const MetadataKey *key_a, *key_b;
-
- key_a = key_pointer_a;
- key_b = key_pointer_b;
-
- return nautilus_strcmp (key_a->file_name, key_b->file_name) == 0
- && nautilus_strcmp (key_a->key, key_b->key) == 0
- && nautilus_strcmp (key_a->subkey, key_b->subkey) == 0;
-}
-
static MetadataValue *
metadata_value_new (const char *default_metadata, const char *metadata)
{
@@ -553,106 +342,195 @@ metadata_value_equal (const MetadataValue *value_a,
static gboolean
set_metadata_in_metafile (NautilusDirectory *directory,
- const MetadataKey *key,
+ const char *file_name,
+ const char *key,
+ const char *subkey,
const MetadataValue *value)
{
gboolean changed;
if (!value->is_list) {
- g_assert (key->subkey == NULL);
- changed = real_set_metadata
- (directory,
- key->file_name,
- key->key,
+ g_assert (subkey == NULL);
+ changed = set_metadata_string_in_metafile
+ (directory, file_name, key,
value->default_value,
value->value.string);
} else {
g_assert (value->default_value == NULL);
- changed = real_set_metadata_list
- (directory,
- key->file_name,
- key->key,
- key->subkey,
+ changed = set_metadata_list_in_metafile
+ (directory, file_name, key, subkey,
value->value.string_list);
}
return changed;
}
+static char *
+get_metadata_string_from_table (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *default_metadata)
+{
+ GHashTable *directory_table, *file_table;
+ MetadataValue *value;
+
+ /* Get the value from the hash table. */
+ directory_table = directory->details->metadata_changes;
+ file_table = directory_table == NULL ? NULL
+ : g_hash_table_lookup (directory_table, file_name);
+ value = file_table == NULL ? NULL
+ : g_hash_table_lookup (file_table, key);
+ if (value == NULL) {
+ return g_strdup (default_metadata);
+ }
+
+ /* Convert it to a string. */
+ g_assert (!value->is_list);
+ if (nautilus_strcmp (value->value.string, value->default_value) == 0) {
+ return g_strdup (default_metadata);
+ }
+ return g_strdup (value->value.string);
+}
+
+static GList *
+get_metadata_list_from_table (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *subkey)
+{
+ GHashTable *directory_table, *file_table;
+ char *combined_key;
+ MetadataValue *value;
+
+ /* Get the value from the hash table. */
+ directory_table = directory->details->metadata_changes;
+ file_table = directory_table == NULL ? NULL
+ : g_hash_table_lookup (directory_table, file_name);
+ if (file_table == NULL) {
+ return NULL;
+ }
+ combined_key = g_strconcat (key, "/", subkey, NULL);
+ value = g_hash_table_lookup (file_table, combined_key);
+ g_free (combined_key);
+ if (value == NULL) {
+ return NULL;
+ }
+
+ /* Copy the list and return it. */
+ g_assert (value->is_list);
+ return nautilus_g_str_list_copy (value->value.string_list);
+}
+
+static guint
+str_or_null_hash (gconstpointer str)
+{
+ return str == NULL ? 0 : g_str_hash (str);
+}
+
static gboolean
-set_metadata_eat_parameters (NautilusDirectory *directory,
- MetadataKey *key,
- MetadataValue *value)
+str_or_null_equal (gconstpointer str_a, gconstpointer str_b)
{
- gboolean changed;
- MetadataKey *destroy_key;
- MetadataValue *destroy_value;
- gpointer old_key, old_value;
+ if (str_a == NULL) {
+ return str_b == NULL;
+ }
+ if (str_b == NULL) {
+ return FALSE;
+ }
+ return g_str_equal (str_a, str_b);
+}
- destroy_key = key;
- destroy_value = value;
+static gboolean
+set_metadata_eat_value (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *subkey,
+ MetadataValue *value)
+{
+ GHashTable *directory_table, *file_table;
+ gboolean found, changed;
+ char *combined_key;
+ gpointer old_key, old_value;
- if (!directory->details->metafile_read) {
+ if (directory->details->metafile_read) {
+ changed = set_metadata_in_metafile
+ (directory, file_name, key, subkey, value);
+ metadata_value_destroy (value);
+ } else {
/* Create hash table only when we need it.
* We'll destroy it when we finish reading the metafile.
*/
- if (directory->details->metadata_changes == NULL) {
- directory->details->metadata_changes =
- g_hash_table_new (metadata_key_hash,
- metadata_key_hash_equal);
+ directory_table = directory->details->metadata_changes;
+ if (directory_table == NULL) {
+ directory_table = g_hash_table_new
+ (str_or_null_hash, str_or_null_equal);
+ directory->details->metadata_changes = directory_table;
+ }
+ file_table = g_hash_table_lookup (directory_table, file_name);
+ if (file_table == NULL) {
+ file_table = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (directory_table,
+ g_strdup (file_name), file_table);
}
- /* Put the change into the hash.
- * Delete the old change.
- */
- if (g_hash_table_lookup_extended (directory->details->metadata_changes,
- key,
- &old_key,
- &old_value)) {
- changed = !metadata_value_equal (old_value, value);
- if (changed) {
- destroy_key = old_key;
- destroy_value = old_value;
- }
+ /* Find the entry in the hash table. */
+ if (subkey == NULL) {
+ combined_key = g_strdup (key);
} else {
+ combined_key = g_strconcat (key, "/", subkey, NULL);
+ }
+ found = g_hash_table_lookup_extended
+ (file_table, combined_key, &old_key, &old_value);
+ g_free (combined_key);
+
+ /* Put the change into the hash. Delete the old change. */
+ if (!found) {
+ old_key = NULL;
+ old_value = NULL;
changed = TRUE;
- destroy_key = NULL;
- destroy_value = NULL;
+ } else {
+ changed = !metadata_value_equal (old_value, value);
}
-
if (changed) {
- g_hash_table_insert (directory->details->metadata_changes,
- key, value);
+ g_hash_table_insert (file_table, combined_key, value);
+ g_free (old_key);
+ metadata_value_destroy (old_value);
+ } else {
+ g_free (combined_key);
+ metadata_value_destroy (value);
}
- } else {
- changed = set_metadata_in_metafile (directory, key, value);
}
- metadata_key_destroy (destroy_key);
- metadata_value_destroy (destroy_value);
-
return changed;
}
static void
-free_metadata_changes_hash_table_entry (gpointer key, gpointer value, gpointer user_data)
+free_file_table_entry (gpointer key, gpointer value, gpointer user_data)
{
g_assert (user_data == NULL);
- metadata_key_destroy (key);
+
+ g_free (key);
metadata_value_destroy (value);
}
static void
-destroy_metadata_changes_hash_table (GHashTable *table)
+free_directory_table_entry (gpointer key, gpointer value, gpointer user_data)
+{
+ g_assert (user_data == NULL);
+ g_assert (value != NULL);
+
+ g_free (key);
+ g_hash_table_foreach (value, free_file_table_entry, NULL);
+ g_hash_table_destroy (value);
+}
+
+static void
+destroy_metadata_changes_hash_table (GHashTable *directory_table)
{
- if (table == NULL) {
+ if (directory_table == NULL) {
return;
}
-
- g_hash_table_foreach (table,
- free_metadata_changes_hash_table_entry,
- NULL);
- g_hash_table_destroy (table);
+ g_hash_table_foreach (directory_table, free_directory_table_entry, NULL);
+ g_hash_table_destroy (directory_table);
}
void
@@ -662,45 +540,149 @@ nautilus_directory_metafile_destroy (NautilusDirectory *directory)
destroy_metadata_changes_hash_table (directory->details->metadata_changes);
}
+char *
+nautilus_directory_get_metadata (NautilusDirectory *directory,
+ const char *key,
+ const char *default_metadata)
+{
+ g_return_val_if_fail (key != NULL, g_strdup (default_metadata));
+ g_return_val_if_fail (key[0] != '\0', g_strdup (default_metadata));
+
+ /* It's legal to call this on a NULL directory. */
+ if (directory == NULL) {
+ return g_strdup (default_metadata);
+ }
+
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), g_strdup (default_metadata));
+
+ if (directory->details->metafile_read) {
+ return get_metadata_string_from_metafile
+ (directory, NULL, key, default_metadata);
+ } else {
+ return get_metadata_string_from_table
+ (directory, NULL, key, default_metadata);
+ }
+}
+
+char *
+nautilus_directory_get_file_metadata (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *default_metadata)
+{
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE);
+ g_return_val_if_fail (file_name != NULL, FALSE);
+ g_return_val_if_fail (file_name[0] != '\0', FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (key[0] != '\0', FALSE);
+
+ if (directory->details->metafile_read) {
+ return get_metadata_string_from_metafile
+ (directory, file_name, key, default_metadata);
+ } else {
+ return get_metadata_string_from_table
+ (directory, file_name, key, default_metadata);
+ }
+}
+
+
+GList *
+nautilus_directory_get_metadata_list (NautilusDirectory *directory,
+ const char *list_key,
+ const char *list_subkey)
+{
+ g_return_val_if_fail (list_key != NULL, NULL);
+ g_return_val_if_fail (list_key[0] != '\0', NULL);
+ g_return_val_if_fail (list_subkey != NULL, NULL);
+ g_return_val_if_fail (list_subkey[0] != '\0', NULL);
+
+ /* It's legal to call this on a NULL directory. */
+ if (directory == NULL) {
+ return NULL;
+ }
+
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
+
+ if (directory->details->metafile_read) {
+ return get_metadata_list_from_metafile
+ (directory, NULL, list_key, list_subkey);
+ } else {
+ return get_metadata_list_from_table
+ (directory, NULL, list_key, list_subkey);
+ }
+}
+
+GList *
+nautilus_directory_get_file_metadata_list (NautilusDirectory *directory,
+ const char *file_name,
+ const char *list_key,
+ const char *list_subkey)
+{
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
+ g_return_val_if_fail (file_name != NULL, NULL);
+ g_return_val_if_fail (file_name[0] != '\0', NULL);
+ g_return_val_if_fail (list_key != NULL, NULL);
+ g_return_val_if_fail (list_key[0] != '\0', NULL);
+ g_return_val_if_fail (list_subkey != NULL, NULL);
+ g_return_val_if_fail (list_subkey[0] != '\0', NULL);
+
+ if (directory->details->metafile_read) {
+ return get_metadata_list_from_metafile
+ (directory, file_name, list_key, list_subkey);
+ } else {
+ return get_metadata_list_from_table
+ (directory, file_name, list_key, list_subkey);
+ }
+}
+
void
nautilus_directory_set_metadata (NautilusDirectory *directory,
- const char *key_string,
+ const char *key,
const char *default_metadata,
const char *metadata)
{
- MetadataKey *key;
MetadataValue *value;
g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
- g_return_if_fail (key_string != NULL);
- g_return_if_fail (key_string[0] != '\0');
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (key[0] != '\0');
- key = metadata_key_new (NULL, key_string, NULL);
- value = metadata_value_new (default_metadata, metadata);
- if (set_metadata_eat_parameters (directory, key, value)) {
- nautilus_directory_emit_metadata_changed (directory);
+ if (directory->details->metafile_read) {
+ if (set_metadata_string_in_metafile (directory, NULL, key,
+ default_metadata, metadata)) {
+ nautilus_directory_request_write_metafile (directory);
+ }
+ } else {
+ value = metadata_value_new (default_metadata, metadata);
+ if (set_metadata_eat_value (directory, NULL, key, NULL, value)) {
+ nautilus_directory_emit_metadata_changed (directory);
+ }
}
}
gboolean
nautilus_directory_set_file_metadata (NautilusDirectory *directory,
const char *file_name,
- const char *key_string,
+ const char *key,
const char *default_metadata,
const char *metadata)
{
- MetadataKey *key;
MetadataValue *value;
g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE);
g_return_val_if_fail (file_name != NULL, FALSE);
g_return_val_if_fail (file_name[0] != '\0', FALSE);
- g_return_val_if_fail (key_string != NULL, FALSE);
- g_return_val_if_fail (key_string[0] != '\0', FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (key[0] != '\0', FALSE);
- key = metadata_key_new (file_name, key_string, NULL);
- value = metadata_value_new (default_metadata, metadata);
- return set_metadata_eat_parameters (directory, key, value);
+ if (directory->details->metafile_read) {
+ return set_metadata_string_in_metafile (directory, file_name, key,
+ default_metadata, metadata);
+ } else {
+ value = metadata_value_new (default_metadata, metadata);
+ return set_metadata_eat_value (directory, file_name,
+ key, NULL, value);
+ }
}
gboolean
@@ -710,7 +692,6 @@ nautilus_directory_set_file_metadata_list (NautilusDirectory *directory,
const char *list_subkey,
GList *list)
{
- MetadataKey *key;
MetadataValue *value;
g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE);
@@ -721,7 +702,193 @@ nautilus_directory_set_file_metadata_list (NautilusDirectory *directory,
g_return_val_if_fail (list_subkey != NULL, FALSE);
g_return_val_if_fail (list_subkey[0] != '\0', FALSE);
- key = metadata_key_new (file_name, list_key, list_subkey);
- value = metadata_value_new_list (list);
- return set_metadata_eat_parameters (directory, key, value);
+ if (directory->details->metafile_read) {
+ return set_metadata_list_in_metafile (directory, file_name,
+ list_key, list_subkey, list);
+ } else {
+ value = metadata_value_new_list (list);
+ return set_metadata_eat_value (directory, file_name,
+ list_key, list_subkey, value);
+ }
+}
+
+void
+nautilus_directory_update_file_metadata (NautilusDirectory *directory,
+ const char *old_file_name,
+ const char *new_file_name)
+{
+ xmlNode *file_node;
+ GHashTable *directory_table;
+ gboolean found;
+ gpointer key, value;
+
+ if (directory->details->metafile_read) {
+ /* Move data in XML document if present. */
+ file_node = get_file_node (directory, old_file_name, FALSE);
+ if (file_node != NULL) {
+ xmlSetProp (file_node, "NAME", new_file_name);
+ nautilus_directory_request_write_metafile (directory);
+ }
+ } else {
+ /* Move data in hash table. */
+ directory_table = directory->details->metadata_changes;
+ found = g_hash_table_lookup_extended
+ (directory_table, old_file_name, &key, &value);
+ if (found) {
+ g_hash_table_remove (directory_table, old_file_name);
+ g_free (key);
+ g_hash_table_insert (directory_table,
+ g_strdup (new_file_name), value);
+ }
+ }
+}
+
+typedef struct {
+ NautilusDirectory *directory;
+ const char *file_name;
+} ChangeContext;
+
+static void
+apply_one_change (gpointer key, gpointer value, gpointer callback_data)
+{
+ ChangeContext *context;
+ const char *hash_table_key, *separator, *metadata_key, *subkey;
+ char *key_prefix;
+
+ g_assert (key != NULL);
+ g_assert (value != NULL);
+ g_assert (callback_data != NULL);
+
+ context = callback_data;
+
+ /* Break the key in half. */
+ hash_table_key = key;
+ separator = strchr (hash_table_key, '/');
+ if (separator == NULL) {
+ key_prefix = NULL;
+ metadata_key = hash_table_key;
+ subkey = NULL;
+ } else {
+ key_prefix = g_strndup (hash_table_key, separator - hash_table_key);
+ metadata_key = key_prefix;
+ subkey = separator + 1;
+ }
+
+ /* Set the metadata. */
+ set_metadata_in_metafile (context->directory, context->file_name,
+ metadata_key, subkey, value);
+ g_free (key_prefix);
+}
+
+static void
+apply_file_changes (gpointer key, gpointer value, gpointer callback_data)
+{
+ ChangeContext context;
+
+ g_assert (value != NULL);
+ g_assert (NAUTILUS_IS_DIRECTORY (callback_data));
+
+ context.directory = callback_data;
+ context.file_name = key;
+
+ g_hash_table_foreach (value, apply_one_change, &context);
+ g_hash_table_destroy (value);
+}
+
+void
+nautilus_directory_metafile_apply_pending_changes (NautilusDirectory *directory)
+{
+ if (directory->details->metadata_changes == NULL) {
+ return;
+ }
+ g_hash_table_foreach (directory->details->metadata_changes,
+ apply_file_changes, directory);
+ g_hash_table_destroy (directory->details->metadata_changes);
+ directory->details->metadata_changes = NULL;
+}
+
+gboolean
+nautilus_directory_get_boolean_metadata (NautilusDirectory *directory,
+ const char *key,
+ gboolean default_metadata)
+{
+ char *result_as_string;
+ gboolean result;
+
+ result_as_string = nautilus_directory_get_metadata
+ (directory, key,
+ default_metadata ? "true" : "false");
+
+ g_strdown (result_as_string);
+ if (strcmp (result_as_string, "true") == 0) {
+ result = TRUE;
+ } else if (strcmp (result_as_string, "false") == 0) {
+ result = FALSE;
+ } else {
+ if (result_as_string != NULL) {
+ g_warning ("boolean metadata with value other than true or false");
+ }
+ result = default_metadata;
+ }
+
+ g_free (result_as_string);
+ return result;
+}
+
+void
+nautilus_directory_set_boolean_metadata (NautilusDirectory *directory,
+ const char *key,
+ gboolean default_metadata,
+ gboolean metadata)
+{
+ nautilus_directory_set_metadata
+ (directory, key,
+ default_metadata ? "true" : "false",
+ metadata ? "true" : "false");
+}
+
+int
+nautilus_directory_get_integer_metadata (NautilusDirectory *directory,
+ const char *key,
+ int default_metadata)
+{
+ char *result_as_string;
+ char *default_as_string;
+ int result;
+
+ default_as_string = g_strdup_printf ("%d", default_metadata);
+ result_as_string = nautilus_directory_get_metadata
+ (directory, key, default_as_string);
+
+ /* Handle oddball case of non-existent directory */
+ if (result_as_string == NULL) {
+ result = default_metadata;
+ } else {
+ result = atoi (result_as_string);
+ g_free (result_as_string);
+ }
+
+ g_free (default_as_string);
+ return result;
+
+}
+
+void
+nautilus_directory_set_integer_metadata (NautilusDirectory *directory,
+ const char *key,
+ int default_metadata,
+ int metadata)
+{
+ char *value_as_string;
+ char *default_as_string;
+
+ value_as_string = g_strdup_printf ("%d", metadata);
+ default_as_string = g_strdup_printf ("%d", default_metadata);
+
+ nautilus_directory_set_metadata
+ (directory, key,
+ default_as_string, value_as_string);
+
+ g_free (value_as_string);
+ g_free (default_as_string);
}
diff --git a/libnautilus-extensions/nautilus-directory-metafile.h b/libnautilus-extensions/nautilus-directory-metafile.h
index 4ee98f14e..cbd37fe99 100644
--- a/libnautilus-extensions/nautilus-directory-metafile.h
+++ b/libnautilus-extensions/nautilus-directory-metafile.h
@@ -25,25 +25,29 @@
#include "nautilus-directory.h"
#include <tree.h>
-char * nautilus_directory_get_file_metadata (NautilusDirectory *directory,
- const char *file_name,
- const char *key,
- const char *default_metadata);
-GList * nautilus_directory_get_file_metadata_list (NautilusDirectory *directory,
- const char *file_name,
- const char *list_key,
- const char *list_subkey);
-gboolean nautilus_directory_set_file_metadata (NautilusDirectory *directory,
- const char *file_name,
- const char *key,
- const char *default_metadata,
- const char *metadata);
-gboolean nautilus_directory_set_file_metadata_list (NautilusDirectory *directory,
- const char *file_name,
- const char *list_key,
- const char *list_subkey,
- GList *list);
-xmlNode *nautilus_directory_get_file_metadata_node (NautilusDirectory *directory,
- const char *file_name,
- gboolean create);
-void nautilus_directory_metafile_destroy (NautilusDirectory *directory);
+/* Interface for file metadata. */
+char * nautilus_directory_get_file_metadata (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *default_metadata);
+GList * nautilus_directory_get_file_metadata_list (NautilusDirectory *directory,
+ const char *file_name,
+ const char *list_key,
+ const char *list_subkey);
+gboolean nautilus_directory_set_file_metadata (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *default_metadata,
+ const char *metadata);
+gboolean nautilus_directory_set_file_metadata_list (NautilusDirectory *directory,
+ const char *file_name,
+ const char *list_key,
+ const char *list_subkey,
+ GList *list);
+void nautilus_directory_update_file_metadata (NautilusDirectory *directory,
+ const char *old_file_name,
+ const char *new_file_name);
+
+/* Interface for housekeeping. */
+void nautilus_directory_metafile_apply_pending_changes (NautilusDirectory *directory);
+void nautilus_directory_metafile_destroy (NautilusDirectory *directory);
diff --git a/libnautilus-extensions/nautilus-directory-private.h b/libnautilus-extensions/nautilus-directory-private.h
index 744f55837..1203fa135 100644
--- a/libnautilus-extensions/nautilus-directory-private.h
+++ b/libnautilus-extensions/nautilus-directory-private.h
@@ -32,8 +32,6 @@
#include "nautilus-file.h"
-#define METADATA_NODE_NAME_FOR_FILE_NAME "NAME"
-
typedef struct MetafileReadState MetafileReadState;
typedef struct MetafileWriteState MetafileWriteState;
typedef struct TopLeftTextReadState TopLeftTextReadState;
diff --git a/libnautilus-extensions/nautilus-file.c b/libnautilus-extensions/nautilus-file.c
index dbe91c5fc..5d0bcba89 100644
--- a/libnautilus-extensions/nautilus-file.c
+++ b/libnautilus-extensions/nautilus-file.c
@@ -520,20 +520,10 @@ file_operation_state_complete (FileOperationState *state,
static void
rename_update_info_and_metafile (FileOperationState *state)
{
- xmlNode *file_node;
-
- file_node = nautilus_directory_get_file_metadata_node
+ nautilus_directory_update_file_metadata
(state->file->details->directory,
state->file->details->info->name,
- FALSE);
-
- if (file_node != NULL) {
- xmlSetProp (file_node,
- METADATA_NODE_NAME_FOR_FILE_NAME,
- state->new_name);
- nautilus_directory_request_write_metafile
- (state->file->details->directory);
- }
+ state->new_name);
g_free (state->file->details->info->name);
state->file->details->info->name = g_strdup (state->new_name);
diff --git a/libnautilus-extensions/nautilus-glib-extensions.c b/libnautilus-extensions/nautilus-glib-extensions.c
index f5a15577f..06f791402 100644
--- a/libnautilus-extensions/nautilus-glib-extensions.c
+++ b/libnautilus-extensions/nautilus-glib-extensions.c
@@ -302,8 +302,6 @@ nautilus_g_ptr_array_sort (GPtrArray *array,
NautilusCompareFunction sort_function,
void *context)
{
- /* FIXME: Is there a good reason this doesn't use qsort? */
-
size_t count, r, l, j;
void **base, **lp, **rp, **ip, **jp, **tmpp;
void *tmp;
diff --git a/libnautilus-extensions/nautilus-string.h b/libnautilus-extensions/nautilus-string.h
index 0c40509c5..59bae3d69 100644
--- a/libnautilus-extensions/nautilus-string.h
+++ b/libnautilus-extensions/nautilus-string.h
@@ -35,41 +35,41 @@
/* NULL is allowed for all the str parameters to these functions. */
/* Versions of basic string functions that allow NULL. */
-size_t nautilus_strlen (const char *string);
-char * nautilus_strchr (const char *haystack,
- char needle);
-int nautilus_strcmp (const char *string_a,
- const char *string_b);
+size_t nautilus_strlen (const char *string);
+char * nautilus_strchr (const char *haystack,
+ char needle);
+int nautilus_strcmp (const char *string_a,
+ const char *string_b);
/* GCompareFunc version. */
-int nautilus_str_compare (gconstpointer string_a,
- gconstpointer string_b);
+int nautilus_str_compare (gconstpointer string_a,
+ gconstpointer string_b);
/* Versions of basic string functions that free their parameters. */
-int nautilus_eat_strcmp (char *string_a_gets_freed,
- const char *string_b);
+int nautilus_eat_strcmp (char *string_a_gets_freed,
+ const char *string_b);
/* Other basic string operations. */
-gboolean nautilus_str_has_prefix (const char *target,
- const char *prefix);
-char * nautilus_str_get_prefix (const char *source,
- const char *delimiter);
-gboolean nautilus_str_has_suffix (const char *target,
- const char *suffix);
-char * nautilus_str_strip_chr (const char *string,
- char remove_this);
-char * nautilus_str_strip_trailing_chr (const char *string,
- char remove_this);
+gboolean nautilus_str_has_prefix (const char *target,
+ const char *prefix);
+char * nautilus_str_get_prefix (const char *source,
+ const char *delimiter);
+gboolean nautilus_str_has_suffix (const char *target,
+ const char *suffix);
+char * nautilus_str_strip_chr (const char *string,
+ char remove_this);
+char * nautilus_str_strip_trailing_chr (const char *string,
+ char remove_this);
/* Conversions to and from strings. */
-gboolean nautilus_str_to_int (const char *string,
- int *integer);
-gboolean nautilus_eat_str_to_int (char *string_gets_freed,
- int *integer);
+gboolean nautilus_str_to_int (const char *string,
+ int *integer);
+gboolean nautilus_eat_str_to_int (char *string_gets_freed,
+ int *integer);
/* Escape function for slashes */
-char * nautilus_str_escape_slashes (const char *string);
+char * nautilus_str_escape_slashes (const char *string);
/* Escape function for '_' character. */
-char * nautilus_str_double_underscores (const char *string);
+char * nautilus_str_double_underscores (const char *string);
#endif /* NAUTILUS_STRING_H */
diff --git a/libnautilus-private/nautilus-directory-async.c b/libnautilus-private/nautilus-directory-async.c
index 9775b5259..0888bd071 100644
--- a/libnautilus-private/nautilus-directory-async.c
+++ b/libnautilus-private/nautilus-directory-async.c
@@ -25,6 +25,7 @@
#include <config.h>
#include "nautilus-directory-private.h"
+#include "nautilus-directory-metafile.h"
#include "nautilus-file-private.h"
#include "nautilus-file-attributes.h"
@@ -140,8 +141,26 @@ nautilus_metafile_read_cancel (NautilusDirectory *directory)
}
static void
+metafile_read_done (NautilusDirectory *directory)
+{
+ g_free (directory->details->metafile_read_state);
+
+ directory->details->metafile_read = TRUE;
+ directory->details->metafile_read_state = NULL;
+
+ /* Move over the changes to the metafile that were in the hash table. */
+ nautilus_directory_metafile_apply_pending_changes (directory);
+
+ /* Let the callers that were waiting for the metafile know. */
+ state_changed (directory);
+}
+
+static void
metafile_read_failed (NautilusDirectory *directory)
{
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
+ g_assert (directory->details->metafile == NULL);
+
g_free (directory->details->metafile_read_state->buffer);
if (directory->details->use_alternate_metafile) {
@@ -153,13 +172,7 @@ metafile_read_failed (NautilusDirectory *directory)
return;
}
- g_free (directory->details->metafile_read_state);
-
- directory->details->metafile_read = TRUE;
- directory->details->metafile_read_state = NULL;
-
- /* Let the callers that were waiting for the metafile know. */
- state_changed (directory);
+ metafile_read_done (directory);
}
static void
@@ -169,16 +182,7 @@ metafile_read_complete (NautilusDirectory *directory)
int size;
g_assert (NAUTILUS_IS_DIRECTORY (directory));
-
- /* FIXME bugzilla.eazel.com 720:
- * The following assertion shouldn't be disabled, but
- * it gets in the way when you set metadata before the
- * metafile is completely read. Currently, the old metadata
- * in the file will be lost. One way to test this is to
- * remove the metafile from your home directory and the
- * ~/Nautilus directory and then start the program.
- */
- /* g_assert (directory->details->metafile == NULL); */
+ g_assert (directory->details->metafile == NULL);
/* The gnome-xml parser requires a zero-terminated array. */
size = directory->details->metafile_read_state->bytes_read;
@@ -187,13 +191,7 @@ metafile_read_complete (NautilusDirectory *directory)
directory->details->metafile = xmlParseMemory (buffer, size);
g_free (buffer);
- g_free (directory->details->metafile_read_state);
-
- directory->details->metafile_read = TRUE;
- directory->details->metafile_read_state = NULL;
-
- /* Let the callers that were waiting for the metafile know. */
- state_changed (directory);
+ metafile_read_done (directory);
}
static void
diff --git a/libnautilus-private/nautilus-directory-metafile.c b/libnautilus-private/nautilus-directory-metafile.c
index 09ef0a81c..3f441a36c 100644
--- a/libnautilus-private/nautilus-directory-metafile.c
+++ b/libnautilus-private/nautilus-directory-metafile.c
@@ -35,12 +35,6 @@
#define METAFILE_XML_VERSION "1.0"
typedef struct {
- char *file_name;
- char *key;
- char *subkey;
-} MetadataKey;
-
-typedef struct {
gboolean is_list;
union {
char *string;
@@ -49,23 +43,6 @@ typedef struct {
char *default_value;
} MetadataValue;
-#if 0
-static MetadataValue *get_metadata (NautilusDirectory *directory,
- const MetadataKey *key);
-#endif
-static char * get_metadata_from_node (xmlNode *node,
- const char *key,
- const char *default_metadata);
-static GList * get_metadata_list_from_node (xmlNode *node,
- const char *list_key,
- const char *list_subkey);
-static gboolean set_metadata_eat_parameters (NautilusDirectory *directory,
- MetadataKey *key,
- MetadataValue *value);
-static gboolean set_metadata_in_metafile (NautilusDirectory *directory,
- const MetadataKey *key,
- const MetadataValue *value);
-
static char *
get_metadata_from_node (xmlNode *node,
const char *key,
@@ -88,17 +65,11 @@ get_metadata_from_node (xmlNode *node,
return result;
}
-
static GList *
get_metadata_list_from_node (xmlNode *node,
const char *list_key,
const char *list_subkey)
{
- g_return_val_if_fail (list_key != NULL, NULL);
- g_return_val_if_fail (list_key[0] != '\0', NULL);
- g_return_val_if_fail (list_subkey != NULL, NULL);
- g_return_val_if_fail (list_subkey[0] != '\0', NULL);
-
return nautilus_xml_get_property_for_children
(node, list_key, list_subkey);
}
@@ -120,136 +91,14 @@ create_metafile_root (NautilusDirectory *directory)
return root;
}
-char *
-nautilus_directory_get_metadata (NautilusDirectory *directory,
- const char *key,
- const char *default_metadata)
-{
- /* It's legal to call this on a NULL directory. */
- if (directory == NULL) {
- return g_strdup (default_metadata);
- }
-
- g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
-
- /* The root itself represents the directory. */
- return get_metadata_from_node
- (xmlDocGetRootElement (directory->details->metafile),
- key, default_metadata);
-}
-
-GList *
-nautilus_directory_get_metadata_list (NautilusDirectory *directory,
- const char *list_key,
- const char *list_subkey)
-{
- /* It's legal to call this on a NULL directory. */
- if (directory == NULL) {
- return NULL;
- }
-
- g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
-
- /* The root itself represents the directory. */
- return get_metadata_list_from_node
- (xmlDocGetRootElement (directory->details->metafile),
- list_key, list_subkey);
-}
-
-gboolean
-nautilus_directory_get_boolean_metadata (NautilusDirectory *directory,
- const char *key,
- gboolean default_metadata)
-{
- char *result_as_string;
- gboolean result;
-
- result_as_string = nautilus_directory_get_metadata
- (directory, key,
- default_metadata ? "true" : "false");
-
- g_strdown (result_as_string);
- if (strcmp (result_as_string, "true") == 0) {
- result = TRUE;
- } else if (strcmp (result_as_string, "false") == 0) {
- result = FALSE;
- } else {
- if (result_as_string != NULL) {
- g_warning ("boolean metadata with value other than true or false");
- }
- result = default_metadata;
- }
-
- g_free (result_as_string);
- return result;
-}
-
-void
-nautilus_directory_set_boolean_metadata (NautilusDirectory *directory,
- const char *key,
- gboolean default_metadata,
- gboolean metadata)
-{
- nautilus_directory_set_metadata
- (directory, key,
- default_metadata ? "true" : "false",
- metadata ? "true" : "false");
-}
-
-int
-nautilus_directory_get_integer_metadata (NautilusDirectory *directory,
- const char *key,
- int default_metadata)
-{
- char *result_as_string;
- char *default_as_string;
- int result;
-
- default_as_string = g_strdup_printf ("%d", default_metadata);
- result_as_string = nautilus_directory_get_metadata
- (directory, key, default_as_string);
-
- /* Handle oddball case of non-existent directory */
- if (result_as_string == NULL) {
- result = default_metadata;
- } else {
- result = atoi (result_as_string);
- g_free (result_as_string);
- }
-
- g_free (default_as_string);
- return result;
-
-}
-
-void
-nautilus_directory_set_integer_metadata (NautilusDirectory *directory,
- const char *key,
- int default_metadata,
- int metadata)
-{
- char *value_as_string;
- char *default_as_string;
-
- value_as_string = g_strdup_printf ("%d", metadata);
- default_as_string = g_strdup_printf ("%d", default_metadata);
-
- nautilus_directory_set_metadata
- (directory, key,
- default_as_string, value_as_string);
-
- g_free (value_as_string);
- g_free (default_as_string);
-}
-
-xmlNode *
-nautilus_directory_get_file_metadata_node (NautilusDirectory *directory,
- const char *file_name,
- gboolean create)
+static xmlNode *
+get_file_node (NautilusDirectory *directory,
+ const char *file_name,
+ gboolean create)
{
xmlNode *root, *child;
- g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
/* The root itself represents the directory.
* The children represent the files.
@@ -260,52 +109,60 @@ nautilus_directory_get_file_metadata_node (NautilusDirectory *directory,
* in memory at all.
*/
child = nautilus_xml_get_root_child_by_name_and_property
- (directory->details->metafile,
- "FILE", METADATA_NODE_NAME_FOR_FILE_NAME, file_name);
+ (directory->details->metafile, "FILE", "NAME", file_name);
if (child != NULL) {
return child;
- }
+ }
/* Create if necessary. */
if (create) {
root = create_metafile_root (directory);
child = xmlNewChild (root, NULL, "FILE", NULL);
- xmlSetProp (child, METADATA_NODE_NAME_FOR_FILE_NAME, file_name);
+ xmlSetProp (child, "NAME", file_name);
return child;
}
return NULL;
}
-char *
-nautilus_directory_get_file_metadata (NautilusDirectory *directory,
- const char *file_name,
- const char *key,
- const char *default_metadata)
+static char *
+get_metadata_string_from_metafile (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *default_metadata)
{
- return get_metadata_from_node
- (nautilus_directory_get_file_metadata_node (directory, file_name, FALSE),
- key, default_metadata);
-}
+ xmlNode *node;
+ if (file_name == NULL) {
+ node = xmlDocGetRootElement (directory->details->metafile);
+ } else {
+ node = get_file_node (directory, file_name, FALSE);
+ }
+ return get_metadata_from_node (node, key, default_metadata);
+}
-GList *
-nautilus_directory_get_file_metadata_list (NautilusDirectory *directory,
- const char *file_name,
- const char *list_key,
- const char *list_subkey)
+static GList *
+get_metadata_list_from_metafile (NautilusDirectory *directory,
+ const char *file_name,
+ const char *list_key,
+ const char *list_subkey)
{
- return get_metadata_list_from_node
- (nautilus_directory_get_file_metadata_node (directory, file_name, FALSE),
- list_key, list_subkey);
+ xmlNode *node;
+
+ if (file_name == NULL) {
+ node = xmlDocGetRootElement (directory->details->metafile);
+ } else {
+ node = get_file_node (directory, file_name, FALSE);
+ }
+ return get_metadata_list_from_node (node, list_key, list_subkey);
}
static gboolean
-real_set_metadata (NautilusDirectory *directory,
- const char *file_name,
- const char *key,
- const char *default_metadata,
- const char *metadata)
+set_metadata_string_in_metafile (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *default_metadata,
+ const char *metadata)
{
char *old_metadata;
gboolean old_metadata_matches;
@@ -340,8 +197,7 @@ real_set_metadata (NautilusDirectory *directory,
if (file_name == NULL) {
node = create_metafile_root (directory);
} else {
- node = nautilus_directory_get_file_metadata_node
- (directory, file_name, value != NULL);
+ node = get_file_node (directory, file_name, value != NULL);
}
/* Add or remove a property node. */
@@ -358,11 +214,11 @@ real_set_metadata (NautilusDirectory *directory,
}
static gboolean
-real_set_metadata_list (NautilusDirectory *directory,
- const char *file_name,
- const char *list_key,
- const char *list_subkey,
- GList *list)
+set_metadata_list_in_metafile (NautilusDirectory *directory,
+ const char *file_name,
+ const char *list_key,
+ const char *list_subkey,
+ GList *list)
{
xmlNode *node, *child, *next;
gboolean changed;
@@ -373,8 +229,7 @@ real_set_metadata_list (NautilusDirectory *directory,
if (file_name == NULL) {
node = create_metafile_root (directory);
} else {
- node = nautilus_directory_get_file_metadata_node
- (directory, file_name, list != NULL);
+ node = get_file_node (directory, file_name, list != NULL);
}
/* Work with the list. */
@@ -420,72 +275,6 @@ real_set_metadata_list (NautilusDirectory *directory,
return TRUE;
}
-static MetadataKey *
-metadata_key_new (const char *file_name,
- const char *key_string,
- const char *subkey)
-{
- MetadataKey *key;
-
- key = g_new0 (MetadataKey, 1);
- key->file_name = g_strdup (file_name);
- key->key = g_strdup (key_string);
- key->subkey = g_strdup (subkey);
-
- return key;
-}
-
-static void
-metadata_key_destroy (MetadataKey *key)
-{
- if (key == NULL) {
- return;
- }
-
- g_free (key->file_name);
- g_free (key->key);
- g_free (key->subkey);
- g_free (key);
-}
-
-static guint
-metadata_key_hash (gconstpointer key_pointer)
-{
- const MetadataKey *key;
- guint hash;
-
- key = key_pointer;
- hash = 0;
-
- if (key->file_name != NULL) {
- hash = g_str_hash (key->file_name);
- }
-
- hash <<= 4;
- hash ^= g_str_hash (key->key);
-
- if (key->subkey != NULL) {
- hash <<= 4;
- hash ^= g_str_hash (key->subkey);
- }
-
- return hash;
-}
-
-static gboolean
-metadata_key_hash_equal (gconstpointer key_pointer_a,
- gconstpointer key_pointer_b)
-{
- const MetadataKey *key_a, *key_b;
-
- key_a = key_pointer_a;
- key_b = key_pointer_b;
-
- return nautilus_strcmp (key_a->file_name, key_b->file_name) == 0
- && nautilus_strcmp (key_a->key, key_b->key) == 0
- && nautilus_strcmp (key_a->subkey, key_b->subkey) == 0;
-}
-
static MetadataValue *
metadata_value_new (const char *default_metadata, const char *metadata)
{
@@ -553,106 +342,195 @@ metadata_value_equal (const MetadataValue *value_a,
static gboolean
set_metadata_in_metafile (NautilusDirectory *directory,
- const MetadataKey *key,
+ const char *file_name,
+ const char *key,
+ const char *subkey,
const MetadataValue *value)
{
gboolean changed;
if (!value->is_list) {
- g_assert (key->subkey == NULL);
- changed = real_set_metadata
- (directory,
- key->file_name,
- key->key,
+ g_assert (subkey == NULL);
+ changed = set_metadata_string_in_metafile
+ (directory, file_name, key,
value->default_value,
value->value.string);
} else {
g_assert (value->default_value == NULL);
- changed = real_set_metadata_list
- (directory,
- key->file_name,
- key->key,
- key->subkey,
+ changed = set_metadata_list_in_metafile
+ (directory, file_name, key, subkey,
value->value.string_list);
}
return changed;
}
+static char *
+get_metadata_string_from_table (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *default_metadata)
+{
+ GHashTable *directory_table, *file_table;
+ MetadataValue *value;
+
+ /* Get the value from the hash table. */
+ directory_table = directory->details->metadata_changes;
+ file_table = directory_table == NULL ? NULL
+ : g_hash_table_lookup (directory_table, file_name);
+ value = file_table == NULL ? NULL
+ : g_hash_table_lookup (file_table, key);
+ if (value == NULL) {
+ return g_strdup (default_metadata);
+ }
+
+ /* Convert it to a string. */
+ g_assert (!value->is_list);
+ if (nautilus_strcmp (value->value.string, value->default_value) == 0) {
+ return g_strdup (default_metadata);
+ }
+ return g_strdup (value->value.string);
+}
+
+static GList *
+get_metadata_list_from_table (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *subkey)
+{
+ GHashTable *directory_table, *file_table;
+ char *combined_key;
+ MetadataValue *value;
+
+ /* Get the value from the hash table. */
+ directory_table = directory->details->metadata_changes;
+ file_table = directory_table == NULL ? NULL
+ : g_hash_table_lookup (directory_table, file_name);
+ if (file_table == NULL) {
+ return NULL;
+ }
+ combined_key = g_strconcat (key, "/", subkey, NULL);
+ value = g_hash_table_lookup (file_table, combined_key);
+ g_free (combined_key);
+ if (value == NULL) {
+ return NULL;
+ }
+
+ /* Copy the list and return it. */
+ g_assert (value->is_list);
+ return nautilus_g_str_list_copy (value->value.string_list);
+}
+
+static guint
+str_or_null_hash (gconstpointer str)
+{
+ return str == NULL ? 0 : g_str_hash (str);
+}
+
static gboolean
-set_metadata_eat_parameters (NautilusDirectory *directory,
- MetadataKey *key,
- MetadataValue *value)
+str_or_null_equal (gconstpointer str_a, gconstpointer str_b)
{
- gboolean changed;
- MetadataKey *destroy_key;
- MetadataValue *destroy_value;
- gpointer old_key, old_value;
+ if (str_a == NULL) {
+ return str_b == NULL;
+ }
+ if (str_b == NULL) {
+ return FALSE;
+ }
+ return g_str_equal (str_a, str_b);
+}
- destroy_key = key;
- destroy_value = value;
+static gboolean
+set_metadata_eat_value (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *subkey,
+ MetadataValue *value)
+{
+ GHashTable *directory_table, *file_table;
+ gboolean found, changed;
+ char *combined_key;
+ gpointer old_key, old_value;
- if (!directory->details->metafile_read) {
+ if (directory->details->metafile_read) {
+ changed = set_metadata_in_metafile
+ (directory, file_name, key, subkey, value);
+ metadata_value_destroy (value);
+ } else {
/* Create hash table only when we need it.
* We'll destroy it when we finish reading the metafile.
*/
- if (directory->details->metadata_changes == NULL) {
- directory->details->metadata_changes =
- g_hash_table_new (metadata_key_hash,
- metadata_key_hash_equal);
+ directory_table = directory->details->metadata_changes;
+ if (directory_table == NULL) {
+ directory_table = g_hash_table_new
+ (str_or_null_hash, str_or_null_equal);
+ directory->details->metadata_changes = directory_table;
+ }
+ file_table = g_hash_table_lookup (directory_table, file_name);
+ if (file_table == NULL) {
+ file_table = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (directory_table,
+ g_strdup (file_name), file_table);
}
- /* Put the change into the hash.
- * Delete the old change.
- */
- if (g_hash_table_lookup_extended (directory->details->metadata_changes,
- key,
- &old_key,
- &old_value)) {
- changed = !metadata_value_equal (old_value, value);
- if (changed) {
- destroy_key = old_key;
- destroy_value = old_value;
- }
+ /* Find the entry in the hash table. */
+ if (subkey == NULL) {
+ combined_key = g_strdup (key);
} else {
+ combined_key = g_strconcat (key, "/", subkey, NULL);
+ }
+ found = g_hash_table_lookup_extended
+ (file_table, combined_key, &old_key, &old_value);
+ g_free (combined_key);
+
+ /* Put the change into the hash. Delete the old change. */
+ if (!found) {
+ old_key = NULL;
+ old_value = NULL;
changed = TRUE;
- destroy_key = NULL;
- destroy_value = NULL;
+ } else {
+ changed = !metadata_value_equal (old_value, value);
}
-
if (changed) {
- g_hash_table_insert (directory->details->metadata_changes,
- key, value);
+ g_hash_table_insert (file_table, combined_key, value);
+ g_free (old_key);
+ metadata_value_destroy (old_value);
+ } else {
+ g_free (combined_key);
+ metadata_value_destroy (value);
}
- } else {
- changed = set_metadata_in_metafile (directory, key, value);
}
- metadata_key_destroy (destroy_key);
- metadata_value_destroy (destroy_value);
-
return changed;
}
static void
-free_metadata_changes_hash_table_entry (gpointer key, gpointer value, gpointer user_data)
+free_file_table_entry (gpointer key, gpointer value, gpointer user_data)
{
g_assert (user_data == NULL);
- metadata_key_destroy (key);
+
+ g_free (key);
metadata_value_destroy (value);
}
static void
-destroy_metadata_changes_hash_table (GHashTable *table)
+free_directory_table_entry (gpointer key, gpointer value, gpointer user_data)
+{
+ g_assert (user_data == NULL);
+ g_assert (value != NULL);
+
+ g_free (key);
+ g_hash_table_foreach (value, free_file_table_entry, NULL);
+ g_hash_table_destroy (value);
+}
+
+static void
+destroy_metadata_changes_hash_table (GHashTable *directory_table)
{
- if (table == NULL) {
+ if (directory_table == NULL) {
return;
}
-
- g_hash_table_foreach (table,
- free_metadata_changes_hash_table_entry,
- NULL);
- g_hash_table_destroy (table);
+ g_hash_table_foreach (directory_table, free_directory_table_entry, NULL);
+ g_hash_table_destroy (directory_table);
}
void
@@ -662,45 +540,149 @@ nautilus_directory_metafile_destroy (NautilusDirectory *directory)
destroy_metadata_changes_hash_table (directory->details->metadata_changes);
}
+char *
+nautilus_directory_get_metadata (NautilusDirectory *directory,
+ const char *key,
+ const char *default_metadata)
+{
+ g_return_val_if_fail (key != NULL, g_strdup (default_metadata));
+ g_return_val_if_fail (key[0] != '\0', g_strdup (default_metadata));
+
+ /* It's legal to call this on a NULL directory. */
+ if (directory == NULL) {
+ return g_strdup (default_metadata);
+ }
+
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), g_strdup (default_metadata));
+
+ if (directory->details->metafile_read) {
+ return get_metadata_string_from_metafile
+ (directory, NULL, key, default_metadata);
+ } else {
+ return get_metadata_string_from_table
+ (directory, NULL, key, default_metadata);
+ }
+}
+
+char *
+nautilus_directory_get_file_metadata (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *default_metadata)
+{
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE);
+ g_return_val_if_fail (file_name != NULL, FALSE);
+ g_return_val_if_fail (file_name[0] != '\0', FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (key[0] != '\0', FALSE);
+
+ if (directory->details->metafile_read) {
+ return get_metadata_string_from_metafile
+ (directory, file_name, key, default_metadata);
+ } else {
+ return get_metadata_string_from_table
+ (directory, file_name, key, default_metadata);
+ }
+}
+
+
+GList *
+nautilus_directory_get_metadata_list (NautilusDirectory *directory,
+ const char *list_key,
+ const char *list_subkey)
+{
+ g_return_val_if_fail (list_key != NULL, NULL);
+ g_return_val_if_fail (list_key[0] != '\0', NULL);
+ g_return_val_if_fail (list_subkey != NULL, NULL);
+ g_return_val_if_fail (list_subkey[0] != '\0', NULL);
+
+ /* It's legal to call this on a NULL directory. */
+ if (directory == NULL) {
+ return NULL;
+ }
+
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
+
+ if (directory->details->metafile_read) {
+ return get_metadata_list_from_metafile
+ (directory, NULL, list_key, list_subkey);
+ } else {
+ return get_metadata_list_from_table
+ (directory, NULL, list_key, list_subkey);
+ }
+}
+
+GList *
+nautilus_directory_get_file_metadata_list (NautilusDirectory *directory,
+ const char *file_name,
+ const char *list_key,
+ const char *list_subkey)
+{
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
+ g_return_val_if_fail (file_name != NULL, NULL);
+ g_return_val_if_fail (file_name[0] != '\0', NULL);
+ g_return_val_if_fail (list_key != NULL, NULL);
+ g_return_val_if_fail (list_key[0] != '\0', NULL);
+ g_return_val_if_fail (list_subkey != NULL, NULL);
+ g_return_val_if_fail (list_subkey[0] != '\0', NULL);
+
+ if (directory->details->metafile_read) {
+ return get_metadata_list_from_metafile
+ (directory, file_name, list_key, list_subkey);
+ } else {
+ return get_metadata_list_from_table
+ (directory, file_name, list_key, list_subkey);
+ }
+}
+
void
nautilus_directory_set_metadata (NautilusDirectory *directory,
- const char *key_string,
+ const char *key,
const char *default_metadata,
const char *metadata)
{
- MetadataKey *key;
MetadataValue *value;
g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
- g_return_if_fail (key_string != NULL);
- g_return_if_fail (key_string[0] != '\0');
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (key[0] != '\0');
- key = metadata_key_new (NULL, key_string, NULL);
- value = metadata_value_new (default_metadata, metadata);
- if (set_metadata_eat_parameters (directory, key, value)) {
- nautilus_directory_emit_metadata_changed (directory);
+ if (directory->details->metafile_read) {
+ if (set_metadata_string_in_metafile (directory, NULL, key,
+ default_metadata, metadata)) {
+ nautilus_directory_request_write_metafile (directory);
+ }
+ } else {
+ value = metadata_value_new (default_metadata, metadata);
+ if (set_metadata_eat_value (directory, NULL, key, NULL, value)) {
+ nautilus_directory_emit_metadata_changed (directory);
+ }
}
}
gboolean
nautilus_directory_set_file_metadata (NautilusDirectory *directory,
const char *file_name,
- const char *key_string,
+ const char *key,
const char *default_metadata,
const char *metadata)
{
- MetadataKey *key;
MetadataValue *value;
g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE);
g_return_val_if_fail (file_name != NULL, FALSE);
g_return_val_if_fail (file_name[0] != '\0', FALSE);
- g_return_val_if_fail (key_string != NULL, FALSE);
- g_return_val_if_fail (key_string[0] != '\0', FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (key[0] != '\0', FALSE);
- key = metadata_key_new (file_name, key_string, NULL);
- value = metadata_value_new (default_metadata, metadata);
- return set_metadata_eat_parameters (directory, key, value);
+ if (directory->details->metafile_read) {
+ return set_metadata_string_in_metafile (directory, file_name, key,
+ default_metadata, metadata);
+ } else {
+ value = metadata_value_new (default_metadata, metadata);
+ return set_metadata_eat_value (directory, file_name,
+ key, NULL, value);
+ }
}
gboolean
@@ -710,7 +692,6 @@ nautilus_directory_set_file_metadata_list (NautilusDirectory *directory,
const char *list_subkey,
GList *list)
{
- MetadataKey *key;
MetadataValue *value;
g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE);
@@ -721,7 +702,193 @@ nautilus_directory_set_file_metadata_list (NautilusDirectory *directory,
g_return_val_if_fail (list_subkey != NULL, FALSE);
g_return_val_if_fail (list_subkey[0] != '\0', FALSE);
- key = metadata_key_new (file_name, list_key, list_subkey);
- value = metadata_value_new_list (list);
- return set_metadata_eat_parameters (directory, key, value);
+ if (directory->details->metafile_read) {
+ return set_metadata_list_in_metafile (directory, file_name,
+ list_key, list_subkey, list);
+ } else {
+ value = metadata_value_new_list (list);
+ return set_metadata_eat_value (directory, file_name,
+ list_key, list_subkey, value);
+ }
+}
+
+void
+nautilus_directory_update_file_metadata (NautilusDirectory *directory,
+ const char *old_file_name,
+ const char *new_file_name)
+{
+ xmlNode *file_node;
+ GHashTable *directory_table;
+ gboolean found;
+ gpointer key, value;
+
+ if (directory->details->metafile_read) {
+ /* Move data in XML document if present. */
+ file_node = get_file_node (directory, old_file_name, FALSE);
+ if (file_node != NULL) {
+ xmlSetProp (file_node, "NAME", new_file_name);
+ nautilus_directory_request_write_metafile (directory);
+ }
+ } else {
+ /* Move data in hash table. */
+ directory_table = directory->details->metadata_changes;
+ found = g_hash_table_lookup_extended
+ (directory_table, old_file_name, &key, &value);
+ if (found) {
+ g_hash_table_remove (directory_table, old_file_name);
+ g_free (key);
+ g_hash_table_insert (directory_table,
+ g_strdup (new_file_name), value);
+ }
+ }
+}
+
+typedef struct {
+ NautilusDirectory *directory;
+ const char *file_name;
+} ChangeContext;
+
+static void
+apply_one_change (gpointer key, gpointer value, gpointer callback_data)
+{
+ ChangeContext *context;
+ const char *hash_table_key, *separator, *metadata_key, *subkey;
+ char *key_prefix;
+
+ g_assert (key != NULL);
+ g_assert (value != NULL);
+ g_assert (callback_data != NULL);
+
+ context = callback_data;
+
+ /* Break the key in half. */
+ hash_table_key = key;
+ separator = strchr (hash_table_key, '/');
+ if (separator == NULL) {
+ key_prefix = NULL;
+ metadata_key = hash_table_key;
+ subkey = NULL;
+ } else {
+ key_prefix = g_strndup (hash_table_key, separator - hash_table_key);
+ metadata_key = key_prefix;
+ subkey = separator + 1;
+ }
+
+ /* Set the metadata. */
+ set_metadata_in_metafile (context->directory, context->file_name,
+ metadata_key, subkey, value);
+ g_free (key_prefix);
+}
+
+static void
+apply_file_changes (gpointer key, gpointer value, gpointer callback_data)
+{
+ ChangeContext context;
+
+ g_assert (value != NULL);
+ g_assert (NAUTILUS_IS_DIRECTORY (callback_data));
+
+ context.directory = callback_data;
+ context.file_name = key;
+
+ g_hash_table_foreach (value, apply_one_change, &context);
+ g_hash_table_destroy (value);
+}
+
+void
+nautilus_directory_metafile_apply_pending_changes (NautilusDirectory *directory)
+{
+ if (directory->details->metadata_changes == NULL) {
+ return;
+ }
+ g_hash_table_foreach (directory->details->metadata_changes,
+ apply_file_changes, directory);
+ g_hash_table_destroy (directory->details->metadata_changes);
+ directory->details->metadata_changes = NULL;
+}
+
+gboolean
+nautilus_directory_get_boolean_metadata (NautilusDirectory *directory,
+ const char *key,
+ gboolean default_metadata)
+{
+ char *result_as_string;
+ gboolean result;
+
+ result_as_string = nautilus_directory_get_metadata
+ (directory, key,
+ default_metadata ? "true" : "false");
+
+ g_strdown (result_as_string);
+ if (strcmp (result_as_string, "true") == 0) {
+ result = TRUE;
+ } else if (strcmp (result_as_string, "false") == 0) {
+ result = FALSE;
+ } else {
+ if (result_as_string != NULL) {
+ g_warning ("boolean metadata with value other than true or false");
+ }
+ result = default_metadata;
+ }
+
+ g_free (result_as_string);
+ return result;
+}
+
+void
+nautilus_directory_set_boolean_metadata (NautilusDirectory *directory,
+ const char *key,
+ gboolean default_metadata,
+ gboolean metadata)
+{
+ nautilus_directory_set_metadata
+ (directory, key,
+ default_metadata ? "true" : "false",
+ metadata ? "true" : "false");
+}
+
+int
+nautilus_directory_get_integer_metadata (NautilusDirectory *directory,
+ const char *key,
+ int default_metadata)
+{
+ char *result_as_string;
+ char *default_as_string;
+ int result;
+
+ default_as_string = g_strdup_printf ("%d", default_metadata);
+ result_as_string = nautilus_directory_get_metadata
+ (directory, key, default_as_string);
+
+ /* Handle oddball case of non-existent directory */
+ if (result_as_string == NULL) {
+ result = default_metadata;
+ } else {
+ result = atoi (result_as_string);
+ g_free (result_as_string);
+ }
+
+ g_free (default_as_string);
+ return result;
+
+}
+
+void
+nautilus_directory_set_integer_metadata (NautilusDirectory *directory,
+ const char *key,
+ int default_metadata,
+ int metadata)
+{
+ char *value_as_string;
+ char *default_as_string;
+
+ value_as_string = g_strdup_printf ("%d", metadata);
+ default_as_string = g_strdup_printf ("%d", default_metadata);
+
+ nautilus_directory_set_metadata
+ (directory, key,
+ default_as_string, value_as_string);
+
+ g_free (value_as_string);
+ g_free (default_as_string);
}
diff --git a/libnautilus-private/nautilus-directory-metafile.h b/libnautilus-private/nautilus-directory-metafile.h
index 4ee98f14e..cbd37fe99 100644
--- a/libnautilus-private/nautilus-directory-metafile.h
+++ b/libnautilus-private/nautilus-directory-metafile.h
@@ -25,25 +25,29 @@
#include "nautilus-directory.h"
#include <tree.h>
-char * nautilus_directory_get_file_metadata (NautilusDirectory *directory,
- const char *file_name,
- const char *key,
- const char *default_metadata);
-GList * nautilus_directory_get_file_metadata_list (NautilusDirectory *directory,
- const char *file_name,
- const char *list_key,
- const char *list_subkey);
-gboolean nautilus_directory_set_file_metadata (NautilusDirectory *directory,
- const char *file_name,
- const char *key,
- const char *default_metadata,
- const char *metadata);
-gboolean nautilus_directory_set_file_metadata_list (NautilusDirectory *directory,
- const char *file_name,
- const char *list_key,
- const char *list_subkey,
- GList *list);
-xmlNode *nautilus_directory_get_file_metadata_node (NautilusDirectory *directory,
- const char *file_name,
- gboolean create);
-void nautilus_directory_metafile_destroy (NautilusDirectory *directory);
+/* Interface for file metadata. */
+char * nautilus_directory_get_file_metadata (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *default_metadata);
+GList * nautilus_directory_get_file_metadata_list (NautilusDirectory *directory,
+ const char *file_name,
+ const char *list_key,
+ const char *list_subkey);
+gboolean nautilus_directory_set_file_metadata (NautilusDirectory *directory,
+ const char *file_name,
+ const char *key,
+ const char *default_metadata,
+ const char *metadata);
+gboolean nautilus_directory_set_file_metadata_list (NautilusDirectory *directory,
+ const char *file_name,
+ const char *list_key,
+ const char *list_subkey,
+ GList *list);
+void nautilus_directory_update_file_metadata (NautilusDirectory *directory,
+ const char *old_file_name,
+ const char *new_file_name);
+
+/* Interface for housekeeping. */
+void nautilus_directory_metafile_apply_pending_changes (NautilusDirectory *directory);
+void nautilus_directory_metafile_destroy (NautilusDirectory *directory);
diff --git a/libnautilus-private/nautilus-directory-private.h b/libnautilus-private/nautilus-directory-private.h
index 744f55837..1203fa135 100644
--- a/libnautilus-private/nautilus-directory-private.h
+++ b/libnautilus-private/nautilus-directory-private.h
@@ -32,8 +32,6 @@
#include "nautilus-file.h"
-#define METADATA_NODE_NAME_FOR_FILE_NAME "NAME"
-
typedef struct MetafileReadState MetafileReadState;
typedef struct MetafileWriteState MetafileWriteState;
typedef struct TopLeftTextReadState TopLeftTextReadState;
diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c
index dbe91c5fc..5d0bcba89 100644
--- a/libnautilus-private/nautilus-file.c
+++ b/libnautilus-private/nautilus-file.c
@@ -520,20 +520,10 @@ file_operation_state_complete (FileOperationState *state,
static void
rename_update_info_and_metafile (FileOperationState *state)
{
- xmlNode *file_node;
-
- file_node = nautilus_directory_get_file_metadata_node
+ nautilus_directory_update_file_metadata
(state->file->details->directory,
state->file->details->info->name,
- FALSE);
-
- if (file_node != NULL) {
- xmlSetProp (file_node,
- METADATA_NODE_NAME_FOR_FILE_NAME,
- state->new_name);
- nautilus_directory_request_write_metafile
- (state->file->details->directory);
- }
+ state->new_name);
g_free (state->file->details->info->name);
state->file->details->info->name = g_strdup (state->new_name);
diff --git a/libnautilus-private/nautilus-glib-extensions.c b/libnautilus-private/nautilus-glib-extensions.c
index f5a15577f..06f791402 100644
--- a/libnautilus-private/nautilus-glib-extensions.c
+++ b/libnautilus-private/nautilus-glib-extensions.c
@@ -302,8 +302,6 @@ nautilus_g_ptr_array_sort (GPtrArray *array,
NautilusCompareFunction sort_function,
void *context)
{
- /* FIXME: Is there a good reason this doesn't use qsort? */
-
size_t count, r, l, j;
void **base, **lp, **rp, **ip, **jp, **tmpp;
void *tmp;
diff --git a/libnautilus-private/nautilus-string.h b/libnautilus-private/nautilus-string.h
index 0c40509c5..59bae3d69 100644
--- a/libnautilus-private/nautilus-string.h
+++ b/libnautilus-private/nautilus-string.h
@@ -35,41 +35,41 @@
/* NULL is allowed for all the str parameters to these functions. */
/* Versions of basic string functions that allow NULL. */
-size_t nautilus_strlen (const char *string);
-char * nautilus_strchr (const char *haystack,
- char needle);
-int nautilus_strcmp (const char *string_a,
- const char *string_b);
+size_t nautilus_strlen (const char *string);
+char * nautilus_strchr (const char *haystack,
+ char needle);
+int nautilus_strcmp (const char *string_a,
+ const char *string_b);
/* GCompareFunc version. */
-int nautilus_str_compare (gconstpointer string_a,
- gconstpointer string_b);
+int nautilus_str_compare (gconstpointer string_a,
+ gconstpointer string_b);
/* Versions of basic string functions that free their parameters. */
-int nautilus_eat_strcmp (char *string_a_gets_freed,
- const char *string_b);
+int nautilus_eat_strcmp (char *string_a_gets_freed,
+ const char *string_b);
/* Other basic string operations. */
-gboolean nautilus_str_has_prefix (const char *target,
- const char *prefix);
-char * nautilus_str_get_prefix (const char *source,
- const char *delimiter);
-gboolean nautilus_str_has_suffix (const char *target,
- const char *suffix);
-char * nautilus_str_strip_chr (const char *string,
- char remove_this);
-char * nautilus_str_strip_trailing_chr (const char *string,
- char remove_this);
+gboolean nautilus_str_has_prefix (const char *target,
+ const char *prefix);
+char * nautilus_str_get_prefix (const char *source,
+ const char *delimiter);
+gboolean nautilus_str_has_suffix (const char *target,
+ const char *suffix);
+char * nautilus_str_strip_chr (const char *string,
+ char remove_this);
+char * nautilus_str_strip_trailing_chr (const char *string,
+ char remove_this);
/* Conversions to and from strings. */
-gboolean nautilus_str_to_int (const char *string,
- int *integer);
-gboolean nautilus_eat_str_to_int (char *string_gets_freed,
- int *integer);
+gboolean nautilus_str_to_int (const char *string,
+ int *integer);
+gboolean nautilus_eat_str_to_int (char *string_gets_freed,
+ int *integer);
/* Escape function for slashes */
-char * nautilus_str_escape_slashes (const char *string);
+char * nautilus_str_escape_slashes (const char *string);
/* Escape function for '_' character. */
-char * nautilus_str_double_underscores (const char *string);
+char * nautilus_str_double_underscores (const char *string);
#endif /* NAUTILUS_STRING_H */