[Xfce4-commits] r29891 - in thunar/branches/migration-to-gio: . thunar

Jannis Pohlmann jannis at xfce.org
Thu Apr 23 02:56:37 CEST 2009


Author: jannis
Date: 2009-04-23 00:56:37 +0000 (Thu, 23 Apr 2009)
New Revision: 29891

Added:
   thunar/branches/migration-to-gio/thunar/thunar-transfer-job.c
   thunar/branches/migration-to-gio/thunar/thunar-transfer-job.h
Modified:
   thunar/branches/migration-to-gio/ChangeLog
   thunar/branches/migration-to-gio/thunar/Makefile.am
   thunar/branches/migration-to-gio/thunar/thunar-application.c
   thunar/branches/migration-to-gio/thunar/thunar-application.h
   thunar/branches/migration-to-gio/thunar/thunar-clipboard-manager.c
   thunar/branches/migration-to-gio/thunar/thunar-clipboard-manager.h
   thunar/branches/migration-to-gio/thunar/thunar-dbus-service.c
   thunar/branches/migration-to-gio/thunar/thunar-dialogs.c
   thunar/branches/migration-to-gio/thunar/thunar-dialogs.h
   thunar/branches/migration-to-gio/thunar/thunar-dnd.c
   thunar/branches/migration-to-gio/thunar/thunar-file.c
   thunar/branches/migration-to-gio/thunar/thunar-file.h
   thunar/branches/migration-to-gio/thunar/thunar-io-jobs.c
   thunar/branches/migration-to-gio/thunar/thunar-io-jobs.h
   thunar/branches/migration-to-gio/thunar/thunar-job.c
   thunar/branches/migration-to-gio/thunar/thunar-job.h
   thunar/branches/migration-to-gio/thunar/thunar-launcher.c
   thunar/branches/migration-to-gio/thunar/thunar-location-button.c
   thunar/branches/migration-to-gio/thunar/thunar-location-buttons.c
   thunar/branches/migration-to-gio/thunar/thunar-marshal.list
   thunar/branches/migration-to-gio/thunar/thunar-progress-dialog.c
   thunar/branches/migration-to-gio/thunar/thunar-shortcuts-view.c
   thunar/branches/migration-to-gio/thunar/thunar-standard-view.c
   thunar/branches/migration-to-gio/thunar/thunar-tree-view.c
Log:
	* thunar/Makefile.am, thunar/thunar-transfer-job.{c,h}: Implement
	  ThunarTransferJob as an equivalent to ThunarVfsTransferJob. The code
	  is very similar except that the error handling is a bit different
	  and all basic operations (non-recursive copy/move) is done based on
	  GFile and GFileInfo. Copying a file into the same directory
	  currently does not work the way it did before (new file 'copy of
	  "%s"' was created). This will be fixed soon.
	* thunar/thunar-application.{c,h}: Add new function
	  thunar_application_collect_and_launch_job() as an alternative to
	  thunar_application_collect_and_launch() but based on GFile and
	  JobLauncher. Implement thunar_application_move_into(),
	  thunar_application_copy_into() and thunar_application_copy_to()
	  based on ThunarTransferJob and GFile instead of ThunarVfsTransferJob.
	* thunar/thunar-clipboard-manager.{c,h}, thunar/thunar-dialogs.{c,h},
	  thunar/thunar-dnd.c, thunar/thunar-dbus-service.c,
	  thunar/thunar-launcher.c, thunar/thunar-location-button.c,
	  thunar/thunar-location-buttons.c, thunar/thunar-progress-dialog.c,
	  thunar/thunar-shortcuts-view.c, thunar/thunar-standard-view.c,
	  thunar/thunar-tree-view.c: Update to new API of
	  ThunarClipboardManager, ThunarApplication and ThunarJob. Replace
	  *a lot* of ThunarVFS references with code based on GIO.
	* thunar/thunar-file.{c,h}: Re-implement thunar_file_accepts_drop()
	  based on a GFile input list. Add new function
	  thunar_file_can_be_trashed().
	* thunar/thunar-io-jobs.{c,h}: Add new jobs
	  thunar_io_jobs_move_files() and thunar_io_jobs_copy_files().
	* thunar/thunar-job.{c,h}: Add "ask-replace" signal and public
	  function thunar_job_ask_replace(), mainly for ThunarTransferJob.
	* thunar/thunar-marshal.list: Add new marshal function
	  _thunar_marshal_FLAGS__OBJECT_OBJECT().

Modified: thunar/branches/migration-to-gio/ChangeLog
===================================================================
--- thunar/branches/migration-to-gio/ChangeLog	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/ChangeLog	2009-04-23 00:56:37 UTC (rev 29891)
@@ -1,3 +1,36 @@
+2009-04-23	Jannis Pohlmann <jannis at xfce.org>
+
+	* thunar/Makefile.am, thunar/thunar-transfer-job.{c,h}: Implement
+	  ThunarTransferJob as an equivalent to ThunarVfsTransferJob. The code
+	  is very similar except that the error handling is a bit different
+	  and all basic operations (non-recursive copy/move) is done based on
+	  GFile and GFileInfo. Copying a file into the same directory
+	  currently does not work the way it did before (new file 'copy of
+	  "%s"' was created). This will be fixed soon.
+	* thunar/thunar-application.{c,h}: Add new function
+	  thunar_application_collect_and_launch_job() as an alternative to
+	  thunar_application_collect_and_launch() but based on GFile and
+	  JobLauncher. Implement thunar_application_move_into(),
+	  thunar_application_copy_into() and thunar_application_copy_to()
+	  based on ThunarTransferJob and GFile instead of ThunarVfsTransferJob.
+	* thunar/thunar-clipboard-manager.{c,h}, thunar/thunar-dialogs.{c,h}, 
+	  thunar/thunar-dnd.c, thunar/thunar-dbus-service.c, 
+	  thunar/thunar-launcher.c, thunar/thunar-location-button.c, 
+	  thunar/thunar-location-buttons.c, thunar/thunar-progress-dialog.c, 
+	  thunar/thunar-shortcuts-view.c, thunar/thunar-standard-view.c, 
+	  thunar/thunar-tree-view.c: Update to new API of 
+	  ThunarClipboardManager, ThunarApplication and ThunarJob. Replace 
+	  *a lot* of ThunarVFS references with code based on GIO.
+	* thunar/thunar-file.{c,h}: Re-implement thunar_file_accepts_drop() 
+	  based on a GFile input list. Add new function
+	  thunar_file_can_be_trashed().
+	* thunar/thunar-io-jobs.{c,h}: Add new jobs
+	  thunar_io_jobs_move_files() and thunar_io_jobs_copy_files().
+	* thunar/thunar-job.{c,h}: Add "ask-replace" signal and public
+	  function thunar_job_ask_replace(), mainly for ThunarTransferJob.
+	* thunar/thunar-marshal.list: Add new marshal function
+	  _thunar_marshal_FLAGS__OBJECT_OBJECT().
+	
 2009-04-22	Jannis Pohlmann <jannis at xfce.org>
 
 	* thunar/Makefile.am, thunar/thunar-io-scan-directory.{c,h}: Port

Modified: thunar/branches/migration-to-gio/thunar/Makefile.am
===================================================================
--- thunar/branches/migration-to-gio/thunar/Makefile.am	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/Makefile.am	2009-04-23 00:56:37 UTC (rev 29891)
@@ -184,6 +184,8 @@
 	thunar-thumbnail-frame.h					\
 	thunar-thumbnail-generator.c					\
 	thunar-thumbnail-generator.h					\
+	thunar-transfer-job.c						\
+	thunar-transfer-job.h						\
 	thunar-trash-action.c						\
 	thunar-trash-action.h						\
 	thunar-tree-model.c						\

Modified: thunar/branches/migration-to-gio/thunar/thunar-application.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-application.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-application.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -96,6 +96,14 @@
                                                              GList                  *source_path_list,
                                                              GList                  *target_path_list,
                                                              GClosure               *new_files_closure);
+static void       thunar_application_collect_and_launch_job (ThunarApplication      *application,
+                                                             gpointer                parent,
+                                                             const gchar            *icon_name,
+                                                             const gchar            *title,
+                                                             JobLauncher             launcher,
+                                                             GList                  *source_file_list,
+                                                             GFile                  *target_file,
+                                                             GClosure               *new_files_closure);
 static void       thunar_application_launch_job             (ThunarApplication      *application,
                                                              gpointer                parent,
                                                              const gchar            *icon_name,
@@ -510,13 +518,76 @@
 
 
 static void
+thunar_application_collect_and_launch_job (ThunarApplication *application,
+                                           gpointer           parent,
+                                           const gchar       *icon_name,
+                                           const gchar       *title,
+                                           JobLauncher        launcher,
+                                           GList             *source_file_list,
+                                           GFile             *target_file,
+                                           GClosure          *new_files_closure)
+{
+  GFile  *file;
+  GError *err = NULL;
+  GList  *target_file_list = NULL;
+  GList  *lp;
+  gchar  *basename;
+
+  /* check if we have anything to operate on */
+  if (G_UNLIKELY (source_file_list == NULL))
+    return;
+
+  /* generate the target path list */
+  for (lp = g_list_last (source_file_list); err == NULL && lp != NULL; lp = lp->prev)
+    {
+      /* verify that we're not trying to collect a root node */
+      if (G_UNLIKELY (g_file_is_root (lp->data)))
+        {
+          /* tell the user that we cannot perform the requested operation */
+          g_set_error (&err, G_FILE_ERROR, G_FILE_ERROR_INVAL, "%s", g_strerror (EINVAL));
+        }
+      else
+        {
+          basename = g_file_get_basename (lp->data);
+          file = g_file_resolve_relative_path (target_file, basename);
+          g_free (basename);
+
+          /* add to the target file list */
+          target_file_list = g_file_list_prepend (target_file_list, file);
+          g_object_unref (file);
+        }
+    }
+
+  /* check if we failed */
+  if (G_UNLIKELY (err != NULL))
+    {
+      /* display an error message to the user */
+      thunar_dialogs_show_error (parent, err, _("Failed to launch operation"));
+
+      /* release the error */
+      g_error_free (err);
+    }
+  else
+    {
+      /* launch the operation */
+      thunar_application_launch_job (application, parent, icon_name, title, launcher,
+                                     source_file_list, target_file_list, new_files_closure);
+    }
+
+  /* release the target path list */
+  g_file_list_free (target_file_list);
+}
+
+
+
+static void
 thunar_application_launch_job (ThunarApplication *application,
                                gpointer           parent,
                                const gchar       *icon_name,
                                const gchar       *title,
                                JobLauncher        launcher,
-                               GList             *source_path_list,
-                               GList             *target_path_list,
+                               GList             *source_file_list,
+                               GList             *target_file_list,
                                GClosure          *new_files_closure)
 {
   ThunarJob *job;
@@ -530,7 +601,7 @@
   screen = thunar_util_parse_parent (parent, &window);
 
   /* try to allocate a new job for the operation */
-  job = (*launcher) (source_path_list, target_path_list);
+  job = (*launcher) (source_file_list, target_file_list);
     
   /* TODO connect the "new-files" closure (if any)
   if (G_LIKELY (new_files_closure != NULL))
@@ -1217,33 +1288,33 @@
  * thunar_application_copy_to:
  * @application       : a #ThunarApplication.
  * @parent            : a #GdkScreen, a #GtkWidget or %NULL.
- * @source_path_list  : the list of #ThunarVfsPath<!---->s that should be copied.
- * @target_path_list  : the list of #ThunarVfsPath<!---->s where files should be copied to.
+ * @source_file_list  : the list of #GFile<!---->s that should be copied.
+ * @target_file_list  : the list of #GFile<!---->s where files should be copied to.
  * @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 #ThunarVfsPath<!---->s created by the job, or
+ *                      list of #GFile<!---->s created by the job, or
  *                      %NULL if you're not interested in the signal.
  *
- * Copies all files from @source_path_list to their locations specified in
- * @target_path_list.
+ * Copies all files from @source_file_list to their locations specified in
+ * @target_file_list.
  *
- * @source_path_list and @target_path_list must be of the same length. 
+ * @source_file_list and @target_file_list must be of the same length. 
  **/
 void
 thunar_application_copy_to (ThunarApplication *application,
                             gpointer           parent,
-                            GList             *source_path_list,
-                            GList             *target_path_list,
+                            GList             *source_file_list,
+                            GList             *target_file_list,
                             GClosure          *new_files_closure)
 {
-  _thunar_return_if_fail (g_list_length (source_path_list) == g_list_length (target_path_list));
+  _thunar_return_if_fail (g_list_length (source_file_list) == g_list_length (target_file_list));
   _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent));
   _thunar_return_if_fail (THUNAR_IS_APPLICATION (application));
 
   /* launch the operation */
-  thunar_application_launch (application, parent, "stock_folder-copy",
-                             _("Copying files..."), thunar_vfs_copy_files,
-                             source_path_list, target_path_list, new_files_closure);
+  thunar_application_launch_job (application, parent, "stock_folder-copy",
+                                 _("Copying files..."), thunar_io_jobs_copy_files,
+                                 source_file_list, target_file_list, new_files_closure);
 }
 
 
@@ -1252,31 +1323,31 @@
  * thunar_application_copy_into:
  * @application       : a #ThunarApplication.
  * @parent            : a #GdkScreen, a #GtkWidget or %NULL.
- * @source_path_list  : the list of #ThunarVfsPath<!---->s that should be copied.
- * @target_path       : the #ThunarVfsPath to the target directory.
+ * @source_file_list  : the list of #GFile<!---->s that should be copied.
+ * @target_file       : the #GFile to the target directory.
  * @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 #ThunarVfsPath<!---->s created by the job, or
+ *                      list of #GFile<!---->s created by the job, or
  *                      %NULL if you're not interested in the signal.
  *
- * Copies all files referenced by the @source_path_list to the directory
- * referenced by @target_path. This method takes care of all user interaction.
+ * Copies all files referenced by the @source_file_list to the directory
+ * referenced by @target_file. This method takes care of all user interaction.
  **/
 void
 thunar_application_copy_into (ThunarApplication *application,
                               gpointer           parent,
-                              GList             *source_path_list,
-                              ThunarVfsPath     *target_path,
+                              GList             *source_file_list,
+                              GFile             *target_file,
                               GClosure          *new_files_closure)
 {
   _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent));
   _thunar_return_if_fail (THUNAR_IS_APPLICATION (application));
