static void drag_data_received_callback (GtkWidget *widget, GdkDragContext *context, int x, int y, GtkSelectionData *data, guint info, guint32 time, gpointer user_data) { NemoDragInfo *drag_info; char *tmp; const char *tmp_raw; int length; gboolean success; drag_info = &(NEMO_ICON_CONTAINER (widget)->details->dnd_info->drag_info); drag_info->got_drop_data_type = TRUE; drag_info->data_type = info; switch (info) { case NEMO_ICON_DND_GNOME_ICON_LIST: nemo_icon_container_dropped_icon_feedback (widget, data, x, y); break; case NEMO_ICON_DND_URI_LIST: case NEMO_ICON_DND_TEXT: case NEMO_ICON_DND_XDNDDIRECTSAVE: case NEMO_ICON_DND_RAW: /* Save the data so we can do the actual work on drop. */ if (drag_info->selection_data != NULL) { gtk_selection_data_free (drag_info->selection_data); } drag_info->selection_data = gtk_selection_data_copy (data); break; /* Netscape keeps sending us the data, even though we accept the first drag */ case NEMO_ICON_DND_NETSCAPE_URL: if (drag_info->selection_data != NULL) { gtk_selection_data_free (drag_info->selection_data); drag_info->selection_data = gtk_selection_data_copy (data); } break; case NEMO_ICON_DND_ROOTWINDOW_DROP: /* Do nothing, this won't even happen, since we don't want to call get_data twice */ break; } /* this is the second use case of this callback. * we have to do the actual work for the drop. */ if (drag_info->drop_occured) { success = FALSE; switch (info) { case NEMO_ICON_DND_GNOME_ICON_LIST: nemo_icon_container_receive_dropped_icons (NEMO_ICON_CONTAINER (widget), context, x, y); break; case NEMO_ICON_DND_NETSCAPE_URL: receive_dropped_netscape_url (NEMO_ICON_CONTAINER (widget), (char *) gtk_selection_data_get_data (data), context, x, y); success = TRUE; break; case NEMO_ICON_DND_URI_LIST: receive_dropped_uri_list (NEMO_ICON_CONTAINER (widget), (char *) gtk_selection_data_get_data (data), context, x, y); success = TRUE; break; case NEMO_ICON_DND_TEXT: tmp = gtk_selection_data_get_text (data); receive_dropped_text (NEMO_ICON_CONTAINER (widget), (char *) tmp, context, x, y); success = TRUE; g_free (tmp); break; case NEMO_ICON_DND_RAW: length = gtk_selection_data_get_length (data); tmp_raw = gtk_selection_data_get_data (data); receive_dropped_raw (NEMO_ICON_CONTAINER (widget), tmp_raw, length, drag_info->direct_save_uri, context, x, y); success = TRUE; break; case NEMO_ICON_DND_ROOTWINDOW_DROP: /* Do nothing, everything is done by the sender */ break; case NEMO_ICON_DND_XDNDDIRECTSAVE: { const guchar *selection_data; gint selection_length; gint selection_format; selection_data = gtk_selection_data_get_data (drag_info->selection_data); selection_length = gtk_selection_data_get_length (drag_info->selection_data); selection_format = gtk_selection_data_get_format (drag_info->selection_data); if (selection_format == 8 && selection_length == 1 && selection_data[0] == 'F') { gtk_drag_get_data (widget, context, gdk_atom_intern (NEMO_ICON_DND_RAW_TYPE, FALSE), time); return; } else if (selection_format == 8 && selection_length == 1 && selection_data[0] == 'F' && drag_info->direct_save_uri != NULL) { GdkPoint p; GFile *location; location = g_file_new_for_uri (drag_info->direct_save_uri); nemo_file_changes_queue_file_added (location); p.x = x; p.y = y; nemo_file_changes_queue_schedule_position_set ( location, p, gdk_screen_get_number ( gtk_widget_get_screen (widget))); g_object_unref (location); nemo_file_changes_consume_changes (TRUE); success = TRUE; } break; } /* NEMO_ICON_DND_XDNDDIRECTSAVE */ } gtk_drag_finish (context, success, FALSE, time); nemo_icon_container_free_drag_data (NEMO_ICON_CONTAINER (widget)); set_drop_target (NEMO_ICON_CONTAINER (widget), NULL); /* reinitialise it for the next dnd */ drag_info->drop_occured = FALSE; } }
static gboolean drag_data_received_callback (GtkWidget *widget, GdkDragContext *context, int x, int y, GtkSelectionData *selection_data, guint info, guint32 time, gpointer data) { NautilusTreeViewDragDest *dest; const gchar *tmp; int length; gboolean success, finished; dest = NAUTILUS_TREE_VIEW_DRAG_DEST (data); if (!dest->details->have_drag_data) { dest->details->have_drag_data = TRUE; dest->details->drag_type = info; dest->details->drag_data = gtk_selection_data_copy (selection_data); if (info == NAUTILUS_ICON_DND_GNOME_ICON_LIST) { dest->details->drag_list = nautilus_drag_build_selection_list (selection_data); } } if (dest->details->drop_occurred) { success = FALSE; finished = TRUE; switch (info) { case NAUTILUS_ICON_DND_GNOME_ICON_LIST : receive_dropped_icons (dest, context, x, y); success = TRUE; break; case NAUTILUS_ICON_DND_NETSCAPE_URL : receive_dropped_netscape_url (dest, context, x, y); success = TRUE; break; case NAUTILUS_ICON_DND_URI_LIST : receive_dropped_uri_list (dest, context, x, y); success = TRUE; break; case NAUTILUS_ICON_DND_TEXT: receive_dropped_text (dest, context, x, y); success = TRUE; break; case NAUTILUS_ICON_DND_RAW: length = gtk_selection_data_get_length (selection_data); tmp = (const gchar *) gtk_selection_data_get_data (selection_data); receive_dropped_raw (dest, tmp, length, context, x, y); success = TRUE; break; case NAUTILUS_ICON_DND_XDNDDIRECTSAVE: finished = receive_xds (dest, widget, time, context, x, y); success = TRUE; break; } if (finished) { dest->details->drop_occurred = FALSE; free_drag_data (dest); gtk_drag_finish (context, success, FALSE, time); } } /* appease GtkTreeView by preventing its drag_data_receive * from being called */ g_signal_stop_emission_by_name (dest->details->tree_view, "drag-data-received"); return TRUE; }