changeset 896:cf21dc928122

implemented directory rename and delete operations
author nadvornik
date Sun, 20 Jul 2008 11:22:19 +0000
parents b48c366d5707
children 6c676d3eef5b
files src/filedata.c src/utilops.c
diffstat 2 files changed, 561 insertions(+), 306 deletions(-) [+]
line wrap: on
line diff
--- a/src/filedata.c	Sun Jul 20 07:52:16 2008 +0000
+++ b/src/filedata.c	Sun Jul 20 11:22:19 2008 +0000
@@ -1551,7 +1551,10 @@
 
 static gboolean file_data_perform_delete(FileData *fd)
 {
-	return unlink_file(fd->path);
+	if (isdir(fd->path) && !islink(fd->path))
+		return rmdir_utf8(fd->path);
+	else
+		return unlink_file(fd->path);
 }
 
 static gboolean file_data_perform_ci(FileData *fd)
--- a/src/utilops.c	Sun Jul 20 07:52:16 2008 +0000
+++ b/src/utilops.c	Sun Jul 20 11:22:19 2008 +0000
@@ -14,7 +14,6 @@
 #include "main.h"
 #include "utilops.h"
 
-
 #include "cache.h"
 #include "cache_maint.h"
 #include "collect.h"
@@ -234,6 +233,7 @@
 	UTILITY_TYPE_COPY,
 	UTILITY_TYPE_MOVE,
 	UTILITY_TYPE_RENAME,
+	UTILITY_TYPE_RENAME_FOLDER,
 	UTILITY_TYPE_EDITOR,
 	UTILITY_TYPE_FILTER,
 	UTILITY_TYPE_DELETE,
@@ -271,8 +271,8 @@
 	UtilityType type;
 	UtilityPhase phase;
 	
-	FileData *source_fd;
-	GList *dlist;
+	FileData *dir_fd;
+	GList *content_list;
 	GList *flist;
 
 	GtkWidget *parent;
@@ -342,8 +342,8 @@
 
 	if (ud->update_idle_id != -1) g_source_remove(ud->update_idle_id);
 
-	file_data_unref(ud->source_fd);
-	filelist_free(ud->dlist);
+	file_data_unref(ud->dir_fd);
+	filelist_free(ud->content_list);
 	filelist_free(ud->flist);
 
 	if (ud->gd) generic_dialog_close(ud->gd);
@@ -442,8 +442,6 @@
 	return view;
 }
 
-// FIXME
-static void file_util_delete_dir_ok_cb(GenericDialog *gd, gpointer data);
 
 void file_util_perform_ci_internal(UtilityData *ud);
 void file_util_dialog_run(UtilityData *ud);
@@ -546,7 +544,7 @@
  */ 
 
 
-void file_util_perform_ci_internal(UtilityData *ud)
+static void file_util_perform_ci_internal(UtilityData *ud)
 {
 	
 	while (ud->flist)
@@ -576,6 +574,147 @@
 		}
 }
 