-  _thunar_return_if_fail (target_path != NULL);
+  _thunar_return_if_fail (G_IS_FILE (target_file));
 
-  /* collect the target paths and launch the job */
-  thunar_application_collect_and_launch (application, parent, "stock_folder-copy",
-                                         _("Copying files..."), thunar_vfs_copy_files,
-                                         source_path_list, target_path, new_files_closure);
+  /* collect the target files and launch the job */
+  thunar_application_collect_and_launch_job (application, parent, "stock_folder-copy",
+                                             _("Copying files..."), thunar_io_jobs_copy_files,
+                                             source_file_list, target_file, new_files_closure);
 }
 
 
@@ -1320,22 +1391,22 @@
  * thunar_application_move_into:
  * @application       : a #ThunarApplication.
  * @parent            : a #GdkScreen, a #GtkWidget or %NULL.
- * @source_path_list  : the list of #ThunarVfsPath<!---->s that should be moved.
- * @target_path       : the target directory.
+ * @source_file_list  : the list of #GFile<!---->s that should be moved.
+ * @target_file       : the target directory.
  * @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 #ThunarVfsPath<!---->s created by the job, or
  *                      %NULL if you're not interested in the signal.
  *
- * Moves all files referenced by the @source_path_list to the directory
- * referenced by @target_path. This method takes care of all user
+ * Moves all files referenced by the @source_file_list to the directory
+ * referenced by @target_file. This method takes care of all user
  * interaction.
  **/
 void
 thunar_application_move_into (ThunarApplication *application,
                               gpointer           parent,
-                              GList             *source_path_list,
-                              ThunarVfsPath     *target_path,
+                              GList             *source_file_list,
+                              GFile             *target_file,
                               GClosure          *new_files_closure)
 {
   const gchar *icon;
@@ -1343,10 +1414,11 @@
 
   _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent));
   _thunar_return_if_fail (THUNAR_IS_APPLICATION (application));
-  _thunar_return_if_fail (target_path != NULL);
+  _thunar_return_if_fail (target_file != NULL);
 
   /* determine the appropriate message text and the icon based on the target_path */
-  if (thunar_vfs_path_get_scheme (target_path) == THUNAR_VFS_PATH_SCHEME_TRASH)
+  /* TODO we can remove this once we have thunar_application_trash() */
+  if (g_file_is_trashed (target_file)) 
     {
       icon = "gnome-fs-trash-full";
       text = _("Moving files into the trash...");
@@ -1358,9 +1430,10 @@
     }
 
   /* launch the operation */
-  thunar_application_collect_and_launch (application, parent, icon, text,
-                                         thunar_vfs_move_files, source_path_list,
-                                         target_path, new_files_closure);
+  thunar_application_collect_and_launch_job (application, parent, icon, text,
+                                             thunar_io_jobs_move_files, 
+                                             source_file_list, target_file, 
+                                             new_files_closure);
 }
 
 
@@ -1392,11 +1465,11 @@
                                  GList             *file_list)
 {
   GdkModifierType state;
-  ThunarVfsPath  *path;
   GtkWidget      *dialog;
   GtkWindow      *window;
   GdkScreen      *screen;
   gboolean        permanently;
+  GFile          *path;
   GList          *path_list = NULL;
   GList          *lp;
   gchar          *message;
@@ -1471,9 +1544,10 @@
   else
     {
       /* launch the "Move to Trash" operation */
-      path = thunar_vfs_path_get_for_trash ();
+      /* TODO Use thunar_application_trash() here */
+      path = g_file_new_for_trash ();
       thunar_application_move_into (application, parent, path_list, path, NULL);
-      thunar_vfs_path_unref (path);
+      g_object_unref (path);
     }
 
   /* release the path list */

Modified: thunar/branches/migration-to-gio/thunar/thunar-application.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-application.h	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-application.h	2009-04-23 00:56:37 UTC (rev 29891)
@@ -2,6 +2,7 @@
 /*-
  * Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
  * Copyright (c) 2005      Jeff Franks <jcfranks at xfce.org>
+ * Copyright (c) 2009      Jannis Pohlmann <jannis at xfce.org>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -69,14 +70,14 @@
 
 void               thunar_application_copy_to           (ThunarApplication *application,
                                                          gpointer           parent,
-                                                         GList             *source_path_list,
-                                                         GList             *target_path_list,
+                                                         GList             *source_file_list,
+                                                         GList             *target_file_list,
                                                          GClosure          *new_files_closure);
 
 void               thunar_application_copy_into         (ThunarApplication *application,
                                                          gpointer           parent,
-                                                         GList             *source_path_list,
-                                                         ThunarVfsPath     *target_path,
+                                                         GList             *source_file_list,
+                                                         GFile             *target_file,
                                                          GClosure          *new_files_closure);
 
 void               thunar_application_link_into         (ThunarApplication *application,
@@ -87,8 +88,8 @@
 
 void               thunar_application_move_into         (ThunarApplication *application,
                                                          gpointer           parent,
-                                                         GList             *source_path_list,
-                                                         ThunarVfsPath     *target_path,
+                                                         GList             *source_file_list,
+                                                         GFile             *target_file,
                                                          GClosure          *new_files_closure);
 
 void               thunar_application_unlink_files      (ThunarApplication *application,

Modified: thunar/branches/migration-to-gio/thunar/thunar-clipboard-manager.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-clipboard-manager.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-clipboard-manager.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -109,7 +109,7 @@
 typedef struct
 {
   ThunarClipboardManager *manager;
-  ThunarVfsPath          *target_path;
+  GFile                  *target_file;
   GtkWidget              *widget;
   GClosure               *new_files_closure;
 } ThunarClipboardPasteRequest;
@@ -302,7 +302,7 @@
   ThunarClipboardManager      *manager = THUNAR_CLIPBOARD_MANAGER (request->manager);
   ThunarApplication           *application;
   gboolean                     path_copy = TRUE;
-  GList                       *path_list = NULL;
+  GList                       *file_list = NULL;
   gchar                       *data;
 
   /* check whether the retrieval worked */
@@ -325,19 +325,19 @@
         }
 
       /* determine the path list stored with the selection */
-      path_list = thunar_vfs_path_list_from_string (data, NULL);
+      file_list = g_file_list_new_from_string (data);
     }
 
   /* perform the action if possible */
-  if (G_LIKELY (path_list != NULL))
+  if (G_LIKELY (file_list != NULL))
     {
       application = thunar_application_get ();
       if (G_LIKELY (path_copy))
-        thunar_application_copy_into (application, request->widget, path_list, request->target_path, request->new_files_closure);
+        thunar_application_copy_into (application, request->widget, file_list, request->target_file, request->new_files_closure);
       else
-        thunar_application_move_into (application, request->widget, path_list, request->target_path, request->new_files_closure);
+        thunar_application_move_into (application, request->widget, file_list, request->target_file, request->new_files_closure);
       g_object_unref (G_OBJECT (application));
-      thunar_vfs_path_list_free (path_list);
+      g_file_list_free (file_list);
 
       /* clear the clipboard if it contained "cutted data"
        * (gtk_clipboard_clear takes care of not clearing
@@ -365,7 +365,7 @@
   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_object_unref (request->target_file);
   _thunar_slice_free (ThunarClipboardPasteRequest, request);
 }
 
@@ -402,11 +402,11 @@
     }
 
   /* notify listeners that we have a new clipboard state */
-  g_signal_emit (G_OBJECT (manager), manager_signals[CHANGED], 0);
+  g_signal_emit (manager, manager_signals[CHANGED], 0);
   g_object_notify (G_OBJECT (manager), "can-paste");
 
   /* drop the reference taken for the callback */
-  g_object_unref (G_OBJECT (manager));
+  g_object_unref (manager);
 }
 
 
@@ -513,12 +513,8 @@
                                 G_OBJECT (manager));
 
   /* Need to fake a "owner-change" event here if the Xserver doesn't support clipboard notification */
-#if GTK_CHECK_VERSION(2,6,0)
   if (!gdk_display_supports_selection_notification (gtk_clipboard_get_display (manager->clipboard)))
-#endif
-    {
-      thunar_clipboard_manager_owner_changed (manager->clipboard, NULL, manager);
-    }
+    thunar_clipboard_manager_owner_changed (manager->clipboard, NULL, manager);
 }
 
 
@@ -654,21 +650,21 @@
 /**
  * thunar_clipboard_manager_paste_files:
  * @manager           : a #ThunarClipboardManager.
- * @target_path       : the #ThunarVfsPath of the folder to which the contents on the clipboard
+ * @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 #ThunarVfsPath<!---->s created by the job, or
+ *                      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_path.
+ * referenced by @target_file.
  **/
 void
 thunar_clipboard_manager_paste_files (ThunarClipboardManager *manager,
-                                      ThunarVfsPath          *target_path,
+                                      GFile                  *target_file,
                                       GtkWidget              *widget,
                                       GClosure               *new_files_closure)
 {
@@ -680,7 +676,7 @@
   /* prepare the paste request */
   request = _thunar_slice_new0 (ThunarClipboardPasteRequest);
   request->manager = g_object_ref (G_OBJECT (manager));
-  request->target_path = thunar_vfs_path_ref (target_path);
+  request->target_file = g_object_ref (target_file);
   request->widget = widget;
 
   /* take a reference on the closure (if any) */

Modified: thunar/branches/migration-to-gio/thunar/thunar-clipboard-manager.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-clipboard-manager.h	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-clipboard-manager.h	2009-04-23 00:56:37 UTC (rev 29891)
@@ -1,6 +1,7 @@
 /* $Id$ */
 /*-
  * Copyright (c) 2005 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -48,7 +49,7 @@
 void                    thunar_clipboard_manager_cut_files       (ThunarClipboardManager *manager,
                                                                   GList                  *files);
 void                    thunar_clipboard_manager_paste_files     (ThunarClipboardManager *manager,
-                                                                  ThunarVfsPath          *target_path,
+                                                                  GFile                  *target_file,
                                                                   GtkWidget              *widget,
                                                                   GClosure               *new_files_closure);
 

Modified: thunar/branches/migration-to-gio/thunar/thunar-dbus-service.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-dbus-service.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-dbus-service.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -589,11 +589,11 @@
                                    GError           **error)
 {
   ThunarApplication *application;
-  ThunarVfsPath     *target_path;
-  ThunarVfsPath     *path;
+  GFile             *file;
+  GFile             *target_file;
   GdkScreen         *screen;
   GError            *err = NULL;
-  GList             *path_list = NULL;
+  GList             *file_list = NULL;
   gchar             *filename;
   guint              n;
 
@@ -609,9 +609,10 @@
           if (G_LIKELY (err == NULL))
             {
               /* determine the path for the filename */
-              path = thunar_vfs_path_new (filename, &err);
-              if (G_LIKELY (path != NULL))
-                path_list = g_list_append (path_list, path);
+              /* TODO Not sure this will work as expected */
+              file = g_file_new_for_commandline_arg (filename);
+              file_list = g_file_list_append (file_list, file);
+              g_object_unref (file);
             }
 
           /* cleanup */
@@ -623,15 +624,16 @@
         {
           /* tell the application to move the specified files to the trash */
           application = thunar_application_get ();
-          target_path = thunar_vfs_path_get_for_trash ();
-          thunar_application_move_into (application, screen, path_list, target_path, NULL);
-          g_object_unref (G_OBJECT (application));
-          thunar_vfs_path_unref (target_path);
+          /* TODO use thunar_application_trash() instead of thunar_application_move_into() here */
+          target_file = g_file_new_for_trash ();
+          thunar_application_move_into (application, screen, file_list, target_file, NULL);
+          g_object_unref (target_file);
+          g_object_unref (application);
         }
 
       /* cleanup */
