diff options
author | Darin Adler <darin@src.gnome.org> | 2000-05-16 22:36:34 +0000 |
---|---|---|
committer | Darin Adler <darin@src.gnome.org> | 2000-05-16 22:36:34 +0000 |
commit | f135aeadde705baebbe5313e3129aac070583df0 (patch) | |
tree | 5c1304b91657654c2bc6fef27fcd47c22e5f398b /libnautilus-extensions/nautilus-directory-metafile.c | |
parent | 1b44ea3bb0a8d6aea8df07895854a149d5ecf89d (diff) | |
download | nautilus-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.
Diffstat (limited to 'libnautilus-extensions/nautilus-directory-metafile.c')
-rw-r--r-- | libnautilus-extensions/nautilus-directory-metafile.c | 831 |
1 files changed, 499 insertions, 332 deletions
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); } |