summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog35
-rw-r--r--libnautilus-extensions/nautilus-drag.c12
-rw-r--r--libnautilus-extensions/nautilus-drag.h1
-rw-r--r--libnautilus-extensions/nautilus-file-operations.c27
-rw-r--r--libnautilus-extensions/nautilus-file-utilities.c36
-rw-r--r--libnautilus-extensions/nautilus-file-utilities.h1
-rw-r--r--libnautilus-extensions/nautilus-file.c30
-rw-r--r--libnautilus-extensions/nautilus-icon-dnd.c10
-rw-r--r--libnautilus-private/nautilus-drag.c12
-rw-r--r--libnautilus-private/nautilus-drag.h1
-rw-r--r--libnautilus-private/nautilus-file-operations.c27
-rw-r--r--libnautilus-private/nautilus-file-utilities.c36
-rw-r--r--libnautilus-private/nautilus-file-utilities.h1
-rw-r--r--libnautilus-private/nautilus-file.c30
-rw-r--r--libnautilus-private/nautilus-icon-dnd.c10
15 files changed, 199 insertions, 70 deletions
diff --git a/ChangeLog b/ChangeLog
index b6bd53dd8..3b8efcc99 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;