[file-roller: 2/123] fixed archive creation and type convertion



commit 089b4901fb360299eaa25f502761c1b1b0833a93
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Tue Jul 17 18:35:58 2012 +0200

    fixed archive creation and type convertion
    
    added a FrNewArchiveDialog class to create a new archive and to save an
    archive in a different format.

 src/Makefile.am                                  |    4 +-
 src/actions.c                                    |  351 +------
 src/actions.h                                    |    3 -
 src/dlg-new.c                                    |  509 ---------
 src/dlg-new.h                                    |   58 -
 src/eggfileformatchooser.c                       |   34 +-
 src/file-roller.gresource.xml                    |    2 +-
 src/fr-archive.h                                 |    3 +-
 src/fr-new-archive-dialog.c                      |  685 ++++++++++++
 src/fr-new-archive-dialog.h                      |   61 +
 src/fr-window.c                                  | 1274 ++++++++++------------
 src/fr-window.h                                  |    7 +-
 src/ui/Makefile.am                               |   28 +-
 src/ui/{new.ui => new-archive-dialog-options.ui} |   94 +--
 14 files changed, 1382 insertions(+), 1731 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 3dbd816..09b108e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -67,8 +67,6 @@ COMMON_SOURCES = 			\
 	dlg-delete.h			\
 	dlg-extract.c			\
 	dlg-extract.h			\
-	dlg-new.c			\
-	dlg-new.h			\
 	dlg-open-with.c			\
 	dlg-open-with.h			\
 	dlg-package-installer.c		\
@@ -134,6 +132,8 @@ COMMON_SOURCES = 			\
 	fr-init.h			\
 	fr-list-model.c			\
 	fr-list-model.h			\
+	fr-new-archive-dialog.c		\
+	fr-new-archive-dialog.h		\
 	fr-stock.c			\
 	fr-stock.h			\
 	fr-process.c			\
diff --git a/src/actions.c b/src/actions.c
index 2142439..7e9353f 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -30,7 +30,6 @@
 #include "dlg-add-folder.h"
 #include "dlg-extract.h"
 #include "dlg-delete.h"
-#include "dlg-new.h"
 #include "dlg-open-with.h"
 #include "dlg-password.h"
 #include "dlg-prop.h"
@@ -43,280 +42,11 @@
 #include "typedefs.h"
 
 
-/* -- new archive -- */
-
-
-static void
-new_archive (DlgNewData *data,
-	     char       *uri)
-{
-	GtkWidget  *archive_window;
-	gboolean    new_window;
-	const char *password;
-	gboolean    encrypt_header;
-	int         volume_size;
-
-	new_window = fr_window_archive_is_present (data->window) && ! fr_window_is_batch_mode (data->window);
-	if (new_window)
-		archive_window = fr_window_new ();
-	else
-		archive_window = (GtkWidget *) data->window;
-
-	password = dlg_new_data_get_password (data);
-	encrypt_header = dlg_new_data_get_encrypt_header (data);
-	volume_size = dlg_new_data_get_volume_size (data);
-
-	fr_window_set_password (FR_WINDOW (archive_window), password);
-	fr_window_set_encrypt_header (FR_WINDOW (archive_window), encrypt_header);
-	fr_window_set_volume_size (FR_WINDOW (archive_window), volume_size);
-
-	if (fr_window_archive_new (FR_WINDOW (archive_window), uri)) {
-		gtk_widget_destroy (data->dialog);
-		if (! fr_window_is_batch_mode (FR_WINDOW (archive_window)))
-			gtk_window_present (GTK_WINDOW (archive_window));
-	}
-	else if (new_window)
-		gtk_widget_destroy (archive_window);
-}
-
-
-/* when on Automatic the user provided extension needs to be supported,
-   otherwise an existing unsupported archive can be deleted (if the user
-   provided name matches with its name) before we find out that the
-   archive is unsupported
-*/
-static gboolean
-is_supported_extension (GtkWidget *file_sel,
-			char      *filename,
-			int       *file_type)
-{
-	int i;
-	for (i = 0; file_type[i] != -1; i++)
-		if (_g_filename_has_extension (filename, mime_type_desc[file_type[i]].default_ext))
-			return TRUE;
-	return FALSE;
-}
-
-
-static char *
-get_full_uri (DlgNewData *data)
-{
-	char        *full_uri = NULL;
-	char        *uri;
-	const char  *filename;
-	int          idx;
-
-	uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (data->dialog));
-
-	if ((uri == NULL) || (*uri == 0))
-		return NULL;
-
-	filename = _g_path_get_file_name (uri);
-	if ((filename == NULL) || (*filename == 0)) {
-		g_free (uri);
-		return NULL;
-	}
-
-	idx = egg_file_format_chooser_get_format (EGG_FILE_FORMAT_CHOOSER (data->format_chooser), uri);
-	if (idx > 0) {
-		const char *uri_ext;
-		char       *default_ext;
-
-		uri_ext = get_archive_filename_extension (uri);
-		default_ext = mime_type_desc[data->supported_types[idx-1]].default_ext;
-		if (_g_strcmp_null_tolerant (uri_ext, default_ext) != 0) {
-			full_uri = g_strconcat (uri, default_ext, NULL);
-			g_free (uri);
-		}
-	}
-	if (full_uri == NULL)
-		full_uri = uri;
-
-	return full_uri;
-}
-
-
-static char *
-get_archive_filename_from_selector (DlgNewData *data)
-{
-	char      *uri = NULL;
-	GFile     *file, *dir;
-	GFileInfo *info;
-	GError    *err = NULL;
-
-	uri = get_full_uri (data);
-	if ((uri == NULL) || (*uri == 0)) {
-		GtkWidget *dialog;
-
-		g_free (uri);
-
-		dialog = _gtk_error_dialog_new (GTK_WINDOW (data->dialog),
-						GTK_DIALOG_DESTROY_WITH_PARENT,
-						NULL,
-						_("Could not create the archive"),
-						"%s",
-						_("You have to specify an archive name."));
-		gtk_dialog_run (GTK_DIALOG (dialog));
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-
-		return NULL;
-	}
-
-	file = g_file_new_for_uri (uri);
-
-	dir = g_file_get_parent (file);
-	info = g_file_query_info (dir,
-				  G_FILE_ATTRIBUTE_ACCESS_CAN_READ ","
-				  G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE ","
-				  G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE,
-				  0, NULL, &err);
-	if (err != NULL) {
-		g_warning ("Failed to get permission for extraction dir: %s",
-			   err->message);
-		g_clear_error (&err);
-		g_object_unref (info);
-		g_object_unref (dir);
-		g_object_unref (file);
-		g_free (uri);
-		return NULL;
-	}
-
-	if (! g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) {
-		GtkWidget *dialog;
-
-		g_object_unref (info);
-		g_object_unref (dir);
-		g_object_unref (file);
-		g_free (uri);
-
-		dialog = _gtk_error_dialog_new (GTK_WINDOW (data->dialog),
-						GTK_DIALOG_DESTROY_WITH_PARENT,
-						NULL,
-						_("Could not create the archive"),
-						"%s",
-						_("You don't have permission to create an archive in this folder"));
-		gtk_dialog_run (GTK_DIALOG (dialog));
-		gtk_widget_destroy (GTK_WIDGET (dialog));
-		return NULL;
-	}
-	g_object_unref (info);
-	g_object_unref (dir);
-
-	/* if the user did not specify a valid extension use the filetype combobox current type
-	 * or tar.gz if automatic is selected. */
-	if (get_archive_filename_extension (uri) == NULL) {
-		int   idx;
-		char *new_uri;
-		char *ext = NULL;
-
-		idx = egg_file_format_chooser_get_format (EGG_FILE_FORMAT_CHOOSER (data->format_chooser), uri);
-		if (idx > 0)
-			ext = mime_type_desc[data->supported_types[idx-1]].default_ext;
-		else
-			ext = ".tar.gz";
-		new_uri = g_strconcat (uri, ext, NULL);
-		g_free (uri);
-		uri = new_uri;
-	}
-
-	debug (DEBUG_INFO, "create/save %s\n", uri);
-
-	if (_g_uri_query_exists (uri)) {
-		GtkWidget *dialog;
-
-		if (! is_supported_extension (data->dialog, uri, data->supported_types)) {
-			dialog = _gtk_error_dialog_new (GTK_WINDOW (data->dialog),
-							GTK_DIALOG_MODAL,
-							NULL,
-							_("Could not create the archive"),
-							"%s",
-							_("Archive type not supported."));
-			gtk_dialog_run (GTK_DIALOG (dialog));
-			gtk_widget_destroy (GTK_WIDGET (dialog));
-			g_free (uri);
-
-			return NULL;
-		}
-
-		g_file_delete (file, NULL, &err);
-		if (err != NULL) {
-			GtkWidget *dialog;
-			dialog = _gtk_error_dialog_new (GTK_WINDOW (data->dialog),
-							GTK_DIALOG_DESTROY_WITH_PARENT,
-							NULL,
-							_("Could not delete the old archive."),
-							"%s",
-							err->message);
-			gtk_dialog_run (GTK_DIALOG (dialog));
-			gtk_widget_destroy (GTK_WIDGET (dialog));
-			g_error_free (err);
-			g_free (uri);
-			g_object_unref (file);
-			return NULL;
-		}
-	}
-
-	g_object_unref (file);
-
-	return uri;
-}
-
-
-static void
-new_file_response_cb (GtkWidget  *w,
-		      int         response,
-		      DlgNewData *data)
-{
-	char *uri;
-
-	if ((response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT)) {
-		/* FIXME: libarchive
-		 fr_archive_action_completed (data->window->archive,
-					     FR_ACTION_CREATING_NEW_ARCHIVE,
-					     FR_PROC_ERROR_STOPPED,
-					     NULL);
-					     */
-		gtk_widget_destroy (data->dialog);
-		return;
-	}
-
-	if (response == GTK_RESPONSE_HELP) {
-		_gtk_show_help_dialog (GTK_WINDOW (data->dialog), "archive-create");
-		return;
-	}
-
-	uri = get_archive_filename_from_selector (data);
-	if (uri != NULL) {
-		new_archive (data, uri);
-		g_free (uri);
-	}
-}
-
-
-void
-show_new_archive_dialog (FrWindow   *window,
-			 const char *archive_name)
-{
-	DlgNewData *data;
-
-	if (archive_name != NULL)
-		data = dlg_save_as (window, archive_name);
-	else
-		data = dlg_new (window);
-
-	g_signal_connect (G_OBJECT (data->dialog),
-			  "response",
-			  G_CALLBACK (new_file_response_cb),
-			  data);
-	gtk_window_present (GTK_WINDOW (data->dialog));
-}
-
-
 void
 activate_action_new (GtkAction *action,
 		     gpointer   data)
 {
-	show_new_archive_dialog ((FrWindow*)data, NULL);
+	fr_window_action_new_archive (FR_WINDOW (data));
 }
 
 
