Index: src/file-transfer-dialog.c
===================================================================
--- src/file-transfer-dialog.c	(revision 1350)
+++ src/file-transfer-dialog.c	(working copy)
@@ -1,493 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/* file-transfer-dialog.c
- * Copyright (C) 2002 Ximian, Inc.
- *
- * Written by Rachel Hestilow <hestilow@ximian.com> 
- *
- * 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, 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 <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs-async-ops.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
-#include <limits.h>
-
-#include "file-transfer-dialog.h"
-
-enum
-{
-	PROP_0,
-	PROP_FROM_URI,
-	PROP_TO_URI,
-	PROP_FRACTION_COMPLETE,
-	PROP_NTH_URI,
-	PROP_TOTAL_URIS
-};
-
-enum
-{
-	CANCEL,
-	DONE,
-	LAST_SIGNAL
-};
-
-guint file_transfer_dialog_signals[LAST_SIGNAL] = {0, };
-
-struct _FileTransferDialogPrivate
-{
-	GtkWidget *progress; 
-	GtkWidget *status;
-	GtkWidget *current;
-	GtkWidget *from;
-	GtkWidget *to;
-	guint nth;
-	guint total;
-	GnomeVFSAsyncHandle *handle;
-};
-
-static GObjectClass *parent_class;
-
-static void
-file_transfer_dialog_cancel (FileTransferDialog *dlg)
-{
-	if (dlg->priv->handle)
-	{
-		gnome_vfs_async_cancel (dlg->priv->handle);
-		dlg->priv->handle = NULL;
-	}
-}
-
-static void
-file_transfer_dialog_finalize (GObject *obj)
-{
-	FileTransferDialog *dlg = FILE_TRANSFER_DIALOG (obj);
-		
-	g_free (dlg->priv);
-
-	if (parent_class->finalize)
-		parent_class->finalize (G_OBJECT (dlg));
-}
-
-static void
-file_transfer_dialog_update_num_files (FileTransferDialog *dlg)
-{
-	gchar *str = g_strdup_printf (_("Copying file: %u of %u"),
-				      dlg->priv->nth, dlg->priv->total);
-	gtk_progress_bar_set_text (GTK_PROGRESS_BAR (dlg->priv->progress), str);
-	g_free (str);
-}
-
-static void
-file_transfer_dialog_response (GtkDialog *dlg, gint response_id)
-{
-	g_signal_emit (G_OBJECT (dlg),
-		       file_transfer_dialog_signals[CANCEL], 0, NULL); 
-}
-
-static void
-file_transfer_dialog_set_prop (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
-	FileTransferDialog *dlg = FILE_TRANSFER_DIALOG (object);
-	gchar *str;
-	gchar *str2;
-	gchar *base;
-	gchar *escaped;
-
-	switch (prop_id)
-	{
-	case PROP_FROM_URI:
-		base = g_path_get_basename (g_value_get_string (value));
-		escaped = gnome_vfs_unescape_string_for_display (base);
-
-		str = g_strdup_printf (_("Copying '%s'"), escaped);
-		str2 = g_strdup_printf ("<i>%s</i>", str);
-		gtk_label_set_markup (GTK_LABEL (dlg->priv->current),
-				      str2);
-		g_free (base);
-		g_free (escaped);
-		g_free (str);
-		g_free (str2);
-
-		base = g_path_get_dirname (g_value_get_string (value));
-		escaped = gnome_vfs_format_uri_for_display (base);
-
-		gtk_label_set_text (GTK_LABEL (dlg->priv->from),
-				    escaped);
-		g_free (base);
-		g_free (escaped);
-		break;
-	case PROP_TO_URI:
-		base = g_path_get_dirname (g_value_get_string (value));
-		escaped = gnome_vfs_format_uri_for_display (base);
-
-		gtk_label_set_text (GTK_LABEL (dlg->priv->to),
-				    escaped);
-		g_free (base);
-		g_free (escaped);
-		break;
-	case PROP_FRACTION_COMPLETE:
-		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (dlg->priv->progress), g_value_get_double (value));
-		break;
-	case PROP_NTH_URI:
-		dlg->priv->nth = g_value_get_uint (value);
-		file_transfer_dialog_update_num_files (dlg);
-		break;
-	case PROP_TOTAL_URIS:
-		dlg->priv->total = g_value_get_uint (value);
-		file_transfer_dialog_update_num_files (dlg);
-		break;
-	}
-}
-	
-static void
-file_transfer_dialog_get_prop (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
-	FileTransferDialog *dlg = FILE_TRANSFER_DIALOG (object);
-	
-	switch (prop_id)
-	{
-	case PROP_NTH_URI:
-		g_value_set_uint (value, dlg->priv->nth);
-		break;
-	case PROP_TOTAL_URIS:
-		g_value_set_uint (value, dlg->priv->total);
-		break;
-	}
-}
-
-static void
-file_transfer_dialog_class_init (FileTransferDialogClass *klass)
-{
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	
-	klass->cancel = file_transfer_dialog_cancel;
-	object_class->finalize = file_transfer_dialog_finalize;
-	object_class->get_property = file_transfer_dialog_get_prop;
-	object_class->set_property = file_transfer_dialog_set_prop;
-
-	GTK_DIALOG_CLASS (klass)->response = file_transfer_dialog_response;
-
-	g_object_class_install_property
-		(object_class, PROP_FROM_URI,
-		 g_param_spec_string ("from_uri",
-				      _("From URI"),
-				      _("URI currently transferring from"),
-				      NULL,
-				      G_PARAM_READWRITE));
-	
-	g_object_class_install_property
-		(object_class, PROP_TO_URI,
-		 g_param_spec_string ("to_uri",
-				      _("To URI"),
-				      _("URI currently transferring to"),
-				      NULL,
-				      G_PARAM_WRITABLE));
-
-	g_object_class_install_property
-		(object_class, PROP_FRACTION_COMPLETE,
-		 g_param_spec_double ("fraction_complete",
-				      _("Fraction completed"),
-				      _("Fraction of transfer currently completed"),
-				      0, 1, 0,
-				      G_PARAM_WRITABLE));
-
-	g_object_class_install_property
-		(object_class, PROP_NTH_URI,
-		 g_param_spec_uint ("nth_uri",
-				    _("Current URI index"),
-				    _("Current URI index - starts from 1"),
-				    1, INT_MAX, 1,
-				    G_PARAM_READWRITE));
-
-	g_object_class_install_property
-		(object_class, PROP_TOTAL_URIS,
-		 g_param_spec_uint ("total_uris",
-				    _("Total URIs"),
-				    _("Total number of URIs"),
-				    1, INT_MAX, 1,
-				    G_PARAM_READWRITE));
-
-	file_transfer_dialog_signals[CANCEL] =
-		g_signal_new ("cancel",
-			      G_TYPE_FROM_CLASS (object_class),
-			      G_SIGNAL_RUN_FIRST,
-			      G_STRUCT_OFFSET (FileTransferDialogClass, cancel),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__VOID,
-			      G_TYPE_NONE, 0);
-
-	file_transfer_dialog_signals[DONE] =
-		g_signal_new ("done",
-			      G_TYPE_FROM_CLASS (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (FileTransferDialogClass, done),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__VOID,
-			      G_TYPE_NONE, 0);
-
-	parent_class = 
-		G_OBJECT_CLASS (g_type_class_ref (GTK_TYPE_DIALOG));
-}
-
-/**
- * eel_gtk_label_make_bold.
- *
- * Switches the font of label to a bold equivalent.
- * @label: The label.
- **/
-static void
-eel_gtk_label_make_bold (GtkLabel *label)
-{
-	PangoFontDescription *font_desc;
-
-	font_desc = pango_font_description_new ();
-
-	pango_font_description_set_weight (font_desc,
-					   PANGO_WEIGHT_BOLD);
-
-	/* This will only affect the weight of the font, the rest is
-	 * from the current state of the widget, which comes from the
-	 * theme or user prefs, since the font desc only has the
-	 * weight flag turned on.
-	 */
-	gtk_widget_modify_font (GTK_WIDGET (label), font_desc);
-
-	pango_font_description_free (font_desc);
-}
-
-/* from nautilus */
-static void
-create_titled_label (GtkTable   *table,
-		     int         row,
-		     GtkWidget **title_widget,
-		     GtkWidget **label_text_widget)
-{
-	*title_widget = gtk_label_new ("");
-	eel_gtk_label_make_bold (GTK_LABEL (*title_widget));
-	gtk_misc_set_alignment (GTK_MISC (*title_widget), 1, 0);
-	gtk_table_attach (table, *title_widget,
-			  0, 1,
-			  row, row + 1,
-			  GTK_FILL, 0,
-			  0, 0);
-	gtk_widget_show (*title_widget);
-
-	*label_text_widget = gtk_label_new ("");
-	gtk_label_set_ellipsize (GTK_LABEL (*label_text_widget), PANGO_ELLIPSIZE_END);
-	gtk_table_attach (table, *label_text_widget,
-			  1, 2,
-			  row, row + 1,
-			  GTK_FILL | GTK_EXPAND, 0,
-			  0, 0);
-	gtk_widget_show (*label_text_widget);
-	gtk_misc_set_alignment (GTK_MISC (*label_text_widget), 0, 0);
-}
-
-static void
-file_transfer_dialog_init (FileTransferDialog *dlg)
-{
-	GtkWidget *vbox;
-	GtkWidget *hbox;
-	GtkWidget *progress_vbox;
-	GtkWidget *table;
-	GtkWidget *label;
-	char      *markup;
-
-	dlg->priv = g_new0 (FileTransferDialogPrivate, 1);
-	
-	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->vbox),
-					4);
-	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->vbox), 4);
-
-	vbox = gtk_vbox_new (FALSE, 6);
-	gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
-	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), vbox, TRUE, TRUE, 0);
-
-	dlg->priv->status = gtk_label_new ("");
-	markup = g_strdup_printf ("<big><b>%s</b></big>", _("Copying files"));
-	gtk_label_set_markup (GTK_LABEL (dlg->priv->status), markup);
-	g_free (markup);
-
-	gtk_misc_set_alignment (GTK_MISC (dlg->priv->status), 0.0, 0.0);
-	
-	gtk_box_pack_start (GTK_BOX (vbox), dlg->priv->status, FALSE, FALSE, 0);
-
-	hbox = gtk_hbox_new (FALSE, 0);
-	gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
-
-	table = gtk_table_new (2, 2, FALSE);
-	gtk_table_set_row_spacings (GTK_TABLE (table), 4);
-	gtk_table_set_col_spacings (GTK_TABLE (table), 4);
-
-	create_titled_label (GTK_TABLE (table), 0,
-			     &label, 
-			     &dlg->priv->from);
-	gtk_label_set_text (GTK_LABEL (label), _("From:"));
-	create_titled_label (GTK_TABLE (table), 1,
-			     &label, 
-			     &dlg->priv->to);
-	gtk_label_set_text (GTK_LABEL (label), _("To:"));
-
-	gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (table), FALSE, FALSE, 0);
-
-	progress_vbox = gtk_vbox_new (TRUE, 0);
-	gtk_box_pack_start (GTK_BOX (vbox), progress_vbox, FALSE, FALSE, 0);
-
-	dlg->priv->progress = gtk_progress_bar_new ();
-	gtk_box_pack_start (GTK_BOX (progress_vbox),
-			    dlg->priv->progress, FALSE, FALSE, 0);
-
-	dlg->priv->current = gtk_label_new ("");
-	gtk_box_pack_start (GTK_BOX (progress_vbox),
-			    dlg->priv->current, FALSE, FALSE, 0);
-	gtk_misc_set_alignment (GTK_MISC (dlg->priv->current), 0.0, 0.5);
-
-	gtk_dialog_add_button (GTK_DIALOG (dlg),
-			       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
-
-	gtk_window_set_title (GTK_WINDOW (dlg),
-			      _("Copying files"));
-	gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
-	gtk_container_set_border_width (GTK_CONTAINER (dlg), 6);
-
-	gtk_widget_show_all (GTK_DIALOG (dlg)->vbox);
-}
-	
-GType
-file_transfer_dialog_get_type (void)
-{
-	static GType file_transfer_dialog_type = 0;
-
-	if (!file_transfer_dialog_type)
-	{
-		static GTypeInfo file_transfer_dialog_info =
-		{
-			sizeof (FileTransferDialogClass),
-			NULL, /* GBaseInitFunc */
-			NULL, /* GBaseFinalizeFunc */
-			(GClassInitFunc) file_transfer_dialog_class_init,
-			NULL, /* GClassFinalizeFunc */
-			NULL, /* data */
-			sizeof (FileTransferDialog),
-			0, /* n_preallocs */
-			(GInstanceInitFunc) file_transfer_dialog_init,
-			NULL
-		};
-
-		file_transfer_dialog_type =
-			g_type_register_static (GTK_TYPE_DIALOG,
-					 	"FileTransferDialog",
-						&file_transfer_dialog_info,
-						0);
-	}
-
-	return file_transfer_dialog_type;
-}
-
-GtkWidget*
-file_transfer_dialog_new (void)
-{
-	return GTK_WIDGET (g_object_new (file_transfer_dialog_get_type (),
-					 NULL));
-}
-
-static int
-file_transfer_dialog_update_cb (GnomeVFSAsyncHandle *handle,
-				GnomeVFSXferProgressInfo *info,
-				gpointer data)
-{
-	FileTransferDialog *dlg = FILE_TRANSFER_DIALOG (data);
-
-	if (info->status == GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR)
-		return GNOME_VFS_XFER_ERROR_ACTION_ABORT;
-		
-	if (info->source_name)
-		g_object_set (G_OBJECT (dlg),
-			      "from_uri", info->source_name,
-			      NULL);
-	if (info->target_name)
-		g_object_set (G_OBJECT (dlg),
-			      "to_uri", info->target_name,
-			      NULL);
-
-	if (info->bytes_total)
-		g_object_set (G_OBJECT (dlg),
-			      "fraction_complete", (double) info->total_bytes_copied / (double) info->bytes_total,
-			      NULL);
-
-	if (info->file_index && info->files_total)
-		g_object_set (G_OBJECT (dlg),
-			      "nth_uri", info->file_index,
-			      "total_uris", info->files_total,
-			      NULL);
-	
-	switch (info->phase)
-	{
-	case GNOME_VFS_XFER_PHASE_INITIAL:
-		{
-			char *str = g_strdup_printf ("<i>%s</i>", _("Connecting..."));
-			gtk_label_set_markup (GTK_LABEL (dlg->priv->current),
-					      str);
-			g_free (str);
-		}
-		break;
-	case GNOME_VFS_XFER_PHASE_READYTOGO:
-	case GNOME_VFS_XFER_PHASE_OPENSOURCE:
-		break;
-	case GNOME_VFS_XFER_PHASE_COMPLETED:
-		g_signal_emit (G_OBJECT (dlg),
-			       file_transfer_dialog_signals[DONE],
-			       0, NULL);
-		return 0;
-	default:
-		break;
-	}
-
-	return 1;
-}
-
-GnomeVFSResult
-file_transfer_dialog_wrap_async_xfer (FileTransferDialog *dlg,
-				      GList *source_uri_list,
-				      GList *target_uri_list,
-				      GnomeVFSXferOptions xfer_options,
-				      GnomeVFSXferErrorMode error_mode,
-				      GnomeVFSXferOverwriteMode overwrite_mode,
-				      int priority)
-{
-	g_return_val_if_fail (IS_FILE_TRANSFER_DIALOG (dlg),
-			      GNOME_VFS_ERROR_BAD_PARAMETERS);
-
-	return gnome_vfs_async_xfer (&dlg->priv->handle,
-				     source_uri_list,
-				     target_uri_list,
-				     xfer_options,
-				     error_mode,
-				     overwrite_mode,
-				     priority,
-				     file_transfer_dialog_update_cb,
-				     dlg,
-				     NULL,
-				     NULL
-				   );
-}
Index: src/file-transfer-dialog.h
===================================================================
--- src/file-transfer-dialog.h	(revision 1350)
+++ src/file-transfer-dialog.h	(working copy)
@@ -1,69 +0,0 @@
-/* -*- mode: c; style: linux -*- */
-
-/* file-transfer-dialog.h
- * Copyright (C) 2002 Ximian, Inc.
- *
- * Written by Rachel Hestilow <hestilow@ximian.com> 
- *
- * 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, 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 __FILE_TRANSFER_DIALOG_H__
-#define __FILE_TRANSFER_DIALOG_H__
-
-#include <gtk/gtkdialog.h>
-#include <libgnomevfs/gnome-vfs-xfer.h>
-
-G_BEGIN_DECLS
-
-#define FILE_TRANSFER_DIALOG(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, file_transfer_dialog_get_type (), FileTransferDialog)
-#define FILE_TRANSFER_DIALOG_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, file_transfer_dialog_get_type (), FileTransferDialogClass)
-#define IS_FILE_TRANSFER_DIALOG(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, file_transfer_dialog_get_type ())
-
-typedef struct _FileTransferDialog FileTransferDialog;
-typedef struct _FileTransferDialogClass FileTransferDialogClass;
-typedef struct _FileTransferDialogPrivate FileTransferDialogPrivate;
-
-struct _FileTransferDialog
-{
-	GtkDialog dialog;
-
-	FileTransferDialogPrivate *priv;
-};
-
-struct _FileTransferDialogClass
-{
-	GtkDialogClass parent_class;
-
-	void (*cancel) (FileTransferDialog *dlg);
-	void (*done) (FileTransferDialog *dlg);
-};
-
-GType	       file_transfer_dialog_get_type (void);
-GtkWidget*     file_transfer_dialog_new (void);
-
-GnomeVFSResult file_transfer_dialog_wrap_async_xfer (FileTransferDialog *dlg,
-						     GList *source_uri_list,
-						     GList *target_uri_list,
-						     GnomeVFSXferOptions xfer_options,
-						     GnomeVFSXferErrorMode error_mode,
-						     GnomeVFSXferOverwriteMode overwrite_mode,
-						     int priority);
-
-
-G_END_DECLS
-
-#endif /* __FILE_TRANSFER_DIALOG_H__ */
Index: src/copy-theme-dialog.c
===================================================================
--- src/copy-theme-dialog.c	(revision 0)
+++ src/copy-theme-dialog.c	(revision 0)
@@ -0,0 +1,518 @@
+/* copy-theme-dialog.c
+ * Copyright (C) 2008 John Millikin <jmillikin@gmail.com>
+ * 
+ * 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, 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 <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+#include <limits.h>
+#include <string.h>
+
+#include "copy-theme-dialog.h"
+
+static void
+copy_theme_dialog_class_init (CopyThemeDialogClass *klass);
+static void
+copy_theme_dialog_init (CopyThemeDialog *dlg);
+static void
+add_file_to_dialog (gpointer data, gpointer user_data);
+static void
+single_copy_complete (GObject *source_object, GAsyncResult *res,
+                      gpointer user_data);
+static void
+copy_theme_dialog_copy_next (CopyThemeDialog *dialog);
+static void
+copy_theme_dialog_cancel (CopyThemeDialog *dialog);
+static void
+copy_theme_dialog_finalize (GObject *obj);
+static void
+copy_theme_dialog_update_num_files (CopyThemeDialog *dlg);
+static void
+copy_theme_dialog_response (GtkDialog *dialog, gint response_id);
+static void
+eel_gtk_label_make_bold (GtkLabel *label);
+static void
+create_titled_label (GtkTable   *table,
+                     int         row,
+                     GtkWidget **title_widget,
+                     GtkWidget **label_text_widget);
+
+static GObjectClass *parent_class = NULL;
+
+enum
+{
+	CANCELLED = 0,
+	COMPLETE,
+	SIGNAL_COUNT
+};
+
+struct _CopyThemeDialogPrivate
+{
+	GtkWidget *progress;
+	GtkWidget *status;
+	GtkWidget *current;
+	GtkWidget *from;
+	GtkWidget *to;
+	
+	GFile *theme_dir;
+	GSList *all_files, *file;
+	GSList *all_basenames, *basename;
+	guint index;
+	guint total_files;
+	GCancellable *cancellable;
+};
+
+guint signals[SIGNAL_COUNT] = {0, 0};
+
+GType
+copy_theme_dialog_get_type (void)
+{
+	static GType copy_theme_dialog_type = 0;
+	
+	if (!copy_theme_dialog_type)
+	{
+		static GTypeInfo copy_theme_dialog_info =
+		{
+			sizeof (CopyThemeDialogClass),
+			NULL, /* GBaseInitFunc */
+			NULL, /* GBaseFinalizeFunc */
+			(GClassInitFunc) copy_theme_dialog_class_init,
+			NULL, /* GClassFinalizeFunc */
+			NULL, /* data */
+			sizeof (CopyThemeDialog),
+			0, /* n_preallocs */
+			(GInstanceInitFunc) copy_theme_dialog_init,
+			NULL
+		};
+		
+		copy_theme_dialog_type = g_type_register_static (GTK_TYPE_DIALOG,
+		                                                 "CopyThemeDialog",
+		                                                 &copy_theme_dialog_info,
+		                                                 0);
+	}
+	
+	return copy_theme_dialog_type;
+}
+
+static void
+copy_theme_dialog_class_init (CopyThemeDialogClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	
+	g_type_class_add_private (klass, sizeof (CopyThemeDialogPrivate));
+	
+	klass->cancelled = copy_theme_dialog_cancel;
+	object_class->finalize = copy_theme_dialog_finalize;
+	
+	GTK_DIALOG_CLASS (klass)->response = copy_theme_dialog_response;
+	
+	signals[CANCELLED] = g_signal_new ("cancelled",
+	                                   G_TYPE_FROM_CLASS (object_class),
+	                                   G_SIGNAL_RUN_FIRST,
+	                                   G_STRUCT_OFFSET (CopyThemeDialogClass, cancelled),
+	                                   NULL, NULL,
+	                                   g_cclosure_marshal_VOID__VOID,
+	                                   G_TYPE_NONE, 0);
+	
+	signals[COMPLETE] = g_signal_new ("complete",
+	                                  G_TYPE_FROM_CLASS (object_class),
+	                                  G_SIGNAL_RUN_LAST,
+	                                  G_STRUCT_OFFSET (CopyThemeDialogClass, complete),
+	                                  NULL, NULL,
+	                                  g_cclosure_marshal_VOID__VOID,
+	                                  G_TYPE_NONE, 0);
+	
+	parent_class = g_type_class_peek_parent (klass);
+}
+
+GtkWidget*
+copy_theme_dialog_new (GList *files)
+{
+	GtkWidget *dialog;
+	CopyThemeDialogPrivate *priv;
+	
+	dialog = GTK_WIDGET (g_object_new (COPY_THEME_DIALOG_TYPE, NULL));
+	priv = COPY_THEME_DIALOG (dialog)->priv;
+	priv->index = 0;
+	priv->total_files = 0;
+	priv->all_files = NULL;
+	priv->all_basenames = NULL;
+	
+	g_list_foreach (files, add_file_to_dialog, dialog);
+	
+	priv->file = priv->all_files;
+	priv->basename = priv->all_basenames;
+	
+	return dialog;
+}
+
+static void
+copy_theme_dialog_init (CopyThemeDialog *dlg)
+{
+	GtkWidget *vbox;
+	GtkWidget *hbox;
+	GtkWidget *progress_vbox;
+	GtkWidget *table;
+	GtkWidget *label;
+	char      *markup;
+	gchar     *theme_dir_path;
+	
+	dlg->priv = G_TYPE_INSTANCE_GET_PRIVATE (dlg, COPY_THEME_DIALOG_TYPE,
+	                                         CopyThemeDialogPrivate);
+	
+	/* Find and, if needed, create the directory for storing themes */
+	theme_dir_path = g_build_filename (g_get_user_data_dir (),
+	                                   "applications", "screensavers",
+	                                   NULL);
+	dlg->priv->theme_dir = g_file_new_for_path (theme_dir_path);
+	g_mkdir_with_parents (theme_dir_path, S_IRWXU);
+	g_free (theme_dir_path);
+	
+	/* For cancelling async I/O operations */
+	dlg->priv->cancellable = g_cancellable_new ();
+	
+	/* GUI settings */
+	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->vbox),
+	                                4);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->vbox), 4);
+	
+	vbox = gtk_vbox_new (FALSE, 6);
+	gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), vbox, TRUE, TRUE, 0);
+	
+	dlg->priv->status = gtk_label_new ("");
+	markup = g_strdup_printf ("<big><b>%s</b></big>", _("Copying files"));
+	gtk_label_set_markup (GTK_LABEL (dlg->priv->status), markup);
+	g_free (markup);
+	
+	gtk_misc_set_alignment (GTK_MISC (dlg->priv->status), 0.0, 0.0);
+	
+	gtk_box_pack_start (GTK_BOX (vbox), dlg->priv->status, FALSE, FALSE, 0);
+	
+	hbox = gtk_hbox_new (FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+	
+	table = gtk_table_new (2, 2, FALSE);
+	gtk_table_set_row_spacings (GTK_TABLE (table), 4);
+	gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+	
+	create_titled_label (GTK_TABLE (table), 0,
+	                     &label, 
+	                     &dlg->priv->from);
+	gtk_label_set_text (GTK_LABEL (label), _("From:"));
+	create_titled_label (GTK_TABLE (table), 1,
+	                     &label, 
+	                     &dlg->priv->to);
+	gtk_label_set_text (GTK_LABEL (label), _("To:"));
+	
+	gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (table), FALSE, FALSE, 0);
+	
+	progress_vbox = gtk_vbox_new (TRUE, 0);
+	gtk_box_pack_start (GTK_BOX (vbox), progress_vbox, FALSE, FALSE, 0);
+	
+	dlg->priv->progress = gtk_progress_bar_new ();
+	gtk_box_pack_start (GTK_BOX (progress_vbox),
+	                    dlg->priv->progress, FALSE, FALSE, 0);
+	
+	dlg->priv->current = gtk_label_new ("");
+	gtk_box_pack_start (GTK_BOX (progress_vbox),
+	                    dlg->priv->current, FALSE, FALSE, 0);
+	gtk_misc_set_alignment (GTK_MISC (dlg->priv->current), 0.0, 0.5);
+	
+	gtk_dialog_add_button (GTK_DIALOG (dlg),
+	                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+	
+	gtk_window_set_title (GTK_WINDOW (dlg),
+	                      _("Copying themes"));
+	gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
+	gtk_container_set_border_width (GTK_CONTAINER (dlg), 6);
+	
+	gtk_widget_show_all (GTK_DIALOG (dlg)->vbox);
+}
+
+static void
+add_file_to_dialog (gpointer data, gpointer user_data)
+{
+	CopyThemeDialogPrivate *priv;
+	GFile *file;
+	gchar *basename = NULL, *raw_basename;
+	
+	priv = COPY_THEME_DIALOG (user_data)->priv;
+	file = G_FILE (data);
+	
+	raw_basename = g_file_get_basename (file);
+	if (g_str_has_suffix (raw_basename, ".desktop"))
+	{
+		/* FIXME: validate key file? */
+		basename = g_strndup (raw_basename,
+		                      /* 8 = strlen (".desktop") */
+		                      strlen (raw_basename) - 8);
+	}
+	g_free (raw_basename);
+	
+	if (basename)
+	{
+		g_object_ref (file);
+		priv->all_files = g_slist_append (priv->all_files, file);
+		priv->all_basenames = g_slist_append (priv->all_basenames, basename);
+		priv->total_files++;
+	}
+	
+	else
+	{
+		GtkWidget *dialog;
+		gchar *uri;
+		
+		dialog = gtk_message_dialog_new (GTK_WINDOW (user_data),
+		                                 GTK_DIALOG_MODAL,
+		                                 GTK_MESSAGE_ERROR,
+		                                 GTK_BUTTONS_OK,
+		                                 _("Invalid screensaver theme"));
+		uri = g_file_get_uri (file);
+		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+		                                          _("%s does not appear to be a valid screensaver theme."),
+		                                          uri);
+		g_free (uri);
+		gtk_window_set_title (GTK_WINDOW (dialog), "");
+		gtk_window_set_icon_name (GTK_WINDOW (dialog), "screensaver");
+		
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+	}
+}
+
+static void
+single_copy_complete (GObject *source_object, GAsyncResult *res,
+                      gpointer user_data)
+{
+	GError *error = NULL;
+	gboolean should_continue = FALSE;
+	CopyThemeDialog *dialog = COPY_THEME_DIALOG (user_data);
+	
+	if (g_file_copy_finish (G_FILE (source_object), res, &error))
+	{
+		should_continue = TRUE;
+	}
+	
+	else
+	{
+		/* If the file already exists, generate a new random name
+		 * and try again.
+		**/
+		if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
+		{
+			GFile *file, *destination;
+			gchar *basename, *full_basename;
+			g_error_free (error);
+			
+			file = G_FILE (dialog->priv->file->data);
+			basename = (gchar *) (dialog->priv->basename->data);
+			
+			g_return_if_fail (file != NULL);
+			g_return_if_fail (basename != NULL);
+			
+			full_basename = g_strdup_printf ("%s-%u.desktop",
+			                                 basename,
+			                                 g_random_int ());
+			destination = g_file_get_child (dialog->priv->theme_dir,
+			                                full_basename);
+			g_free (full_basename);
+			
+			g_file_copy_async (file, destination, G_FILE_COPY_NONE,
+			                   G_PRIORITY_DEFAULT,
+			                   dialog->priv->cancellable,
+			                   NULL, NULL,
+			                   single_copy_complete, dialog);
+		}
+		
+		else
+		{
+			if (g_error_matches (error, G_IO_ERROR,
+			                          G_IO_ERROR_CANCELLED))
+			{
+				/* User has cancelled the theme copy */
+				g_signal_emit (G_OBJECT (dialog),
+				               signals[CANCELLED],
+				               0, NULL);
+			}
+			
+			else
+			{
+				/* Some other error occurred, ignore and 
+				 * try to copy remaining files
+				**/
+				should_continue = TRUE;
+			}
+			
+			g_error_free (error);
+		}
+	}
+	
+	/* Update informational widgets and, if needed, signal
+	 * copy completion.
+	**/
+	if (should_continue)
+	{
+		dialog->priv->index++;
+		dialog->priv->file = dialog->priv->file->next;
+		dialog->priv->basename = dialog->priv->basename->next;
+		copy_theme_dialog_update_num_files (dialog);
+		copy_theme_dialog_copy_next (dialog);
+	}
+}
+
+/* Try to copy the theme file to the user's screensaver directory.
+ * If a file with the given name already exists, the error will be
+ * caught later and the copy re-attempted with a random value
+ * appended to the filename.
+**/
+static void
+copy_theme_dialog_copy_next (CopyThemeDialog *dialog)
+{
+	GFile *file, *destination;
+	gchar *basename, *full_basename;
+	
+	if (dialog->priv->file == NULL)
+	{
+		/* Copy is complete */
+		g_signal_emit (G_OBJECT (dialog), signals[COMPLETE],
+		               0, NULL);
+		gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_NONE);
+		return;
+	}
+	
+	file = G_FILE (dialog->priv->file->data);
+	basename = (gchar *) (dialog->priv->basename->data);
+	
+	g_return_if_fail (file != NULL);
+	g_return_if_fail (basename != NULL);
+	
+	full_basename = g_strdup_printf ("%s.desktop", basename);
+	destination = g_file_get_child (dialog->priv->theme_dir, full_basename);
+	g_free (full_basename);
+	
+	g_file_copy_async (file, destination, G_FILE_COPY_NONE,
+	                   G_PRIORITY_DEFAULT, dialog->priv->cancellable,
+	                   NULL, NULL, single_copy_complete, dialog);
+}
+
+void
+copy_theme_dialog_begin (CopyThemeDialog *dialog)
+{
+	g_object_ref (dialog);
+	copy_theme_dialog_copy_next (dialog);
+	if (!g_cancellable_is_cancelled (dialog->priv->cancellable))
+		gtk_dialog_run (GTK_DIALOG (dialog));
+	g_object_unref (dialog);
+}
+
+static void
+copy_theme_dialog_cancel (CopyThemeDialog *dialog)
+{
+	g_cancellable_cancel (dialog->priv->cancellable);
+}
+
+static void
+copy_theme_dialog_finalize (GObject *obj)
+{
+	CopyThemeDialog *dlg = COPY_THEME_DIALOG (obj);
+	
+	g_object_unref (dlg->priv->theme_dir);
+	g_slist_foreach (dlg->priv->all_files, (GFunc) (g_object_unref), NULL);
+	g_slist_free (dlg->priv->all_files);
+	g_slist_foreach (dlg->priv->all_basenames, (GFunc) (g_free), NULL);
+	g_slist_free (dlg->priv->all_basenames);
+	g_object_unref (dlg->priv->cancellable);
+	
+	if (parent_class->finalize)
+		parent_class->finalize (G_OBJECT (dlg));
+}
+
+static void
+copy_theme_dialog_update_num_files (CopyThemeDialog *dlg)
+{
+	gchar *str = g_strdup_printf (_("Copying file: %u of %u"),
+				      dlg->priv->index, dlg->priv->total_files);
+	gtk_progress_bar_set_text (GTK_PROGRESS_BAR (dlg->priv->progress), str);
+	g_free (str);
+}
+
+static void
+copy_theme_dialog_response (GtkDialog *dialog, gint response_id)
+{
+	g_cancellable_cancel (COPY_THEME_DIALOG (dialog)->priv->cancellable);
+}
+
+/**
+ * eel_gtk_label_make_bold.
+ *
+ * Switches the font of label to a bold equivalent.
+ * @label: The label.
+ **/
+static void
+eel_gtk_label_make_bold (GtkLabel *label)
+{
+	PangoFontDescription *font_desc;
+	
+	font_desc = pango_font_description_new ();
+	
+	pango_font_description_set_weight (font_desc,
+	                                   PANGO_WEIGHT_BOLD);
+	
+	/* This will only affect the weight of the font, the rest is
+	 * from the current state of the widget, which comes from the
+	 * theme or user prefs, since the font desc only has the
+	 * weight flag turned on.
+	 */
+	gtk_widget_modify_font (GTK_WIDGET (label), font_desc);
+	
+	pango_font_description_free (font_desc);
+}
+
+/* from nautilus */
+static void
+create_titled_label (GtkTable   *table,
+                     int         row,
+                     GtkWidget **title_widget,
+                     GtkWidget **label_text_widget)
+{
+	*title_widget = gtk_label_new ("");
+	eel_gtk_label_make_bold (GTK_LABEL (*title_widget));
+	gtk_misc_set_alignment (GTK_MISC (*title_widget), 1, 0);
+	gtk_table_attach (table, *title_widget,
+	                  0, 1,
+	                  row, row + 1,
+	                  GTK_FILL, 0,
+	                  0, 0);
+	gtk_widget_show (*title_widget);
+	
+	*label_text_widget = gtk_label_new ("");
+	gtk_label_set_ellipsize (GTK_LABEL (*label_text_widget), PANGO_ELLIPSIZE_END);
+	gtk_table_attach (table, *label_text_widget,
+	                  1, 2,
+	                  row, row + 1,
+	                  GTK_FILL | GTK_EXPAND, 0,
+	                  0, 0);
+	gtk_widget_show (*label_text_widget);
+	gtk_misc_set_alignment (GTK_MISC (*label_text_widget), 0, 0);
+}
Index: src/copy-theme-dialog.h
===================================================================
--- src/copy-theme-dialog.h	(revision 0)
+++ src/copy-theme-dialog.h	(revision 0)
@@ -0,0 +1,56 @@
+/* copy-theme-dialog.h
+ * Copyright (C) 2008 John Millikin <jmillikin@gmail.com>
+ * 
+ * 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, 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 __COPY_THEME_DIALOG_H__
+#define __COPY_THEME_DIALOG_H__
+
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+
+#define COPY_THEME_DIALOG_TYPE copy_theme_dialog_get_type ()
+#define COPY_THEME_DIALOG(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, COPY_THEME_DIALOG_TYPE, CopyThemeDialog)
+#define COPY_THEME_DIALOG_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, COPY_THEME_DIALOG_TYPE, CopyThemeDialogClass)
+#define IS_COPY_THEME_DIALOG(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, COPY_THEME_DIALOG_TYPE)
+
+typedef struct _CopyThemeDialog CopyThemeDialog;
+typedef struct _CopyThemeDialogClass CopyThemeDialogClass;
+typedef struct _CopyThemeDialogPrivate CopyThemeDialogPrivate;
+
+struct _CopyThemeDialog
+{
+	GtkDialog dialog;
+	CopyThemeDialogPrivate *priv;
+};
+
+struct _CopyThemeDialogClass
+{
+	GtkDialogClass parent_class;
+	
+	void (*cancelled) (CopyThemeDialog *dialog);
+	void (*complete) (CopyThemeDialog *dialog);
+};
+
+GType copy_theme_dialog_get_type (void);
+GtkWidget *copy_theme_dialog_new (GList *files);
+void copy_theme_dialog_begin (CopyThemeDialog *dialog);
+
+G_END_DECLS
+
+#endif /* __COPY_THEME_DIALOG_H__ */
Index: src/gnome-screensaver-preferences.c
===================================================================
--- src/gnome-screensaver-preferences.c	(revision 1350)
+++ src/gnome-screensaver-preferences.c	(working copy)
@@ -36,11 +36,9 @@
 #include <glade/glade.h>
 #include <gconf/gconf-client.h>
 
