[nautilus: 1/47] dnd: move DnD slot proxying code to src/



commit 97e67f49279ad87737541249ef09b99c4bc1d9fe
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Tue Dec 21 14:48:59 2010 +0100

    dnd: move DnD slot proxying code to src/

 libnautilus-private/nautilus-dnd.c |  303 -----------------------------
 libnautilus-private/nautilus-dnd.h |   26 ---
 src/Makefile.am                    |    2 +
 src/nautilus-notebook.c            |   13 +-
 src/nautilus-pathbar.c             |   18 +-
 src/nautilus-window-slot-dnd.c     |  369 ++++++++++++++++++++++++++++++++++++
 src/nautilus-window-slot-dnd.h     |   41 ++++
 7 files changed, 423 insertions(+), 349 deletions(-)
---
diff --git a/libnautilus-private/nautilus-dnd.c b/libnautilus-private/nautilus-dnd.c
index ec6d0bf..592c438 100644
--- a/libnautilus-private/nautilus-dnd.c
+++ b/libnautilus-private/nautilus-dnd.c
@@ -24,8 +24,6 @@
    	    Ettore Perazzoli <ettore gnu org>
 */
 
-/* FIXME: This should really be back in Nautilus, not here in Eel. */
-
 #include <config.h>
 #include "nautilus-dnd.h"
 
@@ -957,304 +955,3 @@ nautilus_drag_selection_includes_special_link (GList *selection_list)
 	
 	return FALSE;
 }