@@ -328,6 +58,7 @@ window_archive_loaded_cb (FrWindow  *window,
 			  gboolean   success,
 			  GtkWidget *file_sel)
 {
+	/* FIXME: libarchive */
 	if (success) {
 		g_signal_handlers_disconnect_by_data (window, file_sel);
 		gtk_widget_destroy (file_sel);
@@ -419,85 +150,11 @@ activate_action_open (GtkAction *action,
 /* -- save archive -- */
 
 
-static void
-save_file_response_cb (GtkWidget  *w,
-		       gint        response,
-		       DlgNewData *data)
-{
-	char       *path;
-	const char *password;
-	gboolean    encrypt_header;
-	int         volume_size;
-	GSettings  *settings;
-
-	if ((response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT)) {
-		gtk_widget_destroy (data->dialog);
-		return;
-	}
-
-	if (response == GTK_RESPONSE_HELP) {
-		_gtk_show_help_dialog (GTK_WINDOW (data->dialog), "archive-convert");
-		return;
-	}
-
-	path = get_archive_filename_from_selector (data);
-	if (path == NULL)
-		return;
-
-	password = dlg_new_data_get_password (data);
-	encrypt_header = dlg_new_data_get_encrypt_header (data);
-	volume_size = dlg_new_data_get_volume_size (data);
-
-	settings = g_settings_new (FILE_ROLLER_SCHEMA_BATCH_ADD);
-	g_settings_set_int (settings, PREF_BATCH_ADD_VOLUME_SIZE, volume_size);
-	g_object_unref (settings);
-
-	fr_window_archive_save_as (data->window, path, password, encrypt_header, volume_size);
-	gtk_widget_destroy (data->dialog);
-
-	g_free (path);
-}
-
-
 void
 activate_action_save_as (GtkAction *action,
-			 gpointer   callback_data)
-{
-	FrWindow   *window = callback_data;
-	DlgNewData *data;
-	char       *archive_name = NULL;
-
-	if (fr_window_get_archive_uri (window)) {
-		const char *uri;
-		GFile      *file;
-		GFileInfo  *info;
-		GError     *err = NULL;
-
-		uri = fr_window_get_archive_uri (window);
-		file = g_file_new_for_uri (uri);
-		info = g_file_query_info (file,
-					  G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
-					  0, NULL, &err);
-
-		if (err != NULL) {
-			g_warning ("Failed to get display name for uri %s: %s", uri, err->message);
-			g_clear_error (&err);
-		}
-		else
-			archive_name = g_strdup (g_file_info_get_display_name (info));
-
-		g_object_unref (info);
-		g_object_unref (file);
-	}
-
-	data = dlg_save_as (window, archive_name);
-	g_signal_connect (G_OBJECT (data->dialog),
-			  "response",
-			  G_CALLBACK (save_file_response_cb),
-			  data);
-	gtk_window_present (GTK_WINDOW (data->dialog));
-
-	g_free (archive_name);
+			 gpointer   user_data)
+{
+	fr_window_action_save_as (FR_WINDOW (user_data));
 }
 
 
diff --git a/src/actions.h b/src/actions.h
index d2b9d95..f1b8e54 100644
--- a/src/actions.h
+++ b/src/actions.h
@@ -23,9 +23,6 @@
 #define ACTIONS_H
 
 #include <gtk/gtk.h>
-#include "fr-window.h"
-
-void show_new_archive_dialog (FrWindow *window, const char *archive_name);
 
 void activate_action_new (GtkAction *action, gpointer data);
 void activate_action_open (GtkAction *action, gpointer data);
diff --git a/src/eggfileformatchooser.c b/src/eggfileformatchooser.c
index e441467..ce2c906 100644
--- a/src/eggfileformatchooser.c
+++ b/src/eggfileformatchooser.c
@@ -27,7 +27,7 @@
 typedef struct _EggFileFormatFilterInfo EggFileFormatFilterInfo;
 typedef struct _EggFileFormatSearch EggFileFormatSearch;
 
-enum 
+enum
 {
   MODEL_COLUMN_ID,
   MODEL_COLUMN_NAME,
@@ -38,7 +38,7 @@ enum
   MODEL_COLUMN_DESTROY
 };
 
-enum 
+enum
 {
   SIGNAL_SELECTION_CHANGED,
   SIGNAL_LAST
@@ -76,7 +76,7 @@ struct _EggFileFormatSearch
 
 static guint signals[SIGNAL_LAST];
 
-G_DEFINE_TYPE (EggFileFormatChooser, 
+G_DEFINE_TYPE (EggFileFormatChooser,
 	       egg_file_format_chooser,
                GTK_TYPE_EXPANDER);
 static EGG_DEFINE_QUARK (EggFileFormatFilterInfo,
@@ -229,7 +229,7 @@ selection_changed_cb (GtkTreeSelection     *selection,
   GtkTreeIter parent;
   GtkTreeIter iter;
 
-  if (gtk_tree_selection_get_selected (selection, &model, &iter)) 
+  if (gtk_tree_selection_get_selected (selection, &model, &iter))
     {
       gtk_tree_model_get (model, &iter, MODEL_COLUMN_NAME, &name, -1);
 
@@ -254,7 +254,7 @@ selection_changed_cb (GtkTreeSelection     *selection,
     }
 }
 
-/* XXX This hack is needed, as gtk_expander_set_label seems 
+/* XXX This hack is needed, as gtk_expander_set_label seems
  * not to work from egg_file_format_chooser_init */
 static gboolean
 select_default_file_format (gpointer data)
@@ -386,7 +386,7 @@ egg_file_format_chooser_init (EggFileFormatChooser *self)
   GtkCellRenderer *cell;
   GtkTreeIter iter;
 
-  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EGG_TYPE_FILE_FORMAT_CHOOSER, 
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EGG_TYPE_FILE_FORMAT_CHOOSER,
                                             EggFileFormatChooserPrivate);
 
   self->priv->size_changed_event = 0;
@@ -556,7 +556,7 @@ filter_changed_cb (GObject    *object,
   current_filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (object));
   model = GTK_TREE_MODEL (self->priv->model);
 
-  if (gtk_tree_selection_get_selected (self->priv->selection, &model, &iter)) 
+  if (gtk_tree_selection_get_selected (self->priv->selection, &model, &iter))
     {
       while (gtk_tree_model_iter_parent (model, &parent, &iter))
         iter = parent;
@@ -699,7 +699,7 @@ chooser_response_cb (GtkDialog *dialog,
           g_free (filename);
         }
 
-      g_free (basename); 
+      g_free (basename);
     }
 
 }
@@ -732,7 +732,7 @@ egg_file_format_chooser_realize (GtkWidget *widget)
 
   g_object_ref (self->priv->chooser);
 
-  g_signal_connect (self->priv->chooser, "notify::filter", 
+  g_signal_connect (self->priv->chooser, "notify::filter",
                     G_CALLBACK (filter_changed_cb), self);
   gtk_file_chooser_add_filter (self->priv->chooser, self->priv->all_files);
 
@@ -841,7 +841,7 @@ egg_file_format_chooser_add_format_impl (EggFileFormatChooser *self,
   else
     filter = egg_file_format_filter_new (name, TRUE);
 
-  gtk_tree_store_append (self->priv->model, &iter, 
+  gtk_tree_store_append (self->priv->model, &iter,
                          parent > 0 ? &search.iter : NULL);
 
   gtk_tree_store_set (self->priv->model, &iter,
@@ -941,7 +941,7 @@ get_icon_name (const gchar *mime_type)
   return name;
 }
 
-void           
+void
 egg_file_format_chooser_add_pixbuf_formats (EggFileFormatChooser *self,
                                             guint                 parent G_GNUC_UNUSED,
                                             guint               **formats)
@@ -980,7 +980,7 @@ egg_file_format_chooser_add_pixbuf_formats (EggFileFormatChooser *self,
       description = gdk_pixbuf_format_get_description (format);
       name = gdk_pixbuf_format_get_name (format);
 
-      id = egg_file_format_chooser_add_format_impl (self, parent, description, 
+      id = egg_file_format_chooser_add_format_impl (self, parent, description,
                                                     icon, extensions);
 
       g_free (description);
@@ -1039,7 +1039,7 @@ egg_file_format_chooser_remove_format (EggFileFormatChooser *self,
   gtk_tree_store_remove (self->priv->model, &search.iter);
 }
 
-void            
+void
 egg_file_format_chooser_set_format (EggFileFormatChooser *self,
                                     guint                 format)
 {
@@ -1104,7 +1104,7 @@ egg_file_format_chooser_get_format (EggFileFormatChooser *self,
   return format;
 }
 
-void            
+void
 egg_file_format_chooser_set_format_data (EggFileFormatChooser *self,
                                          guint                 format,
                                          gpointer              data,
@@ -1184,14 +1184,14 @@ egg_file_format_chooser_append_extension (EggFileFormatChooser *self,
 
   g_return_val_if_fail (search.success, NULL);
 
-  gtk_tree_model_get (model, &search.iter, 
+  gtk_tree_model_get (model, &search.iter,
                       MODEL_COLUMN_EXTENSIONS, &extensions,
                       -1);
 
-  if (NULL == extensions && 
+  if (NULL == extensions &&
       gtk_tree_model_iter_nth_child (model, &child, &search.iter, 0))
     {
-      gtk_tree_model_get (model, &child, 
+      gtk_tree_model_get (model, &child,
                           MODEL_COLUMN_EXTENSIONS, &extensions,
                           -1);
     }
diff --git a/src/file-roller.gresource.xml b/src/file-roller.gresource.xml
index 7301af7..54b76a2 100644
--- a/src/file-roller.gresource.xml
+++ b/src/file-roller.gresource.xml
@@ -9,7 +9,7 @@
     <file compressed="true">ui/error-dialog.ui</file>
     <file compressed="true">ui/menus-toolbars.ui</file>
     <file compressed="true">ui/message-dialog.ui</file>
-    <file compressed="true">ui/new.ui</file>
+    <file compressed="true">ui/new-archive-dialog-options.ui</file>
     <file compressed="true">ui/password.ui</file>
     <file compressed="true">ui/progress-dialog.ui</file>
     <file compressed="true">ui/properties.ui</file>
diff --git a/src/fr-archive.h b/src/fr-archive.h
index af7c256..98781f5 100644
--- a/src/fr-archive.h
+++ b/src/fr-archive.h
@@ -43,7 +43,8 @@ typedef enum {
 	FR_ACTION_EXTRACTING_FILES,           /* extracting files */
 	FR_ACTION_COPYING_FILES_TO_REMOTE,    /* copying extracted files to a remote location */
 	FR_ACTION_CREATING_ARCHIVE,           /* creating a local archive */
-	FR_ACTION_SAVING_REMOTE_ARCHIVE       /* copying the archive to a remote location */
+	FR_ACTION_SAVING_REMOTE_ARCHIVE,      /* copying the archive to a remote location */
+	FR_ACTION_RENAMING_FILES              /* renaming files stored in the archive */
 } FrAction;
 
 #ifdef DEBUG
diff --git a/src/fr-new-archive-dialog.c b/src/fr-new-archive-dialog.c
new file mode 100644
index 0000000..1044218
--- /dev/null
+++ b/src/fr-new-archive-dialog.c
@@ -0,0 +1,685 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  File-Roller
+ *
+ *  Copyright (C) 2008, 2012 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/>.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include <gio/gio.h>
+#include "eggfileformatchooser.h"
+#include "file-utils.h"
+#include "fr-init.h"
+#include "fr-new-archive-dialog.h"
+#include "fr-stock.h"
+#include "glib-utils.h"
+#include "gtk-utils.h"
+#include "preferences.h"
+
+
+#define GET_WIDGET(x)     (_gtk_builder_get_widget (self->priv->builder, (x)))
+#define DEFAULT_EXTENSION ".tar.gz"
+#define MEGABYTE          (1024 * 1024)
+
+
+struct _FrNewArchiveDialogPrivate {
+	GtkBuilder           *builder;
+	EggFileFormatChooser *format_chooser;
+	int                  *supported_types;
+	gboolean              can_encrypt;
+	gboolean              can_encrypt_header;
+	gboolean              can_create_volumes;
+};
+
+
+G_DEFINE_TYPE (FrNewArchiveDialog, fr_new_archive_dialog, GTK_TYPE_FILE_CHOOSER_DIALOG)
+
+
+static void
+fr_new_archive_dialog_finalize (GObject *object)
+{
+	FrNewArchiveDialog *self;
+
+	self = FR_NEW_ARCHIVE_DIALOG (object);
+
+	g_object_unref (self->priv->builder);
+
+	G_OBJECT_CLASS (fr_new_archive_dialog_parent_class)->finalize (object);
+}
+
+
+static void
+fr_new_archive_dialog_class_init (FrNewArchiveDialogClass *klass)
+{
+	GObjectClass *object_class;
+
+	g_type_class_add_private (klass, sizeof (FrNewArchiveDialogPrivate));
+
+	object_class = (GObjectClass*) klass;
+	object_class->finalize = fr_new_archive_dialog_finalize;
+}
+
+
+static void
+fr_new_archive_dialog_init (FrNewArchiveDialog *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, FR_TYPE_NEW_ARCHIVE_DIALOG, FrNewArchiveDialogPrivate);
+	self->priv->builder = NULL;
+}
+
+
+static void
+_fr_new_archive_dialog_update_sensitivity (FrNewArchiveDialog *self)
+{
+	gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (GET_WIDGET ("encrypt_header_checkbutton")), ! self->priv->can_encrypt_header);
+	gtk_widget_set_sensitive (GET_WIDGET ("encrypt_header_checkbutton"), self->priv->can_encrypt_header);
+	gtk_widget_set_sensitive (GET_WIDGET ("volume_spinbutton"), ! self->priv->can_create_volumes || gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("volume_checkbutton"))));
+}
+
+
+static void
+_fr_new_archive_dialog_update_sensitivity_for_ext (FrNewArchiveDialog *self,
+						   const char         *ext)
+{
+	const char *mime_type;
+	int         i;
+
+	self->priv->can_encrypt = FALSE;
+	self->priv->can_encrypt_header = FALSE;
+	self->priv->can_create_volumes = FALSE;
+
+	mime_type = get_mime_type_from_extension (ext);
+
+	if (mime_type == NULL) {
+		gtk_widget_set_sensitive (GET_WIDGET ("password_entry"), FALSE);
+		gtk_widget_set_sensitive (GET_WIDGET ("password_label"), FALSE);
+		gtk_widget_set_sensitive (GET_WIDGET ("encrypt_header_checkbutton"), FALSE);
+		gtk_widget_set_sensitive (GET_WIDGET ("volume_box"), FALSE);
+		return;
+	}
+
+	for (i = 0; mime_type_desc[i].mime_type != NULL; i++) {
+		if (strcmp (mime_type_desc[i].mime_type, mime_type) == 0) {
+			self->priv->can_encrypt = mime_type_desc[i].capabilities & FR_ARCHIVE_CAN_ENCRYPT;
+			gtk_widget_set_sensitive (GET_WIDGET ("password_entry"), self->priv->can_encrypt);
+			gtk_widget_set_sensitive (GET_WIDGET ("password_label"), self->priv->can_encrypt);
+
+			self->priv->can_encrypt_header = mime_type_desc[i].capabilities & FR_ARCHIVE_CAN_ENCRYPT_HEADER;
+			gtk_widget_set_sensitive (GET_WIDGET ("encrypt_header_checkbutton"), self->priv->can_encrypt_header);
+
+			self->priv->can_create_volumes = mime_type_desc[i].capabilities & FR_ARCHIVE_CAN_CREATE_VOLUMES;
+			gtk_widget_set_sensitive (GET_WIDGET ("volume_box"), self->priv->can_create_volumes);
+
+			break;
+		}
+	}
+
+	_fr_new_archive_dialog_update_sensitivity (self);
+}
+
+
+/* FIXME
+static void
+archive_type_combo_box_changed_cb (GtkComboBox *combo_box,
+				   DlgNewData  *data)
+{
+	const char *uri;
+	const char *ext;
+	int         idx;
+
+	uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (data->dialog));
+
+	ext = get_archive_filename_extension (uri);
+	idx = gtk_combo_box_get_active (GTK_COMBO_BOX (data->n_archive_type_combo_box)) - 1;
+	if ((ext == NULL) && (idx >= 0))
+		ext = mime_type_desc[self->priv->supported_types[idx]].default_ext;
+
+	_fr_new_archive_dialog_update_sensitivity_for_ext (data, ext);
+
+	if ((idx >= 0) && (uri != NULL)) {
+		const char *new_ext;
+		const char *basename;
+		char       *basename_noext;
+		char       *new_basename;
+		char       *new_basename_uft8;
+
+		new_ext = mime_type_desc[self->priv->supported_types[idx]].default_ext;
+		basename = _g_path_get_file_name (uri);
+		if (g_str_has_suffix (basename, ext))
+			basename_noext = g_strndup (basename, strlen (basename) - strlen (ext));
+		else
+			basename_noext = g_strdup (basename);
+		new_basename = g_strconcat (basename_noext, new_ext, NULL);
+		new_basename_uft8 = g_uri_unescape_string (new_basename, NULL);
+
+		gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (data->dialog), new_basename_uft8);
+		_fr_new_archive_dialog_update_sensitivity_for_ext (data, new_ext);
+
+		g_free (new_basename_uft8);
+		g_free (new_basename);
+		g_free (basename_noext);
+	}
+}
+*/
+
+
+static void
+password_entry_changed_cb (GtkEditable *editable,
+			   gpointer     user_data)
+{
+	_fr_new_archive_dialog_update_sensitivity (FR_NEW_ARCHIVE_DIALOG (user_data));
+}
+
+
+static void
+volume_toggled_cb (GtkToggleButton *toggle_button,
+		   gpointer         user_data)
+{
+	_fr_new_archive_dialog_update_sensitivity (FR_NEW_ARCHIVE_DIALOG (user_data));
+}
+
+
+static void
+format_chooser_selection_changed_cb (EggFileFormatChooser *format_chooser,
+				     gpointer              user_data)
+{
+	FrNewArchiveDialog *self = user_data;
+	const char         *uri;
+	const char         *ext;
+	int                 n_format;
+
+	uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (self));
+	if (uri == NULL)
+		return;
+
+	ext = get_archive_filename_extension (uri);
+	n_format = egg_file_format_chooser_get_format (EGG_FILE_FORMAT_CHOOSER (self->priv->format_chooser), uri);
+	if (ext == NULL)
+		ext = mime_type_desc[self->priv->supported_types[n_format - 1]].default_ext;
+
+	_fr_new_archive_dialog_update_sensitivity_for_ext (self, ext);
+
+	if (uri != NULL) {
+		const char *new_ext;
+		const char *basename;
+		char       *basename_noext;
+		char       *new_basename;
+		char       *new_basename_uft8;
+
+		new_ext = mime_type_desc[self->priv->supported_types[n_format - 1]].default_ext;
+		basename = _g_path_get_file_name (uri);
+		if (g_str_has_suffix (basename, ext))
+			basename_noext = g_strndup (basename, strlen (basename) - strlen (ext));
+		else
+			basename_noext = g_strdup (basename);
+		new_basename = g_strconcat (basename_noext, new_ext, NULL);
+		new_basename_uft8 = g_uri_unescape_string (new_basename, NULL);
+
+		gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (self), new_basename_uft8);
+		_fr_new_archive_dialog_update_sensitivity_for_ext (self, new_ext);
+
+		g_free (new_basename_uft8);
+		g_free (new_basename);
+		g_free (basename_noext);
+	}
+}
+
+
+static void
+options_expander_unmap_cb (GtkWidget *widget,
+			   gpointer   user_data)
+{
+	egg_file_format_chooser_emit_size_changed ((EggFileFormatChooser *) user_data);
+}
+
+
+static char *
+get_icon_name_for_type (const char *mime_type)
+{
+	char *name = NULL;
+
+	if (mime_type != NULL) {
+		char *s;
+
+		name = g_strconcat ("gnome-mime-", mime_type, NULL);
+		for (s = name; *s; ++s)
+			if (! g_ascii_isalpha (*s))
+				*s = '-';
+	}
+
+	if ((name == NULL) || ! gtk_icon_theme_has_icon (gtk_icon_theme_get_default (), name)) {
+		g_free (name);
+		name = g_strdup ("package-x-generic");
+	}
+
+	return name;
+}
+
+
+static void
+_fr_new_archive_dialog_construct (FrNewArchiveDialog *self,
+				  GtkWindow          *parent,
+				  FrNewArchiveAction  action,
+				  const char         *default_name)
+{
+	GSettings *settings;
+	int        i;
+
+	gtk_file_chooser_set_action (GTK_FILE_CHOOSER (self), GTK_FILE_CHOOSER_ACTION_SAVE);
+	gtk_window_set_modal (GTK_WINDOW (self), TRUE);
+	gtk_window_set_transient_for (GTK_WINDOW (self), parent);
+
+	self->priv->builder = _gtk_builder_new_from_resource ("new-archive-dialog-options.ui");
+	if (self->priv->builder == NULL)
+		return;
+
+	gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+
+	switch (action) {
+	case FR_NEW_ARCHIVE_ACTION_NEW:
+		self->priv->supported_types = create_type;
+		gtk_window_set_title (GTK_WINDOW (self), C_("File", "New"));
+		gtk_dialog_add_button (GTK_DIALOG (self), FR_STOCK_CREATE_ARCHIVE, GTK_RESPONSE_OK);
+		break;
+	case FR_NEW_ARCHIVE_ACTION_SAVE_AS:
+		self->priv->supported_types = save_type;
+		gtk_window_set_title (GTK_WINDOW (self), C_("File", "Save"));
+		gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_SAVE, GTK_RESPONSE_OK);
+		break;
+	}
+	gtk_dialog_set_default_response (GTK_DIALOG (self), GTK_RESPONSE_OK);
+
+	sort_mime_types_by_description (self->priv->supported_types);
+
+	/* Set widgets data. */
+
+	gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (self), GET_WIDGET ("extra_widget"));
+
+	if (default_name != NULL)
+		gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (self), default_name);
+
+	/**/
+
+	gtk_expander_set_expanded (GTK_EXPANDER (GET_WIDGET ("other_options_expander")), FALSE);
+
+	settings = g_settings_new (FILE_ROLLER_SCHEMA_GENERAL);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("encrypt_header_checkbutton")), g_settings_get_boolean (settings, PREF_GENERAL_ENCRYPT_HEADER));
+	g_object_unref (settings);
+
+	settings = g_settings_new (FILE_ROLLER_SCHEMA_BATCH_ADD);
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET("volume_spinbutton")), (double) g_settings_get_int (settings, PREF_BATCH_ADD_VOLUME_SIZE) / MEGABYTE);
+	g_object_unref (settings);
+
+	/* format chooser */
+
+	self->priv->format_chooser = (EggFileFormatChooser *) egg_file_format_chooser_new ();
+	for (i = 0; self->priv->supported_types[i] != -1; i++) {
+		int   idx = self->priv->supported_types[i];
+		char *exts[4];
+		int   e;
+		int   n_exts;
+		char *icon_name;
+
+		n_exts = 0;
+		for (e = 0; (n_exts < 4) && file_ext_type[e].ext != NULL; e++) {
+			if (strcmp (file_ext_type[e].ext, mime_type_desc[idx].default_ext) == 0)
+				continue;
+			if (strcmp (file_ext_type[e].mime_type, mime_type_desc[idx].mime_type) == 0)
+				exts[n_exts++] = file_ext_type[e].ext;
+		}
+		while (n_exts < 4)
+			exts[n_exts++] = NULL;
+
+		/* g_print ("%s => %s, %s, %s, %s\n", mime_type_desc[idx].mime_type, exts[0], exts[1], exts[2], exts[3]); */
+
+		icon_name = get_icon_name_for_type (mime_type_desc[idx].mime_type);
+		egg_file_format_chooser_add_format (self->priv->format_chooser,
+						    0,
+						    _(mime_type_desc[idx].name),
+						    icon_name,
+						    mime_type_desc[idx].default_ext,
+						    exts[0],
+						    exts[1],
+						    exts[2],
+						    exts[3],
+						    NULL);
+
+		g_free (icon_name);
+	}
+	egg_file_format_chooser_set_format (self->priv->format_chooser, 0);
+	gtk_widget_show (GTK_WIDGET (self->priv->format_chooser));
+	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("format_chooser_box")), GTK_WIDGET (self->priv->format_chooser), TRUE, TRUE, 0);
+
+	gtk_widget_set_vexpand (GET_WIDGET ("extra_widget"), FALSE);
+
+	_fr_new_archive_dialog_update_sensitivity (self);
+
+	/* Set the signals handlers. */
+
+	/* FIXME g_signal_connect (GET_WIDGET ("archive_type_combo_box"),
+			  "changed",
+			  G_CALLBACK (archive_type_combo_box_changed_cb),
+			  self); */
+	g_signal_connect (GET_WIDGET ("password_entry"),
+			  "changed",
+			  G_CALLBACK (password_entry_changed_cb),
+			  self);
+	g_signal_connect (GET_WIDGET ("volume_checkbutton"),
+			  "toggled",
+			  G_CALLBACK (volume_toggled_cb),
+			  self);
+	g_signal_connect (self->priv->format_chooser,
+			  "selection-changed",
+			  G_CALLBACK (format_chooser_selection_changed_cb),
+			  self);
+	g_signal_connect_after (GET_WIDGET ("other_options_alignment"),
+				"unmap",
+				G_CALLBACK (options_expander_unmap_cb),
+				self->priv->format_chooser);
+}
+
+
+GtkWidget *
+fr_new_archive_dialog_new (GtkWindow          *parent,
+			   FrNewArchiveAction  action,
+			   const char         *default_name)
+{
+	FrNewArchiveDialog *self;
+
+	self = g_object_new (FR_TYPE_NEW_ARCHIVE_DIALOG, NULL);
+	_fr_new_archive_dialog_construct (self, parent, action, default_name);
+
+	return (GtkWidget *) self;
+}
+
+
+static int
+_fr_new_archive_dialog_get_archive_type (FrNewArchiveDialog *self)
+{
+	const char *uri;
+	const char *ext;
+
+	uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (self));
+	if (uri == NULL)
+		return -1;
+
+	ext = get_archive_filename_extension (uri);
+	if (ext == NULL) {
+		int idx;
+
+		idx = egg_file_format_chooser_get_format (EGG_FILE_FORMAT_CHOOSER (self->priv->format_chooser), uri);
+		/*idx = gtk_combo_box_get_active (GTK_COMBO_BOX (data->n_archive_type_combo_box)) - 1;*/
+		if (idx >= 0)
+			return self->priv->supported_types[idx];
+
+		ext = DEFAULT_EXTENSION;
+	}
+
+	return get_mime_type_index (get_mime_type_from_extension (ext));
+}
+
+
+/* when on Automatic the user provided extension needs to be supported,
+   otherwise an existing unsupported archive can be deleted (if the user
+   provided name matches with its name) before we find out that the
+   archive is unsupported
+*/
+static gboolean
+is_supported_extension (char *filename,
+			int  *file_types)
+{
+	int i;
+	for (i = 0; file_types[i] != -1; i++)
+		if (_g_filename_has_extension (filename, mime_type_desc[file_types[i]].default_ext))
+			return TRUE;
+	return FALSE;
+}
+
+
+static char *
+_fr_new_archive_dialog_get_uri (FrNewArchiveDialog *self)
+{
+	char        *full_uri = NULL;
+	char        *uri;
+	const char  *filename;
+	int          idx;
+
+	uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (self));
+
+	if ((uri == NULL) || (*uri == 0))
+		return NULL;
+
+	filename = _g_path_get_file_name (uri);
+	if ((filename == NULL) || (*filename == 0)) {
+		g_free (uri);
+		return NULL;
+	}
+
+	idx = egg_file_format_chooser_get_format (EGG_FILE_FORMAT_CHOOSER (self->priv->format_chooser), uri);
+	if (idx > 0) {
+		const char *uri_ext;
+		char       *default_ext;
+
+		uri_ext = get_archive_filename_extension (uri);
+		default_ext = mime_type_desc[self->priv->supported_types[idx-1]].default_ext;
+		if (_g_strcmp_null_tolerant (uri_ext, default_ext) != 0) {
+			full_uri = g_strconcat (uri, default_ext, NULL);
+			g_free (uri);
+		}
+	}
+	if (full_uri == NULL)
+		full_uri = uri;
+
+	return full_uri;
+}
+
+
+char *
+fr_new_archive_dialog_get_uri (FrNewArchiveDialog *self)
+{
+	char      *uri = NULL;
+	GFile     *file, *dir;
+	GFileInfo *info;
+	GError    *err = NULL;
+
+	uri = _fr_new_archive_dialog_get_uri (self);
+	if ((uri == NULL) || (*uri == 0)) {
+		GtkWidget *dialog;
+
+		g_free (uri);
+
+		dialog = _gtk_error_dialog_new (GTK_WINDOW (self),
+						GTK_DIALOG_DESTROY_WITH_PARENT,
+						NULL,
+						_("Could not create the archive"),
+						"%s",
+						_("You have to specify an archive name."));
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+
+		return NULL;
+	}
+
+	file = g_file_new_for_uri (uri);
+
+	dir = g_file_get_parent (file);
+	info = g_file_query_info (dir,
+				  G_FILE_ATTRIBUTE_ACCESS_CAN_READ ","
+				  G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE ","
+				  G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE,
+				  0, NULL, &err);
+	if (err != NULL) {
+		g_warning ("Failed to get permission for extraction dir: %s",
+			   err->message);
+		g_clear_error (&err);
+		g_object_unref (info);
+		g_object_unref (dir);
+		g_object_unref (file);
+		g_free (uri);
+		return NULL;
+	}
+
+	if (! g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) {
+		GtkWidget *dialog;
+
+		g_object_unref (info);
+		g_object_unref (dir);
+		g_object_unref (file);
+		g_free (uri);
+
+		dialog = _gtk_error_dialog_new (GTK_WINDOW (self),
+						GTK_DIALOG_DESTROY_WITH_PARENT,
+						NULL,
+						_("Could not create the archive"),
+						"%s",
+						_("You don't have permission to create an archive in this folder"));
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+		return NULL;
+	}
+	g_object_unref (info);
+	g_object_unref (dir);
+
+	/* if the user did not specify a valid extension use the filetype combobox current type
+	 * or tar.gz if automatic is selected. */
+	if (get_archive_filename_extension (uri) == NULL) {
+		int   idx;
+		char *new_uri;
+		char *ext = NULL;
+
+		idx = egg_file_format_chooser_get_format (EGG_FILE_FORMAT_CHOOSER (self->priv->format_chooser), uri);
+		if (idx > 0)
+			ext = mime_type_desc[self->priv->supported_types[idx-1]].default_ext;
+		else
+			ext = ".tar.gz";
+		new_uri = g_strconcat (uri, ext, NULL);
+		g_free (uri);
+		uri = new_uri;
+	}
+
+	debug (DEBUG_INFO, "create/save %s\n", uri);
+
+	if (_g_uri_query_exists (uri)) {
+		GtkWidget *dialog;
+
+		if (! is_supported_extension (uri, self->priv->supported_types)) {
+			dialog = _gtk_error_dialog_new (GTK_WINDOW (self),
+							GTK_DIALOG_MODAL,
+							NULL,
+							_("Could not create the archive"),
+							"%s",
+							_("Archive type not supported."));
+			gtk_dialog_run (GTK_DIALOG (dialog));
+			gtk_widget_destroy (GTK_WIDGET (dialog));
+			g_free (uri);
+
+			return NULL;
+		}
+
+		g_file_delete (file, NULL, &err);
+		if (err != NULL) {
+			GtkWidget *dialog;
+
+			dialog = _gtk_error_dialog_new (GTK_WINDOW (self),
+							GTK_DIALOG_DESTROY_WITH_PARENT,
+							NULL,
+							_("Could not delete the old archive."),
+							"%s",
+							err->message);
+			gtk_dialog_run (GTK_DIALOG (dialog));
+
+			gtk_widget_destroy (GTK_WIDGET (dialog));
+			g_error_free (err);
+			g_free (uri);
+			g_object_unref (file);
+
+			return NULL;
+		}
+	}
+
+	g_object_unref (file);
+
+	return uri;
+}
+
+
+const char *
+fr_new_archive_dialog_get_password (FrNewArchiveDialog *self)
+{
+	const char *password = NULL;
+	int         idx;
+
+	idx = _fr_new_archive_dialog_get_archive_type (self);
+	if (idx < 0)
+		return NULL;
+
+	if (mime_type_desc[idx].capabilities & FR_ARCHIVE_CAN_ENCRYPT)
+		password = (char*) gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("password_entry")));
+
+	return password;
+}
+
+
+gboolean
+fr_new_archive_dialog_get_encrypt_header (FrNewArchiveDialog *self)
+{
+	gboolean encrypt_header = FALSE;
+	int      idx;
+
+	idx = _fr_new_archive_dialog_get_archive_type (self);
+	if (idx < 0)
+		return FALSE;
+
+	if (mime_type_desc[idx].capabilities & FR_ARCHIVE_CAN_ENCRYPT) {
+		const char *password = gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("password_entry")));
+		if (password != NULL) {
+			if (strcmp (password, "") != 0) {
+				if (mime_type_desc[idx].capabilities & FR_ARCHIVE_CAN_ENCRYPT_HEADER)
+					encrypt_header = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("encrypt_header_checkbutton")));
+			}
+		}
+	}
+
+	return encrypt_header;
+}
+
+
+int
+fr_new_archive_dialog_get_volume_size (FrNewArchiveDialog *self)
+{
+	guint volume_size = 0;
+	int   idx;
+
+	idx = _fr_new_archive_dialog_get_archive_type (self);
+	if (idx < 0)
+		return 0;
+
+	if ((mime_type_desc[idx].capabilities & FR_ARCHIVE_CAN_CREATE_VOLUMES)
+	    && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("volume_checkbutton"))))
+	{
+		double value;
+
+		value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (GET_WIDGET ("volume_spinbutton")));
+		volume_size = floor (value * MEGABYTE);
+
+	}
+
+	return volume_size;
+}
diff --git a/src/fr-new-archive-dialog.h b/src/fr-new-archive-dialog.h
new file mode 100644
index 0000000..c2f63b9
--- /dev/null
+++ b/src/fr-new-archive-dialog.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  File-Roller
+ *
+ *  Copyright (C) 2012 The 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/>.
+ */
+
+#ifndef FR_NEW_ARCHIVE_DIALOG_H
+#define FR_NEW_ARCHIVE_DIALOG_H
+
+#include <gtk/gtk.h>
+
+typedef enum {
+	FR_NEW_ARCHIVE_ACTION_NEW,
+	FR_NEW_ARCHIVE_ACTION_SAVE_AS
+} FrNewArchiveAction;
+
+#define FR_TYPE_NEW_ARCHIVE_DIALOG            (fr_new_archive_dialog_get_type ())
+#define FR_NEW_ARCHIVE_DIALOG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), FR_TYPE_NEW_ARCHIVE_DIALOG, FrNewArchiveDialog))
+#define FR_NEW_ARCHIVE_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), FR_TYPE_NEW_ARCHIVE_DIALOG, FrNewArchiveDialogClass))
+#define FR_IS_NEW_ARCHIVE_DIALOG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FR_TYPE_NEW_ARCHIVE_DIALOG))
+#define FR_IS_NEW_ARCHIVE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FR_TYPE_NEW_ARCHIVE_DIALOG))
+#define FR_NEW_ARCHIVE_DIALOG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), FR_TYPE_NEW_ARCHIVE_DIALOG, FrNewArchiveDialogClass))
+
+typedef struct _FrNewArchiveDialog FrNewArchiveDialog;
+typedef struct _FrNewArchiveDialogClass FrNewArchiveDialogClass;
+typedef struct _FrNewArchiveDialogPrivate FrNewArchiveDialogPrivate;
+
+struct _FrNewArchiveDialog {
+	GtkFileChooserDialog parent_instance;
+	FrNewArchiveDialogPrivate *priv;
+};
+
+struct _FrNewArchiveDialogClass {
+	GtkFileChooserDialogClass parent_class;
+};
+
+GType           fr_new_archive_dialog_get_type            (void);
+GtkWidget *     fr_new_archive_dialog_new                 (GtkWindow          *parent,
+							   FrNewArchiveAction  action,
+							   const char         *default_name);
+char *          fr_new_archive_dialog_get_uri             (FrNewArchiveDialog *dialog);
+const char *    fr_new_archive_dialog_get_password        (FrNewArchiveDialog *dialog);
+gboolean        fr_new_archive_dialog_get_encrypt_header  (FrNewArchiveDialog *dialog);
+int             fr_new_archive_dialog_get_volume_size     (FrNewArchiveDialog *dialog);
+
+#endif /* FR_NEW_ARCHIVE_DIALOG_H */
diff --git a/src/fr-window.c b/src/fr-window.c
index 61fc551..566479f 100644
--- a/src/fr-window.c
+++ b/src/fr-window.c
@@ -44,6 +44,7 @@
 #include "fr-archive.h"
 #include "fr-command.h"
 #include "fr-error.h"
