Commit 293e7cd0 authored by Martin Wehner's avatar Martin Wehner Committed by Martin Wehner
Browse files

Add functions nautilus_drag_can_accept_files and

2006-07-11  Martin Wehner  <martin.wehner@gmail.com>

	* libnautilus-private/nautilus-file-dnd.[ch]:
	Add functions nautilus_drag_can_accept_files and
	nautilus_drag_can_accept_info.

	* libnautilus-private/nautilus-icon-dnd.c: (receive_dropped_url),
	(receive_dropped_uri_list), (receive_dropped_text),
	(drag_data_received_callback):
	Accept the entire drag context as parameter and use
	nautilus_icon_container_find_drop_target.

	(nautilus_icon_container_find_drop_target):
	(nautilus_icon_dnd_update_drop_target):
	Use nautilus_drag_can_accept_info.

	* libnautilus-private/nautilus-marshal.list:
	Add new signature.

	* libnautilus-private/nautilus-tree-view-drag-dest.c:
	Add function get_drop_target_uri_at_pos and use it in the drop
	handlers to determine the target uris for actions.
	Rename get_drop_target to get_drop_target_uri_for path.

	(nautilus_tree_view_drag_dest_class_init):
	Adapt to new drag handler signatures.

	(set_widget_highlight):
	Fix DND highlighting of an empty tree view.

	(drag_motion_callback):
	Ignore drags on the header.

	* libnautilus-private/nautilus-tree-view-drag-dest.[ch]:
	* libnautilus-private/nautilus-icon-container.[ch]:
	* src/file-manager/fm-icon-view.c:
	* src/file-manager/fm-list-view.c:
	Add a target/parent uri parameter to the drop handler functions.

	* src/file-manager/fm-directory-view.[ch]:
	Add handling for the additional target parameter to support
	drops of URIs, URLs and text to subfolders.

	Patch from Christian Neumair  <chris@gnome-de.org>