-#include <libgnomevfs/gnome-vfs-async-ops.h>
-#include <libgnomevfs/gnome-vfs-ops.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
+#include <gio/gio.h>
 
-#include "file-transfer-dialog.h"
+#include "copy-theme-dialog.h"
 
 #include "gs-theme-manager.h"
 #include "gs-job.h"
@@ -810,125 +808,32 @@
 }
 
 static void
-transfer_done_cb (GtkWidget *dialog,
-                  char      *path)
+theme_copy_complete_cb (GtkWidget *dialog, gpointer user_data)
 {
-
-        g_free (path);
-
-        gtk_widget_destroy (dialog);
-
         reload_themes ();
 }
 
 static void
-transfer_cancel_cb (GtkWidget *dialog,
-                    char      *path)
+theme_installer_run (GtkWidget *prefs_dialog, GList *files)
 {
-        gnome_vfs_unlink (path);
-        g_free (path);
-
-        gtk_widget_destroy (dialog);
+        GtkWidget *copy_dialog;
+        
+        copy_dialog = copy_theme_dialog_new (files);
+        g_list_foreach (files, (GFunc) (g_object_unref), NULL);
+        g_list_free (files);
+        
+        gtk_window_set_transient_for (GTK_WINDOW (copy_dialog),
+                                        GTK_WINDOW (prefs_dialog));
+        gtk_window_set_icon_name (GTK_WINDOW (copy_dialog),
+                                        "screensaver");
+        
+        g_signal_connect (copy_dialog, "complete",
+                          G_CALLBACK (theme_copy_complete_cb), NULL);
+        
+        copy_theme_dialog_begin (COPY_THEME_DIALOG (copy_dialog));
+        gtk_widget_destroy (copy_dialog);
 }
 
-static void
-theme_installer_run (GtkWidget *parent,
-                     char      *filename)
-{
-        GtkWidget    *dialog;
-        GnomeVFSURI  *src_uri;
-        GList        *src;
-        GList        *target;
-        char         *user_dir;
-        char         *short_name;
-        char         *base_name;
-        char         *target_path;
-        gboolean      is_desktop;
-
-        src_uri = gnome_vfs_uri_new (filename);
-        src = g_list_append (NULL, src_uri);
-        target = NULL;
-        target_path = NULL;
-
-        user_dir = g_build_filename (g_get_user_data_dir (), "applications", "screensavers", NULL);
-        g_mkdir_with_parents (user_dir, S_IRWXU);
-
-        short_name = gnome_vfs_uri_extract_short_name (src_uri);
-        base_name = NULL;
-
-        is_desktop = FALSE;
-        if (short_name != NULL
-            && g_str_has_suffix (short_name, ".desktop")) {
-                /* FIXME: validate key file? */
-                is_desktop = TRUE;
-                base_name = g_strndup (short_name, strlen (short_name) - 8);
-        }
-
-        while (TRUE) {
-                char *tmp;
-                gboolean exists;
-
-                if (! is_desktop) {
-                        dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
-                                                         GTK_DIALOG_MODAL,
-                                                         GTK_MESSAGE_ERROR,
-                                                         GTK_BUTTONS_OK,
-                                                         _("Invalid screensaver theme"));
-                        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
-                                                                  "%s",
-                                                                  _("This file does not appear to be a valid screensaver theme."));
-                        gtk_window_set_title (GTK_WINDOW (dialog), "");
-                        gtk_window_set_icon_name (GTK_WINDOW (dialog), "screensaver");
-
-                        gtk_dialog_run (GTK_DIALOG (dialog));
-                        gtk_widget_destroy (dialog);
-                        g_free (target_path);
-                        goto out;
-                }
-
-                g_free (target_path);
-                target_path = g_build_filename (user_dir, short_name, NULL);
-
-                /* FIXME: racy, oh well */
-                exists = gnome_vfs_uri_exists (gnome_vfs_uri_new (target_path));
-                if (! exists) {
-                        target = g_list_append (NULL, gnome_vfs_uri_new (target_path));
-                        break;
-                }
-
-                /* try another name */
-                tmp = g_strdup_printf ("%s-%u.desktop",  base_name, g_random_int ());
-                g_free (short_name);
-                short_name = tmp;
-        }
-
-        dialog = file_transfer_dialog_new ();
-        gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
-        gtk_window_set_icon_name (GTK_WINDOW (dialog), "screensaver");
-
-        file_transfer_dialog_wrap_async_xfer (FILE_TRANSFER_DIALOG (dialog),
-                                              src, target,
-                                              GNOME_VFS_XFER_RECURSIVE,
-                                              GNOME_VFS_XFER_ERROR_MODE_QUERY,
-                                              GNOME_VFS_XFER_OVERWRITE_MODE_QUERY,
-                                              GNOME_VFS_PRIORITY_DEFAULT);
-
-        g_signal_connect (dialog, "cancel",
-                          G_CALLBACK (transfer_cancel_cb), target_path);
-        g_signal_connect (dialog, "done",
-                          G_CALLBACK (transfer_done_cb), target_path);
-
-        gtk_widget_show (dialog);
-
- out:
-        gnome_vfs_uri_list_unref (src);
-        gnome_vfs_uri_list_unref (target);
-
-        g_free (user_dir);
-        g_free (base_name);
-        g_free (short_name);
-}
-
 /* Callback issued during drag movements */
 static gboolean
 drag_motion_cb (GtkWidget      *widget,
@@ -951,6 +856,63 @@
         gtk_widget_queue_draw (widget);
 }
 