+#include "fr-new-archive-dialog.h"
 #include "fr-stock.h"
 #include "fr-window.h"
 #include "file-data.h"
@@ -115,7 +116,7 @@ typedef struct {
 	FrBatchActionType type;
 	void *            data;
 	GFreeFunc         free_func;
-} FRBatchAction;
+} FrBatchAction;
 
 
 typedef struct {
@@ -126,7 +127,7 @@ typedef struct {
 	gboolean   encrypt_header;
 	guint      volume_size;
 	char      *new_file;
-} FRConvertData;
+} FrConvertData;
 
 
 typedef struct {
@@ -292,7 +293,7 @@ struct _FrWindowPrivate {
 	gboolean         ask_to_open_destination_after_extraction;
 	gboolean         destroy_with_error_dialog;
 
-	FRBatchAction    current_batch_action;
+	FrBatchAction    current_batch_action;
 
 	gboolean         give_focus_to_the_list;
 	gboolean         single_click;
@@ -322,7 +323,7 @@ struct _FrWindowPrivate {
 	guint            update_timeout_handle;     /* update file list
 						     * timeout handle. */
 
-	FRConvertData    convert_data;
+	FrConvertData    convert_data;
 
 	gboolean         stoppable;
 	gboolean         closing;
@@ -377,7 +378,7 @@ struct _FrWindowPrivate {
 
 	gboolean          batch_mode;          /* whether we are in a non interactive
 					 	* mode. */
-	GList            *batch_action_list;   /* FRBatchAction * elements */
+	GList            *batch_action_list;   /* FrBatchAction * elements */
 	GList            *batch_action;        /* current action. */
 	char             *batch_title;
 
@@ -392,7 +393,6 @@ struct _FrWindowPrivate {
 	GSettings        *settings_nautilus;
 
 	gulong            theme_changed_handler_id;
-	gboolean          non_interactive;
 	char             *extract_here_dir;
 	gboolean          extract_interact_use_default_dir;
 	gboolean          update_dropped_files;
@@ -413,7 +413,7 @@ fr_window_free_batch_data (FrWindow *window)
 	GList *scan;
 
 	for (scan = window->priv->batch_action_list; scan; scan = scan->next) {
-		FRBatchAction *adata = scan->data;
+		FrBatchAction *adata = scan->data;
 
 		if ((adata->data != NULL) && (adata->free_func != NULL))
 			(*adata->free_func) (adata->data);
@@ -1435,7 +1435,7 @@ fr_window_update_statusbar_list_info (FrWindow *window)
 	goffset  tot_size, sel_size;
 	GList   *scan;
 
-	if (window == NULL)
+	if ((window == NULL) || window->priv->batch_mode)
 		return;
 
 	if (window->archive == NULL) {
@@ -2062,7 +2062,7 @@ fr_window_update_sensitivity (FrWindow *window)
 	no_archive           = (window->archive == NULL) || ! window->priv->archive_present;
 	ro                   = ! no_archive && window->archive->read_only;
 	file_op              = ! no_archive && ! window->priv->archive_new  && ! running;
-	can_store_many_files = fr_archive_is_capable_of (window->archive, FR_ARCHIVE_CAN_STORE_MANY_FILES);
+	can_store_many_files = (window->archive != NULL) && fr_archive_is_capable_of (window->archive, FR_ARCHIVE_CAN_STORE_MANY_FILES);
 	n_selected           = fr_window_get_n_selected_files (window);
 	sel_not_null         = n_selected > 0;
 	one_file_selected    = n_selected == 1;
@@ -2369,7 +2369,7 @@ progress_dialog_update_action_description (FrWindow *window)
 
 
 static gboolean
-fr_window_working_archive_cb (FrCommand  *command,
+fr_window_working_archive_cb (FrArchive  *archive,
 			      const char *archive_filename,
 			      FrWindow   *window)
 {
@@ -2384,9 +2384,9 @@ fr_window_working_archive_cb (FrCommand  *command,
 
 
 static gboolean
-fr_archive_message_cb (FrCommand  *command,
-		      const char *msg,
-		      FrWindow   *window)
+fr_archive_message_cb (FrArchive  *archive,
+		       const char *msg,
+		       FrWindow   *window)
 {
 	if (window->priv->pd_last_message != msg) {
 		g_free (window->priv->pd_last_message);
@@ -2516,7 +2516,7 @@ display_progress_dialog (gpointer data)
 		gtk_dialog_set_response_sensitive (GTK_DIALOG (window->priv->progress_dialog),
 						   GTK_RESPONSE_OK,
 						   window->priv->stoppable);
-		if (! window->priv->non_interactive)
+		if (! window->priv->batch_mode)
 			gtk_widget_show (GTK_WIDGET (window));
 		gtk_widget_hide (window->priv->progress_bar);
 		gtk_widget_show (window->priv->progress_dialog);
@@ -2569,8 +2569,8 @@ open_progress_dialog (FrWindow *window,
 
 static gboolean
 fr_archive_progress_cb (FrArchive *archive,
-		       double     fraction,
-		       FrWindow  *window)
+		        double     fraction,
+		        FrWindow  *window)
 {
 	window->priv->progress_pulse = (fraction < 0.0);
 	if (! window->priv->progress_pulse) {
@@ -2929,6 +2929,10 @@ _handle_archive_operation_error (FrWindow  *window,
 			msg = _("An error occurred while saving the archive.");
 			break;
 
+		case FR_ACTION_RENAMING_FILES:
+			msg = _("An error occurred while renaming the files.");
+			break;
+
 		default:
 			msg = _("An error occurred.");
 			break;
@@ -3008,21 +3012,14 @@ _archive_operation_completed (FrWindow *window,
 		close_progress_dialog (window, FALSE);
 		if (error != NULL) {
 			fr_window_remove_from_recent_list (window, window->priv->archive_uri);
-			if (window->priv->non_interactive) {
+			if (window->priv->batch_mode)
 				fr_window_archive_close (window);
-				fr_window_stop_batch (window);
-			}
 		}
 		else {
 			fr_window_add_to_recent_list (window, window->priv->archive_uri);
-			if (! window->priv->non_interactive)
+			if (! window->priv->batch_mode)
 				gtk_window_present (GTK_WINDOW (window));
 		}
-		continue_batch = FALSE;
-		g_signal_emit (window,
-			       fr_window_signals[ARCHIVE_LOADED],
-			       0,
-			       error == NULL);
 		break;
 
 	case FR_ACTION_LISTING_CONTENT:
@@ -3066,7 +3063,7 @@ _archive_operation_completed (FrWindow *window,
 		fr_window_update_title (window);
 		fr_window_go_to_location (window, fr_window_get_current_location (window), TRUE);
 		fr_window_update_dir_tree (window);
-		if (! window->priv->batch_mode && window->priv->non_interactive)
+		if (! window->priv->batch_mode)
 			gtk_window_present (GTK_WINDOW (window));
 		break;
 
@@ -3114,215 +3111,26 @@ _archive_operation_completed (FrWindow *window,
 		break;
 	}
 
-	if (window->priv->batch_action == NULL) {
-		fr_window_update_sensitivity (window);
-		fr_window_update_statusbar_list_info (window);
-	}
-
-	if (continue_batch) {
-		if (error != NULL)
-			fr_window_stop_batch (window);
-		else
-			fr_window_exec_next_batch_action (window);
-	}
+	if (continue_batch)
+		fr_window_exec_next_batch_action (window);
+	else
+		fr_window_stop_batch (window);
 }
 
 
-#if 0  /* FIXME: libarchive */
-
-
 static void
-action_performed (FrArchive   *archive,
-		  FrAction     action,
-		  FrError *error,
-		  gpointer     data)
+_archive_operation_cancelled (FrWindow *window,
+			      FrAction  action)
 {
-	FrWindow *window = data;
-	gboolean  continue_batch = FALSE;
-	char     *archive_dir;
-	gboolean  temp_dir;
-
-#ifdef DEBUG
-	debug (DEBUG_INFO, "%s [DONE] (FR::Window)\n", action_names[action]);
-#endif
-
-	fr_window_stop_activity_mode (window);
-	fr_window_pop_message (window);
-
-	continue_batch = _handle_archive_operation_error (window, archive, action, error);
-
-	if ((error->type == FR_ERROR_ASK_PASSWORD)
-	    || (error->type == FR_ERROR_UNSUPPORTED_FORMAT)
-	    /*|| (error->type == FR_PROC_ERROR_BAD_CHARSET)*/)
-	{
-		return;
-	}
-
-	switch (action) {
-	case FR_ACTION_CREATING_NEW_ARCHIVE:
-	case FR_ACTION_CREATING_ARCHIVE:
-		close_progress_dialog (window, FALSE);
-		if (error->type != FR_ERROR_STOPPED) {
-			fr_window_history_clear (window);
-			fr_window_go_to_location (window, "/", TRUE);
-			fr_window_update_dir_tree (window);
-			fr_window_update_title (window);
-			fr_window_update_sensitivity (window);
-		}
-		break;
-
-	case FR_ACTION_LOADING_ARCHIVE:
-		close_progress_dialog (window, FALSE);
-		if (error->type != FR_ERROR_NONE) {
-			fr_window_remove_from_recent_list (window, window->priv->archive_uri);
-			if (window->priv->non_interactive) {
-				fr_window_archive_close (window);
-				fr_window_stop_batch (window);
-			}
-		}
-		else {
-			fr_window_add_to_recent_list (window, window->priv->archive_uri);
-			if (! window->priv->non_interactive)
-				gtk_window_present (GTK_WINDOW (window));
-		}
-		continue_batch = FALSE;
-		g_signal_emit (window,
-			       fr_window_signals[ARCHIVE_LOADED],
-			       0,
-			       error->type == FR_ERROR_NONE);
-		break;
-
-	case FR_ACTION_LISTING_CONTENT:
-		/* update the uri because multi-volume archives can have
-		 * a different name after loading. */
-		g_free (window->priv->archive_uri);
-		window->priv->archive_uri = g_file_get_uri (window->archive->file);
-
-		close_progress_dialog (window, FALSE);
-		if (error->type != FR_ERROR_NONE) {
-			fr_window_remove_from_recent_list (window, window->priv->archive_uri);
-			fr_window_archive_close (window);
-			fr_window_set_password (window, NULL);
-			break;
-		}
-
-		archive_dir = _g_path_remove_level (window->priv->archive_uri);
-		temp_dir = _g_path_is_temp_dir (archive_dir);
-		if (! window->priv->archive_present) {
-			window->priv->archive_present = TRUE;
-
-			fr_window_history_clear (window);
-			fr_window_history_add (window, "/");
-
-			if (! temp_dir) {
-				fr_window_set_open_default_dir (window, archive_dir);
-				fr_window_set_add_default_dir (window, archive_dir);
-				if (! window->priv->freeze_default_dir)
-					fr_window_set_extract_default_dir (window, archive_dir, FALSE);
-			}
-
-			window->priv->archive_new = FALSE;
-		}
-		g_free (archive_dir);
-
-		if (! temp_dir)
-			fr_window_add_to_recent_list (window, window->priv->archive_uri);
-
-		fr_window_update_title (window);
-		fr_window_go_to_location (window, fr_window_get_current_location (window), TRUE);
-		fr_window_update_dir_tree (window);
-		if (! window->priv->batch_mode && window->priv->non_interactive)
-			gtk_window_present (GTK_WINDOW (window));
-		break;
-
-	case FR_ACTION_DELETING_FILES:
-		close_progress_dialog (window, FALSE);
-		if (error->type != FR_ERROR_STOPPED)
-			fr_window_archive_reload (window);
-		return;
-
-	case FR_ACTION_ADDING_FILES:
-		close_progress_dialog (window, FALSE);
-
-		/* update the uri because multi-volume archives can have
-		 * a different name after creation. */
-		g_free (window->priv->archive_uri);
-		window->priv->archive_uri = g_file_get_uri (window->archive->file);
-
-		if (error->type == FR_ERROR_NONE) {
-			if (window->priv->archive_new)
-				window->priv->archive_new = FALSE;
-			fr_window_add_to_recent_list (window, window->priv->archive_uri);
-		}
-		if (! window->priv->batch_mode && (error->type != FR_ERROR_STOPPED)) {
-			fr_window_archive_reload (window);
-			return;
-		}
-		break;
-
-	case FR_ACTION_TESTING_ARCHIVE:
-		close_progress_dialog (window, FALSE);
-		if (error->type == FR_ERROR_NONE)
-			fr_window_view_last_output (window, _("Test Result"));
-		return;
-
-	case FR_ACTION_EXTRACTING_FILES:
-		if (error->type != FR_ERROR_NONE) {
-			if (window->priv->convert_data.converting) {
-				_g_path_remove_directory (window->priv->convert_data.temp_dir);
-				_fr_window_convert_data_free (window, TRUE);
-			}
-			break;
-		}
-		if (window->priv->convert_data.converting) {
-			char *source_dir;
-
-			source_dir = g_filename_to_uri (window->priv->convert_data.temp_dir, NULL, NULL);
-			fr_archive_add_with_wildcard (window->priv->convert_data.new_archive,
-						      "*",
-						      NULL,
-						      NULL,
-						      source_dir,
-						      NULL,
-						      FALSE,
-						      TRUE,
-						      window->priv->convert_data.password,
-						      window->priv->convert_data.encrypt_header,
-						      window->priv->compression,
-						      window->priv->convert_data.volume_size);
-			g_free (source_dir);
-		}
-		else {
-			if (window->priv->ask_to_open_destination_after_extraction)
-				open_progress_dialog_with_open_destination (window);
-			else
-				close_progress_dialog (window, FALSE);
-		}
-		break;
-
-	default:
-		close_progress_dialog (window, FALSE);
-		continue_batch = FALSE;
-		break;
-	}
+	GError *error;
 
-	if (window->priv->batch_action == NULL) {
-		fr_window_update_sensitivity (window);
-		fr_window_update_statusbar_list_info (window);
-	}
+	error = g_error_new_literal (FR_ERROR, FR_ERROR_STOPPED, "");
+	_archive_operation_completed (window, action, error);
 
-	if (continue_batch) {
-		if (error->type != FR_ERROR_NONE)
-			fr_window_stop_batch (window);
-		else
-			fr_window_exec_next_batch_action (window);
-	}
+	g_error_free (error);
 }
 
 
-#endif
-
-
 /* -- selections -- */
 
 
@@ -4035,6 +3843,66 @@ get_clipboard_data_from_selection_data (FrWindow   *window,
 
 
 static void
+new_archive_dialog_response_cb (GtkDialog *dialog,
+				int        response,
+				gpointer   user_data)
+{
+	FrWindow   *window = user_data;
+	char       *uri;
+	GtkWidget  *archive_window;
+	gboolean    new_window;
+	const char *password;
+	gboolean    encrypt_header;
+	int         volume_size;
+
+	if ((response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT)) {
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+		_archive_operation_cancelled (window, FR_ACTION_CREATING_NEW_ARCHIVE);
+		return;
+	}
+
+	uri = fr_new_archive_dialog_get_uri (FR_NEW_ARCHIVE_DIALOG (dialog));
+	if (uri == NULL)
+		return;
+
+	new_window = fr_window_archive_is_present (window) && ! fr_window_is_batch_mode (window);
+	if (new_window)
+		archive_window = fr_window_new ();
+	else
+		archive_window = (GtkWidget *) window;
+
+	password = fr_new_archive_dialog_get_password (FR_NEW_ARCHIVE_DIALOG (dialog));
+	encrypt_header = fr_new_archive_dialog_get_encrypt_header (FR_NEW_ARCHIVE_DIALOG (dialog));
+	volume_size = fr_new_archive_dialog_get_volume_size (FR_NEW_ARCHIVE_DIALOG (dialog));
+
+	fr_window_set_password (FR_WINDOW (archive_window), password);
+	fr_window_set_encrypt_header (FR_WINDOW (archive_window), encrypt_header);
+	fr_window_set_volume_size (FR_WINDOW (archive_window), volume_size);
+
+	if (fr_window_archive_new (FR_WINDOW (archive_window), uri)) {
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+		if (! fr_window_is_batch_mode (FR_WINDOW (archive_window)))
+			gtk_window_present (GTK_WINDOW (archive_window));
+		_archive_operation_completed (window, FR_ACTION_CREATING_NEW_ARCHIVE, NULL);
+	}
+	else {
+		GError *error;
+
+		if (new_window)
+			gtk_widget_destroy (archive_window);
+
+		error = g_error_new_literal (FR_ERROR, FR_ERROR_GENERIC, _("Archive type not supported."));
+		window->priv->load_error_parent_window = GTK_WINDOW (dialog);
+		_handle_archive_operation_error (window, NULL, FR_ACTION_CREATING_ARCHIVE, error, NULL, NULL);
+
+		g_error_free (error);
+	}
+
+	g_free (uri);
+}
+
+
+static void
 fr_window_drag_data_received  (GtkWidget          *widget,
 			       GdkDragContext     *context,
 			       gint                x,
@@ -4159,6 +4027,7 @@ fr_window_drag_data_received  (GtkWidget          *widget,
 				char       *local_path = NULL;
 				char       *utf8_path = NULL;
 				const char *archive_name;
+				GtkWidget  *dialog;
 
 				fr_window_free_batch_data (window);
 				fr_window_append_batch_action (window,
@@ -4189,9 +4058,17 @@ fr_window_drag_data_received  (GtkWidget          *widget,
 					archive_name = _g_path_get_file_name (utf8_path);
 				}
 
-				show_new_archive_dialog (window, archive_name);
-				g_free (utf8_path);
+				dialog = fr_new_archive_dialog_new (GTK_WINDOW (window),
+								    FR_NEW_ARCHIVE_ACTION_SAVE_AS,
+								    archive_name);
+				gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), fr_window_get_open_default_dir (window));
+				g_signal_connect (G_OBJECT (dialog),
+						  "response",
+						  G_CALLBACK (new_archive_dialog_response_cb),
+						  window);
+				gtk_window_present (GTK_WINDOW (dialog));
 
+				g_free (utf8_path);
 				g_free (folder);
 			}
 		}
@@ -5128,9 +5005,9 @@ theme_changed_cb (GtkIconTheme *theme, FrWindow *window)
 
 
 static gboolean
-fr_archive_stoppable_cb (FrCommand  *command,
-			gboolean    stoppable,
-			FrWindow   *window)
+fr_archive_stoppable_cb (FrArchive *archive,
+			 gboolean   stoppable,
+			 FrWindow  *window)
 {
 	window->priv->stoppable = stoppable;
 	set_sensitive (window, "Stop", stoppable);
@@ -5500,7 +5377,6 @@ fr_window_construct (FrWindow *window)
 	window->priv->batch_action_list = NULL;
 	window->priv->batch_action = NULL;
 	window->priv->extract_interact_use_default_dir = FALSE;
-	window->priv->non_interactive = FALSE;
 
 	window->priv->password = NULL;
 	window->priv->compression = g_settings_get_enum (window->priv->settings_general, PREF_GENERAL_COMPRESSION_LEVEL);
@@ -6037,39 +5913,13 @@ fr_window_archive_new (FrWindow   *window,
 		_fr_window_set_archive_uri (window, uri);
 		window->priv->archive_present = TRUE;
 		window->priv->archive_new = TRUE;
+
+		g_object_unref (archive);
 	}
 
-	g_object_unref (archive);
 	g_object_unref (file);
 
 	return archive != NULL;
-
-	/* FIXME: libarchive */
-#if 0
-
-	if (! fr_archive_create (window->archive, uri)) {
-		GtkWindow *file_sel = g_object_get_data (G_OBJECT (window), "fr_file_sel");
-
-		window->priv->load_error_parent_window = file_sel;
-		fr_archive_action_completed (window->archive,
-					     FR_ACTION_CREATING_NEW_ARCHIVE,
-					     FR_ERROR_GENERIC,
-					     _("Archive type not supported."));
-
-		return FALSE;
-	}
-
-	_fr_window_set_archive_uri (window, uri);
-	window->priv->archive_present = TRUE;
-	window->priv->archive_new = TRUE;
-
-	fr_archive_action_completed (window->archive,
-				     FR_ACTION_CREATING_NEW_ARCHIVE,
-				     FR_ERROR_NONE,
-				     NULL);
-
-	return TRUE;
-#endif
 }
 
 
@@ -6109,6 +5959,12 @@ archive_open_ready_cb (GObject      *source_object,
 	GError    *error = NULL;
 
 	archive = fr_archive_open_finish (G_FILE (source_object), result, &error);
+
+	g_signal_emit (window,
+		       fr_window_signals[ARCHIVE_LOADED],
+		       0,
+		       archive != NULL);
+
 	if (archive == NULL) {
 		_archive_operation_completed (window, FR_ACTION_LOADING_ARCHIVE, error);
 		g_error_free (error);
@@ -6140,6 +5996,7 @@ fr_window_archive_open (FrWindow   *current_window,
 	window->priv->give_focus_to_the_list = TRUE;
 	window->priv->load_error_parent_window = parent;
 
+	/* this is used to reload the archive after asking a password */
 	fr_window_set_current_batch_action (window,
 					    FR_BATCH_ACTION_LOAD,
 					    g_strdup (window->priv->archive_uri),
@@ -6213,316 +6070,38 @@ fr_window_archive_is_present (FrWindow *window)
 }
 
 
-typedef struct {
-	char     *uri;
-	char     *password;
-	gboolean  encrypt_header;
-	guint     volume_size;
-} SaveAsData;
-
-
-static SaveAsData *
-save_as_data_new (const char *uri,
-		  const char *password,
-		  gboolean    encrypt_header,
-	  	  guint       volume_size)
+void
+fr_window_archive_reload (FrWindow *window)
 {
-	SaveAsData *sdata;
-
-	sdata = g_new0 (SaveAsData, 1);
-	if (uri != NULL)
-		sdata->uri = g_strdup (uri);
-	if (password != NULL)
-		sdata->password = g_strdup (password);
-	sdata->encrypt_header = encrypt_header;
-	sdata->volume_size = volume_size;
-
-	return sdata;
-}
-
+	g_return_if_fail (window != NULL);
 
-static void
-save_as_data_free (SaveAsData *sdata)
-{
-	if (sdata == NULL)
+	if (window->priv->activity_ref > 0)
 		return;
-	g_free (sdata->uri);
-	g_free (sdata->password);
-	g_free (sdata);
+	if (window->priv->archive_new)
+		return;
+	if (window->archive == NULL)
+		return;
+
+	fr_window_archive_load (window);
 }
 
 
-#if 0 /* FIXME: libarchive */
+/**/
 
 
 static void
-convert__action_performed (FrArchive   *archive,
-			   FrAction     action,
-			   FrError *error,
-			   gpointer     data)
+archive_add_files_ready_cb (GObject      *source_object,
+			    GAsyncResult *result,
+			    gpointer      user_data)
 {
-	FrWindow *window = data;
-
-#ifdef DEBUG
-	debug (DEBUG_INFO, "%s [CONVERT::DONE] (FR::Window)\n", action_names[action]);
-#endif
+	FrWindow *window = user_data;
+	GError   *error = NULL;
 
-	if ((action == FR_ACTION_GETTING_FILE_LIST) || (action == FR_ACTION_ADDING_FILES)) {
-		fr_window_stop_activity_mode (window);
-		fr_window_pop_message (window);
-		close_progress_dialog (window, FALSE);
-	}
+	fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
+	_archive_operation_completed (window, FR_ACTION_ADDING_FILES, error);
 
-	if (action != FR_ACTION_ADDING_FILES)
-		return;
-
-	_handle_archive_operation_error (window, archive, action, error);
-
-	if (error->type == FR_ERROR_NONE)
-		open_progress_dialog_with_open_archive (window);
-
-	_g_path_remove_directory (window->priv->convert_data.temp_dir);
-	_fr_window_convert_data_free (window, FALSE);
-
-	fr_window_update_sensitivity (window);
-	fr_window_update_statusbar_list_info (window);
-}
-
-
-#endif
-
-
-#if 0
-
-
-if (error != NULL) {
-	/* FIXME
-	if (window->priv->convert_data.converting) {
-		_g_path_remove_directory (window->priv->convert_data.temp_dir);
-		_fr_window_convert_data_free (window, TRUE);
-	}
-	*/
-	break;
-}
-/* FIXME
-if (window->priv->convert_data.converting) {
-	char *source_dir;
-
-	source_dir = g_filename_to_uri (window->priv->convert_data.temp_dir, NULL, NULL);
-	fr_archive_add_with_wildcard (window->priv->convert_data.new_archive,
-				      "*",
-				      NULL,
-				      NULL,
-				      source_dir,
-				      NULL,
-				      FALSE,
-				      TRUE,
-				      window->priv->convert_data.password,
-				      window->priv->convert_data.encrypt_header,
-				      window->priv->compression,
-				      window->priv->convert_data.volume_size);
-	g_free (source_dir);
-}
-else */ {
-	if (window->priv->ask_to_open_destination_after_extraction)
-		open_progress_dialog_with_open_destination (window);
-	else
-		close_progress_dialog (window, FALSE);
-}
-
-
-#endif
-
-
-static void
-archive_add_ready_for_conversion_cb (GObject      *source_object,
-				     GAsyncResult *result,
-				     gpointer      user_data)
-{
-	FrWindow *window = user_data;
-	GError   *error = NULL;
-
-	fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
-
-	fr_window_stop_activity_mode (window);
-	fr_window_pop_message (window);
-	close_progress_dialog (window, FALSE);
-
-	if (error == NULL)
-		open_progress_dialog_with_open_archive (window);
-	else
-		_handle_archive_operation_error (window,
-						 window->priv->convert_data.new_archive,
-						 FR_ACTION_ADDING_FILES,
-						 error,
-						 NULL,
-						 NULL);
-
-	_g_path_remove_directory (window->priv->convert_data.temp_dir);
-	_fr_window_convert_data_free (window, FALSE);
-
-	fr_window_update_sensitivity (window);
-	fr_window_update_statusbar_list_info (window);
-}
-
-
-static void
-archive_extraction_ready_for_convertion_cb (GObject      *source_object,
-					    GAsyncResult *result,
-					    gpointer      user_data)
-{
-	FrWindow *window = user_data;
-	GError   *error = NULL;
-	char     *source_dir;
-
-	if (! fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error)) {
-		_g_path_remove_directory (window->priv->convert_data.temp_dir);
-		_fr_window_convert_data_free (window, TRUE);
-		_archive_operation_completed (window, FR_ACTION_EXTRACTING_FILES, error);
-		return;
-	}
-
-	source_dir = g_filename_to_uri (window->priv->convert_data.temp_dir, NULL, NULL);
-	fr_archive_add_with_wildcard (window->priv->convert_data.new_archive,
-				      "*",
-				      NULL,
-				      NULL,
-				      source_dir,
-				      NULL,
-				      FALSE,
-				      TRUE,
-				      window->priv->convert_data.password,
-				      window->priv->convert_data.encrypt_header,
-				      window->priv->compression,
-				      window->priv->convert_data.volume_size,
-				      window->priv->cancellable,
-				      archive_add_ready_for_conversion_cb,
-				      window);
-
-	g_free (source_dir);
-}
-
-
-void
-fr_window_archive_save_as (FrWindow   *window,
-			   const char *uri,
-			   const char *password,
-			   gboolean    encrypt_header,
-			   guint       volume_size)
-{
-	GFile *file;
-
-	g_return_if_fail (window != NULL);
-	g_return_if_fail (uri != NULL);
-	g_return_if_fail (window->archive != NULL);
-
-	_fr_window_convert_data_free (window, TRUE);
-	window->priv->convert_data.new_file = g_strdup (uri);
-
-	/* create the new archive */
-
-	file = g_file_new_for_uri (uri);
-	window->priv->convert_data.new_archive = fr_archive_create (file);
-	g_object_unref (file);
-
-	if (window->priv->convert_data.new_archive == NULL) {
-		GtkWidget *d;
-		char      *utf8_name;
-		char      *message;
-
-		utf8_name = _g_uri_display_basename (uri);
-		message = g_strdup_printf (_("Could not save the archive \"%s\""), utf8_name);
-		g_free (utf8_name);
-
-		d = _gtk_error_dialog_new (GTK_WINDOW (window),
-					   GTK_DIALOG_DESTROY_WITH_PARENT,
-					   NULL,
-					   message,
-					   "%s",
-					   _("Archive type not supported."));
-		gtk_dialog_run (GTK_DIALOG (d));
-		gtk_widget_destroy (d);
-
-		g_free (message);
-
-		return;
-	}
-
-	if (password != NULL) {
-		window->priv->convert_data.password = g_strdup (password);
-		window->priv->convert_data.encrypt_header = encrypt_header;
-	}
-	else
-		window->priv->convert_data.encrypt_header = FALSE;
-	window->priv->convert_data.volume_size = volume_size;
-
-	fr_window_set_current_batch_action (window,
-					    FR_BATCH_ACTION_SAVE_AS,
-					    save_as_data_new (uri, password, encrypt_header, volume_size),
-					    (GFreeFunc) save_as_data_free);
-
-	g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
-			  "progress",
-			  G_CALLBACK (fr_archive_progress_cb),
-			  window);
-	g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
-			  "message",
-			  G_CALLBACK (fr_archive_message_cb),
-			  window);
-	g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
-			  "stoppable",
-			  G_CALLBACK (fr_archive_stoppable_cb),
-			  window);
-
-	window->priv->convert_data.converting = TRUE;
-	window->priv->convert_data.temp_dir = _g_path_get_temp_work_dir (NULL);
-
-	fr_archive_extract_to_local (window->archive,
-				     NULL,
-				     window->priv->convert_data.temp_dir,
-				     NULL,
-				     TRUE,
-				     FALSE,
-				     FALSE,
-				     window->priv->password,
-				     window->priv->cancellable,
-				     archive_extraction_ready_for_convertion_cb,
-				     window);
-}
-
-
-void
-fr_window_archive_reload (FrWindow *window)
-{
-	g_return_if_fail (window != NULL);
-
-	if (window->priv->activity_ref > 0)
-		return;
-	if (window->priv->archive_new)
-		return;
-	if (window->archive == NULL)
-		return;
-
-	fr_window_archive_load (window);
-}
-
-
-/**/
-
-
-static void
-archive_add_files_ready_cb (GObject      *source_object,
-			    GAsyncResult *result,
-			    gpointer      user_data)
-{
-	FrWindow *window = user_data;
-	GError   *error = NULL;
-
-	fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
-	_archive_operation_completed (window, FR_ACTION_ADDING_FILES, error);
-
-	_g_error_free (error);
-}
+	_g_error_free (error);
+}
 
 
 void
@@ -7349,159 +6928,467 @@ fr_window_go_forward (FrWindow *window)
 {
 	g_return_if_fail (window != NULL);
 
-	if (window->priv->history == NULL)
-		return;
-	if (window->priv->history_current == NULL)
-		return;
-	if (window->priv->history_current->prev == NULL)
-		return;
-	window->priv->history_current = window->priv->history_current->prev;
+	if (window->priv->history == NULL)
+		return;
+	if (window->priv->history_current == NULL)
+		return;
+	if (window->priv->history_current->prev == NULL)
+		return;
+	window->priv->history_current = window->priv->history_current->prev;
+
+	fr_window_go_to_location (window, window->priv->history_current->data, FALSE);
+}
+
+
+void
+fr_window_set_list_mode (FrWindow         *window,
+			 FrWindowListMode  list_mode)
+{
+	g_return_if_fail (window != NULL);
+
+	window->priv->list_mode = window->priv->last_list_mode = list_mode;
+	if (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT) {
+		fr_window_history_clear (window);
+		fr_window_history_add (window, "/");
+	}
+
+	g_settings_set_enum (window->priv->settings_listing, PREF_LISTING_LIST_MODE, window->priv->last_list_mode);
+	g_settings_set_boolean (window->priv->settings_listing, PREF_LISTING_SHOW_PATH, (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT));
+
+	fr_window_update_file_list (window, TRUE);
+	fr_window_update_dir_tree (window);
+	fr_window_update_current_location (window);
+}
+
+
+GtkTreeModel *
+fr_window_get_list_store (FrWindow *window)
+{
+	return GTK_TREE_MODEL (window->priv->list_store);
+}
+
+
+void
+fr_window_find (FrWindow *window)
+{
+	window->priv->filter_mode = TRUE;
+	gtk_widget_show (window->priv->filter_bar);
+	gtk_widget_grab_focus (window->priv->filter_entry);
+}
+
+
+void
+fr_window_select_all (FrWindow *window)
+{
+	gtk_tree_selection_select_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view)));
+}
+
+
+void
+fr_window_unselect_all (FrWindow *window)
+{
+	gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view)));
+}
+
+
+void
+fr_window_set_sort_type (FrWindow     *window,
+			 GtkSortType   sort_type)
+{
+	window->priv->sort_type = sort_type;
+	fr_window_update_list_order (window);
+}
+
+
+void
+fr_window_stop (FrWindow *window)
+{
+	if (! window->priv->stoppable)
+		return;
+
+	g_cancellable_cancel (window->priv->cancellable);
+
+	/* FIXME: libarchive
+	if (window->priv->activity_ref > 0)
+		fr_archive_stop (window->archive);
+
+	if (window->priv->convert_data.converting)
+		_fr_window_convert_data_free (window, TRUE);
+	*/
+}
+
+
+/* -- start/stop activity mode -- */
+
+
+static int
+activity_cb (gpointer data)
+{
+	FrWindow *window = data;
+
+	if ((window->priv->pd_progress_bar != NULL) && window->priv->progress_pulse)
+		gtk_progress_bar_pulse (GTK_PROGRESS_BAR (window->priv->pd_progress_bar));
+	if (window->priv->progress_pulse)
+		gtk_progress_bar_pulse (GTK_PROGRESS_BAR (window->priv->progress_bar));
+
+	return TRUE;
+}
+
+
+/* FIXME: libarchive, call once for each async operation */
+void
+fr_window_start_activity_mode (FrWindow *window)
+{
+	g_return_if_fail (window != NULL);
+
+	if (window->priv->activity_ref++ > 0)
+		return;
+
+	window->priv->activity_timeout_handle = g_timeout_add (ACTIVITY_DELAY,
+							       activity_cb,
+							       window);
+	fr_window_update_sensitivity (window);
+}
+
+
+void
+fr_window_stop_activity_mode (FrWindow *window)
+{
+	g_return_if_fail (window != NULL);
+
+	if (window->priv->activity_ref == 0)
+		return;
+
+	window->priv->activity_ref--;
+
+	if (window->priv->activity_ref > 0)
+		return;
+
+	if (window->priv->activity_timeout_handle == 0)
+		return;
+
+	g_source_remove (window->priv->activity_timeout_handle);
+	window->priv->activity_timeout_handle = 0;
+
+	if (! gtk_widget_get_realized (GTK_WIDGET (window)))
+		return;
+
+	if (window->priv->progress_dialog != NULL)
+		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->pd_progress_bar), 0.0);
+
+	if (! window->priv->batch_mode) {
+		if (window->priv->progress_bar != NULL)
+			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->progress_bar), 0.0);
+		fr_window_update_sensitivity (window);
+	}
+}
+
+
+void
+fr_window_action_new_archive (FrWindow *window)
+{
+	GtkWidget *dialog;
+
+	dialog = fr_new_archive_dialog_new (GTK_WINDOW (window),
+					    FR_NEW_ARCHIVE_ACTION_NEW,
+					    NULL);
+	gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), fr_window_get_open_default_dir (window));
+	g_signal_connect (G_OBJECT (dialog),
+			  "response",
+			  G_CALLBACK (new_archive_dialog_response_cb),
+			  window);
+	gtk_window_present (GTK_WINDOW (dialog));
+}
+
+
+/* -- fr_window_action_save_as -- */
+
+
+typedef struct {
+	char     *uri;
+	char     *password;
+	gboolean  encrypt_header;
+	guint     volume_size;
+} SaveAsData;
+
+
+static SaveAsData *
+save_as_data_new (const char *uri,
+		  const char *password,
+		  gboolean    encrypt_header,
+	  	  guint       volume_size)
+{
+	SaveAsData *sdata;
+
+	sdata = g_new0 (SaveAsData, 1);
+	if (uri != NULL)
+		sdata->uri = g_strdup (uri);
+	if (password != NULL)
+		sdata->password = g_strdup (password);
+	sdata->encrypt_header = encrypt_header;
+	sdata->volume_size = volume_size;
+
+	return sdata;
+}
+
+
+static void
+save_as_data_free (SaveAsData *sdata)
+{
+	if (sdata == NULL)
+		return;
+	g_free (sdata->uri);
+	g_free (sdata->password);
+	g_free (sdata);
+}
+
+
+static void
+archive_add_ready_for_conversion_cb (GObject      *source_object,
+				     GAsyncResult *result,
+				     gpointer      user_data)
+{
+	FrWindow *window = user_data;
+	GError   *error = NULL;
+
+	fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
+
+	fr_window_stop_activity_mode (window);
+	fr_window_pop_message (window);
+	close_progress_dialog (window, FALSE);
+
+	if (error == NULL)
+		open_progress_dialog_with_open_archive (window);
+	else
+		_handle_archive_operation_error (window,
+						 window->priv->convert_data.new_archive,
+						 FR_ACTION_ADDING_FILES,
+						 error,
+						 NULL,
+						 NULL);
+
+	_g_path_remove_directory (window->priv->convert_data.temp_dir);
+	_fr_window_convert_data_free (window, FALSE);
 
-	fr_window_go_to_location (window, window->priv->history_current->data, FALSE);
+	if (window->priv->batch_mode)
+		fr_window_exec_next_batch_action (window);
+	else
+		fr_window_stop_batch (window);
 }
 
 
-void
-fr_window_set_list_mode (FrWindow         *window,
-			 FrWindowListMode  list_mode)
+static void
+archive_extraction_ready_for_convertion_cb (GObject      *source_object,
+					    GAsyncResult *result,
+					    gpointer      user_data)
 {
-	g_return_if_fail (window != NULL);
+	FrWindow *window = user_data;
+	GError   *error = NULL;
+	char     *source_dir;
 
-	window->priv->list_mode = window->priv->last_list_mode = list_mode;
-	if (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT) {
-		fr_window_history_clear (window);
-		fr_window_history_add (window, "/");
+	if (! fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error)) {
+		_g_path_remove_directory (window->priv->convert_data.temp_dir);
+		_fr_window_convert_data_free (window, TRUE);
+		_archive_operation_completed (window, FR_ACTION_EXTRACTING_FILES, error);
+		return;
 	}
 
-	g_settings_set_enum (window->priv->settings_listing, PREF_LISTING_LIST_MODE, window->priv->last_list_mode);
-	g_settings_set_boolean (window->priv->settings_listing, PREF_LISTING_SHOW_PATH, (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT));
+	source_dir = g_filename_to_uri (window->priv->convert_data.temp_dir, NULL, NULL);
+	fr_archive_add_with_wildcard (window->priv->convert_data.new_archive,
+				      "*",
+				      NULL,
+				      NULL,
+				      source_dir,
+				      NULL,
+				      FALSE,
+				      TRUE,
+				      window->priv->convert_data.password,
+				      window->priv->convert_data.encrypt_header,
+				      window->priv->compression,
+				      window->priv->convert_data.volume_size,
+				      window->priv->cancellable,
+				      archive_add_ready_for_conversion_cb,
+				      window);
 
-	fr_window_update_file_list (window, TRUE);
-	fr_window_update_dir_tree (window);
-	fr_window_update_current_location (window);
+	g_free (source_dir);
 }
 
 
-GtkTreeModel *
-fr_window_get_list_store (FrWindow *window)
+static void
+fr_window_archive_save_as (FrWindow   *window,
+			   const char *uri,
+			   const char *password,
+			   gboolean    encrypt_header,
+			   guint       volume_size)
 {
-	return GTK_TREE_MODEL (window->priv->list_store);
-}
-
+	GFile *file;
 
-void
-fr_window_find (FrWindow *window)
-{
-	window->priv->filter_mode = TRUE;
-	gtk_widget_show (window->priv->filter_bar);
-	gtk_widget_grab_focus (window->priv->filter_entry);
-}
+	g_return_if_fail (window != NULL);
+	g_return_if_fail (uri != NULL);
+	g_return_if_fail (window->archive != NULL);
 
+	_fr_window_convert_data_free (window, TRUE);
+	window->priv->convert_data.new_file = g_strdup (uri);
 
-void
-fr_window_select_all (FrWindow *window)
-{
-	gtk_tree_selection_select_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view)));
-}
+	/* create the new archive */
 
