[file-roller] extract dialog: always ask whether to overwrite



commit fe71357aa128d029b6ca4a9493b8a408c8aaf017
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Tue Aug 7 09:17:40 2012 +0200

    extract dialog: always ask whether to overwrite
    
    Removed the overwrite option in the extract dialog, always ask whether to
    overwrite a file.  This makes obvious to the user that data overwriting is
    going to happen, minimizing risks of important data loss.

 data/org.gnome.FileRoller.gschema.xml.in |   38 +++----
 src/dlg-extract.c                        |   36 +------
 src/fr-window.c                          |  176 ++++++++++++++++++++----------
 src/preferences.h                        |    1 -
 4 files changed, 137 insertions(+), 114 deletions(-)
---
diff --git a/data/org.gnome.FileRoller.gschema.xml.in b/data/org.gnome.FileRoller.gschema.xml.in
index 06484cb..049fcaf 100644
--- a/data/org.gnome.FileRoller.gschema.xml.in
+++ b/data/org.gnome.FileRoller.gschema.xml.in
@@ -1,19 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
   File-Roller
- 
+
   Copyright  2010 Free Software Foundation, Inc.
- 
+
   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, see <http://www.gnu.org/licenses/>.
 -->
@@ -26,31 +26,31 @@
     <value nick="time" value="3"/>
     <value nick="path" value="4"/>
   </enum>
-  
+
   <enum id="org.gnome.FileRoller.SortType">
     <value nick="ascending" value="0"/>
     <value nick="descending" value="1"/>
   </enum>
-  
+
   <enum id="org.gnome.FileRoller.ListMode">
     <value nick="all-files" value="0"/>
     <value nick="as-folder" value="1"/>
   </enum>
-  
+
   <enum id="org.gnome.FileRoller.CompressionLevel">
     <value nick="very-fast" value="0"/>
     <value nick="fast" value="1"/>
     <value nick="normal" value="2"/>
     <value nick="maximum" value="3"/>
   </enum>
-  
+
   <schema id="org.gnome.FileRoller" path="/org/gnome/file-roller/">
     <child name="listing" schema="org.gnome.FileRoller.Listing"/>
     <child name="ui" schema="org.gnome.FileRoller.UI"/>
     <child name="general" schema="org.gnome.FileRoller.General"/>
     <child name="dialogs" schema="org.gnome.FileRoller.Dialogs"/>
   </schema>
-  
+
   <schema id="org.gnome.FileRoller.Listing" path="/org/gnome/file-roller/listing/" gettext-domain="file-roller">
     <key name="sort-method" enum="org.gnome.FileRoller.SortMethod">
       <default>'name'</default>
@@ -98,7 +98,7 @@
       <_description>The default width of the name column in the file list.</_description>
     </key>
   </schema>
-  
+
   <schema id="org.gnome.FileRoller.UI" path="/org/gnome/file-roller/ui/" gettext-domain="file-roller">
     <key name="history-len" type="i">
       <default>5</default>
@@ -130,7 +130,7 @@
       <_description>Whether to display the folders pane.</_description>
     </key>
   </schema>
-  
+
   <schema id="org.gnome.FileRoller.General" path="/org/gnome/file-roller/general/" gettext-domain="file-roller">
     <key name="editors" type="as">
       <default>[]</default>
@@ -148,19 +148,15 @@
       <_description>Whether to encrypt the archive header.  If the header is encrypted the password will be required to list the archive content as well.</_description>
     </key>
   </schema>
-  
+
   <schema id="org.gnome.FileRoller.Dialogs" path="/org/gnome/file-roller/dialogs/">
     <child name="extract" schema="org.gnome.FileRoller.Dialogs.Extract"/>
     <child name="add" schema="org.gnome.FileRoller.Dialogs.Add"/>
     <child name="batch-add" schema="org.gnome.FileRoller.Dialogs.BatchAdd"/>
     <child name="last-output" schema="org.gnome.FileRoller.Dialogs.LastOutput"/>
   </schema>
-  
+
   <schema id="org.gnome.FileRoller.Dialogs.Extract" path="/org/gnome/file-roller/dialogs/extract/" gettext-domain="file-roller">