-      thunar_vfs_path_list_free (path_list);
-      g_object_unref (G_OBJECT (screen));
+      g_file_list_free (file_list);
+      g_object_unref (screen);
     }
 
   /* check if we failed */

Modified: thunar/branches/migration-to-gio/thunar/thunar-dialogs.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-dialogs.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-dialogs.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -393,10 +393,10 @@
  *
  * Return value: the #ThunarVfsJobResponse.
  **/
-ThunarVfsJobResponse
-thunar_dialogs_show_job_ask (GtkWindow           *parent,
-                             const gchar         *question,
-                             ThunarVfsJobResponse choices)
+ThunarJobResponse
+thunar_dialogs_show_job_ask (GtkWindow        *parent,
+                             const gchar      *question,
+                             ThunarJobResponse choices)
 {
   const gchar *separator;
   const gchar *mnemonic;
@@ -526,26 +526,24 @@
 /**
  * thunar_dialogs_show_job_ask_replace:
  * @parent   : the parent #GtkWindow or %NULL.
- * @src_info : the #ThunarVfsInfo of the source file.
- * @dst_info : the #ThunarVfsInfo of the destination file that
+ * @src_file : the #ThunarFile of the source file.
+ * @dst_file : the #ThunarFile of the destination file that
  *             may be replaced with the source file.
  *
  * Asks the user whether to replace the destination file with the
- * source file identified by @src_info.
+ * source file identified by @src_file.
  *
  * Return value: the selected #ThunarVfsJobResponse.
  **/
-ThunarVfsJobResponse
-thunar_dialogs_show_job_ask_replace (GtkWindow     *parent,
-                                     ThunarVfsInfo *src_info,
-                                     ThunarVfsInfo *dst_info)
+ThunarJobResponse
+thunar_dialogs_show_job_ask_replace (GtkWindow  *parent,
+                                     ThunarFile *src_file,
+                                     ThunarFile *dst_file)
 {
   ThunarIconFactory *icon_factory;
   ThunarPreferences *preferences;
   ThunarDateStyle    date_style;
   GtkIconTheme      *icon_theme;
-  ThunarFile        *src_file;
-  ThunarFile        *dst_file;
   GtkWidget         *dialog;
   GtkWidget         *table;
   GtkWidget         *image;
@@ -556,19 +554,15 @@
   gchar             *text;
   gint               response;
 
-  _thunar_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), THUNAR_VFS_JOB_RESPONSE_CANCEL);
-  _thunar_return_val_if_fail (src_info != NULL, THUNAR_VFS_JOB_RESPONSE_CANCEL);
-  _thunar_return_val_if_fail (dst_info != NULL, THUNAR_VFS_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), THUNAR_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (THUNAR_IS_FILE (src_file), THUNAR_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (THUNAR_IS_FILE (dst_file), THUNAR_JOB_RESPONSE_CANCEL);
 
   /* determine the style used to format dates */
   preferences = thunar_preferences_get ();
   g_object_get (G_OBJECT (preferences), "misc-date-style", &date_style, NULL);
   g_object_unref (G_OBJECT (preferences));
 
-  /* determine the files for the infos */
-  src_file = thunar_file_get_for_info (src_info);
-  dst_file = thunar_file_get_for_info (dst_info);
-
   /* setup the confirmation dialog */
   dialog = gtk_dialog_new_with_buttons (_("Confirm to replace files"),
                                         parent,
@@ -576,17 +570,17 @@
                                         | GTK_DIALOG_NO_SEPARATOR
                                         | GTK_DIALOG_DESTROY_WITH_PARENT,
                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                        _("_Skip"), THUNAR_VFS_JOB_RESPONSE_NO,
-                                        _("Replace _All"), THUNAR_VFS_JOB_RESPONSE_YES_ALL,
-                                        _("_Replace"), THUNAR_VFS_JOB_RESPONSE_YES,
+                                        _("_Skip"), THUNAR_JOB_RESPONSE_NO,
+                                        _("Replace _All"), THUNAR_JOB_RESPONSE_YES_ALL,
+                                        _("_Replace"), THUNAR_JOB_RESPONSE_YES,
                                         NULL);
   gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
-                                           THUNAR_VFS_JOB_RESPONSE_YES,
-                                           THUNAR_VFS_JOB_RESPONSE_YES_ALL,
-                                           THUNAR_VFS_JOB_RESPONSE_NO,
+                                           THUNAR_JOB_RESPONSE_YES,
+                                           THUNAR_JOB_RESPONSE_YES_ALL,
+                                           THUNAR_JOB_RESPONSE_NO,
                                            GTK_RESPONSE_CANCEL,
                                            -1);
-  gtk_dialog_set_default_response (GTK_DIALOG (dialog), THUNAR_VFS_JOB_RESPONSE_YES);
+  gtk_dialog_set_default_response (GTK_DIALOG (dialog), THUNAR_JOB_RESPONSE_YES);
 
   /* determine the icon factory to use */
   icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (dialog));
@@ -672,12 +666,10 @@
 
   /* cleanup */
   g_object_unref (G_OBJECT (icon_factory));
-  g_object_unref (G_OBJECT (dst_file));
-  g_object_unref (G_OBJECT (src_file));
 
   /* translate GTK responses */
   if (G_UNLIKELY (response < 0))
-    response = THUNAR_VFS_JOB_RESPONSE_CANCEL;
+    response = THUNAR_JOB_RESPONSE_CANCEL;
 
   return response;
 }

Modified: thunar/branches/migration-to-gio/thunar/thunar-dialogs.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-dialogs.h	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-dialogs.h	2009-04-23 00:56:37 UTC (rev 29891)
@@ -25,33 +25,33 @@
 
 G_BEGIN_DECLS;
 
-gboolean              thunar_dialogs_show_rename_file     (GtkWindow            *parent,
-                                                           ThunarFile           *file) G_GNUC_INTERNAL;
+gboolean           thunar_dialogs_show_rename_file     (GtkWindow            *parent,
+                                                        ThunarFile           *file) G_GNUC_INTERNAL;
 
-void                  thunar_dialogs_show_about           (GtkWindow            *parent,
-                                                           const gchar          *title,
-                                                           const gchar          *format,
-                                                           ...) G_GNUC_INTERNAL G_GNUC_PRINTF (3, 4);
+void               thunar_dialogs_show_about           (GtkWindow            *parent,
+                                                        const gchar          *title,
+                                                        const gchar          *format,
+                                                        ...) G_GNUC_INTERNAL G_GNUC_PRINTF (3, 4);
 
-void                  thunar_dialogs_show_error           (gpointer              parent,
-                                                           const GError         *error,
-                                                           const gchar          *format,
-                                                           ...) G_GNUC_INTERNAL G_GNUC_PRINTF (3, 4);
+void               thunar_dialogs_show_error           (gpointer              parent,
+                                                        const GError         *error,
+                                                        const gchar          *format,
+                                                        ...) G_GNUC_INTERNAL G_GNUC_PRINTF (3, 4);
 
-void                  thunar_dialogs_show_help            (gpointer              parent,
-                                                           const gchar          *page,
-                                                           const gchar          *offset) G_GNUC_INTERNAL;
+void               thunar_dialogs_show_help            (gpointer              parent,
+                                                        const gchar          *page,
+                                                        const gchar          *offset) G_GNUC_INTERNAL;
 
-ThunarVfsJobResponse  thunar_dialogs_show_job_ask         (GtkWindow            *parent,
-                                                           const gchar          *question,
-                                                           ThunarVfsJobResponse  choices) G_GNUC_INTERNAL;
+ThunarJobResponse  thunar_dialogs_show_job_ask         (GtkWindow            *parent,
+                                                        const gchar          *question,
+                                                        ThunarJobResponse     choices) G_GNUC_INTERNAL;
 
-ThunarVfsJobResponse  thunar_dialogs_show_job_ask_replace (GtkWindow            *parent,
-                                                           ThunarVfsInfo        *src_info,
-                                                           ThunarVfsInfo        *dst_info) G_GNUC_INTERNAL;
+ThunarJobResponse  thunar_dialogs_show_job_ask_replace (GtkWindow            *parent,
+                                                        ThunarFile           *src_file,
+                                                        ThunarFile           *dst_file) G_GNUC_INTERNAL;
 
-void                  thunar_dialogs_show_job_error       (GtkWindow            *parent,
-                                                           GError               *error) G_GNUC_INTERNAL;
+void               thunar_dialogs_show_job_error       (GtkWindow            *parent,
+                                                        GError               *error) G_GNUC_INTERNAL;
 
 G_END_DECLS;
 

Modified: thunar/branches/migration-to-gio/thunar/thunar-dnd.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-dnd.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-dnd.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -1,6 +1,7 @@
 /* $Id$ */
 /*-
  * Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -44,7 +45,7 @@
  * thunar_dnd_ask:
  * @widget    : the widget on which the drop was performed.
  * @folder    : the #ThunarFile to which the @path_list is being dropped.
- * @path_list : the #ThunarVfsPath<!---->s of the files being dropped to @file.
+ * @path_list : the #GFile<!---->s of the files being dropped to @file.
  * @time      : the time of the drop event.
  * @actions   : the list of actions supported for the drop.
  *
@@ -124,7 +125,7 @@
       for (lp = path_list; lp != NULL; lp = lp->next)
         {
           /* try to resolve this path */
-          file = thunar_file_cache_lookup_path (lp->data);
+          file = thunar_file_cache_lookup (lp->data);
           if (G_LIKELY (file != NULL))
             file_list = g_list_prepend (file_list, file);
           else
@@ -189,11 +190,11 @@
  * thunar_dnd_perform:
  * @widget            : the #GtkWidget on which the drop was done.
  * @file              : the #ThunarFile on which the @path_list was dropped.
- * @path_list         : the list of #ThunarVfsPath<!---->s that was dropped.
+ * @path_list         : the list of #GFile<!---->s that was dropped.
  * @action            : the #GdkDragAction that was performed.
  * @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 #ThunarVfsPath<!---->s created by the job, or
+ *                      list of #GFile<!---->s created by the job, or
  *                      %NULL if you're not interested in the signal.
  *
  * Performs the drop of @path_list on @file in @widget, as given in
@@ -228,15 +229,17 @@
       switch (action)
         {
         case GDK_ACTION_COPY:
-          thunar_application_copy_into (application, widget, path_list, thunar_file_get_path (file), new_files_closure);
+          thunar_application_copy_into (application, widget, path_list, thunar_file_get_file (file), new_files_closure);
           break;
 
         case GDK_ACTION_MOVE:
-          thunar_application_move_into (application, widget, path_list, thunar_file_get_path (file), new_files_closure);
+          thunar_application_move_into (application, widget, path_list, thunar_file_get_file (file), new_files_closure);
           break;
 
         case GDK_ACTION_LINK:
+          /* TODO Enable this again:
           thunar_application_link_into (application, widget, path_list, thunar_file_get_path (file), new_files_closure);
+          */
           break;
 
         default:

Modified: thunar/branches/migration-to-gio/thunar/thunar-file.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-file.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-file.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -1112,7 +1112,7 @@
 /**
  * thunar_file_accepts_drop:
  * @file                    : a #ThunarFile instance.
- * @path_list               : the list of #ThunarVfsPath<!---->s that will be droppped.
+ * @file_list               : the list of #GFile<!---->s that will be droppped.
  * @context                 : the current #GdkDragContext, which is used for the drop.
  * @suggested_action_return : return location for the suggested #GdkDragAction or %NULL.
  *
@@ -1129,7 +1129,7 @@
  **/
 GdkDragAction
 thunar_file_accepts_drop (ThunarFile     *file,
-                          GList          *path_list,
+                          GList          *file_list,
                           GdkDragContext *context,
                           GdkDragAction  *suggested_action_return)
 {
@@ -1137,16 +1137,14 @@
   GdkDragAction actions;
   ThunarFile   *ofile;
   GFile        *parent_file;
-  GFile        *gfile;
   GList        *lp;
-  gchar        *uri;
   guint         n;
 
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), 0);
   _thunar_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), 0);
 
   /* we can never drop an empty list */
-  if (G_UNLIKELY (path_list == NULL))
+  if (G_UNLIKELY (file_list == NULL))
     return 0;
 
   /* default to whatever GTK+ thinks for the suggested action */
@@ -1165,21 +1163,14 @@
       /* check up to 100 of the paths (just in case somebody tries to
        * drag around his music collection with 5000 files).
        */
