Commit 45e5a79f authored by Pavel Cisler's avatar Pavel Cisler Committed by Pavel Cisler

Fixed 1215 - inter-volume move now removes the source files. Made it so

2000-07-04  Pavel Cisler <pavel@eazel.com>

	* src/file-manager/dfos-xfer-progress-dialog.c:
	* src/file-manager/dfos-xfer-progress-dialog.h:
	(handle_xfer_ok),
	(fs_xfer), (fs_move_to_trash), (fs_delete), (fs_empty_trash):
	* src/file-manager/dfos-xfer-progress-dialog.c:
	(dfos_xfer_progress_dialog_clear):
	Fixed 1215 - inter-volume move now removes the source files.
	Made it so that when an inter-volume copy has ended and source files
	are removed, the progress dialog updates. Added a new cleanup phase
	string.

	* src/file-manager/dfos-xfer-progress-dialog.c:
	(dfos_xfer_progress_dialog_new_file),
	(set_text_unescaped_trimmed):
	Added code to unescape paths in progress dialogs.

	* src/file-manager/dfos-xfer.c:
	* src/file-manager/dfos-xfer.h:
	(nautilus_convert_to_unescaped_string_for_display),
	(handle_xfer_vfs_error), (handle_xfer_overwrite):
	Added code to unescape paths in error dialogs.

	* libnautilus-extensions/nautilus-drag.c:
	(nautilus_drag_default_drop_action),
	(nautilus_drag_modifier_based_action):
	* libnautilus-extensions/nautilus-drag.h:
	* libnautilus-extensions/nautilus-icon-dnd.c:
	(handle_nonlocal_move), (nautilus_icon_container_find_drop_target),
	(nautilus_icon_container_receive_dropped_icons),
	(nautilus_icon_container_get_drop_action), (drag_motion_callback):
	* libnautilus-extensions/nautilus-list.c:
	(nautilus_list_drag_motion):
	Reworked a whole lot to allow me to update the default copy action
	based on the drag&drop context - an inter-volume drag&drop will now
	suggest a copy as a default.
	Moved out more sharable code into nautilus-drag.c.
	Added a common routine for figuring out the drop target.

	* src/file-manager/fm-directory-view.c: (fm_directory_is_trash),
	(fm_directory_can_move_to_trash):
	Fixed a bunch of asserts caused by unreffing NULL uris.
