Blob Blame Raw
@@ -, +, @@ 
 desktop. Fixes bug 3804.
---
 src/xfdesktop-clipboard-manager.c |  114 ++++++++++++++++++++++++++++++-------
 src/xfdesktop-file-icon-manager.c |   27 ++++++++-
 2 files changed, 120 insertions(+), 21 deletions(-)
--- a/src/xfdesktop-clipboard-manager.c	
+++ a/src/xfdesktop-clipboard-manager.c	
@@ -307,7 +307,6 @@ xfdesktop_clipboard_manager_owner_changed (GtkClipboard           *clipboard,
 }
 
 
-#if 0
 static void
 xfdesktop_clipboard_manager_contents_received (GtkClipboard     *clipboard,
                                             GtkSelectionData *selection_data,
@@ -318,6 +317,8 @@ xfdesktop_clipboard_manager_contents_received (GtkClipboard     *clipboard,
   GtkWindow                      *parent = GTK_WINDOW(gtk_widget_get_toplevel(request->widget));
   gboolean                        path_copy = TRUE;
   GList                          *path_list = NULL;
+  GList                          *dest_file_list  = NULL;
+  GList                          *l               = NULL;
   gchar                          *data;
 
   /* check whether the retrieval worked */
@@ -340,19 +341,43 @@ xfdesktop_clipboard_manager_contents_received (GtkClipboard     *clipboard,
         }
 
       /* determine the path list stored with the selection */
-      path_list = thunar_vfs_path_list_from_string (data, NULL);
+      path_list = xfdesktop_file_utils_file_list_from_string (data);
     }
 
   /* perform the action if possible */
   if (G_LIKELY (path_list != NULL))
     {
+      for (l = path_list; l; l = l->next) {
+        gchar *dest_basename = g_file_get_basename(l->data);
+
+        if(dest_basename && *dest_basename != '\0') {
+          /* If we copy a file, we need to use the new absolute filename
+           * as the destination. If we move, we need to use the destination
+           * directory. */
+           if(path_copy) {
+             GFile *dest_file = g_file_get_child(request->target_file, dest_basename);
+             dest_file_list = g_list_prepend(dest_file_list, dest_file);
+           } else {
+             dest_file_list = g_list_prepend(dest_file_list, request->target_file);
+           }
+         }
+         g_free(dest_basename);
+      }
+
+      dest_file_list = g_list_reverse(dest_file_list);
+
       if (G_LIKELY (path_copy))
-        xfdesktop_file_utils_copy_into(parent, path_list, request->target_path);
-        //thunar_application_copy_into (application, request->widget, path_list, request->target_path, request->new_files_closure);
-      else
-        xfdesktop_file_utils_move_into(parent, path_list, request->target_path);
-        //thunar_application_move_into (application, request->widget, path_list, request->target_path, request->new_files_closure);
-      thunar_vfs_path_list_free (path_list);
+      {
+        xfdesktop_file_utils_transfer_files(GDK_ACTION_COPY,
+                                            path_list,
+                                            dest_file_list,
+                                            gtk_widget_get_screen(GTK_WIDGET(parent)));
+      } else {
+        xfdesktop_file_utils_transfer_files(GDK_ACTION_MOVE,
+                                            path_list,
+                                            dest_file_list,
+                                            gtk_widget_get_screen(GTK_WIDGET(parent)));
+      }
 
       /* clear the clipboard if it contained "cutted data"
        * (gtk_clipboard_clear takes care of not clearing
@@ -365,18 +390,11 @@ xfdesktop_clipboard_manager_contents_received (GtkClipboard     *clipboard,
        * if either the Xserver or our GTK+ version
        * doesn't support the XFixes extension.
        */
-#if GTK_CHECK_VERSION(2,6,0)
       if (!gdk_display_supports_selection_notification (gtk_clipboard_get_display (manager->clipboard)))
-#endif
         {
           xfdesktop_clipboard_manager_owner_changed (manager->clipboard, NULL, manager);
         }
     }
-  else
-    {
-      /* tell the user that we cannot paste */
-//      thunar_dialogs_show_error (request->widget, NULL, _("There is nothing on the clipboard to paste"));
-    }
 
   /* free the request */
   if (G_LIKELY (request->widget != NULL))
@@ -384,10 +402,11 @@ xfdesktop_clipboard_manager_contents_received (GtkClipboard     *clipboard,
   if (G_LIKELY (request->new_files_closure != NULL))
     g_closure_unref (request->new_files_closure);
   g_object_unref (G_OBJECT (request->manager));
-  thunar_vfs_path_unref (request->target_path);
-  g_free (request);
+
+  g_list_free(dest_file_list);
+  g_list_free(path_list);
 }
-#endif
+
 
 
 static void
@@ -654,6 +673,61 @@ xfdesktop_clipboard_manager_cut_files (XfdesktopClipboardManager *manager,
 gboolean
 xfdesktop_clipboard_manager_get_can_paste (XfdesktopClipboardManager *manager)
 {
-    /* FIXME: implement */
-    return FALSE;
+    g_return_val_if_fail (XFDESKTOP_IS_CLIPBOARD_MANAGER (manager), FALSE);
+    return manager->can_paste;
+}
+
+
+/**
+ * thunar_clipboard_manager_paste_files:
+ * @manager           : a #XfdesktopClipboardManager.
+ * @target_file       : the #GFile of the folder to which the contents on the clipboard
+ *                      should be pasted.
+ * @widget            : a #GtkWidget, on which to perform the paste or %NULL if no widget is
+ *                      known.
+ * @new_files_closure : a #GClosure to connect to the job's "new-files" signal,
+ *                      which will be emitted when the job finishes with the
+ *                      list of #GFile<!---->s created by the job, or
+ *                      %NULL if you're not interested in the signal.
+ *
+ * Pastes the contents from the clipboard associated with @manager to the directory
+ * referenced by @target_file.
+ * Code copied and adapted from thunar-clipboard-manager.c
+ * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2009-2011 Jannis Pohlmann <jannis@xfce.org>
+ **/
+void
+xfdesktop_clipboard_manager_paste_files (XfdesktopClipboardManager *manager,
+                                      GFile                  *target_file,
+                                      GtkWidget              *widget,
+                                      GClosure               *new_files_closure)
+{
+  XfdesktopClipboardPasteRequest *request;
+
+  g_return_if_fail (XFDESKTOP_IS_CLIPBOARD_MANAGER (manager));
+  g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
+
+  /* prepare the paste request */
+  request = g_slice_new0 (XfdesktopClipboardPasteRequest);
+  request->manager = g_object_ref (G_OBJECT (manager));
+  request->target_file = g_object_ref (target_file);
+  request->widget = widget;
+
+  /* take a reference on the closure (if any) */
+  if (G_LIKELY (new_files_closure != NULL))
+    {
+      request->new_files_closure = new_files_closure;
+      g_closure_ref (new_files_closure);
+      g_closure_sink (new_files_closure);
+    }
+
+  /* get notified when the widget is destroyed prior to
+   * completing the clipboard contents retrieval
+   */
+  if (G_LIKELY (request->widget != NULL))
+    g_object_add_weak_pointer (G_OBJECT (request->widget), (gpointer) &request->widget);
+
+  /* schedule the request */
+  gtk_clipboard_request_contents (manager->clipboard, manager->x_special_gnome_copied_files,
+                                  xfdesktop_clipboard_manager_contents_received, request);
 }
--- a/src/xfdesktop-file-icon-manager.c	
+++ a/src/xfdesktop-file-icon-manager.c	
@@ -858,6 +858,15 @@ xfdesktop_file_icon_menu_delete(GtkWidget *widget,
 }
 
 static void
+xfdesktop_file_icon_menu_paste(GtkWidget *widget,
+                               gpointer user_data)
+{
+    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
+    if(widget && fmanager)
+        xfdesktop_clipboard_manager_paste_files(clipboard_manager, fmanager->priv->folder, widget, NULL);
+}
+
+static void
 xfdesktop_file_icon_menu_properties(GtkWidget *widget,
                                     gpointer user_data)
 {
@@ -1616,7 +1625,11 @@ xfdesktop_file_icon_manager_populate_context_menu(XfceDesktop *desktop,
             mi = gtk_image_menu_item_new_from_stock(GTK_STOCK_PASTE, NULL);
             gtk_widget_show(mi);
             gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
-            /* FIXME: implement */
+            if(xfdesktop_clipboard_manager_get_can_paste(clipboard_manager)) {
+                g_signal_connect(G_OBJECT(mi), "activate",
+                                 G_CALLBACK(xfdesktop_file_icon_menu_paste),
+                                 fmanager);
+            } else
             gtk_widget_set_sensitive(mi, FALSE);
         } else {
             mi = gtk_image_menu_item_new_from_stock(GTK_STOCK_COPY, NULL);
@@ -2098,6 +2111,18 @@ xfdesktop_file_icon_manager_key_press(GtkWidget *widget,
             }
             return TRUE;
         
+        case GDK_v:
+        case GDK_V:
+            if(!(evt->state & GDK_CONTROL_MASK)
+               || (evt->state & (GDK_SHIFT_MASK|GDK_MOD1_MASK|GDK_MOD4_MASK)))
+            {
+                return FALSE;
+            }
+            if(xfdesktop_clipboard_manager_get_can_paste(clipboard_manager)) {
+                xfdesktop_clipboard_manager_paste_files(clipboard_manager, fmanager->priv->folder, widget, NULL);
+            }
+            return TRUE;
+
         case GDK_r:
         case GDK_R:
             if(!(evt->state & GDK_CONTROL_MASK)
--