-    <key name="overwrite" type="b">
-      <default>true</default>
-      <_summary>Overwrite existing files</_summary>
-    </key>
     <key name="skip-newer" type="b">
       <default>false</default>
       <_summary>Do not overwrite newer files</_summary>
@@ -170,7 +166,7 @@
       <_summary>Recreate the folders stored in the archive</_summary>
     </key>
   </schema>
-  
+
   <schema id="org.gnome.FileRoller.Dialogs.Add" path="/org/gnome/file-roller/dialogs/add/" gettext-domain="file-roller">
     <key name="current-folder" type="s">
       <default>''</default>
@@ -197,7 +193,7 @@
       <default>false</default>
     </key>
   </schema>
-  
+
   <schema id="org.gnome.FileRoller.Dialogs.BatchAdd" path="/org/gnome/file-roller/dialogs/batch-add/" gettext-domain="file-roller">
     <key name="default-extension" type="s">
       <default>'.tar.gz'</default>
@@ -211,7 +207,7 @@
       <_description>The default size for volumes.</_description>
     </key>
   </schema>
-  
+
   <schema id="org.gnome.FileRoller.Dialogs.LastOutput" path="/org/gnome/file-roller/dialogs/last-output/" gettext-domain="file-roller">
     <key name="width" type="i">
       <default>-1</default>
@@ -220,5 +216,5 @@
       <default>-1</default>
     </key>
   </schema>
-  
+
 </schemalist>
diff --git a/src/dlg-extract.c b/src/dlg-extract.c
index 5fabcb3..4946b94 100644
--- a/src/dlg-extract.c
+++ b/src/dlg-extract.c
@@ -75,7 +75,6 @@ extract_cb (GtkWidget   *w,
 	FrWindow   *window = data->window;
 	gboolean    do_not_extract = FALSE;
 	GFile      *destination;
-	gboolean    overwrite;
 	gboolean    skip_newer;
 	gboolean    selected_files;
 	gboolean    pattern_files;
@@ -187,11 +186,9 @@ extract_cb (GtkWidget   *w,
 
 	fr_window_set_extract_default_dir (window, destination, TRUE);
 
-	overwrite = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->e_overwrite_checkbutton));
 	skip_newer = ! gtk_toggle_button_get_inconsistent (GTK_TOGGLE_BUTTON (data->e_not_newer_checkbutton)) && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->e_not_newer_checkbutton));
 	junk_paths = ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->e_recreate_dir_checkbutton));
 
-	g_settings_set_boolean (data->settings, PREF_EXTRACT_OVERWRITE, overwrite);
 	if (! gtk_toggle_button_get_inconsistent (GTK_TOGGLE_BUTTON (data->e_not_newer_checkbutton)))
 		g_settings_set_boolean (data->settings, PREF_EXTRACT_SKIP_NEWER, skip_newer);
 	g_settings_set_boolean (data->settings, PREF_EXTRACT_RECREATE_FOLDERS, ! junk_paths);
@@ -237,7 +234,7 @@ extract_cb (GtkWidget   *w,
 				   destination,
 				   base_dir,
 				   skip_newer,
-				   overwrite ? FR_OVERWRITE_YES : FR_OVERWRITE_NO,
+				   FR_OVERWRITE_ASK,
 				   junk_paths,
 				   TRUE);
 
@@ -276,16 +273,6 @@ files_entry_changed_cb (GtkWidget  *widget,
 
 
 static void
-overwrite_toggled_cb (GtkToggleButton *button,
-		      DialogData      *data)
-{
-	gboolean active = gtk_toggle_button_get_active (button);
-	gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (data->e_not_newer_checkbutton), !active);
-	gtk_widget_set_sensitive (data->e_not_newer_checkbutton, active);
-}
-
-
-static void
 set_bold_label (GtkWidget  *label,
 		const char *label_txt)
 {
@@ -393,10 +380,6 @@ create_extra_widget (DialogData *data)
 	gtk_box_pack_start (GTK_BOX (vbox15), data->e_recreate_dir_checkbutton, FALSE, FALSE, 0);
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->e_recreate_dir_checkbutton), TRUE);
 