+static void file_util_perform_ci_dir(UtilityData *ud, gboolean internal, gboolean ext_result)
+{
+	switch (ud->type)
+		{
+		case UTILITY_TYPE_DELETE_LINK:
+			{
+			if (internal && file_data_sc_perform_ci(ud->dir_fd) ||
+			    !internal && ext_result)
+				{
+				file_data_sc_apply_ci(ud->dir_fd);
+				}
+			else
+				{
+				gchar *text;
+
+				text = g_strdup_printf("Unable to remove symbolic link:\n %s", ud->dir_fd->path);
+				file_util_warning_dialog(_("Delete failed"), text,
+							 GTK_STOCK_DIALOG_ERROR, NULL);
+				g_free(text);
+				}
+			file_data_sc_free_ci(ud->dir_fd);
+			break;
+			}
+		case UTILITY_TYPE_DELETE_FOLDER:
+			{
+			FileData *fail = NULL;
+			GList *work;
+			work = ud->content_list;
+			while (work)
+				{
+				FileData *fd;
+
+				fd = work->data;
+				work = work->next;
+				
+				if (!fail)
+					{
+					if (internal && file_data_sc_perform_ci(fd) ||
+					    !internal && ext_result)
+						{
+						file_data_sc_apply_ci(fd);
+						}
+					else
+						{
+						if (internal) fail = file_data_ref(fd);
+						}
+					}
+				file_data_sc_free_ci(fd);
+				}
+
+			if (!fail)
+				{
+				if (internal && file_data_sc_perform_ci(ud->dir_fd) ||
+				    !internal && ext_result)
+					{
+					file_data_sc_apply_ci(ud->dir_fd);
+					}
+				else
+					{
+					fail = file_data_ref(ud->dir_fd);
+					}
+				}
+			
+			if (fail)
+				{
+				gchar *text;
+				GenericDialog *gd;
+
+				text = g_strdup_printf(_("Unable to delete folder:\n\n%s"), ud->dir_fd->path);
+				gd = file_util_warning_dialog(_("Delete failed"), text, GTK_STOCK_DIALOG_ERROR, NULL);
+				g_free(text);
+
+				if (fail != ud->dir_fd)
+					{
+					pref_spacer(gd->vbox, PREF_PAD_GROUP);
+					text = g_strdup_printf(_("Removal of folder contents failed at this file:\n\n%s"),
+								fail->path);
+					pref_label_new(gd->vbox, text);
+					g_free(text);
+					}
+
+				file_data_unref(fail);
+				}
+			break;
+			}
+		case UTILITY_TYPE_RENAME_FOLDER:
+			{
+			FileData *fail = NULL;
+			GList *work;
+			if (internal && file_data_sc_perform_ci(ud->dir_fd) ||
+			    !internal && ext_result)
+				{
+				file_data_sc_apply_ci(ud->dir_fd);
+				}
+			else
+				{
+				fail = file_data_ref(ud->dir_fd);
+				}
+			
+
+			work = ud->content_list;
+			while (work)
+				{
+				FileData *fd;
+
+				fd = work->data;
+				work = work->next;
+				
+				if (!fail)
+					{
+					file_data_sc_apply_ci(fd);
+					}
+				file_data_sc_free_ci(fd);
+				}
+			
+			if (fail)
+				{
+				gchar *text;
+				GenericDialog *gd;
+
+				text = g_strdup_printf(_("Unable to rename folder:\n\n%s"), ud->dir_fd->path);
+				gd = file_util_warning_dialog(_("Rename failed"), text, GTK_STOCK_DIALOG_ERROR, NULL);
+				g_free(text);
+
+				file_data_unref(fail);
+				}
+			break;
+			}
+		default:
+			g_warning("unhandled operation");
+		}
+	ud->phase = UTILITY_PHASE_DONE;
+	file_util_dialog_run(ud);
+}
+
+static gint file_util_perform_ci_dir_cb(gpointer resume_data, gint flags, GList *list, gpointer data)
+{
+	UtilityData *ud = data;
+	file_util_perform_ci_dir(ud, FALSE, !((flags & EDITOR_ERROR_MASK) && !(flags & EDITOR_ERROR_SKIPPED)));
+	return EDITOR_CB_CONTINUE; /* does not matter, there was just single directory */
+}
 
 void file_util_perform_ci(UtilityData *ud)
 {
@@ -588,6 +727,7 @@
 			ud->external_command = CMD_MOVE;
 			break;
 		case UTILITY_TYPE_RENAME:
+		case UTILITY_TYPE_RENAME_FOLDER:
 			ud->external_command = CMD_RENAME;
 			break;
 		case UTILITY_TYPE_DELETE:
@@ -606,7 +746,15 @@
 		gint flags;
 		
 		ud->external = TRUE;
-		flags = start_editor_from_filelist_full(ud->external_command, ud->flist, file_util_perform_ci_cb, ud);
+		
+		if (ud->dir_fd)
+			{
+			flags = start_editor_from_file_full(ud->external_command, ud->dir_fd, file_util_perform_ci_dir_cb, ud);
+			}
+		else
+			{
+			flags = start_editor_from_filelist_full(ud->external_command, ud->flist, file_util_perform_ci_cb, ud);
+			}
 
 		if (flags)
 			{
@@ -618,7 +766,14 @@
 	else
 		{
 		ud->external = FALSE;
-		file_util_perform_ci_internal(ud);
+		if (ud->dir_fd)
+			{
+			file_util_perform_ci_dir(ud, TRUE, FALSE);
+			}
+		else
+			{
+			file_util_perform_ci_internal(ud);
+			}
 		}
 }
 
@@ -692,6 +847,7 @@
 		case UTILITY_TYPE_DELETE_LINK:
 		case UTILITY_TYPE_DELETE_FOLDER:
 		case UTILITY_TYPE_RENAME:
+		case UTILITY_TYPE_RENAME_FOLDER:
 			g_warning("unhandled operation");
 		}
 }
@@ -920,15 +1076,28 @@
 {
 	GtkWidget *box;
 	GtkTreeSelection *selection;
+	gchar *dir_msg;
 
 	ud->gd = file_util_gen_dlg(ud->messages.title, GQ_WMCLASS, "dlg_confirm",
 				   ud->parent, FALSE,  file_util_cancel_cb, ud);
 	generic_dialog_add_button(ud->gd, GTK_STOCK_DELETE, NULL, file_util_ok_cb, TRUE);
 
+
+	if (ud->dir_fd)
+		{
+		dir_msg = g_strdup_printf("%s\n\n%s\n", ud->messages.desc_source_fd, ud->dir_fd->path);
+		}
+	else
+		{
+		dir_msg = g_strdup("");
+		}
+		
 	box = generic_dialog_add_message(ud->gd, GTK_STOCK_DIALOG_QUESTION,
 					 ud->messages.question,
-					 ud->messages.desc_flist);
+					 dir_msg);
 
+	g_free(dir_msg);
+	
 	box = pref_group_new(box, TRUE, ud->messages.desc_flist, GTK_ORIENTATION_HORIZONTAL);
 
 	ud->listview = file_util_dialog_add_list(box, ud->flist, FALSE);
@@ -1152,6 +1321,7 @@
 				case UTILITY_TYPE_COPY:
 				case UTILITY_TYPE_MOVE:
 				case UTILITY_TYPE_FILTER:
+				case UTILITY_TYPE_RENAME_FOLDER:
 					file_util_dialog_init_dest_folder(ud);
 					break;
 				}
@@ -1168,8 +1338,8 @@
 		case UTILITY_PHASE_CANCEL:
 		case UTILITY_PHASE_DONE:
 			file_data_sc_free_ci_list(ud->flist);
-			file_data_sc_free_ci_list(ud->dlist);
-			if (ud->source_fd) file_data_sc_free_ci(ud->source_fd);
+			file_data_sc_free_ci_list(ud->content_list);
+			if (ud->dir_fd) file_data_sc_free_ci(ud->dir_fd);
 			file_util_data_free(ud);
 			break;
 		}
@@ -1178,10 +1348,6 @@
 
 
 
-static gint file_util_unlink(FileData *fd)
-{
-}
-
 static void file_util_warn_op_in_progress(const gchar *title)
 {
 	file_util_warning_dialog(title, _("Another operation in progress.\n"), GTK_STOCK_DIALOG_ERROR, NULL);
@@ -1222,9 +1388,9 @@
 	
 	ud->phase = phase;
 
-	ud->source_fd = NULL;
+	ud->dir_fd = NULL;
 	ud->flist = flist;
-	ud->dlist = NULL;
+	ud->content_list = NULL;
 	ud->parent = parent;
 	
 	ud->messages.title = _("Delete");
@@ -1258,9 +1424,9 @@
 
 	ud->phase = phase;
 
-	ud->source_fd = NULL;
+	ud->dir_fd = NULL;
 	ud->flist = flist;
-	ud->dlist = NULL;
+	ud->content_list = NULL;
 	ud->parent = parent;
 
 	ud->dest_path = g_strdup(dest_path ? dest_path : "");
@@ -1295,9 +1461,9 @@
 
 	ud->phase = phase;
 
-	ud->source_fd = NULL;
+	ud->dir_fd = NULL;
 	ud->flist = flist;
-	ud->dlist = NULL;
+	ud->content_list = NULL;
 	ud->parent = parent;
 
 	ud->dest_path = g_strdup(dest_path ? dest_path : "");
@@ -1333,9 +1499,9 @@
 
 	ud->phase = phase;
 
-	ud->source_fd = NULL;
+	ud->dir_fd = NULL;
 	ud->flist = flist;
-	ud->dlist = NULL;
+	ud->content_list = NULL;
 	ud->parent = parent;
 	
 	ud->messages.title = _("Rename");
@@ -1378,9 +1544,9 @@
 	
 	ud->external_command = n;
 
-	ud->source_fd = NULL;
+	ud->dir_fd = NULL;
 	ud->flist = flist;
-	ud->dlist = NULL;
+	ud->content_list = NULL;
 	ud->parent = parent;
 
 	ud->dest_path = g_strdup(dest_path ? dest_path : "");
@@ -1395,6 +1561,364 @@
 	file_util_dialog_run(ud);
 }
 
+static GList *file_util_delete_dir_remaining_folders(GList *dlist);
+
+
+static gboolean file_util_delete_dir_empty_path(UtilityData *ud, FileData *fd, gint level)
+{
+	GList *dlist;
+	GList *flist;
+	GList *work;
+	
+	gboolean ok = TRUE;
+
+	DEBUG_1("deltree into: %s", fd->path);
+
+	level++;
+	if (level > UTILITY_DELETE_MAX_DEPTH)
+		{
+		log_printf("folder recursion depth past %d, giving up\n", UTILITY_DELETE_MAX_DEPTH);
+		// ud->fail_fd = fd
+		return 0;
+		}
+
+	if (!filelist_read_lstat(fd, &flist, &dlist))
+		{
+		// ud->fail_fd = fd
+		return 0;
+		}
+
+	if (ok)
+		{
+		if ((ok = file_data_sc_add_ci_delete(fd)))
+			{
+			ud->content_list = g_list_prepend(ud->content_list, fd);
+			}
+		// ud->fail_fd = fd
+		}
+
+	work = dlist;
+	while (work && ok)
+		{
+		FileData *lfd;
+
+		lfd = work->data;
+		work = work->next;
+
+		ok = file_util_delete_dir_empty_path(ud, lfd, level);
+
+		}
+
+	work = flist;
+	while (work && ok)
+		{
+		FileData *lfd;
+
+		lfd = work->data;
+		work = work->next;
+
+		DEBUG_1("deltree child: %s", lfd->path);
+
+		if ((ok = file_data_sc_add_ci_delete(lfd)))
+			{
+			ud->content_list = g_list_prepend(ud->content_list, lfd);
+			}
+		// ud->fail_fd = fd
+		}
+
+	filelist_free(dlist);
+	filelist_free(flist);
+
+
+	DEBUG_1("deltree done: %s", fd->path);
+
+	return ok;
+}
+
+static gboolean file_util_delete_dir_prepare(UtilityData *ud, GList *flist, GList *dlist)
+{
+	gboolean ok = TRUE;
+	GList *work;
+
+
+	work = dlist;
+	while (work && ok)
+		{
+		FileData *fd;
+
+		fd = work->data;
+		work = work->next;
+
+		ok = file_util_delete_dir_empty_path(ud, fd, 0);
+		}
+
+	work = flist;
+	if (ok && file_data_sc_add_ci_delete_list(flist))
+		{
+		ud->content_list = g_list_concat(filelist_copy(flist), ud->content_list);
+		}
+	else
+		{
+		ok = FALSE;
+		}
+
+	if (ok)
+		{
+		ok = file_data_sc_add_ci_delete(ud->dir_fd);
+		}
+	
+	if (!ok)
+		{
+		work = ud->content_list;
+		while (work)
+			{
+			FileData *fd;
+
+			fd = work->data;
+			work = work->next;
+			file_data_sc_free_ci(fd);
+			}
+		}
+	
+	return ok;
+}
+
+static void file_util_delete_dir_full(FileData *fd, GtkWidget *parent, UtilityPhase phase)
+{
+	GList *dlist;
+	GList *flist;
+	GList *rlist;
+
+	if (!isdir(fd->path)) return;
+
+	if (islink(fd->path))
+		{
+		UtilityData *ud;
+		ud = file_util_data_new(UTILITY_TYPE_DELETE_LINK);
+
+		ud->phase = phase;
+		ud->dir_fd = file_data_ref(fd);
+		ud->content_list = NULL;
+		ud->flist = NULL;
+
+		ud->parent = parent;
+	
+		ud->messages.title = _("Delete folder");
+		ud->messages.question = _("Delete symbolic link?");
+		ud->messages.desc_flist = "";
+		ud->messages.desc_dlist = "";
+		ud->messages.desc_source_fd = _("This will delete the symbolic link.\n"
+					        "The folder this link points to will not be deleted.");
+		ud->messages.fail = _("Link deletion failed");
+
+		file_util_dialog_run(ud);
+		return;
+		}
+
+	if (!access_file(fd->path, W_OK | X_OK))
+		{
+		gchar *text;
+
+		text = g_strdup_printf(_("Unable to remove folder %s\n"
+					 "Permissions do not allow writing to the folder."), fd->path);
+		file_util_warning_dialog(_("Delete failed"), text, GTK_STOCK_DIALOG_ERROR, parent);
+		g_free(text);
+
+		return;
+		}
+
+	if (!filelist_read_lstat(fd, &flist, &dlist))
+		{
+		gchar *text;
+
+		text = g_strdup_printf(_("Unable to list contents of folder %s"), fd->path);
+		file_util_warning_dialog(_("Delete failed"), text, GTK_STOCK_DIALOG_ERROR, parent);
+		g_free(text);
+
+		return;
+		}
+
+	rlist = file_util_delete_dir_remaining_folders(dlist);
+	if (rlist)
+		{
+		GenericDialog *gd;
+		GtkWidget *box;
+		gchar *text;
+
+		gd = file_util_gen_dlg(_("Folder contains subfolders"), GQ_WMCLASS, "dlg_warning",
+					parent, TRUE, NULL, NULL);
+		generic_dialog_add_button(gd, GTK_STOCK_CLOSE, NULL, NULL, TRUE);
+
+		text = g_strdup_printf(_("Unable to delete the folder:\n\n%s\n\n"
+					 "This folder contains subfolders which must be moved before it can be deleted."),
+					fd->path);
+		box = generic_dialog_add_message(gd, GTK_STOCK_DIALOG_WARNING,
+						 _("Folder contains subfolders"),
+						 text);
+		g_free(text);
+
+		box = pref_group_new(box, TRUE, _("Subfolders:"), GTK_ORIENTATION_VERTICAL);
+
+		rlist = filelist_sort_path(rlist);
+		file_util_dialog_add_list(box, rlist, FALSE);
+
+		gtk_widget_show(gd->dialog);
+		}
+	else
+		{
+		UtilityData *ud;
+		ud = file_util_data_new(UTILITY_TYPE_DELETE_FOLDER);
+
+		ud->phase = phase;
+		ud->dir_fd = file_data_ref(fd);
+		ud->content_list = NULL; /* will be filled by file_util_delete_dir_prepare */
+		ud->flist = flist = filelist_sort_path(flist);
+
+		ud->parent = parent;
+	
+		ud->messages.title = _("Delete folder");
+		ud->messages.question = _("Delete folder?");
+		ud->messages.desc_flist = _("The folder contains these files:");
+		ud->messages.desc_source_fd = _("This will delete the folder.\n"
+					        "The contents of this folder will also be deleted.");
+		ud->messages.fail = _("File deletion failed");
+		
+		if (!file_util_delete_dir_prepare(ud, flist, dlist))
+			{
+			gchar *text;
+
+			text = g_strdup_printf(_("Unable to list contents of folder %s"), fd->path);
+			file_util_warning_dialog(_("Delete failed"), text, GTK_STOCK_DIALOG_ERROR, parent);
+			g_free(text);
+			file_data_unref(ud->dir_fd);
+			file_util_data_free(ud);
+			}
+		else
+			{
+			filelist_free(dlist);
+			file_util_dialog_run(ud);
+			return;
+			}
+		}
+
+	g_list_free(rlist);
+	filelist_free(dlist);
+	filelist_free(flist);
+}
+
+static gboolean file_util_rename_dir_scan(UtilityData *ud, FileData *fd)
+{
+	GList *dlist;
+	GList *flist;
+	GList *work;
+	
+	gboolean ok = TRUE;
+
+	if (!filelist_read_lstat(fd, &flist, &dlist))
+		{
+		// ud->fail_fd = fd
+		return 0;
+		}
+
+	ud->content_list = g_list_concat(flist, ud->content_list);
+
+	work = dlist;
+	while (work && ok)
+		{
+		FileData *lfd;
+
+		lfd = work->data;
+		work = work->next;
+
+		ud->content_list = g_list_prepend(ud->content_list, file_data_ref(lfd));
+		ok = file_util_rename_dir_scan(ud, lfd);
+		}
+
+	filelist_free(dlist);
+
+	return ok;
+}
+
+static gboolean file_util_rename_dir_prepare(UtilityData *ud, const char *new_path)
+{
+	gboolean ok;
+	GList *work;
+	gint orig_len = strlen(ud->dir_fd->path);
+	
+	ok = file_util_rename_dir_scan(ud, ud->dir_fd);
+	
+	work = ud->content_list;
+	
+	while (ok && work)
+		{
+		gchar *np;
+		FileData *fd;
+
+		fd = work->data;
+		work = work->next;
+		
+		g_assert(strncmp(fd->path, ud->dir_fd->path, orig_len) == 0);
+		
+		np = g_strdup_printf("%s%s", new_path, fd->path + orig_len);
+		
+		ok = file_data_sc_add_ci_rename(fd, np);
+		
+		DEBUG_1("Dir rename: %s -> %s", fd->path, np);
+		g_free(np);
+		}
+	
+	if (ok)
+		{
+		ok = file_data_sc_add_ci_rename(ud->dir_fd, new_path);
+		}
+	
+	if (!ok)
+		{
+		work = ud->content_list;
+		while (work)
+			{
+			FileData *fd;
+
+			fd = work->data;
+			work = work->next;
+			file_data_sc_free_ci(fd);
+			}
+		}
+	return ok;
+}	
+	
+
+static void file_util_rename_dir_full(FileData *fd, const char *new_path, GtkWidget *parent, UtilityPhase phase)
+{
+	UtilityData *ud;
+
+	ud = file_util_data_new(UTILITY_TYPE_RENAME_FOLDER);
+
+	ud->phase = phase;
+
+	ud->dir_fd = file_data_ref(fd);
+	ud->flist = NULL;
+	ud->content_list = NULL;
+	ud->parent = parent;
+	
+	ud->messages.title = _("Rename");
+	ud->messages.question = _("Rename folder?");
+	ud->messages.desc_flist = _("The folder contains the following files");
+	ud->messages.desc_dlist = "";
+	ud->messages.desc_source_fd = "";
+	ud->messages.fail = _("Rename failed");
+
+	if (!file_util_rename_dir_prepare(ud, new_path))
+		{
+		file_util_warn_op_in_progress(ud->messages.fail);
+		file_util_data_free(ud);
+		return;
+		}
+
+//	ud->flist = filelist_recursive(fd);
+
+	file_util_dialog_run(ud);
+}
 
 /* FIXME: */
 void file_util_create_dir(FileData *dir_fd, GtkWidget *parent)
@@ -1403,6 +1927,7 @@
 
 gint file_util_rename_dir(FileData *source_fd, const gchar *new_path, GtkWidget *parent)
 {
+	file_util_rename_dir_full(source_fd, new_path, parent, UTILITY_PHASE_ENTERING);
 }
 
 /* full-featured entry points
@@ -1467,6 +1992,11 @@
 	file_util_start_editor_full(n, NULL, list, dest_path, parent, UTILITY_PHASE_ENTERING);
 }
 
+void file_util_delete_dir(FileData *fd, GtkWidget *parent)
+{
+	file_util_delete_dir_full(fd, parent, UTILITY_PHASE_START);
+}
+
 
 /*
  *--------------------------------------------------------------------------
@@ -1478,150 +2008,6 @@
 
 
 
-FileData *file_util_delete_dir_empty_path(FileData *fd, gint real_content, gint level)
-{
-	GList *dlist;
-	GList *flist;
-	GList *work;
-	FileData *fail = NULL;
-
-	DEBUG_1("deltree into: %s", fd->path);
-
-	level++;
-	if (level > UTILITY_DELETE_MAX_DEPTH)
-		{
-		log_printf("folder recursion depth past %d, giving up\n", UTILITY_DELETE_MAX_DEPTH);
-		return file_data_ref(fd);
-		}
-
-	if (!filelist_read_lstat(fd, &flist, &dlist)) file_data_ref(fd);
-
-	work = dlist;
-	while (work && !fail)
-		{
-		FileData *lfd;
-
-		lfd = work->data;
-		work = work->next;
-
-		fail = file_util_delete_dir_empty_path(lfd, real_content, level);
-		}
-
-	work = flist;
-	while (work && !fail)
-		{
-		FileData *lfd;
-
-		lfd = work->data;
-		work = work->next;
-
-		DEBUG_1("deltree child: %s", lfd->path);
-
-		if (real_content && !islink(lfd->path))
-			{
-			if (!file_util_unlink(lfd)) fail = file_data_ref(lfd);
-			}
-		else
-			{
-			if (!unlink_file(lfd->path)) fail = file_data_ref(lfd);
-			}
-		}
-
-	filelist_free(dlist);
-	filelist_free(flist);
-
-	if (!fail && !rmdir_utf8(fd->path))
-		{
-		fail = file_data_ref(fd);
-		}
-
-	DEBUG_1("deltree done: %s", fd->path);
-
-	return fail;
-}
-
-static void file_util_delete_dir_ok_cb(GenericDialog *gd, gpointer data)
-{
-	UtilityData *ud = data;
-
-	ud->gd = NULL;
-
-	if (ud->type == UTILITY_TYPE_DELETE_LINK)
-		{
-		if (!unlink_file(ud->source_fd->path))
-			{
-			gchar *text;
-
-			text = g_strdup_printf("Unable to remove symbolic link:\n %s", ud->source_fd->path);
-			file_util_warning_dialog(_("Delete failed"), text,
-						 GTK_STOCK_DIALOG_ERROR, NULL);
-			g_free(text);
-			}
-		}
-	else
-		{
-		FileData *fail = NULL;
-		GList *work;
-
-		work = ud->dlist;
-		while (work && !fail)
-			{
-			FileData *fd;
-
-			fd = work->data;
-			work = work->next;
-
-			fail = file_util_delete_dir_empty_path(fd, FALSE, 0);
-			}
-
-		work = ud->flist;
-		while (work && !fail)
-			{
-			FileData *fd;
-
-			fd = work->data;
-			work = work->next;
-
-			DEBUG_1("deltree unlink: %s", fd->path);
-
-			if (islink(fd->path))
-				{
-				if (!unlink_file(fd->path)) fail = file_data_ref(fd);
-				}
-			else
-				{
-				if (!file_util_unlink(fd)) fail = file_data_ref(fd);
-				}
-			}
-
-		if (!fail)
-			{
-			if (!rmdir_utf8(ud->source_fd->path)) fail = file_data_ref(ud->source_fd);
-			}
-
-		if (fail)
-			{
-			gchar *text;
-
-			text = g_strdup_printf(_("Unable to delete folder:\n\n%s"), ud->source_fd->path);
-			gd = file_util_warning_dialog(_("Delete failed"), text, GTK_STOCK_DIALOG_ERROR, NULL);
-			g_free(text);
-
-			if (fail != ud->source_fd)
-				{
-				pref_spacer(gd->vbox, PREF_PAD_GROUP);
-				text = g_strdup_printf(_("Removal of folder contents failed at this file:\n\n%s"),
-							fail->path);
-				pref_label_new(gd->vbox, text);
-				g_free(text);
-				}
-
-			file_data_unref(fail);
-			}
-		}
-
-	file_util_data_free(ud);
-}
 
 static GList *file_util_delete_dir_remaining_folders(GList *dlist)
 {
@@ -1646,140 +2032,6 @@
 	return g_list_reverse(rlist);
 }
 
-void file_util_delete_dir(FileData *fd, GtkWidget *parent)
-{
-	GList *dlist;
-	GList *flist;
-	GList *rlist;
-
-	if (!isdir(fd->path)) return;
-
-	if (islink(fd->path))
-		{
-		UtilityData *ud;
-		gchar *text;
-
-		ud = g_new0(UtilityData, 1);
-		ud->type = UTILITY_TYPE_DELETE_LINK;
-		ud->source_fd = file_data_ref(fd);
-		ud->dlist = NULL;
-		ud->flist = NULL;
-
-		ud->gd = file_util_gen_dlg(_("Delete folder"), GQ_WMCLASS, "dlg_confirm",
-					   parent, TRUE,
-					   file_util_cancel_cb, ud);
-
-		text = g_strdup_printf(_("This will delete the symbolic link:\n\n%s\n\n"
-					 "The folder this link points to will not be deleted."),
-				       fd->path);
-		generic_dialog_add_message(ud->gd, GTK_STOCK_DIALOG_QUESTION,
-					   _("Delete symbolic link to folder?"),
-					   text);
-		g_free(text);
-
-		generic_dialog_add_button(ud->gd, GTK_STOCK_DELETE, NULL, file_util_delete_dir_ok_cb, TRUE);
-
-		gtk_widget_show(ud->gd->dialog);
-
-		return;
-		}
-
-	if (!access_file(fd->path, W_OK | X_OK))
-		{
-		gchar *text;
-
-		text = g_strdup_printf(_("Unable to remove folder %s\n"
-					 "Permissions do not allow writing to the folder."), fd->path);
-		file_util_warning_dialog(_("Delete failed"), text, GTK_STOCK_DIALOG_ERROR, parent);
-		g_free(text);
-
-		return;
-		}
-
-	if (!filelist_read_lstat(fd, &flist, &dlist))
-		{
-		gchar *text;
-
-		text = g_strdup_printf(_("Unable to list contents of folder %s"), fd->path);
-		file_util_warning_dialog(_("Delete failed"), text, GTK_STOCK_DIALOG_ERROR, parent);
-		g_free(text);
-
-		return;
-		}
-
-	rlist = file_util_delete_dir_remaining_folders(dlist);
-	if (rlist)
-		{
-		GenericDialog *gd;
-		GtkWidget *box;
-		gchar *text;
-
-		gd = file_util_gen_dlg(_("Folder contains subfolders"), GQ_WMCLASS, "dlg_warning",
-					parent, TRUE, NULL, NULL);
-		generic_dialog_add_button(gd, GTK_STOCK_CLOSE, NULL, NULL, TRUE);
-
-		text = g_strdup_printf(_("Unable to delete the folder:\n\n%s\n\n"
-					 "This folder contains subfolders which must be moved before it can be deleted."),
-					fd->path);
-		box = generic_dialog_add_message(gd, GTK_STOCK_DIALOG_WARNING,
-						 _("Folder contains subfolders"),
-						 text);
-		g_free(text);
-
-		box = pref_group_new(box, TRUE, _("Subfolders:"), GTK_ORIENTATION_VERTICAL);
-
-		rlist = filelist_sort_path(rlist);
-		file_util_dialog_add_list(box, rlist, FALSE);
-
-		gtk_widget_show(gd->dialog);
-		}
-	else
-		{
-		UtilityData *ud;
-		GtkWidget *box;
-		GtkWidget *view;
-		GtkTreeSelection *selection;
-		gchar *text;
-
-		ud = g_new0(UtilityData, 1);
-		ud->type = UTILITY_TYPE_DELETE_FOLDER;
-		ud->source_fd = file_data_ref(fd);
-		ud->dlist = dlist;
-		dlist = NULL;
-		ud->flist = filelist_sort_path(flist);
-		flist = NULL;
-
-		ud->gd = file_util_gen_dlg(_("Delete folder"), GQ_WMCLASS, "dlg_confirm",
-					   parent, TRUE,  file_util_cancel_cb, ud);
-		generic_dialog_add_button(ud->gd, GTK_STOCK_DELETE, NULL, file_util_delete_dir_ok_cb, TRUE);
-
-		text = g_strdup_printf(_("This will delete the folder:\n\n%s\n\n"
-					 "The contents of this folder will also be deleted."),
-					fd->path);
-		box = generic_dialog_add_message(ud->gd, GTK_STOCK_DIALOG_QUESTION,
-						 _("Delete folder?"),
-						 text);
-		g_free(text);
-
-		box = pref_group_new(box, TRUE, _("Contents:"), GTK_ORIENTATION_HORIZONTAL);
-
-		view = file_util_dialog_add_list(box, ud->flist, FALSE);
-		selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
-		gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
-		gtk_tree_selection_set_select_function(selection, file_util_preview_cb, ud, NULL);
-
-		generic_dialog_add_image(ud->gd, box, NULL, NULL, NULL, NULL, FALSE);
-
-		box_append_safe_delete_status(ud->gd);
-
-		gtk_widget_show(ud->gd->dialog);
-		}
-
-	g_list_free(rlist);
-	filelist_free(dlist);
-	filelist_free(flist);
-}
-
 
 void file_util_copy_path_to_clipboard(FileData *fd)
 {