-      for (lp = path_list, n = 0; lp != NULL && n < 100; lp = lp->next, ++n)
+      for (lp = file_list, n = 0; lp != NULL && n < 100; lp = lp->next, ++n)
         {
-          uri = thunar_vfs_path_dup_uri (lp->data);
-          gfile = g_file_new_for_uri (uri);
-          g_free (uri);
-
           /* we cannot drop a file on itself */
-          if (G_UNLIKELY (g_file_equal (file->gfile, gfile)))
-            {
-              g_object_unref (gfile);
-              return 0;
-            }
+          if (G_UNLIKELY (g_file_equal (file->gfile, lp->data)))
+            return 0;
 
           /* check whether source and destination are the same */
-          parent_file = g_file_get_parent (gfile);
+          parent_file = g_file_get_parent (lp->data);
           if (G_LIKELY (parent_file != NULL))
             {
               if (g_file_equal (file->gfile, parent_file))
@@ -1191,39 +1182,29 @@
                 g_object_unref (parent_file);
             }
 
-          /* check if both source and target is in the trash */
-          if (G_UNLIKELY (g_file_is_trashed (gfile) && thunar_file_is_trashed (file)))
-            {
-              /* copy/move/link within the trash not possible */
-              g_object_unref (gfile);
-              return 0;
-            }
+          /* copy/move/link within the trash not possible */
+          if (G_UNLIKELY (g_file_is_trashed (lp->data) && thunar_file_is_trashed (file)))
+            return 0;
         }
 
       /* if the source offers both copy and move and the GTK+ suggested action is copy, try to be smart telling whether
        * we should copy or move by default by checking whether the source and target are on the same disk.
        */
-      if ((actions & (GDK_ACTION_COPY | GDK_ACTION_MOVE)) != 0 && (suggested_action == GDK_ACTION_COPY))
+      if ((actions & (GDK_ACTION_COPY | GDK_ACTION_MOVE)) != 0 
+          && (suggested_action == GDK_ACTION_COPY))
         {
           /* default to move as suggested action */
           suggested_action = GDK_ACTION_MOVE;
 
           /* check for up to 100 files, for the reason state above */
-          for (lp = path_list, n = 0; lp != NULL && n < 100; lp = lp->next, ++n)
+          for (lp = file_list, n = 0; lp != NULL && n < 100; lp = lp->next, ++n)
             {
-              uri = thunar_vfs_path_dup_uri (lp->data);
-              gfile = g_file_new_for_uri (uri);
-              g_free (uri);
-
               /* dropping from the trash always suggests move */
-              if (G_UNLIKELY (g_file_is_trashed (gfile)))
-                {
-                  g_object_unref (gfile);
-                  break;
-                }
+              if (G_UNLIKELY (g_file_is_trashed (lp->data)))
+                break;
 
               /* determine the cached version of the source file */
-              ofile = thunar_file_cache_lookup (gfile);
+              ofile = thunar_file_cache_lookup (lp->data);
 
               /* we have only move if we know the source and both the source and the target
                * are on the same disk, and the source file is owned by the current user.
@@ -1232,14 +1213,10 @@
                   || (ofile->info->device != file->info->device) 
                   || (ofile->info->uid != effective_user_id))
                 {
-                  g_object_unref (gfile);
-
                   /* default to copy and get outa here */
                   suggested_action = GDK_ACTION_COPY;
                   break;
                 }
-
-              g_object_unref (gfile);
             }
         }
     }
@@ -2029,6 +2006,17 @@
 
 
 
+gboolean
+thunar_file_can_be_trashed (const ThunarFile *file)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
+  _thunar_return_val_if_fail (G_IS_FILE_INFO (file->ginfo), FALSE);
+  return g_file_info_get_attribute_boolean (file->ginfo, 
+                                            G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH);
+}
+
+
+
 /**
  * thunar_file_get_emblem_names:
  * @file : a #ThunarFile instance.

Modified: thunar/branches/migration-to-gio/thunar/thunar-file.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-file.h	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-file.h	2009-04-23 00:56:37 UTC (rev 29891)
@@ -225,6 +225,7 @@
 
 gboolean          thunar_file_is_chmodable         (const ThunarFile       *file);
 gboolean          thunar_file_is_renameable        (const ThunarFile       *file);
+gboolean          thunar_file_can_be_trashed       (const ThunarFile       *file);
 
 GList            *thunar_file_get_emblem_names     (ThunarFile              *file);
 void              thunar_file_set_emblem_names     (ThunarFile              *file,

Modified: thunar/branches/migration-to-gio/thunar/thunar-io-jobs.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-io-jobs.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-io-jobs.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -29,6 +29,7 @@
 #include <thunar/thunar-job.h>
 #include <thunar/thunar-private.h>
 #include <thunar/thunar-simple-job.h>
+#include <thunar/thunar-transfer-job.h>
 
 
 
@@ -92,7 +93,7 @@
   
   _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
   _thunar_return_val_if_fail (param_values != NULL, FALSE);
-  _thunar_return_val_if_fail (param_values->n_values > 0, FALSE);
+  _thunar_return_val_if_fail (param_values->n_values == 1, FALSE);
   _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
   /* get the file list */
@@ -235,7 +236,7 @@
 
   _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
   _thunar_return_val_if_fail (param_values != NULL, FALSE);
-  _thunar_return_val_if_fail (param_values->n_values > 0, FALSE);
+  _thunar_return_val_if_fail (param_values->n_values == 1, FALSE);
   _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
   file_list = g_value_get_boxed (g_value_array_get_nth (param_values, 0));
@@ -370,7 +371,7 @@
 
   _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
   _thunar_return_val_if_fail (param_values != NULL, FALSE);
-  _thunar_return_val_if_fail (param_values->n_values > 0, FALSE);
+  _thunar_return_val_if_fail (param_values->n_values == 1, FALSE);
   _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
   /* get the file list */
@@ -468,3 +469,33 @@
   return thunar_simple_job_launch (_thunar_io_jobs_unlink, 1,
                                    G_TYPE_FILE_LIST, file_list);
 }
+
+
+
+ThunarJob *
+thunar_io_jobs_move_files (GList *source_file_list,
+                           GList *target_file_list)
+{
+  _thunar_return_val_if_fail (source_file_list != NULL, NULL);
+  _thunar_return_val_if_fail (target_file_list != NULL, NULL);
+  _thunar_return_val_if_fail (g_list_length (source_file_list) == g_list_length (target_file_list), NULL);
+  
+  return thunar_job_launch (thunar_transfer_job_new (source_file_list, 
+                                                     target_file_list, 
+                                                     THUNAR_TRANSFER_JOB_MOVE));
+}
+
+
+
+ThunarJob *
+thunar_io_jobs_copy_files (GList *source_file_list,
+                           GList *target_file_list)
+{
+  _thunar_return_val_if_fail (source_file_list != NULL, NULL);
+  _thunar_return_val_if_fail (target_file_list != NULL, NULL);
+  _thunar_return_val_if_fail (g_list_length (source_file_list) == g_list_length (target_file_list), NULL);
+
+  return thunar_job_launch (thunar_transfer_job_new (source_file_list,
+                                                     target_file_list,
+                                                     THUNAR_TRANSFER_JOB_COPY));
+}