-	data->e_overwrite_checkbutton = gtk_check_button_new_with_mnemonic (_("Over_write existing files"));
-	gtk_box_pack_start (GTK_BOX (vbox15), data->e_overwrite_checkbutton, FALSE, FALSE, 0);
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->e_overwrite_checkbutton), TRUE);
-
 	data->e_not_newer_checkbutton = gtk_check_button_new_with_mnemonic (_("Do not e_xtract older files"));
 	gtk_box_pack_start (GTK_BOX (vbox15), data->e_not_newer_checkbutton, FALSE, FALSE, 0);
 
@@ -430,12 +413,11 @@ dlg_extract__common (FrWindow *window,
 					     NULL);
 
 	gtk_window_set_default_size (GTK_WINDOW (file_sel), 530, 510);
-
 	gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (file_sel), FALSE);
 	gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (file_sel), FALSE);
-	gtk_dialog_set_default_response (GTK_DIALOG (file_sel), GTK_RESPONSE_OK);
-
+	gtk_file_chooser_set_create_folders (GTK_FILE_CHOOSER (file_sel), TRUE);
 	gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (file_sel), create_extra_widget (data));
+	gtk_dialog_set_default_response (GTK_DIALOG (file_sel), GTK_RESPONSE_OK);
 
 	/* Set widgets data. */
 
@@ -448,13 +430,7 @@ dlg_extract__common (FrWindow *window,
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->e_all_radiobutton), TRUE);
 	}
 
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->e_overwrite_checkbutton), g_settings_get_boolean (data->settings, PREF_EXTRACT_OVERWRITE));
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->e_not_newer_checkbutton), g_settings_get_boolean (data->settings, PREF_EXTRACT_SKIP_NEWER));
-	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->e_overwrite_checkbutton))) {
-		gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (data->e_not_newer_checkbutton), TRUE);
-		gtk_widget_set_sensitive (data->e_not_newer_checkbutton, FALSE);
-	}
-
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->e_recreate_dir_checkbutton), g_settings_get_boolean (data->settings, PREF_EXTRACT_RECREATE_FOLDERS));
 
 	/* Set the signals handlers. */
@@ -463,16 +439,10 @@ dlg_extract__common (FrWindow *window,
 			  "destroy",
 			  G_CALLBACK (destroy_cb),
 			  data);
-
 	g_signal_connect (G_OBJECT (file_sel),
 			  "response",
 			  G_CALLBACK (file_sel_response_cb),
 			  data);
