Commit 4b45756b authored by Pavel Cisler's avatar Pavel Cisler Committed by Pavel Cisler
Browse files

Did most of bug 1371: Implemented a drop context menu that allows users to

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

	* libnautilus-extensions/nautilus-drag.c:
	(nautilus_drag_modifier_based_action),
	(nautilus_drag_drop_action_ask):
	* libnautilus-extensions/nautilus-drag.h:
	* libnautilus-extensions/nautilus-icon-container.c:
	(motion_notify_event):
	* libnautilus-extensions/nautilus-icon-dnd.c:
	(nautilus_icon_container_receive_dropped_icons),
	(nautilus_icon_dnd_init):
	* libnautilus-extensions/nautilus-list.c:
	(nautilus_list_initialize), (nautilus_list_drag_start):
	* src/file-manager/fm-list-view.c: (fm_list_handle_dropped_icons):
	Did most of bug 1371:
	Implemented a drop context menu that allows users to choose between
	Copy, Move and link.
	Added the GDK_ACTION_ASK selector and added support for it.
parent eec7aa25
2000-07-05 Pavel Cisler <pavel@eazel.com>
* libnautilus-extensions/nautilus-drag.c:
(nautilus_drag_modifier_based_action),
(nautilus_drag_drop_action_ask):
* libnautilus-extensions/nautilus-drag.h:
* libnautilus-extensions/nautilus-icon-container.c:
(motion_notify_event):
* libnautilus-extensions/nautilus-icon-dnd.c:
(nautilus_icon_container_receive_dropped_icons),
(nautilus_icon_dnd_init):
* libnautilus-extensions/nautilus-list.c:
(nautilus_list_initialize), (nautilus_list_drag_start):
* src/file-manager/fm-list-view.c: (fm_list_handle_dropped_icons):
Did most of bug 1371:
Implemented a drop context menu that allows users to choose between
Copy, Move and link.
Added the GDK_ACTION_ASK selector and added support for it.
2000-07-04 Andy Hertzfeld <andy@eazel.com>
First cut at the first-time preferences druid. It's still
......
......@@ -28,6 +28,8 @@
#include <libgnomevfs/gnome-vfs-types.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <libgnomeui/gnome-uidefs.h>
#include <libgnomeui/gnome-popup-menu.h>
#include <string.h>
#include <stdio.h>
......@@ -350,10 +352,59 @@ nautilus_drag_modifier_based_action (int default_action, int non_default_action)
if ((modifiers & GDK_CONTROL_MASK) != 0) {
return non_default_action;
} else if ((modifiers & GDK_MOD1_MASK) != 0) {
} else if ((modifiers & GDK_SHIFT_MASK) != 0) {
return GDK_ACTION_LINK;
} else if ((modifiers & GDK_MOD1_MASK) != 0) {
return GDK_ACTION_ASK;
}
return default_action;
}
/* The menu of DnD actions */
static GnomeUIInfo menu_items[] = {
GNOMEUIINFO_ITEM_NONE ("_Move here", NULL, NULL),
GNOMEUIINFO_ITEM_NONE ("_Copy here", NULL, NULL),
GNOMEUIINFO_ITEM_NONE ("_Link here", NULL, NULL),
GNOMEUIINFO_SEPARATOR,
GNOMEUIINFO_ITEM_NONE ("Cancel", NULL, NULL),
GNOMEUIINFO_END
};
/* Pops up a menu of actions to perform on dropped files */
GdkDragAction
nautilus_drag_drop_action_ask (GdkDragAction actions)
{
GtkWidget *menu;
int action;
/* Create the menu and set the sensitivity of the items based on the
* allowed actions.
*/
menu = gnome_popup_menu_new (menu_items);
gtk_widget_set_sensitive (menu_items[0].widget, (actions & GDK_ACTION_MOVE) != 0);
gtk_widget_set_sensitive (menu_items[1].widget, (actions & GDK_ACTION_COPY) != 0);
gtk_widget_set_sensitive (menu_items[2].widget, (actions & GDK_ACTION_LINK) != 0);
switch (gnome_popup_menu_do_popup_modal (menu, NULL, NULL, NULL, NULL)) {
case 0:
action = GDK_ACTION_MOVE;
break;
case 1:
action = GDK_ACTION_COPY;
break;
case 2:
action = GDK_ACTION_LINK;
break;
default:
action = -1;
}
gtk_widget_destroy (menu);
return action;
}
......@@ -117,4 +117,6 @@ gboolean nautilus_drag_drag_data_get (GtkWidget *widget,
int nautilus_drag_modifier_based_action (int default_action,
int non_default_action);
GdkDragAction nautilus_drag_drop_action_ask (GdkDragAction possible_actions);
#endif
......@@ -1988,7 +1988,8 @@ motion_notify_event (GtkWidget *widget,
nautilus_icon_dnd_begin_drag (container,
GDK_ACTION_MOVE
| GDK_ACTION_COPY
| GDK_ACTION_LINK,
| GDK_ACTION_LINK
| GDK_ACTION_ASK,
details->drag_button,
motion);
}
......
......@@ -689,30 +689,39 @@ nautilus_icon_container_receive_dropped_icons (NautilusIconContainer *container,
gboolean local_move_only;
double world_x, world_y;
gboolean icon_hit;
drop_target = NULL;
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);
if (context->action == GDK_ACTION_ASK) {
context->action = nautilus_drag_drop_action_ask
(GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
}
drop_target = nautilus_icon_container_find_drop_target (container,
context, x, y, &icon_hit);
if (context->action >= 0) {
gnome_canvas_window_to_world (GNOME_CANVAS (container),
x, y, &world_x, &world_y);
local_move_only = FALSE;
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
*/
local_move_only = nautilus_icon_container_selection_items_local
(container, container->details->dnd_info->drag_info.selection_list);
}
drop_target = nautilus_icon_container_find_drop_target (container,
context, x, y, &icon_hit);
if (local_move_only) {
handle_local_move (container, world_x, world_y);
} else {
handle_nonlocal_move (container, context, x, y, drop_target, icon_hit);
local_move_only = FALSE;
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
*/
local_move_only = nautilus_icon_container_selection_items_local
(container, container->details->dnd_info->drag_info.selection_list);
}
if (local_move_only) {
handle_local_move (container, world_x, world_y);
} else {
handle_nonlocal_move (container, context, x, y, drop_target, icon_hit);
}
}
g_free (drop_target);
......@@ -863,7 +872,8 @@ nautilus_icon_dnd_init (NautilusIconContainer *container,
gtk_drag_dest_set (GTK_WIDGET (container),
0,
drop_types, NAUTILUS_N_ELEMENTS (drop_types),
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK
| GDK_ACTION_ASK);
/* Messages for outgoing drag. */
gtk_signal_connect (GTK_OBJECT (container), "drag_data_get",
......
......@@ -471,7 +471,8 @@ nautilus_list_initialize (NautilusList *list)
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
nautilus_list_dnd_target_table,
NAUTILUS_N_ELEMENTS (nautilus_list_dnd_target_table),
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK
| GDK_ACTION_ASK);
/* Emit "selection changed" signal when parent class changes selection */
list->details->select_row_signal_id = gtk_signal_connect (GTK_OBJECT (list),
......@@ -2330,7 +2331,7 @@ nautilus_list_drag_start (GtkWidget *widget, GdkEventMotion *event)
list->details->drag_started = TRUE;
list->details->dnd_select_pending = FALSE;
context = gtk_drag_begin (widget, list->details->drag_info->target_list,
GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK,
GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK,
list->details->dnd_press_button,
(GdkEvent *) event);
......
......@@ -28,6 +28,8 @@
#include <libgnomevfs/gnome-vfs-types.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <libgnomeui/gnome-uidefs.h>
#include <libgnomeui/gnome-popup-menu.h>
#include <string.h>
#include <stdio.h>
......@@ -350,10 +352,59 @@ nautilus_drag_modifier_based_action (int default_action, int non_default_action)
if ((modifiers & GDK_CONTROL_MASK) != 0) {
return non_default_action;
} else if ((modifiers & GDK_MOD1_MASK) != 0) {
} else if ((modifiers & GDK_SHIFT_MASK) != 0) {
return GDK_ACTION_LINK;
} else if ((modifiers & GDK_MOD1_MASK) != 0) {
return GDK_ACTION_ASK;
}
return default_action;
}
/* The menu of DnD actions */
static GnomeUIInfo menu_items[] = {
GNOMEUIINFO_ITEM_NONE ("_Move here", NULL, NULL),
GNOMEUIINFO_ITEM_NONE ("_Copy here", NULL, NULL),
GNOMEUIINFO_ITEM_NONE ("_Link here", NULL, NULL),
GNOMEUIINFO_SEPARATOR,
GNOMEUIINFO_ITEM_NONE ("Cancel", NULL, NULL),
GNOMEUIINFO_END
};
/* Pops up a menu of actions to perform on dropped files */
GdkDragAction
nautilus_drag_drop_action_ask (GdkDragAction actions)
{
GtkWidget *menu;
int action;
/* Create the menu and set the sensitivity of the items based on the
* allowed actions.
*/
menu = gnome_popup_menu_new (menu_items);
gtk_widget_set_sensitive (menu_items[0].widget, (actions & GDK_ACTION_MOVE) != 0);
gtk_widget_set_sensitive (menu_items[1].widget, (actions & GDK_ACTION_COPY) != 0);
gtk_widget_set_sensitive (menu_items[2].widget, (actions & GDK_ACTION_LINK) != 0);
switch (gnome_popup_menu_do_popup_modal (menu, NULL, NULL, NULL, NULL)) {
case 0:
action = GDK_ACTION_MOVE;
break;
case 1:
action = GDK_ACTION_COPY;
break;
case 2:
action = GDK_ACTION_LINK;
break;
default:
action = -1;
}
gtk_widget_destroy (menu);
return action;
}
......@@ -117,4 +117,6 @@ gboolean nautilus_drag_drag_data_get (GtkWidget *widget,
int nautilus_drag_modifier_based_action (int default_action,
int non_default_action);
GdkDragAction nautilus_drag_drop_action_ask (GdkDragAction possible_actions);
#endif
......@@ -1988,7 +1988,8 @@ motion_notify_event (GtkWidget *widget,
nautilus_icon_dnd_begin_drag (container,
GDK_ACTION_MOVE
| GDK_ACTION_COPY
| GDK_ACTION_LINK,
| GDK_ACTION_LINK
| GDK_ACTION_ASK,
details->drag_button,
motion);
}
......
......@@ -689,30 +689,39 @@ nautilus_icon_container_receive_dropped_icons (NautilusIconContainer *container,
gboolean local_move_only;
double world_x, world_y;
gboolean icon_hit;
drop_target = NULL;
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);
if (context->action == GDK_ACTION_ASK) {
context->action = nautilus_drag_drop_action_ask
(GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
}
drop_target = nautilus_icon_container_find_drop_target (container,
context, x, y, &icon_hit);
if (context->action >= 0) {
gnome_canvas_window_to_world (GNOME_CANVAS (container),
x, y, &world_x, &world_y);
local_move_only = FALSE;
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
*/
local_move_only = nautilus_icon_container_selection_items_local
(container, container->details->dnd_info->drag_info.selection_list);
}
drop_target = nautilus_icon_container_find_drop_target (container,
context, x, y, &icon_hit);
if (local_move_only) {
handle_local_move (container, world_x, world_y);
} else {
handle_nonlocal_move (container, context, x, y, drop_target, icon_hit);
local_move_only = FALSE;
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
*/
local_move_only = nautilus_icon_container_selection_items_local
(container, container->details->dnd_info->drag_info.selection_list);
}
if (local_move_only) {
handle_local_move (container, world_x, world_y);
} else {
handle_nonlocal_move (container, context, x, y, drop_target, icon_hit);
}
}
g_free (drop_target);
......@@ -863,7 +872,8 @@ nautilus_icon_dnd_init (NautilusIconContainer *container,
gtk_drag_dest_set (GTK_WIDGET (container),
0,
drop_types, NAUTILUS_N_ELEMENTS (drop_types),
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK
| GDK_ACTION_ASK);
/* Messages for outgoing drag. */
gtk_signal_connect (GTK_OBJECT (container), "drag_data_get",
......
......@@ -471,7 +471,8 @@ nautilus_list_initialize (NautilusList *list)
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
nautilus_list_dnd_target_table,
NAUTILUS_N_ELEMENTS (nautilus_list_dnd_target_table),
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK
| GDK_ACTION_ASK);
/* Emit "selection changed" signal when parent class changes selection */
list->details->select_row_signal_id = gtk_signal_connect (GTK_OBJECT (list),
......@@ -2330,7 +2331,7 @@ nautilus_list_drag_start (GtkWidget *widget, GdkEventMotion *event)
list->details->drag_started = TRUE;
list->details->dnd_select_pending = FALSE;
context = gtk_drag_begin (widget, list->details->drag_info->target_list,
GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK,
GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK,
list->details->dnd_press_button,
(GdkEvent *) event);
......
......@@ -507,37 +507,44 @@ fm_list_handle_dropped_icons (NautilusList *list, GList *drop_data, int x, int y
source_uris = NULL;
directory_view = FM_DIRECTORY_VIEW (list_view);
/* find the item we hit and figure out if it will take the dropped items */
target_item = fm_list_nautilus_file_at (list, x, y);
if (target_item != NULL
&& !nautilus_drag_can_accept_items (target_item, drop_data)) {
target_item = NULL;
if (action == GDK_ACTION_ASK) {
action = nautilus_drag_drop_action_ask
(GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
}
list_view_uri = fm_directory_view_get_uri (directory_view);
if (target_item != NULL
|| action != GDK_ACTION_MOVE
|| !nautilus_drag_items_local (list_view_uri, drop_data)) {
/* build a list of URIs to copy */
for (p = drop_data; p != NULL; p = p->next) {
/* do a shallow copy of all the uri strings of the copied files */
source_uris = g_list_prepend (source_uris,
((DragSelectionItem *)p->data)->uri);
}
source_uris = g_list_reverse (source_uris);
/* figure out the uri of the destination */
if (target_item != NULL) {
target_item_uri = nautilus_file_get_uri (target_item);
} else {
target_item_uri = g_strdup (list_view_uri);
if (action >= 0) {
/* find the item we hit and figure out if it will take the dropped items */
target_item = fm_list_nautilus_file_at (list, x, y);
if (target_item != NULL
&& !nautilus_drag_can_accept_items (target_item, drop_data)) {
target_item = NULL;
}
list_view_uri = fm_directory_view_get_uri (directory_view);
if (target_item != NULL
|| action != GDK_ACTION_MOVE
|| !nautilus_drag_items_local (list_view_uri, drop_data)) {
/* build a list of URIs to copy */
for (p = drop_data; p != NULL; p = p->next) {
/* do a shallow copy of all the uri strings of the copied files */
source_uris = g_list_prepend (source_uris,
((DragSelectionItem *)p->data)->uri);
}
source_uris = g_list_reverse (source_uris);
/* figure out the uri of the destination */
if (target_item != NULL) {
target_item_uri = nautilus_file_get_uri (target_item);
} else {
target_item_uri = g_strdup (list_view_uri);
}
/* start the copy */
fm_directory_view_move_copy_items (source_uris, NULL,
target_item_uri, action, x, y, directory_view);
/* start the copy */
fm_directory_view_move_copy_items (source_uris, NULL,
target_item_uri, action, x, y, directory_view);
}
}
g_free (target_item_uri);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment