From daee7ca55208f6e01db5f5be0839d146e7fb5c18 Mon Sep 17 00:00:00 2001 From: Darin Adler Date: Mon, 15 Jan 2001 23:45:04 +0000 Subject: Fix bug 5557 (Intermittent crash in Nautilus_View_history_changed): * src/nautilus-view-frame.c: (send_history): Added a check for NULL so we don't try to send a NULL history list through the history machinery. Fix bug 5360 ("menthos's Home" string is hard to translate): * src/file-manager/fm-desktop-icon-view.c: (update_home_link_and_delete_copies): Added comment to help translators understand what to do with "%s's Home". Fix bug 5641 ("xfree" does not work with newer versions of RPM 4 headers): * components/services/install/lib/eazel-package-system-rpm3.c: (eazel_package_system_rpm3_packagedata_fill_from_header): Just use "free" instead of "xfree". Fix bug 5631 (Tear-offs of right-click menus don't work): * src/nautilus-shell-ui.xml: * src/file-manager/nautilus-directory-view-ui.xml: * src/file-manager/nautilus-icon-view-ui.xml: Mark popups and submenus of the popups with tearoff="0" so they don't have tear-off menu items. More work on bug 2147 (NautilusFile for trash needs non-empty values for more properties). * libnautilus-extensions/nautilus-file.h: * libnautilus-extensions/nautilus-file.c: (nautilus_file_new_from_relative_uri), (nautilus_file_new_from_info), (nautilus_file_monitor_add), (nautilus_file_monitor_remove), (nautilus_file_get_directory_item_count), (nautilus_file_get_deep_counts), (nautilus_file_check_if_ready), (nautilus_file_call_when_ready), (nautilus_file_cancel_call_when_ready): Put more of the machinery in place to make enough of NautilusFile virtual so that we can implement the trash case. * libnautilus-extensions/nautilus-merged-directory.h: * libnautilus-extensions/nautilus-merged-directory.c: (merged_add_real_directory), (nautilus_merged_directory_add_real_directory), (merged_remove_real_directory), (nautilus_merged_directory_remove_real_directory), (remove_all_real_directories), (nautilus_merged_directory_initialize_class): Make adding and removing directories use signals so we can share this list with the NautilusTrashFile. * libnautilus-extensions/nautilus-trash-file.c: (add_directory_callback), (remove_directory_callback), (nautilus_trash_file_initialize), (trash_destroy): Use a NautilusTrashDirectory object for the list of directories. * libnautilus-extensions/nautilus-vfs-file.c: (vfs_file_monitor_add), (vfs_file_monitor_remove), (vfs_file_call_when_ready), (vfs_file_cancel_call_when_ready), (vfs_file_check_if_ready), (vfs_file_get_item_count), (vfs_file_get_deep_counts), (nautilus_vfs_file_initialize_class): Move the guts of these functions into the "VFS" subclass. Other stuff: * libnautilus-extensions/nautilus-trash-directory.c: (find_directory_start), (find_directory_end), (find_directory_callback), (add_volume), (remove_trash_volume): Fix bug in the recently-added timed-wait, to handle the case where the call is cancelled as well as the case where it succeeds or fails. * src/file-manager/fm-directory-view.c: (zoomable_set_zoom_level_callback): Formatting tweak. * src/nautilus-main.c: (main): Fix the FIXME. --- ChangeLog | 86 ++++++++++++- .../install/lib/eazel-package-system-rpm3.c | 4 +- libnautilus-extensions/nautilus-file.c | 96 +++++---------- libnautilus-extensions/nautilus-file.h | 16 +-- libnautilus-extensions/nautilus-merged-directory.c | 130 ++++++++++++++------ libnautilus-extensions/nautilus-merged-directory.h | 5 + libnautilus-extensions/nautilus-trash-directory.c | 51 +++++--- libnautilus-extensions/nautilus-trash-file.c | 64 +++++++++- libnautilus-extensions/nautilus-vfs-file.c | 134 ++++++++++++++++++++- libnautilus-private/nautilus-file.c | 96 +++++---------- libnautilus-private/nautilus-file.h | 16 +-- libnautilus-private/nautilus-merged-directory.c | 130 ++++++++++++++------ libnautilus-private/nautilus-merged-directory.h | 5 + libnautilus-private/nautilus-trash-directory.c | 51 +++++--- libnautilus-private/nautilus-trash-file.c | 64 +++++++++- libnautilus-private/nautilus-vfs-file.c | 134 ++++++++++++++++++++- src/file-manager/fm-desktop-icon-view.c | 6 + src/file-manager/fm-directory-view.c | 2 +- src/file-manager/nautilus-directory-view-ui.xml | 4 +- src/file-manager/nautilus-icon-view-ui.xml | 2 +- src/nautilus-main.c | 19 ++- src/nautilus-shell-ui.xml | 2 +- src/nautilus-view-frame.c | 3 + 23 files changed, 843 insertions(+), 277 deletions(-) diff --git a/ChangeLog b/ChangeLog index d7cebeaae..261c5efd7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,85 @@ +2001-01-15 Darin Adler + + Fix bug 5557 (Intermittent crash in + Nautilus_View_history_changed): + + * src/nautilus-view-frame.c: (send_history): Added a check for + NULL so we don't try to send a NULL history list through the + history machinery. + + Fix bug 5360 ("menthos's Home" string is hard to translate): + + * src/file-manager/fm-desktop-icon-view.c: + (update_home_link_and_delete_copies): Added comment to help + translators understand what to do with "%s's Home". + + Fix bug 5641 ("xfree" does not work with newer versions of RPM 4 + headers): + + * components/services/install/lib/eazel-package-system-rpm3.c: + (eazel_package_system_rpm3_packagedata_fill_from_header): Just + use "free" instead of "xfree". + + Fix bug 5631 (Tear-offs of right-click menus don't work): + + * src/nautilus-shell-ui.xml: + * src/file-manager/nautilus-directory-view-ui.xml: + * src/file-manager/nautilus-icon-view-ui.xml: + Mark popups and submenus of the popups with tearoff="0" so they + don't have tear-off menu items. + + More work on bug 2147 (NautilusFile for trash needs non-empty + values for more properties). + + * libnautilus-extensions/nautilus-file.h: + * libnautilus-extensions/nautilus-file.c: + (nautilus_file_new_from_relative_uri), + (nautilus_file_new_from_info), (nautilus_file_monitor_add), + (nautilus_file_monitor_remove), + (nautilus_file_get_directory_item_count), + (nautilus_file_get_deep_counts), (nautilus_file_check_if_ready), + (nautilus_file_call_when_ready), + (nautilus_file_cancel_call_when_ready): + Put more of the machinery in place to make enough of NautilusFile + virtual so that we can implement the trash case. + + * libnautilus-extensions/nautilus-merged-directory.h: + * libnautilus-extensions/nautilus-merged-directory.c: + (merged_add_real_directory), + (nautilus_merged_directory_add_real_directory), + (merged_remove_real_directory), + (nautilus_merged_directory_remove_real_directory), + (remove_all_real_directories), + (nautilus_merged_directory_initialize_class): + Make adding and removing directories use signals so we can share + this list with the NautilusTrashFile. + + * libnautilus-extensions/nautilus-trash-file.c: + (add_directory_callback), (remove_directory_callback), + (nautilus_trash_file_initialize), (trash_destroy): + Use a NautilusTrashDirectory object for the list of directories. + + * libnautilus-extensions/nautilus-vfs-file.c: + (vfs_file_monitor_add), (vfs_file_monitor_remove), + (vfs_file_call_when_ready), (vfs_file_cancel_call_when_ready), + (vfs_file_check_if_ready), (vfs_file_get_item_count), + (vfs_file_get_deep_counts), (nautilus_vfs_file_initialize_class): + Move the guts of these functions into the "VFS" subclass. + + Other stuff: + + * libnautilus-extensions/nautilus-trash-directory.c: + (find_directory_start), (find_directory_end), + (find_directory_callback), (add_volume), (remove_trash_volume): + Fix bug in the recently-added timed-wait, to handle the case where + the call is cancelled as well as the case where it succeeds or + fails. + + * src/file-manager/fm-directory-view.c: + (zoomable_set_zoom_level_callback): Formatting tweak. + + * src/nautilus-main.c: (main): Fix the FIXME. + 2001-01-15 Ian McKellar * components/services/inventory-view/nautilus-inventory-config-page @@ -1228,8 +1310,8 @@ * libnautilus-extensions/nautilus-file-operations.c: (handle_transfer_overwrite): - We now check for special link files being overwritten and notify the user - that such an action is not allowed. + We now check for special link files being overwritten and + notify the user that such an action is not allowed. 2001-01-08 Andy Hertzfeld diff --git a/components/services/install/lib/eazel-package-system-rpm3.c b/components/services/install/lib/eazel-package-system-rpm3.c index 08d4c3c93..66168ad19 100644 --- a/components/services/install/lib/eazel-package-system-rpm3.c +++ b/components/services/install/lib/eazel-package-system-rpm3.c @@ -582,8 +582,8 @@ eazel_package_system_rpm3_packagedata_fill_from_header (EazelPackageSystemRpm3 * g_free (paths_copy[index]); } g_free (paths_copy); - xfree (paths); - xfree (names); + free (paths); + free (names); } /* FIXME: bugzill.eaze.com 5262 diff --git a/libnautilus-extensions/nautilus-file.c b/libnautilus-extensions/nautilus-file.c index 9ff2db5f5..c3fc40687 100644 --- a/libnautilus-extensions/nautilus-file.c +++ b/libnautilus-extensions/nautilus-file.c @@ -23,12 +23,13 @@ */ #include -#include "nautilus-file-private.h" -#include "nautilus-file-attributes.h" +#include "nautilus-file.h" #include "nautilus-directory-metafile.h" #include "nautilus-directory-notify.h" #include "nautilus-directory-private.h" +#include "nautilus-file-attributes.h" +#include "nautilus-file-private.h" #include "nautilus-glib-extensions.h" #include "nautilus-global-preferences.h" #include "nautilus-gtk-extensions.h" @@ -36,6 +37,8 @@ #include "nautilus-lib-self-check-functions.h" #include "nautilus-link.h" #include "nautilus-string.h" +#include "nautilus-trash-file.h" +#include "nautilus-vfs-file.h" #include #include #include @@ -138,7 +141,7 @@ nautilus_file_new_from_relative_uri (NautilusDirectory *directory, g_return_val_if_fail (relative_uri != NULL, NULL); g_return_val_if_fail (relative_uri[0] != '\0', NULL); - file = NAUTILUS_FILE (gtk_object_new (NAUTILUS_TYPE_FILE, NULL)); + file = NAUTILUS_FILE (gtk_object_new (NAUTILUS_TYPE_VFS_FILE, NULL)); gtk_object_ref (GTK_OBJECT (file)); gtk_object_sink (GTK_OBJECT (file)); @@ -248,7 +251,7 @@ nautilus_file_new_from_info (NautilusDirectory *directory, g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL); g_return_val_if_fail (info != NULL, NULL); - file = NAUTILUS_FILE (gtk_object_new (NAUTILUS_TYPE_FILE, NULL)); + file = NAUTILUS_FILE (gtk_object_new (NAUTILUS_TYPE_VFS_FILE, NULL)); #ifdef NAUTILUS_FILE_DEBUG_REF printf("%10p ref'd\n", file); @@ -2075,9 +2078,9 @@ nautilus_file_monitor_add (NautilusFile *file, g_return_if_fail (NAUTILUS_IS_FILE (file)); g_return_if_fail (client != NULL); - nautilus_directory_monitor_add_internal - (file->details->directory, file, - client, TRUE, TRUE, attributes); + NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + monitor_add, (file, client, attributes)); } void @@ -2087,8 +2090,9 @@ nautilus_file_monitor_remove (NautilusFile *file, g_return_if_fail (NAUTILUS_IS_FILE (file)); g_return_if_fail (client != NULL); - nautilus_directory_monitor_remove_internal - (file->details->directory, file, client); + NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + monitor_remove, (file, client)); } @@ -2310,16 +2314,9 @@ nautilus_file_get_directory_item_count (NautilusFile *file, return FALSE; } - if (count_unreadable != NULL) { - *count_unreadable = file->details->directory_count_failed; - } - - if (!file->details->got_directory_count) { - return FALSE; - } - - *count = file->details->directory_count; - return TRUE; + return NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + get_item_count, (file, count, count_unreadable)); } /** @@ -2343,8 +2340,6 @@ nautilus_file_get_deep_counts (NautilusFile *file, guint *unreadable_directory_count, GnomeVFSFileSize *total_size) { - GnomeVFSFileType type; - if (directory_count != NULL) { *directory_count = 0; } @@ -2360,35 +2355,13 @@ nautilus_file_get_deep_counts (NautilusFile *file, g_return_val_if_fail (NAUTILUS_IS_FILE (file), NAUTILUS_REQUEST_DONE); - if (!nautilus_file_is_directory (file)) { - return NAUTILUS_REQUEST_DONE; - } - - if (file->details->deep_counts_status != NAUTILUS_REQUEST_NOT_STARTED) { - if (directory_count != NULL) { - *directory_count = file->details->deep_directory_count; - } - if (file_count != NULL) { - *file_count = file->details->deep_file_count; - } - if (unreadable_directory_count != NULL) { - *unreadable_directory_count = file->details->deep_unreadable_count; - } - if (total_size != NULL) { - *total_size = file->details->deep_size; - } - return file->details->deep_counts_status; - } - - /* For directories, or before we know the type, we haven't started. */ - type = nautilus_file_get_file_type (file); - if (type == GNOME_VFS_FILE_TYPE_UNKNOWN - || type == GNOME_VFS_FILE_TYPE_DIRECTORY) { - return NAUTILUS_REQUEST_NOT_STARTED; - } - - /* For other types, we are done, and the zeros are permanent. */ - return NAUTILUS_REQUEST_DONE; + return NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + get_deep_counts, (file, + directory_count, + file_count, + unreadable_directory_count, + total_size)); } void @@ -4284,10 +4257,9 @@ nautilus_file_check_if_ready (NautilusFile *file, g_return_val_if_fail (NAUTILUS_IS_FILE (file), FALSE); - return nautilus_directory_check_if_ready_internal - (file->details->directory, - file, - file_attributes); + return NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + check_if_ready, (file, file_attributes)); } void @@ -4306,9 +4278,10 @@ nautilus_file_call_when_ready (NautilusFile *file, g_return_if_fail (NAUTILUS_IS_FILE (file)); - nautilus_directory_call_when_ready_internal - (file->details->directory, file, - file_attributes, NULL, callback, callback_data); + NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + call_when_ready, (file, file_attributes, + callback, callback_data)); } void @@ -4324,12 +4297,9 @@ nautilus_file_cancel_call_when_ready (NautilusFile *file, g_return_if_fail (NAUTILUS_IS_FILE (file)); - nautilus_directory_cancel_callback_internal - (file->details->directory, - file, - NULL, - callback, - callback_data); + NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + cancel_call_when_ready, (file, callback, callback_data)); } static void diff --git a/libnautilus-extensions/nautilus-file.h b/libnautilus-extensions/nautilus-file.h index 158ee78ff..2f0f26f74 100644 --- a/libnautilus-extensions/nautilus-file.h +++ b/libnautilus-extensions/nautilus-file.h @@ -300,14 +300,6 @@ typedef struct { GList *attributes); void (* monitor_remove) (NautilusFile *file, gconstpointer client); - gboolean (* get_item_count) (NautilusFile *file, - guint *count, - gboolean *count_unreadable); - NautilusRequestStatus (* get_deep_counts) (NautilusFile *file, - guint *directory_count, - guint *file_count, - guint *unreadable_directory_count, - GnomeVFSFileSize *total_size); void (* call_when_ready) (NautilusFile *file, GList *attributes, NautilusFileCallback callback, @@ -317,6 +309,14 @@ typedef struct { gpointer callback_data); gboolean (* check_if_ready) (NautilusFile *file, GList *attributes); + gboolean (* get_item_count) (NautilusFile *file, + guint *count, + gboolean *count_unreadable); + NautilusRequestStatus (* get_deep_counts) (NautilusFile *file, + guint *directory_count, + guint *file_count, + guint *unreadable_directory_count, + GnomeVFSFileSize *total_size); } NautilusFileClass; #endif /* NAUTILUS_FILE_H */ diff --git a/libnautilus-extensions/nautilus-merged-directory.c b/libnautilus-extensions/nautilus-merged-directory.c index 91f0fe93b..2bea0815a 100644 --- a/libnautilus-extensions/nautilus-merged-directory.c +++ b/libnautilus-extensions/nautilus-merged-directory.c @@ -60,6 +60,14 @@ typedef struct { gboolean force_reload; } MergedMonitor; +enum { + ADD_REAL_DIRECTORY, + REMOVE_REAL_DIRECTORY, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + static void nautilus_merged_directory_initialize (gpointer object, gpointer klass); static void nautilus_merged_directory_initialize_class (gpointer klass); @@ -407,26 +415,6 @@ merged_is_not_empty (NautilusDirectory *directory) return FALSE; } -static void -nautilus_merged_directory_initialize_class (gpointer klass) -{ - GtkObjectClass *object_class; - NautilusDirectoryClass *directory_class; - - object_class = GTK_OBJECT_CLASS (klass); - directory_class = NAUTILUS_DIRECTORY_CLASS (klass); - - object_class->destroy = merged_destroy; - - directory_class->contains_file = merged_contains_file; - directory_class->call_when_ready = merged_call_when_ready; - directory_class->cancel_callback = merged_cancel_callback; - directory_class->file_monitor_add = merged_file_monitor_add; - directory_class->file_monitor_remove = merged_file_monitor_remove; - directory_class->are_all_files_seen = merged_are_all_files_seen; - directory_class->is_not_empty = merged_is_not_empty; -} - static void forward_files_added_cover (NautilusDirectory *real_directory, GList *files, @@ -470,18 +458,14 @@ monitor_add_directory (gpointer key, monitor->force_reload); } -void -nautilus_merged_directory_add_real_directory (NautilusMergedDirectory *merged, - NautilusDirectory *real_directory) +static void +merged_add_real_directory (NautilusMergedDirectory *merged, + NautilusDirectory *real_directory) { g_return_if_fail (NAUTILUS_IS_MERGED_DIRECTORY (merged)); g_return_if_fail (NAUTILUS_IS_DIRECTORY (real_directory)); g_return_if_fail (!NAUTILUS_IS_MERGED_DIRECTORY (real_directory)); - - /* Quietly do nothing if asked to add something that's already there. */ - if (g_list_find (merged->details->directories, real_directory) != NULL) { - return; - } + g_return_if_fail (g_list_find (merged->details->directories, real_directory) == NULL); /* Add to our list of directories. */ nautilus_directory_ref (real_directory); @@ -515,6 +499,24 @@ nautilus_merged_directory_add_real_directory (NautilusMergedDirectory *merged, /* FIXME bugzilla.eazel.com 2541: Do we need to add the directory to callbacks too? */ } +void +nautilus_merged_directory_add_real_directory (NautilusMergedDirectory *merged, + NautilusDirectory *real_directory) +{ + g_return_if_fail (NAUTILUS_IS_MERGED_DIRECTORY (merged)); + g_return_if_fail (NAUTILUS_IS_DIRECTORY (real_directory)); + g_return_if_fail (!NAUTILUS_IS_MERGED_DIRECTORY (real_directory)); + + /* Quietly do nothing if asked to add something that's already there. */ + if (g_list_find (merged->details->directories, real_directory) != NULL) { + return; + } + + gtk_signal_emit (GTK_OBJECT (merged), + signals[ADD_REAL_DIRECTORY], + real_directory); +} + static void merged_callback_remove_directory_cover (gpointer key, gpointer value, @@ -533,17 +535,13 @@ monitor_remove_directory (gpointer key, (NAUTILUS_DIRECTORY (callback_data), value); } -void -nautilus_merged_directory_remove_real_directory (NautilusMergedDirectory *merged, - NautilusDirectory *real_directory) +static void +merged_remove_real_directory (NautilusMergedDirectory *merged, + NautilusDirectory *real_directory) { g_return_if_fail (NAUTILUS_IS_MERGED_DIRECTORY (merged)); g_return_if_fail (NAUTILUS_IS_DIRECTORY (real_directory)); - - /* Quietly do nothing if asked to remove something that's not there. */ - if (g_list_find (merged->details->directories, real_directory) == NULL) { - return; - } + g_return_if_fail (g_list_find (merged->details->directories, real_directory) != NULL); /* Remove this directory from callbacks and monitors. */ nautilus_g_hash_table_safe_for_each @@ -566,6 +564,22 @@ nautilus_merged_directory_remove_real_directory (NautilusMergedDirectory *merged nautilus_directory_unref (real_directory); } +void +nautilus_merged_directory_remove_real_directory (NautilusMergedDirectory *merged, + NautilusDirectory *real_directory) +{ + g_return_if_fail (NAUTILUS_IS_MERGED_DIRECTORY (merged)); + + /* Quietly do nothing if asked to remove something that's not there. */ + if (g_list_find (merged->details->directories, real_directory) == NULL) { + return; + } + + gtk_signal_emit (GTK_OBJECT (merged), + signals[REMOVE_REAL_DIRECTORY], + real_directory); +} + static void remove_all_real_directories (NautilusMergedDirectory *merged) { @@ -574,3 +588,47 @@ remove_all_real_directories (NautilusMergedDirectory *merged) (merged, merged->details->directories->data); } } + +static void +nautilus_merged_directory_initialize_class (gpointer klass) +{ + GtkObjectClass *object_class; + NautilusDirectoryClass *directory_class; + NautilusMergedDirectoryClass *merged_directory_class; + + object_class = GTK_OBJECT_CLASS (klass); + directory_class = NAUTILUS_DIRECTORY_CLASS (klass); + merged_directory_class = NAUTILUS_MERGED_DIRECTORY_CLASS (klass); + + object_class->destroy = merged_destroy; + + directory_class->contains_file = merged_contains_file; + directory_class->call_when_ready = merged_call_when_ready; + directory_class->cancel_callback = merged_cancel_callback; + directory_class->file_monitor_add = merged_file_monitor_add; + directory_class->file_monitor_remove = merged_file_monitor_remove; + directory_class->are_all_files_seen = merged_are_all_files_seen; + directory_class->is_not_empty = merged_is_not_empty; + + merged_directory_class->add_real_directory = merged_add_real_directory; + merged_directory_class->remove_real_directory = merged_remove_real_directory; + + signals[ADD_REAL_DIRECTORY] + = gtk_signal_new ("add_real_directory", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (NautilusMergedDirectoryClass, + add_real_directory), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, GTK_TYPE_POINTER); + signals[REMOVE_REAL_DIRECTORY] + = gtk_signal_new ("remove_real_directory", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (NautilusMergedDirectoryClass, + remove_real_directory), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, GTK_TYPE_POINTER); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); +} diff --git a/libnautilus-extensions/nautilus-merged-directory.h b/libnautilus-extensions/nautilus-merged-directory.h index 4b1f0152d..5a3f41a4d 100644 --- a/libnautilus-extensions/nautilus-merged-directory.h +++ b/libnautilus-extensions/nautilus-merged-directory.h @@ -49,6 +49,11 @@ typedef struct { typedef struct { NautilusDirectoryClass parent_slot; + + void (* add_real_directory) (NautilusMergedDirectory *merged_directory, + NautilusDirectory *real_directory); + void (* remove_real_directory) (NautilusMergedDirectory *merged_directory, + NautilusDirectory *real_directory); } NautilusMergedDirectoryClass; GtkType nautilus_merged_directory_get_type (void); diff --git a/libnautilus-extensions/nautilus-trash-directory.c b/libnautilus-extensions/nautilus-trash-directory.c index ce05fa0d0..cff445713 100644 --- a/libnautilus-extensions/nautilus-trash-directory.c +++ b/libnautilus-extensions/nautilus-trash-directory.c @@ -59,7 +59,31 @@ NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusTrashDirectory, nautilus_trash_directory, NAUTILUS_TYPE_MERGED_DIRECTORY) -static gint pending_find_directory_count = 0; +static int pending_find_directory_count = 0; + +static void +find_directory_start (void) +{ + if (pending_find_directory_count == 0) { + nautilus_timed_wait_start (NULL, + add_volume, + _("Searching Disks"), + _("Nautilus is searching for trash folders."), + NULL); + } + + ++pending_find_directory_count; +} + +static void +find_directory_end (void) +{ + --pending_find_directory_count; + + if (pending_find_directory_count == 0) { + nautilus_timed_wait_stop (NULL, add_volume); + } +} static void find_directory_callback (GnomeVFSAsyncHandle *handle, @@ -73,17 +97,13 @@ find_directory_callback (GnomeVFSAsyncHandle *handle, trash_volume = callback_data; - --pending_find_directory_count; - - if (pending_find_directory_count == 0) { - nautilus_timed_wait_stop (NULL, &add_volume); - } - g_assert (nautilus_g_list_exactly_one_item (results)); g_assert (trash_volume != NULL); g_assert (NAUTILUS_IS_TRASH_DIRECTORY (trash_volume->trash)); g_assert (trash_volume->real_directory == NULL); g_assert (trash_volume->handle == handle); + + find_directory_end (); /* We are done with the async. I/O. */ trash_volume->handle = NULL; @@ -129,8 +149,8 @@ add_volume (NautilusTrashDirectory *trash, return; } - volume_mount_uri = gnome_vfs_uri_new ( - nautilus_volume_monitor_get_volume_mount_uri (volume)); + volume_mount_uri = gnome_vfs_uri_new + (nautilus_volume_monitor_get_volume_mount_uri (volume)); /* Make the structure used to track the trash for this volume. */ trash_volume = g_new0 (TrashVolume, 1); @@ -142,21 +162,13 @@ add_volume (NautilusTrashDirectory *trash, vfs_uri_as_list.data = volume_mount_uri; vfs_uri_as_list.next = NULL; vfs_uri_as_list.prev = NULL; + /* Search for Trash directories but don't create new ones. */ + find_directory_start (); gnome_vfs_async_find_directory (&trash_volume->handle, &vfs_uri_as_list, GNOME_VFS_DIRECTORY_KIND_TRASH, FALSE, TRUE, 0777, find_directory_callback, trash_volume); - - if (pending_find_directory_count == 0) { - nautilus_timed_wait_start (NULL, - &add_volume, - _("Searching Disks"), - _("Nautilus is searching for trash folders."), - NULL); - } - - ++pending_find_directory_count; } static void @@ -167,6 +179,7 @@ remove_trash_volume (TrashVolume *trash_volume) if (trash_volume->handle != NULL) { gnome_vfs_async_cancel (trash_volume->handle); + find_directory_end (); } if (trash_volume->real_directory != NULL) { nautilus_merged_directory_remove_real_directory diff --git a/libnautilus-extensions/nautilus-trash-file.c b/libnautilus-extensions/nautilus-trash-file.c index 319b64591..7c5e9481f 100644 --- a/libnautilus-extensions/nautilus-trash-file.c +++ b/libnautilus-extensions/nautilus-trash-file.c @@ -26,9 +26,15 @@ #include #include "nautilus-trash-file.h" +#include "nautilus-file-utilities.h" #include "nautilus-gtk-macros.h" +#include "nautilus-trash-directory.h" +#include struct NautilusTrashFileDetails { + NautilusTrashDirectory *as_directory; + guint add_directory_connection_id; + guint remove_directory_connection_id; }; static void nautilus_trash_file_initialize (gpointer object, @@ -39,19 +45,71 @@ NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusTrashFile, nautilus_trash_file, NAUTILUS_TYPE_FILE) +static void +add_directory_callback (NautilusTrashDirectory *trash_directory, + NautilusDirectory *real_directory, + NautilusTrashFile *trash_file) +{ + g_assert (NAUTILUS_IS_TRASH_DIRECTORY (trash_directory)); + g_assert (NAUTILUS_IS_DIRECTORY (real_directory)); + g_assert (!NAUTILUS_IS_MERGED_DIRECTORY (real_directory)); + g_assert (NAUTILUS_IS_TRASH_FILE (trash_file)); + g_assert (trash_file->details->as_directory == trash_directory); +} + +static void +remove_directory_callback (NautilusTrashDirectory *trash_directory, + NautilusDirectory *real_directory, + NautilusTrashFile *trash_file) +{ + g_assert (NAUTILUS_IS_TRASH_DIRECTORY (trash_directory)); + g_assert (NAUTILUS_IS_DIRECTORY (real_directory)); + g_assert (!NAUTILUS_IS_MERGED_DIRECTORY (real_directory)); + g_assert (NAUTILUS_IS_TRASH_FILE (trash_file)); + g_assert (trash_file->details->as_directory == trash_directory); +} + static void nautilus_trash_file_initialize (gpointer object, gpointer klass) { - NautilusTrashFile *file; + NautilusTrashFile *trash_file; + NautilusTrashDirectory *trash_directory; + + trash_file = NAUTILUS_TRASH_FILE (object); + + trash_directory = NAUTILUS_TRASH_DIRECTORY (nautilus_directory_get (NAUTILUS_TRASH_URI)); - file = NAUTILUS_TRASH_FILE (object); + trash_file->details = g_new0 (NautilusTrashFileDetails, 1); + trash_file->details->as_directory = trash_directory; - file->details = g_new0 (NautilusTrashFileDetails, 1); + trash_file->details->add_directory_connection_id = gtk_signal_connect + (GTK_OBJECT (trash_directory), + "add_real_directory", + add_directory_callback, + trash_file); + trash_file->details->remove_directory_connection_id = gtk_signal_connect + (GTK_OBJECT (trash_directory), + "remove_real_directory", + remove_directory_callback, + trash_file); } static void trash_destroy (GtkObject *object) { + NautilusTrashFile *trash_file; + NautilusTrashDirectory *trash_directory; + + trash_file = NAUTILUS_TRASH_FILE (object); + trash_directory = trash_file->details->as_directory; + + gtk_signal_disconnect (GTK_OBJECT (trash_directory), + trash_file->details->add_directory_connection_id); + gtk_signal_disconnect (GTK_OBJECT (trash_directory), + trash_file->details->remove_directory_connection_id); + nautilus_directory_unref (NAUTILUS_DIRECTORY (trash_directory)); + g_free (trash_file->details); + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); } diff --git a/libnautilus-extensions/nautilus-vfs-file.c b/libnautilus-extensions/nautilus-vfs-file.c index 655ede485..455ac59c7 100644 --- a/libnautilus-extensions/nautilus-vfs-file.c +++ b/libnautilus-extensions/nautilus-vfs-file.c @@ -26,19 +26,143 @@ #include #include "nautilus-vfs-file.h" +#include "nautilus-directory-private.h" +#include "nautilus-file-private.h" #include "nautilus-gtk-macros.h" struct NautilusVFSFileDetails { }; static void nautilus_vfs_file_initialize (gpointer object, - gpointer klass); + gpointer klass); static void nautilus_vfs_file_initialize_class (gpointer klass); NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusVFSFile, nautilus_vfs_file, NAUTILUS_TYPE_FILE) +static void +vfs_file_monitor_add (NautilusFile *file, + gconstpointer client, + GList *attributes) +{ + nautilus_directory_monitor_add_internal + (file->details->directory, file, + client, TRUE, TRUE, attributes); +} + +static void +vfs_file_monitor_remove (NautilusFile *file, + gconstpointer client) +{ + nautilus_directory_monitor_remove_internal + (file->details->directory, file, client); +} + +static void +vfs_file_call_when_ready (NautilusFile *file, + GList *file_attributes, + NautilusFileCallback callback, + gpointer callback_data) + +{ + nautilus_directory_call_when_ready_internal + (file->details->directory, file, + file_attributes, NULL, callback, callback_data); +} + +static void +vfs_file_cancel_call_when_ready (NautilusFile *file, + NautilusFileCallback callback, + gpointer callback_data) +{ + nautilus_directory_cancel_callback_internal + (file->details->directory, + file, + NULL, + callback, + callback_data); +} + +static gboolean +vfs_file_check_if_ready (NautilusFile *file, + GList *file_attributes) +{ + return nautilus_directory_check_if_ready_internal + (file->details->directory, + file, + file_attributes); +} + +static gboolean +vfs_file_get_item_count (NautilusFile *file, + guint *count, + gboolean *count_unreadable) +{ + if (count_unreadable != NULL) { + *count_unreadable = file->details->directory_count_failed; + } + if (!file->details->got_directory_count) { + *count = 0; + return FALSE; + } + *count = file->details->directory_count; + return TRUE; +} + +static NautilusRequestStatus +vfs_file_get_deep_counts (NautilusFile *file, + guint *directory_count, + guint *file_count, + guint *unreadable_directory_count, + GnomeVFSFileSize *total_size) +{ + GnomeVFSFileType type; + + if (directory_count != NULL) { + *directory_count = 0; + } + if (file_count != NULL) { + *file_count = 0; + } + if (unreadable_directory_count != NULL) { + *unreadable_directory_count = 0; + } + if (total_size != NULL) { + *total_size = 0; + } + + if (!nautilus_file_is_directory (file)) { + return NAUTILUS_REQUEST_DONE; + } + + if (file->details->deep_counts_status != NAUTILUS_REQUEST_NOT_STARTED) { + if (directory_count != NULL) { + *directory_count = file->details->deep_directory_count; + } + if (file_count != NULL) { + *file_count = file->details->deep_file_count; + } + if (unreadable_directory_count != NULL) { + *unreadable_directory_count = file->details->deep_unreadable_count; + } + if (total_size != NULL) { + *total_size = file->details->deep_size; + } + return file->details->deep_counts_status; + } + + /* For directories, or before we know the type, we haven't started. */ + type = nautilus_file_get_file_type (file); + if (type == GNOME_VFS_FILE_TYPE_UNKNOWN + || type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + return NAUTILUS_REQUEST_NOT_STARTED; + } + + /* For other types, we are done, and the zeros are permanent. */ + return NAUTILUS_REQUEST_DONE; +} + static void nautilus_vfs_file_initialize (gpointer object, gpointer klass) { @@ -66,5 +190,11 @@ nautilus_vfs_file_initialize_class (gpointer klass) object_class->destroy = vfs_destroy; - /* file_class-> */ + file_class->monitor_add = vfs_file_monitor_add; + file_class->monitor_remove = vfs_file_monitor_remove; + file_class->call_when_ready = vfs_file_call_when_ready; + file_class->cancel_call_when_ready = vfs_file_cancel_call_when_ready; + file_class->check_if_ready = vfs_file_check_if_ready; + file_class->get_item_count = vfs_file_get_item_count; + file_class->get_deep_counts = vfs_file_get_deep_counts; } diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c index 9ff2db5f5..c3fc40687 100644 --- a/libnautilus-private/nautilus-file.c +++ b/libnautilus-private/nautilus-file.c @@ -23,12 +23,13 @@ */ #include -#include "nautilus-file-private.h" -#include "nautilus-file-attributes.h" +#include "nautilus-file.h" #include "nautilus-directory-metafile.h" #include "nautilus-directory-notify.h" #include "nautilus-directory-private.h" +#include "nautilus-file-attributes.h" +#include "nautilus-file-private.h" #include "nautilus-glib-extensions.h" #include "nautilus-global-preferences.h" #include "nautilus-gtk-extensions.h" @@ -36,6 +37,8 @@ #include "nautilus-lib-self-check-functions.h" #include "nautilus-link.h" #include "nautilus-string.h" +#include "nautilus-trash-file.h" +#include "nautilus-vfs-file.h" #include #include #include @@ -138,7 +141,7 @@ nautilus_file_new_from_relative_uri (NautilusDirectory *directory, g_return_val_if_fail (relative_uri != NULL, NULL); g_return_val_if_fail (relative_uri[0] != '\0', NULL); - file = NAUTILUS_FILE (gtk_object_new (NAUTILUS_TYPE_FILE, NULL)); + file = NAUTILUS_FILE (gtk_object_new (NAUTILUS_TYPE_VFS_FILE, NULL)); gtk_object_ref (GTK_OBJECT (file)); gtk_object_sink (GTK_OBJECT (file)); @@ -248,7 +251,7 @@ nautilus_file_new_from_info (NautilusDirectory *directory, g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL); g_return_val_if_fail (info != NULL, NULL); - file = NAUTILUS_FILE (gtk_object_new (NAUTILUS_TYPE_FILE, NULL)); + file = NAUTILUS_FILE (gtk_object_new (NAUTILUS_TYPE_VFS_FILE, NULL)); #ifdef NAUTILUS_FILE_DEBUG_REF printf("%10p ref'd\n", file); @@ -2075,9 +2078,9 @@ nautilus_file_monitor_add (NautilusFile *file, g_return_if_fail (NAUTILUS_IS_FILE (file)); g_return_if_fail (client != NULL); - nautilus_directory_monitor_add_internal - (file->details->directory, file, - client, TRUE, TRUE, attributes); + NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + monitor_add, (file, client, attributes)); } void @@ -2087,8 +2090,9 @@ nautilus_file_monitor_remove (NautilusFile *file, g_return_if_fail (NAUTILUS_IS_FILE (file)); g_return_if_fail (client != NULL); - nautilus_directory_monitor_remove_internal - (file->details->directory, file, client); + NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + monitor_remove, (file, client)); } @@ -2310,16 +2314,9 @@ nautilus_file_get_directory_item_count (NautilusFile *file, return FALSE; } - if (count_unreadable != NULL) { - *count_unreadable = file->details->directory_count_failed; - } - - if (!file->details->got_directory_count) { - return FALSE; - } - - *count = file->details->directory_count; - return TRUE; + return NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + get_item_count, (file, count, count_unreadable)); } /** @@ -2343,8 +2340,6 @@ nautilus_file_get_deep_counts (NautilusFile *file, guint *unreadable_directory_count, GnomeVFSFileSize *total_size) { - GnomeVFSFileType type; - if (directory_count != NULL) { *directory_count = 0; } @@ -2360,35 +2355,13 @@ nautilus_file_get_deep_counts (NautilusFile *file, g_return_val_if_fail (NAUTILUS_IS_FILE (file), NAUTILUS_REQUEST_DONE); - if (!nautilus_file_is_directory (file)) { - return NAUTILUS_REQUEST_DONE; - } - - if (file->details->deep_counts_status != NAUTILUS_REQUEST_NOT_STARTED) { - if (directory_count != NULL) { - *directory_count = file->details->deep_directory_count; - } - if (file_count != NULL) { - *file_count = file->details->deep_file_count; - } - if (unreadable_directory_count != NULL) { - *unreadable_directory_count = file->details->deep_unreadable_count; - } - if (total_size != NULL) { - *total_size = file->details->deep_size; - } - return file->details->deep_counts_status; - } - - /* For directories, or before we know the type, we haven't started. */ - type = nautilus_file_get_file_type (file); - if (type == GNOME_VFS_FILE_TYPE_UNKNOWN - || type == GNOME_VFS_FILE_TYPE_DIRECTORY) { - return NAUTILUS_REQUEST_NOT_STARTED; - } - - /* For other types, we are done, and the zeros are permanent. */ - return NAUTILUS_REQUEST_DONE; + return NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + get_deep_counts, (file, + directory_count, + file_count, + unreadable_directory_count, + total_size)); } void @@ -4284,10 +4257,9 @@ nautilus_file_check_if_ready (NautilusFile *file, g_return_val_if_fail (NAUTILUS_IS_FILE (file), FALSE); - return nautilus_directory_check_if_ready_internal - (file->details->directory, - file, - file_attributes); + return NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + check_if_ready, (file, file_attributes)); } void @@ -4306,9 +4278,10 @@ nautilus_file_call_when_ready (NautilusFile *file, g_return_if_fail (NAUTILUS_IS_FILE (file)); - nautilus_directory_call_when_ready_internal - (file->details->directory, file, - file_attributes, NULL, callback, callback_data); + NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + call_when_ready, (file, file_attributes, + callback, callback_data)); } void @@ -4324,12 +4297,9 @@ nautilus_file_cancel_call_when_ready (NautilusFile *file, g_return_if_fail (NAUTILUS_IS_FILE (file)); - nautilus_directory_cancel_callback_internal - (file->details->directory, - file, - NULL, - callback, - callback_data); + NAUTILUS_CALL_VIRTUAL + (NAUTILUS_FILE_CLASS, file, + cancel_call_when_ready, (file, callback, callback_data)); } static void diff --git a/libnautilus-private/nautilus-file.h b/libnautilus-private/nautilus-file.h index 158ee78ff..2f0f26f74 100644 --- a/libnautilus-private/nautilus-file.h +++ b/libnautilus-private/nautilus-file.h @@ -300,14 +300,6 @@ typedef struct { GList *attributes); void (* monitor_remove) (NautilusFile *file, gconstpointer client); - gboolean (* get_item_count) (NautilusFile *file, - guint *count, - gboolean *count_unreadable); - NautilusRequestStatus (* get_deep_counts) (NautilusFile *file, - guint *directory_count, - guint *file_count, - guint *unreadable_directory_count, - GnomeVFSFileSize *total_size); void (* call_when_ready) (NautilusFile *file, GList *attributes, NautilusFileCallback callback, @@ -317,6 +309,14 @@ typedef struct { gpointer callback_data); gboolean (* check_if_ready) (NautilusFile *file, GList *attributes); + gboolean (* get_item_count) (NautilusFile *file, + guint *count, + gboolean *count_unreadable); + NautilusRequestStatus (* get_deep_counts) (NautilusFile *file, + guint *directory_count, + guint *file_count, + guint *unreadable_directory_count, + GnomeVFSFileSize *total_size); } NautilusFileClass; #endif /* NAUTILUS_FILE_H */ diff --git a/libnautilus-private/nautilus-merged-directory.c b/libnautilus-private/nautilus-merged-directory.c index 91f0fe93b..2bea0815a 100644 --- a/libnautilus-private/nautilus-merged-directory.c +++ b/libnautilus-private/nautilus-merged-directory.c @@ -60,6 +60,14 @@ typedef struct { gboolean force_reload; } MergedMonitor; +enum { + ADD_REAL_DIRECTORY, + REMOVE_REAL_DIRECTORY, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + static void nautilus_merged_directory_initialize (gpointer object, gpointer klass); static void nautilus_merged_directory_initialize_class (gpointer klass); @@ -407,26 +415,6 @@ merged_is_not_empty (NautilusDirectory *directory) return FALSE; } -static void -nautilus_merged_directory_initialize_class (gpointer klass) -{ - GtkObjectClass *object_class; - NautilusDirectoryClass *directory_class; - - object_class = GTK_OBJECT_CLASS (klass); - directory_class = NAUTILUS_DIRECTORY_CLASS (klass); - - object_class->destroy = merged_destroy; - - directory_class->contains_file = merged_contains_file; - directory_class->call_when_ready = merged_call_when_ready; - directory_class->cancel_callback = merged_cancel_callback; - directory_class->file_monitor_add = merged_file_monitor_add; - directory_class->file_monitor_remove = merged_file_monitor_remove; - directory_class->are_all_files_seen = merged_are_all_files_seen; - directory_class->is_not_empty = merged_is_not_empty; -} - static void forward_files_added_cover (NautilusDirectory *real_directory, GList *files, @@ -470,18 +458,14 @@ monitor_add_directory (gpointer key, monitor->force_reload); } -void -nautilus_merged_directory_add_real_directory (NautilusMergedDirectory *merged, - NautilusDirectory *real_directory) +static void +merged_add_real_directory (NautilusMergedDirectory *merged, + NautilusDirectory *real_directory) { g_return_if_fail (NAUTILUS_IS_MERGED_DIRECTORY (merged)); g_return_if_fail (NAUTILUS_IS_DIRECTORY (real_directory)); g_return_if_fail (!NAUTILUS_IS_MERGED_DIRECTORY (real_directory)); - - /* Quietly do nothing if asked to add something that's already there. */ - if (g_list_find (merged->details->directories, real_directory) != NULL) { - return; - } + g_return_if_fail (g_list_find (merged->details->directories, real_directory) == NULL); /* Add to our list of directories. */ nautilus_directory_ref (real_directory); @@ -515,6 +499,24 @@ nautilus_merged_directory_add_real_directory (NautilusMergedDirectory *merged, /* FIXME bugzilla.eazel.com 2541: Do we need to add the directory to callbacks too? */ } +void +nautilus_merged_directory_add_real_directory (NautilusMergedDirectory *merged, + NautilusDirectory *real_directory) +{ + g_return_if_fail (NAUTILUS_IS_MERGED_DIRECTORY (merged)); + g_return_if_fail (NAUTILUS_IS_DIRECTORY (real_directory)); + g_return_if_fail (!NAUTILUS_IS_MERGED_DIRECTORY (real_directory)); + + /* Quietly do nothing if asked to add something that's already there. */ + if (g_list_find (merged->details->directories, real_directory) != NULL) { + return; + } + + gtk_signal_emit (GTK_OBJECT (merged), + signals[ADD_REAL_DIRECTORY], + real_directory); +} + static void merged_callback_remove_directory_cover (gpointer key, gpointer value, @@ -533,17 +535,13 @@ monitor_remove_directory (gpointer key, (NAUTILUS_DIRECTORY (callback_data), value); } -void -nautilus_merged_directory_remove_real_directory (NautilusMergedDirectory *merged, - NautilusDirectory *real_directory) +static void +merged_remove_real_directory (NautilusMergedDirectory *merged, + NautilusDirectory *real_directory) { g_return_if_fail (NAUTILUS_IS_MERGED_DIRECTORY (merged)); g_return_if_fail (NAUTILUS_IS_DIRECTORY (real_directory)); - - /* Quietly do nothing if asked to remove something that's not there. */ - if (g_list_find (merged->details->directories, real_directory) == NULL) { - return; - } + g_return_if_fail (g_list_find (merged->details->directories, real_directory) != NULL); /* Remove this directory from callbacks and monitors. */ nautilus_g_hash_table_safe_for_each @@ -566,6 +564,22 @@ nautilus_merged_directory_remove_real_directory (NautilusMergedDirectory *merged nautilus_directory_unref (real_directory); } +void +nautilus_merged_directory_remove_real_directory (NautilusMergedDirectory *merged, + NautilusDirectory *real_directory) +{ + g_return_if_fail (NAUTILUS_IS_MERGED_DIRECTORY (merged)); + + /* Quietly do nothing if asked to remove something that's not there. */ + if (g_list_find (merged->details->directories, real_directory) == NULL) { + return; + } + + gtk_signal_emit (GTK_OBJECT (merged), + signals[REMOVE_REAL_DIRECTORY], + real_directory); +} + static void remove_all_real_directories (NautilusMergedDirectory *merged) { @@ -574,3 +588,47 @@ remove_all_real_directories (NautilusMergedDirectory *merged) (merged, merged->details->directories->data); } } + +static void +nautilus_merged_directory_initialize_class (gpointer klass) +{ + GtkObjectClass *object_class; + NautilusDirectoryClass *directory_class; + NautilusMergedDirectoryClass *merged_directory_class; + + object_class = GTK_OBJECT_CLASS (klass); + directory_class = NAUTILUS_DIRECTORY_CLASS (klass); + merged_directory_class = NAUTILUS_MERGED_DIRECTORY_CLASS (klass); + + object_class->destroy = merged_destroy; + + directory_class->contains_file = merged_contains_file; + directory_class->call_when_ready = merged_call_when_ready; + directory_class->cancel_callback = merged_cancel_callback; + directory_class->file_monitor_add = merged_file_monitor_add; + directory_class->file_monitor_remove = merged_file_monitor_remove; + directory_class->are_all_files_seen = merged_are_all_files_seen; + directory_class->is_not_empty = merged_is_not_empty; + + merged_directory_class->add_real_directory = merged_add_real_directory; + merged_directory_class->remove_real_directory = merged_remove_real_directory; + + signals[ADD_REAL_DIRECTORY] + = gtk_signal_new ("add_real_directory", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (NautilusMergedDirectoryClass, + add_real_directory), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, GTK_TYPE_POINTER); + signals[REMOVE_REAL_DIRECTORY] + = gtk_signal_new ("remove_real_directory", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (NautilusMergedDirectoryClass, + remove_real_directory), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, GTK_TYPE_POINTER); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); +} diff --git a/libnautilus-private/nautilus-merged-directory.h b/libnautilus-private/nautilus-merged-directory.h index 4b1f0152d..5a3f41a4d 100644 --- a/libnautilus-private/nautilus-merged-directory.h +++ b/libnautilus-private/nautilus-merged-directory.h @@ -49,6 +49,11 @@ typedef struct { typedef struct { NautilusDirectoryClass parent_slot; + + void (* add_real_directory) (NautilusMergedDirectory *merged_directory, + NautilusDirectory *real_directory); + void (* remove_real_directory) (NautilusMergedDirectory *merged_directory, + NautilusDirectory *real_directory); } NautilusMergedDirectoryClass; GtkType nautilus_merged_directory_get_type (void); diff --git a/libnautilus-private/nautilus-trash-directory.c b/libnautilus-private/nautilus-trash-directory.c index ce05fa0d0..cff445713 100644 --- a/libnautilus-private/nautilus-trash-directory.c +++ b/libnautilus-private/nautilus-trash-directory.c @@ -59,7 +59,31 @@ NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusTrashDirectory, nautilus_trash_directory, NAUTILUS_TYPE_MERGED_DIRECTORY) -static gint pending_find_directory_count = 0; +static int pending_find_directory_count = 0; + +static void +find_directory_start (void) +{ + if (pending_find_directory_count == 0) { + nautilus_timed_wait_start (NULL, + add_volume, + _("Searching Disks"), + _("Nautilus is searching for trash folders."), + NULL); + } + + ++pending_find_directory_count; +} + +static void +find_directory_end (void) +{ + --pending_find_directory_count; + + if (pending_find_directory_count == 0) { + nautilus_timed_wait_stop (NULL, add_volume); + } +} static void find_directory_callback (GnomeVFSAsyncHandle *handle, @@ -73,17 +97,13 @@ find_directory_callback (GnomeVFSAsyncHandle *handle, trash_volume = callback_data; - --pending_find_directory_count; - - if (pending_find_directory_count == 0) { - nautilus_timed_wait_stop (NULL, &add_volume); - } - g_assert (nautilus_g_list_exactly_one_item (results)); g_assert (trash_volume != NULL); g_assert (NAUTILUS_IS_TRASH_DIRECTORY (trash_volume->trash)); g_assert (trash_volume->real_directory == NULL); g_assert (trash_volume->handle == handle); + + find_directory_end (); /* We are done with the async. I/O. */ trash_volume->handle = NULL; @@ -129,8 +149,8 @@ add_volume (NautilusTrashDirectory *trash, return; } - volume_mount_uri = gnome_vfs_uri_new ( - nautilus_volume_monitor_get_volume_mount_uri (volume)); + volume_mount_uri = gnome_vfs_uri_new + (nautilus_volume_monitor_get_volume_mount_uri (volume)); /* Make the structure used to track the trash for this volume. */ trash_volume = g_new0 (TrashVolume, 1); @@ -142,21 +162,13 @@ add_volume (NautilusTrashDirectory *trash, vfs_uri_as_list.data = volume_mount_uri; vfs_uri_as_list.next = NULL; vfs_uri_as_list.prev = NULL; + /* Search for Trash directories but don't create new ones. */ + find_directory_start (); gnome_vfs_async_find_directory (&trash_volume->handle, &vfs_uri_as_list, GNOME_VFS_DIRECTORY_KIND_TRASH, FALSE, TRUE, 0777, find_directory_callback, trash_volume); - - if (pending_find_directory_count == 0) { - nautilus_timed_wait_start (NULL, - &add_volume, - _("Searching Disks"), - _("Nautilus is searching for trash folders."), - NULL); - } - - ++pending_find_directory_count; } static void @@ -167,6 +179,7 @@ remove_trash_volume (TrashVolume *trash_volume) if (trash_volume->handle != NULL) { gnome_vfs_async_cancel (trash_volume->handle); + find_directory_end (); } if (trash_volume->real_directory != NULL) { nautilus_merged_directory_remove_real_directory diff --git a/libnautilus-private/nautilus-trash-file.c b/libnautilus-private/nautilus-trash-file.c index 319b64591..7c5e9481f 100644 --- a/libnautilus-private/nautilus-trash-file.c +++ b/libnautilus-private/nautilus-trash-file.c @@ -26,9 +26,15 @@ #include #include "nautilus-trash-file.h" +#include "nautilus-file-utilities.h" #include "nautilus-gtk-macros.h" +#include "nautilus-trash-directory.h" +#include struct NautilusTrashFileDetails { + NautilusTrashDirectory *as_directory; + guint add_directory_connection_id; + guint remove_directory_connection_id; }; static void nautilus_trash_file_initialize (gpointer object, @@ -39,19 +45,71 @@ NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusTrashFile, nautilus_trash_file, NAUTILUS_TYPE_FILE) +static void +add_directory_callback (NautilusTrashDirectory *trash_directory, + NautilusDirectory *real_directory, + NautilusTrashFile *trash_file) +{ + g_assert (NAUTILUS_IS_TRASH_DIRECTORY (trash_directory)); + g_assert (NAUTILUS_IS_DIRECTORY (real_directory)); + g_assert (!NAUTILUS_IS_MERGED_DIRECTORY (real_directory)); + g_assert (NAUTILUS_IS_TRASH_FILE (trash_file)); + g_assert (trash_file->details->as_directory == trash_directory); +} + +static void +remove_directory_callback (NautilusTrashDirectory *trash_directory, + NautilusDirectory *real_directory, + NautilusTrashFile *trash_file) +{ + g_assert (NAUTILUS_IS_TRASH_DIRECTORY (trash_directory)); + g_assert (NAUTILUS_IS_DIRECTORY (real_directory)); + g_assert (!NAUTILUS_IS_MERGED_DIRECTORY (real_directory)); + g_assert (NAUTILUS_IS_TRASH_FILE (trash_file)); + g_assert (trash_file->details->as_directory == trash_directory); +} + static void nautilus_trash_file_initialize (gpointer object, gpointer klass) { - NautilusTrashFile *file; + NautilusTrashFile *trash_file; + NautilusTrashDirectory *trash_directory; + + trash_file = NAUTILUS_TRASH_FILE (object); + + trash_directory = NAUTILUS_TRASH_DIRECTORY (nautilus_directory_get (NAUTILUS_TRASH_URI)); - file = NAUTILUS_TRASH_FILE (object); + trash_file->details = g_new0 (NautilusTrashFileDetails, 1); + trash_file->details->as_directory = trash_directory; - file->details = g_new0 (NautilusTrashFileDetails, 1); + trash_file->details->add_directory_connection_id = gtk_signal_connect + (GTK_OBJECT (trash_directory), + "add_real_directory", + add_directory_callback, + trash_file); + trash_file->details->remove_directory_connection_id = gtk_signal_connect + (GTK_OBJECT (trash_directory), + "remove_real_directory", + remove_directory_callback, + trash_file); } static void trash_destroy (GtkObject *object) { + NautilusTrashFile *trash_file; + NautilusTrashDirectory *trash_directory; + + trash_file = NAUTILUS_TRASH_FILE (object); + trash_directory = trash_file->details->as_directory; + + gtk_signal_disconnect (GTK_OBJECT (trash_directory), + trash_file->details->add_directory_connection_id); + gtk_signal_disconnect (GTK_OBJECT (trash_directory), + trash_file->details->remove_directory_connection_id); + nautilus_directory_unref (NAUTILUS_DIRECTORY (trash_directory)); + g_free (trash_file->details); + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); } diff --git a/libnautilus-private/nautilus-vfs-file.c b/libnautilus-private/nautilus-vfs-file.c index 655ede485..455ac59c7 100644 --- a/libnautilus-private/nautilus-vfs-file.c +++ b/libnautilus-private/nautilus-vfs-file.c @@ -26,19 +26,143 @@ #include #include "nautilus-vfs-file.h" +#include "nautilus-directory-private.h" +#include "nautilus-file-private.h" #include "nautilus-gtk-macros.h" struct NautilusVFSFileDetails { }; static void nautilus_vfs_file_initialize (gpointer object, - gpointer klass); + gpointer klass); static void nautilus_vfs_file_initialize_class (gpointer klass); NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusVFSFile, nautilus_vfs_file, NAUTILUS_TYPE_FILE) +static void +vfs_file_monitor_add (NautilusFile *file, + gconstpointer client, + GList *attributes) +{ + nautilus_directory_monitor_add_internal + (file->details->directory, file, + client, TRUE, TRUE, attributes); +} + +static void +vfs_file_monitor_remove (NautilusFile *file, + gconstpointer client) +{ + nautilus_directory_monitor_remove_internal + (file->details->directory, file, client); +} + +static void +vfs_file_call_when_ready (NautilusFile *file, + GList *file_attributes, + NautilusFileCallback callback, + gpointer callback_data) + +{ + nautilus_directory_call_when_ready_internal + (file->details->directory, file, + file_attributes, NULL, callback, callback_data); +} + +static void +vfs_file_cancel_call_when_ready (NautilusFile *file, + NautilusFileCallback callback, + gpointer callback_data) +{ + nautilus_directory_cancel_callback_internal + (file->details->directory, + file, + NULL, + callback, + callback_data); +} + +static gboolean +vfs_file_check_if_ready (NautilusFile *file, + GList *file_attributes) +{ + return nautilus_directory_check_if_ready_internal + (file->details->directory, + file, + file_attributes); +} + +static gboolean +vfs_file_get_item_count (NautilusFile *file, + guint *count, + gboolean *count_unreadable) +{ + if (count_unreadable != NULL) { + *count_unreadable = file->details->directory_count_failed; + } + if (!file->details->got_directory_count) { + *count = 0; + return FALSE; + } + *count = file->details->directory_count; + return TRUE; +} + +static NautilusRequestStatus +vfs_file_get_deep_counts (NautilusFile *file, + guint *directory_count, + guint *file_count, + guint *unreadable_directory_count, + GnomeVFSFileSize *total_size) +{ + GnomeVFSFileType type; + + if (directory_count != NULL) { + *directory_count = 0; + } + if (file_count != NULL) { + *file_count = 0; + } + if (unreadable_directory_count != NULL) { + *unreadable_directory_count = 0; + } + if (total_size != NULL) { + *total_size = 0; + } + + if (!nautilus_file_is_directory (file)) { + return NAUTILUS_REQUEST_DONE; + } + + if (file->details->deep_counts_status != NAUTILUS_REQUEST_NOT_STARTED) { + if (directory_count != NULL) { + *directory_count = file->details->deep_directory_count; + } + if (file_count != NULL) { + *file_count = file->details->deep_file_count; + } + if (unreadable_directory_count != NULL) { + *unreadable_directory_count = file->details->deep_unreadable_count; + } + if (total_size != NULL) { + *total_size = file->details->deep_size; + } + return file->details->deep_counts_status; + } + + /* For directories, or before we know the type, we haven't started. */ + type = nautilus_file_get_file_type (file); + if (type == GNOME_VFS_FILE_TYPE_UNKNOWN + || type == GNOME_VFS_FILE_TYPE_DIRECTORY) { + return NAUTILUS_REQUEST_NOT_STARTED; + } + + /* For other types, we are done, and the zeros are permanent. */ + return NAUTILUS_REQUEST_DONE; +} + static void nautilus_vfs_file_initialize (gpointer object, gpointer klass) { @@ -66,5 +190,11 @@ nautilus_vfs_file_initialize_class (gpointer klass) object_class->destroy = vfs_destroy; - /* file_class-> */ + file_class->monitor_add = vfs_file_monitor_add; + file_class->monitor_remove = vfs_file_monitor_remove; + file_class->call_when_ready = vfs_file_call_when_ready; + file_class->cancel_call_when_ready = vfs_file_cancel_call_when_ready; + file_class->check_if_ready = vfs_file_check_if_ready; + file_class->get_item_count = vfs_file_get_item_count; + file_class->get_deep_counts = vfs_file_get_deep_counts; } diff --git a/src/file-manager/fm-desktop-icon-view.c b/src/file-manager/fm-desktop-icon-view.c index 800f69d3c..e13458957 100644 --- a/src/file-manager/fm-desktop-icon-view.c +++ b/src/file-manager/fm-desktop-icon-view.c @@ -793,6 +793,12 @@ update_home_link_and_delete_copies (void) char *desktop_path, *home_link_name, *home_dir_uri, *home_uri; desktop_path = nautilus_get_desktop_directory (); + + /* Note to translators: If it's hard to compose a good home + * icon name from the user name, you can use a string without + * an "%s" here, in which case the home icon name will not + * include the user's name, which should be fine. + */ home_link_name = g_strdup_printf (_("%s's Home"), g_get_user_name ()); home_dir_uri = gnome_vfs_get_uri_from_local_path (g_get_home_dir ()); diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c index c07620da1..46d88b2d2 100644 --- a/src/file-manager/fm-directory-view.c +++ b/src/file-manager/fm-directory-view.c @@ -1513,7 +1513,7 @@ nautilus_zoom_level_from_float(float zoom_level) static void zoomable_set_zoom_level_callback (BonoboZoomable *zoomable, float level, FMDirectoryView *view) { - fm_directory_view_zoom_to_level (view, nautilus_zoom_level_from_float(level)); + fm_directory_view_zoom_to_level (view, nautilus_zoom_level_from_float (level)); } static void diff --git a/src/file-manager/nautilus-directory-view-ui.xml b/src/file-manager/nautilus-directory-view-ui.xml index 922b28bfa..5b3dbca8e 100644 --- a/src/file-manager/nautilus-directory-view-ui.xml +++ b/src/file-manager/nautilus-directory-view-ui.xml @@ -133,11 +133,11 @@ - + - + diff --git a/src/file-manager/nautilus-icon-view-ui.xml b/src/file-manager/nautilus-icon-view-ui.xml index e9c64d95c..7c0b0c1ea 100644 --- a/src/file-manager/nautilus-icon-view-ui.xml +++ b/src/file-manager/nautilus-icon-view-ui.xml @@ -117,7 +117,7 @@ - + diff --git a/src/nautilus-main.c b/src/nautilus-main.c index fcb0c098f..02c6acb9c 100644 --- a/src/nautilus-main.c +++ b/src/nautilus-main.c @@ -139,13 +139,20 @@ main (int argc, char *argv[]) struct poptOption options[] = { #ifndef NAUTILUS_OMIT_SELF_CHECK - { "check", 'c', POPT_ARG_NONE, &perform_self_check, 0, N_("Perform a quick set of self-check tests."), NULL }, + { "check", 'c', POPT_ARG_NONE, &perform_self_check, 0, + N_("Perform a quick set of self-check tests."), NULL }, #endif - { "geometry", 'g', POPT_ARG_STRING, &geometry, 0, N_("Create the initial window with the given geometry."), N_("GEOMETRY") }, - { "no-default-window", 'n', POPT_ARG_NONE, &no_default_window, 0, N_("Only create windows for explicitly specified URIs."), NULL }, - { "quit", 'q', POPT_ARG_NONE, &kill_shell, 0, N_("Quit Nautilus."), NULL }, - { "restart", '\0', POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &restart_shell, 0, N_("Restart Nautilus."), NULL }, - /* FIXME bugzilla.eazel.com 5510: These OAF options don't get translated for some reason. */ + { "geometry", 'g', POPT_ARG_STRING, &geometry, 0, + N_("Create the initial window with the given geometry."), N_("GEOMETRY") }, + { "no-default-window", 'n', POPT_ARG_NONE, &no_default_window, 0, + N_("Only create windows for explicitly specified URIs."), NULL }, + { "quit", 'q', POPT_ARG_NONE, &kill_shell, 0, + N_("Quit Nautilus."), NULL }, + { "restart", '\0', POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &restart_shell, 0, + N_("Restart Nautilus."), NULL }, + /* FIXME bugzilla.eazel.com 5228: The help for these OAF options + * should be in a separate section. + */ { NULL, '\0', POPT_ARG_INCLUDE_TABLE, &oaf_popt_options, 0, NULL, NULL }, { NULL, '\0', 0, NULL, 0, NULL, NULL } }; diff --git a/src/nautilus-shell-ui.xml b/src/nautilus-shell-ui.xml index 15e74f962..2ea455a85 100644 --- a/src/nautilus-shell-ui.xml +++ b/src/nautilus-shell-ui.xml @@ -343,7 +343,7 @@ - + diff --git a/src/nautilus-view-frame.c b/src/nautilus-view-frame.c index 144cf95dd..6db3c91e3 100644 --- a/src/nautilus-view-frame.c +++ b/src/nautilus-view-frame.c @@ -1244,6 +1244,9 @@ send_history (NautilusViewFrame *view) } history = get_history_list (view); + if (history == NULL) { + return; + } CORBA_exception_init (&ev); Nautilus_View_history_changed (get_CORBA_object (view), history, &ev); -- cgit v1.2.1