diff options
author | Maciej Stachowiak <mstachow@src.gnome.org> | 2000-11-30 01:39:44 +0000 |
---|---|---|
committer | Maciej Stachowiak <mstachow@src.gnome.org> | 2000-11-30 01:39:44 +0000 |
commit | bf02801cba31e933617e5c0af3264cc5a2576ed2 (patch) | |
tree | b2717d5299683330f5df76af9ae973a161d5aae1 /libnautilus-extensions/nautilus-directory-async.c | |
parent | 4301017d79456f58642d88c3b0b5508eb09f8c38 (diff) | |
download | nautilus-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.c | 282 |
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 */ + } +} + + + + |