[nautilus/wip/csoriano/dnd: 2/2] dnd: use sidebar show drop targets



commit 60948b5d403f73283bce411167937939ff2432ad
Author: Carlos Soriano <csoriano gnome org>
Date:   Fri Sep 25 09:19:43 2015 +0200

    dnd: use sidebar show drop targets
    
    Currently the dnd on the sidebar is only trigered when hovering
    above the sidebar itself. However we would like to give some
    feedback all along on the dnd operation.
    For that GtkPlacesSidebar has set_drop_targets_visible public API,
    which was implemnted a few months ago and the GtkFileChooser is
    already using.
    
    I just forgot to implement the support for it on Nautilus... but
    of course all the work was done for Nautilus, since users will probably
    use dnd more on nautilus than on the file chooser.

 libnautilus-private/nautilus-canvas-dnd.c          |   40 +++++++-
 libnautilus-private/nautilus-canvas-dnd.h          |    4 +
 libnautilus-private/nautilus-canvas-private.h      |    1 +
 libnautilus-private/nautilus-dnd.c                 |   60 ++++++++++--
 libnautilus-private/nautilus-dnd.h                 |   11 ++-
 libnautilus-private/nautilus-tree-view-drag-dest.c |    6 +
 src/nautilus-list-view.c                           |  102 +++++++++++++++----
 src/nautilus-list-view.h                           |    6 +
 src/nautilus-window-slot-dnd.c                     |    3 +
 src/nautilus-window.c                              |   45 ++++++++-
 src/nautilus-window.h                              |    4 +
 11 files changed, 247 insertions(+), 35 deletions(-)
---
diff --git a/libnautilus-private/nautilus-canvas-dnd.c b/libnautilus-private/nautilus-canvas-dnd.c
index b4da369..41e673b 100644
--- a/libnautilus-private/nautilus-canvas-dnd.c
+++ b/libnautilus-private/nautilus-canvas-dnd.c
@@ -32,6 +32,8 @@
 
 #include <config.h>
 #include <math.h>
+#include <src/nautilus-window.h>
+
 #include "nautilus-canvas-dnd.h"
 
 #include "nautilus-file-dnd.h"
@@ -528,12 +530,18 @@ drag_end_callback (GtkWidget *widget,
 {
        NautilusCanvasContainer *container;
        NautilusCanvasDndInfo *dnd_info;
+        NautilusWindow *window;
 
        container = NAUTILUS_CANVAS_CONTAINER (widget);
+        window = NAUTILUS_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (container)));
        dnd_info = container->details->dnd_info;
 
        nautilus_drag_destroy_selection_list (dnd_info->drag_info.selection_list);
+       nautilus_drag_destroy_selection_list (container->details->dnd_source_info->selection_cache);
        dnd_info->drag_info.selection_list = NULL;
+        container->details->dnd_source_info->selection_cache = NULL;
+
+        nautilus_window_end_dnd (window, context);
 }
 
 static NautilusCanvasIcon *
@@ -1074,6 +1082,14 @@ nautilus_canvas_container_receive_dropped_icons (NautilusCanvasContainer *contai
        container->details->dnd_info->drag_info.selection_list = NULL;
 }
 