+/* GIO has no version of gnome_vfs_uri_list_parse(), so copy from GnomeVFS
+ * and re-work to create GFiles.
+**/
+static GList *
+uri_list_parse (const gchar *uri_list)
+{
+        const gchar *p, *q;
+        gchar *retval;
+        GFile *file;
+        GList *result = NULL;
+        
+        g_return_val_if_fail (uri_list != NULL, NULL);
+        
+        p = uri_list;
+        
+        /* We don't actually try to validate the URI according to RFC
+         * 2396, or even check for allowed characters - we just ignore
+         * comments and trim whitespace off the ends.  We also
+         * allow LF delimination as well as the specified CRLF.
+         */
+        while (p != NULL) {
+                if (*p != '#') {
+                        while (g_ascii_isspace (*p))
+                                p++;
+                        
+                        q = p;
+                        while ((*q != '\0')
+                               && (*q != '\n')
+                               && (*q != '\r'))
+                                q++;
+                        
+                        if (q > p) {
+                                q--;
+                                while (q > p
+                                       && g_ascii_isspace (*q))
+                                        q--;
+                                
+                                retval = g_malloc (q - p + 2);
+                                strncpy (retval, p, q - p + 1);
+                                retval[q - p + 1] = '\0';
+                                
+                                file = g_file_new_for_uri (retval);
+                                
+                                g_free (retval);
+                                
+                                if (file != NULL)
+                                        result = g_list_prepend (result, file);
+                        }
+                }
+                p = strchr (p, '\n');
+                if (p != NULL)
+                        p++;
+        }
+        
+        return g_list_reverse (result);
+}
+
 /* Callback issued on actual drops. Attempts to load the file dropped. */
 static void
 drag_data_received_cb (GtkWidget        *widget,
@@ -962,32 +924,18 @@
                        guint             time,
                        gpointer          data)
 {
-        GtkWidget *dialog;
-        GList     *uris;
-        char      *filename = NULL;
+        GList     *files;
 
         if (!(info == TARGET_URI_LIST || info == TARGET_NS_URL))
                 return;
-
-        uris = gnome_vfs_uri_list_parse ((char *) selection_data->data);
-        if (uris != NULL && uris->data != NULL) {
-                GnomeVFSURI *uri = (GnomeVFSURI *) uris->data;
-
-                if (gnome_vfs_uri_is_local (uri)) {
-                        filename = gnome_vfs_unescape_string (gnome_vfs_uri_get_path (uri),
-                                                              G_DIR_SEPARATOR_S);
-                } else {
-                        filename = gnome_vfs_unescape_string (gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE),
-                                                              G_DIR_SEPARATOR_S);
-                }
-
-                gnome_vfs_uri_list_unref (uris);
+        
+        files = uri_list_parse ((char *) selection_data->data);
+        if (files != NULL) {
+                GtkWidget *prefs_dialog;
+                
+                prefs_dialog = glade_xml_get_widget (xml, "prefs_dialog");
+                theme_installer_run (prefs_dialog, files);
         }
-
-        dialog = glade_xml_get_widget (xml, "prefs_dialog");
-        theme_installer_run (dialog, filename);
-
-        g_free (filename);
 }
 
 /* Adapted from totem_time_to_string_text */
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 1350)
+++ src/Makefile.am	(working copy)
@@ -212,8 +212,8 @@
 
 gnome_screensaver_preferences_SOURCES =	\
 	gnome-screensaver-preferences.c	\