Modified: thunar/branches/migration-to-gio/thunar/thunar-io-jobs.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-io-jobs.h	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-io-jobs.h	2009-04-23 00:56:37 UTC (rev 29891)
@@ -28,6 +28,10 @@
 ThunarJob *thunar_io_jobs_create_files     (GList *file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 ThunarJob *thunar_io_jobs_make_directories (GList *file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 ThunarJob *thunar_io_jobs_unlink_files     (GList *file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+ThunarJob *thunar_io_jobs_move_files       (GList *source_file_list,
+                                            GList *target_file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+ThunarJob *thunar_io_jobs_copy_files       (GList *source_file_list,
+                                            GList *target_file_list) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 
 G_END_DECLS
 

Modified: thunar/branches/migration-to-gio/thunar/thunar-job.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-job.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-job.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -60,24 +60,26 @@
 
 
 
-static void     thunar_job_class_init          (ThunarJobClass     *klass);
-static void     thunar_job_init                (ThunarJob          *job);
-static void     thunar_job_finalize            (GObject            *object);
+static void              thunar_job_class_init          (ThunarJobClass     *klass);
+static void              thunar_job_init                (ThunarJob          *job);
+static void              thunar_job_finalize            (GObject            *object);
+static ThunarJobResponse thunar_job_real_ask_replace    (ThunarJob          *job,
+                                                         ThunarFile         *source_file,
+                                                         ThunarFile         *target_file);
+static void              _thunar_job_error              (ThunarJob          *job,
+                                                         GError             *error);
+static void              _thunar_job_finished           (ThunarJob          *job);
+static gboolean          _thunar_job_finish             (ThunarJob          *job,
+                                                         GSimpleAsyncResult *result,
+                                                         GError            **error);
+static void              _thunar_job_async_ready        (GObject            *object,
+                                                         GAsyncResult       *result);
+static gboolean          _thunar_job_scheduler_job_func (GIOSchedulerJob    *scheduler_job,
+                                                         GCancellable       *cancellable,
+                                                         gpointer            user_data);
 
-static void     _thunar_job_error              (ThunarJob          *job,
-                                                GError             *error);
-static void     _thunar_job_finished           (ThunarJob          *job);
-static gboolean _thunar_job_finish             (ThunarJob          *job,
-                                                GSimpleAsyncResult *result,
-                                                GError            **error);
-static void     _thunar_job_async_ready        (GObject            *object,
-                                                GAsyncResult       *result);
-static gboolean _thunar_job_scheduler_job_func (GIOSchedulerJob    *scheduler_job,
-                                                GCancellable       *cancellable,
-                                                gpointer            user_data);
 
 
-
 struct _ThunarJobPrivate
 {
   ThunarJobResponse earlier_ask_overwrite_response;
@@ -151,6 +153,7 @@
   gobject_class->finalize = thunar_job_finalize;
 
   klass->execute = NULL;
+  klass->ask_replace = thunar_job_real_ask_replace;
 
   /**
    * ThunarJob::ask:
@@ -174,6 +177,28 @@
                   THUNAR_TYPE_JOB_RESPONSE);
 
   /**
+   * ThunarJob::ask-replace:
+   * @job      : a #ThunarJob.
+   * @src_file : the #ThunarFile of the source file.
+   * @dst_file : the #ThunarFile of the destination file, that
+   *             may be replaced with the source file.
+   *
+   * Emitted to ask the user whether the destination file should
+   * be replaced by the source file.
+   *
+   * Return value: the selected choice.
+   **/
+  job_signals[ASK_REPLACE] =
+    g_signal_new (I_("ask-replace"),
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_NO_HOOKS | G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (ThunarJobClass, ask_replace),
+                  _thunar_job_ask_accumulator, NULL,
+                  _thunar_marshal_FLAGS__OBJECT_OBJECT,
+                  THUNAR_TYPE_JOB_RESPONSE, 
+                  2, THUNAR_TYPE_FILE, THUNAR_TYPE_FILE);
+
+  /**
    * ThunarJob::error:
    * @job   : a #ThunarJob.
    * @error : a #GError describing the cause.
@@ -269,6 +294,38 @@
 
 
 
+static ThunarJobResponse 
+thunar_job_real_ask_replace (ThunarJob  *job,
+                             ThunarFile *source_file,
+                             ThunarFile *target_file)
+{
+  ThunarJobResponse response;
+  gchar            *message;
+
+  _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (THUNAR_IS_FILE (source_file), THUNAR_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (THUNAR_IS_FILE (target_file), THUNAR_JOB_RESPONSE_CANCEL);
+
+  message = g_strdup_printf (_("The file \"%s\" already exists. Would you like to replace it?\n\n"
+                               "If you replace an existing file, its contents will be overwritten."),
+                             thunar_file_get_display_name (source_file));
+
+  g_signal_emit (job, job_signals[ASK], 0, message,
+                 THUNAR_JOB_RESPONSE_YES
+                 | THUNAR_JOB_RESPONSE_YES_ALL
+                 | THUNAR_JOB_RESPONSE_NO
+                 | THUNAR_JOB_RESPONSE_NO_ALL
+                 | THUNAR_JOB_RESPONSE_CANCEL,
+                 &response);
+
+  /* clean up */
+  g_free (message);
+
+  return response;
+}
+
+
+
 static gboolean
 _thunar_job_finish (ThunarJob          *job,
                     GSimpleAsyncResult *result,
@@ -590,6 +647,65 @@
 
 
 ThunarJobResponse 
+thunar_job_ask_replace (ThunarJob *job,
+                        GFile     *source_path,
+                        GFile     *target_path,
+                        GError   **error)
+{
+  ThunarJobResponse response;
+  ThunarFile       *source_file;
+  ThunarFile       *target_file;
+
+  _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (G_IS_FILE (source_path), THUNAR_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (G_IS_FILE (target_path), THUNAR_JOB_RESPONSE_CANCEL);
+
+  if (G_UNLIKELY (thunar_job_set_error_if_cancelled (job, error)))
+    return THUNAR_JOB_RESPONSE_CANCEL;
+
+  /* check if the user said "Overwrite All" earlier */
+  if (G_UNLIKELY (job->priv->earlier_ask_overwrite_response == THUNAR_JOB_RESPONSE_YES_ALL))
+    return THUNAR_JOB_RESPONSE_YES;
+
+  /* check if the user said "Overwrite None" earlier */
+  if (G_UNLIKELY (job->priv->earlier_ask_overwrite_response == THUNAR_JOB_RESPONSE_NO_ALL))
+    return THUNAR_JOB_RESPONSE_NO;
+
+  source_file = thunar_file_get (source_path, error);
+
+  if (G_UNLIKELY (source_file == NULL))
+    return THUNAR_JOB_RESPONSE_NO;
+
+  target_file = thunar_file_get (target_path, error);
+
+  if (G_UNLIKELY (target_file == NULL))
+    {
+      g_object_unref (source_file);
+      return THUNAR_JOB_RESPONSE_NO;
+    }
+
+  thunar_job_emit (job, job_signals[ASK_REPLACE], 0, source_file, target_file, &response);
+
+  g_object_unref (source_file);
+  g_object_unref (target_file);
+
+  /* remember the response for later */
+  job->priv->earlier_ask_overwrite_response = response;
+
+  /* translate the response */
+  if (response == THUNAR_JOB_RESPONSE_YES_ALL)
+    response = THUNAR_JOB_RESPONSE_YES;
+  else if (response == THUNAR_JOB_RESPONSE_NO_ALL)
+    response = THUNAR_JOB_RESPONSE_NO;
+  else if (response == THUNAR_JOB_RESPONSE_CANCEL)
+    thunar_job_cancel (job);
+
+  return response;
+}
+
+
+
+ThunarJobResponse 
 thunar_job_ask_skip (ThunarJob   *job,
                      const gchar *format,
                      ...)
@@ -660,7 +776,7 @@
 {
   _thunar_return_if_fail (THUNAR_IS_JOB (job));
 
-  percent = MIN (0.0, MAX (100.0, percent));
+  percent = MAX (0.0, MIN (100.0, percent));
   thunar_job_emit (job, job_signals[PERCENT], 0, percent);
 }
 

Modified: thunar/branches/migration-to-gio/thunar/thunar-job.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-job.h	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-job.h	2009-04-23 00:56:37 UTC (rev 29891)
@@ -52,9 +52,12 @@
                                 GError          **error);
 
   /* signals */
-  ThunarJobResponse (*ask)     (ThunarJob        *job,
-                                const gchar      *message,
-                                ThunarJobResponse choices);
+  ThunarJobResponse (*ask)         (ThunarJob        *job,
+                                    const gchar      *message,
+                                    ThunarJobResponse choices);
+  ThunarJobResponse (*ask_replace) (ThunarJob        *job,
+                                    ThunarFile       *source_file,
+                                    ThunarFile       *target_file);
 };
 
 struct _ThunarJob
@@ -85,6 +88,10 @@
 ThunarJobResponse thunar_job_ask_overwrite          (ThunarJob       *job,
                                                      const gchar     *format,
                                                      ...);
+ThunarJobResponse thunar_job_ask_replace            (ThunarJob       *job,
+                                                     GFile           *source_path,
+                                                     GFile           *target_path,
+                                                     GError         **error);
 ThunarJobResponse thunar_job_ask_skip               (ThunarJob       *job,
                                                      const gchar     *format,
                                                      ...);

Modified: thunar/branches/migration-to-gio/thunar/thunar-launcher.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-launcher.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-launcher.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -1173,15 +1173,18 @@
 {
   ThunarApplication *application;
   ThunarVfsVolume   *volume;
+  ThunarVfsPath     *path;
   GError            *err = NULL;
-  GList             *paths;
+  GFile             *target_file;
+  GList             *files;
+  gchar             *uri;
 
   _thunar_return_if_fail (GTK_IS_ACTION (action));
   _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher));
 
   /* determine the source paths */
-  paths = thunar_file_list_to_path_list (launcher->selected_files);
-  if (G_UNLIKELY (paths == NULL))
+  files = thunar_file_list_to_g_file_list (launcher->selected_files);
+  if (G_UNLIKELY (files == NULL))
     return;
 
   /* determine the volume to which to send */
@@ -1199,14 +1202,22 @@
     }
   else
     {
+      /* Determine the GFile for the mount point */
+      path = thunar_vfs_volume_get_mount_point (volume);
+      uri = thunar_vfs_path_dup_uri (path);
+      target_file = g_file_new_for_uri (uri);
+      g_free (uri);
+
       /* copy the files onto the specified volume */
       application = thunar_application_get ();
-      thunar_application_copy_into (application, launcher->widget, paths, thunar_vfs_volume_get_mount_point (volume), NULL);
+      thunar_application_copy_into (application, launcher->widget, files, target_file, NULL);
       g_object_unref (G_OBJECT (application));
+
+      g_object_unref (target_file);
     }
 
   /* cleanup */
-  thunar_vfs_path_list_free (paths);
+  g_file_list_free (files);
 }
 
 

Modified: thunar/branches/migration-to-gio/thunar/thunar-location-button.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-location-button.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-location-button.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -1,6 +1,7 @@
 /* $Id$ */
 /*-
  * Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -30,6 +31,7 @@
 
 #include <thunar/thunar-application.h>
 #include <thunar/thunar-dnd.h>
+#include <thunar/thunar-gio-extensions.h>
 #include <thunar/thunar-icon-factory.h>
 #include <thunar/thunar-location-button.h>
 #include <thunar/thunar-pango-extensions.h>
@@ -140,7 +142,7 @@
   gint                enter_timeout_id;
 
   /* drop support for the button */
-  GList              *drop_path_list;
+  GList              *drop_file_list;
   guint               drop_data_ready : 1;
   guint               drop_occurred : 1;
 
@@ -340,7 +342,7 @@
   ThunarLocationButton *location_button = THUNAR_LOCATION_BUTTON (object);
 
   /* release the drop path list (just in case the drag-leave wasn't fired before) */
-  thunar_vfs_path_list_free (location_button->drop_path_list);
+  g_file_list_free (location_button->drop_file_list);
 
   /* be sure to cancel any pending enter timeout */
   if (G_UNLIKELY (location_button->enter_timeout_id != 0))
@@ -434,7 +436,7 @@
   if (G_LIKELY (location_button->file != NULL))
     {
       /* determine the possible drop actions for the file (and the suggested action if any) */
-      actions = thunar_file_accepts_drop (location_button->file, location_button->drop_path_list, context, &action);
+      actions = thunar_file_accepts_drop (location_button->file, location_button->drop_file_list, context, &action);
     }
 
   /* tell Gdk whether we can drop here */
@@ -699,7 +701,7 @@
     {
       /* extract the URI list from the selection data (if valid) */
       if (selection_data->format == 8 && selection_data->length > 0)
-        location_button->drop_path_list = thunar_vfs_path_list_from_string ((const gchar *) selection_data->data, NULL);
+        location_button->drop_file_list = g_file_list_new_from_string ((const gchar *) selection_data->data);
 
       /* reset the state */
       location_button->drop_data_ready = TRUE;
@@ -717,12 +719,12 @@
         {
           /* as the user what to do with the drop data */
           action = (context->action == GDK_ACTION_ASK)
-                 ? thunar_dnd_ask (button, location_button->file, location_button->drop_path_list, time, actions)
+                 ? thunar_dnd_ask (button, location_button->file, location_button->drop_file_list, time, actions)
                  : context->action;
 
           /* perform the requested action */
           if (G_LIKELY (action != 0))
-            succeed = thunar_dnd_perform (button, location_button->file, location_button->drop_path_list, action, NULL);
+            succeed = thunar_dnd_perform (button, location_button->file, location_button->drop_file_list, action, NULL);
         }
 
       /* tell the peer that we handled the drop */
@@ -758,9 +760,9 @@
   /* reset the "drop data ready" status and free the path list */
   if (G_LIKELY (location_button->drop_data_ready))
     {
-      thunar_vfs_path_list_free (location_button->drop_path_list);
+      g_file_list_free (location_button->drop_file_list);
       location_button->drop_data_ready = FALSE;
-      location_button->drop_path_list = NULL;
+      location_button->drop_file_list = NULL;
     }
 
   /* be sure to cancel any running enter timeout */

Modified: thunar/branches/migration-to-gio/thunar/thunar-location-buttons.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-location-buttons.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-location-buttons.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -1460,7 +1460,7 @@
     {
       /* paste files from the clipboard to the folder represented by this button */
       clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (GTK_WIDGET (buttons)));
-      thunar_clipboard_manager_paste_files (clipboard, thunar_file_get_path (directory), GTK_WIDGET (buttons), NULL);
+      thunar_clipboard_manager_paste_files (clipboard, thunar_file_get_file (directory), GTK_WIDGET (buttons), NULL);
       g_object_unref (G_OBJECT (clipboard));
     }
 }

Modified: thunar/branches/migration-to-gio/thunar/thunar-marshal.list
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-marshal.list	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-marshal.list	2009-04-23 00:56:37 UTC (rev 29891)
@@ -1,6 +1,6 @@
 BOOLEAN:POINTER
 BOOLEAN:VOID
-FLAGS:BOXED,BOXED
+FLAGS:OBJECT,OBJECT
 FLAGS:STRING,FLAGS
 VOID:BOXED,OBJECT
 VOID:BOXED,POINTER

Modified: thunar/branches/migration-to-gio/thunar/thunar-progress-dialog.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-progress-dialog.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-progress-dialog.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -39,38 +39,38 @@
 
 
 
-static void                 thunar_progress_dialog_class_init   (ThunarProgressDialogClass  *klass);
-static void                 thunar_progress_dialog_init         (ThunarProgressDialog       *dialog);
-static void                 thunar_progress_dialog_dispose      (GObject                    *object);
-static void                 thunar_progress_dialog_get_property (GObject                    *object,
-                                                                 guint                       prop_id,
-                                                                 GValue                     *value,
-                                                                 GParamSpec                 *pspec);
-static void                 thunar_progress_dialog_set_property (GObject                    *object,
-                                                                 guint                       prop_id,
-                                                                 const GValue               *value,
-                                                                 GParamSpec                 *pspec);
-static void                 thunar_progress_dialog_response     (GtkDialog                  *dialog,
-                                                                 gint                        response);
-static ThunarJobResponse    thunar_progress_dialog_ask          (ThunarProgressDialog       *dialog,
-                                                                 const gchar                *message,
-                                                                 ThunarJobResponse           choices,
-                                                                 gpointer                   *job);
-static ThunarVfsJobResponse thunar_progress_dialog_ask_replace  (ThunarProgressDialog       *dialog,
-                                                                 ThunarVfsInfo              *src_info,
-                                                                 ThunarVfsInfo              *dst_info,
-                                                                 ThunarVfsJob               *job);
-static void                 thunar_progress_dialog_error        (ThunarProgressDialog       *dialog,
-                                                                 GError                     *error,
-                                                                 gpointer                   *job);
-static void                 thunar_progress_dialog_finished     (ThunarProgressDialog       *dialog,
-                                                                 gpointer                   *job);
-static void                 thunar_progress_dialog_info_message (ThunarProgressDialog       *dialog,
-                                                                 const gchar                *message,
-                                                                 gpointer                   *job);
-static void                 thunar_progress_dialog_percent      (ThunarProgressDialog       *dialog,
-                                                                 gdouble                     percent,
-                                                                 gpointer                   *job);
+static void              thunar_progress_dialog_class_init   (ThunarProgressDialogClass  *klass);
+static void              thunar_progress_dialog_init         (ThunarProgressDialog       *dialog);
+static void              thunar_progress_dialog_dispose      (GObject                    *object);
+static void              thunar_progress_dialog_get_property (GObject                    *object,
+                                                              guint                       prop_id,
+                                                              GValue                     *value,
+                                                              GParamSpec                 *pspec);
+static void              thunar_progress_dialog_set_property (GObject                    *object,
+                                                              guint                       prop_id,
+                                                              const GValue               *value,
+                                                              GParamSpec                 *pspec);
+static void              thunar_progress_dialog_response     (GtkDialog                  *dialog,
+                                                              gint                        response);
+static ThunarJobResponse thunar_progress_dialog_ask          (ThunarProgressDialog       *dialog,
+                                                              const gchar                *message,
+                                                              ThunarJobResponse           choices,
+                                                              gpointer                   *job);
+static ThunarJobResponse thunar_progress_dialog_ask_replace  (ThunarProgressDialog       *dialog,
+                                                              ThunarFile                 *src_file,
+                                                              ThunarFile                 *dst_file,
+                                                              gpointer                   *job);
+static void              thunar_progress_dialog_error        (ThunarProgressDialog       *dialog,
+                                                              GError                     *error,
+                                                              gpointer                   *job);
+static void              thunar_progress_dialog_finished     (ThunarProgressDialog       *dialog,
+                                                              gpointer                   *job);
+static void              thunar_progress_dialog_info_message (ThunarProgressDialog       *dialog,
+                                                              const gchar                *message,
+                                                              gpointer                   *job);
+static void              thunar_progress_dialog_percent      (ThunarProgressDialog       *dialog,
+                                                              gdouble                     percent,
+                                                              gpointer                   *job);
 
 
 
