Updated Slovenian translation
[nautilus.git] / libnautilus-private / nautilus-tree-view-drag-dest.c
blob8383e628da3ca6d3598c206a86795e67bc228c9a
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
3 /*
4 * Nautilus
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
30 #include <config.h>
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;
52 guint drag_type;
53 GtkSelectionData *drag_data;
54 GList *drag_list;
56 guint highlight_id;
57 guint scroll_id;
58 guint expand_id;
61 enum {
62 GET_ROOT_URI,
63 GET_FILE_FOR_PATH,
64 MOVE_COPY_ITEMS,
65 HANDLE_NETSCAPE_URL,
66 HANDLE_URI_LIST,
67 HANDLE_TEXT,
68 LAST_SIGNAL
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 }
89 static void
90 gtk_tree_view_vertical_autoscroll (GtkTreeView *tree_view)
92 GdkRectangle visible_rect;
93 GtkAdjustment *vadjustment;
94 GdkWindow *window;
95 int y;
96 int offset;
97 float value;
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);
109 if (offset > 0) {
110 offset = y - (visible_rect.y + visible_rect.height - 2 * AUTO_SCROLL_MARGIN);
111 if (offset < 0) {
112 return;
116 value = CLAMP (vadjustment->value + offset, 0.0,
117 vadjustment->upper - vadjustment->page_size);
118 gtk_adjustment_set_value (vadjustment, value);
121 static int
122 scroll_timeout (gpointer data)
124 GtkTreeView *tree_view = GTK_TREE_VIEW (data);
126 gtk_tree_view_vertical_autoscroll (tree_view);
128 return TRUE;
131 static void
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;
140 static int
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);
150 if (drop_path) {
151 gtk_tree_view_expand_row (tree_view, drop_path, FALSE);
152 gtk_tree_path_free (drop_path);
155 return FALSE;
158 static void
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;
167 static gboolean
168 highlight_expose (GtkWidget *widget,
169 GdkEventExpose *event,
170 gpointer data)
172 GdkWindow *bin_window;
173 int width;
174 int height;
176 if (GTK_WIDGET_DRAWABLE (widget)) {
177 bin_window =
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,
183 bin_window,
184 GTK_WIDGET_STATE (widget),
185 NULL,
186 widget,
187 "treeview-drop-indicator",
188 0, 0, width, height);
191 return FALSE;
194 static void
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,
206 "expose_event",
207 G_CALLBACK (highlight_expose),
208 dest, 0);
210 gtk_widget_queue_draw (GTK_WIDGET (dest->details->tree_view));
213 static void
214 set_drag_dest_row (NautilusTreeViewDragDest *dest,
215 GtkTreePath *path)
217 if (path) {
218 set_widget_highlight (dest, FALSE);
219 gtk_tree_view_set_drag_dest_row
220 (dest->details->tree_view,
221 path,
222 GTK_TREE_VIEW_DROP_INTO_OR_BEFORE);
223 } else {
224 set_widget_highlight (dest, TRUE);
225 gtk_tree_view_set_drag_dest_row (dest->details->tree_view,
226 NULL,
231 static void
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);
238 static void
239 get_drag_data (NautilusTreeViewDragDest *dest,
240 GdkDragContext *context,
241 guint32 time)
243 GdkAtom target;
245 target = gtk_drag_dest_find_target (GTK_WIDGET (dest->details->tree_view),
246 context,
247 NULL);
249 gtk_drag_get_data (GTK_WIDGET (dest->details->tree_view),
250 context, target, time);
253 static void
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;
269 static char *
270 get_root_uri (NautilusTreeViewDragDest *dest)
272 char *uri;
274 g_signal_emit (dest, signals[GET_ROOT_URI], 0, &uri);
276 return uri;
279 static NautilusFile *
280 file_for_path (NautilusTreeViewDragDest *dest, GtkTreePath *path)
282 NautilusFile *file;
283 char *uri;
285 if (path) {
286 g_signal_emit (dest, signals[GET_FILE_FOR_PATH], 0, path, &file);
287 } else {
288 uri = get_root_uri (dest);
290 file = NULL;
291 if (uri != NULL) {
292 file = nautilus_file_get_by_uri (uri);
295 g_free (uri);
298 return file;
301 static GtkTreePath *
302 get_drop_path (NautilusTreeViewDragDest *dest,
303 GtkTreePath *path)
305 NautilusFile *file;
306 GtkTreePath *ret;
308 if (!path || !dest->details->have_drag_data) {
309 return NULL;
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);
322 ret = NULL;
323 break;
324 } else {
325 gtk_tree_path_up (ret);
327 nautilus_file_unref (file);
328 file = file_for_path (dest, ret);
331 nautilus_file_unref (file);
333 return ret;
336 static char *
337 get_drop_target_uri_for_path (NautilusTreeViewDragDest *dest,
338 GtkTreePath *path)
340 NautilusFile *file;
341 char *target;
343 file = file_for_path (dest, path);
344 if (file == NULL) {
345 return NULL;
348 target = nautilus_file_get_drop_target_uri (file);
349 nautilus_file_unref (file);
351 return target;
354 static guint
355 get_drop_action (NautilusTreeViewDragDest *dest,
356 GdkDragContext *context,
357 GtkTreePath *path)
359 char *drop_target;
360 int action;
362 if (!dest->details->have_drag_data ||
363 (dest->details->drag_type == NAUTILUS_ICON_DND_GNOME_ICON_LIST &&
364 dest->details->drag_list == NULL)) {
365 return 0;
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);
372 if (!drop_target) {
373 return 0;
376 nautilus_drag_default_drop_action_for_icons
377 (context,
378 drop_target,
379 dest->details->drag_list,
380 &action);
382 g_free (drop_target);
384 return action;
386 case NAUTILUS_ICON_DND_NETSCAPE_URL:
387 drop_target = get_drop_target_uri_for_path (dest, path);
389 if (drop_target == NULL) {
390 return 0;
393 action = nautilus_drag_default_drop_action_for_netscape_url (context);
395 g_free (drop_target);
397 return action;
399 case NAUTILUS_ICON_DND_URI_LIST :
400 drop_target = get_drop_target_uri_for_path (dest, path);
402 if (drop_target == NULL) {
403 return 0;
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:
415 if (!path) {
416 return 0;
419 return GDK_ACTION_COPY;
422 return 0;
425 static gboolean
426 drag_motion_callback (GtkWidget *widget,
427 GdkDragContext *context,
428 int x,
429 int y,
430 guint32 time,
431 gpointer data)
433 NautilusTreeViewDragDest *dest;
434 GtkTreePath *path;
435 GtkTreePath *drop_path, *old_drop_path;
436 GtkTreeModel *model;
437 GtkTreeIter drop_iter;
438 GtkTreeViewDropPosition pos;
439 GdkWindow *bin_window;
440 guint action;
442 dest = NAUTILUS_TREE_VIEW_DRAG_DEST (data);
444 gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget),
445 x, y, &path, &pos);
448 if (!dest->details->have_drag_data) {
449 get_drag_data (dest, context, time);
451 drop_path = get_drop_path (dest, path);
453 action = 0;
454 bin_window = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget));
455 if (bin_window != NULL) {
456 int bin_x, bin_y;
457 gdk_window_get_position (bin_window, &bin_x, &bin_y);
458 if (bin_y <= 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,
465 NULL);
467 if (action) {
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,
478 expand_timeout,
479 dest->details->tree_view);
482 } else {
483 clear_drag_dest_row (dest);
484 remove_expand_timeout (dest);
487 if (path) {
488 gtk_tree_path_free (path);
491 if (drop_path) {
492 gtk_tree_path_free (drop_path);
495 if (old_drop_path) {
496 gtk_tree_path_free (old_drop_path);
499 if (dest->details->scroll_id == 0) {
500 dest->details->scroll_id =
501 g_timeout_add (150,
502 scroll_timeout,
503 dest->details->tree_view);
506 gdk_drag_status (context, action, time);
508 return TRUE;
511 static void
512 drag_leave_callback (GtkWidget *widget,
513 GdkDragContext *context,
514 guint32 time,
515 gpointer data)
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);
529 static char *
530 get_drop_target_uri_at_pos (NautilusTreeViewDragDest *dest, int x, int y)
532 char *drop_target;
533 GtkTreePath *path;
534 GtkTreePath *drop_path;
535 GtkTreeViewDropPosition pos;
537 gtk_tree_view_get_dest_row_at_pos (dest->details->tree_view, x, y,
538 &path, &pos);
540 drop_path = get_drop_path (dest, path);
542 drop_target = get_drop_target_uri_for_path (dest, drop_path);
544 if (path != NULL) {
545 gtk_tree_path_free (path);
548 if (drop_path != NULL) {
549 gtk_tree_path_free (drop_path);
552 return drop_target;
555 static void
556 receive_uris (NautilusTreeViewDragDest *dest,
557 GdkDragContext *context,
558 GList *source_uris,
559 int x, int y)
561 char *drop_target;
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;
571 } else {
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,
586 source_uris,
587 drop_target,
588 context->action,
589 x, y);
593 g_free (drop_target);
596 static void
597 receive_dropped_icons (NautilusTreeViewDragDest *dest,
598 GdkDragContext *context,
599 int x, int y)
601 GList *source_uris;
602 GList *l;
604 /* FIXME: ignore local only moves */
606 if (!dest->details->drag_list) {
607 return;
610 source_uris = NULL;
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);
623 static void
624 receive_dropped_uri_list (NautilusTreeViewDragDest *dest,
625 GdkDragContext *context,
626 int x, int y)
628 char *drop_target;
630 if (!dest->details->drag_data) {
631 return;
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,
639 drop_target,
640 context->action,
641 x, y);
643 g_free (drop_target);
646 static void
647 receive_dropped_text (NautilusTreeViewDragDest *dest,
648 GdkDragContext *context,
649 int x, int y)
651 char *drop_target;
652 char *text;
654 if (!dest->details->drag_data) {
655 return;
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,
664 context->action,
665 x, y);
667 g_free (text);
668 g_free (drop_target);
672 static void
673 receive_dropped_netscape_url (NautilusTreeViewDragDest *dest,
674 GdkDragContext *context,
675 int x, int y)
677 char *drop_target;
679 if (!dest->details->drag_data) {
680 return;
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,
688 drop_target,
689 context->action,
690 x, y);
692 g_free (drop_target);
695 static void
696 receive_dropped_keyword (NautilusTreeViewDragDest *dest,
697 GdkDragContext *context,
698 int x, int y)
700 char *drop_target_uri;
701 NautilusFile *drop_target_file;
703 if (!dest->details->drag_data) {
704 return;
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);
721 static gboolean
722 drag_data_received_callback (GtkWidget *widget,
723 GdkDragContext *context,
724 int x,
725 int y,
726 GtkSelectionData *selection_data,
727 guint info,
728 guint32 time,
729 gpointer data)
731 NautilusTreeViewDragDest *dest;
732 gboolean success;
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) {
748 success = FALSE;
749 switch (info) {
750 case NAUTILUS_ICON_DND_GNOME_ICON_LIST :
751 receive_dropped_icons (dest, context, x, y);
752 success = TRUE;
753 break;
754 case NAUTILUS_ICON_DND_NETSCAPE_URL :
755 receive_dropped_netscape_url (dest, context, x, y);
756 success = TRUE;
757 break;
758 case NAUTILUS_ICON_DND_URI_LIST :
759 receive_dropped_uri_list (dest, context, x, y);
760 success = TRUE;
761 break;
762 case NAUTILUS_ICON_DND_TEXT:
763 receive_dropped_text (dest, context, x, y);
764 success = TRUE;
765 break;
766 case NAUTILUS_ICON_DND_KEYWORD:
767 receive_dropped_keyword (dest, context, x, y);
768 success = TRUE;
769 break;
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");
782 return TRUE;
785 static gboolean
786 drag_drop_callback (GtkWidget *widget,
787 GdkDragContext *context,
788 int x,
789 int y,
790 guint32 time,
791 gpointer data)
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);
804 return TRUE;
807 static void
808 tree_view_weak_notify (gpointer user_data,
809 GObject *object)
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;
821 static void
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,
831 dest);
834 remove_scroll_timeout (dest);
835 remove_expand_timeout (dest);
837 EEL_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
840 static void
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));
854 static void
855 nautilus_tree_view_drag_dest_instance_init (NautilusTreeViewDragDest *dest)
857 dest->details = g_new0 (NautilusTreeViewDragDestDetails, 1);
860 static void
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),
873 G_SIGNAL_RUN_LAST,
874 G_STRUCT_OFFSET (NautilusTreeViewDragDestClass,
875 get_root_uri),
876 NULL, NULL,
877 nautilus_marshal_STRING__VOID,
878 G_TYPE_STRING, 0);
879 signals[GET_FILE_FOR_PATH] =
880 g_signal_new ("get_file_for_path",
881 G_TYPE_FROM_CLASS (class),
882 G_SIGNAL_RUN_LAST,
883 G_STRUCT_OFFSET (NautilusTreeViewDragDestClass,
884 get_file_for_path),
885 NULL, NULL,
886 nautilus_marshal_OBJECT__BOXED,
887 NAUTILUS_TYPE_FILE, 1,
888 GTK_TYPE_TREE_PATH);
889 signals[MOVE_COPY_ITEMS] =
890 g_signal_new ("move_copy_items",
891 G_TYPE_FROM_CLASS (class),
892 G_SIGNAL_RUN_LAST,
893 G_STRUCT_OFFSET (NautilusTreeViewDragDestClass,
894 move_copy_items),
895 NULL, NULL,
897 nautilus_marshal_VOID__POINTER_STRING_ENUM_INT_INT,
898 G_TYPE_NONE, 5,
899 G_TYPE_POINTER,
900 G_TYPE_STRING,
901 GDK_TYPE_DRAG_ACTION,
902 G_TYPE_INT,
903 G_TYPE_INT);
904 signals[HANDLE_NETSCAPE_URL] =
905 g_signal_new ("handle_netscape_url",
906 G_TYPE_FROM_CLASS (class),
907 G_SIGNAL_RUN_LAST,
908 G_STRUCT_OFFSET (NautilusTreeViewDragDestClass,
909 handle_netscape_url),
910 NULL, NULL,
911 nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT,
912 G_TYPE_NONE, 5,
913 G_TYPE_STRING,
914 G_TYPE_STRING,
915 GDK_TYPE_DRAG_ACTION,
916 G_TYPE_INT,
917 G_TYPE_INT);
918 signals[HANDLE_URI_LIST] =
919 g_signal_new ("handle_uri_list",
920 G_TYPE_FROM_CLASS (class),
921 G_SIGNAL_RUN_LAST,
922 G_STRUCT_OFFSET (NautilusTreeViewDragDestClass,
923 handle_uri_list),
924 NULL, NULL,
925 nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT,
926 G_TYPE_NONE, 5,
927 G_TYPE_STRING,
928 G_TYPE_STRING,
929 GDK_TYPE_DRAG_ACTION,
930 G_TYPE_INT,
931 G_TYPE_INT);
932 signals[HANDLE_TEXT] =
933 g_signal_new ("handle_text",
934 G_TYPE_FROM_CLASS (class),
935 G_SIGNAL_RUN_LAST,
936 G_STRUCT_OFFSET (NautilusTreeViewDragDestClass,
937 handle_text),
938 NULL, NULL,
939 nautilus_marshal_VOID__STRING_STRING_ENUM_INT_INT,
940 G_TYPE_NONE, 5,
941 G_TYPE_STRING,
942 G_TYPE_STRING,
943 GDK_TYPE_DRAG_ACTION,
944 G_TYPE_INT,
945 G_TYPE_INT);
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,
970 "drag_motion",
971 G_CALLBACK (drag_motion_callback),
972 dest, 0);
973 g_signal_connect_object (tree_view,
974 "drag_leave",
975 G_CALLBACK (drag_leave_callback),
976 dest, 0);
977 g_signal_connect_object (tree_view,
978 "drag_drop",
979 G_CALLBACK (drag_drop_callback),
980 dest, 0);
981 g_signal_connect_object (tree_view,
982 "drag_data_received",
983 G_CALLBACK (drag_data_received_callback),
984 dest, 0);
986 return dest;