[file-roller] allow the user to cancel addition and deletion of files



commit 815ad36da74abdc9e4948500af402e3f7d67e3ba
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Mon Jun 18 17:37:12 2012 +0200

    allow the user to cancel addition and deletion of files
    
    to make these operations stoppable the archive is copied in a
    temporary directory and if the user cancel the operation the
    temporary directory is deleted and the original file is preserved.

 src/fr-archive.c     |  166 +++++++++++++++++++++++++++++++++++++++-----------
 src/fr-archive.h     |    3 -
 src/fr-command-tar.c |    6 +--
 src/fr-window.c      |   12 ----
 4 files changed, 132 insertions(+), 55 deletions(-)
---
diff --git a/src/fr-archive.c b/src/fr-archive.c
index 3e5bdca..f0fbcea 100644
--- a/src/fr-archive.c
+++ b/src/fr-archive.c
@@ -114,9 +114,6 @@ struct _FrArchivePrivData {
 							     * fr_archive_load is invoked, used
 							     * in batch mode. */
 	gpointer             fake_load_data;
-	FakeLoadFunc         add_is_stoppable_func;         /* Returns whether the add operation is
-							     * stoppable. */
-	gpointer             add_is_stoppable_data;
 	GCancellable        *cancellable;
 	char                *temp_dir;
 	gboolean             continue_adding_dropped_items;
@@ -338,20 +335,10 @@ fr_archive_action_completed (FrArchive       *archive,
 
 
 static gboolean
-fr_archive_add_is_stoppable (FrArchive *archive)
-{
-	if (archive->priv->add_is_stoppable_func != NULL)
-		return (*archive->priv->add_is_stoppable_func) (archive, archive->priv->add_is_stoppable_data);
-	else
-		return FALSE;
-}
-
-
-static gboolean
 archive_sticky_only_cb (FrProcess *process,
 			FrArchive *archive)
 {
-	fr_archive_stoppable (archive, fr_archive_add_is_stoppable (archive));
+	fr_archive_stoppable (archive, FALSE);
 	return TRUE;
 }
 
@@ -369,8 +356,6 @@ fr_archive_init (FrArchive *archive)
 	archive->priv = g_new0 (FrArchivePrivData, 1);
 	archive->priv->fake_load_func = NULL;
 	archive->priv->fake_load_data = NULL;
-	archive->priv->add_is_stoppable_func = NULL;
-	archive->priv->add_is_stoppable_data = NULL;
 
 	archive->priv->extraction_destination = NULL;
 	archive->priv->temp_extraction_dir = NULL;
@@ -1448,16 +1433,6 @@ newer_files_only (FrArchive  *archive,
 }
 
 
-void
-fr_archive_set_add_is_stoppable_func (FrArchive     *archive,
-				      FakeLoadFunc   func,
-				      gpointer       data)
-{
-	archive->priv->add_is_stoppable_func = func;
-	archive->priv->add_is_stoppable_data = data;
-}
-
-
 static gboolean
 save_list_to_temp_file (GList   *file_list,
 		        char   **list_dir,
@@ -1565,6 +1540,9 @@ fr_archive_add (FrArchive     *archive,
 	gboolean  base_dir_created = FALSE;
 	GList    *scan;
 	char     *tmp_base_dir = NULL;
+	char     *tmp_archive_dir = NULL;
+	char     *archive_filename = NULL;
+	char     *tmp_archive_filename = NULL;
 	gboolean  error_occurred = FALSE;
 
 	if (file_list == NULL)
@@ -1574,14 +1552,13 @@ fr_archive_add (FrArchive     *archive,
 		return;
 
 	g_object_set (archive->command,
-		      "file", archive->local_copy,
 		      "password", password,
 		      "encrypt_header", encrypt_header,
 		      "compression", compression,
 		      "volume_size", volume_size,
 		      NULL);
 
-	fr_archive_stoppable (archive, fr_archive_add_is_stoppable (archive));
+	fr_archive_stoppable (archive, TRUE);
 
 	/* dest_dir is the destination folder inside the archive */
 
@@ -1630,7 +1607,42 @@ fr_archive_add (FrArchive     *archive,
 		return;
 	}
 
-	archive->command->creating_archive = ! g_file_query_exists (archive->local_copy, NULL);
+	archive->command->creating_archive = ! g_file_query_exists (archive->local_copy, archive->priv->cancellable);
+
+	/* create the new archive in a temporary sub-directory, this allows
+	 * to cancel the operation without losing the original archive and
+	 * removing possible temporary files created by the command. */
+
+	{
+		GFile *local_copy_parent;
+		char  *archive_dir;
+		GFile *tmp_file;
+
+		/* create the new archive in a sub-folder of the original
+		 * archive this way the 'mv' command is fast. */
+
+		local_copy_parent = g_file_get_parent (archive->local_copy);
+		archive_dir = g_file_get_path (local_copy_parent);
+		tmp_archive_dir = get_temp_work_dir (archive_dir);
+		archive_filename = g_file_get_path (archive->local_copy);
+		tmp_archive_filename = g_build_filename (tmp_archive_dir, file_name_from_path (archive_filename), NULL);
+		tmp_file = g_file_new_for_path (tmp_archive_filename);
+		g_object_set (archive->command, "file", tmp_file, NULL);
+
+		if (! archive->command->creating_archive) {
+			/* copy the original archive to the new position */
+
+			fr_process_begin_command (archive->process, "cp");
+			fr_process_add_arg (archive->process, "-f");
+			fr_process_add_arg (archive->process, archive_filename);
+			fr_process_add_arg (archive->process, tmp_archive_filename);
+			fr_process_end_command (archive->process);
+		}
+
+		g_object_unref (tmp_file);
+		g_free (archive_dir);
+		g_object_unref (local_copy_parent);
+	}
 
 	fr_command_uncompress (archive->command);
 
@@ -1731,7 +1743,26 @@ fr_archive_add (FrArchive     *archive,
 	if (! error_occurred) {
 		fr_command_recompress (archive->command);
 
-		if (base_dir_created) { /* remove the temp dir */
+		/* move the new archive to the original position */
+
+		fr_process_begin_command (archive->process, "mv");
+		fr_process_add_arg (archive->process, "-f");
+		fr_process_add_arg (archive->process, tmp_archive_filename);
+		fr_process_add_arg (archive->process, archive_filename);
+		fr_process_end_command (archive->process);
+
+		/* remove the temp sub-directory */
+
+		fr_process_begin_command (archive->process, "rm");
+		fr_process_set_working_dir (archive->process, g_get_tmp_dir());
+		fr_process_set_sticky (archive->process, TRUE);
+		fr_process_add_arg (archive->process, "-rf");
+		fr_process_add_arg (archive->process, tmp_archive_dir);
+		fr_process_end_command (archive->process);
+
+		/* remove the base dir */
+
+		if (base_dir_created) {
 			fr_process_begin_command (archive->process, "rm");
 			fr_process_set_working_dir (archive->process, g_get_tmp_dir());
 			fr_process_set_sticky (archive->process, TRUE);
@@ -1741,6 +1772,9 @@ fr_archive_add (FrArchive     *archive,
 		}
 	}
 
+	g_free (tmp_archive_filename);
+	g_free (archive_filename);
+	g_free (tmp_archive_dir);
 	g_free (tmp_base_dir);
 }
 
@@ -2354,6 +2388,7 @@ add_dropped_items (DroppedItemsData *data)
 	 * files without path info. FIXME: doesn't work with remote files. */
 
 	fr_archive_stoppable (archive, FALSE);
+	archive->command->creating_archive = ! g_file_query_exists (archive->local_copy, archive->priv->cancellable);
 	g_object_set (archive->command,
 		      "file", archive->local_copy,
 		      "password", data->password,
@@ -2581,19 +2616,80 @@ fr_archive_remove (FrArchive     *archive,
 		   GList         *file_list,
 		   FrCompression  compression)
 {
+	char *tmp_archive_dir = NULL;
+	char *archive_filename = NULL;
+	char *tmp_archive_filename = NULL;
+
 	g_return_if_fail (archive != NULL);
 
 	if (archive->read_only)
 		return;
 
-	fr_archive_stoppable (archive, FALSE);
-	g_object_set (archive->command,
-		      "file", archive->local_copy,
-		      "compression", compression,
-		      NULL);
+	fr_archive_stoppable (archive, TRUE);
+	archive->command->creating_archive = FALSE;
+	g_object_set (archive->command, "compression", compression, NULL);
+
+	/* create the new archive in a temporary sub-directory, this allows
+	 * to cancel the operation without losing the original archive and
+	 * removing possible temporary files created by the command. */
+
+	{
+		GFile *local_copy_parent;
+		char  *archive_dir;
+		GFile *tmp_file;
+
+		/* create the new archive in a sub-folder of the original
+		 * archive this way the 'mv' command is fast. */
+
+		local_copy_parent = g_file_get_parent (archive->local_copy);
+		archive_dir = g_file_get_path (local_copy_parent);
+		tmp_archive_dir = get_temp_work_dir (archive_dir);
+		archive_filename = g_file_get_path (archive->local_copy);
+		tmp_archive_filename = g_build_filename (tmp_archive_dir, file_name_from_path (archive_filename), NULL);
+		tmp_file = g_file_new_for_path (tmp_archive_filename);
+		g_object_set (archive->command, "file", tmp_file, NULL);
+
+		if (! archive->command->creating_archive) {
+			/* copy the original archive to the new position */
+
+			fr_process_begin_command (archive->process, "cp");
+			fr_process_add_arg (archive->process, "-f");
+			fr_process_add_arg (archive->process, archive_filename);
+			fr_process_add_arg (archive->process, tmp_archive_filename);
+			fr_process_end_command (archive->process);
+		}
+
+		g_object_unref (tmp_file);
+		g_free (archive_dir);
+		g_object_unref (local_copy_parent);
+	}
+
+	/* uncompress, delete and recompress */
+
 	fr_command_uncompress (archive->command);
 	delete_from_archive (archive, file_list);
 	fr_command_recompress (archive->command);
+
+	/* move the new archive to the original position */
+
+	fr_process_begin_command (archive->process, "mv");
+	fr_process_add_arg (archive->process, "-f");
+	fr_process_add_arg (archive->process, tmp_archive_filename);
+	fr_process_add_arg (archive->process, archive_filename);
+	fr_process_end_command (archive->process);
+
+	/* remove the temp sub-directory */
+
+	fr_process_begin_command (archive->process, "rm");
+	fr_process_set_working_dir (archive->process, g_get_tmp_dir());
+	fr_process_set_sticky (archive->process, TRUE);
+	fr_process_add_arg (archive->process, "-rf");
+	fr_process_add_arg (archive->process, tmp_archive_dir);
+	fr_process_end_command (archive->process);
+
+	g_free (tmp_archive_filename);
+	g_free (archive_filename);
+	g_free (tmp_archive_dir);
 }
 
 
diff --git a/src/fr-archive.h b/src/fr-archive.h
index a934277..41e23cf 100644
--- a/src/fr-archive.h
+++ b/src/fr-archive.h
@@ -93,9 +93,6 @@ void        fr_archive_set_fake_load_func        (FrArchive       *archive,
 						  FakeLoadFunc     func,
 						  gpointer         data);
 gboolean    fr_archive_fake_load                 (FrArchive       *archive);
-void        fr_archive_set_add_is_stoppable_func (FrArchive       *archive,
-						  FakeLoadFunc     func,
-						  gpointer         data);
 void        fr_archive_stoppable                 (FrArchive       *archive,
 						  gboolean         stoppable);
 void        fr_archive_stop	                 (FrArchive       *archive);
diff --git a/src/fr-command-tar.c b/src/fr-command-tar.c
index 97ae8e2..4522bf4 100644
--- a/src/fr-command-tar.c
+++ b/src/fr-command-tar.c
@@ -863,11 +863,7 @@ fr_command_tar_uncompress (FrCommand *comm)
 		c_tar->uncomp_filename = NULL;
 	}
 
-	{
-		char *uri = g_filename_to_uri (comm->filename, NULL, NULL);
-		archive_exists = uri_exists (uri);
-		g_free (uri);
-	}
+	archive_exists = ! comm->creating_archive;
 
 	c_tar->name_modified = ! is_mime_type (comm->mime_type, "application/x-tar");
 	if (c_tar->name_modified) {
diff --git a/src/fr-window.c b/src/fr-window.c
index dfaef47..205ea60 100644
--- a/src/fr-window.c
+++ b/src/fr-window.c
@@ -5151,15 +5151,6 @@ fr_window_fake_load (FrArchive *archive,
 }
 
 
-static gboolean
-fr_window_add_is_stoppable (FrArchive *archive,
-			    gpointer   data)
-{
-	FrWindow *window = data;
-	return window->priv->archive_new;
-}
-
-
 static void
 menu_item_select_cb (GtkMenuItem *proxy,
 		     FrWindow    *window)
@@ -5527,9 +5518,6 @@ fr_window_construct (FrWindow *window)
 	fr_archive_set_fake_load_func (window->archive,
 				       fr_window_fake_load,
 				       window);
-	fr_archive_set_add_is_stoppable_func (window->archive,
-					      fr_window_add_is_stoppable,
-					      window);
 
 	window->priv->sort_method = g_settings_get_enum (window->priv->settings_listing, PREF_LISTING_SORT_METHOD);
 	window->priv->sort_type = g_settings_get_enum (window->priv->settings_listing, PREF_LISTING_SORT_TYPE);



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