nautilus/nautilus-2.22.0-treeview-xds-dnd.patch
2008-05-16 13:55:30 +00:00

204 lines
7.0 KiB
Diff

--- nautilus-2.22.0-orig/libnautilus-private/nautilus-tree-view-drag-dest.c 2008-03-07 16:28:45.000000000 +0100
+++ nautilus-2.22.0-xdstree/libnautilus-private/nautilus-tree-view-drag-dest.c 2008-03-18 15:01:32.000000000 +0100
@@ -21,6 +21,7 @@
* Boston, MA 02111-1307, USA.
*
* Author: Dave Camp <dave@ximian.com>
+ * XDS support: Benedikt Meurer <benny@xfce.org> (adapted by Amos Brocco <amos.brocco@unifr.ch>)
*/
/* nautilus-tree-view-drag-dest.c: Handles drag and drop for treeviews which
@@ -38,6 +39,9 @@
#include "nautilus-icon-dnd.h"
#include "nautilus-link.h"
#include "nautilus-marshal.h"
+#include "nautilus-debug-log.h"
+#include <stdio.h>
+#include <string.h>
#define AUTO_SCROLL_MARGIN 20
@@ -56,6 +60,8 @@ struct _NautilusTreeViewDragDestDetails
guint highlight_id;
guint scroll_id;
guint expand_id;
+
+ gchar *drop_path;
};
enum {
@@ -82,7 +88,8 @@ static const GtkTargetEntry drag_types [
/* prefer "_NETSCAPE_URL" over "text/uri-list" to satisfy web browsers. */
{ NAUTILUS_ICON_DND_NETSCAPE_URL_TYPE, 0, NAUTILUS_ICON_DND_NETSCAPE_URL },
{ NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST },
- { NAUTILUS_ICON_DND_KEYWORD_TYPE, 0, NAUTILUS_ICON_DND_KEYWORD }
+ { NAUTILUS_ICON_DND_KEYWORD_TYPE, 0, NAUTILUS_ICON_DND_KEYWORD },
+ { NAUTILUS_ICON_DND_XDNDDIRECTSAVE_TYPE, 0, NAUTILUS_ICON_DND_XDNDDIRECTSAVE }, /* XDS Protocol Type */
};
@@ -408,6 +415,7 @@ get_drop_action (NautilusTreeViewDragDes
return context->suggested_action;
case NAUTILUS_ICON_DND_TEXT:
+ case NAUTILUS_ICON_DND_XDNDDIRECTSAVE:
return GDK_ACTION_COPY;
case NAUTILUS_ICON_DND_KEYWORD:
@@ -438,6 +446,7 @@ drag_motion_callback (GtkWidget *widget,
GtkTreeViewDropPosition pos;
GdkWindow *bin_window;
guint action;
+ gchar *uri_path;
dest = NAUTILUS_TREE_VIEW_DRAG_DEST (data);
@@ -464,13 +473,42 @@ drag_motion_callback (GtkWidget *widget,
gtk_tree_view_get_drag_dest_row (GTK_TREE_VIEW (widget), &old_drop_path,
NULL);
+
if (action) {
+
+ /* XDS support: I need to save the drop path here, because I didn't
+ * succeeded to get it from the drag_drop_callback (x and y coordinates
+ * passed to it do not match drop position, so I cannot get the target later) */
+
+ uri_path = get_drop_target_uri_for_path (dest, drop_path);
+
+ if (uri_path != NULL) {
+ if (dest->details->drop_path != NULL) {
+ /* A path is already in, free and replace */
+ if (strcmp (uri_path, dest->details->drop_path) != 0) {
+ g_free (dest->details->drop_path);
+ dest->details->drop_path = g_strdup (uri_path);
+ }
+ } else {
+ /* No previous path is there */
+ dest->details->drop_path = g_strdup (uri_path);
+ }
+
+ g_free (uri_path);
+
+ }
+
+ /* End XDS support */
+
set_drag_dest_row (dest, drop_path);
+
model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
if (drop_path == NULL || (old_drop_path != NULL &&
gtk_tree_path_compare (old_drop_path, drop_path) != 0)) {
remove_expand_timeout (dest);
}
+
+
if (dest->details->expand_id == 0 && drop_path != NULL) {
gtk_tree_model_get_iter (model, &drop_iter, drop_path);
if (gtk_tree_model_iter_has_child (model, &drop_iter)) {
@@ -767,6 +805,22 @@ drag_data_received_callback (GtkWidget *
receive_dropped_keyword (dest, context, x, y);
success = TRUE;
break;
+ case NAUTILUS_ICON_DND_XDNDDIRECTSAVE:
+ /* Indicate that we don't provide "F" fallback */
+ if (G_UNLIKELY (dest->details->drag_data->format == 8
+ && dest->details->drag_data->length == 1
+ && dest->details->drag_data->data[0] == 'F')) {
+ gdk_property_change (GDK_DRAWABLE (context->source_window),
+ gdk_atom_intern (NAUTILUS_ICON_DND_XDNDDIRECTSAVE_TYPE, FALSE),
+ gdk_atom_intern ("text/plain", FALSE), 8,
+ GDK_PROP_MODE_REPLACE, (const guchar *) "", 0);
+ } else if (G_LIKELY (dest->details->drag_data->format == 8
+ && dest->details->drag_data->length == 1
+ && dest->details->drag_data->data[0] == 'S')) {
+ /* FIXME: XDS Successful... Do we need to tell the treeview to update itself? */
+ }
+ success = TRUE;
+ break;
}
dest->details->drop_occurred = FALSE;
@@ -791,8 +845,71 @@ drag_drop_callback (GtkWidget *widget,
gpointer data)
{
NautilusTreeViewDragDest *dest;
+ guint info;
+ guchar *prop_text;
+ gint prop_len;
+ GFile *base, *child;
+ gchar *uri = NULL;
+ GdkAtom target;
dest = NAUTILUS_TREE_VIEW_DRAG_DEST (data);
+
+ target = gtk_drag_dest_find_target (GTK_WIDGET (dest->details->tree_view),
+ context,
+ NULL);
+
+ info = dest->details->drag_type;
+
+ if (G_UNLIKELY (target == GDK_NONE)) {
+ return FALSE;
+ } else if (target != GDK_NONE) {
+ if (info == NAUTILUS_ICON_DND_XDNDDIRECTSAVE) {
+ if (gdk_property_get (context->source_window, gdk_atom_intern (NAUTILUS_ICON_DND_XDNDDIRECTSAVE_TYPE, FALSE),
+ gdk_atom_intern ("text/plain", FALSE), 0, 1024, FALSE, NULL, NULL,
+ &prop_len, &prop_text) && prop_text != NULL) {
+ /* Zero-terminate the string */
+ prop_text = g_realloc (prop_text, prop_len + 1);
+ prop_text[prop_len] = '\0';
+
+ /* Verify that the file name provided by the source is valid */
+ if (G_LIKELY (*prop_text != '\0' && strchr ((const gchar *) prop_text, G_DIR_SEPARATOR) == NULL)) {
+
+ /* Retrieve drop target path */
+ if (dest->details->drop_path != NULL) {
+ /* Resolve relative path */
+ base = g_file_new_for_uri (dest->details->drop_path);
+ child = g_file_get_child (base, (const gchar *) prop_text);
+ uri = g_file_get_uri (child);
+ g_object_unref (base);
+ g_object_unref (child);
+ /* Change the property */
+ gdk_property_change (GDK_DRAWABLE (context->source_window),
+ gdk_atom_intern (NAUTILUS_ICON_DND_XDNDDIRECTSAVE_TYPE, FALSE),
+ gdk_atom_intern ("text/plain", FALSE), 8,
+ GDK_PROP_MODE_REPLACE, (const guchar *) uri,
+ strlen (uri));
+
+ /* Free memory */
+ g_free (dest->details->drop_path);
+ dest->details->drop_path = NULL;
+ g_free (uri);
+ } else {
+ nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+ "Could not retrieve XDS drag site ");
+ }
+ } else {
+ /* tell the user that the file name provided by the X Direct Save source is invalid */
+ nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
+ "Invalid filename provided by XDS drag site");
+ }
+ /* cleanup */
+ g_free (prop_text);
+ }
+ /* if uri == NULL, we didn't set the property */
+ if (G_UNLIKELY (uri == NULL))
+ return FALSE;
+ }
+ }
dest->details->drop_occurred = TRUE;
@@ -845,6 +962,9 @@ nautilus_tree_view_drag_dest_finalize (G
dest = NAUTILUS_TREE_VIEW_DRAG_DEST (object);
free_drag_data (dest);
+
+ if (dest->details->drop_path)
+ g_free (dest->details->drop_path);
g_free (dest->details);