summaryrefslogtreecommitdiff
path: root/libnautilus-extensions/nautilus-directory-async.c
diff options
context:
space:
mode:
authorMaciej Stachowiak <mstachow@src.gnome.org>2000-11-30 01:39:44 +0000
committerMaciej Stachowiak <mstachow@src.gnome.org>2000-11-30 01:39:44 +0000
commitbf02801cba31e933617e5c0af3264cc5a2576ed2 (patch)
treeb2717d5299683330f5df76af9ae973a161d5aae1 /libnautilus-extensions/nautilus-directory-async.c
parent4301017d79456f58642d88c3b0b5508eb09f8c38 (diff)
downloadnautilus-bf02801cba31e933617e5c0af3264cc5a2576ed2.tar.gz
reviewed by: Darin Adler <darin@eazel.com>
Fixed bugs 4385 (Nautilus doesn't gracefully handle deleting in-use image file), 3240 (reloading a directory doesn't update directory counts of the entries) and 4683 (embedded text on icon isn't updated when text changes) by implementing forgetting of file attributes and using it when appropriate. Also fixed various other bugs cought by testing of these fixes or reading the code. * libnautilus-extensions/nautilus-file.c: (nautilus_file_forget_attributes): New function that makes the file forget the specified attributes, including cancelling possible in-progress I/O for them, and kicking off new I/O if anyone is monitoring any of the attributes or has a pending call_when_ready. (nautilus_file_forget_attributes_internal): Forget all attributes of this file, *not* including cancelling in-progress I/O, or kicking off new I/O. This is for the benefit of NautilusDirectory being able to forget the attributes of all files it is monitoring at one go. (nautilus_file_forget_all_attributes): Forget all attributes of this file, including cancelling in-progress I/O, and kicking off new I/O. (forget_directory_count, forget_deep_counts, forget_mime_list, forget_top_left_text, forget_file_info, forget_activation_uri): Helper functions to forget individual attributes. (nautilus_file_forget_activation_uri): Removed as obsolete. (destroy): use `nautilus_g_list_free_deep' to free the mime list. * libnautilus-extensions/nautilus-directory-notify.h: Remove prototype for `nautilus_file_forget_activation_uri'. * libnautilus-extensions/nautilus-file-private.h: Prototype `nautilus_file_forget_attributes_internal'. * libnautilus-extensions/nautilus-file.h: `nautilus_file_forget_attributes' and `nautilus_file_forget_all_attributes'. * libnautilus-extensions/nautilus-link.c (nautilus_link_local_set_link_uri): Use `nautilus_file_forget_attributes', not `nautilus_file_forget_activation_uri' to ensure reload of the activation URI. (forget_file_activation_uri): Helper function for the above. * libnautilus-extensions/nautilus-directory-async.c (nautilus_directory_cancel_loading_file_attributes): Function to cancel in-progress I/O for a given set of attributes but only if it is in progress for the specified file. This function is used to implement part of `nautilus_file_forget_attributes'. (cancel_directory_count_for_file, cancel_deep_counts_for_file, cancel_mime_list_for_file, cancel_top_left_text_for_file, cancel_file_info_for_file, cancel_activation_uri_for_file): Helper functions for the above. (nautilus_directory_force_reload): Add a `file_attributes' argument and make sure to forget the specified attributes. Forgetting the attributes fixes bugs 3240 and 4683. (nautilus_directory_forget_file_attributes): Function to forget the specified attributes for all files. It makes sure to only cancel and kick off new I/O once. (cancel_loading_attributes): helper function for the above that cancels in-progress loads for the specified attributes, regardless of for what file. (request_is_satisfied): The request is not satisfied if the request calls for top left text and the file lacks it. (top_left_read_callback): Set 1got_top_left_text' field of the NautilusFile to TRUE. This problem was masked by the problem with `request_is_satisfied' fixed above. (set_up_request_by_file_attributes): Make sure to request the file_info as well if top left text is requested, since applicability of top left text depends on the mime type. (get_info_callback): Mark the file gone if we get GNOME_VFS_ERROR_NOT_FOUND; we can only get this error for files gnome-vfs should know about but that do not exist. This is needed to detect files that are removed on a reload. * libnautilus-extensions/nautilus-directory-private.h: Update prototype for `nautilus_directory_force_reload'; Prototype `nautilus_directory_cancel_loading_file_attributes' * libnautilus-extensions/nautilus-vfs-directory.c (vfs_file_monitor_add): Pass the file attributes to `nautilus_directory_force_reload' since it now wants them. * src/nautilus-window-manage-views.c (viewed_file_changed_callback): Cancel location change before closing the window, since detecting the file is gone is now likely to happen in the middle of an in-progress reload, and we get crashes if this is not done. (nautilus_window_begin_location_change): If we're doing a reload, forget all file attributes of the NautilusFile for the currently viewed location. This is to make sure we detect if the file is gone, and also update the sidebar panel icon and other info appropriately. This fixes bug 4385.
Diffstat (limited to 'libnautilus-extensions/nautilus-directory-async.c')
-rw-r--r--libnautilus-extensions/nautilus-directory-async.c282
1 files changed, 276 insertions, 6 deletions
diff --git a/libnautilus-extensions/nautilus-directory-async.c b/libnautilus-extensions/nautilus-directory-async.c
index 40f43cc1f..e286a1df0 100644
--- a/libnautilus-extensions/nautilus-directory-async.c
+++ b/libnautilus-extensions/nautilus-directory-async.c
@@ -128,6 +128,10 @@ static gboolean request_is_satisfied (NautilusDirectory *directory,
NautilusFile *file,
Request *request);
+static void cancel_loading_attributes (NautilusDirectory *directory,
+ GList *file_attributes);
+
+
/* Some helpers for case-insensitive strings.
* Move to nautilus-glib-extensions?
*/
@@ -1007,10 +1011,6 @@ set_up_request_by_file_attributes (Request *request,
(file_attributes,
NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_MIME_TYPES,
nautilus_str_compare) != NULL;
- request->top_left_text = g_list_find_custom
- (file_attributes,
- NAUTILUS_FILE_ATTRIBUTE_TOP_LEFT_TEXT,
- nautilus_str_compare) != NULL;
request->file_info = g_list_find_custom
(file_attributes,
NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE,
@@ -1023,6 +1023,14 @@ set_up_request_by_file_attributes (Request *request,
(file_attributes,
NAUTILUS_FILE_ATTRIBUTE_FILE_TYPE,
nautilus_str_compare) != NULL;
+
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_TOP_LEFT_TEXT,
+ nautilus_str_compare) != NULL) {
+ request->top_left_text = TRUE;
+ request->file_info = TRUE;
+ }
+
if (g_list_find_custom (file_attributes,
NAUTILUS_FILE_ATTRIBUTE_ACTIVATION_URI,
nautilus_str_compare) != NULL) {
@@ -1920,7 +1928,13 @@ request_is_satisfied (NautilusDirectory *directory,
return FALSE;
}
}
-
+
+ if (request->top_left_text) {
+ if (has_problem (directory, file, lacks_top_left)) {
+ return FALSE;
+ }
+ }
+
if (request->deep_count) {
if (has_problem (directory, file, lacks_deep_count)) {
return FALSE;
@@ -2132,9 +2146,32 @@ nautilus_directory_invalidate_counts (NautilusDirectory *directory)
}
}
+static void
+nautilus_directory_forget_file_attributes (NautilusDirectory *directory,
+ GList *file_attributes)
+{
+ GList *node;
+
+ cancel_loading_attributes (directory, file_attributes);
+
+ for (node = directory->details->file_list; node != NULL; node = node->next) {
+ nautilus_file_forget_attributes_internal (NAUTILUS_FILE (p->data),
+ file_attributes);
+ }
+
+ if (directory->details->as_file != NULL) {
+ nautilus_file_forget_attributes_internal (directory->details->as_file,
+ file_attributes);
+ }
+}
+
void
-nautilus_directory_force_reload (NautilusDirectory *directory)
+nautilus_directory_force_reload (NautilusDirectory *directory,
+ GList *file_attributes)
{
+ /* forget attributes that are getting reloaded for all files */
+ nautilus_directory_forget_file_attributes (directory, file_attributes);
+
/* Start a new directory load. */
file_list_cancel (directory);
directory->details->directory_loaded = FALSE;
@@ -2690,6 +2727,8 @@ top_left_read_callback (GnomeVFSResult result,
directory->details->top_left_read_state->file->details->top_left_text =
nautilus_extract_top_left_text (file_contents, bytes_read);
+ directory->details->top_left_read_state->file->details->got_top_left_text = TRUE;
+
nautilus_file_changed (directory->details->top_left_read_state->file);
g_free (file_contents);
@@ -2776,15 +2815,29 @@ get_info_callback (GnomeVFSAsyncHandle *handle,
directory->details->get_info_file = NULL;
directory->details->get_info_in_progress = NULL;
+
+ /* ref here because we might be removing the last ref when we
+ * mark the file gone below, but we need to keep a ref at
+ * least long enough to send the change notification.
+ */
+ nautilus_file_ref (get_info_file);
result = results->data;
if (result->result != GNOME_VFS_OK) {
get_info_file->details->get_info_failed = TRUE;
get_info_file->details->get_info_error = result->result;
+ if (result->result == GNOME_VFS_ERROR_NOT_FOUND) {
+ /* mark file as gone */
+
+ get_info_file->details->is_gone = TRUE;
+ nautilus_directory_remove_file (directory, get_info_file);
+ }
} else {
nautilus_file_update_info (get_info_file, result->file_info);
}
+
nautilus_file_changed (get_info_file);
+ nautilus_file_unref (get_info_file);
async_job_end (directory, "file info");
nautilus_directory_async_state_changed (directory);
@@ -3084,3 +3137,220 @@ nautilus_directory_cancel (NautilusDirectory *directory)
/* Check if any directories should wake up. */
async_job_wake_up ();
}
+
+
+static void
+cancel_directory_count_for_file (NautilusDirectory *directory,
+ NautilusFile *file)
+{
+ if (directory->details->count_file == file) {
+ directory_count_cancel (directory);
+ }
+}
+
+
+static void
+cancel_deep_counts_for_file (NautilusDirectory *directory,
+ NautilusFile *file)
+{
+ if (directory->details->deep_count_file == file) {
+ deep_count_cancel (directory);
+ }
+}
+
+
+static void
+cancel_mime_list_for_file (NautilusDirectory *directory,
+ NautilusFile *file)
+{
+ if (directory->details->mime_list_file == file) {
+ mime_list_cancel (directory);
+ }
+}
+
+static void
+cancel_top_left_text_for_file (NautilusDirectory *directory,
+ NautilusFile *file)
+{
+ if (directory->details->top_left_read_state != NULL &&
+ directory->details->top_left_read_state->file == file) {
+ top_left_cancel (directory);
+ }
+}
+
+static void
+cancel_file_info_for_file (NautilusDirectory *directory,
+ NautilusFile *file)
+{
+ if (directory->details->get_info_file == file) {
+ file_info_cancel (directory);
+ }
+}
+
+static void
+cancel_activation_uri_for_file (NautilusDirectory *directory,
+ NautilusFile *file)
+{
+ if (directory->details->activation_uri_read_state != NULL &&
+ directory->details->activation_uri_read_state->file == file) {
+ activation_uri_cancel (directory);
+ }
+}
+
+
+static void
+cancel_loading_attributes (NautilusDirectory *directory,
+ GList *file_attributes)
+{
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT,
+ nautilus_str_compare) != NULL) {
+ directory_count_cancel (directory);
+ }
+
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_DEEP_COUNTS,
+ nautilus_str_compare) != NULL) {
+ deep_count_cancel (directory);
+ }
+
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_MIME_TYPES,
+ nautilus_str_compare) != NULL) {
+ mime_list_cancel (directory);
+ }
+
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_TOP_LEFT_TEXT,
+ nautilus_str_compare) != NULL) {
+ /* clear file info, since applicability of top left
+ * text depends on it.
+ */
+ file_info_cancel (directory);
+
+ /* cancel top left text */
+ top_left_cancel (directory);
+ }
+
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE,
+ nautilus_str_compare) != NULL ||
+ g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_FILE_TYPE,
+ nautilus_str_compare) != NULL ||
+ g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_IS_DIRECTORY,
+ nautilus_str_compare) != NULL) {
+ file_info_cancel (directory);
+ }
+
+
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_ACTIVATION_URI,
+ nautilus_str_compare) != NULL) {
+
+ /* clear file info, since applicability of activation
+ * URI depends on it
+ */
+ file_info_cancel (directory);
+
+ /* cancel activation URI */
+ file_info_cancel (directory);
+ }
+
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_METADATA,
+ nautilus_str_compare) != NULL ||
+ /* FIXME bugzilla.eazel.com 2435:
+ * Some file attributes are really pieces of metadata.
+ * This is a confusing/broken design, since other metadata
+ * pieces are handled separately from file attributes...
+ */
+ g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_CUSTOM_ICON,
+ nautilus_str_compare) != NULL) {
+ /* FIXME: implement cancelling metadata when we
+ implement forgetting metadata */
+ }
+}
+
+void
+nautilus_directory_cancel_loading_file_attributes (NautilusDirectory *directory,
+ NautilusFile *file,
+ GList *file_attributes)
+{
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT,
+ nautilus_str_compare) != NULL) {
+ cancel_directory_count_for_file (directory, file);
+ }
+
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_DEEP_COUNTS,
+ nautilus_str_compare) != NULL) {
+ cancel_deep_counts_for_file (directory, file);
+ }
+
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_MIME_TYPES,
+ nautilus_str_compare) != NULL) {
+ cancel_mime_list_for_file (directory, file);
+ }
+
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_TOP_LEFT_TEXT,
+ nautilus_str_compare) != NULL) {
+ /* clear file info, since applicability of top left
+ * text depends on it.
+ */
+ cancel_file_info_for_file (directory, file);
+
+ /* cancel top left text */
+ cancel_top_left_text_for_file (directory, file);
+ }
+
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE,
+ nautilus_str_compare) != NULL ||
+ g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_FILE_TYPE,
+ nautilus_str_compare) != NULL ||
+ g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_IS_DIRECTORY,
+ nautilus_str_compare) != NULL) {
+ cancel_file_info_for_file (directory, file);
+ }
+
+
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_ACTIVATION_URI,
+ nautilus_str_compare) != NULL) {
+
+ /* clear file info, since applicability of activation
+ * URI depends on it
+ */
+ cancel_file_info_for_file (directory, file);
+
+ /* cancel activation URI */
+ cancel_activation_uri_for_file (directory, file);
+ }
+
+ if (g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_METADATA,
+ nautilus_str_compare) != NULL ||
+ /* FIXME bugzilla.eazel.com 2435:
+ * Some file attributes are really pieces of metadata.
+ * This is a confusing/broken design, since other metadata
+ * pieces are handled separately from file attributes...
+ */
+ g_list_find_custom (file_attributes,
+ NAUTILUS_FILE_ATTRIBUTE_CUSTOM_ICON,
+ nautilus_str_compare) != NULL) {
+ /* FIXME: implement cancelling metadata when we
+ implement forgetting metadata */
+ }
+}
+
+
+
+