@@ -289,21 +289,23 @@
 
 
 
-static ThunarVfsJobResponse
+static ThunarJobResponse
 thunar_progress_dialog_ask_replace (ThunarProgressDialog *dialog,
-                                    ThunarVfsInfo        *src_info,
-                                    ThunarVfsInfo        *dst_info,
-                                    ThunarVfsJob         *job)
+                                    ThunarFile           *src_file,
+                                    ThunarFile           *dst_file,
+                                    gpointer             *job)
 {
-  _thunar_return_val_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog), THUNAR_VFS_JOB_RESPONSE_CANCEL);
-  _thunar_return_val_if_fail (THUNAR_VFS_IS_JOB (job), THUNAR_VFS_JOB_RESPONSE_CANCEL);
-  _thunar_return_val_if_fail (dialog->job == job, THUNAR_VFS_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (THUNAR_IS_PROGRESS_DIALOG (dialog), THUNAR_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (dialog->job == job, THUNAR_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (THUNAR_IS_FILE (src_file), THUNAR_JOB_RESPONSE_CANCEL);
+  _thunar_return_val_if_fail (THUNAR_IS_FILE (dst_file), THUNAR_JOB_RESPONSE_CANCEL);
 
   /* be sure to display the progress dialog prior to opening the question dialog */
   gtk_widget_show_now (GTK_WIDGET (dialog));
 
   /* display the question dialog */
-  return thunar_dialogs_show_job_ask_replace (GTK_WINDOW (dialog), src_info, dst_info);
+  return thunar_dialogs_show_job_ask_replace (GTK_WINDOW (dialog), src_file, dst_file);
 }
 
 
@@ -540,8 +542,7 @@
       g_object_ref (job);
 
       g_signal_connect_swapped (job, "ask", G_CALLBACK (thunar_progress_dialog_ask), dialog);
-      if (THUNAR_VFS_IS_JOB (job))
-        g_signal_connect_swapped (job, "ask-replace", G_CALLBACK (thunar_progress_dialog_ask_replace), dialog);
+      g_signal_connect_swapped (job, "ask-replace", G_CALLBACK (thunar_progress_dialog_ask_replace), dialog);
       g_signal_connect_swapped (job, "error", G_CALLBACK (thunar_progress_dialog_error), dialog);
       g_signal_connect_swapped (job, "finished", G_CALLBACK (thunar_progress_dialog_finished), dialog);
       g_signal_connect_swapped (job, "info-message", G_CALLBACK (thunar_progress_dialog_info_message), dialog);

Modified: thunar/branches/migration-to-gio/thunar/thunar-shortcuts-view.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-shortcuts-view.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-shortcuts-view.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -152,7 +152,7 @@
   /* drop site support */
   guint  drop_data_ready : 1; /* whether the drop data was received already */
   guint  drop_occurred : 1;
-  GList *drop_path_list;      /* the list of URIs that are contained in the drop data */
+  GList *drop_file_list;      /* the list of URIs that are contained in the drop data */
 
 #if GTK_CHECK_VERSION(2,8,0)
   /* id of the signal used to queue a resize on the
@@ -335,7 +335,7 @@
   ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (object);
 
   /* release drop path list (if drag_leave wasn't called) */
-  thunar_vfs_path_list_free (view->drop_path_list);
+  g_file_list_free (view->drop_file_list);
 
   /* release the provider factory */
   g_object_unref (G_OBJECT (view->provider_factory));
@@ -474,7 +474,7 @@
     {
       /* extract the URI list from the selection data (if valid) */
       if (info == TEXT_URI_LIST && selection_data->format == 8 && selection_data->length > 0)
-        view->drop_path_list = thunar_vfs_path_list_from_string ((const gchar *) selection_data->data, NULL);
+        view->drop_file_list = g_file_list_new_from_string ((const gchar *) selection_data->data);
 
       /* reset the state */
       view->drop_data_ready = TRUE;
@@ -503,7 +503,7 @@
                     gtk_tree_path_next (path);
 
                   /* just add the required shortcuts then */
-                  thunar_shortcuts_view_drop_uri_list (view, view->drop_path_list, path);
+                  thunar_shortcuts_view_drop_uri_list (view, view->drop_file_list, path);
                 }
               else if (G_LIKELY ((actions & (GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK)) != 0))
                 {
@@ -519,13 +519,13 @@
                         {
                           /* ask the user what to do with the drop data */
                           if (G_UNLIKELY (action == GDK_ACTION_ASK))
-                            action = thunar_dnd_ask (widget, file, view->drop_path_list, time, actions);
+                            action = thunar_dnd_ask (widget, file, view->drop_file_list, time, actions);
 
                           /* perform the requested action */
                           if (G_LIKELY (action != 0))
                             {
                               /* really perform the drop :-) */
-                              succeed = thunar_dnd_perform (widget, file, view->drop_path_list, action, NULL);
+                              succeed = thunar_dnd_perform (widget, file, view->drop_file_list, action, NULL);
                             }
 
                           /* release the file */
@@ -720,9 +720,9 @@
   /* reset the "drop data ready" status and free the URI list */
   if (G_LIKELY (view->drop_data_ready))
     {
-      thunar_vfs_path_list_free (view->drop_path_list);
+      g_file_list_free (view->drop_file_list);
       view->drop_data_ready = FALSE;
-      view->drop_path_list = NULL;
+      view->drop_file_list = NULL;
     }
 
   /* schedule a repaint to make sure the special drop icon for the target row
@@ -1077,7 +1077,7 @@
           if (G_LIKELY (file != NULL))
             {
               /* check if the file accepts the drop */
-              actions = thunar_file_accepts_drop (file, view->drop_path_list, context, action_return);
+              actions = thunar_file_accepts_drop (file, view->drop_file_list, context, action_return);
               if (G_LIKELY (actions != 0))
                 {
                   /* we can drop into this location */
@@ -1192,8 +1192,6 @@
   GtkTreePath  *path;
   ThunarFile   *file;
   GError       *error = NULL;
-  gchar        *display_string;
-  gchar        *uri_string;
   GList        *lp;
 
   /* take a copy of the destination path */
@@ -1203,26 +1201,22 @@
   model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
   for (lp = path_list; lp != NULL; lp = lp->next)
     {
-      file = thunar_file_get_for_path (lp->data, &error);
+      file = thunar_file_get (lp->data, &error);
       if (G_UNLIKELY (file == NULL))
         break;
 
       /* make sure, that only directories gets added to the shortcuts list */
       if (G_UNLIKELY (!thunar_file_is_directory (file)))
         {
-          uri_string = thunar_vfs_path_dup_string (lp->data);
-          display_string = g_filename_display_name (uri_string);
           g_set_error (&error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR,
                        _("The path \"%s\" does not refer to a directory"),
-                       display_string);
-          g_object_unref (G_OBJECT (file));
-          g_free (display_string);
-          g_free (uri_string);
+                       thunar_file_get_display_name (file));
+          g_object_unref (file);
           break;
         }
 
       thunar_shortcuts_model_add (THUNAR_SHORTCUTS_MODEL (model), path, file);
-      g_object_unref (G_OBJECT (file));
+      g_object_unref (file);
       gtk_tree_path_next (path);
     }
 

Modified: thunar/branches/migration-to-gio/thunar/thunar-standard-view.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-standard-view.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-standard-view.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -302,7 +302,7 @@
   guint                   drop_data_ready : 1; /* whether the drop data was received already */
   guint                   drop_highlight : 1;
   guint                   drop_occurred : 1;   /* whether the data was dropped */
-  GList                  *drop_path_list;      /* the list of URIs that are contained in the drop data */
+  GList                  *drop_file_list;      /* the list of URIs that are contained in the drop data */
 
   /* the "new-files" closure, which is used to select files whenever 
    * new files are created by a ThunarVfsJob associated with this view
@@ -767,7 +767,7 @@
   thunar_vfs_path_list_free (standard_view->priv->drag_path_list);
 
   /* release the drop path list (just in case the drag-leave wasn't fired before) */
-  thunar_vfs_path_list_free (standard_view->priv->drop_path_list);
+  g_file_list_free (standard_view->priv->drop_file_list);
 
   /* release the reference on the name renderer */
   g_object_unref (G_OBJECT (standard_view->name_renderer));
@@ -1549,7 +1549,7 @@
   if (G_LIKELY (file != NULL))
     {
       /* determine the possible drop actions for the file (and the suggested action if any) */
-      actions = thunar_file_accepts_drop (file, standard_view->priv->drop_path_list, context, &action);
+      actions = thunar_file_accepts_drop (file, standard_view->priv->drop_file_list, context, &action);
       if (G_LIKELY (actions != 0))
         {
           /* tell the caller about the file (if it's interested) */
@@ -2014,7 +2014,7 @@
   current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view));
   if (G_LIKELY (current_directory != NULL))
     {
-      thunar_clipboard_manager_paste_files (standard_view->clipboard, thunar_file_get_path (current_directory),
+      thunar_clipboard_manager_paste_files (standard_view->clipboard, thunar_file_get_file (current_directory),
                                             GTK_WIDGET (standard_view), thunar_standard_view_new_files_closure (standard_view));
     }
 }
@@ -2050,7 +2050,7 @@
   /* determine the first selected file and verify that it's a folder */
   file = g_list_nth_data (standard_view->selected_files, 0);
   if (G_LIKELY (file != NULL && thunar_file_is_directory (file)))
-    thunar_clipboard_manager_paste_files (standard_view->clipboard, thunar_file_get_path (file), GTK_WIDGET (standard_view), NULL);
+    thunar_clipboard_manager_paste_files (standard_view->clipboard, thunar_file_get_file (file), GTK_WIDGET (standard_view), NULL);
 }
 
 
@@ -2138,7 +2138,7 @@
   ThunarApplication *application;
   ThunarFile        *current_directory;
   GClosure          *new_files_closure;
-  GList             *selected_paths;
+  GList             *selected_files;
 
   _thunar_return_if_fail (GTK_IS_ACTION (action));
   _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view));
@@ -2147,21 +2147,21 @@
   current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view));
   if (G_LIKELY (current_directory != NULL))
     {
-      /* determine the selected paths for the view */
-      selected_paths = thunar_file_list_to_path_list (standard_view->selected_files);
-      if (G_LIKELY (selected_paths != NULL))
+      /* determine the selected files for the view */
+      selected_files = thunar_file_list_to_g_file_list (standard_view->selected_files);
+      if (G_LIKELY (selected_files != NULL))
         {
           /* copy the selected files into the current directory, which effectively
            * creates duplicates of the files.
            */
           application = thunar_application_get ();
           new_files_closure = thunar_standard_view_new_files_closure (standard_view);
-          thunar_application_copy_into (application, GTK_WIDGET (standard_view), selected_paths,
-                                        thunar_file_get_path (current_directory), new_files_closure);
+          thunar_application_copy_into (application, GTK_WIDGET (standard_view), selected_files,
+                                        thunar_file_get_file (current_directory), new_files_closure);
           g_object_unref (G_OBJECT (application));
 
           /* clean up */
-          thunar_vfs_path_list_free (selected_paths);
+          g_file_list_free (selected_files);
         }
     }
 }