+	file = g_file_new_for_uri (uri);
+	window->priv->convert_data.new_archive = fr_archive_create (file);
+	g_object_unref (file);
 
-void
-fr_window_unselect_all (FrWindow *window)
-{
-	gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view)));
-}
+	if (window->priv->convert_data.new_archive == NULL) {
+		GtkWidget *d;
+		char      *utf8_name;
+		char      *message;
 
+		utf8_name = _g_uri_display_basename (uri);
+		message = g_strdup_printf (_("Could not save the archive \"%s\""), utf8_name);
+		g_free (utf8_name);
 
-void
-fr_window_set_sort_type (FrWindow     *window,
-			 GtkSortType   sort_type)
-{
-	window->priv->sort_type = sort_type;
-	fr_window_update_list_order (window);
-}
+		d = _gtk_error_dialog_new (GTK_WINDOW (window),
+					   GTK_DIALOG_DESTROY_WITH_PARENT,
+					   NULL,
+					   message,
+					   "%s",
+					   _("Archive type not supported."));
+		gtk_dialog_run (GTK_DIALOG (d));
+		gtk_widget_destroy (d);
 
+		g_free (message);
 
-void
-fr_window_stop (FrWindow *window)
-{
-	if (! window->priv->stoppable)
 		return;
+	}
 
-	g_cancellable_cancel (window->priv->cancellable);
+	if (password != NULL) {
+		window->priv->convert_data.password = g_strdup (password);
+		window->priv->convert_data.encrypt_header = encrypt_header;
+	}
+	else
+		window->priv->convert_data.encrypt_header = FALSE;
+	window->priv->convert_data.volume_size = volume_size;
 
-	/* FIXME: libarchive
-	if (window->priv->activity_ref > 0)
-		fr_archive_stop (window->archive);
+	fr_window_set_current_batch_action (window,
+					    FR_BATCH_ACTION_SAVE_AS,
+					    save_as_data_new (uri, password, encrypt_header, volume_size),
+					    (GFreeFunc) save_as_data_free);
 
-	if (window->priv->convert_data.converting)
-		_fr_window_convert_data_free (window, TRUE);
-	*/
-}
+	g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
+			  "progress",
+			  G_CALLBACK (fr_archive_progress_cb),
+			  window);
+	g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
+			  "message",
+			  G_CALLBACK (fr_archive_message_cb),
+			  window);
+	g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
+			  "stoppable",
+			  G_CALLBACK (fr_archive_stoppable_cb),
+			  window);
+	g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
+			  "working_archive",
+			  G_CALLBACK (fr_window_working_archive_cb),
+			  window);
 