-
-static gboolean
-slot_proxy_drag_motion (GtkWidget          *widget,
-			GdkDragContext     *context,
-			int                 x,
-			int                 y,
-			unsigned int        time,
-			gpointer            user_data)
-{
-	NautilusDragSlotProxyInfo *drag_info;
-	NautilusWindowSlotInfo *target_slot;
-	GtkWidget *window;
-	GdkAtom target;
-	int action;
-	char *target_uri;
-
-	drag_info = user_data;
-
-	action = 0;
-
-	if (gtk_drag_get_source_widget (context) == widget) {
-		goto out;
-	}
-
-	window = gtk_widget_get_toplevel (widget);
-	g_assert (NAUTILUS_IS_WINDOW_INFO (window));
-
-	if (!drag_info->have_data) {
-		target = gtk_drag_dest_find_target (widget, context, NULL);
-
-		if (target == GDK_NONE) {
-			goto out;
-		}
-
-		gtk_drag_get_data (widget, context, target, time);
-	}
-
-	target_uri = NULL;
-	if (drag_info->target_location != NULL) {
-		target_uri = g_file_get_uri (drag_info->target_location);
-	} else {
-		if (drag_info->target_slot != NULL) {
-			target_slot = drag_info->target_slot;
-		} else {
-			target_slot = nautilus_window_info_get_active_slot (NAUTILUS_WINDOW_INFO (window));
-		}
-
-		if (target_slot != NULL) {
-			target_uri = nautilus_window_slot_info_get_current_location (target_slot);
-		}
-	}
-
-	if (drag_info->have_data &&
-	    drag_info->have_valid_data) {
-		if (drag_info->info == NAUTILUS_ICON_DND_GNOME_ICON_LIST) {
-			nautilus_drag_default_drop_action_for_icons (context, target_uri,
-								     drag_info->data.selection_list,
-								     &action);
-		} else if (drag_info->info == NAUTILUS_ICON_DND_URI_LIST) {
-			action = nautilus_drag_default_drop_action_for_uri_list (context, target_uri);
-		} else if (drag_info->info == NAUTILUS_ICON_DND_NETSCAPE_URL) {
-			action = nautilus_drag_default_drop_action_for_netscape_url (context);
-		}
-	}
-
-	g_free (target_uri);
-
-out:
-	if (action != 0) {
-		gtk_drag_highlight (widget);
-	} else {
-		gtk_drag_unhighlight (widget);
-	}
-
-	gdk_drag_status (context, action, time);
-
-	return TRUE;
-}
-
-static void
-drag_info_clear (NautilusDragSlotProxyInfo *drag_info)
-{
-	if (!drag_info->have_data) {
-		goto out;
-	}
-
-	if (drag_info->info == NAUTILUS_ICON_DND_GNOME_ICON_LIST) {
-		nautilus_drag_destroy_selection_list (drag_info->data.selection_list);
-	} else if (drag_info->info == NAUTILUS_ICON_DND_URI_LIST) {
-		g_list_free (drag_info->data.uri_list);
-	} else if (drag_info->info == NAUTILUS_ICON_DND_NETSCAPE_URL) {
-		g_free (drag_info->data.netscape_url);
-	}
-
-out:
-	drag_info->have_data = FALSE;
-	drag_info->have_valid_data = FALSE;
-
-	drag_info->drop_occured = FALSE;
-}
-
-static void
-slot_proxy_drag_leave (GtkWidget          *widget,
-		       GdkDragContext     *context,
-		       unsigned int        time,
-		       gpointer            user_data)
-{
-	NautilusDragSlotProxyInfo *drag_info;
-
-	drag_info = user_data;
-
-	gtk_drag_unhighlight (widget);
-	drag_info_clear (drag_info);
-}
-
-static gboolean
-slot_proxy_drag_drop (GtkWidget          *widget,
-		      GdkDragContext     *context,
-		      int                 x,
-		      int                 y,
-		      unsigned int        time,
-		      gpointer            user_data)
-{
-	GdkAtom target;
-	NautilusDragSlotProxyInfo *drag_info;
-
-	drag_info = user_data;
-	g_assert (!drag_info->have_data);
-
-	drag_info->drop_occured = TRUE;
-
-	target = gtk_drag_dest_find_target (widget, context, NULL);
-	gtk_drag_get_data (widget, context, target, time);
-
-	return TRUE;
-}
-
-
-static void
-slot_proxy_handle_drop (GtkWidget                *widget,
-			GdkDragContext           *context,
-			unsigned int              time,
-			NautilusDragSlotProxyInfo *drag_info)
-{
-	GtkWidget *window;
-	NautilusWindowSlotInfo *target_slot;
-	NautilusView *target_view;
-	char *target_uri;
-	GList *uri_list;
-
-	if (!drag_info->have_data ||
-	    !drag_info->have_valid_data) {
-		gtk_drag_finish (context, FALSE, FALSE, time);
-		drag_info_clear (drag_info);
-		return;
-	}
-
-	window = gtk_widget_get_toplevel (widget);
-	g_assert (NAUTILUS_IS_WINDOW_INFO (window));
-
-	if (drag_info->target_slot != NULL) {
-		target_slot = drag_info->target_slot;
-	} else {
-		target_slot = nautilus_window_info_get_active_slot (NAUTILUS_WINDOW_INFO (window));
-	}
-
-	target_uri = NULL;
-	if (drag_info->target_location != NULL) {
-		target_uri = g_file_get_uri (drag_info->target_location);
-	} else if (target_slot != NULL) {
-		target_uri = nautilus_window_slot_info_get_current_location (target_slot);
-	}
-
-	target_view = NULL;
-	if (target_slot != NULL) {
-		target_view = nautilus_window_slot_info_get_current_view (target_slot);
-	}
-
-	if (target_slot != NULL && target_view != NULL) {
-		if (drag_info->info == NAUTILUS_ICON_DND_GNOME_ICON_LIST) {
-			uri_list = nautilus_drag_uri_list_from_selection_list (drag_info->data.selection_list);
-			g_assert (uri_list != NULL);
-
-			nautilus_view_drop_proxy_received_uris (target_view,
-								uri_list,
-								target_uri,
-								gdk_drag_context_get_selected_action (context));
-			g_list_free_full (uri_list, g_free);
-		} else if (drag_info->info == NAUTILUS_ICON_DND_URI_LIST) {
-			nautilus_view_drop_proxy_received_uris (target_view,
-								drag_info->data.uri_list,
-								target_uri,
-								gdk_drag_context_get_selected_action (context));
-		} if (drag_info->info == NAUTILUS_ICON_DND_NETSCAPE_URL) {
-			nautilus_view_drop_proxy_received_netscape_url (target_view,
-									drag_info->data.netscape_url,
-									target_uri,
-									gdk_drag_context_get_selected_action (context));
-		}
-
-
-		gtk_drag_finish (context, TRUE, FALSE, time);
-	} else {
-		gtk_drag_finish (context, FALSE, FALSE, time);
-	}
-
-	if (target_view != NULL) {
-		g_object_unref (target_view);
-	}
-
-	g_free (target_uri);
-
-	drag_info_clear (drag_info);
-}
-
-static void
-slot_proxy_drag_data_received (GtkWidget          *widget,
-			       GdkDragContext     *context,
-			       int                 x,
-			       int                 y,
-			       GtkSelectionData   *data,
-			       unsigned int        info,
-			       unsigned int        time,
-			       gpointer            user_data)
-{
-	NautilusDragSlotProxyInfo *drag_info;
-	char **uris;
-
-	drag_info = user_data;
-
-	g_assert (!drag_info->have_data);
-
-	drag_info->have_data = TRUE;
-	drag_info->info = info;
-
-	if (gtk_selection_data_get_length (data) < 0) {
-		drag_info->have_valid_data = FALSE;
-		return;
-	}
-
-	if (info == NAUTILUS_ICON_DND_GNOME_ICON_LIST) {
-		drag_info->data.selection_list = nautilus_drag_build_selection_list (data);
-
-		drag_info->have_valid_data = drag_info->data.selection_list != NULL;
-	} else if (info == NAUTILUS_ICON_DND_URI_LIST) {
-		uris = gtk_selection_data_get_uris (data);
-		drag_info->data.uri_list = nautilus_drag_uri_list_from_array ((const char **) uris);
-		g_strfreev (uris);
-
-		drag_info->have_valid_data = drag_info->data.uri_list != NULL;
-	} else if (info == NAUTILUS_ICON_DND_NETSCAPE_URL) {
-		drag_info->data.netscape_url = g_strdup ((char *) gtk_selection_data_get_data (data));
-
-		drag_info->have_valid_data = drag_info->data.netscape_url != NULL;
-	}
-
-	if (drag_info->drop_occured) {
-		slot_proxy_handle_drop (widget, context, time, drag_info);
-	}
-}
-
-void
-nautilus_drag_slot_proxy_init (GtkWidget *widget,
-			       NautilusDragSlotProxyInfo *drag_info)
-{
-        const GtkTargetEntry targets[] = {
-		{ NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST },
-		{ NAUTILUS_ICON_DND_NETSCAPE_URL_TYPE, 0, NAUTILUS_ICON_DND_NETSCAPE_URL }
-        };
-	GtkTargetList *target_list;
-
-	g_assert (GTK_IS_WIDGET (widget));
-	g_assert (drag_info != NULL);
-
-	gtk_drag_dest_set (widget, 0,
-			   NULL, 0,
-			   GDK_ACTION_MOVE |
-			   GDK_ACTION_COPY |
-			   GDK_ACTION_LINK |
-			   GDK_ACTION_ASK);
-
-	target_list = gtk_target_list_new (targets, G_N_ELEMENTS (targets));
-	gtk_target_list_add_uri_targets (target_list, NAUTILUS_ICON_DND_URI_LIST);
-	gtk_drag_dest_set_target_list (widget, target_list);
-	gtk_target_list_unref (target_list);
-
-	g_signal_connect (widget, "drag-motion",
-			  G_CALLBACK (slot_proxy_drag_motion),
-			  drag_info);
-	g_signal_connect (widget, "drag-drop",
-			  G_CALLBACK (slot_proxy_drag_drop),
-			  drag_info);
-	g_signal_connect (widget, "drag-data-received",
-			  G_CALLBACK (slot_proxy_drag_data_received),
-			  drag_info);
-	g_signal_connect (widget, "drag-leave",
-			  G_CALLBACK (slot_proxy_drag_leave),
-			  drag_info);
-}
-
-
diff --git a/libnautilus-private/nautilus-dnd.h b/libnautilus-private/nautilus-dnd.h
index ab30c75..35e7a9e 100644
--- a/libnautilus-private/nautilus-dnd.h
+++ b/libnautilus-private/nautilus-dnd.h
@@ -96,29 +96,6 @@ typedef struct {
 
 } NautilusDragInfo;
 