parent bd3c344f
2000-07-04 Pavel Cisler <pavel@eazel.com>
* src/file-manager/dfos-xfer-progress-dialog.c:
* src/file-manager/dfos-xfer-progress-dialog.h:
(handle_xfer_ok),
(fs_xfer), (fs_move_to_trash), (fs_delete), (fs_empty_trash):
* src/file-manager/dfos-xfer-progress-dialog.c:
(dfos_xfer_progress_dialog_clear):
Fixed 1215 - inter-volume move now removes the source files.
Made it so that when an inter-volume copy has ended and source files
are removed, the progress dialog updates. Added a new cleanup phase
string.
* src/file-manager/dfos-xfer-progress-dialog.c:
(dfos_xfer_progress_dialog_new_file),
(set_text_unescaped_trimmed):
Added code to unescape paths in progress dialogs.
* src/file-manager/dfos-xfer.c:
* src/file-manager/dfos-xfer.h:
(nautilus_convert_to_unescaped_string_for_display),
(handle_xfer_vfs_error), (handle_xfer_overwrite):
Added code to unescape paths in error dialogs.
* libnautilus-extensions/nautilus-drag.c:
(nautilus_drag_default_drop_action),
(nautilus_drag_modifier_based_action):
* libnautilus-extensions/nautilus-drag.h:
* libnautilus-extensions/nautilus-icon-dnd.c:
(handle_nonlocal_move), (nautilus_icon_container_find_drop_target),
(nautilus_icon_container_receive_dropped_icons),
(nautilus_icon_container_get_drop_action), (drag_motion_callback):
* libnautilus-extensions/nautilus-list.c:
(nautilus_list_drag_motion):
Reworked a whole lot to allow me to update the default copy action
based on the drag&drop context - an inter-volume drag&drop will now
suggest a copy as a default.
Moved out more sharable code into nautilus-drag.c.
Added a common routine for figuring out the drop target.
* src/file-manager/fm-directory-view.c: (fm_directory_is_trash),
(fm_directory_can_move_to_trash):
Fixed a bunch of asserts caused by unreffing NULL uris.
2000-07-04 Michael Meeks <michael@helixcode.com>
* libnautilus-extensions/bonobo-stream-vfs.c (vfs_read): update
......
......@@ -27,6 +27,7 @@
#include <libgnomevfs/gnome-vfs-types.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <string.h>
#include <stdio.h>
......@@ -242,6 +243,37 @@ nautilus_drag_can_accept_items (NautilusFile *drop_target_item,
return TRUE;
}
void
nautilus_drag_default_drop_action (const char *target_uri_string, const GList *items,
int *default_action, int *non_default_action)
{
gboolean same_fs;
GnomeVFSURI *target_uri;
GnomeVFSURI *dropped_uri;
if (target_uri_string == NULL) {
*default_action = 0;
*non_default_action = 0;
return;
}
target_uri = gnome_vfs_uri_new (target_uri_string);
/* Compare the first dropped uri with the target uri for same fs match. */
dropped_uri = gnome_vfs_uri_new (((DragSelectionItem *)items->data)->uri);
same_fs = TRUE;
gnome_vfs_check_same_fs_uris (target_uri, dropped_uri, &same_fs);
gnome_vfs_uri_unref (dropped_uri);
gnome_vfs_uri_unref (target_uri);
if (same_fs) {
*default_action = GDK_ACTION_MOVE;
*non_default_action = GDK_ACTION_COPY;
} else {
*default_action = GDK_ACTION_COPY;
*non_default_action = GDK_ACTION_MOVE;
}
}
/* Encode a "x-special/gnome-icon-list" selection.
Along with the URIs of the dragged files, this encodes
......@@ -311,17 +343,17 @@ nautilus_drag_drag_data_get (GtkWidget *widget,
}
int
nautilus_drag_modifier_based_action ()
nautilus_drag_modifier_based_action (int default_action, int non_default_action)
{
GdkModifierType modifiers;
gdk_window_get_pointer (NULL, NULL, NULL, &modifiers);
if ((modifiers & GDK_CONTROL_MASK) != 0) {
return GDK_ACTION_COPY;
return non_default_action;
} else if ((modifiers & GDK_MOD1_MASK) != 0) {
return GDK_ACTION_LINK;
}
return GDK_ACTION_MOVE;
return default_action;
}
......@@ -102,6 +102,10 @@ gboolean nautilus_drag_can_accept_item (NautilusFile *drop_target_item,
const char *item_uri);
gboolean nautilus_drag_can_accept_items (NautilusFile *drop_target_item,
const GList *items);
void nautilus_drag_default_drop_action (const char *target_uri,
const GList *items,
int *default_action,
int *non_default_action);
gboolean nautilus_drag_drag_data_get (GtkWidget *widget,
GdkDragContext *context,
......@@ -110,6 +114,7 @@ gboolean nautilus_drag_drag_data_get (GtkWidget *widget,
guint32 time,
gpointer container_context,
NautilusDragEachSelectedItemIterator each_selected_item_iterator);
int nautilus_drag_modifier_based_action (void);
int nautilus_drag_modifier_based_action (int default_action,
int non_default_action);
#endif
......@@ -19,9 +19,13 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Author: Ettore Perazzoli <ettore@gnu.org> */
Authors:
Ettore Perazzoli <ettore@gnu.org>
Pavel Cisler <pavel@eazel.com>
*/
#include <config.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include "dfos-xfer-progress-dialog.h"
#include <gnome.h>
......@@ -79,49 +83,61 @@ trim_string (const char *string,
}
static void
set_text_trimmed (GtkLabel *label,
const char *text,
const char *trimmable_text,
guint max_width)
set_text_unescaped_trimmed (GtkLabel *label,
const char *text,
const char *trimmable_text,
guint max_width)
{
GdkFont *font;
char *unescaped_text;
char *trimmed_text;
char *unescaped_trimmable_text;
char *s;
guint text_width;
guint trimmable_text_width;
font = GTK_WIDGET (label)->style->font;
if (text != NULL)
text_width = gdk_string_width (font, text);
else
trimmed_text = NULL;
unescaped_text = NULL;
unescaped_trimmable_text = NULL;
if (text) {
unescaped_text = gnome_vfs_unescape_string_for_display (text);
}
if (trimmable_text) {
unescaped_trimmable_text = gnome_vfs_unescape_string_for_display (trimmable_text);
}
if (unescaped_text != NULL) {
text_width = gdk_string_width (font, unescaped_text);
} else {
text_width = 0;
}
if (trimmable_text != NULL)
trimmable_text_width = gdk_string_width (font, trimmable_text);
if (unescaped_trimmable_text != NULL)
trimmable_text_width = gdk_string_width (font, unescaped_trimmable_text);
else
trimmable_text_width = 0;
if (text_width + trimmable_text_width <= max_width) {
s = g_strconcat (text, trimmable_text, NULL);
gtk_label_set_text (GTK_LABEL (label), s);
g_free (s);
return;
s = g_strconcat (unescaped_text, unescaped_trimmable_text, NULL);
} else {
trimmed_text = trim_string (unescaped_trimmable_text,
font,
max_width - text_width,
trimmable_text_width);
s = g_strconcat (unescaped_text, trimmed_text, NULL);
}
trimmed_text = trim_string (trimmable_text,
font,
max_width - text_width,
trimmable_text_width);
s = g_strconcat (text, trimmed_text, NULL);
gtk_label_set_text (GTK_LABEL (label), s);
g_free (s);
g_free (trimmed_text);
g_free (unescaped_text);
g_free (unescaped_trimmable_text);
}
/* GnomeDialog signals. */
/* This is just to make sure the dialog is not closed without explicit
......@@ -135,7 +151,6 @@ do_close (GnomeDialog *dialog)
return FALSE;
}
/* GtkObject methods. */
static void
......@@ -148,7 +163,6 @@ destroy (GtkObject *object)
g_free (dialog->operation_string);
}
/* Initialization. */
static GtkWidget *
......@@ -215,7 +229,6 @@ class_init (DFOSXferProgressDialogClass *class)
dialog_class->close = do_close;
}
/* Public functions. */
guint
......@@ -320,19 +333,29 @@ dfos_xfer_progress_dialog_new_file (DFOSXferProgressDialog *dialog,
gtk_label_set_text (GTK_LABEL (dialog->operation_label), s);
g_free (s);
set_text_trimmed (GTK_LABEL (dialog->source_label),
dialog->from_prefix, source_uri,
DIALOG_WIDTH);
set_text_unescaped_trimmed (GTK_LABEL (dialog->source_label),
dialog->from_prefix, source_uri, DIALOG_WIDTH);
if (dialog->to_prefix != NULL && dialog->target_label != NULL)
set_text_trimmed (GTK_LABEL (dialog->target_label),
dialog->to_prefix, target_uri,
DIALOG_WIDTH);
set_text_unescaped_trimmed (GTK_LABEL (dialog->target_label),
dialog->to_prefix, target_uri, DIALOG_WIDTH);
update (dialog);
}
void
dfos_xfer_progress_dialog_clear (DFOSXferProgressDialog *dialog)
{
gtk_label_set_text (GTK_LABEL (dialog->source_label), "");
gtk_label_set_text (GTK_LABEL (dialog->target_label), "");
dialog->files_total = 0;
dialog->bytes_total = 0;
update (dialog);
}
void
dfos_xfer_progress_dialog_update (DFOSXferProgressDialog *dialog,
gulong bytes_done_in_file,
......@@ -346,7 +369,6 @@ dfos_xfer_progress_dialog_update (DFOSXferProgressDialog *dialog,
update (dialog);
}
void
dfos_xfer_progress_dialog_freeze (DFOSXferProgressDialog *dialog)
{
......
......@@ -86,6 +86,9 @@ void dfos_xfer_progress_dialog_set_operation_string
(DFOSXferProgressDialog *dialog,
const char *operation_string);
void dfos_xfer_progress_dialog_clear
(DFOSXferProgressDialog *dialog);
void dfos_xfer_progress_dialog_new_file
(DFOSXferProgressDialog *dialog,
const char *source_uri,
......
......@@ -42,12 +42,12 @@ typedef enum {
XFER_DELETE
} XferKind;
typedef struct XferInfo {
GnomeVFSAsyncHandle *handle;
GtkWidget *progress_dialog;
const char *operation_name;
const char *preparation_name;
const char *cleanup_name;
GnomeVFSXferErrorMode error_mode;
GnomeVFSXferOverwriteMode overwrite_mode;
GtkWidget *parent_view;
......@@ -75,6 +75,19 @@ xfer_info_new (GnomeVFSAsyncHandle *handle,
return info;
}
char *
nautilus_convert_to_unescaped_string_for_display (char *escaped)
{
char *result;
if (!escaped) {
return NULL;
}
result = gnome_vfs_unescape_string_for_display (escaped);
g_free (escaped);
return result;
}
static void
xfer_dialog_clicked_callback (DFOSXferProgressDialog *dialog,
int button_number,
......@@ -153,6 +166,7 @@ handle_xfer_ok (const GnomeVFSXferProgressInfo *progress_info,
case GNOME_VFS_XFER_PHASE_COPYING:
if (xfer_info->progress_dialog != NULL) {
if (progress_info->bytes_copied == 0) {
dfos_xfer_progress_dialog_new_file
(DFOS_XFER_PROGRESS_DIALOG
......@@ -181,6 +195,18 @@ handle_xfer_ok (const GnomeVFSXferProgressInfo *progress_info,
}
return TRUE;
case GNOME_VFS_XFER_PHASE_CLEANUP:
if (xfer_info->progress_dialog != NULL) {
dfos_xfer_progress_dialog_clear(
DFOS_XFER_PROGRESS_DIALOG
(xfer_info->progress_dialog));
dfos_xfer_progress_dialog_set_operation_string
(DFOS_XFER_PROGRESS_DIALOG
(xfer_info->progress_dialog),
xfer_info->cleanup_name);
}
return TRUE;
case GNOME_VFS_XFER_PHASE_COMPLETED:
nautilus_file_changes_consume_changes (TRUE);
if (xfer_info->progress_dialog != NULL) {
......@@ -204,15 +230,18 @@ handle_xfer_vfs_error (const GnomeVFSXferProgressInfo *progress_info,
int result;
char *text;
char *unescaped_name;
switch (xfer_info->error_mode) {
case GNOME_VFS_XFER_ERROR_MODE_QUERY:
unescaped_name = gnome_vfs_unescape_string_for_display (progress_info->source_name);
/* transfer error, prompt the user to continue or stop */
text = g_strdup_printf ( _("Error %s copying file %s.\n"
"Would you like to continue?"),
gnome_vfs_result_to_string (progress_info->vfs_status),
progress_info->source_name);
unescaped_name);
g_free (unescaped_name);
result = nautilus_simple_dialog
(xfer_info->parent_view, text,
_("File copy error"),
......@@ -247,10 +276,13 @@ handle_xfer_overwrite (const GnomeVFSXferProgressInfo *progress_info,
/* transfer conflict, prompt the user to replace or skip */
int result;
char *text;
char *unescaped_name;
unescaped_name = gnome_vfs_unescape_string_for_display (progress_info->target_name);
text = g_strdup_printf ( _("File %s already exists.\n"
"Would you like to replace it?"),
progress_info->target_name);
unescaped_name);
g_free (unescaped_name);
if (progress_info->duplicate_count == 1) {
/* we are going to only get one duplicate alert, don't offer
......@@ -358,7 +390,6 @@ sync_xfer_callback (GnomeVFSXferProgressInfo *progress_info, gpointer data)
return 1;
}
void
dfos_xfer (DFOS *dfos,
const gchar *source_directory_uri,
......@@ -452,6 +483,7 @@ fs_xfer (const GList *item_uris,
XferInfo *xfer_info;
char *target_dir_uri_text;
GnomeVFSResult result;
gboolean same_fs;
g_assert (item_uris != NULL);
......@@ -482,6 +514,12 @@ fs_xfer (const GList *item_uris,
move_options |= GNOME_VFS_XFER_REMOVESOURCE;
}
same_fs = TRUE;
if (source_dir_uri != NULL && target_dir_uri != NULL) {
gnome_vfs_check_same_fs_uris (source_dir_uri,
target_dir_uri, &same_fs);
}
/* set up the copy/move parameters */
xfer_info = g_new (XferInfo, 1);
xfer_info->parent_view = view;
......@@ -490,14 +528,17 @@ fs_xfer (const GList *item_uris,
if ((move_options & GNOME_VFS_XFER_REMOVESOURCE) != 0) {
xfer_info->operation_name = _("Moving");
xfer_info->preparation_name =_("Preparing To Move...");
xfer_info->cleanup_name =_("Finishing Move...");
xfer_info->kind = XFER_MOVE;
/* Do an arbitrary guess that an operation will take very little
* time and the progress shouldn't be shown.
*/
xfer_info->show_progress_dialog = g_list_length ((GList *)item_uris) > 20;
xfer_info->show_progress_dialog =
!same_fs || g_list_length ((GList *)item_uris) > 20;
} else {
xfer_info->operation_name = _("Copying");
xfer_info->preparation_name =_("Preparing To Copy...");
xfer_info->cleanup_name =_("Finishing Copy...");
xfer_info->kind = XFER_COPY;
/* always show progress during copy */
xfer_info->show_progress_dialog = TRUE;
......@@ -574,7 +615,9 @@ fs_xfer (const GList *item_uris,
g_free (target_dir_uri_text);
gnome_vfs_uri_unref (trash_dir_uri);
if (trash_dir_uri != NULL) {
gnome_vfs_uri_unref (trash_dir_uri);
}
gnome_vfs_uri_unref (target_dir_uri);
gnome_vfs_uri_unref (source_dir_uri);
nautilus_g_list_free_deep (item_names);
......@@ -681,7 +724,8 @@ fs_move_to_trash (const GList *item_uris, GtkWidget *parent_view)
_("OK"), NULL, NULL);
bail = TRUE;
} else if (gnome_vfs_uri_is_parent (uri, trash_dir_uri, TRUE)) {
item_name = gnome_vfs_uri_extract_short_name (uri);
item_name = nautilus_convert_to_unescaped_string_for_display
(gnome_vfs_uri_extract_short_name (uri));
text = g_strdup_printf ( _("You cannot throw \"%s\" "
"into the Trash."), item_name);
......@@ -716,6 +760,7 @@ fs_move_to_trash (const GList *item_uris, GtkWidget *parent_view)
xfer_info->operation_name = _("Moving to Trash");
xfer_info->preparation_name =_("Preparing to Move to Trash...");
xfer_info->cleanup_name =_("Finishing Move to Trash...");
xfer_info->error_mode = GNOME_VFS_XFER_ERROR_MODE_QUERY;
xfer_info->overwrite_mode = GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE;
xfer_info->kind = XFER_MOVE_TO_TRASH;
......@@ -756,6 +801,7 @@ fs_delete (const GList *item_uris, GtkWidget *parent_view)
xfer_info->show_progress_dialog = TRUE;
xfer_info->operation_name = _("Deleting");
xfer_info->preparation_name =_("Preparing to Delete...");
xfer_info->cleanup_name =_("Finishing Delete...");
xfer_info->error_mode = GNOME_VFS_XFER_ERROR_MODE_QUERY;
xfer_info->overwrite_mode = GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE;
xfer_info->kind = XFER_DELETE;
......@@ -801,6 +847,7 @@ fs_empty_trash (GtkWidget *parent_view)
xfer_info->show_progress_dialog = TRUE;
xfer_info->operation_name = _("Emptying the Trash");
xfer_info->preparation_name =_("Preparing to Empty the Trash...");
xfer_info->cleanup_name =_("Finishing Emptying the Trash...");
xfer_info->error_mode = GNOME_VFS_XFER_ERROR_MODE_QUERY;
xfer_info->overwrite_mode = GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE;
xfer_info->kind = XFER_EMPTY_TRASH;
......
......@@ -52,4 +52,9 @@ void fs_new_folder (GtkWidget *parent_view,
gpointer data);
void fs_delete (const GList *item_uris, GtkWidget *parent_view);
/* Prepare an escaped string for display. Unescapes a string in place.
* Frees the original string.
*/
char *nautilus_convert_to_unescaped_string_for_display (char *escaped);
#endif /* DFOS_XFER_H */
......@@ -590,10 +590,10 @@ static void
handle_nonlocal_move (NautilusIconContainer *container,
GdkDragContext *context,
int x, int y,
NautilusIcon *drop_target_icon)
const char *target_uri,
gboolean icon_hit)
{
GList *source_uris, *p;
char *target_uri;
GdkPoint *source_item_locations;
int i;
......@@ -609,7 +609,7 @@ handle_nonlocal_move (NautilusIconContainer *container,
source_uris = g_list_reverse (source_uris);
source_item_locations = NULL;
if (drop_target_icon != NULL) {
if (!icon_hit) {
/* Drop onto a container. Pass along the item points to allow placing
* the items in their same relative positions in the new container.
*/
......@@ -623,15 +623,7 @@ handle_nonlocal_move (NautilusIconContainer *container,
source_item_locations[i].y = ((DragSelectionItem *)p->data)->icon_y;
}
}
/* get the URI of either the item or the container we hit */
if (drop_target_icon != NULL) {
target_uri = nautilus_icon_container_get_icon_uri
(container, drop_target_icon);
} else {
target_uri = get_container_uri (container);
}
/* start the copy */
gtk_signal_emit_by_name (GTK_OBJECT (container), "move_copy_items",
source_uris,
......@@ -641,20 +633,19 @@ handle_nonlocal_move (NautilusIconContainer *container,
x, y);
g_list_free (source_uris);
g_free (source_item_locations);
g_free (target_uri);
}
static void
nautilus_icon_container_receive_dropped_icons (NautilusIconContainer *container,
GdkDragContext *context,
int x, int y)
static char *
nautilus_icon_container_find_drop_target (NautilusIconContainer *container,
GdkDragContext *context,
int x, int y,
gboolean *icon_hit)
{
NautilusIcon *drop_target_icon;
gboolean local_move_only;
double world_x, world_y;
if (container->details->dnd_info->drag_info.selection_list == NULL) {
return;
return NULL;
}
gnome_canvas_window_to_world (GNOME_CANVAS (container),
......@@ -679,8 +670,38 @@ nautilus_icon_container_receive_dropped_icons (NautilusIconContainer *container,
drop_target_icon = NULL;
}
if (!drop_target_icon) {
*icon_hit = FALSE;
return get_container_uri (container);
}
*icon_hit = TRUE;
return nautilus_icon_container_get_icon_uri (container, drop_target_icon);
}
static void
nautilus_icon_container_receive_dropped_icons (NautilusIconContainer *container,
GdkDragContext *context,
int x, int y)
{
char *drop_target;
gboolean local_move_only;
double world_x, world_y;
gboolean icon_hit;
if (container->details->dnd_info->drag_info.selection_list == NULL) {
return;
}
gnome_canvas_window_to_world (GNOME_CANVAS (container),
x, y, &world_x, &world_y);
drop_target = nautilus_icon_container_find_drop_target (container,
context, x, y, &icon_hit);
local_move_only = FALSE;
if (drop_target_icon == NULL && context->action == GDK_ACTION_MOVE) {
if (!icon_hit && context->action == GDK_ACTION_MOVE) {
/* we can just move the icon positions if the move ended up in
* the item's parent container
*/
......@@ -691,13 +712,44 @@ nautilus_icon_container_receive_dropped_icons (NautilusIconContainer *container,
if (local_move_only) {
handle_local_move (container, world_x, world_y);
} else {
handle_nonlocal_move (container, context, x, y, drop_target_icon);
handle_nonlocal_move (container, context, x, y, drop_target, icon_hit);
}
g_free (drop_target);
nautilus_drag_destroy_selection_list (container->details->dnd_info->drag_info.selection_list);
container->details->dnd_info->drag_info.selection_list = NULL;
}
static void
nautilus_icon_container_get_drop_action (NautilusIconContainer *container,
GdkDragContext *context,
int x, int y,
int *default_action,
int *non_default_action)
{
char *drop_target;
gboolean icon_hit;
if (container->details->dnd_info->drag_info.selection_list == NULL) {
*default_action = 0;
*non_default_action = 0;
return;
}
drop_target = nautilus_icon_container_find_drop_target (container,
context, x, y, &icon_hit);
if (!drop_target) {
*default_action = 0;
*non_default_action = 0;
return;
}
nautilus_drag_default_drop_action (drop_target,
container->details->dnd_info->drag_info.selection_list, default_action, non_default_action);
g_free (drop_target);
}
static void
set_drop_target (NautilusIconContainer *container,
NautilusIcon *icon)
......@@ -927,11 +979,22 @@ drag_motion_callback (GtkWidget *widget,
int x, int y,
guint32 time)
{
int default_action, non_default_action;
nautilus_icon_container_ensure_drag_data (NAUTILUS_ICON_CONTAINER (widget), context, time);
nautilus_icon_container_position_shadow (NAUTILUS_ICON_CONTAINER (widget), x, y);
nautilus_icon_dnd_update_drop_target (NAUTILUS_ICON_CONTAINER (widget), context, x, y);
gdk_drag_status (context, nautilus_drag_modifier_based_action (), time);
/* Find out what the drop actions are based on our drag selection and
* the drop target.
*/
nautilus_icon_container_get_drop_action (NAUTILUS_ICON_CONTAINER (widget), context, x, y,
&default_action, &non_default_action);
/* set the right drop action, choose based on modifier key state
*/
gdk_drag_status (context, nautilus_drag_modifier_based_action (default_action,
non_default_action), time);
return TRUE;
}
......
......@@ -2463,7 +2463,12 @@ nautilus_list_drag_motion (GtkWidget *widget, GdkDragContext *context,
{
NautilusList *list;
gdk_drag_status (context, nautilus_drag_modifier_based_action (), time);
/* FIXME:
* pass in the drop action default and non-default values here based on
* the drag selection and drop target
*/
gdk_drag_status (context, nautilus_drag_modifier_based_action (GDK_ACTION_MOVE,
GDK_ACTION_COPY), time);
g_assert (NAUTILUS_IS_LIST (widget));
list = NAUTILUS_LIST (widget);
......
......@@ -27,6 +27,7 @@
#include <libgnomevfs/gnome-vfs-types.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <string.h>
#include <stdio.h>
......@@ -242,6 +243,37 @@ nautilus_drag_can_accept_items (NautilusFile *drop_target_item,
return TRUE;
}
void
nautilus_drag_default_drop_action (const char *target_uri_string, const GList *items,
int *default_action, int *non_default_action)
{
gboolean same_fs;
GnomeVFSURI *target_uri;
GnomeVFSURI *dropped_uri;
if (target_uri_string == NULL) {
*default_action = 0;
*non_default_action = 0;
return;
}
target_uri = gnome_vfs_uri_new (target_uri_string);
/* Compare the first dropped uri with the target uri for same fs match. */
dropped_uri = gnome_vfs_uri_new (((DragSelectionItem *)items->data)->uri);
same_fs = TRUE;
gnome_vfs_check_same_fs_uris (target_uri, dropped_uri, &same_fs);
gnome_vfs_uri_unref (dropped_uri);
gnome_vfs_uri_unref (target_uri);