parent e1f4d9db
2006-07-11 Martin Wehner <martin.wehner@gmail.com>
* libnautilus-private/nautilus-file-dnd.[ch]:
Add functions nautilus_drag_can_accept_files and
nautilus_drag_can_accept_info.
* libnautilus-private/nautilus-icon-dnd.c: (receive_dropped_url),
(receive_dropped_uri_list), (receive_dropped_text),
(drag_data_received_callback):
Accept the entire drag context as parameter and use
nautilus_icon_container_find_drop_target.
(nautilus_icon_container_find_drop_target):
(nautilus_icon_dnd_update_drop_target):
Use nautilus_drag_can_accept_info.
* libnautilus-private/nautilus-marshal.list:
Add new signature.
* libnautilus-private/nautilus-tree-view-drag-dest.c:
Add function get_drop_target_uri_at_pos and use it in the drop
handlers to determine the target uris for actions.
Rename get_drop_target to get_drop_target_uri_for path.
(nautilus_tree_view_drag_dest_class_init):
Adapt to new drag handler signatures.
(set_widget_highlight):
Fix DND highlighting of an empty tree view.
(drag_motion_callback):
Ignore drags on the header.
* libnautilus-private/nautilus-tree-view-drag-dest.[ch]:
* libnautilus-private/nautilus-icon-container.[ch]:
* src/file-manager/fm-icon-view.c:
* src/file-manager/fm-list-view.c:
Add a target/parent uri parameter to the drop handler functions.
* src/file-manager/fm-directory-view.[ch]:
Add handling for the additional target parameter to support
drops of URIs, URLs and text to subfolders.
Patch from Christian Neumair <chris@gnome-de.org>
2006-07-08 Christian Neumair <chris@gnome-de.org>
* libnautilus-private/nautilus-file-utilities.c:
......
......@@ -32,19 +32,14 @@
#include <eel/eel-glib-extensions.h>
#include <eel/eel-string.h>
gboolean
nautilus_drag_can_accept_item (NautilusFile *drop_target_item,
const char *item_uri)
static gboolean
nautilus_drag_can_accept_files (NautilusFile *drop_target_item)
{
NautilusDirectory *directory;
gboolean res;
if (nautilus_file_matches_uri (drop_target_item, item_uri)) {
/* can't accept itself */
return FALSE;
}
if (nautilus_file_is_directory (drop_target_item)) {
gboolean res;
/* target is a directory, accept if editable */
directory = nautilus_directory_get_for_file (drop_target_item);
res = nautilus_directory_is_editable (directory);
......@@ -68,7 +63,19 @@ nautilus_drag_can_accept_item (NautilusFile *drop_target_item,
return FALSE;
}
gboolean
nautilus_drag_can_accept_item (NautilusFile *drop_target_item,
const char *item_uri)
{
if (nautilus_file_matches_uri (drop_target_item, item_uri)) {
/* can't accept itself */
return FALSE;
}
return nautilus_drag_can_accept_files (drop_target_item);
}
gboolean
nautilus_drag_can_accept_items (NautilusFile *drop_target_item,
const GList *items)
......@@ -94,6 +101,39 @@ nautilus_drag_can_accept_items (NautilusFile *drop_target_item,
return TRUE;
}
gboolean
nautilus_drag_can_accept_info (NautilusFile *drop_target_item,
NautilusIconDndTargetType drag_type,
const GList *items)
{
switch (drag_type) {
case NAUTILUS_ICON_DND_GNOME_ICON_LIST:
return nautilus_drag_can_accept_items (drop_target_item, items);
case NAUTILUS_ICON_DND_URI_LIST:
case NAUTILUS_ICON_DND_URL:
case NAUTILUS_ICON_DND_TEXT:
return nautilus_drag_can_accept_files (drop_target_item);
case NAUTILUS_ICON_DND_KEYWORD:
return TRUE;
case NAUTILUS_ICON_DND_ROOTWINDOW_DROP:
return FALSE;
/* TODO return TRUE for folders as soon as drop handling is implemented */
case NAUTILUS_ICON_DND_COLOR:
case NAUTILUS_ICON_DND_BGIMAGE:
case NAUTILUS_ICON_DND_RESET_BACKGROUND:
return FALSE;
default:
g_assert_not_reached ();
return FALSE;
}
}
void
nautilus_drag_file_receive_dropped_keyword (NautilusFile *file, const char *keyword)
{
......
......@@ -25,6 +25,7 @@
#ifndef NAUTILUS_FILE_DND_H
#define NAUTILUS_FILE_DND_H
#include <libnautilus-private/nautilus-dnd.h>
#include <libnautilus-private/nautilus-file.h>
#define NAUTILUS_FILE_DND_ERASE_KEYWORD "erase"
......@@ -33,6 +34,9 @@ gboolean nautilus_drag_can_accept_item (NautilusFile *drop_target_i
const char *item_uri);
gboolean nautilus_drag_can_accept_items (NautilusFile *drop_target_item,
const GList *items);
gboolean nautilus_drag_can_accept_info (NautilusFile *drop_target_item,
NautilusIconDndTargetType drag_type,
const GList *items);
void nautilus_drag_file_receive_dropped_keyword (NautilusFile *file,
const char *keyword);
......
......@@ -4596,8 +4596,9 @@ nautilus_icon_container_class_init (NautilusIconContainerClass *class)
G_STRUCT_OFFSET (NautilusIconContainerClass,
handle_url),
NULL, NULL,
nautilus_marshal_VOID__STRING_ENUM_INT_INT,
G_TYPE_NONE, 4,
nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT,
G_TYPE_NONE, 5,
G_TYPE_STRING,
G_TYPE_STRING,
GDK_TYPE_DRAG_ACTION,
G_TYPE_INT,
......@@ -4609,8 +4610,9 @@ nautilus_icon_container_class_init (NautilusIconContainerClass *class)
G_STRUCT_OFFSET (NautilusIconContainerClass,
handle_uri_list),
NULL, NULL,
nautilus_marshal_VOID__STRING_ENUM_INT_INT,
G_TYPE_NONE, 4,
nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT,
G_TYPE_NONE, 5,
G_TYPE_STRING,
G_TYPE_STRING,
GDK_TYPE_DRAG_ACTION,
G_TYPE_INT,
......@@ -4622,8 +4624,9 @@ nautilus_icon_container_class_init (NautilusIconContainerClass *class)
G_STRUCT_OFFSET (NautilusIconContainerClass,
handle_text),
NULL, NULL,
nautilus_marshal_VOID__STRING_ENUM_INT_INT,
G_TYPE_NONE, 4,
nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT,
G_TYPE_NONE, 5,
G_TYPE_STRING,
G_TYPE_STRING,
GDK_TYPE_DRAG_ACTION,
G_TYPE_INT,
......
......@@ -93,24 +93,27 @@ typedef struct {
void (* context_click_selection) (NautilusIconContainer *container,
GdkEventButton *event);
void (* move_copy_items) (NautilusIconContainer *container,
GList *item_uris,
const GList *item_uris,
GdkPoint *relative_item_points,
const char *target_uri,
GdkDragAction action,
int x,
int y);
void (* handle_url) (NautilusIconContainer *container,
char *url,
const char *url,
const char *target_uri,
GdkDragAction action,
int x,
int y);
void (* handle_uri_list) (NautilusIconContainer *container,
char *uri_list,
const char *uri_list,
const char *target_uri,
GdkDragAction action,
int x,
int y);
void (* handle_text) (NautilusIconContainer *container,
char *text,
const char *text,
const char *target_uri,
GdkDragAction action,
int x,
int y);
......
......@@ -84,6 +84,10 @@ static void dnd_highlight_queue_redraw (GtkWidget *widget);
static GtkTargetList *drop_types_list = NULL;
static GtkTargetList *drop_types_list_root = NULL;
static char * nautilus_icon_container_find_drop_target (NautilusIconContainer *container,
GdkDragContext *context,
int x, int y, gboolean *icon_hit);
static EelCanvasItem *
create_selection_shadow (NautilusIconContainer *container,
GList *list)
......@@ -618,44 +622,65 @@ receive_dropped_keyword (NautilusIconContainer *container, const char *keyword,
/* handle dropped url */
static void
receive_dropped_url (NautilusIconContainer *container, const char *encoded_url, GdkDragAction action, int x, int y)
receive_dropped_url (NautilusIconContainer *container, const char *encoded_url, GdkDragContext *context, int x, int y)
{
char *drop_target;
if (encoded_url == NULL) {
return;
}
drop_target = nautilus_icon_container_find_drop_target (container, context, x, y, NULL);
g_signal_emit_by_name (container, "handle_url",
encoded_url,
action,
drop_target,
context->action,
x, y);
g_free (drop_target);
}
/* handle dropped uri list */
static void
receive_dropped_uri_list (NautilusIconContainer *container, const char *uri_list, GdkDragAction action, int x, int y)
receive_dropped_uri_list (NautilusIconContainer *container, const char *uri_list, GdkDragContext *context, int x, int y)
{
char *drop_target;
if (uri_list == NULL) {
return;
}
drop_target = nautilus_icon_container_find_drop_target (container, context, x, y, NULL);
g_signal_emit_by_name (container, "handle_uri_list",
uri_list,
action,
drop_target,
context->action,
x, y);
g_free (drop_target);
}
/* handle dropped text */
static void
receive_dropped_text (NautilusIconContainer *container, const char *text, GdkDragAction action, int x, int y)
receive_dropped_text (NautilusIconContainer *container, const char *text, GdkDragContext *context, int x, int y)
{
char *drop_target;
if (text == NULL) {
return;
}
drop_target = nautilus_icon_container_find_drop_target (container, context, x, y, NULL);
g_signal_emit_by_name (container, "handle_text",
text,
action,
drop_target,
context->action,
x, y);
g_free (drop_target);
}
static int
......@@ -939,8 +964,11 @@ nautilus_icon_container_find_drop_target (NautilusIconContainer *container,
NautilusFile *file;
char *icon_uri;
*icon_hit = FALSE;
if (container->details->dnd_info->drag_info.selection_list == NULL) {
if (icon_hit) {
*icon_hit = FALSE;
}
if (!container->details->dnd_info->drag_info.got_drop_data_type) {
return NULL;
}
......@@ -959,8 +987,9 @@ nautilus_icon_container_find_drop_target (NautilusIconContainer *container,
if (icon_uri != NULL) {
file = nautilus_file_get (icon_uri);
if (!nautilus_drag_can_accept_items (file,
container->details->dnd_info->drag_info.selection_list)) {
if (!nautilus_drag_can_accept_info (file,
container->details->dnd_info->drag_info.data_type,
container->details->dnd_info->drag_info.selection_list)) {
/* the item we dropped our selection on cannot accept the items,
* do the same thing as if we just dropped the items on the canvas
*/
......@@ -973,11 +1002,16 @@ nautilus_icon_container_find_drop_target (NautilusIconContainer *container,
}
if (drop_target_icon == NULL) {
*icon_hit = FALSE;
if (icon_hit) {
*icon_hit = FALSE;
}
return get_container_uri (container);
}
*icon_hit = TRUE;
if (icon_hit) {
*icon_hit = TRUE;
}
return nautilus_icon_container_get_icon_drop_target_uri (container, drop_target_icon);
}
......@@ -1177,10 +1211,6 @@ nautilus_icon_dnd_update_drop_target (NautilusIconContainer *container,
char *uri;
g_assert (NAUTILUS_IS_ICON_CONTAINER (container));
if ((container->details->dnd_info->drag_info.selection_list == NULL)
&& (container->details->dnd_info->drag_info.data_type != NAUTILUS_ICON_DND_KEYWORD)) {
return;
}
canvas_widget_to_world (EEL_CANVAS (container), x, y, &world_x, &world_y);
......@@ -1199,8 +1229,9 @@ nautilus_icon_dnd_update_drop_target (NautilusIconContainer *container,
file = nautilus_file_get (uri);
g_free (uri);
if (!nautilus_drag_can_accept_items (file,
container->details->dnd_info->drag_info.selection_list)) {
if (!nautilus_drag_can_accept_info (file,
container->details->dnd_info->drag_info.data_type,
container->details->dnd_info->drag_info.selection_list)) {
icon = NULL;
}
......@@ -1642,20 +1673,20 @@ drag_data_received_callback (GtkWidget *widget,
case NAUTILUS_ICON_DND_URL:
receive_dropped_url
(NAUTILUS_ICON_CONTAINER (widget),
(char *) data->data, context->action, x, y);
(char *) data->data, context, x, y);
success = TRUE;
break;
case NAUTILUS_ICON_DND_URI_LIST:
receive_dropped_uri_list
(NAUTILUS_ICON_CONTAINER (widget),
(char *) data->data, context->action, x, y);
(char *) data->data, context, x, y);
success = TRUE;
break;
case NAUTILUS_ICON_DND_TEXT:
tmp = gtk_selection_data_get_text (data);
receive_dropped_text
(NAUTILUS_ICON_CONTAINER (widget),
(char *) tmp, context->action, x, y);
(char *) tmp, context, x, y);
success = TRUE;
g_free (tmp);
break;
......
......@@ -16,5 +16,6 @@ VOID:POINTER,POINTER
VOID:POINTER,POINTER,POINTER,ENUM,INT,INT
VOID:POINTER,STRING
VOID:POINTER,STRING,ENUM,INT,INT
VOID:STRING,STRING,ENUM,INT,INT
VOID:STRING,ENUM,INT,INT
VOID:STRING,STRING
......@@ -205,8 +205,7 @@ set_widget_highlight (NautilusTreeViewDragDest *dest, gboolean highlight)
g_signal_connect_object (dest->details->tree_view,
"expose_event",
G_CALLBACK (highlight_expose),
dest,
G_CONNECT_AFTER);
dest, 0);
}
gtk_widget_queue_draw (GTK_WIDGET (dest->details->tree_view));
}
......@@ -306,7 +305,7 @@ get_drop_path (NautilusTreeViewDragDest *dest,
NautilusFile *file;
GtkTreePath *ret;
if (!path) {
if (!path || !dest->details->have_drag_data) {
return NULL;
}
......@@ -315,7 +314,9 @@ get_drop_path (NautilusTreeViewDragDest *dest,
/* Go up the tree until we find a file that can accept a drop */
while (file == NULL /* dummy row */ ||
!nautilus_drag_can_accept_items (file, dest->details->drag_list)) {
!nautilus_drag_can_accept_info (file,
dest->details->drag_type,
dest->details->drag_list)) {
if (gtk_tree_path_get_depth (ret) == 1) {
gtk_tree_path_free (ret);
ret = NULL;
......@@ -333,8 +334,8 @@ get_drop_path (NautilusTreeViewDragDest *dest,
}
static char *
get_drop_target (NautilusTreeViewDragDest *dest,
GtkTreePath *path)
get_drop_target_uri_for_path (NautilusTreeViewDragDest *dest,
GtkTreePath *path)
{
NautilusFile *file;
char *target;
......@@ -366,7 +367,7 @@ get_drop_action (NautilusTreeViewDragDest *dest,
switch (dest->details->drag_type) {
case NAUTILUS_ICON_DND_GNOME_ICON_LIST :
drop_target = get_drop_target (dest, path);
drop_target = get_drop_target_uri_for_path (dest, path);
if (!drop_target) {
return 0;
......@@ -383,9 +384,27 @@ get_drop_action (NautilusTreeViewDragDest *dest,
return action;
case NAUTILUS_ICON_DND_URL:
return nautilus_drag_default_drop_action_for_url (context);
drop_target = get_drop_target_uri_for_path (dest, path);
if (drop_target == NULL) {
return 0;
}
action = nautilus_drag_default_drop_action_for_url (context);
g_free (drop_target);
return action;
case NAUTILUS_ICON_DND_URI_LIST :
drop_target = get_drop_target_uri_for_path (dest, path);
if (drop_target == NULL) {
return 0;
}
g_free (drop_target);
return context->suggested_action;
case NAUTILUS_ICON_DND_TEXT:
......@@ -417,6 +436,7 @@ drag_motion_callback (GtkWidget *widget,
GtkTreeModel *model;
GtkTreeIter drop_iter;
GtkTreeViewDropPosition pos;
GdkWindow *bin_window;
guint action;
dest = NAUTILUS_TREE_VIEW_DRAG_DEST (data);
......@@ -430,8 +450,17 @@ drag_motion_callback (GtkWidget *widget,
}
drop_path = get_drop_path (dest, path);
action = get_drop_action (dest, context, drop_path);
action = 0;
bin_window = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget));
if (bin_window != NULL) {
int bin_x, bin_y;
gdk_window_get_position (bin_window, &bin_x, &bin_y);
if (bin_y <= y) {
/* ignore drags on the header */
action = get_drop_action (dest, context, drop_path);
}
}
gtk_tree_view_get_drag_dest_row (GTK_TREE_VIEW (widget), &old_drop_path,
NULL);
......@@ -497,24 +526,43 @@ drag_leave_callback (GtkWidget *widget,
remove_expand_timeout (dest);
}
static void
receive_uris (NautilusTreeViewDragDest *dest,
GdkDragContext *context,
GList *source_uris,
int x, int y)
static char *
get_drop_target_uri_at_pos (NautilusTreeViewDragDest *dest, int x, int y)
{
char *drop_target;
GtkTreePath *path;
GtkTreePath *drop_path;
GtkTreeViewDropPosition pos;
GdkDragAction action;
gtk_tree_view_get_dest_row_at_pos (dest->details->tree_view, x, y,
&path, &pos);
drop_path = get_drop_path (dest, path);
drop_target = get_drop_target (dest, drop_path);
drop_target = get_drop_target_uri_for_path (dest, drop_path);
if (path != NULL) {
gtk_tree_path_free (path);
}
if (drop_path != NULL) {
gtk_tree_path_free (drop_path);
}
return drop_target;
}
static void
receive_uris (NautilusTreeViewDragDest *dest,
GdkDragContext *context,
GList *source_uris,
int x, int y)
{
char *drop_target;
GdkDragAction action;
drop_target = get_drop_target_uri_at_pos (dest, x, y);
g_assert (drop_target != NULL);
if (context->action == GDK_ACTION_ASK) {
if (nautilus_drag_selection_includes_special_link (dest->details->drag_list)) {
......@@ -540,14 +588,6 @@ receive_uris (NautilusTreeViewDragDest *dest,
x, y);
}
if (path) {
gtk_tree_path_free (path);
}
if (drop_path) {
gtk_tree_path_free (drop_path);
}
g_free (drop_target);
}
......@@ -583,14 +623,22 @@ receive_dropped_uri_list (NautilusTreeViewDragDest *dest,
GdkDragContext *context,
int x, int y)
{
char *drop_target;
if (!dest->details->drag_data) {
return;
}
drop_target = get_drop_target_uri_at_pos (dest, x, y);
g_assert (drop_target != NULL);
g_signal_emit (dest, signals[HANDLE_URI_LIST], 0,
(char*)dest->details->drag_data->data,
drop_target,
context->action,
x, y);
g_free (drop_target);
}
static void
......@@ -598,18 +646,24 @@ receive_dropped_text (NautilusTreeViewDragDest *dest,
GdkDragContext *context,
int x, int y)
{
char *drop_target;
char *text;
if (!dest->details->drag_data) {
return;
}
drop_target = get_drop_target_uri_at_pos (dest, x, y);
g_assert (drop_target != NULL);
text = gtk_selection_data_get_text (dest->details->drag_data);
g_signal_emit (dest, signals[HANDLE_TEXT], 0,
(char *) text,
(char *) text, drop_target,
context->action,
x, y);
g_free (text);