summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dlg-extract.c2
-rw-r--r--src/fr-window.c256
-rw-r--r--src/fr-window.h2
-rw-r--r--src/typedefs.h6
4 files changed, 225 insertions, 41 deletions
diff --git a/src/dlg-extract.c b/src/dlg-extract.c
index b4c5228..9cdc272 100644
--- a/src/dlg-extract.c
+++ b/src/dlg-extract.c
@@ -237,7 +237,7 @@ extract_cb (GtkWidget *w,
extract_to_dir,
base_dir,
skip_newer,
- overwrite,
+ overwrite ? FR_OVERWRITE_YES : FR_OVERWRITE_NO,
junk_paths,
TRUE);
diff --git a/src/fr-window.c b/src/fr-window.c
index 3087a80..776c09e 100644
--- a/src/fr-window.c
+++ b/src/fr-window.c
@@ -140,14 +140,15 @@ typedef enum {
typedef struct {
- GList *file_list;
- char *extract_to_dir;
- char *base_dir;
- gboolean skip_older;
- gboolean overwrite;
- gboolean junk_paths;
- char *password;
- gboolean extract_here;
+ GList *file_list;
+ char *extract_to_dir;
+ char *base_dir;
+ gboolean skip_older;
+ FrOverwrite overwrite;
+ gboolean junk_paths;
+ char *password;
+ gboolean extract_here;
+ gboolean ask_to_open_destination;
} ExtractData;
@@ -4144,7 +4145,7 @@ file_list_drag_end (GtkWidget *widget,
window->priv->drag_destination_folder,
window->priv->drag_base_dir,
FALSE,
- TRUE,
+ FR_OVERWRITE_ASK,
FALSE,
FALSE);
path_list_free (window->priv->drag_file_list);
@@ -6454,13 +6455,14 @@ fr_window_archive_remove (FrWindow *window,
static ExtractData*
-extract_data_new (GList *file_list,
- const char *extract_to_dir,
- const char *base_dir,
- gboolean skip_older,
- gboolean overwrite,
- gboolean junk_paths,
- gboolean extract_here)
+extract_data_new (GList *file_list,
+ const char *extract_to_dir,
+ const char *base_dir,
+ gboolean skip_older,
+ FrOverwrite overwrite,
+ gboolean junk_paths,
+ gboolean extract_here,
+ gboolean ask_to_open_destination)
{
ExtractData *edata;
@@ -6474,6 +6476,7 @@ extract_data_new (GList *file_list,
if (base_dir != NULL)
edata->base_dir = g_strdup (base_dir);
edata->extract_here = extract_here;
+ edata->ask_to_open_destination = ask_to_open_destination;
return edata;
}
@@ -6488,6 +6491,7 @@ extract_to_data_new (const char *extract_to_dir)
FALSE,
TRUE,
FALSE,
+ FALSE,
FALSE);
}
@@ -6565,7 +6569,8 @@ fr_window_archive_extract_here (FrWindow *window,
skip_older,
overwrite,
junk_paths,
- TRUE);
+ TRUE,
+ FALSE);
fr_window_set_current_batch_action (window,
FR_BATCH_ACTION_EXTRACT,
edata,
@@ -6576,7 +6581,7 @@ fr_window_archive_extract_here (FrWindow *window,
return;
}
- window->priv->ask_to_open_destination_after_extraction = FALSE;
+ window->priv->ask_to_open_destination_after_extraction = edata->ask_to_open_destination;
fr_process_clear (window->archive->process);
if (fr_archive_extract_here (window->archive,
@@ -6590,15 +6595,183 @@ fr_window_archive_extract_here (FrWindow *window,
}
+/* -- fr_window_archive_extract -- */
+
+
+typedef struct {
+ FrWindow *window;
+ ExtractData *edata;
+ GList *current_file;
+} OverwriteData;
+
+
+#define _FR_RESPONSE_OVERWRITE_YES_ALL 100
+#define _FR_RESPONSE_OVERWRITE_YES 101
+#define _FR_RESPONSE_OVERWRITE_NO 102
+
+
+static void
+_fr_window_archive_extract_from_edata (FrWindow *window,
+ ExtractData *edata)
+{
+ window->priv->ask_to_open_destination_after_extraction = edata->ask_to_open_destination;
+
+ fr_process_clear (window->archive->process);
+ fr_archive_extract (window->archive,
+ edata->file_list,
+ edata->extract_to_dir,
+ edata->base_dir,
+ edata->skip_older,
+ edata->overwrite == FR_OVERWRITE_YES,
+ edata->junk_paths,
+ window->priv->password);
+ fr_process_start (window->archive->process);
+}
+
+
+static gboolean _fr_window_ask_overwrite_dialog (OverwriteData *odata);
+
+
+static void
+overwrite_dialog_response_cb (GtkDialog *dialog,
+ int response_id,
+ gpointer user_data)
+{
+ OverwriteData *odata = user_data;
+ gboolean do_not_extract = FALSE;
+
+ switch (response_id) {
+ case _FR_RESPONSE_OVERWRITE_YES_ALL:
+ odata->edata->overwrite = FR_OVERWRITE_YES;
+ break;
+
+ case _FR_RESPONSE_OVERWRITE_YES:
+ odata->current_file = odata->current_file->next;
+ break;
+
+ case _FR_RESPONSE_OVERWRITE_NO:
+ {
+ /* 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);
+ path_list_free (odata->current_file);
+ odata->current_file = next;
+ }
+ break;
+
+ case GTK_RESPONSE_DELETE_EVENT:
+ case GTK_RESPONSE_CANCEL:
+ do_not_extract = TRUE;
+ break;
+
+ default:
+ break;
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+
+ if (do_not_extract) {
+ fr_window_stop_batch (odata->window);
+ g_free (odata);
+ return;
+ }
+
+ _fr_window_ask_overwrite_dialog (odata);
+}
+
+
+static gboolean
+_fr_window_ask_overwrite_dialog (OverwriteData *odata)
+{
+ gboolean do_not_extract = FALSE;
+
+ while ((odata->edata->overwrite == FR_OVERWRITE_ASK) && (odata->current_file != NULL)) {
+ char *path;
+ char *dest_uri;
+ GFile *file;
+ GFileInfo *info;
+ GFileType file_type;
+
+ path = g_uri_escape_string ((char *) odata->current_file->data, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE);
+ dest_uri = g_strdup_printf ("%s/%s", odata->edata->extract_to_dir, path);
+ file = g_file_new_for_uri (dest_uri);
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL,
+ NULL);
+
+ g_free (dest_uri);
+ g_free (path);
+
+ if (info == NULL) {
+ g_object_unref (file);
+ odata->current_file = odata->current_file->next;
+ continue;
+ }
+
+ 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 (file);
+ 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 (file);
+
+ return;
+ }
+
+ g_object_unref (info);
+ g_object_unref (file);
+ }
+
+ 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);
+}
+
+
void
-fr_window_archive_extract (FrWindow *window,
- GList *file_list,
- const char *extract_to_dir,
- const char *base_dir,
- gboolean skip_older,
- gboolean overwrite,
- gboolean junk_paths,
- gboolean ask_to_open_destination)
+fr_window_archive_extract (FrWindow *window,
+ GList *file_list,
+ const char *extract_to_dir,
+ const char *base_dir,
+ gboolean skip_older,
+ FrOverwrite overwrite,
+ gboolean junk_paths,
+ gboolean ask_to_open_destination)
{
ExtractData *edata;
gboolean do_not_extract = FALSE;
@@ -6610,7 +6783,8 @@ fr_window_archive_extract (FrWindow *window,
skip_older,
overwrite,
junk_paths,
- FALSE);
+ FALSE,
+ ask_to_open_destination);
fr_window_set_current_batch_action (window,
FR_BATCH_ACTION_EXTRACT,
@@ -6623,6 +6797,11 @@ fr_window_archive_extract (FrWindow *window,
}
if (! uri_is_dir (edata->extract_to_dir)) {
+
+ /* There is nothing to ask if the destination doesn't exist. */
+ if (edata->overwrite == FR_OVERWRITE_ASK)
+ edata->overwrite = FR_OVERWRITE_YES;
+
if (! ForceDirectoryCreation) {
GtkWidget *d;
int r;
@@ -6686,18 +6865,17 @@ fr_window_archive_extract (FrWindow *window,
return;
}
- window->priv->ask_to_open_destination_after_extraction = ask_to_open_destination;
+ if (edata->overwrite == FR_OVERWRITE_ASK) {
+ OverwriteData *odata;
- fr_process_clear (window->archive->process);
- fr_archive_extract (window->archive,
- edata->file_list,
- edata->extract_to_dir,
- edata->base_dir,
- edata->skip_older,
- edata->overwrite,
- edata->junk_paths,
- window->priv->password);
- fr_process_start (window->archive->process);
+ odata = g_new0 (OverwriteData, 1);
+ odata->window = window;
+ odata->edata = edata;
+ odata->current_file = odata->edata->file_list;
+ _fr_window_ask_overwrite_dialog (odata);
+ }
+ else
+ _fr_window_archive_extract_from_edata (window, edata);
}
@@ -8566,7 +8744,7 @@ fr_window_exec_batch_action (FrWindow *window,
window->priv->extract_default_dir,
NULL,
FALSE,
- TRUE,
+ FR_OVERWRITE_ASK,
FALSE,
TRUE);
}
diff --git a/src/fr-window.h b/src/fr-window.h
index cb1f38c..77e5d4b 100644
--- a/src/fr-window.h
+++ b/src/fr-window.h
@@ -151,7 +151,7 @@ void fr_window_archive_extract (FrWindow *window,
const char *extract_to_dir,
const char *base_dir,
gboolean skip_older,
- gboolean overwrite,
+ FrOverwrite overwrite,
gboolean junk_paths,
gboolean ask_to_open_destination);
void fr_window_archive_extract_here (FrWindow *window,
diff --git a/src/typedefs.h b/src/typedefs.h
index 8e687de..e25ed73 100644
--- a/src/typedefs.h
+++ b/src/typedefs.h
@@ -50,6 +50,12 @@ typedef enum {
FR_COMPRESSION_MAXIMUM
} FrCompression;
+typedef enum {
+ FR_OVERWRITE_YES,
+ FR_OVERWRITE_NO,
+ FR_OVERWRITE_ASK
+} FrOverwrite;
+
typedef enum { /*< skip >*/
FR_PROC_ERROR_NONE,
FR_PROC_ERROR_GENERIC,