1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
6 * Copyright (C) 2002 Sun Microsystems, Inc.
8 * Nautilus is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
13 * Nautilus is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
23 * Author: Dave Camp <dave@ximian.com>
26 /* nautilus-tree-view-drag-dest.c: Handles drag and drop for treeviews which
27 * contain a hierarchy of files
31 #include "nautilus-tree-view-drag-dest.h"
33 #include <eel/eel-gtk-macros.h>
34 #include <gtk/gtkmain.h>
35 #include <gtk/gtksignal.h>
36 #include <libgnome/gnome-macros.h>
37 #include "nautilus-file-dnd.h"
38 #include "nautilus-icon-dnd.h"
39 #include "nautilus-link.h"
40 #include "nautilus-marshal.h"
42 #define AUTO_SCROLL_MARGIN 20
44 #define HOVER_EXPAND_TIMEOUT 1000
46 struct _NautilusTreeViewDragDestDetails
{
47 GtkTreeView
*tree_view
;
49 gboolean drop_occurred
;
51 gboolean have_drag_data
;
53 GtkSelectionData
*drag_data
;
71 static void nautilus_tree_view_drag_dest_instance_init (NautilusTreeViewDragDest
*dest
);
72 static void nautilus_tree_view_drag_dest_class_init (NautilusTreeViewDragDestClass
*class);
74 static guint signals
[LAST_SIGNAL
];
76 GNOME_CLASS_BOILERPLATE (NautilusTreeViewDragDest
,
77 nautilus_tree_view_drag_dest
,
78 GObject
, G_TYPE_OBJECT
);
80 static const GtkTargetEntry drag_types
[] = {
81 { NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE
, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST
},
82 /* prefer "_NETSCAPE_URL" over "text/uri-list" to satisfy web browsers. */
83 { NAUTILUS_ICON_DND_NETSCAPE_URL_TYPE
, 0, NAUTILUS_ICON_DND_NETSCAPE_URL
},
84 { NAUTILUS_ICON_DND_URI_LIST_TYPE
, 0, NAUTILUS_ICON_DND_URI_LIST
},
85 { NAUTILUS_ICON_DND_KEYWORD_TYPE
, 0, NAUTILUS_ICON_DND_KEYWORD
}
90 gtk_tree_view_vertical_autoscroll (GtkTreeView
*tree_view
)
92 GdkRectangle visible_rect
;
93 GtkAdjustment
*vadjustment
;
99 window
= gtk_tree_view_get_bin_window (tree_view
);
100 vadjustment
= gtk_tree_view_get_vadjustment (tree_view
);
102 gdk_window_get_pointer (window
, NULL
, &y
, NULL
);
104 y
+= vadjustment
->value
;
106 gtk_tree_view_get_visible_rect (tree_view
, &visible_rect
);
108 offset
= y
- (visible_rect
.y
+ 2 * AUTO_SCROLL_MARGIN
);
110 offset
= y
- (visible_rect
.y
+ visible_rect
.height
- 2 * AUTO_SCROLL_MARGIN
);
116 value
= CLAMP (vadjustment
->value
+ offset
, 0.0,
117 vadjustment
->upper
- vadjustment
->page_size
);
118 gtk_adjustment_set_value (vadjustment
, value
);
122 scroll_timeout (gpointer data
)
124 GtkTreeView
*tree_view
= GTK_TREE_VIEW (data
);
126 gtk_tree_view_vertical_autoscroll (tree_view
);
132 remove_scroll_timeout (NautilusTreeViewDragDest
*dest
)
134 if (dest
->details
->scroll_id
) {
135 g_source_remove (dest
->details
->scroll_id
);
136 dest
->details
->scroll_id
= 0;
141 expand_timeout (gpointer data
)
143 GtkTreeView
*tree_view
;
144 GtkTreePath
*drop_path
;
146 tree_view
= GTK_TREE_VIEW (data
);
148 gtk_tree_view_get_drag_dest_row (tree_view
, &drop_path
, NULL
);
151 gtk_tree_view_expand_row (tree_view
, drop_path
, FALSE
);
152 gtk_tree_path_free (drop_path
);
159 remove_expand_timeout (NautilusTreeViewDragDest
*dest
)
161 if (dest
->details
->expand_id
) {
162 g_source_remove (dest
->details
->expand_id
);
163 dest
->details
->expand_id
= 0;
168 highlight_expose (GtkWidget
*widget
,
169 GdkEventExpose
*event
,
172 GdkWindow
*bin_window
;
176 if (GTK_WIDGET_DRAWABLE (widget
)) {
178 gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget
));
180 gdk_drawable_get_size (bin_window
, &width
, &height
);
182 gtk_paint_focus (widget
->style
,
184 GTK_WIDGET_STATE (widget
),
187 "treeview-drop-indicator",
188 0, 0, width
, height
);
195 set_widget_highlight (NautilusTreeViewDragDest
*dest
, gboolean highlight
)
197 if (!highlight
&& dest
->details
->highlight_id
) {
198 g_signal_handler_disconnect (dest
->details
->tree_view
,
199 dest
->details
->highlight_id
);
200 dest
->details
->highlight_id
= 0;
203 if (highlight
&& !dest
->details
->highlight_id
) {
204 dest
->details
->highlight_id
=
205 g_signal_connect_object (dest
->details
->tree_view
,
207 G_CALLBACK (highlight_expose
),
210 gtk_widget_queue_draw (GTK_WIDGET (dest
->details
->tree_view
));
214 set_drag_dest_row (NautilusTreeViewDragDest
*dest
,
218 set_widget_highlight (dest
, FALSE
);
219 gtk_tree_view_set_drag_dest_row
220 (dest
->details
->tree_view
,
222 GTK_TREE_VIEW_DROP_INTO_OR_BEFORE
);
224 set_widget_highlight (dest
, TRUE
);
225 gtk_tree_view_set_drag_dest_row (dest
->details
->tree_view
,
232 clear_drag_dest_row (NautilusTreeViewDragDest
*dest
)
234 gtk_tree_view_set_drag_dest_row (dest
->details
->tree_view
, NULL
, 0);
235 set_widget_highlight (dest
, FALSE
);
239 get_drag_data (NautilusTreeViewDragDest
*dest
,
240 GdkDragContext
*context
,
245 target
= gtk_drag_dest_find_target (GTK_WIDGET (dest
->details
->tree_view
),
249 gtk_drag_get_data (GTK_WIDGET (dest
->details
->tree_view
),
250 context
, target
, time
);
254 free_drag_data (NautilusTreeViewDragDest
*dest
)
256 dest
->details
->have_drag_data
= FALSE
;
258 if (dest
->details
->drag_data
) {
259 gtk_selection_data_free (dest
->details
->drag_data
);
260 dest
->details
->drag_data
= NULL
;
263 if (dest
->details
->drag_list
) {
264 nautilus_drag_destroy_selection_list (dest
->details
->drag_list
);
265 dest
->details
->drag_list
= NULL
;
270 get_root_uri (NautilusTreeViewDragDest
*dest
)
274 g_signal_emit (dest
, signals
[GET_ROOT_URI
], 0, &uri
);
279 static NautilusFile
*
280 file_for_path (NautilusTreeViewDragDest
*dest
, GtkTreePath
*path
)
286 g_signal_emit (dest
, signals
[GET_FILE_FOR_PATH
], 0, path
, &file
);
288 uri
= get_root_uri (dest
);
292 file
= nautilus_file_get_by_uri (uri
);
302 get_drop_path (NautilusTreeViewDragDest
*dest
,
308 if (!path
|| !dest
->details
->have_drag_data
) {
312 ret
= gtk_tree_path_copy (path
);
313 file
= file_for_path (dest
, ret
);
315 /* Go up the tree until we find a file that can accept a drop */
316 while (file
== NULL
/* dummy row */ ||
317 !nautilus_drag_can_accept_info (file
,
318 dest
->details
->drag_type
,
319 dest
->details
->drag_list
)) {
320 if (gtk_tree_path_get_depth (ret
) == 1) {
321 gtk_tree_path_free (ret
);
325 gtk_tree_path_up (ret
);
327 nautilus_file_unref (file
);
328 file
= file_for_path (dest
, ret
);
331 nautilus_file_unref (file
);
337 get_drop_target_uri_for_path (NautilusTreeViewDragDest
*dest
,
343 file
= file_for_path (dest
, path
);
348 target
= nautilus_file_get_drop_target_uri (file
);
349 nautilus_file_unref (file
);
355 get_drop_action (NautilusTreeViewDragDest
*dest
,
356 GdkDragContext
*context
,
362 if (!dest
->details
->have_drag_data
||
363 (dest
->details
->drag_type
== NAUTILUS_ICON_DND_GNOME_ICON_LIST
&&
364 dest
->details
->drag_list
== NULL
)) {
368 switch (dest
->details
->drag_type
) {
369 case NAUTILUS_ICON_DND_GNOME_ICON_LIST
:
370 drop_target
= get_drop_target_uri_for_path (dest
, path
);
376 nautilus_drag_default_drop_action_for_icons
379 dest
->details
->drag_list
,
382 g_free (drop_target
);
386 case NAUTILUS_ICON_DND_NETSCAPE_URL
:
387 drop_target
= get_drop_target_uri_for_path (dest
, path
);
389 if (drop_target
== NULL
) {
393 action
= nautilus_drag_default_drop_action_for_netscape_url (context
);
395 g_free (drop_target
);
399 case NAUTILUS_ICON_DND_URI_LIST
:
400 drop_target
= get_drop_target_uri_for_path (dest
, path
);
402 if (drop_target
== NULL
) {
406 g_free (drop_target
);
408 return context
->suggested_action
;
410 case NAUTILUS_ICON_DND_TEXT
:
411 return GDK_ACTION_COPY
;
413 case NAUTILUS_ICON_DND_KEYWORD
:
419 return GDK_ACTION_COPY
;
426 drag_motion_callback (GtkWidget
*widget
,
427 GdkDragContext
*context
,
433 NautilusTreeViewDragDest
*dest
;
435 GtkTreePath
*drop_path
, *old_drop_path
;
437 GtkTreeIter drop_iter
;
438 GtkTreeViewDropPosition pos
;
439 GdkWindow
*bin_window
;
442 dest
= NAUTILUS_TREE_VIEW_DRAG_DEST (data
);
444 gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget
),
448 if (!dest
->details
->have_drag_data
) {
449 get_drag_data (dest
, context
, time
);
451 drop_path
= get_drop_path (dest
, path
);
454 bin_window
= gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget
));
455 if (bin_window
!= NULL
) {
457 gdk_window_get_position (bin_window
, &bin_x
, &bin_y
);
459 /* ignore drags on the header */
460 action
= get_drop_action (dest
, context
, drop_path
);
464 gtk_tree_view_get_drag_dest_row (GTK_TREE_VIEW (widget
), &old_drop_path
,
468 set_drag_dest_row (dest
, drop_path
);
469 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (widget
));
470 if (drop_path
== NULL
|| (old_drop_path
!= NULL
&&
471 gtk_tree_path_compare (old_drop_path
, drop_path
) != 0)) {
472 remove_expand_timeout (dest
);
474 if (dest
->details
->expand_id
== 0 && drop_path
!= NULL
) {
475 gtk_tree_model_get_iter (model
, &drop_iter
, drop_path
);
476 if (gtk_tree_model_iter_has_child (model
, &drop_iter
)) {
477 dest
->details
->expand_id
= g_timeout_add (HOVER_EXPAND_TIMEOUT
,
479 dest
->details
->tree_view
);
483 clear_drag_dest_row (dest
);
484 remove_expand_timeout (dest
);
488 gtk_tree_path_free (path
);
492 gtk_tree_path_free (drop_path
);
496 gtk_tree_path_free (old_drop_path
);
499 if (dest
->details
->scroll_id
== 0) {
500 dest
->details
->scroll_id
=
503 dest
->details
->tree_view
);
506 gdk_drag_status (context
, action
, time
);
512 drag_leave_callback (GtkWidget
*widget
,
513 GdkDragContext
*context
,
517 NautilusTreeViewDragDest
*dest
;
519 dest
= NAUTILUS_TREE_VIEW_DRAG_DEST (data
);
521 clear_drag_dest_row (dest
);
523 free_drag_data (dest
);
525 remove_scroll_timeout (dest
);
526 remove_expand_timeout (dest
);
530 get_drop_target_uri_at_pos (NautilusTreeViewDragDest
*dest
, int x
, int y
)
534 GtkTreePath
*drop_path
;
535 GtkTreeViewDropPosition pos
;
537 gtk_tree_view_get_dest_row_at_pos (dest
->details
->tree_view
, x
, y
,
540 drop_path
= get_drop_path (dest
, path
);
542 drop_target
= get_drop_target_uri_for_path (dest
, drop_path
);
545 gtk_tree_path_free (path
);
548 if (drop_path
!= NULL
) {
549 gtk_tree_path_free (drop_path
);
556 receive_uris (NautilusTreeViewDragDest
*dest
,
557 GdkDragContext
*context
,
562 GdkDragAction action
;
564 drop_target
= get_drop_target_uri_at_pos (dest
, x
, y
);
565 g_assert (drop_target
!= NULL
);
567 if (context
->action
== GDK_ACTION_ASK
) {
568 if (nautilus_drag_selection_includes_special_link (dest
->details
->drag_list
)) {
569 /* We only want to move the trash */
570 action
= GDK_ACTION_MOVE
;
572 action
= GDK_ACTION_MOVE
| GDK_ACTION_COPY
| GDK_ACTION_LINK
;
574 context
->action
= nautilus_drag_drop_action_ask
575 (GTK_WIDGET (dest
->details
->tree_view
), action
);
578 /* We only want to copy external uris */
579 if (dest
->details
->drag_type
== NAUTILUS_ICON_DND_URI_LIST
) {
580 action
= GDK_ACTION_COPY
;
583 if (context
->action
> 0) {
584 if (!nautilus_drag_uris_local (drop_target
, source_uris
)) {
585 g_signal_emit (dest
, signals
[MOVE_COPY_ITEMS
], 0,
593 g_free (drop_target
);
597 receive_dropped_icons (NautilusTreeViewDragDest
*dest
,
598 GdkDragContext
*context
,
604 /* FIXME: ignore local only moves */
606 if (!dest
->details
->drag_list
) {
611 for (l
= dest
->details
->drag_list
; l
!= NULL
; l
= l
->next
) {
612 source_uris
= g_list_prepend (source_uris
,
613 ((NautilusDragSelectionItem
*)l
->data
)->uri
);
616 source_uris
= g_list_reverse (source_uris
);
618 receive_uris (dest
, context
, source_uris
, x
, y
);
620 g_list_free (source_uris
);
624 receive_dropped_uri_list (NautilusTreeViewDragDest
*dest
,
625 GdkDragContext
*context
,
630 if (!dest
->details
->drag_data
) {
634 drop_target
= get_drop_target_uri_at_pos (dest
, x
, y
);
635 g_assert (drop_target
!= NULL
);
637 g_signal_emit (dest
, signals
[HANDLE_URI_LIST
], 0,
638 (char*)dest
->details
->drag_data
->data
,
643 g_free (drop_target
);
647 receive_dropped_text (NautilusTreeViewDragDest
*dest
,
648 GdkDragContext
*context
,
654 if (!dest
->details
->drag_data
) {
658 drop_target
= get_drop_target_uri_at_pos (dest
, x
, y
);
659 g_assert (drop_target
!= NULL
);
661 text
= gtk_selection_data_get_text (dest
->details
->drag_data
);
662 g_signal_emit (dest
, signals
[HANDLE_TEXT
], 0,
663 (char *) text
, drop_target
,
668 g_free (drop_target
);
673 receive_dropped_netscape_url (NautilusTreeViewDragDest
*dest
,
674 GdkDragContext
*context
,
679 if (!dest
->details
->drag_data
) {
683 drop_target
= get_drop_target_uri_at_pos (dest
, x
, y
);
684 g_assert (drop_target
!= NULL
);
686 g_signal_emit (dest
, signals
[HANDLE_NETSCAPE_URL
], 0,
687 (char*)dest
->details
->drag_data
->data
,
692 g_free (drop_target
);
696 receive_dropped_keyword (NautilusTreeViewDragDest
*dest
,
697 GdkDragContext
*context
,
700 char *drop_target_uri
;
701 NautilusFile
*drop_target_file
;
703 if (!dest
->details
->drag_data
) {
707 drop_target_uri
= get_drop_target_uri_at_pos (dest
, x
, y
);
708 g_assert (drop_target_uri
!= NULL
);
710 drop_target_file
= nautilus_file_get_by_uri (drop_target_uri
);
712 if (drop_target_file
!= NULL
) {
713 nautilus_drag_file_receive_dropped_keyword (drop_target_file
,
714 (char *) dest
->details
->drag_data
->data
);
715 nautilus_file_unref (drop_target_file
);
718 g_free (drop_target_uri
);
722 drag_data_received_callback (GtkWidget
*widget
,
723 GdkDragContext
*context
,
726 GtkSelectionData
*selection_data
,
731 NautilusTreeViewDragDest
*dest
;
734 dest
= NAUTILUS_TREE_VIEW_DRAG_DEST (data
);
736 if (!dest
->details
->have_drag_data
) {
737 dest
->details
->have_drag_data
= TRUE
;
738 dest
->details
->drag_type
= info
;
739 dest
->details
->drag_data
=
740 gtk_selection_data_copy (selection_data
);
741 if (info
== NAUTILUS_ICON_DND_GNOME_ICON_LIST
) {
742 dest
->details
->drag_list
=
743 nautilus_drag_build_selection_list (selection_data
);
747 if (dest
->details
->drop_occurred
) {
750 case NAUTILUS_ICON_DND_GNOME_ICON_LIST
:
751 receive_dropped_icons (dest
, context
, x
, y
);
754 case NAUTILUS_ICON_DND_NETSCAPE_URL
:
755 receive_dropped_netscape_url (dest
, context
, x
, y
);
758 case NAUTILUS_ICON_DND_URI_LIST
:
759 receive_dropped_uri_list (dest
, context
, x
, y
);
762 case NAUTILUS_ICON_DND_TEXT
:
763 receive_dropped_text (dest
, context
, x
, y
);
766 case NAUTILUS_ICON_DND_KEYWORD
:
767 receive_dropped_keyword (dest
, context
, x
, y
);
772 dest
->details
->drop_occurred
= FALSE
;
773 free_drag_data (dest
);
774 gtk_drag_finish (context
, success
, FALSE
, time
);
777 /* appease GtkTreeView by preventing its drag_data_receive
778 * from being called */
779 g_signal_stop_emission_by_name (dest
->details
->tree_view
,
780 "drag_data_received");
786 drag_drop_callback (GtkWidget
*widget
,
787 GdkDragContext
*context
,
793 NautilusTreeViewDragDest
*dest
;
795 dest
= NAUTILUS_TREE_VIEW_DRAG_DEST (data
);
797 dest
->details
->drop_occurred
= TRUE
;
799 get_drag_data (dest
, context
, time
);
800 remove_scroll_timeout (dest
);
801 remove_expand_timeout (dest
);
802 clear_drag_dest_row (dest
);
808 tree_view_weak_notify (gpointer user_data
,
811 NautilusTreeViewDragDest
*dest
;
813 dest
= NAUTILUS_TREE_VIEW_DRAG_DEST (user_data
);
815 remove_scroll_timeout (dest
);
816 remove_expand_timeout (dest
);
818 dest
->details
->tree_view
= NULL
;
822 nautilus_tree_view_drag_dest_dispose (GObject
*object
)
824 NautilusTreeViewDragDest
*dest
;
826 dest
= NAUTILUS_TREE_VIEW_DRAG_DEST (object
);
828 if (dest
->details
->tree_view
) {
829 g_object_weak_unref (G_OBJECT (dest
->details
->tree_view
),
830 tree_view_weak_notify
,
834 remove_scroll_timeout (dest
);
835 remove_expand_timeout (dest
);
837 EEL_CALL_PARENT (G_OBJECT_CLASS
, dispose
, (object
));
841 nautilus_tree_view_drag_dest_finalize (GObject
*object
)
843 NautilusTreeViewDragDest
*dest
;
845 dest
= NAUTILUS_TREE_VIEW_DRAG_DEST (object
);
847 free_drag_data (dest
);
849 g_free (dest
->details
);
851 EEL_CALL_PARENT (G_OBJECT_CLASS
, finalize
, (object
));
855 nautilus_tree_view_drag_dest_instance_init (NautilusTreeViewDragDest
*dest
)
857 dest
->details
= g_new0 (NautilusTreeViewDragDestDetails
, 1);
861 nautilus_tree_view_drag_dest_class_init (NautilusTreeViewDragDestClass
*class)
863 GObjectClass
*gobject_class
;
865 gobject_class
= G_OBJECT_CLASS (class);
867 gobject_class
->dispose
= nautilus_tree_view_drag_dest_dispose
;
868 gobject_class
->finalize
= nautilus_tree_view_drag_dest_finalize
;
870 signals
[GET_ROOT_URI
] =
871 g_signal_new ("get_root_uri",
872 G_TYPE_FROM_CLASS (class),
874 G_STRUCT_OFFSET (NautilusTreeViewDragDestClass
,
877 nautilus_marshal_STRING__VOID
,
879 signals
[GET_FILE_FOR_PATH
] =
880 g_signal_new ("get_file_for_path",
881 G_TYPE_FROM_CLASS (class),
883 G_STRUCT_OFFSET (NautilusTreeViewDragDestClass
,
886 nautilus_marshal_OBJECT__BOXED
,
887 NAUTILUS_TYPE_FILE
, 1,
889 signals
[MOVE_COPY_ITEMS
] =
890 g_signal_new ("move_copy_items",
891 G_TYPE_FROM_CLASS (class),
893 G_STRUCT_OFFSET (NautilusTreeViewDragDestClass
,
897 nautilus_marshal_VOID__POINTER_STRING_ENUM_INT_INT
,
901 GDK_TYPE_DRAG_ACTION
,
904 signals
[HANDLE_NETSCAPE_URL
] =
905 g_signal_new ("handle_netscape_url",
906 G_TYPE_FROM_CLASS (class),
908 G_STRUCT_OFFSET (NautilusTreeViewDragDestClass
,
909 handle_netscape_url
),
911 nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT
,
915 GDK_TYPE_DRAG_ACTION
,
918 signals
[HANDLE_URI_LIST
] =
919 g_signal_new ("handle_uri_list",
920 G_TYPE_FROM_CLASS (class),
922 G_STRUCT_OFFSET (NautilusTreeViewDragDestClass
,
925 nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT
,
929 GDK_TYPE_DRAG_ACTION
,
932 signals
[HANDLE_TEXT
] =
933 g_signal_new ("handle_text",
934 G_TYPE_FROM_CLASS (class),
936 G_STRUCT_OFFSET (NautilusTreeViewDragDestClass
,
939 nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT
,
943 GDK_TYPE_DRAG_ACTION
,
950 NautilusTreeViewDragDest
*
951 nautilus_tree_view_drag_dest_new (GtkTreeView
*tree_view
)
953 NautilusTreeViewDragDest
*dest
;
954 GtkTargetList
*targets
;
956 dest
= g_object_new (NAUTILUS_TYPE_TREE_VIEW_DRAG_DEST
, NULL
);
958 dest
->details
->tree_view
= tree_view
;
959 g_object_weak_ref (G_OBJECT (dest
->details
->tree_view
),
960 tree_view_weak_notify
, dest
);
962 gtk_drag_dest_set (GTK_WIDGET (tree_view
),
963 0, drag_types
, G_N_ELEMENTS (drag_types
),
964 GDK_ACTION_MOVE
| GDK_ACTION_COPY
| GDK_ACTION_LINK
| GDK_ACTION_ASK
);
966 targets
= gtk_drag_dest_get_target_list (GTK_WIDGET (tree_view
));
967 gtk_target_list_add_text_targets (targets
, NAUTILUS_ICON_DND_TEXT
);
969 g_signal_connect_object (tree_view
,
971 G_CALLBACK (drag_motion_callback
),
973 g_signal_connect_object (tree_view
,
975 G_CALLBACK (drag_leave_callback
),
977 g_signal_connect_object (tree_view
,
979 G_CALLBACK (drag_drop_callback
),
981 g_signal_connect_object (tree_view
,
982 "drag_data_received",
983 G_CALLBACK (drag_data_received_callback
),