@@ -2623,7 +2623,7 @@
     {
       /* extract the URI list from the selection data (if valid) */
       if (info == TARGET_TEXT_URI_LIST && selection_data->format == 8 && selection_data->length > 0)
-        standard_view->priv->drop_path_list = thunar_vfs_path_list_from_string ((gchar *) selection_data->data, NULL);
+        standard_view->priv->drop_file_list = g_file_list_new_from_string ((gchar *) selection_data->data);
 
       /* reset the state */
       standard_view->priv->drop_data_ready = TRUE;
@@ -2745,13 +2745,13 @@
             {
               /* ask the user what to do with the drop data */
               action = (context->action == GDK_ACTION_ASK)
-                     ? thunar_dnd_ask (GTK_WIDGET (standard_view), file, standard_view->priv->drop_path_list, time, actions)
+                     ? thunar_dnd_ask (GTK_WIDGET (standard_view), file, standard_view->priv->drop_file_list, time, actions)
                      : context->action;
 
               /* perform the requested action */
               if (G_LIKELY (action != 0))
                 {
-                  succeed = thunar_dnd_perform (GTK_WIDGET (standard_view), file, standard_view->priv->drop_path_list,
+                  succeed = thunar_dnd_perform (GTK_WIDGET (standard_view), file, standard_view->priv->drop_file_list,
                                                 action, thunar_standard_view_new_files_closure (standard_view));
                 }
             }
@@ -2794,8 +2794,8 @@
   /* reset the "drop data ready" status and free the URI list */
   if (G_LIKELY (standard_view->priv->drop_data_ready))
     {
-      thunar_vfs_path_list_free (standard_view->priv->drop_path_list);
-      standard_view->priv->drop_path_list = NULL;
+      g_file_list_free (standard_view->priv->drop_file_list);
+      standard_view->priv->drop_file_list = NULL;
       standard_view->priv->drop_data_ready = FALSE;
     }
 

Added: thunar/branches/migration-to-gio/thunar/thunar-transfer-job.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-transfer-job.c	                        (rev 0)
+++ thunar/branches/migration-to-gio/thunar/thunar-transfer-job.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -0,0 +1,633 @@
+/* vi:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2005-2007 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU General Public License as published by 
+ * the Free Software Foundation; either version 2 of the License, or (at 
+ * your option) any later version.
+ *
+ * This program 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 
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ * MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gio/gio.h>
+
+#include <thunar/thunar-io-scan-directory.h>
+#include <thunar/thunar-job.h>
+#include <thunar/thunar-private.h>
+#include <thunar/thunar-transfer-job.h>
+
+
+
+typedef struct _ThunarTransferNode ThunarTransferNode;
+
+
+
+static void     thunar_transfer_job_class_init   (ThunarTransferJobClass *klass);
+static void     thunar_transfer_job_init         (ThunarTransferJob      *job);
+static void     thunar_transfer_job_finalize     (GObject                *object);
+static gboolean thunar_transfer_job_execute      (ThunarJob              *job,
+                                                  GError                **error);
+static void     thunar_transfer_node_free        (ThunarTransferNode     *node);
+
+
+
+struct _ThunarTransferJobClass
+{
+  ThunarJobClass __parent__;
+};
+
+struct _ThunarTransferJob
+{
+  ThunarJob             __parent__;
+
+  ThunarTransferJobType type;
+  GList                *source_node_list;
+  GList                *target_file_list;
+
+  guint64               total_size;
+};
+
+struct _ThunarTransferNode
+{
+  ThunarTransferNode *next;
+  ThunarTransferNode *children;
+  GFile              *source_file;
+};
+
+
+
+static GObjectClass *thunar_transfer_job_parent_class = NULL;
+
+
+
+GType
+thunar_transfer_job_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (THUNAR_TYPE_JOB, 
+                                            "ThunarTransferJob",
+                                            sizeof (ThunarTransferJobClass),
+                                            (GClassInitFunc) thunar_transfer_job_class_init,
+                                            sizeof (ThunarTransferJob),
+                                            (GInstanceInitFunc) thunar_transfer_job_init,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+thunar_transfer_job_class_init (ThunarTransferJobClass *klass)
+{
+  ThunarJobClass *thunarjob_class;
+  GObjectClass   *gobject_class;
+
+  /* Determine the parent type class */
+  thunar_transfer_job_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = thunar_transfer_job_finalize; 
+
+  thunarjob_class = THUNAR_JOB_CLASS (klass);
+  thunarjob_class->execute = thunar_transfer_job_execute;
+}
+
+
+
+static void
+thunar_transfer_job_init (ThunarTransferJob *job)
+{
+  job->type = 0;
+  job->source_node_list = NULL;
+  job->target_file_list = NULL;
+  job->total_size = 0;
+}
+
+
+
+static void
+thunar_transfer_job_finalize (GObject *object)
+{
+  ThunarTransferJob *job = THUNAR_TRANSFER_JOB (object);
+
+  g_list_foreach (job->source_node_list, (GFunc) thunar_transfer_node_free, NULL);
+  g_list_free (job->source_node_list);
+
+  g_file_list_free (job->target_file_list);
+
+  (*G_OBJECT_CLASS (thunar_transfer_job_parent_class)->finalize) (object);
+}
+
+
+
+static void
+thunar_transfer_job_progress (goffset  current_num_bytes,
+                              goffset  total_num_bytes,
+                              gpointer user_data)
+{
+  ThunarTransferJob *job = user_data;
+
+  _thunar_return_if_fail (THUNAR_IS_TRANSFER_JOB (job));
+  
+  if (G_LIKELY (total_num_bytes > 0))
+    thunar_job_percent (THUNAR_JOB (job), (current_num_bytes * 100.0) / total_num_bytes);
+}
+
+
+
+static gboolean
+thunar_transfer_job_collect_node (ThunarTransferJob  *job,
+                                  ThunarTransferNode *node,
+                                  GError            **error)
+{
+  ThunarTransferNode *child_node;
+  GFileInfo          *info;
+  GError             *err = NULL;
+  GList              *file_list;
+  GList              *lp;
+
+  _thunar_return_val_if_fail (THUNAR_IS_TRANSFER_JOB (job), FALSE);
+  _thunar_return_val_if_fail (node != NULL && G_IS_FILE (node->source_file), FALSE);
+  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  if (thunar_job_set_error_if_cancelled (THUNAR_JOB (job), error))
+    return FALSE;
+
+  info = g_file_query_info (node->source_file, 
+                            G_FILE_ATTRIBUTE_STANDARD_SIZE ","
+                            G_FILE_ATTRIBUTE_STANDARD_TYPE,
+                            G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                            thunar_job_get_cancellable (THUNAR_JOB (job)),
+                            &err);
+
+  if (G_UNLIKELY (info == NULL))
+    return FALSE;
+
+  job->total_size += g_file_info_get_size (info);
+
+  /* check if we have a directory here */
+  if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
+    {
+      /* scan the directory for immediate children */
+      file_list = thunar_io_scan_directory (THUNAR_JOB (job), node->source_file,
+                                            G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                            FALSE, &err);
+
+      /* add children to the transfer node */
+      for (lp = file_list; err == NULL && lp != NULL; lp = lp->next)
+        {
+          /* allocate a new transfer node for the child */
+          child_node = _thunar_slice_new0 (ThunarTransferNode);
+          child_node->source_file = g_object_ref (lp->data);
+
+          /* hook the child node into the child list */
+          child_node->next = node->children;
+          node->children = child_node;
+
+          /* collect the child node */
+          thunar_transfer_job_collect_node (job, child_node, &err);
+        }
+      
+      /* release the child files */
+      g_file_list_free (file_list);
+    }
+
+  /* release file info */
+  g_object_unref (info);
+
+  if (G_UNLIKELY (err != NULL))
+    {
+      g_propagate_error (error, err);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+
+
+static gboolean
+thunar_transfer_job_copy_file (ThunarTransferJob *job,
+                               GFile             *source_file,
+                               GFile             *target_file,
+                               GFile            **target_file_return,
+                               GError           **error)
+{
+  ThunarJobResponse response;
+  GFileCopyFlags    copy_flags = G_FILE_COPY_NOFOLLOW_SYMLINKS;
+  GError           *err = NULL;
+
+  _thunar_return_val_if_fail (THUNAR_IS_TRANSFER_JOB (job), FALSE);
+  _thunar_return_val_if_fail (G_IS_FILE (source_file), FALSE);
+  _thunar_return_val_if_fail (G_IS_FILE (target_file), FALSE);
+  _thunar_return_val_if_fail (target_file_return != NULL && *target_file_return == NULL, FALSE);
+  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  if (thunar_job_set_error_if_cancelled (THUNAR_JOB (job), error))
+    return FALSE;
+
+  /* various attempts to copy the file */
+  while (err == NULL)
+    {
+      /* try to copy the file from source_file to the target_file */
+      /* TODO generate duplicate names like 'copy of \"%s\"' if source and target file
+       * are equal */
+      if (g_file_copy (source_file, target_file, copy_flags, 
+                       thunar_job_get_cancellable (THUNAR_JOB (job)),
+                       thunar_transfer_job_progress, THUNAR_JOB (job), &err))
+        {
+          /* return the real target file */
+          *target_file_return = target_file;
+          return TRUE;
+        }
+
+      /* check if we can recover from this error */
+      if (err->domain == G_IO_ERROR && err->code == G_IO_ERROR_EXISTS)
+        {
+          /* reset the error */
+          g_clear_error (&err);
+
+          /* ask the user whether to replace the target file */
+          response = thunar_job_ask_replace (THUNAR_JOB (job), source_file, target_file, &err);
+
+          if (err != NULL)
+            break;
+
+          /* check if we should retry */
+          if (response == THUNAR_JOB_RESPONSE_RETRY)
+            continue;
+
+          /* add overwrite flag and try again if we should overwrite */
+          if (response == THUNAR_JOB_RESPONSE_YES)
+            {
+              copy_flags |= G_FILE_COPY_OVERWRITE;
+              continue;
+            }
+
+          /* check if the file should not be overwritten */
+          if (response == THUNAR_JOB_RESPONSE_NO)
+            {
+              /* tell the caller that we skipped this one */
+              *target_file_return = NULL;
+              return TRUE;
+            }
+        }
+    }
+
+  g_propagate_error (error, err);
+
+  return FALSE;
+}
+
+
+
+static void
+thunar_transfer_job_copy_node (ThunarTransferJob  *job,
+                               ThunarTransferNode *node,
+                               GFile              *target_file,
+                               GFile              *target_parent_file,
+                               GList             **target_file_list_return,
+                               GError            **error)
+{
+  ThunarJobResponse response;
+  GFileInfo        *info;
+  GError           *err = NULL;
+  GFile            *target_file_return = NULL;
+  gchar            *basename;
+
+  _thunar_return_if_fail (THUNAR_IS_TRANSFER_JOB (job));
+  _thunar_return_if_fail (node != NULL && G_IS_FILE (node->source_file));
+  _thunar_return_if_fail (target_file == NULL || node->next == NULL);
+  _thunar_return_if_fail ((target_file == NULL && target_parent_file != NULL) || (target_file != NULL && target_parent_file == NULL));
+  _thunar_return_if_fail (error == NULL || *error == NULL);
+
+  /* The caller can either provide a target_file or a target_parent_file, but not both. The toplevel
+   * transfer_nodes (for which next is NULL) should be called with target_file, to get proper behavior
+   * wrt restoring files from the trash. Other transfer_nodes will be called with target_parent_file.
+   */
+
+  for (; err == NULL && node != NULL; node = node->next)
+    {
+      /* guess the target file for this node (unless already provided) */
+      if (G_LIKELY (target_file == NULL))
+        {
+          basename = g_file_get_basename (node->source_file);
+          target_file = g_file_get_child (target_parent_file, basename);
+          g_free (basename);
+        }
+      else
+        target_file = g_object_ref (target_file);
+
+      /* query file info */
+      info = g_file_query_info (node->source_file,
+                                G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                thunar_job_get_cancellable (THUNAR_JOB (job)),
+                                &err);
+
+      /* abort on error or cancellation */
+      if (info == NULL)
+        {
+          g_object_unref (target_file);
+          break;
+        }
+
+      /* update progress information */
+      thunar_job_info_message (THUNAR_JOB (job), g_file_info_get_display_name (info));
+
+retry_copy:
+      target_file_return = NULL;
+
+      /* copy the item specified by this node (not recursively) */
+      if (thunar_transfer_job_copy_file (job, node->source_file, target_file, &target_file_return, &err))
+        {
+          /* target file return == NULL means to skip the file */
+          if (G_LIKELY (target_file_return != NULL))
+            {
+              /* check if we have children to copy */
+              if (node->children != NULL)
+                {
+                  /* copy all children of this node */
+                  thunar_transfer_job_copy_node (job, node->children, NULL, target_file_return, NULL, &err);
+
+                  /* free resources allocted for the children */
+                  thunar_transfer_node_free (node->children);
+                  node->children = NULL;
+                }
+
+              /* check if the child copy failed */
+              if (G_UNLIKELY (err != NULL))
+                {
+                  /* outa here, freeing the target paths */
+                  g_object_unref (target_file_return);
+                  g_object_unref (target_file);
+                  break;
+                }
+
+              /* add the real target file to the return list */
+              if (G_LIKELY (target_file_list_return != NULL))
+                *target_file_list_return = g_list_prepend (*target_file_list_return, target_file_return);
+              else
+                g_object_unref (target_file_return);
+
+retry_remove:
+              /* try to remove the source directory if we are on copy+remove fallback for move */
+              if (job->type == THUNAR_TRANSFER_JOB_MOVE && 
+                  !g_file_delete (node->source_file, thunar_job_get_cancellable (THUNAR_JOB (job)), &err))
+                {
+                  /* ask the user to retry */
+                  response = thunar_job_ask_skip (THUNAR_JOB (job), "%s", err->message);
+
+                  /* reset the error */
+                  g_clear_error (&err);
+
+                  /* check whether to retry */
+                  if (G_UNLIKELY (response == THUNAR_JOB_RESPONSE_RETRY))
+                    goto retry_remove;
+                }
+            }
+        }
+      else if (err != NULL)
+        { 
+          /* we can only skip if there is space left on the device */
+          if (err->domain != G_IO_ERROR || err->code != G_IO_ERROR_NO_SPACE) 
+            {
+              /* ask the user to skip this node and all subnodes */
+              response = thunar_job_ask_skip (THUNAR_JOB (job), "%s", err->message);
+
+              /* reset the error */
+              g_clear_error (&err);
+
+              /* check whether to retry */
+              if (G_UNLIKELY (response == THUNAR_JOB_RESPONSE_RETRY))
+                goto retry_copy;
+            }
+        }
+
+      /* release the guessed target file */
+      g_object_unref (target_file);
+      target_file = NULL;
+
+      /* release file info */
+      g_object_unref (info);
+    }
+
+  /* propagate error if we failed or the job was cancelled */
+  if (G_UNLIKELY (err != NULL))
+    g_propagate_error (error, err);
+
+  return;
+}
+
+
+static gboolean
+thunar_transfer_job_execute (ThunarJob *job,
+                             GError   **error)
+{
+  ThunarTransferNode *node;
+  ThunarTransferJob  *transfer_job = THUNAR_TRANSFER_JOB (job);
+  GFileInfo          *info;
+  GError             *err = NULL;
+  GList              *new_files_list = NULL;
+  GList              *snext;
+  GList              *sp;
+  GList              *tnext;
+  GList              *tp;
+  gchar              *message;
+
+  _thunar_return_val_if_fail (THUNAR_IS_TRANSFER_JOB (job), FALSE);
+  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  if (thunar_job_set_error_if_cancelled (job, error))
+    return FALSE;
+
+  thunar_job_info_message (job, _("Collecting files..."));
+
+  for (sp = transfer_job->source_node_list, tp = transfer_job->target_file_list;
+       sp != NULL && tp != NULL && err == NULL;
+       sp = snext, tp = tnext)
+    {
+      /* determine the next list items */
+      snext = sp->next;
+      tnext = tp->next;
+
+      /* determine the current source transfer node */
+      node = sp->data;
+
+      info = g_file_query_info (node->source_file,
+                                G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                thunar_job_get_cancellable (job),
+                                &err);
+
+      if (G_UNLIKELY (info == NULL))
+        break;
+
+      if (transfer_job->type == THUNAR_TRANSFER_JOB_MOVE)
+        {
+          message = g_strdup_printf (_("Trying to move \"%s\""),
+                                     g_file_info_get_display_name (info));
+          thunar_job_info_message (job, message);
+          g_free (message);
+
+          if (g_file_move (node->source_file, tp->data, 
+                           G_FILE_COPY_NOFOLLOW_SYMLINKS 
+                           | G_FILE_COPY_NO_FALLBACK_FOR_MOVE,
+                           thunar_job_get_cancellable (job),
+                           thunar_transfer_job_progress,
+                           job, &err))
+            {
+              /* add the target file to the new files list */
+              new_files_list = g_file_list_prepend (new_files_list, tp->data);
+
+              /* release source and target files */
+              thunar_transfer_node_free (node);
+              g_object_unref (tp->data);
+
+              /* drop the matching list items */
+              transfer_job->source_node_list = g_list_delete_link (transfer_job->source_node_list, sp);
+              transfer_job->target_file_list = g_list_delete_link (transfer_job->target_file_list, tp);
+            }
+          else if (!thunar_job_is_cancelled (job))
+            {
+              g_clear_error (&err);
+
+              message = g_strdup_printf (_("Could not move \"%s\" directly. "
+                                           "Collecting files for copying..."), 
+                                         g_file_info_get_display_name (info));
+              thunar_job_info_message (job, message);
+              g_free (message);
+
+              if (!thunar_transfer_job_collect_node (transfer_job, node, &err))
+                {
+                  /* failed to collect, cannot continue */
+                  g_object_unref (info);
+                  break;
+                }
+            }
+        }
+
+      g_object_unref (info);
+    }
+
+  /* continue if there were no errors yet */
+  if (G_LIKELY (err == NULL))
+    {
+      /* perform the copy recursively for all source transfer nodes */
+      for (sp = transfer_job->source_node_list, tp = transfer_job->target_file_list;
+           sp != NULL && tp != NULL && err == NULL;
+           sp = sp->next, tp = tp->next)
+        {
+          thunar_transfer_job_copy_node (transfer_job, sp->data, tp->data, NULL, 
+                                         &new_files_list, &err);
+        }
+    }
+
+  /* check if we failed */
+  if (G_UNLIKELY (err != NULL))
+    {
+      g_propagate_error (error, err);
+      return FALSE;
+    }
+  else
+    {
+      /* TODO 
+      thunar_job_new_files (job, new_files_list);
+      g_file_list_free (new_files_list);
+      */
+      return TRUE;
+    }
+}
+
+
+
+static void
+thunar_transfer_node_free (ThunarTransferNode *node)
+{
+  ThunarTransferNode *next;
+
+  /* free all nodes in a row */
+  while (node != NULL)
+    {
+      /* free all children of this node */
+      thunar_transfer_node_free (node->children);
+
+      /* determine the next node */
+      next = node->next;
+
+      /* drop the source file of this node */
+      g_object_unref (node->source_file);
+
+      /* release the resources of this node */
+      _thunar_slice_free (ThunarTransferNode, node);
+
+      /* continue with the next node */
+      node = next;
+    }
+}
+
+
+
+ThunarJob *
+thunar_transfer_job_new (GList                *source_node_list,
+                         GList                *target_file_list,
+                         ThunarTransferJobType type)
+{
+  ThunarTransferNode *node;
+  ThunarTransferJob  *job;
+  GList              *sp;
+  GList              *tp;
+
+  _thunar_return_val_if_fail (source_node_list != NULL, NULL);
+  _thunar_return_val_if_fail (target_file_list != NULL, NULL);
+  _thunar_return_val_if_fail (g_list_length (source_node_list) == g_list_length (target_file_list), NULL);
+
+  job = g_object_new (THUNAR_TYPE_TRANSFER_JOB, NULL);
+  job->type = type;
+
+  /* add a transfer node for each source path and a matching target parent path */
+  for (sp = source_node_list, tp = target_file_list; 
+       sp != NULL; 
+       sp = sp->next, tp = tp->next)
+    {
+      /* make sure we don't transfer root directories. this should be prevented in the GUI */
+      if (G_UNLIKELY (g_file_is_root (sp->data) || g_file_is_root (tp->data)))
+        continue;
+
+      /* only process non-equal pairs unless we're copying */
+      if (G_LIKELY (type != THUNAR_TRANSFER_JOB_MOVE || !g_file_equal (sp->data, tp->data)))
+        {
+          /* append transfer node for this source file */
+          node = _thunar_slice_new0 (ThunarTransferNode);
+          node->source_file = g_object_ref (sp->data);
+          job->source_node_list = g_list_append (job->source_node_list, node);
+
+          /* append target file */
+          job->target_file_list = g_file_list_append (job->target_file_list, tp->data);
+        }
+    }
+
+  /* make sure we didn't mess things up */
+  _thunar_assert (g_list_length (job->source_node_list) == g_list_length (job->target_file_list));
+
+  return THUNAR_JOB (job);
+}

Added: thunar/branches/migration-to-gio/thunar/thunar-transfer-job.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-transfer-job.h	                        (rev 0)
+++ thunar/branches/migration-to-gio/thunar/thunar-transfer-job.h	2009-04-23 00:56:37 UTC (rev 29891)
@@ -0,0 +1,59 @@
+/* vi:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>.
+ *
+ * This program is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU General Public License as published by 
+ * the Free Software Foundation; either version 2 of the License, or (at 
+ * your option) any later version.
+ *
+ * This program 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 
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ * MA  02111-1307  USA
+ */
+
+#ifndef __THUNAR_TRANSFER_JOB_H__
+#define __THUNAR_TRANSFER_JOB_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ * ThunarTransferJobFlags:
+ *
+ * Flags to control the behavior of the transfer job.
+ **/
+typedef enum /*< enum >*/
+{
+  THUNAR_TRANSFER_JOB_COPY,
+  THUNAR_TRANSFER_JOB_MOVE,
+  THUNAR_TRANSFER_JOB_TRASH,
+} ThunarTransferJobType;
+
+typedef struct _ThunarTransferJobPrivate ThunarTransferJobPrivate;
+typedef struct _ThunarTransferJobClass   ThunarTransferJobClass;
+typedef struct _ThunarTransferJob        ThunarTransferJob;
+
+#define THUNAR_TYPE_TRANSFER_JOB            (thunar_transfer_job_get_type ())
+#define THUNAR_TRANSFER_JOB(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_TRANSFER_JOB, ThunarTransferJob))
+#define THUNAR_TRANSFER_JOB_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_TRANSFER_JOB, ThunarTransferJobClass))
+#define THUNAR_IS_TRANSFER_JOB(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_TRANSFER_JOB))
+#define THUNAR_IS_TRANSFER_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_TRANSFER_JOB)
+#define THUNAR_TRANSFER_JOB_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_TRANSFER_JOB, ThunarTransferJobClass))
+
+GType      thunar_transfer_job_get_type (void) G_GNUC_CONST;
+
+ThunarJob *thunar_transfer_job_new      (GList                *source_file_list,
+                                         GList                *target_file_list,
+                                         ThunarTransferJobType type) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+G_END_DECLS
+
+#endif /* !__THUNAR_TRANSFER_JOB_H__ */

Modified: thunar/branches/migration-to-gio/thunar/thunar-tree-view.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-tree-view.c	2009-04-22 21:25:56 UTC (rev 29890)
+++ thunar/branches/migration-to-gio/thunar/thunar-tree-view.c	2009-04-23 00:56:37 UTC (rev 29891)
@@ -196,7 +196,7 @@
   /* drop site support */
   guint                   drop_data_ready : 1; /* whether the drop data was received already */
   guint                   drop_occurred : 1;
-  GList                  *drop_path_list;      /* the list of URIs that are contained in the drop data */
+  GList                  *drop_file_list;      /* the list of URIs that are contained in the drop data */
 
   /* the "new-files" closure, which is used to
    * open newly created directories once done.
@@ -449,7 +449,7 @@
   ThunarTreeView *view = THUNAR_TREE_VIEW (object);
 
   /* release drop path list (if drag_leave wasn't called) */
-  thunar_vfs_path_list_free (view->drop_path_list);
+  g_file_list_free (view->drop_file_list);
 
   /* release the provider factory */
   g_object_unref (G_OBJECT (view->provider_factory));
@@ -744,7 +744,7 @@
     {
       /* extract the URI list from the selection data (if valid) */
       if (info == TARGET_TEXT_URI_LIST && selection_data->format == 8 && selection_data->length > 0)
-        view->drop_path_list = thunar_vfs_path_list_from_string ((const gchar *) selection_data->data, NULL);
+        view->drop_file_list = g_file_list_new_from_string ((const gchar *) selection_data->data);
 
       /* reset the state */
       view->drop_data_ready = TRUE;
@@ -762,12 +762,12 @@
         {
           /* ask the user what to do with the drop data */
           action = (context->action == GDK_ACTION_ASK)
-                 ? thunar_dnd_ask (GTK_WIDGET (view), file, view->drop_path_list, time, actions)
+                 ? thunar_dnd_ask (GTK_WIDGET (view), file, view->drop_file_list, time, actions)
                  : context->action;
 
           /* perform the requested action */
           if (G_LIKELY (action != 0))
-            succeed = thunar_dnd_perform (GTK_WIDGET (view), file, view->drop_path_list, action, NULL);
+            succeed = thunar_dnd_perform (GTK_WIDGET (view), file, view->drop_file_list, action, NULL);
         }
 
       /* release the file reference */
@@ -886,9 +886,9 @@
   /* reset the "drop data ready" status and free the URI list */
   if (G_LIKELY (view->drop_data_ready))
     {
-      thunar_vfs_path_list_free (view->drop_path_list);
+      g_file_list_free (view->drop_file_list);
       view->drop_data_ready = FALSE;
-      view->drop_path_list = NULL;
+      view->drop_file_list = NULL;
     }
 
   /* call the parent's handler */
@@ -1341,7 +1341,7 @@
           if (G_LIKELY (file != NULL))
             {
               /* check if the file accepts the drop */
-              actions = thunar_file_accepts_drop (file, view->drop_path_list, context, &action);
+              actions = thunar_file_accepts_drop (file, view->drop_file_list, context, &action);
               if (G_UNLIKELY (actions == 0))
                 {
                   /* reset file */
@@ -1801,7 +1801,7 @@
   if (G_LIKELY (file != NULL))
     {
       /* paste the files from the clipboard to the selected folder */
-      thunar_clipboard_manager_paste_files (view->clipboard, thunar_file_get_path (file), GTK_WIDGET (view), NULL);
+      thunar_clipboard_manager_paste_files (view->clipboard, thunar_file_get_file (file), GTK_WIDGET (view), NULL);
 
       /* release the file reference */
       g_object_unref (G_OBJECT (file));




More information about the Xfce4-commits mailing list