-typedef struct {
-	/* NB: the following elements are managed by us */
-	gboolean have_data;
-	gboolean have_valid_data;
-
-	gboolean drop_occured;
-
-	unsigned int info;
-	union {
-		GList *selection_list;
-		GList *uri_list;
-		char *netscape_url;
-	} data;
-
-	/* NB: the following elements are managed by the caller of
-	 *   nautilus_drag_slot_proxy_init() */
-
-	/* a fixed location, or NULL to use slot's location */
-	GFile *target_location;
-	/* a fixed slot, or NULL to use the window's active slot */
-	NautilusWindowSlotInfo *target_slot;
-} NautilusDragSlotProxyInfo;
-
 typedef void		(* NautilusDragEachSelectedItemDataGet)	(const char *url, 
 								 int x, int y, int w, int h, 
 								 gpointer data);
@@ -179,7 +156,4 @@ void			    nautilus_drag_autoscroll_stop		(NautilusDragInfo		      *drag_info);
 
 gboolean		    nautilus_drag_selection_includes_special_link (GList			      *selection_list);
 
-void                        nautilus_drag_slot_proxy_init               (GtkWidget *widget,
-									 NautilusDragSlotProxyInfo *drag_info);
-
 #endif
diff --git a/src/Makefile.am b/src/Makefile.am
index baba538..8b03351 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -129,6 +129,8 @@ nautilus_SOURCES = \
 	nautilus-window-private.h		\
 	nautilus-window-slot.c			\
 	nautilus-window-slot.h			\