-
-	g_signal_connect (G_OBJECT (data->e_overwrite_checkbutton),
-			  "toggled",
-			  G_CALLBACK (overwrite_toggled_cb),
-			  data);
 	g_signal_connect (G_OBJECT (data->e_files_entry),
 			  "changed",
 			  G_CALLBACK (files_entry_changed_cb),
diff --git a/src/fr-window.c b/src/fr-window.c
index 68a162e..098192c 100644
--- a/src/fr-window.c
+++ b/src/fr-window.c
@@ -3503,6 +3503,24 @@ fr_window_get_file_list_pattern (FrWindow    *window,
 }
 
 
+static GList *
+fr_window_get_file_list (FrWindow *window)
+{
+	GList *list;
+	int    i;
+
+	g_return_val_if_fail (window != NULL, NULL);
+
+	list = NULL;
+	for (i = 0; i < window->archive->files->len; i++) {
+		FileData *fd = g_ptr_array_index (window->archive->files, i);
+		list = g_list_prepend (list, g_strdup (fd->original_path));
+	}
+
+	return g_list_reverse (list);
+}
+
+
 int
 fr_window_get_n_selected_files (FrWindow *window)
 {
@@ -6618,6 +6636,7 @@ typedef struct {
 	FrWindow    *window;
 	ExtractData *edata;
 	GList       *current_file;
+	gboolean     extract_all;
 } OverwriteData;
 
 
@@ -6702,9 +6721,11 @@ overwrite_dialog_response_cb (GtkDialog *dialog,
 		{
 			/* remove the file from the list to extract */
 			GList *next = odata->current_file->next;
+
 			odata->edata->file_list = g_list_remove_link (odata->edata->file_list, odata->current_file);
 			_g_string_list_free (odata->current_file);
 			odata->current_file = next;
+			odata->extract_all = FALSE;
 		}
 		break;
 
@@ -6730,81 +6751,114 @@ overwrite_dialog_response_cb (GtkDialog *dialog,
 
 
 static void
-_fr_window_ask_overwrite_dialog (OverwriteData *odata)
+query_info_ready_for_overwrite_dialog_cb (GObject      *source_object,
+					  GAsyncResult *result,
+					  gpointer      user_data)
 {
-	gboolean do_not_extract = FALSE;
+	OverwriteData *odata = user_data;
+	GFile         *destination = G_FILE (source_object);
+	GFileInfo     *info;
+	GFileType      file_type;
 
-	while ((odata->edata->overwrite == FR_OVERWRITE_ASK) && (odata->current_file != NULL)) {
+	info = g_file_query_info_finish (destination, result, NULL);
+	if (info == NULL) {
+		odata->current_file = odata->current_file->next;
+		_fr_window_ask_overwrite_dialog (odata);
+		return;
+	}
+
+	file_type = g_file_info_get_file_type (info);
+	if ((file_type != G_FILE_TYPE_UNKNOWN) && (file_type != G_FILE_TYPE_DIRECTORY)) {
+		char      *msg;
+		GFile     *parent;
+		char      *parent_name;
+		char      *details;
+		GtkWidget *d;
+
+		msg = g_strdup_printf (_("Replace file \"%s\"?"), g_file_info_get_display_name (info));
+		parent = g_file_get_parent (destination);
+		parent_name = g_file_get_parse_name (parent);
+		details = g_strdup_printf (_("Another file with the same name already exists in \"%s\"."), parent_name);
+		d = _gtk_message_dialog_new (GTK_WINDOW (odata->window),
+					     GTK_DIALOG_MODAL,
+					     GTK_STOCK_DIALOG_QUESTION,
+					     msg,
+					     details,
+					     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+					     _("Replace _All"), _FR_RESPONSE_OVERWRITE_YES_ALL,
+					     _("_Skip"), _FR_RESPONSE_OVERWRITE_NO,
+					     _("_Replace"), _FR_RESPONSE_OVERWRITE_YES,
+					     NULL);
+		gtk_dialog_set_default_response (GTK_DIALOG (d), _FR_RESPONSE_OVERWRITE_YES);
+		g_signal_connect (d,
+				  "response",
+				  G_CALLBACK (overwrite_dialog_response_cb),
+				  odata);
+		gtk_widget_show (d);
+
+		g_free (parent_name);
+		g_object_unref (parent);
+		g_object_unref (info);
+
+		return;
+	}
+
+	g_object_unref (info);
+
+	odata->current_file = odata->current_file->next;
+	_fr_window_ask_overwrite_dialog (odata);
+}
+
+
+static void
+_fr_window_ask_overwrite_dialog (OverwriteData *odata)
+{
+	if ((odata->edata->overwrite == FR_OVERWRITE_ASK) && (odata->current_file != NULL)) {
 		const char *base_name;
 		GFile      *destination;
-		GFileInfo  *info;
-		GFileType   file_type;
 
 		base_name = _g_path_get_relative_basename ((char *) odata->current_file->data, odata->edata->base_dir, odata->edata->junk_paths);
 		destination = g_file_get_child (odata->edata->destination, base_name);
-		info = g_file_query_info (destination,
-					  G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
-					  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
-					  NULL,
-					  NULL);
-
-		if (info == NULL) {
-			g_object_unref (destination);
-			odata->current_file = odata->current_file->next;
-			continue;
-		}
+		g_file_query_info_async (destination,
+					 G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+					 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+					 G_PRIORITY_DEFAULT,
+					 odata->window->priv->cancellable,
+					 query_info_ready_for_overwrite_dialog_cb,
+					 odata);
 
-		file_type = g_file_info_get_file_type (info);
-		if ((file_type != G_FILE_TYPE_UNKNOWN) && (file_type != G_FILE_TYPE_DIRECTORY)) {
-			char      *msg;
-			GFile     *parent;
-			char      *parent_name;
-			char      *details;
-			GtkWidget *d;
+		g_object_unref (destination);
 
-			msg = g_strdup_printf (_("Replace file \"%s\"?"), g_file_info_get_display_name (info));
-			parent = g_file_get_parent (destination);
-			parent_name = g_file_get_parse_name (parent);
-			details = g_strdup_printf (_("Another file with the same name already exists in \"%s\"."), parent_name);
-			d = _gtk_message_dialog_new (GTK_WINDOW (odata->window),
-						     GTK_DIALOG_MODAL,
-						     GTK_STOCK_DIALOG_QUESTION,
-						     msg,
-						     details,
-						     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-						     _("Replace _All"), _FR_RESPONSE_OVERWRITE_YES_ALL,
-						     _("_Skip"), _FR_RESPONSE_OVERWRITE_NO,
-						     _("_Replace"), _FR_RESPONSE_OVERWRITE_YES,
-						     NULL);
-			gtk_dialog_set_default_response (GTK_DIALOG (d), _FR_RESPONSE_OVERWRITE_YES);
-			g_signal_connect (d,
-					  "response",
-					  G_CALLBACK (overwrite_dialog_response_cb),
-					  odata);
-			gtk_widget_show (d);
-
-			g_free (parent_name);
-			g_object_unref (parent);
-			g_object_unref (info);
-			g_object_unref (destination);
+		return;
+	}
 
-			return;
+	if (odata->edata->file_list != NULL) {
+		/* speed optimization: passing NULL when extracting all the
+		 * files is faster if the command supports the
+		 * propCanExtractAll property. */
+		if (odata->extract_all) {
+			_g_string_list_free (odata->edata->file_list);
+			odata->edata->file_list = NULL;
 		}
-		else
-			odata->current_file = odata->current_file->next;
-
-		g_object_unref (info);
-		g_object_unref (destination);
+		odata->edata->overwrite = FR_OVERWRITE_YES;
+		_fr_window_archive_extract_from_edata (odata->window, odata->edata);
 	}
+	else {
+		GtkWidget *d;
+
+		d = _gtk_message_dialog_new (GTK_WINDOW (odata->window),
+					     0,
+					     GTK_STOCK_DIALOG_WARNING,
+					     _("Extraction not performed"),
+					     NULL,
+					     GTK_STOCK_OK, GTK_RESPONSE_OK,
+					     NULL);
+		gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_OK);
+		fr_window_show_error_dialog (odata->window, d, GTK_WINDOW (odata->window), _("Extraction not performed"));
 
-	if (do_not_extract) {
 		fr_window_stop_batch (odata->window);
-		g_free (odata);
-		return;
 	}
 
-	odata->edata->overwrite = FR_OVERWRITE_YES;
-	_fr_window_archive_extract_from_edata (odata->window, odata->edata);
 	g_free (odata);
 }
 
@@ -6967,7 +7021,11 @@ fr_window_archive_extract (FrWindow    *window,
 		odata = g_new0 (OverwriteData, 1);
 		odata->window = window;
 		odata->edata = edata;
+		odata->extract_all = (edata->file_list == NULL) || (g_list_length (edata->file_list) == window->archive->files->len);
+		if (edata->file_list == NULL)
+			edata->file_list = fr_window_get_file_list (window);
 		odata->current_file = odata->edata->file_list;
+
 		_fr_window_ask_overwrite_dialog (odata);
 	}
 	else
diff --git a/src/preferences.h b/src/preferences.h
index 93d271d..1ae3195 100644
--- a/src/preferences.h
+++ b/src/preferences.h
@@ -58,7 +58,6 @@
 #define PREF_GENERAL_COMPRESSION_LEVEL    "compression-level"
 #define PREF_GENERAL_ENCRYPT_HEADER       "encrypt-header"
 
-#define PREF_EXTRACT_OVERWRITE            "overwrite"
 #define PREF_EXTRACT_SKIP_NEWER           "skip-newer"
 #define PREF_EXTRACT_RECREATE_FOLDERS     "recreate-folders"
 



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