+	window->priv->convert_data.converting = TRUE;
+	window->priv->convert_data.temp_dir = _g_path_get_temp_work_dir (NULL);
 
-/* -- start/stop activity mode -- */
+	fr_archive_extract_to_local (window->archive,
+				     NULL,
+				     window->priv->convert_data.temp_dir,
+				     NULL,
+				     TRUE,
+				     TRUE,
+				     FALSE,
+				     window->priv->password,
+				     window->priv->cancellable,
+				     archive_extraction_ready_for_convertion_cb,
+				     window);
+}
 
 
-static int
-activity_cb (gpointer data)
+static void
+save_as_archive_dialog_response_cb (GtkDialog *dialog,
+				    int        response,
+				    gpointer   user_data)
 {
-	FrWindow *window = data;
+	FrWindow   *window = user_data;
+	char       *uri;
+	const char *password;
+	gboolean    encrypt_header;
+	int         volume_size;
+	GSettings  *settings;
+
+	if ((response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT)) {
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+		_archive_operation_cancelled (window, FR_ACTION_CREATING_ARCHIVE);
+		return;
+	}
 
-	if ((window->priv->pd_progress_bar != NULL) && window->priv->progress_pulse)
-		gtk_progress_bar_pulse (GTK_PROGRESS_BAR (window->priv->pd_progress_bar));
-	if (window->priv->progress_pulse)
-		gtk_progress_bar_pulse (GTK_PROGRESS_BAR (window->priv->progress_bar));
+	if (response != GTK_RESPONSE_OK)
+		return;
 
-	return TRUE;
-}
+	uri = fr_new_archive_dialog_get_uri (FR_NEW_ARCHIVE_DIALOG (dialog));
+	if (uri == NULL)
+		return;
 
