diff options
-rw-r--r-- | ChangeLog | 35 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-drag.c | 12 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-drag.h | 1 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-file-operations.c | 27 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-file-utilities.c | 36 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-file-utilities.h | 1 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-file.c | 30 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-icon-dnd.c | 10 | ||||
-rw-r--r-- | libnautilus-private/nautilus-drag.c | 12 | ||||
-rw-r--r-- | libnautilus-private/nautilus-drag.h | 1 | ||||
-rw-r--r-- | libnautilus-private/nautilus-file-operations.c | 27 | ||||
-rw-r--r-- | libnautilus-private/nautilus-file-utilities.c | 36 | ||||
-rw-r--r-- | libnautilus-private/nautilus-file-utilities.h | 1 | ||||
-rw-r--r-- | libnautilus-private/nautilus-file.c | 30 | ||||
-rw-r--r-- | libnautilus-private/nautilus-icon-dnd.c | 10 |
15 files changed, 199 insertions, 70 deletions
@@ -1,3 +1,38 @@ +2001-02-01 Pavel Cisler <pavel@eazel.com> + + reviewed by: Gene Ragan <gzr@eazel.com> + + Fix 6152 (Dragging a file to the trash will bring up a replace + dialog) + Fix 5387 (Dragging a file within Trash gives "already exists" + error) + + * libnautilus-extensions/nautilus-drag.c: + * libnautilus-extensions/nautilus-drag.h: + (nautilus_drag_items_local), (nautilus_drag_items_in_trash): + Add more convenience calls for Trash handling. + + * libnautilus-extensions/nautilus-file-utilities.h: + * libnautilus-extensions/nautilus-file-utilities.c: + (nautilus_uri_is_in_trash): + New convenience call for Trash handling. + + * libnautilus-extensions/nautilus-file.c: + (nautilus_file_is_in_trash): + Use the new nautilus_uri_is_in_trash call. + + * libnautilus-extensions/nautilus-file-operations.c: + (nautilus_file_operations_copy_move): + Handle the case where a file is dragged into a Trash window or + onto a Trash icon as if the "Move to Trash" command was issued - + if there is a name conflict with a pre-existing file in the Trash, + use a new unique name for the new file. + + * libnautilus-extensions/nautilus-icon-dnd.c: + (nautilus_icon_container_selection_items_local): + Handle files in the Trash properly - doing a parent match with + the container URI fails for these, special case Trash handling. + 2001-02-01 John Sullivan <sullivan@eazel.com> reviewed by: Pavel Cisler <pavel@eazel.com> diff --git a/libnautilus-extensions/nautilus-drag.c b/libnautilus-extensions/nautilus-drag.c index eeceb5c2d..764db8884 100644 --- a/libnautilus-extensions/nautilus-drag.c +++ b/libnautilus-extensions/nautilus-drag.c @@ -188,6 +188,7 @@ gboolean nautilus_drag_items_local (const char *target_uri_string, const GList *selection_list) { /* check if the first item on the list has target_uri_string as a parent + * FIXME: * we should really test each item but that would be slow for large selections * and currently dropped items can only be from the same container */ @@ -213,6 +214,17 @@ nautilus_drag_items_local (const char *target_uri_string, const GList *selection } gboolean +nautilus_drag_items_in_trash (const GList *selection_list) +{ + /* check if the first item on the list is in trash. + * FIXME: + * we should really test each item but that would be slow for large selections + * and currently dropped items can only be from the same container + */ + return nautilus_uri_is_in_trash (((DragSelectionItem *)selection_list->data)->uri); +} + +gboolean nautilus_drag_can_accept_item (NautilusFile *drop_target_item, const char *item_uri) { diff --git a/libnautilus-extensions/nautilus-drag.h b/libnautilus-extensions/nautilus-drag.h index f60a7c006..f25af7bb0 100644 --- a/libnautilus-extensions/nautilus-drag.h +++ b/libnautilus-extensions/nautilus-drag.h @@ -120,6 +120,7 @@ void nautilus_drag_destroy_selection_list (GList *selection_list); GList *nautilus_drag_build_selection_list (GtkSelectionData *data); gboolean nautilus_drag_items_local (const char *target_uri, const GList *selection_list); +gboolean nautilus_drag_items_in_trash (const GList *selection_list); gboolean nautilus_drag_can_accept_item (NautilusFile *drop_target_item, const char *item_uri); diff --git a/libnautilus-extensions/nautilus-file-operations.c b/libnautilus-extensions/nautilus-file-operations.c index 1030ac711..65fcecc48 100644 --- a/libnautilus-extensions/nautilus-file-operations.c +++ b/libnautilus-extensions/nautilus-file-operations.c @@ -1674,7 +1674,7 @@ nautilus_file_operations_copy_move (const GList *item_uris, SyncTransferInfo *sync_transfer_info; GnomeVFSResult result; gboolean same_fs; - gboolean is_trash_move; + gboolean target_is_trash; gboolean is_desktop_trash_link; gboolean duplicate; @@ -1690,14 +1690,14 @@ nautilus_file_operations_copy_move (const GList *item_uris, source_uri_list = NULL; target_uri_list = NULL; same_fs = TRUE; - is_trash_move = FALSE; + target_is_trash = FALSE; duplicate = copy_action != GDK_ACTION_MOVE; move_options = GNOME_VFS_XFER_RECURSIVE; if (target_dir != NULL) { if (nautilus_uri_is_trash (target_dir)) { - is_trash_move = TRUE; + target_is_trash = TRUE; } else { target_dir_uri = gnome_vfs_uri_new (target_dir); } @@ -1721,7 +1721,7 @@ nautilus_file_operations_copy_move (const GList *item_uris, source_dir_uri = gnome_vfs_uri_get_parent (source_uri); target_uri = NULL; if (target_dir != NULL) { - if (is_trash_move) { + if (target_is_trash) { gnome_vfs_find_directory (source_uri, GNOME_VFS_DIRECTORY_KIND_TRASH, &target_dir_uri, FALSE, FALSE, 0777); } @@ -1785,7 +1785,24 @@ nautilus_file_operations_copy_move (const GList *item_uris, icon_position_iterator = icon_position_iterator_new (relative_item_points, item_uris); } - if ((move_options & GNOME_VFS_XFER_REMOVESOURCE) != 0) { + if (target_is_trash && (move_options & GNOME_VFS_XFER_REMOVESOURCE) != 0) { + /* when moving to trash, handle name conflicts automatically */ + move_options |= GNOME_VFS_XFER_USE_UNIQUE_NAMES; + /* localizers: progress dialog title */ + transfer_info->operation_title = _("Moving files to the Trash"); + /* localizers: label prepended to the progress count */ + transfer_info->action_label =_("Files thrown out:"); + /* localizers: label prepended to the name of the current file moved */ + transfer_info->progress_verb =_("Moving"); + transfer_info->preparation_name =_("Preparing to Move to Trash..."); + + transfer_info->kind = TRANSFER_MOVE_TO_TRASH; + /* Do an arbitrary guess that an operation will take very little + * time and the progress shouldn't be shown. + */ + transfer_info->show_progress_dialog = + !same_fs || g_list_length ((GList *)item_uris) > 20; + } else if ((move_options & GNOME_VFS_XFER_REMOVESOURCE) != 0) { /* localizers: progress dialog title */ transfer_info->operation_title = _("Moving files"); /* localizers: label prepended to the progress count */ diff --git a/libnautilus-extensions/nautilus-file-utilities.c b/libnautilus-extensions/nautilus-file-utilities.c index 8c2a759bf..68f891629 100644 --- a/libnautilus-extensions/nautilus-file-utilities.c +++ b/libnautilus-extensions/nautilus-file-utilities.c @@ -39,6 +39,7 @@ #include <libgnomevfs/gnome-vfs-uri.h> #include <libgnomevfs/gnome-vfs-utils.h> #include <libgnomevfs/gnome-vfs-xfer.h> +#include <libgnomevfs/gnome-vfs-find-directory.h> #include <pthread.h> #include <pwd.h> #include <stdlib.h> @@ -211,6 +212,41 @@ nautilus_uri_is_trash (const char *uri) || nautilus_istr_has_prefix (uri, "gnome-trash:"); } +gboolean +nautilus_uri_is_in_trash (const char *uri) +{ + GnomeVFSURI *vfs_uri, *trash_vfs_uri; + gboolean result; + + /* Use a check for the actual trash first so that the trash + * itself will be "in trash". There are fancier ways to do + * this, but lets start with this. + */ + if (nautilus_uri_is_trash (uri)) { + return TRUE; + } + + vfs_uri = gnome_vfs_uri_new (uri); + if (vfs_uri == NULL) { + return FALSE; + } + + result = gnome_vfs_find_directory + (vfs_uri, GNOME_VFS_DIRECTORY_KIND_TRASH, + &trash_vfs_uri, FALSE, FALSE, 0777) == GNOME_VFS_OK; + + if (result) { + result = gnome_vfs_uri_equal (trash_vfs_uri, vfs_uri) + || gnome_vfs_uri_is_parent (trash_vfs_uri, vfs_uri, TRUE); + gnome_vfs_uri_unref (trash_vfs_uri); + } + + gnome_vfs_uri_unref (vfs_uri); + + return result; +} + + static gboolean nautilus_uri_is_local_scheme (const char *uri) { diff --git a/libnautilus-extensions/nautilus-file-utilities.h b/libnautilus-extensions/nautilus-file-utilities.h index 32035c329..9e97c2bbc 100644 --- a/libnautilus-extensions/nautilus-file-utilities.h +++ b/libnautilus-extensions/nautilus-file-utilities.h @@ -41,6 +41,7 @@ typedef struct NautilusReadFileHandle NautilusReadFileHandle; char * nautilus_format_uri_for_display (const char *uri); char * nautilus_make_uri_from_input (const char *location); gboolean nautilus_uri_is_trash (const char *uri); +gboolean nautilus_uri_is_in_trash (const char *uri); char * nautilus_make_uri_canonical (const char *uri); gboolean nautilus_uris_match (const char *uri_1, const char *uri_2); diff --git a/libnautilus-extensions/nautilus-file.c b/libnautilus-extensions/nautilus-file.c index 1de4ac00e..a89ba4c7b 100644 --- a/libnautilus-extensions/nautilus-file.c +++ b/libnautilus-extensions/nautilus-file.c @@ -4014,37 +4014,9 @@ nautilus_file_is_directory (NautilusFile *file) gboolean nautilus_file_is_in_trash (NautilusFile *file) { - GnomeVFSURI *file_vfs_uri, *trash_vfs_uri; - gboolean result; - g_return_val_if_fail (NAUTILUS_IS_FILE (file), FALSE); - /* Use a check for the actual trash first so that the trash - * itself will be "in trash". There are fancier ways to do - * this, but lets start with this. - */ - if (nautilus_uri_is_trash (file->details->directory->details->uri)) { - return TRUE; - } - - file_vfs_uri = nautilus_file_get_gnome_vfs_uri (file); - if (file_vfs_uri == NULL) { - return FALSE; - } - - result = gnome_vfs_find_directory - (file_vfs_uri, GNOME_VFS_DIRECTORY_KIND_TRASH, - &trash_vfs_uri, FALSE, FALSE, 0777) - == GNOME_VFS_OK; - if (result) { - result = gnome_vfs_uri_equal (trash_vfs_uri, file_vfs_uri) - || gnome_vfs_uri_is_parent (trash_vfs_uri, file_vfs_uri, TRUE); - gnome_vfs_uri_unref (trash_vfs_uri); - } - - gnome_vfs_uri_unref (file_vfs_uri); - - return result; + return nautilus_uri_is_in_trash (file->details->directory->details->uri); } GnomeVFSResult diff --git a/libnautilus-extensions/nautilus-icon-dnd.c b/libnautilus-extensions/nautilus-icon-dnd.c index 0b883e3ae..1746a8fc9 100644 --- a/libnautilus-extensions/nautilus-icon-dnd.c +++ b/libnautilus-extensions/nautilus-icon-dnd.c @@ -542,7 +542,15 @@ nautilus_icon_container_selection_items_local (const NautilusIconContainer *cont /* get the URI associated with the container */ container_uri_string = get_container_uri (container); - result = nautilus_drag_items_local (container_uri_string, items); + + if (nautilus_uri_is_trash (container_uri_string)) { + /* Special-case "trash:" because the nautilus_drag_items_local + * would not work for it. + */ + result = nautilus_drag_items_in_trash (items); + } else { + result = nautilus_drag_items_local (container_uri_string, items); + } g_free (container_uri_string); return result; diff --git a/libnautilus-private/nautilus-drag.c b/libnautilus-private/nautilus-drag.c index eeceb5c2d..764db8884 100644 --- a/libnautilus-private/nautilus-drag.c +++ b/libnautilus-private/nautilus-drag.c @@ -188,6 +188,7 @@ gboolean nautilus_drag_items_local (const char *target_uri_string, const GList *selection_list) { /* check if the first item on the list has target_uri_string as a parent + * FIXME: * we should really test each item but that would be slow for large selections * and currently dropped items can only be from the same container */ @@ -213,6 +214,17 @@ nautilus_drag_items_local (const char *target_uri_string, const GList *selection } gboolean +nautilus_drag_items_in_trash (const GList *selection_list) +{ + /* check if the first item on the list is in trash. + * FIXME: + * we should really test each item but that would be slow for large selections + * and currently dropped items can only be from the same container + */ + return nautilus_uri_is_in_trash (((DragSelectionItem *)selection_list->data)->uri); +} + +gboolean nautilus_drag_can_accept_item (NautilusFile *drop_target_item, const char *item_uri) { diff --git a/libnautilus-private/nautilus-drag.h b/libnautilus-private/nautilus-drag.h index f60a7c006..f25af7bb0 100644 --- a/libnautilus-private/nautilus-drag.h +++ b/libnautilus-private/nautilus-drag.h @@ -120,6 +120,7 @@ void nautilus_drag_destroy_selection_list (GList *selection_list); GList *nautilus_drag_build_selection_list (GtkSelectionData *data); gboolean nautilus_drag_items_local (const char *target_uri, const GList *selection_list); +gboolean nautilus_drag_items_in_trash (const GList *selection_list); gboolean nautilus_drag_can_accept_item (NautilusFile *drop_target_item, const char *item_uri); diff --git a/libnautilus-private/nautilus-file-operations.c b/libnautilus-private/nautilus-file-operations.c index 1030ac711..65fcecc48 100644 --- a/libnautilus-private/nautilus-file-operations.c +++ b/libnautilus-private/nautilus-file-operations.c @@ -1674,7 +1674,7 @@ nautilus_file_operations_copy_move (const GList *item_uris, SyncTransferInfo *sync_transfer_info; GnomeVFSResult result; gboolean same_fs; - gboolean is_trash_move; + gboolean target_is_trash; gboolean is_desktop_trash_link; gboolean duplicate; @@ -1690,14 +1690,14 @@ nautilus_file_operations_copy_move (const GList *item_uris, source_uri_list = NULL; target_uri_list = NULL; same_fs = TRUE; - is_trash_move = FALSE; + target_is_trash = FALSE; duplicate = copy_action != GDK_ACTION_MOVE; move_options = GNOME_VFS_XFER_RECURSIVE; if (target_dir != NULL) { if (nautilus_uri_is_trash (target_dir)) { - is_trash_move = TRUE; + target_is_trash = TRUE; } else { target_dir_uri = gnome_vfs_uri_new (target_dir); } @@ -1721,7 +1721,7 @@ nautilus_file_operations_copy_move (const GList *item_uris, source_dir_uri = gnome_vfs_uri_get_parent (source_uri); target_uri = NULL; if (target_dir != NULL) { - if (is_trash_move) { + if (target_is_trash) { gnome_vfs_find_directory (source_uri, GNOME_VFS_DIRECTORY_KIND_TRASH, &target_dir_uri, FALSE, FALSE, 0777); } @@ -1785,7 +1785,24 @@ nautilus_file_operations_copy_move (const GList *item_uris, icon_position_iterator = icon_position_iterator_new (relative_item_points, item_uris); } - if ((move_options & GNOME_VFS_XFER_REMOVESOURCE) != 0) { + if (target_is_trash && (move_options & GNOME_VFS_XFER_REMOVESOURCE) != 0) { + /* when moving to trash, handle name conflicts automatically */ + move_options |= GNOME_VFS_XFER_USE_UNIQUE_NAMES; + /* localizers: progress dialog title */ + transfer_info->operation_title = _("Moving files to the Trash"); + /* localizers: label prepended to the progress count */ + transfer_info->action_label =_("Files thrown out:"); + /* localizers: label prepended to the name of the current file moved */ + transfer_info->progress_verb =_("Moving"); + transfer_info->preparation_name =_("Preparing to Move to Trash..."); + + transfer_info->kind = TRANSFER_MOVE_TO_TRASH; + /* Do an arbitrary guess that an operation will take very little + * time and the progress shouldn't be shown. + */ + transfer_info->show_progress_dialog = + !same_fs || g_list_length ((GList *)item_uris) > 20; + } else if ((move_options & GNOME_VFS_XFER_REMOVESOURCE) != 0) { /* localizers: progress dialog title */ transfer_info->operation_title = _("Moving files"); /* localizers: label prepended to the progress count */ diff --git a/libnautilus-private/nautilus-file-utilities.c b/libnautilus-private/nautilus-file-utilities.c index 8c2a759bf..68f891629 100644 --- a/libnautilus-private/nautilus-file-utilities.c +++ b/libnautilus-private/nautilus-file-utilities.c @@ -39,6 +39,7 @@ #include <libgnomevfs/gnome-vfs-uri.h> #include <libgnomevfs/gnome-vfs-utils.h> #include <libgnomevfs/gnome-vfs-xfer.h> +#include <libgnomevfs/gnome-vfs-find-directory.h> #include <pthread.h> #include <pwd.h> #include <stdlib.h> @@ -211,6 +212,41 @@ nautilus_uri_is_trash (const char *uri) || nautilus_istr_has_prefix (uri, "gnome-trash:"); } +gboolean +nautilus_uri_is_in_trash (const char *uri) +{ + GnomeVFSURI *vfs_uri, *trash_vfs_uri; + gboolean result; + + /* Use a check for the actual trash first so that the trash + * itself will be "in trash". There are fancier ways to do + * this, but lets start with this. + */ + if (nautilus_uri_is_trash (uri)) { + return TRUE; + } + + vfs_uri = gnome_vfs_uri_new (uri); + if (vfs_uri == NULL) { + return FALSE; + } + + result = gnome_vfs_find_directory + (vfs_uri, GNOME_VFS_DIRECTORY_KIND_TRASH, + &trash_vfs_uri, FALSE, FALSE, 0777) == GNOME_VFS_OK; + + if (result) { + result = gnome_vfs_uri_equal (trash_vfs_uri, vfs_uri) + || gnome_vfs_uri_is_parent (trash_vfs_uri, vfs_uri, TRUE); + gnome_vfs_uri_unref (trash_vfs_uri); + } + + gnome_vfs_uri_unref (vfs_uri); + + return result; +} + + static gboolean nautilus_uri_is_local_scheme (const char *uri) { diff --git a/libnautilus-private/nautilus-file-utilities.h b/libnautilus-private/nautilus-file-utilities.h index 32035c329..9e97c2bbc 100644 --- a/libnautilus-private/nautilus-file-utilities.h +++ b/libnautilus-private/nautilus-file-utilities.h @@ -41,6 +41,7 @@ typedef struct NautilusReadFileHandle NautilusReadFileHandle; char * nautilus_format_uri_for_display (const char *uri); char * nautilus_make_uri_from_input (const char *location); gboolean nautilus_uri_is_trash (const char *uri); +gboolean nautilus_uri_is_in_trash (const char *uri); char * nautilus_make_uri_canonical (const char *uri); gboolean nautilus_uris_match (const char *uri_1, const char *uri_2); diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c index 1de4ac00e..a89ba4c7b 100644 --- a/libnautilus-private/nautilus-file.c +++ b/libnautilus-private/nautilus-file.c @@ -4014,37 +4014,9 @@ nautilus_file_is_directory (NautilusFile *file) gboolean nautilus_file_is_in_trash (NautilusFile *file) { - GnomeVFSURI *file_vfs_uri, *trash_vfs_uri; - gboolean result; - g_return_val_if_fail (NAUTILUS_IS_FILE (file), FALSE); - /* Use a check for the actual trash first so that the trash - * itself will be "in trash". There are fancier ways to do - * this, but lets start with this. - */ - if (nautilus_uri_is_trash (file->details->directory->details->uri)) { - return TRUE; - } - - file_vfs_uri = nautilus_file_get_gnome_vfs_uri (file); - if (file_vfs_uri == NULL) { - return FALSE; - } - - result = gnome_vfs_find_directory - (file_vfs_uri, GNOME_VFS_DIRECTORY_KIND_TRASH, - &trash_vfs_uri, FALSE, FALSE, 0777) - == GNOME_VFS_OK; - if (result) { - result = gnome_vfs_uri_equal (trash_vfs_uri, file_vfs_uri) - || gnome_vfs_uri_is_parent (trash_vfs_uri, file_vfs_uri, TRUE); - gnome_vfs_uri_unref (trash_vfs_uri); - } - - gnome_vfs_uri_unref (file_vfs_uri); - - return result; + return nautilus_uri_is_in_trash (file->details->directory->details->uri); } GnomeVFSResult diff --git a/libnautilus-private/nautilus-icon-dnd.c b/libnautilus-private/nautilus-icon-dnd.c index 0b883e3ae..1746a8fc9 100644 --- a/libnautilus-private/nautilus-icon-dnd.c +++ b/libnautilus-private/nautilus-icon-dnd.c @@ -542,7 +542,15 @@ nautilus_icon_container_selection_items_local (const NautilusIconContainer *cont /* get the URI associated with the container */ container_uri_string = get_container_uri (container); - result = nautilus_drag_items_local (container_uri_string, items); + + if (nautilus_uri_is_trash (container_uri_string)) { + /* Special-case "trash:" because the nautilus_drag_items_local + * would not work for it. + */ + result = nautilus_drag_items_in_trash (items); + } else { + result = nautilus_drag_items_local (container_uri_string, items); + } g_free (container_uri_string); return result; |