+	nautilus-window-slot-dnd.c		\
+	nautilus-window-slot-dnd.h		\
 	nautilus-window-toolbars.c              \
 	nautilus-window.c			\
 	nautilus-window.h			\
diff --git a/src/nautilus-notebook.c b/src/nautilus-notebook.c
index 38a2590..1ac24bc 100644
--- a/src/nautilus-notebook.c
+++ b/src/nautilus-notebook.c
@@ -27,12 +27,13 @@
 #include "config.h"
 
 #include "nautilus-notebook.h"
+
 #include "nautilus-navigation-window.h"
+#include "nautilus-navigation-window-pane.h"
 #include "nautilus-window-manage-views.h"
 #include "nautilus-window-private.h"
 #include "nautilus-window-slot.h"
-#include "nautilus-navigation-window-pane.h"
-#include <libnautilus-private/nautilus-dnd.h>
+#include "nautilus-window-slot-dnd.h"
 
 #include <glib/gi18n.h>
 #include <gio/gio.h>
@@ -331,7 +332,6 @@ close_button_clicked_cb (GtkWidget *widget,
 static GtkWidget *
 build_tab_label (NautilusNotebook *nb, NautilusWindowSlot *slot)
 {
-	NautilusDragSlotProxyInfo *drag_info;
 	GtkWidget *hbox, *label, *close_button, *image, *spinner, *icon;
 
 	/* set hbox spacing and label padding (see below) so that there's an
@@ -377,12 +377,7 @@ build_tab_label (NautilusNotebook *nb, NautilusWindowSlot *slot)
 	gtk_box_pack_start (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
 	gtk_widget_show (close_button);
 
-	drag_info = g_new0 (NautilusDragSlotProxyInfo, 1);
-	drag_info->target_slot = slot;
-	g_object_set_data_full (G_OBJECT (hbox), "proxy-drag-info",
-				drag_info, (GDestroyNotify) g_free);
-
-	nautilus_drag_slot_proxy_init (hbox, drag_info);
+	nautilus_drag_slot_proxy_init (hbox, NULL, slot);
 
 	g_object_set_data (G_OBJECT (hbox), "label", label);
 	g_object_set_data (G_OBJECT (hbox), "spinner", spinner);
diff --git a/src/nautilus-pathbar.c b/src/nautilus-pathbar.c
index ef2a185..1ada80d 100644
--- a/src/nautilus-pathbar.c
+++ b/src/nautilus-pathbar.c
@@ -18,22 +18,26 @@
  * Boston, MA 02111-1307, USA.
  */
 
+
 #include <config.h>
 #include <string.h>
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
 #include <gio/gio.h>
+
+#include "nautilus-pathbar.h"
+
 #include <libnautilus-private/nautilus-file.h>
 #include <libnautilus-private/nautilus-file-utilities.h>
 #include <libnautilus-private/nautilus-global-preferences.h>
 #include <libnautilus-private/nautilus-icon-names.h>
 #include <libnautilus-private/nautilus-trash-monitor.h>
-#include <libnautilus-private/nautilus-dnd.h>
 #include <libnautilus-private/nautilus-icon-dnd.h>
-#include "nautilus-pathbar.h"
+
 #include "nautilus-window.h"
 #include "nautilus-window-private.h"
 #include "nautilus-window-slot.h"
+#include "nautilus-window-slot-dnd.h"
 
 enum {
         PATH_CLICKED,
@@ -83,8 +87,6 @@ struct _ButtonData
         guint ignore_changes : 1;
         guint file_is_hidden : 1;
         guint fake_root : 1;
-
-	NautilusDragSlotProxyInfo drag_info;
 };
 
 G_DEFINE_TYPE (NautilusPathBar,
@@ -1276,9 +1278,6 @@ button_data_free (ButtonData *button_data)
 		nautilus_file_unref (button_data->file);
 	}
 
-	g_object_unref (button_data->drag_info.target_location);
-	button_data->drag_info.target_location = NULL;
-
         g_free (button_data);
 }
 
@@ -1664,8 +1663,6 @@ make_directory_button (NautilusPathBar  *path_bar,
 	gtk_button_set_focus_on_click (GTK_BUTTON (button_data->button), FALSE);
 	/* TODO update button type when xdg directories change */
 
-	button_data->drag_info.target_location = g_object_ref (path);
-
 	button_data->image = gtk_image_new ();
 
         switch (button_data->type) {
@@ -1733,8 +1730,7 @@ make_directory_button (NautilusPathBar  *path_bar,
 
 	setup_button_drag_source (button_data);
 
-	nautilus_drag_slot_proxy_init (button_data->button,
-				       &(button_data->drag_info));
+	nautilus_drag_slot_proxy_init (button_data->button, path, NULL);
 
 	g_object_unref (path);
 
diff --git a/src/nautilus-window-slot-dnd.c b/src/nautilus-window-slot-dnd.c
new file mode 100644
index 0000000..660619b
--- /dev/null
+++ b/src/nautilus-window-slot-dnd.c
@@ -0,0 +1,369 @@
+/*
+ * nautilus-window-slot-dnd.c - Handle DnD for widgets acting as
+ * NautilusWindowSlot proxies
+ *
+ * Copyright (C) 2000, 2001 Eazel, Inc.
+ * Copyright (C) 2010, Red Hat, Inc.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ *  License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Pavel Cisler <pavel eazel com>,
+ * 	    Ettore Perazzoli <ettore gnu org>
+ */
+
+#include <config.h>
+
+#include "nautilus-window-slot-dnd.h"
+
+typedef struct {
+  gboolean have_data;
+  gboolean have_valid_data;
+
+  gboolean drop_occured;
+
+  unsigned int info;
+  union {
+    GList *selection_list;
+    GList *uri_list;
+    char *netscape_url;
+  } data;
+
+  GFile *target_location;
+  NautilusWindowSlotInfo *target_slot;
+} NautilusDragSlotProxyInfo;
+
+static gboolean
+slot_proxy_drag_motion (GtkWidget          *widget,
+			GdkDragContext     *context,
+			int                 x,
+			int                 y,
+			unsigned int        time,
+			gpointer            user_data)
+{
+  NautilusDragSlotProxyInfo *drag_info;
+  NautilusWindowSlotInfo *target_slot;
+  GtkWidget *window;
+  GdkAtom target;
+  int action;
+  char *target_uri;
+
+  drag_info = user_data;
+
+  action = 0;
+
+  if (gtk_drag_get_source_widget (context) == widget) {
+    goto out;
+  }
+
+  window = gtk_widget_get_toplevel (widget);
+  g_assert (NAUTILUS_IS_WINDOW_INFO (window));
+
+  if (!drag_info->have_data) {
+    target = gtk_drag_dest_find_target (widget, context, NULL);
+
+    if (target == GDK_NONE) {
+      goto out;
+    }
+
+    gtk_drag_get_data (widget, context, target, time);
+  }
+
+  target_uri = NULL;
+  if (drag_info->target_location != NULL) {
+    target_uri = g_file_get_uri (drag_info->target_location);
+  } else {
+    if (drag_info->target_slot != NULL) {
+      target_slot = drag_info->target_slot;
+    } else {
+      target_slot = nautilus_window_info_get_active_slot (NAUTILUS_WINDOW_INFO (window));
+    }
+
+    if (target_slot != NULL) {
+      target_uri = nautilus_window_slot_info_get_current_location (target_slot);
+    }
+  }
+
+  if (drag_info->have_data &&
+      drag_info->have_valid_data) {
+    if (drag_info->info == NAUTILUS_ICON_DND_GNOME_ICON_LIST) {
+      nautilus_drag_default_drop_action_for_icons (context, target_uri,
+                                                   drag_info->data.selection_list,
+                                                   &action);
+    } else if (drag_info->info == NAUTILUS_ICON_DND_URI_LIST) {
+      action = nautilus_drag_default_drop_action_for_uri_list (context, target_uri);
+    } else if (drag_info->info == NAUTILUS_ICON_DND_NETSCAPE_URL) {
+      action = nautilus_drag_default_drop_action_for_netscape_url (context);
+    }
+  }
+
+  g_free (target_uri);
+
+ out:
+  if (action != 0) {
+    gtk_drag_highlight (widget);
+  } else {
+    gtk_drag_unhighlight (widget);
+  }
+
+  gdk_drag_status (context, action, time);
+
+  return TRUE;
+}
+
+static void
+drag_info_free (gpointer user_data)
+{
+  NautilusDragSlotProxyInfo *drag_info = user_data;
+
+  g_clear_object (&drag_info->target_location);
+  g_clear_object (&drag_info->target_slot);
+
+  g_slice_free (NautilusDragSlotProxyInfo, drag_info);
+}
+
+static void
+drag_info_clear (NautilusDragSlotProxyInfo *drag_info)
+{
+  if (!drag_info->have_data) {
+    goto out;
+  }
+
+  if (drag_info->info == NAUTILUS_ICON_DND_GNOME_ICON_LIST) {
+    nautilus_drag_destroy_selection_list (drag_info->data.selection_list);
+  } else if (drag_info->info == NAUTILUS_ICON_DND_URI_LIST) {
+    g_list_free (drag_info->data.uri_list);
+  } else if (drag_info->info == NAUTILUS_ICON_DND_NETSCAPE_URL) {
+    g_free (drag_info->data.netscape_url);
+  }
+
+ out:
+  drag_info->have_data = FALSE;
+  drag_info->have_valid_data = FALSE;
+
+  drag_info->drop_occured = FALSE;
+}
+
+static void
+slot_proxy_drag_leave (GtkWidget          *widget,
+		       GdkDragContext     *context,
+		       unsigned int        time,
+		       gpointer            user_data)
+{
+  NautilusDragSlotProxyInfo *drag_info;
+
+  drag_info = user_data;
+
+  gtk_drag_unhighlight (widget);
+  drag_info_clear (drag_info);
+}
+
+static gboolean
+slot_proxy_drag_drop (GtkWidget          *widget,
+		      GdkDragContext     *context,
+		      int                 x,
+		      int                 y,
+		      unsigned int        time,
+		      gpointer            user_data)
+{
+  GdkAtom target;
+  NautilusDragSlotProxyInfo *drag_info;
+
+  drag_info = user_data;
+  g_assert (!drag_info->have_data);
+
+  drag_info->drop_occured = TRUE;
+
+  target = gtk_drag_dest_find_target (widget, context, NULL);
+  gtk_drag_get_data (widget, context, target, time);
+
+  return TRUE;
+}
+
+
+static void
+slot_proxy_handle_drop (GtkWidget                *widget,
+			GdkDragContext           *context,
+			unsigned int              time,
+			NautilusDragSlotProxyInfo *drag_info)
+{
+  GtkWidget *window;
+  NautilusWindowSlotInfo *target_slot;
+  NautilusView *target_view;
+  char *target_uri;
+  GList *uri_list;
+
+  if (!drag_info->have_data ||
+      !drag_info->have_valid_data) {
+    gtk_drag_finish (context, FALSE, FALSE, time);
+    drag_info_clear (drag_info);
+    return;
+  }
+
+  window = gtk_widget_get_toplevel (widget);
+  g_assert (NAUTILUS_IS_WINDOW_INFO (window));
+
+  if (drag_info->target_slot != NULL) {
+    target_slot = drag_info->target_slot;
+  } else {
+    target_slot = nautilus_window_info_get_active_slot (NAUTILUS_WINDOW_INFO (window));
+  }
+
+  target_uri = NULL;
+  if (drag_info->target_location != NULL) {
+    target_uri = g_file_get_uri (drag_info->target_location);
+  } else if (target_slot != NULL) {
+    target_uri = nautilus_window_slot_info_get_current_location (target_slot);
+  }
+
+  target_view = NULL;
+  if (target_slot != NULL) {
+    target_view = nautilus_window_slot_info_get_current_view (target_slot);
+  }
+
+  if (target_slot != NULL && target_view != NULL) {
+    if (drag_info->info == NAUTILUS_ICON_DND_GNOME_ICON_LIST) {
+      uri_list = nautilus_drag_uri_list_from_selection_list (drag_info->data.selection_list);
+      g_assert (uri_list != NULL);
+
+      nautilus_view_drop_proxy_received_uris (target_view,
+                                              uri_list,
+                                              target_uri,
+                                              gdk_drag_context_get_selected_action (context));
+      g_list_free_full (uri_list, g_free);
+    } else if (drag_info->info == NAUTILUS_ICON_DND_URI_LIST) {
+      nautilus_view_drop_proxy_received_uris (target_view,
+                                              drag_info->data.uri_list,
+                                              target_uri,
+                                              gdk_drag_context_get_selected_action (context));
+    } if (drag_info->info == NAUTILUS_ICON_DND_NETSCAPE_URL) {
+      nautilus_view_drop_proxy_received_netscape_url (target_view,
+                                                      drag_info->data.netscape_url,
+                                                      target_uri,
+                                                      gdk_drag_context_get_selected_action (context));
+    }
+
+
+    gtk_drag_finish (context, TRUE, FALSE, time);
+  } else {
+    gtk_drag_finish (context, FALSE, FALSE, time);
+  }
+
+  if (target_view != NULL) {
+    g_object_unref (target_view);
+  }
+
+  g_free (target_uri);
+
+  drag_info_clear (drag_info);
+}
+
+static void
+slot_proxy_drag_data_received (GtkWidget          *widget,
+			       GdkDragContext     *context,
+			       int                 x,
+			       int                 y,
+			       GtkSelectionData   *data,
+			       unsigned int        info,
+			       unsigned int        time,
+			       gpointer            user_data)
+{
+  NautilusDragSlotProxyInfo *drag_info;
+  char **uris;
+
+  drag_info = user_data;
+
+  g_assert (!drag_info->have_data);
+
+  drag_info->have_data = TRUE;
+  drag_info->info = info;
+
+  if (gtk_selection_data_get_length (data) < 0) {
+    drag_info->have_valid_data = FALSE;
+    return;
+  }
+
+  if (info == NAUTILUS_ICON_DND_GNOME_ICON_LIST) {
+    drag_info->data.selection_list = nautilus_drag_build_selection_list (data);
+
+    drag_info->have_valid_data = drag_info->data.selection_list != NULL;
+  } else if (info == NAUTILUS_ICON_DND_URI_LIST) {
+    uris = gtk_selection_data_get_uris (data);
+    drag_info->data.uri_list = nautilus_drag_uri_list_from_array ((const char **) uris);
+    g_strfreev (uris);
+
+    drag_info->have_valid_data = drag_info->data.uri_list != NULL;
+  } else if (info == NAUTILUS_ICON_DND_NETSCAPE_URL) {
+    drag_info->data.netscape_url = g_strdup ((char *) gtk_selection_data_get_data (data));
+
+    drag_info->have_valid_data = drag_info->data.netscape_url != NULL;
+  }
+
+  if (drag_info->drop_occured) {
+    slot_proxy_handle_drop (widget, context, time, drag_info);
+  }
+}
+
+void
+nautilus_drag_slot_proxy_init (GtkWidget *widget,
+                               GFile *target_location,
+                               NautilusWindowSlot *target_slot)
+{
+  NautilusDragSlotProxyInfo *drag_info;
+
+  const GtkTargetEntry targets[] = {
+    { NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST },
+    { NAUTILUS_ICON_DND_NETSCAPE_URL_TYPE, 0, NAUTILUS_ICON_DND_NETSCAPE_URL }
+  };
+  GtkTargetList *target_list;
+
+  g_assert (GTK_IS_WIDGET (widget));
+
+  drag_info = g_slice_new0 (NautilusDragSlotProxyInfo);
+
+  g_object_set_data_full (G_OBJECT (widget), "drag-slot-proxy-data", drag_info,
+                          drag_info_free);
+
+  if (target_location != NULL)
+    drag_info->target_location = g_object_ref (target_location);
+
+  if (target_slot != NULL)
+    drag_info->target_slot = g_object_ref (target_slot);
+
+  gtk_drag_dest_set (widget, 0,
+                     NULL, 0,
+                     GDK_ACTION_MOVE |
+                     GDK_ACTION_COPY |
+                     GDK_ACTION_LINK |
+                     GDK_ACTION_ASK);
+
+  target_list = gtk_target_list_new (targets, G_N_ELEMENTS (targets));
+  gtk_target_list_add_uri_targets (target_list, NAUTILUS_ICON_DND_URI_LIST);
+  gtk_drag_dest_set_target_list (widget, target_list);
+  gtk_target_list_unref (target_list);
+
+  g_signal_connect (widget, "drag-motion",
+                    G_CALLBACK (slot_proxy_drag_motion),
+                    drag_info);
+  g_signal_connect (widget, "drag-drop",
+                    G_CALLBACK (slot_proxy_drag_drop),
+                    drag_info);
+  g_signal_connect (widget, "drag-data-received",
+                    G_CALLBACK (slot_proxy_drag_data_received),
+                    drag_info);
+  g_signal_connect (widget, "drag-leave",
+                    G_CALLBACK (slot_proxy_drag_leave),
+                    drag_info);
+}
diff --git a/src/nautilus-window-slot-dnd.h b/src/nautilus-window-slot-dnd.h
new file mode 100644
index 0000000..0b4805c
--- /dev/null
+++ b/src/nautilus-window-slot-dnd.h
@@ -0,0 +1,41 @@
+/*
+ * nautilus-window-slot-dnd.c - Handle DnD for widgets acting as
+ * NautilusWindowSlot proxies
+ *
+ * Copyright (C) 2000, 2001 Eazel, Inc.
+ * Copyright (C) 2010, Red Hat, Inc.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ *  License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Pavel Cisler <pavel eazel com>,
+ * 	    Ettore Perazzoli <ettore gnu org>
+ */
+
+#ifndef __NAUTILUS_WINDOW_SLOT_DND_H__
+#define __NAUTILUS_WINDOW_SLOT_DND_H__
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+
+#include <libnautilus-private/nautilus-dnd.h>
+
+#include "nautilus-window-slot.h"
+
+void nautilus_drag_slot_proxy_init (GtkWidget *widget,
+                                    GFile *target_location,
+                                    NautilusWindowSlot *target_slot);
+
+#endif /* __NAUTILUS_WINDOW_SLOT_DND_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]