+	password = fr_new_archive_dialog_get_password (FR_NEW_ARCHIVE_DIALOG (dialog));
+	encrypt_header = fr_new_archive_dialog_get_encrypt_header (FR_NEW_ARCHIVE_DIALOG (dialog));
+	volume_size = fr_new_archive_dialog_get_volume_size (FR_NEW_ARCHIVE_DIALOG (dialog));
 
-void
-fr_window_start_activity_mode (FrWindow *window)
-{
-	g_return_if_fail (window != NULL);
+	settings = g_settings_new (FILE_ROLLER_SCHEMA_BATCH_ADD);
+	g_settings_set_int (settings, PREF_BATCH_ADD_VOLUME_SIZE, volume_size);
+	g_object_unref (settings);
 
-	if (window->priv->activity_ref++ > 0)
-		return;
+	fr_window_archive_save_as (window, uri, password, encrypt_header, volume_size);
 
-	window->priv->activity_timeout_handle = g_timeout_add (ACTIVITY_DELAY,
-							       activity_cb,
-							       window);
-	fr_window_update_sensitivity (window);
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+	g_free (uri);
 }
 
 
 void
-fr_window_stop_activity_mode (FrWindow *window)
+fr_window_action_save_as (FrWindow *window)
 {
-	g_return_if_fail (window != NULL);
+	char      *archive_name;
+	GtkWidget *dialog;
 
-	if (window->priv->activity_ref == 0)
-		return;
+	archive_name = NULL;
+	if (window->priv->archive_uri != NULL) {
+		GFile      *file;
+		GFileInfo  *info;
+		GError     *err = NULL;
 
-	window->priv->activity_ref--;
+		file = g_file_new_for_uri (window->priv->archive_uri);
+		info = g_file_query_info (file,
+					  G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+					  0, NULL, &err);
 
-	if (window->priv->activity_ref > 0)
-		return;
+		if (err != NULL) {
+			g_warning ("Failed to get display name for uri %s: %s", window->priv->archive_uri, err->message);
+			g_clear_error (&err);
+		}
+		else
+			archive_name = g_strdup (g_file_info_get_display_name (info));
 
-	if (window->priv->activity_timeout_handle == 0)
-		return;
+		g_object_unref (info);
+		g_object_unref (file);
+	}
 
-	g_source_remove (window->priv->activity_timeout_handle);
-	window->priv->activity_timeout_handle = 0;
+	dialog = fr_new_archive_dialog_new (GTK_WINDOW (window),
+					    FR_NEW_ARCHIVE_ACTION_SAVE_AS,
+					    archive_name);
+	gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), fr_window_get_open_default_dir (window));
+	g_signal_connect (G_OBJECT (dialog),
+			  "response",
+			  G_CALLBACK (save_as_archive_dialog_response_cb),
+			  window);
+	gtk_window_present (GTK_WINDOW (dialog));
 