-	file-transfer-dialog.c		\
-	file-transfer-dialog.h		\
+	copy-theme-dialog.c		\
+	copy-theme-dialog.h		\
 	gs-theme-manager.c		\
 	gs-theme-manager.h		\
 	gs-job.c			\
Index: configure.ac
===================================================================
--- configure.ac	(revision 1350)
+++ configure.ac	(working copy)
@@ -36,11 +36,10 @@
 # Dependencies
 
 DBUS_REQUIRED_VERSION=0.30
-GLIB_REQUIRED_VERSION=2.7.0
+GLIB_REQUIRED_VERSION=2.15.0
 GCONF_REQUIRED_VERSION=2.6.1
 GDK_REQUIRED_VERSION=2.7.0
 GTK_REQUIRED_VERSION=2.11.5
-GNOME_VFS_REQUIRED_VERSION=2.14
 LIBGNOME_MENU_REQUIRED_VERSION=2.11.1
 
 GLADE_REQUIRED_VERSION=2.5.0
@@ -71,7 +70,8 @@
 AC_SUBST(GNOME_SCREENSAVER_DIALOG_LIBS)
 
 PKG_CHECK_MODULES(GNOME_SCREENSAVER_CAPPLET,
-        gnome-vfs-2.0 >= $GNOME_VFS_REQUIRED_VERSION
+        gio-2.0 >= $GLIB_REQUIRED_VERSION
+        gconf-2.0 >= $GCONF_REQUIRED_VERSION
         libglade-2.0 >= $GLADE_REQUIRED_VERSION
         gtk+-2.0 >= $GTK_REQUIRED_VERSION
         libgnome-menu >= $LIBGNOME_MENU_REQUIRED_VERSION)