+NautilusDragInfo *
+nautilus_canvas_container_get_drag_source_data (NautilusCanvasContainer *container,
+                                                GdkDragContext          *context,
+                                                guint32                  time)
+{
+        return container->details->dnd_source_info;
+}
+
 static void
 nautilus_canvas_container_get_drop_action (NautilusCanvasContainer *container,
                                         GdkDragContext *context,
@@ -1104,8 +1120,11 @@ nautilus_canvas_container_get_drop_action (NautilusCanvasContainer *container,
        switch (container->details->dnd_info->drag_info.data_type) {
        case NAUTILUS_ICON_DND_GNOME_ICON_LIST:
                if (container->details->dnd_info->drag_info.selection_list != NULL) {
-                       nautilus_drag_default_drop_action_for_icons (context, drop_target, 
-                                                                    
container->details->dnd_info->drag_info.selection_list, 
+                        NautilusWindow *window;
+                        window = NAUTILUS_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (container)));
+                       nautilus_drag_default_drop_action_for_icons (context, drop_target,
+                                                                    
container->details->dnd_info->drag_info.selection_list,
+                                                                     0,
                                                                     action);
                }
                break;
@@ -1258,12 +1277,14 @@ drag_begin_callback (GtkWidget      *widget,
 {
        NautilusCanvasContainer *container;
        NautilusDragInfo *drag_info;
+        NautilusWindow *window;
        cairo_surface_t *surface;
        double x1, y1, x2, y2, winx, winy;
        int x_offset, y_offset;
        int start_x, start_y;
 
        container = NAUTILUS_CANVAS_CONTAINER (widget);
+        window = NAUTILUS_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (container)));
 
        start_x = container->details->dnd_info->drag_info.start_x +
                gtk_adjustment_get_value (gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (container)));
@@ -1290,6 +1311,10 @@ drag_begin_callback (GtkWidget      *widget,
        drag_info->selection_cache = nautilus_drag_create_selection_cache (widget,
                                                                           each_icon_get_data_binder);
 
+        container->details->dnd_source_info->selection_cache = nautilus_drag_create_selection_cache (widget,
+                                                                                                     
each_icon_get_data_binder);
+
+        nautilus_window_start_dnd (window, context);
 }
 
 void
@@ -1301,11 +1326,14 @@ nautilus_canvas_dnd_begin_drag (NautilusCanvasContainer *container,
                              int                    start_y)
 {
        NautilusCanvasDndInfo *dnd_info;
+       NautilusDragInfo *dnd_source_info;
        
        g_return_if_fail (NAUTILUS_IS_CANVAS_CONTAINER (container));
        g_return_if_fail (event != NULL);
 
        dnd_info = container->details->dnd_info;
+       container->details->dnd_source_info = g_new0 (NautilusDragInfo, 1);
+       dnd_source_info = container->details->dnd_source_info;
        g_return_if_fail (dnd_info != NULL);
        
        /* Notice that the event is in bin_window coordinates, because of
@@ -1316,6 +1344,7 @@ nautilus_canvas_dnd_begin_drag (NautilusCanvasContainer *container,
        dnd_info->drag_info.start_y = start_y -
                gtk_adjustment_get_value (gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (container))); 
 
+        dnd_source_info->overrided_actions = actions;
        /* start the drag */
        gtk_drag_begin_with_coordinates (GTK_WIDGET (container),
                                         dnd_info->drag_info.target_list,
@@ -1485,6 +1514,13 @@ drag_motion_callback (GtkWidget *widget,
                      guint32 time)
 {
        int action;
+        NautilusWindow *window;
+        NautilusWindowSlot *slot;
+        NautilusView *view;
+
+        window = NAUTILUS_WINDOW (gtk_widget_get_toplevel (widget));
+        slot = nautilus_window_get_active_slot (window);
+        view = nautilus_window_slot_get_current_view (slot);
 
        nautilus_canvas_container_ensure_drag_data (NAUTILUS_CANVAS_CONTAINER (widget), context, time);
        nautilus_canvas_container_position_shadow (NAUTILUS_CANVAS_CONTAINER (widget), x, y);
diff --git a/libnautilus-private/nautilus-canvas-dnd.h b/libnautilus-private/nautilus-canvas-dnd.h
index f780848..aecf49d 100644
--- a/libnautilus-private/nautilus-canvas-dnd.h
+++ b/libnautilus-private/nautilus-canvas-dnd.h
@@ -54,4 +54,8 @@ void   nautilus_canvas_dnd_begin_drag            (NautilusCanvasContainer *conta
                                                  int                    start_y);
 void   nautilus_canvas_dnd_end_drag              (NautilusCanvasContainer *container);
 
+NautilusDragInfo* nautilus_canvas_container_get_drag_source_data (NautilusCanvasContainer *container,
+                                                       GdkDragContext          *context,
+                                                       guint32                  time);
+
 #endif /* NAUTILUS_CANVAS_DND_H */
diff --git a/libnautilus-private/nautilus-canvas-private.h b/libnautilus-private/nautilus-canvas-private.h
index 6cdd7a6..2e693aa 100644
--- a/libnautilus-private/nautilus-canvas-private.h
+++ b/libnautilus-private/nautilus-canvas-private.h
@@ -182,6 +182,7 @@ struct NautilusCanvasContainerDetails {
 
        /* DnD info. */
        NautilusCanvasDndInfo *dnd_info;
+       NautilusDragInfo *dnd_source_info;
 
        /* zoom level */
        int zoom_level;
diff --git a/libnautilus-private/nautilus-dnd.c b/libnautilus-private/nautilus-dnd.c
index 694f295..a873204 100644
--- a/libnautilus-private/nautilus-dnd.c
+++ b/libnautilus-private/nautilus-dnd.c
@@ -35,6 +35,8 @@
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
 #include <libnautilus-private/nautilus-file-utilities.h>
+#include <libnautilus-private/nautilus-canvas-dnd.h>
+#include <src/nautilus-list-view.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -85,7 +87,6 @@ nautilus_drag_finalize (NautilusDragInfo *drag_info)
        g_free (drag_info);
 }
 
-
 /* Functions to deal with NautilusDragSelectionItems.  */
 
 NautilusDragSelectionItem *
@@ -381,10 +382,52 @@ source_is_deletable (GFile *file)
        return ret;
 }
 
+NautilusDragInfo *
+nautilus_drag_get_source_data (GdkDragContext *context,
+                               guint32         time)
+{
+        GtkWidget *source_widget;
+        NautilusDragInfo *source_data;
+
+        source_widget = gtk_drag_get_source_widget (context);
+        if (source_widget == NULL)
+                return NULL;
+
+        if (NAUTILUS_IS_CANVAS_CONTAINER (source_widget)) {
+               source_data = nautilus_canvas_container_get_drag_source_data (NAUTILUS_CANVAS_CONTAINER 
(source_widget),
+                                                                             context,
+                                                                             time);
+        } else if (GTK_IS_TREE_VIEW (source_widget)) {
+                NautilusWindow *window;
+                NautilusWindowSlot *active_slot;
+                NautilusView *view;
+
+                window = NAUTILUS_WINDOW (gtk_widget_get_toplevel (source_widget));
+                active_slot = nautilus_window_get_active_slot (window);
+                view = nautilus_window_slot_get_current_view (active_slot);
+                if (NAUTILUS_IS_LIST_VIEW (view)) {
+                        source_data = nautilus_list_view_get_drag_source_data (NAUTILUS_LIST_VIEW (view),
+                                                                               context,
+                                                                               time);
+                } else {
+                        g_warning ("Got a drag context with a tree view source widget, but current view is 
not list view");
+                        source_data = NULL;
+                }
+        } else {
+                /* it's a slot or something else */
+                g_warning ("Requested drag source data from a widget that doesn't support it");
+                source_data = NULL;
+        }
+
+        return source_data;
+}
+
 void
 nautilus_drag_default_drop_action_for_icons (GdkDragContext *context,
-                                            const char *target_uri_string, const GList *items,
-                                            int *action)
+                                             const char     *target_uri_string,
+                                             const GList    *items,
+                                             guint32         overrided_actions,
+                                             int            *action)
 {
        gboolean same_fs;
        gboolean target_is_source_parent;
@@ -399,7 +442,10 @@ nautilus_drag_default_drop_action_for_icons (GdkDragContext *context,
                return;
        }
 
-       actions = gdk_drag_context_get_actions (context) & (GDK_ACTION_MOVE | GDK_ACTION_COPY);
+        if (overrided_actions)
+                actions = overrided_actions & (GDK_ACTION_MOVE | GDK_ACTION_COPY);
+        else
+               actions = gdk_drag_context_get_actions (context) & (GDK_ACTION_MOVE | GDK_ACTION_COPY);
        if (actions == 0) {
                 /* We can't use copy or move, just go with the suggested action. */
                *action = gdk_drag_context_get_suggested_action (context);
@@ -411,7 +457,7 @@ nautilus_drag_default_drop_action_for_icons (GdkDragContext *context,
                *action = gdk_drag_context_get_suggested_action (context);
                return;
        }
-       
+
        dropped_uri = ((NautilusDragSelectionItem *)items->data)->uri;
        dropped_file = ((NautilusDragSelectionItem *)items->data)->file;
        target_file = nautilus_file_get_existing_by_uri (target_uri_string);
@@ -453,7 +499,7 @@ nautilus_drag_default_drop_action_for_icons (GdkDragContext *context,
                        if (actions & GDK_ACTION_MOVE) {
                                *action = GDK_ACTION_MOVE;
                        }
-                       
+
                        g_object_unref (target);
                        nautilus_file_unref (target_file);
                        return;
@@ -470,7 +516,7 @@ nautilus_drag_default_drop_action_for_icons (GdkDragContext *context,
        same_fs = check_same_fs (target_file, dropped_file);
 
        nautilus_file_unref (target_file);
-       
+
        /* Compare the first dropped uri with the target uri for same fs match. */
        dropped = g_file_new_for_uri (dropped_uri);
        dropped_directory = g_file_get_parent (dropped);
diff --git a/libnautilus-private/nautilus-dnd.h b/libnautilus-private/nautilus-dnd.h
index 2b343ce..01cd4b9 100644
--- a/libnautilus-private/nautilus-dnd.h
+++ b/libnautilus-private/nautilus-dnd.h
@@ -88,7 +88,11 @@ typedef struct {
        /* autoscrolling during dragging */
        int auto_scroll_timeout_id;
        gboolean waiting_to_autoscroll;
-       gint64 start_auto_scroll_in;
+       guint64 start_auto_scroll_in;
+
+        /* overrided actions. Used for knowing the actions using a GdkDragContext
+         * source instead of destination */
+        guint32 overrided_actions;
 
 } NautilusDragInfo;
 
@@ -106,6 +110,7 @@ void                            nautilus_drag_init                          
(NautilusDragInfo                     *drag_info,
 void                       nautilus_drag_finalize                      (NautilusDragInfo                     
*drag_info);
 NautilusDragSelectionItem  *nautilus_drag_selection_item_new           (void);
 void                       nautilus_drag_destroy_selection_list        (GList                                
*selection_list);
+void                        nautilus_drag_source_destroy                (NautilusDragInfo                    
 *drag_info);
 GList                     *nautilus_drag_build_selection_list          (GtkSelectionData                     
*data);
 
 GList *                            nautilus_drag_uri_list_from_selection_list  (const GList                  
        *selection_list);
@@ -120,6 +125,7 @@ gboolean                nautilus_drag_items_on_desktop              (const GList          
                *selection_li
 void                       nautilus_drag_default_drop_action_for_icons (GdkDragContext                       
*context,
                                                                         const char                           
*target_uri,
                                                                         const GList                          
*items,
+                                                                         guint32                             
  overrided_actions,
                                                                         int                                  
*action);
 GdkDragAction              nautilus_drag_default_drop_action_for_netscape_url (GdkDragContext                
       *context);
 GdkDragAction              nautilus_drag_default_drop_action_for_uri_list     (GdkDragContext                
       *context,
@@ -149,4 +155,7 @@ void                            nautilus_drag_autoscroll_stop               
(NautilusDragInfo                     *drag_info);
 
 gboolean                   nautilus_drag_selection_includes_special_link (GList                              
*selection_list);
 
+NautilusDragInfo *                     nautilus_drag_get_source_data               (GdkDragContext *context,
+                                                                         guint32         time);
+
 #endif
diff --git a/libnautilus-private/nautilus-tree-view-drag-dest.c 
b/libnautilus-private/nautilus-tree-view-drag-dest.c
index ee57881..1dbd805 100644
--- a/libnautilus-private/nautilus-tree-view-drag-dest.c
+++ b/libnautilus-private/nautilus-tree-view-drag-dest.c
@@ -36,6 +36,7 @@
 #include "nautilus-link.h"
 
 #include <gtk/gtk.h>
+#include <src/nautilus-window.h>
 
 #include <stdio.h>
 #include <string.h>
@@ -513,6 +514,7 @@ get_drop_action (NautilusTreeViewDragDest *dest,
                        (context,
                         drop_target,
                         dest->details->drag_list,
+                         0,
                         &action);
                break;
        case NAUTILUS_ICON_DND_NETSCAPE_URL:
@@ -542,6 +544,7 @@ drag_motion_callback (GtkWidget *widget,
                      gpointer data)
 {
        NautilusTreeViewDragDest *dest;
+        NautilusWindow *window;
        GtkTreePath *path;
        GtkTreePath *drop_path, *old_drop_path;
        GtkTreeViewDropPosition pos;
@@ -550,6 +553,7 @@ drag_motion_callback (GtkWidget *widget,
        gboolean res = TRUE;
 
        dest = NAUTILUS_TREE_VIEW_DRAG_DEST (data);
+        window = NAUTILUS_WINDOW (gtk_widget_get_toplevel (widget));
 
        gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget),
                                           x, y, &path, &pos);
@@ -623,8 +627,10 @@ drag_leave_callback (GtkWidget *widget,
                     gpointer data)
 {
        NautilusTreeViewDragDest *dest;
+        NautilusWindow *window;
 
        dest = NAUTILUS_TREE_VIEW_DRAG_DEST (data);
+        window = NAUTILUS_WINDOW (gtk_widget_get_toplevel (widget));
 
        clear_drag_dest_row (dest);
 
diff --git a/src/nautilus-list-view.c b/src/nautilus-list-view.c
index 50e76a4..ee74f7c 100644
--- a/src/nautilus-list-view.c
+++ b/src/nautilus-list-view.c
@@ -46,7 +46,6 @@
 #include <libnautilus-private/nautilus-clipboard-monitor.h>
 #include <libnautilus-private/nautilus-column-chooser.h>
 #include <libnautilus-private/nautilus-column-utilities.h>
-#include <libnautilus-private/nautilus-dnd.h>
 #include <libnautilus-private/nautilus-file-dnd.h>
 #include <libnautilus-private/nautilus-file-utilities.h>
 #include <libnautilus-private/nautilus-ui-utilities.h>
@@ -97,6 +96,7 @@ struct NautilusListViewDetails {
        gboolean ignore_button_release;
        gboolean row_selected_on_button_down;
        gboolean active;
+        NautilusDragInfo *drag_source_info;
        
        GHashTable *columns;
        GtkWidget *column_editor;
@@ -108,6 +108,8 @@ struct NautilusListViewDetails {
        GQuark last_sort_attr;
 
         GIcon *icon;
+
+        GList *selection_cache;
 };
 
 struct SelectionForeachData {
@@ -342,31 +344,59 @@ nautilus_list_view_did_not_drag (NautilusListView *view,
        
 }
 
-static void 
-drag_data_get_callback (GtkWidget *widget,
-                       GdkDragContext *context,
-                       GtkSelectionData *selection_data,
-                       guint info,
-                       guint time)
+NautilusDragInfo *
+nautilus_list_view_get_drag_source_data (NautilusListView *list_view,
+                                         GdkDragContext   *context,
+                                         guint32           time)
+{
+       GtkTreeView *tree_view;
+       GtkTreeModel *model;
+
+
+       tree_view = GTK_TREE_VIEW (list_view->details->tree_view);
+
+       model = gtk_tree_view_get_model (tree_view);
+
+       if (model == NULL) {
+               return NULL;
+       }
+
+       if (list_view->details->drag_source_info == NULL ||
+            list_view->details->drag_source_info->selection_cache == NULL) {
+               return NULL;
+       }
+
+        return list_view->details->drag_source_info;
+}
+
+static void
+drag_data_get_callback (GtkWidget        *widget,
+                        GdkDragContext   *context,
+                        GtkSelectionData *selection_data,
+                        guint             info,
+                        guint             time,
+                        gpointer          user_data)
 {
        GtkTreeView *tree_view;
        GtkTreeModel *model;
-       GList *selection_cache;
+        NautilusListView *list_view;
 
        tree_view = GTK_TREE_VIEW (widget);
-  
+        list_view = NAUTILUS_LIST_VIEW (user_data);
+
        model = gtk_tree_view_get_model (tree_view);
-  
+
        if (model == NULL) {
                return;
        }
 
-       selection_cache = g_object_get_data (G_OBJECT (context), "drag-info");
-       if (selection_cache == NULL) {
+       if (list_view->details->drag_source_info == NULL ||
+            list_view->details->drag_source_info->selection_cache == NULL) {
                return;
        }
 
-       nautilus_drag_drag_data_get_from_cache (selection_cache, context, selection_data, info, time);
+       nautilus_drag_drag_data_get_from_cache (list_view->details->drag_source_info->selection_cache,
+                                                context, selection_data, info, time);
 }
 
 static void
@@ -479,16 +509,34 @@ each_item_get_data_binder (NautilusDragEachSelectedItemDataGet iteratee,
        gtk_tree_selection_selected_foreach (selection, item_get_data_binder, &context);
 }
 
+static void
+drag_end_callback (GtkWidget        *widget,
+                   GdkDragContext   *context,
+                   NautilusListView *view)
+{
+        NautilusWindow *window;
+
+        window = nautilus_files_view_get_window (NAUTILUS_FILES_VIEW (view));
+
+        nautilus_window_end_dnd (window, context);
+
+       nautilus_drag_destroy_selection_list (view->details->drag_source_info->selection_cache);
+       view->details->drag_source_info->selection_cache = NULL;
+}
 
 static void
 drag_begin_callback (GtkWidget *widget,
                     GdkDragContext *context,
                     NautilusListView *view)
 {
-       GList *selection_cache;
        cairo_surface_t *surface;
+        GdkDragAction actions;
+        NautilusWindow *window;
+
+        window = nautilus_files_view_get_window (NAUTILUS_FILES_VIEW (view));
 
        surface = get_drag_surface (view);
+        actions = gdk_drag_context_get_actions (context);
        if (surface) {
                gtk_drag_set_icon_surface (context, surface);
                cairo_surface_destroy (surface);
@@ -499,13 +547,10 @@ drag_begin_callback (GtkWidget *widget,
        stop_drag_check (view);
        view->details->drag_started = TRUE;
 
-       selection_cache = nautilus_drag_create_selection_cache (view,
-                                                               each_item_get_data_binder);
-
-       g_object_set_data_full (G_OBJECT (context),
-                               "drag-info",
-                               selection_cache,
-                               (GDestroyNotify)nautilus_drag_destroy_selection_list);
+        /* Source selection */
+        view->details->drag_source_info->selection_cache = nautilus_drag_create_selection_cache (view,
+                                                                                                 
each_item_get_data_binder);
+        nautilus_window_start_dnd (window, context);
 }
 
 static gboolean
@@ -553,10 +598,14 @@ motion_notify_callback (GtkWidget *widget,
                                              view->details->drag_y,
                                              event->x, 
                                              event->y)) {
+                        guint32 actions;
+
+                        actions = GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK;
+                        view->details->drag_source_info->overrided_actions = actions;
                        gtk_drag_begin
                                (widget,
                                 source_target_list,
-                                GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK,
+                                actions,
                                 view->details->drag_button,
                                 (GdkEvent*)event);
                }                     
@@ -1851,6 +1900,8 @@ create_and_set_up_tree_view (NautilusListView *view)
 
        g_signal_connect_object (view->details->tree_view, "drag-begin",
                                 G_CALLBACK (drag_begin_callback), view, 0);
+       g_signal_connect_object (view->details->tree_view, "drag-end",
+                                G_CALLBACK (drag_end_callback), view, 0);
        g_signal_connect_object (view->details->tree_view, "drag-data-get",
                                 G_CALLBACK (drag_data_get_callback), view, 0);
        g_signal_connect_object (view->details->tree_view, "motion-notify-event",
@@ -3174,6 +3225,11 @@ nautilus_list_view_finalize (GObject *object)
 
        g_free (list_view->details);
 
+       nautilus_drag_destroy_selection_list (list_view->details->drag_source_info->selection_cache);
+       list_view->details->drag_source_info->selection_cache = NULL;
+        g_free (list_view->details->drag_source_info);
+
+
        g_signal_handlers_disconnect_by_func (nautilus_preferences,
                                              default_sort_order_changed_callback,
                                              list_view);
@@ -3427,6 +3483,8 @@ nautilus_list_view_init (NautilusListView *list_view)
                                  "clipboard-info",
                                  G_CALLBACK (list_view_notify_clipboard_info), list_view);
 
+       list_view->details->drag_source_info = g_new0 (NautilusDragInfo, 1);
+
        view_action_group = nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (list_view));
        g_action_map_add_action_entries (G_ACTION_MAP (view_action_group),
                                        list_view_entries,
diff --git a/src/nautilus-list-view.h b/src/nautilus-list-view.h
index 03f027e..fd20b1b 100644
--- a/src/nautilus-list-view.h
+++ b/src/nautilus-list-view.h
@@ -27,6 +27,7 @@
 #define NAUTILUS_LIST_VIEW_H
 
 #include "nautilus-files-view.h"
+#include <libnautilus-private/nautilus-dnd.h>
 
 #define NAUTILUS_TYPE_LIST_VIEW nautilus_list_view_get_type()
 #define NAUTILUS_LIST_VIEW(obj) \
@@ -54,4 +55,9 @@ typedef struct {
 GType nautilus_list_view_get_type (void);
 NautilusFilesView * nautilus_list_view_new (NautilusWindowSlot *slot);
 
+NautilusDragInfo *
+nautilus_list_view_get_drag_source_data (NautilusListView *list_view,
+                                         GdkDragContext   *context,
+                                         guint32           time);
+
 #endif /* NAUTILUS_LIST_VIEW_H */
diff --git a/src/nautilus-window-slot-dnd.c b/src/nautilus-window-slot-dnd.c
index 6c9fea5..0e0aeb0 100644
--- a/src/nautilus-window-slot-dnd.c
+++ b/src/nautilus-window-slot-dnd.c
@@ -212,8 +212,11 @@ slot_proxy_drag_motion (GtkWidget          *widget,
   if (drag_info->have_data &&
       drag_info->have_valid_data) {
     if (drag_info->info == NAUTILUS_ICON_DND_GNOME_ICON_LIST) {
+      nautilus_window_start_dnd (NAUTILUS_WINDOW (window), context);
+
       nautilus_drag_default_drop_action_for_icons (context, target_uri,
                                                    drag_info->data.selection_list,
+                                                  0,
                                                    &action);
     } else if (drag_info->info == NAUTILUS_ICON_DND_URI_LIST) {
       action = nautilus_drag_default_drop_action_for_uri_list (context, target_uri);
diff --git a/src/nautilus-window.c b/src/nautilus-window.c
index da28b52..e2c6300 100644
--- a/src/nautilus-window.c
+++ b/src/nautilus-window.c
@@ -977,6 +977,27 @@ build_selection_list_from_gfile_list (GList *gfile_list)
        return g_list_reverse (result);
 }
 
+void
+nautilus_window_start_dnd (NautilusWindow *window,
+                           GdkDragContext *context)
+{
+        /* currently we don't use the context, so the sidebar enables all the
+         * known files and the 'New Bookmark' row.
+         */
+        gtk_places_sidebar_set_drop_targets_visible (GTK_PLACES_SIDEBAR (window->priv->places_sidebar),
+                                                     TRUE,
+                                                     context);
+}
+
+void
+nautilus_window_end_dnd (NautilusWindow *window,
+                         GdkDragContext *context)
+{
+        gtk_places_sidebar_set_drop_targets_visible (GTK_PLACES_SIDEBAR (window->priv->places_sidebar),
+                                                     FALSE,
+                                                     context);
+}
+
 /* Callback used when the places sidebar needs to know the drag action to suggest */
 static GdkDragAction
 places_sidebar_drag_action_requested_cb (GtkPlacesSidebar *sidebar,
@@ -988,13 +1009,31 @@ places_sidebar_drag_action_requested_cb (GtkPlacesSidebar *sidebar,
        GList *items;
        char *uri;
        int action = 0;
+        GtkWidget *source_widget;
+        NautilusDragInfo *info;
+        guint32 overrided_actions;
+
+
+        source_widget = gtk_drag_get_source_widget (context);
 
-       items = build_selection_list_from_gfile_list (source_file_list);
+        info = nautilus_drag_get_source_data (context, GDK_CURRENT_TIME);
+        if (info != NULL) {
+                items = info->selection_cache;
+                overrided_actions = info->overrided_actions;
+        } else {
+                items = build_selection_list_from_gfile_list (source_file_list);
+                overrided_actions = 0;
+        }
        uri = g_file_get_uri (dest_file);
 
-       nautilus_drag_default_drop_action_for_icons (context, uri, items, &action);
+        if (g_list_length (items) < 1)
+                return 0;
+
+       nautilus_drag_default_drop_action_for_icons (context, uri, items, overrided_actions, &action);
+
+        if (info == NULL)
+               nautilus_drag_destroy_selection_list (items);
 
-       nautilus_drag_destroy_selection_list (items);
        g_free (uri);
 
        return action;
diff --git a/src/nautilus-window.h b/src/nautilus-window.h
index d9b0b24..8ba877b 100644
--- a/src/nautilus-window.h
+++ b/src/nautilus-window.h
@@ -145,4 +145,8 @@ void nautilus_window_sync_title            (NautilusWindow *window,
 void nautilus_window_show_operation_notification (NautilusWindow *window,
                                                   gchar          *main_label,
                                                   GFile          *folder_to_open);
+void nautilus_window_start_dnd (NautilusWindow *window,
+                                GdkDragContext *context);
+void nautilus_window_end_dnd (NautilusWindow *window,
+                              GdkDragContext *context);
 #endif


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