-	if (! gtk_widget_get_realized (GTK_WIDGET (window)))
-		return;
+	g_free (archive_name);
+}
 
-	if (window->priv->progress_dialog != NULL)
-		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->pd_progress_bar), 0.0);
 
-	if (! window->priv->batch_mode) {
-		if (window->priv->progress_bar != NULL)
-			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->progress_bar), 0.0);
-		fr_window_update_sensitivity (window);
-	}
-}
+/* -- fr_window_view_last_output  -- */
 
 
 static gboolean
@@ -7674,7 +7561,7 @@ archive_rename_ready_cb (GObject      *source_object,
 	GError   *error = NULL;
 
 	fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
-	_archive_operation_completed (window, FR_ACTION_ADDING_FILES /* FIXME: FR_ACTION_RENAME_FILES ? */, error);
+	_archive_operation_completed (window, FR_ACTION_RENAMING_FILES, error);
 
 	_g_error_free (error);
 }
@@ -8065,6 +7952,8 @@ _paste_from_archive_operation_completed (FrWindow *window,
 					 FrAction  action,
 					 GError   *error)
 {
+	FrArchive *archive;
+
 #ifdef DEBUG
 	debug (DEBUG_INFO, "%s [DONE] (FR::Window)\n", action_names[action]);
 #endif
@@ -8078,8 +7967,11 @@ _paste_from_archive_operation_completed (FrWindow *window,
 		return;
 	}
 
-	/* FIXME: do not use this function !! */
-	_archive_operation_completed (window, FR_ACTION_EXTRACTING_FILES, error);
+	if (action == FR_ACTION_ADDING_FILES)
+		archive = window->archive;
+	else
+		archive = window->priv->copy_from_archive;
+	_handle_archive_operation_error (window, archive, action, error, NULL, NULL);
 
 	if (error->code != FR_ERROR_NONE) {
 		fr_clipboard_data_unref (window->priv->clipboard_data);
@@ -8477,8 +8369,6 @@ update_files_ready_cb (GObject      *source_object,
 
 	fr_window_stop_activity_mode (window);
 	fr_window_pop_message (window);
-
-	/* FIXME: do not use this function !!! */
 	_handle_archive_operation_error (window, window->archive, FR_ACTION_ADDING_FILES, error, NULL, NULL);
 
 	_g_error_free (error);
@@ -8688,7 +8578,6 @@ open_files_extract_ready_cb (GObject      *source_object,
 	GError        *error;
 
 	if (! fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error)) {
-		/* FIXME: do not use this function!!! */
 		_archive_operation_completed (odata->window, FR_ACTION_EXTRACTING_FILES, error);
 		g_error_free (error);
 	}
@@ -8912,7 +8801,7 @@ static void fr_window_exec_current_batch_action (FrWindow *window);
 
 static void
 fr_window_exec_batch_action (FrWindow      *window,
-			     FRBatchAction *action)
+			     FrBatchAction *action)
 {
 	ExtractData   *edata;
 	RenameData    *rdata;
@@ -8923,8 +8812,15 @@ fr_window_exec_batch_action (FrWindow      *window,
 	case FR_BATCH_ACTION_LOAD:
 		debug (DEBUG_INFO, "[BATCH] LOAD\n");
 
-		if (! _g_uri_query_exists ((char*) action->data))
-			fr_window_archive_new (window, (char*) action->data);
+		if (! _g_uri_query_exists ((char*) action->data)) {
+			GError *error = NULL;
+
+			if (! fr_window_archive_new (window, (char*) action->data))
+				error = g_error_new_literal (FR_ERROR, FR_ERROR_GENERIC, _("Archive type not supported."));
+			_archive_operation_completed (window, FR_ACTION_CREATING_NEW_ARCHIVE, error);
+
+			_g_error_free (error);
+		}
 		else
 			fr_window_archive_open (window, (char*) action->data, GTK_WINDOW (window));
 		break;
@@ -9060,7 +8956,7 @@ fr_window_exec_batch_action (FrWindow      *window,
 void
 fr_window_reset_current_batch_action (FrWindow *window)
 {
-	FRBatchAction *action = &window->priv->current_batch_action;
+	FrBatchAction *action = &window->priv->current_batch_action;
 
 	if ((action->data != NULL) && (action->free_func != NULL))
 		(*action->free_func) (action->data);
@@ -9076,7 +8972,7 @@ fr_window_set_current_batch_action (FrWindow          *window,
 				    void              *data,
 				    GFreeFunc          free_func)
 {
-	FRBatchAction *action;
+	FrBatchAction *action;
 
 	fr_window_reset_current_batch_action (window);
 
@@ -9100,11 +8996,11 @@ fr_window_append_batch_action (FrWindow          *window,
 			       void              *data,
 			       GFreeFunc          free_func)
 {
-	FRBatchAction *a_desc;
+	FrBatchAction *a_desc;
 
 	g_return_if_fail (window != NULL);
 
-	a_desc = g_new0 (FRBatchAction, 1);
+	a_desc = g_new0 (FrBatchAction, 1);
 	a_desc->type = action;
 	a_desc->data = data;
 	a_desc->free_func = free_func;
@@ -9116,13 +9012,13 @@ fr_window_append_batch_action (FrWindow          *window,
 static void
 fr_window_exec_current_batch_action (FrWindow *window)
 {
-	FRBatchAction *action;
+	FrBatchAction *action;
 
 	if (window->priv->batch_action == NULL) {
 		window->priv->batch_mode = FALSE;
 		return;
 	}
-	action = (FRBatchAction *) window->priv->batch_action->data;
+	action = (FrBatchAction *) window->priv->batch_action->data;
 	fr_window_exec_batch_action (window, action);
 }
 
@@ -9155,6 +9051,7 @@ fr_window_start_batch (FrWindow *window)
 
 	window->priv->batch_mode = TRUE;
 	window->priv->batch_action = window->priv->batch_action_list;
+	gtk_widget_hide (window);
 
 	fr_window_exec_current_batch_action (window);
 }
@@ -9163,27 +9060,21 @@ fr_window_start_batch (FrWindow *window)
 void
 fr_window_stop_batch (FrWindow *window)
 {
-	if (! window->priv->non_interactive)
+	fr_window_update_sensitivity (window);
+	fr_window_update_statusbar_list_info (window);
+
+	if (! window->priv->batch_mode)
 		return;
 
 	window->priv->extract_interact_use_default_dir = FALSE;
 
-	if (window->priv->batch_mode) {
-		if (! window->priv->showing_error_dialog) {
-			g_signal_emit (window,
-				       fr_window_signals[READY],
-				       0,
-				       NULL);
-			gtk_widget_destroy (GTK_WIDGET (window));
-			return;
-		}
-	}
-	else {
-		gtk_window_present (GTK_WINDOW (window));
-		fr_window_archive_close (window);
+	if (! window->priv->showing_error_dialog) {
+		g_signal_emit (window,
+			       fr_window_signals[READY],
+			       0,
+			       NULL);
+		gtk_widget_destroy (GTK_WIDGET (window));
 	}
-
-	window->priv->batch_mode = FALSE;
 }
 
 
@@ -9206,7 +9097,6 @@ fr_window_new_batch (FrWindow   *window,
 		     const char *title)
 {
 	fr_window_free_batch_data (window);
-	window->priv->non_interactive = TRUE;
 	g_free (window->priv->batch_title);
 	window->priv->batch_title = g_strdup (title);
 }
diff --git a/src/fr-window.h b/src/fr-window.h
index 723ce29..0fe78e4 100644
--- a/src/fr-window.h
+++ b/src/fr-window.h
@@ -116,11 +116,6 @@ void            fr_window_archive_close                (FrWindow      *window);
 const char *    fr_window_get_archive_uri              (FrWindow      *window);
 const char *    fr_window_get_paste_archive_uri        (FrWindow      *window);
 gboolean        fr_window_archive_is_present           (FrWindow      *window);
-void            fr_window_archive_save_as              (FrWindow      *window,
-						        const char    *filename,
-						        const char    *password,
-						        gboolean       encrypt_header,
-						        guint          volume_size);
 void            fr_window_archive_reload               (FrWindow      *window);
 void            fr_window_archive_add_files            (FrWindow      *window,
 						        GList         *file_list, /* GFile list */
@@ -238,6 +233,8 @@ void            fr_window_stop_activity_mode           (FrWindow    *window);
 
 /**/
 
+void            fr_window_action_new_archive           (FrWindow   *window);
+void            fr_window_action_save_as               (FrWindow   *window);
 void            fr_window_view_last_output             (FrWindow   *window,
 						        const char *title);
 void            fr_window_open_files                   (FrWindow   *window,
diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am
index f68ab36..8bb0ca7 100644
--- a/src/ui/Makefile.am
+++ b/src/ui/Makefile.am
@@ -1,17 +1,17 @@
-EXTRA_DIST = 			\
-	add-options.ui		\
-	app-menu.ui		\
-	batch-add-files.ui	\
-	batch-password.ui	\
-	delete.ui		\
-	error-dialog.ui		\
-	menus-toolbars.ui	\
-	message-dialog.ui	\
-	new.ui			\
-	password.ui		\
-	progress-dialog.ui	\
-	properties.ui		\
-	request-dialog.ui	\
+EXTRA_DIST = 				\
+	add-options.ui			\
+	app-menu.ui			\
+	batch-add-files.ui		\
+	batch-password.ui		\
+	delete.ui			\
+	error-dialog.ui			\
+	menus-toolbars.ui		\
+	message-dialog.ui		\
+	new-archive-dialog-options.ui	\
+	password.ui			\
+	progress-dialog.ui		\
+	properties.ui			\
+	request-dialog.ui		\
 	update.ui
 
 -include $(top_srcdir)/git.mk
diff --git a/src/ui/new.ui b/src/ui/new-archive-dialog-options.ui
similarity index 69%
rename from src/ui/new.ui
rename to src/ui/new-archive-dialog-options.ui
index e1a5a95..231cebe 100644
--- a/src/ui/new.ui
+++ b/src/ui/new-archive-dialog-options.ui
@@ -20,12 +20,12 @@
       </packing>
     </child>
     <child>
-      <object class="GtkExpander" id="n_other_options_expander">
+      <object class="GtkExpander" id="other_options_expander">
         <property name="visible">True</property>
         <property name="can_focus">True</property>
         <property name="expanded">True</property>
         <child>
-          <object class="GtkAlignment" id="other_oprtions_alignment">
+          <object class="GtkAlignment" id="other_options_alignment">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="top_padding">6</property>
@@ -48,25 +48,26 @@
                         <property name="column_spacing">12</property>
                         <property name="row_spacing">6</property>
                         <child>
-                          <object class="GtkLabel" id="n_password_label">
+                          <object class="GtkLabel" id="password_label">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
                             <property name="xalign">0</property>
                             <property name="label" translatable="yes">_Password:</property>
                             <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">n_password_entry</property>
+                            <property name="mnemonic_widget">password_entry</property>
                           </object>
                           <packing>
                             <property name="bottom_attach">2</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkEntry" id="n_password_entry">
+                          <object class="GtkEntry" id="password_entry">
                             <property name="width_request">300</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="visibility">False</property>
                             <property name="invisible_char">â</property>
+                            <property name="invisible_char_set">True</property>
                           </object>
                           <packing>
                             <property name="left_attach">1</property>
@@ -75,7 +76,7 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkCheckButton" id="n_encrypt_header_checkbutton">
+                          <object class="GtkCheckButton" id="encrypt_header_checkbutton">
                             <property name="label" translatable="yes">_Encrypt the file list too</property>
                             <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
@@ -107,12 +108,12 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkHBox" id="n_volume_box">
+                  <object class="GtkHBox" id="volume_box">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="spacing">6</property>
                     <child>
-                      <object class="GtkCheckButton" id="n_volume_checkbutton">
+                      <object class="GtkCheckButton" id="volume_checkbutton">
                         <property name="label" translatable="yes">Split into _volumes of</property>
                         <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
@@ -120,7 +121,7 @@
                         <property name="receives_default">False</property>
                         <property name="use_action_appearance">False</property>
                         <property name="use_underline">True</property>
-                        <property name="xalign">0.5</property>
+                        <property name="xalign">0</property>
                         <property name="draw_indicator">True</property>
                       </object>
                       <packing>
@@ -130,10 +131,11 @@
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkSpinButton" id="n_volume_spinbutton">
+                      <object class="GtkSpinButton" id="volume_spinbutton">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="invisible_char">â</property>
+                        <property name="invisible_char_set">True</property>
                         <property name="adjustment">volume_adjustment</property>
                         <property name="climb_rate">1</property>
                         <property name="digits">1</property>
@@ -184,81 +186,9 @@
       </packing>
     </child>
   </object>
-  <object class="GtkFileChooserDialog" id="filechooserdialog">
-    <property name="can_focus">False</property>
-    <property name="border_width">5</property>
-    <property name="modal">True</property>
-    <property name="window_position">center-on-parent</property>
-    <property name="type_hint">normal</property>
-    <property name="action">save</property>
-    <property name="do_overwrite_confirmation">True</property>
-    <property name="extra_widget">extra_widget</property>
-    <child internal-child="vbox">
-      <object class="GtkBox" id="dialog-vbox1">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
-        <child internal-child="action_area">
-          <object class="GtkButtonBox" id="dialog-action_area1">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="layout_style">end</property>
-            <child>
-              <object class="GtkButton" id="n_cancel_button">
-                <property name="label">gtk-cancel</property>
-                <property name="use_action_appearance">False</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_action_appearance">False</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="n_new_button">
-                <property name="label">gtk-new</property>
-                <property name="use_action_appearance">False</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_action_appearance">False</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <placeholder/>
-        </child>
-      </object>
-    </child>
-    <action-widgets>
-      <action-widget response="-6">n_cancel_button</action-widget>
-      <action-widget response="-5">n_new_button</action-widget>
-    </action-widgets>
-  </object>
   <object class="GtkAdjustment" id="volume_adjustment">
     <property name="lower">0.10000000149</property>
     <property name="upper">1000</property>
-    <property name="value">10</property>
     <property name="step_increment">0.10000000149</property>
     <property name="page_increment">10</property>
   </object>



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