From eb6b2cdb2e89e41759cf3b1cd136cfca42e6e42b Mon Sep 17 00:00:00 2001
From: Christian Persch <chpe@cvs.gnome.org>
Date: Sun, 26 Oct 2003 10:45:56 +0000
Subject: Port to new gtk+ file chooser.

2003-10-26  Christian Persch  <chpe@cvs.gnome.org>

	Port to new gtk+ file chooser.

	* data/epiphany.schemas.in:
	* lib/ephy-prefs.h:

	Add key for remembering upload path.

	* embed	/Makefile.am:
	* embed/downloader-view.c:
	* embed/ephy-embed-persist.c: (ephy_embed_persist_get_type),
	(ephy_embed_persist_set_dest), (ephy_embed_persist_set_embed),
	(ephy_embed_persist_set_fc_title),
	(ephy_embed_persist_set_fc_parent), (ephy_embed_persist_set_flags),
	(ephy_embed_persist_set_max_size),
	(ephy_embed_persist_set_persist_key),
	(ephy_embed_persist_set_source), (ephy_embed_persist_get_dest),
	(ephy_embed_persist_get_embed), (ephy_embed_persist_get_fc_title),
	(ephy_embed_persist_get_fc_parent), (ephy_embed_persist_get_flags),
	(ephy_embed_persist_get_max_size),
	(ephy_embed_persist_get_persist_key),
	(ephy_embed_persist_get_source), (ephy_embed_persist_set_property),
	(ephy_embed_persist_get_property), (ephy_embed_persist_init),
	(ephy_embed_persist_finalize), (ephy_embed_persist_class_init),
	(ephy_embed_persist_cancel), (ephy_embed_persist_save),
	(ephy_embed_persist_new):
	* embed/ephy-embed-persist.h:
	* embed/ephy-embed-popup-control.c: (save_url),
	(save_property_url), (background_download_completed),
	(embed_popup_set_image_as_background_cmd),
	(embed_popup_copy_image_location_cmd):
        * src/popup-commands.c: (save_property_url),
	(background_download_completed),
	(popup_cmd_set_image_as_background):
	* src/window-commands.c: (open_response_cb),
	(window_cmd_file_open), (window_cmd_file_save_as):
	* src/window-commands.h:
	* embed/ephy-favicon-cache.c: (ephy_favicon_cache_get_type),
	(ephy_favicon_cache_new), (icon_is_obsolete), (icons_added_cb),
	(remove_obsolete_icons), (ephy_favicon_cache_init),
	(favicon_download_completed_cb), (ephy_favicon_cache_download),
	(ephy_favicon_cache_get):
	* embed/mozilla/MozDownload.cpp:
	* embed/mozilla/EphyHeaderSniffer.cpp:
	* embed/mozilla/mozilla-embed-persist.cpp:
	* embed/mozilla/mozilla-embed-single.cpp:
	* src/popup-commands.c: (save_property_url),
	(background_download_completed),
	(popup_cmd_set_image_as_background):
	* src/window-commands.c: (open_response_cb),
	(window_cmd_file_open), (window_cmd_file_save_as):
	* src/window-commands.h:

	Simplify EphyEmbedPersist implementation. Augment it with properties
	for showing a file chooser to select persist destination. Port all
	callers to new interfaces.

	* embed/ephy-embed-single.c: (ephy_embed_single_remove_passwords):
	* embed/ephy-embed-single.h:

	* embed/ephy-embed-utils.c:
	* embed/ephy-embed-utils.h:

	Obsolete and removed.

	* embed/mozilla/ContentHandler.cpp:
	* embed/mozilla/ContentHandler.h:

	Misc cleanups.

	* embed/mozilla/FilePicker.cpp:
	* embed/mozilla/FilePicker.h:

	Port to new file chooser class.

	* embed/mozilla/Makefile.am:
	* lib/Makefile.am:
	* lib/ephy-file-chooser.c: (ephy_file_chooser_get_type),
	(current_folder_changed_cb), (ephy_file_chooser_init),
	(ephy_file_chooser_finalize), (ephy_file_chooser_set_persist_key),
	(ephy_file_chooser_set_property), (ephy_file_chooser_get_property),
	(ephy_file_chooser_class_init), (ephy_file_chooser_new):
	* lib/ephy-file-chooser.h:
	* src/bookmarks/ephy-bookmarks-editor.c:
	(import_from_file_response_cb), (import_dialog_response_cb):

	New file chooser wrapper class; ported file chooser callers to it.
---
 ChangeLog                               |  89 +++++
 data/epiphany.schemas.in                |   9 +
 embed/Makefile.am                       |   2 -
 embed/downloader-view.c                 |   1 -
 embed/ephy-embed-persist.c              | 673 +++++++++++++++-----------------
 embed/ephy-embed-persist.h              | 101 +++--
 embed/ephy-embed-popup-control.c        |  79 ++--
 embed/ephy-embed-single.c               |  38 +-
 embed/ephy-embed-single.h               |  21 +-
 embed/ephy-embed-utils.c                | 214 ----------
 embed/ephy-embed-utils.h                |  39 --
 embed/ephy-favicon-cache.c              |  67 ++--
 embed/mozilla/ContentHandler.cpp        |  74 ++--
 embed/mozilla/ContentHandler.h          |   5 +
 embed/mozilla/EphyHeaderSniffer.cpp     |  26 +-
 embed/mozilla/FilePicker.cpp            | 503 ++++++++++--------------
 embed/mozilla/FilePicker.h              |  55 +--
 embed/mozilla/Makefile.am               |   1 +
 embed/mozilla/MozDownload.cpp           |   7 +-
 embed/mozilla/mozilla-embed-persist.cpp |   9 +-
 embed/mozilla/mozilla-embed-single.cpp  |  72 +---
 lib/Makefile.am                         |   2 +
 lib/ephy-file-chooser.c                 | 238 +++++++++++
 lib/ephy-file-chooser.h                 |  66 ++++
 lib/ephy-prefs.h                        |   1 +
 src/bookmarks/ephy-bookmarks-editor.c   |  47 ++-
 src/ephy-window.c                       |  21 +-
 src/popup-commands.c                    |  40 +-
 src/window-commands.c                   |  88 ++---
 src/window-commands.h                   |   1 -
 30 files changed, 1254 insertions(+), 1335 deletions(-)
 delete mode 100644 embed/ephy-embed-utils.c
 delete mode 100644 embed/ephy-embed-utils.h
 create mode 100644 lib/ephy-file-chooser.c
 create mode 100644 lib/ephy-file-chooser.h

diff --git a/ChangeLog b/ChangeLog
index a630c70f0..8c386cea3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,92 @@
+2003-10-26  Christian Persch  <chpe@cvs.gnome.org>
+
+	Port to new gtk+ file chooser.
+
+	* data/epiphany.schemas.in:
+	* lib/ephy-prefs.h:
+
+	Add key for remembering upload path.
+
+	* embed	/Makefile.am:
+	* embed/downloader-view.c:
+	* embed/ephy-embed-persist.c: (ephy_embed_persist_get_type),
+	(ephy_embed_persist_set_dest), (ephy_embed_persist_set_embed),
+	(ephy_embed_persist_set_fc_title),
+	(ephy_embed_persist_set_fc_parent), (ephy_embed_persist_set_flags),
+	(ephy_embed_persist_set_max_size),
+	(ephy_embed_persist_set_persist_key),
+	(ephy_embed_persist_set_source), (ephy_embed_persist_get_dest),
+	(ephy_embed_persist_get_embed), (ephy_embed_persist_get_fc_title),
+	(ephy_embed_persist_get_fc_parent), (ephy_embed_persist_get_flags),
+	(ephy_embed_persist_get_max_size),
+	(ephy_embed_persist_get_persist_key),
+	(ephy_embed_persist_get_source), (ephy_embed_persist_set_property),
+	(ephy_embed_persist_get_property), (ephy_embed_persist_init),
+	(ephy_embed_persist_finalize), (ephy_embed_persist_class_init),
+	(ephy_embed_persist_cancel), (ephy_embed_persist_save),
+	(ephy_embed_persist_new):
+	* embed/ephy-embed-persist.h:
+	* embed/ephy-embed-popup-control.c: (save_url),
+	(save_property_url), (background_download_completed),
+	(embed_popup_set_image_as_background_cmd),
+	(embed_popup_copy_image_location_cmd):
+        * src/popup-commands.c: (save_property_url),
+	(background_download_completed),
+	(popup_cmd_set_image_as_background):
+	* src/window-commands.c: (open_response_cb),
+	(window_cmd_file_open), (window_cmd_file_save_as):
+	* src/window-commands.h:
+	* embed/ephy-favicon-cache.c: (ephy_favicon_cache_get_type),
+	(ephy_favicon_cache_new), (icon_is_obsolete), (icons_added_cb),
+	(remove_obsolete_icons), (ephy_favicon_cache_init),
+	(favicon_download_completed_cb), (ephy_favicon_cache_download),
+	(ephy_favicon_cache_get):
+	* embed/mozilla/MozDownload.cpp:
+	* embed/mozilla/EphyHeaderSniffer.cpp:
+	* embed/mozilla/mozilla-embed-persist.cpp:
+	* embed/mozilla/mozilla-embed-single.cpp:
+	* src/popup-commands.c: (save_property_url),
+	(background_download_completed),
+	(popup_cmd_set_image_as_background):
+	* src/window-commands.c: (open_response_cb),
+	(window_cmd_file_open), (window_cmd_file_save_as):
+	* src/window-commands.h:
+
+	Simplify EphyEmbedPersist implementation. Augment it with properties
+	for showing a file chooser to select persist destination. Port all
+	callers to new interfaces.
+
+	* embed/ephy-embed-single.c: (ephy_embed_single_remove_passwords):
+	* embed/ephy-embed-single.h:
+
+	* embed/ephy-embed-utils.c:
+	* embed/ephy-embed-utils.h:
+
+	Obsolete and removed.
+
+	* embed/mozilla/ContentHandler.cpp:
+	* embed/mozilla/ContentHandler.h:
+
+	Misc cleanups.
+
+	* embed/mozilla/FilePicker.cpp:
+	* embed/mozilla/FilePicker.h:
+
+	Port to new file chooser class.
+
+	* embed/mozilla/Makefile.am:
+	* lib/Makefile.am:
+	* lib/ephy-file-chooser.c: (ephy_file_chooser_get_type),
+	(current_folder_changed_cb), (ephy_file_chooser_init),
+	(ephy_file_chooser_finalize), (ephy_file_chooser_set_persist_key),
+	(ephy_file_chooser_set_property), (ephy_file_chooser_get_property),
+	(ephy_file_chooser_class_init), (ephy_file_chooser_new):
+	* lib/ephy-file-chooser.h:
+	* src/bookmarks/ephy-bookmarks-editor.c:
+	(import_from_file_response_cb), (import_dialog_response_cb):
+
+	New file chooser wrapper class; ported file chooser callers to it.
+
 2003-10-26  Marco Pesenti Gritti  <marco@gnome.org>
 
 	* lib/egg/egg-editable-toolbar.c: (toolbar_drag_motion_cb):
diff --git a/data/epiphany.schemas.in b/data/epiphany.schemas.in
index 84a74de28..f0d6371da 100644
--- a/data/epiphany.schemas.in
+++ b/data/epiphany.schemas.in
@@ -418,6 +418,15 @@
         <locale name="C">
         </locale>
       </schema>
+      <schema>
+        <key>/schemas/apps/epiphany/directories/upload</key>
+        <applyto>/apps/epiphany/directories/upload</applyto>
+        <owner>epiphany</owner>
+        <type>string</type>
+        <default>~</default>
+        <locale name="C">
+        </locale>
+      </schema>
       <schema>
         <key>/schemas/apps/epiphany/web/autodetect_encoding</key>
         <applyto>/apps/epiphany/web/autodetect_encoding</applyto>
diff --git a/embed/Makefile.am b/embed/Makefile.am
index 36fc9f247..614ed9955 100644
--- a/embed/Makefile.am
+++ b/embed/Makefile.am
@@ -23,7 +23,6 @@ NOINST_H_FILES = \
 	ephy-download.h			\
 	ephy-embed-dialog.h		\
 	ephy-embed-popup-control.h	\
-	ephy-embed-utils.h		\
 	ephy-favicon-cache.h		\
 	find-dialog.h			\
 	print-dialog.h
@@ -51,7 +50,6 @@ libephyembed_la_SOURCES = \
 	ephy-embed-popup-control.c	\
 	ephy-embed-single.c		\
 	ephy-embed-shell.c		\
-	ephy-embed-utils.c		\
 	ephy-encodings.c		\
 	ephy-favicon-cache.c		\
 	ephy-history.c			\
diff --git a/embed/downloader-view.c b/embed/downloader-view.c
index 63050ac61..e557422ca 100644
--- a/embed/downloader-view.c
+++ b/embed/downloader-view.c
@@ -26,7 +26,6 @@
 #include "ephy-gui.h"
 #include "ephy-prefs.h"
 #include "ephy-ellipsizing-label.h"
-#include "ephy-embed-utils.h"
 #include "ephy-file-helpers.h"
 #include "ephy-embed-shell.h"
 #include "ephy-cell-renderer-progress.h"
diff --git a/embed/ephy-embed-persist.c b/embed/ephy-embed-persist.c
index 54581e52b..231bf3064 100644
--- a/embed/ephy-embed-persist.c
+++ b/embed/ephy-embed-persist.c
@@ -1,5 +1,6 @@
 /*
- *  Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
+ *  Copyright (C) 2000-2003 Marco Pesenti Gritti
+ *  Copyright (C) 2003 Christian Persch
  *
  *  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
@@ -18,474 +19,436 @@
  *  $Id$
  */
 
-#include <config.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
 #include "ephy-embed-persist.h"
-#include "ephy-debug.h"
-#include "mozilla-embed.h"
 #include "mozilla-embed-persist.h"
+#include "ephy-debug.h"
 
 enum
 {
-        COMPLETED,
-        LAST_SIGNAL
-};
-
-enum
-{
-  PROP_0,
-  PROP_EMBED,
-  PROP_SOURCE,
-  PROP_DEST,
-  PROP_MAX_SIZE,
-  PROP_FLAGS,
-  PROP_HANDLER
+	PROP_0,
+	PROP_DEST,
+	PROP_EMBED,
+	PROP_FILECHOOSER_TITLE,
+	PROP_FILECHOOSER_PARENT,
+	PROP_FLAGS,
+	PROP_HANDLER,
+	PROP_MAX_SIZE,
+	PROP_PERSISTKEY,
+	PROP_SOURCE,	
 };
 
 #define EPHY_EMBED_PERSIST_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_EMBED_PERSIST, EphyEmbedPersistPrivate))
 
 struct EphyEmbedPersistPrivate
 {
-	char *dir;
-	char *src;
-	PersistHandlerInfo *handler;
+	char *dest;
+	char *source;
+	char *fc_title;
+	char *persist_key;
 	EphyEmbed *embed;
 	int max_size;
 	EmbedPersistFlags flags;
+	GtkWindow *fc_parent;
 };
 
-static void
-ephy_embed_persist_class_init (EphyEmbedPersistClass *klass);
-static void
-ephy_embed_persist_init (EphyEmbedPersist *ges);
-static void
-ephy_embed_persist_finalize (GObject *object);
-static void
-ephy_embed_persist_set_property (GObject *object,
-                                  guint prop_id,
-                                  const GValue *value,
-                                  GParamSpec *pspec);
-static void
-ephy_embed_persist_get_property (GObject *object,
-                                  guint prop_id,
-                                  GValue *value,
-                                  GParamSpec *pspec);
-
-static gresult
-impl_set_source (EphyEmbedPersist *persist,
-		 const char *url);
-static gresult
-impl_set_dest (EphyEmbedPersist *persist,
-	       const char *dir);
-static gresult
-impl_set_max_size (EphyEmbedPersist *persist,
-		   int kb_size);
-static gresult
-impl_set_embed (EphyEmbedPersist *persist,
-		EphyEmbed *embed);
-static gresult
-impl_set_flags (EphyEmbedPersist *persist,
-		EmbedPersistFlags flags);
-static gresult
-impl_set_handler (EphyEmbedPersist *persist,
-		  const char *command,
-		  gboolean need_terminal);
+static void	ephy_embed_persist_class_init	(EphyEmbedPersistClass *klass);
+static void	ephy_embed_persist_init		(EphyEmbedPersist *ges);
+
+enum
+{
+	COMPLETED,
+	LAST_SIGNAL
+};
 
-static GObjectClass *parent_class = NULL;
 static guint ephy_embed_persist_signals[LAST_SIGNAL] = { 0 };
 
+static GObjectClass *parent_class = NULL;
+
 GType
 ephy_embed_persist_get_type (void)
 {
        static GType ephy_embed_persist_type = 0;
 
-        if (ephy_embed_persist_type == 0)
-        {
-                static const GTypeInfo our_info =
-                {
-                        sizeof (EphyEmbedPersistClass),
-                        NULL, /* base_init */
-                        NULL, /* base_finalize */
-                        (GClassInitFunc) ephy_embed_persist_class_init,
-                        NULL, /* class_finalize */
-                        NULL, /* class_data */
-                        sizeof (EphyEmbedPersist),
-                        0,    /* n_preallocs */
-                        (GInstanceInitFunc) ephy_embed_persist_init
-                };
-
-                ephy_embed_persist_type = g_type_register_static (G_TYPE_OBJECT,
-                                                                    "EphyEmbedPersist",
-                                                                    &our_info, 0);
-        }
-
-        return ephy_embed_persist_type;
+	if (ephy_embed_persist_type == 0)
+	{
+		static const GTypeInfo our_info =
+		{
+			sizeof (EphyEmbedPersistClass),
+			NULL, /* base_init */
+			NULL, /* base_finalize */
+			(GClassInitFunc) ephy_embed_persist_class_init,
+			NULL, /* class_finalize */
+			NULL, /* class_data */
+			sizeof (EphyEmbedPersist),
+			0,    /* n_preallocs */
+			(GInstanceInitFunc) ephy_embed_persist_init
+		};
+
+		ephy_embed_persist_type = g_type_register_static (G_TYPE_OBJECT,
+								  "EphyEmbedPersist",
+								  &our_info, 0);
+	}
+
+	return ephy_embed_persist_type;
 }
 
-static void
-ephy_embed_persist_class_init (EphyEmbedPersistClass *klass)
+void
+ephy_embed_persist_set_dest (EphyEmbedPersist *persist,
+			     const char *value)
 {
-        GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-        parent_class = g_type_class_peek_parent (klass);
+	g_return_if_fail (EPHY_IS_EMBED_PERSIST (persist));
 
-        object_class->finalize = ephy_embed_persist_finalize;
-        object_class->set_property = ephy_embed_persist_set_property;
-	object_class->get_property = ephy_embed_persist_get_property;
-
-	klass->set_source = impl_set_source;
-	klass->set_dest   = impl_set_dest;
-	klass->set_embed  = impl_set_embed;
-	klass->set_max_size = impl_set_max_size;
-	klass->set_flags = impl_set_flags;
-	klass->set_handler = impl_set_handler;
-
-	/* init signals */
-        ephy_embed_persist_signals[COMPLETED] =
-                g_signal_new ("completed",
-                              G_OBJECT_CLASS_TYPE (object_class),
-                              G_SIGNAL_RUN_LAST,
-                              G_STRUCT_OFFSET (EphyEmbedPersistClass, completed),
-                              NULL, NULL,
-                              g_cclosure_marshal_VOID__VOID,
-                              G_TYPE_NONE,
-                              0);
-
-	g_object_class_install_property (object_class,
-                                         PROP_EMBED,
-                                         g_param_spec_object ("embed",
-                                                              "Embed",
-                                                              "The embed containing the document",
-                                                              G_TYPE_OBJECT,
-                                                              G_PARAM_READWRITE));
-	g_object_class_install_property (object_class,
-                                         PROP_SOURCE,
-                                         g_param_spec_string  ("source",
-                                                               "Source",
-                                                               "Url of the document to save",
-                                                               NULL,
-                                                               G_PARAM_READWRITE));
-
-	g_object_class_install_property (object_class,
-                                         PROP_DEST,
-                                         g_param_spec_string ("dest",
-                                                              "Destination",
-                                                              "Destination directory",
-                                                              NULL,
-                                                              G_PARAM_READWRITE));
-
-	g_object_class_install_property (object_class,
-                                         PROP_MAX_SIZE,
-                                         g_param_spec_int    ("max_size",
-                                                              "Maxsize",
-                                                              "Maximum size of the file",
-                                                              0,
-							      G_MAXINT,
-							      0,
-                                                              G_PARAM_READWRITE));
-
-	g_object_class_install_property (object_class,
-                                         PROP_FLAGS,
-                                         g_param_spec_int    ("flags",
-                                                              "Flags",
-                                                              "Flags",
-                                                              0,
-							      G_MAXINT,
-							      0,
-                                                              G_PARAM_READWRITE));
-
-	g_object_class_install_property (object_class,
-                                         PROP_HANDLER,
-                                         g_param_spec_pointer ("handler",
-                                                              "Handler",
-                                                              "Handler",
-                                                              G_PARAM_READWRITE));
-
-	g_type_class_add_private (object_class, sizeof(EphyEmbedPersistPrivate));
+	persist->priv->dest = g_strdup (value);
 }
 
-static void
-ephy_embed_persist_set_property (GObject *object,
-                                   guint prop_id,
-                                   const GValue *value,
-                                   GParamSpec *pspec)
+void
+ephy_embed_persist_set_embed (EphyEmbedPersist *persist,
+			      EphyEmbed *value)
 {
-	EphyEmbedPersist *persist;
-	PersistHandlerInfo *h;
-
-	persist = EPHY_EMBED_PERSIST (object);
+	g_return_if_fail (EPHY_IS_EMBED_PERSIST (persist));
 
-	switch (prop_id)
-	{
-		case PROP_EMBED:
-			ephy_embed_persist_set_embed (persist,
-							g_value_get_object (value));
-			break;
-		case PROP_SOURCE:
-			ephy_embed_persist_set_source (persist,
-							 g_value_get_string (value));
-			break;
-		case PROP_DEST:
-			ephy_embed_persist_set_dest  (persist,
-							 g_value_get_string (value));
-			break;
-		case PROP_MAX_SIZE:
-			ephy_embed_persist_set_max_size  (persist,
-							    g_value_get_int (value));
-			break;
-		case PROP_FLAGS:
-			ephy_embed_persist_set_flags
-				(persist,
-				(EmbedPersistFlags)g_value_get_int (value));
-			break;
-		case PROP_HANDLER:
-			h = (PersistHandlerInfo *)g_value_get_pointer (value);
-			ephy_embed_persist_set_handler
-				(persist, h->command, h->need_terminal);
-			break;
-	}
+	persist->priv->embed = value;
 }
 
-static void
-ephy_embed_persist_get_property (GObject *object,
-                                   guint prop_id,
-                                   GValue *value,
-                                   GParamSpec *pspec)
+void
+ephy_embed_persist_set_fc_title (EphyEmbedPersist *persist,
+				 const char *value)
 {
-	EphyEmbedPersist *persist;
-
-	persist = EPHY_EMBED_PERSIST (object);
+	g_return_if_fail (EPHY_IS_EMBED_PERSIST (persist));
 
-	switch (prop_id)
-	{
-		case PROP_EMBED:
-			g_value_set_object (value, persist->priv->embed);
-			break;
-		case PROP_SOURCE:
-			g_value_set_string (value, persist->priv->src);
-			break;
-		case PROP_DEST:
-			g_value_set_string (value, persist->priv->dir);
-			break;
-		case PROP_MAX_SIZE:
-			g_value_set_int (value, persist->priv->max_size);
-			break;
-		case PROP_FLAGS:
-			g_value_set_int (value, (int)persist->priv->flags);
-			break;
-		case PROP_HANDLER:
-			g_value_set_pointer (value, persist->priv->handler);
-	}
+	persist->priv->fc_title = g_strdup (value);
 }
 
-static void
-ephy_embed_persist_init (EphyEmbedPersist *persist)
+void
+ephy_embed_persist_set_fc_parent (EphyEmbedPersist *persist,
+				  GtkWindow *value)
 {
-	persist->priv = EPHY_EMBED_PERSIST_GET_PRIVATE (persist);
-
-	persist->priv->src = NULL;
-	persist->priv->dir = NULL;
-	persist->priv->handler = NULL;
+	g_return_if_fail (EPHY_IS_EMBED_PERSIST (persist));
 
-	LOG ("Embed persist init")
+	persist->priv->fc_parent = value;
 }
 
-static void
-ephy_embed_persist_finalize (GObject *object)
+void
+ephy_embed_persist_set_flags (EphyEmbedPersist *persist,
+			      EmbedPersistFlags value)
 {
-        EphyEmbedPersist *persist = EPHY_EMBED_PERSIST (object);
+	g_return_if_fail (EPHY_IS_EMBED_PERSIST (persist));
 
-	g_free (persist->priv->dir);
-	g_free (persist->priv->src);
-
-	if (persist->priv->handler)
-	{
-		g_free (persist->priv->handler->command);
-		g_free (persist->priv->handler);
-	}
+	persist->priv->flags = value;
+}
 
-	LOG ("Embed persist finalize")
+void
+ephy_embed_persist_set_max_size (EphyEmbedPersist *persist,
+				 int value)
+{
+	g_return_if_fail (EPHY_IS_EMBED_PERSIST (persist));
 
-        G_OBJECT_CLASS (parent_class)->finalize (object);
+	persist->priv->max_size = value;
 }
 
-
-EphyEmbedPersist *
-ephy_embed_persist_new (EphyEmbed *embed)
+void
+ephy_embed_persist_set_persist_key (EphyEmbedPersist *persist,
+				    const char *value)
 {
-	EphyEmbedPersist *persist;
+	g_return_if_fail (EPHY_IS_EMBED_PERSIST (persist));
 
-        persist = EPHY_EMBED_PERSIST (g_object_new (MOZILLA_TYPE_EMBED_PERSIST,
-						    "embed", embed,
-						    NULL));
-
-	return persist;
+	persist->priv->persist_key = g_strdup (value);
 }
 
-gresult
+void
 ephy_embed_persist_set_source (EphyEmbedPersist *persist,
-				 const char *url)
+			       const char *value)
 {
-	 EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist);
-	 return klass->set_source (persist, url);
+	g_return_if_fail (EPHY_IS_EMBED_PERSIST (persist));
+
+	persist->priv->source = g_strdup (value);
 }
 
-gresult
-ephy_embed_persist_get_source (EphyEmbedPersist *persist,
-				 const char **url)
+const char *
+ephy_embed_persist_get_dest (EphyEmbedPersist *persist)
 {
-	*url = persist->priv->src;
+	g_return_val_if_fail (EPHY_IS_EMBED_PERSIST (persist), NULL);
 
-	return G_OK;
+	return persist->priv->dest;
 }
 
-gresult
-ephy_embed_persist_get_dest (EphyEmbedPersist *persist,
-			       const char **dir)
+EphyEmbed *
+ephy_embed_persist_get_embed (EphyEmbedPersist *persist)
 {
-	*dir = persist->priv->dir;
+	g_return_val_if_fail (EPHY_IS_EMBED_PERSIST (persist), NULL);
 
-	return G_OK;
+	return persist->priv->embed;
 }
 
-gresult
-ephy_embed_persist_set_dest (EphyEmbedPersist *persist,
-			       const char *dir)
+const char *
+ephy_embed_persist_get_fc_title (EphyEmbedPersist *persist)
 {
-	EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist);
-	return klass->set_dest (persist, dir);
-}
+	g_return_val_if_fail (EPHY_IS_EMBED_PERSIST (persist), NULL);
 
-gresult
-ephy_embed_persist_cancel (EphyEmbedPersist *persist)
-{
-	EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist);
-	return klass->cancel (persist);
+	return persist->priv->fc_title;
 }
 
-gresult
-ephy_embed_persist_save (EphyEmbedPersist *persist)
+GtkWindow *
+ephy_embed_persist_get_fc_parent (EphyEmbedPersist *persist)
 {
-	EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist);
-	return klass->save (persist);
+	g_return_val_if_fail (EPHY_IS_EMBED_PERSIST (persist), NULL);
+
+	return persist->priv->fc_parent;
 }
 
-gresult
-ephy_embed_persist_set_max_size (EphyEmbedPersist *persist,
-			           int kb_size)
+EmbedPersistFlags
+ephy_embed_persist_get_flags (EphyEmbedPersist *persist)
 {
-	EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist);
-	return klass->set_max_size (persist, kb_size);
+	g_return_val_if_fail (EPHY_IS_EMBED_PERSIST (persist), 0);
+
+	return persist->priv->flags;
 }
 
-gresult
-ephy_embed_persist_set_embed (EphyEmbedPersist *persist,
-		                EphyEmbed *embed)
+int
+ephy_embed_persist_get_max_size (EphyEmbedPersist *persist)
 {
-	EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist);
-	return klass->set_embed (persist, embed);
+	g_return_val_if_fail (EPHY_IS_EMBED_PERSIST (persist), 0);
+
+	return persist->priv->max_size;
 }
 
-gresult
-ephy_embed_persist_get_embed (EphyEmbedPersist *persist,
-		                EphyEmbed **embed)
+const char *
+ephy_embed_persist_get_persist_key (EphyEmbedPersist *persist)
 {
-	*embed = persist->priv->embed;
+	g_return_val_if_fail (EPHY_IS_EMBED_PERSIST (persist), NULL);
 
-	return G_OK;
+	return persist->priv->persist_key;
 }
 
-gresult
-ephy_embed_persist_set_flags (EphyEmbedPersist *persist,
-		                EmbedPersistFlags flags)
+const char *
+ephy_embed_persist_get_source (EphyEmbedPersist *persist)
 {
-	EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist);
-	return klass->set_flags (persist, flags);
+	g_return_val_if_fail (EPHY_IS_EMBED_PERSIST (persist), NULL);
+
+	return persist->priv->source;
 }
 
-gresult
-ephy_embed_persist_get_flags (EphyEmbedPersist *persist,
-		                EmbedPersistFlags *flags)
+static void
+ephy_embed_persist_set_property (GObject *object,
+				 guint prop_id,
+				 const GValue *value,
+				 GParamSpec *pspec)
 {
-	*flags = persist->priv->flags= persist->priv->flags;
+	EphyEmbedPersist *persist = EPHY_EMBED_PERSIST (object);
 
-	return G_OK;
+	switch (prop_id)
+	{
+		case PROP_DEST:
+			ephy_embed_persist_set_dest (persist, g_value_get_string (value));
+			break;
+		case PROP_EMBED:
+			ephy_embed_persist_set_embed (persist, g_value_get_object (value));
+			break;
+		case PROP_FILECHOOSER_TITLE:
+			ephy_embed_persist_set_fc_title (persist, g_value_get_string (value));
+			break;
+		case PROP_FILECHOOSER_PARENT:
+			ephy_embed_persist_set_fc_parent (persist, g_value_get_object (value));
+			break;
+		case PROP_FLAGS:
+			ephy_embed_persist_set_flags (persist, g_value_get_int (value));
+			break;
+		case PROP_MAX_SIZE:
+			ephy_embed_persist_set_max_size (persist, g_value_get_int (value));
+			break;
+		case PROP_PERSISTKEY:
+			ephy_embed_persist_set_persist_key (persist, g_value_get_string (value));
+			break;
+		case PROP_SOURCE:
+			ephy_embed_persist_set_source (persist, g_value_get_string (value));
+			break;
+	}
 }
 
-gresult
-ephy_embed_persist_set_handler (EphyEmbedPersist *persist,
-				  const char *command,
-				  gboolean need_terminal)
+static void
+ephy_embed_persist_get_property (GObject *object,
+				 guint prop_id,
+				 GValue *value,
+				 GParamSpec *pspec)
 {
-	EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist);
-	return klass->set_handler (persist, command, need_terminal);
+	EphyEmbedPersist *persist = EPHY_EMBED_PERSIST (object);
+
+	switch (prop_id)
+	{
+		case PROP_DEST:
+			g_value_set_string (value, ephy_embed_persist_get_dest (persist));
+			break;
+		case PROP_EMBED:
+			g_value_set_object (value, ephy_embed_persist_get_embed (persist));
+			break;
+		case PROP_FILECHOOSER_TITLE:
+			g_value_set_string (value, ephy_embed_persist_get_fc_title (persist));
+			break;
+		case PROP_FILECHOOSER_PARENT:
+			g_value_set_object (value, ephy_embed_persist_get_fc_parent (persist));
+			break;
+		case PROP_FLAGS:
+			g_value_set_int (value, ephy_embed_persist_get_flags (persist));
+			break;
+		case PROP_MAX_SIZE:
+			g_value_set_int (value, ephy_embed_persist_get_max_size (persist));
+			break;
+		case PROP_PERSISTKEY:
+			g_value_set_string (value, ephy_embed_persist_get_persist_key (persist));
+			break;
+		case PROP_SOURCE:
+			g_value_set_string (value, ephy_embed_persist_get_source (persist));
+			break;
+	}
 }
 
-static gresult
-impl_set_handler (EphyEmbedPersist *persist,
-		  const char *command,
-		  gboolean need_terminal)
+static void
+ephy_embed_persist_init (EphyEmbedPersist *persist)
 {
-	persist->priv->handler = g_new0 (PersistHandlerInfo, 1);
-	persist->priv->handler->command = g_strdup (command);
-	persist->priv->handler->need_terminal = need_terminal;
+	persist->priv = EPHY_EMBED_PERSIST_GET_PRIVATE (persist);
 
-	g_object_notify (G_OBJECT(persist), "handler");
+	LOG ("EphyEmbedPersist initialising %p", persist)
 
-	return G_OK;
+	persist->priv->dest = NULL;
+	persist->priv->source = NULL;
+	persist->priv->fc_title = NULL;
+	persist->priv->fc_parent = NULL;
+	persist->priv->flags = 0;
+	persist->priv->max_size = 0;
+	persist->priv->persist_key = NULL;
 }
 
-static gresult
-impl_set_flags (EphyEmbedPersist *persist,
-		EmbedPersistFlags flags)
+static void
+ephy_embed_persist_finalize (GObject *object)
 {
-	persist->priv->flags = flags;
+	EphyEmbedPersist *persist = EPHY_EMBED_PERSIST (object);
+
+	g_free (persist->priv->dest);
+	g_free (persist->priv->source);
+	g_free (persist->priv->fc_title);
+	g_free (persist->priv->persist_key);
 
-	g_object_notify (G_OBJECT(persist), "flags");
+	LOG ("EphyEmbedPersist finalised %p", object)
 
-	return G_OK;
+	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
-static gresult
-impl_set_source (EphyEmbedPersist *persist,
-		 const char *url)
+static void
+ephy_embed_persist_class_init (EphyEmbedPersistClass *klass)
 {
-	persist->priv->src = g_strdup(url);
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-	g_object_notify (G_OBJECT(persist), "source");
+	parent_class = g_type_class_peek_parent (klass);
 
-	return G_OK;
-}
+	object_class->finalize = ephy_embed_persist_finalize;
+	object_class->set_property = ephy_embed_persist_set_property;
+	object_class->get_property = ephy_embed_persist_get_property;
 
-static gresult
-impl_set_dest (EphyEmbedPersist *persist,
-	       const char *dir)
-{
-	persist->priv->dir = g_strdup (dir);
+	/* init signals */
+	ephy_embed_persist_signals[COMPLETED] =
+		g_signal_new ("completed",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (EphyEmbedPersistClass, completed),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
 
-	g_object_notify (G_OBJECT(persist), "dest");
+	g_object_class_install_property (object_class,
+					 PROP_DEST,
+					 g_param_spec_string ("dest",
+							      "Destination",
+							      "Destination file path",
+							      NULL,
+							      G_PARAM_READWRITE));
 
-	return G_OK;
-}
+	g_object_class_install_property (object_class,
+					 PROP_EMBED,
+					 g_param_spec_object ("embed",
+							      "Embed",
+							      "The embed containing the document",
+							      G_TYPE_OBJECT,
+							      G_PARAM_READWRITE |
+							      G_PARAM_CONSTRUCT_ONLY));
 
-static gresult
-impl_set_max_size (EphyEmbedPersist *persist,
-		   int kb_size)
-{
-	persist->priv->max_size = kb_size;
+	g_object_class_install_property (object_class,
+					 PROP_FILECHOOSER_TITLE,
+					 g_param_spec_string  ("filechooser-title",
+							       "Filechooser title",
+							       "Title to use if showing filechooser",
+							       NULL,
+							       G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class,
+					 PROP_FILECHOOSER_PARENT,
+					 g_param_spec_object ("filechooser-parent",
+							      "Filechooser parent",
+							      "The parent window for the filechooser",
+							      GTK_TYPE_WINDOW,
+							      G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class,
+					 PROP_FLAGS,
+					 g_param_spec_int    ("flags",
+							      "Flags",
+							      "Flags",
+							      0,
+							      G_MAXINT,
+							      0,
+							      G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class,
+					 PROP_MAX_SIZE,
+					 g_param_spec_int    ("max_size",
+							      "Maxsize",
+							      "Maximum size of the file",
+							      0,
+							      G_MAXINT,
+							      0,
+							      G_PARAM_READWRITE));
 
-	g_object_notify (G_OBJECT(persist), "max_size");
+	g_object_class_install_property (object_class,
+					 PROP_PERSISTKEY,
+					 g_param_spec_string  ("persist-key",
+							       "persist key",
+							       "Path persistence gconf key",
+							       NULL,
+							       G_PARAM_READWRITE));
 
-	return G_OK;
+	g_object_class_install_property (object_class,
+					 PROP_SOURCE,
+					 g_param_spec_string  ("source",
+							       "Source",
+							       "Url of the document to save",
+							       NULL,
+							       G_PARAM_READWRITE));
+
+	g_type_class_add_private (object_class, sizeof(EphyEmbedPersistPrivate));
 }
 
-static gresult
-impl_set_embed (EphyEmbedPersist *persist,
-		EphyEmbed *embed)
+gresult
+ephy_embed_persist_cancel (EphyEmbedPersist *persist)
 {
-	persist->priv->embed = embed;
+	EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist);
+	return klass->cancel (persist);
+}
 
-	g_object_notify (G_OBJECT(persist), "embed");
+gresult
+ephy_embed_persist_save (EphyEmbedPersist *persist)
+{
+	EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist);
+	return klass->save (persist);
+}
 
-	return G_OK;
+EphyEmbedPersist *
+ephy_embed_persist_new (EphyEmbed *embed)
+{
+	return EPHY_EMBED_PERSIST (g_object_new (MOZILLA_TYPE_EMBED_PERSIST,
+						 "embed", embed,
+						 NULL));
 }
diff --git a/embed/ephy-embed-persist.h b/embed/ephy-embed-persist.h
index 1a48d2455..2f2db4f1b 100644
--- a/embed/ephy-embed-persist.h
+++ b/embed/ephy-embed-persist.h
@@ -1,5 +1,6 @@
 /*
- *  Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
+ *  Copyright (C) 2000-2003 Marco Pesenti Gritti
+ *  Copyright (C) 2003 Christian Persch
  *
  *  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
@@ -14,6 +15,8 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  $Id$
  */
 
 #ifndef EPHY_EMBED_PERSIST_H
@@ -24,6 +27,8 @@
 #include <glib-object.h>
 #include <glib.h>
 
+#include <gtk/gtkwindow.h>
+
 G_BEGIN_DECLS
 
 #define EPHY_TYPE_EMBED_PERSIST		(ephy_embed_persist_get_type ())
@@ -39,94 +44,78 @@ typedef struct EphyEmbedPersistPrivate EphyEmbedPersistPrivate;
 
 typedef enum
 {
-	EMBED_PERSIST_BYPASSCACHE = 1 << 0,
-	EMBED_PERSIST_MAINDOC = 1 << 1,
-	EMBED_PERSIST_NO_VIEW = 1 << 2,
-	EMBED_PERSIST_ASK_DESTINATION = 1 << 3
+	EMBED_PERSIST_BYPASSCACHE	= 1 << 0,
+	EMBED_PERSIST_MAINDOC		= 1 << 1,
+	EMBED_PERSIST_NO_VIEW		= 1 << 2,
+	EMBED_PERSIST_ASK_DESTINATION	= 1 << 3
 } EmbedPersistFlags;
 
-typedef struct
-{
-	char *command;
-	gboolean need_terminal;
-} PersistHandlerInfo;
-
 struct EphyEmbedPersist
 {
-        GObject parent;
-        EphyEmbedPersistPrivate *priv;
+	GObject parent;
+	EphyEmbedPersistPrivate *priv;
 };
 
 struct EphyEmbedPersistClass
 {
-        GObjectClass parent_class;
+	GObjectClass parent_class;
 
-	void (* completed) (EphyEmbedPersist *persist);
+	void (* completed)	(EphyEmbedPersist *persist);
 
 	/* Methods */
 
-	gresult (* set_source)   (EphyEmbedPersist *persist,
-				  const char *url);
+	gresult (* save)	(EphyEmbedPersist *persist);
 
-	gresult (* set_dest)     (EphyEmbedPersist *persist,
-				  const char *dir);
+	gresult (* cancel)	(EphyEmbedPersist *persist);
+};
 
-	gresult (* save)         (EphyEmbedPersist *persist);
+GType			 ephy_embed_persist_get_type	(void);
 
-	gresult (* cancel)       (EphyEmbedPersist *persist);
+EphyEmbedPersist	*ephy_embed_persist_new			(EphyEmbed *embed);
 
-	gresult (* set_max_size) (EphyEmbedPersist *persist,
-				  int max_size);
+gresult			 ephy_embed_persist_save		(EphyEmbedPersist *persist);
 
-	gresult (* set_embed)    (EphyEmbedPersist *persist,
-				  EphyEmbed *embed);
+gresult			 ephy_embed_persist_cancel		(EphyEmbedPersist *persist);
 
-	gresult (* set_flags)    (EphyEmbedPersist *persist,
-				  EmbedPersistFlags flags);
+void			 ephy_embed_persist_set_dest		(EphyEmbedPersist *persist,
+								 const char *value);
 
-	gresult (* set_handler)  (EphyEmbedPersist *persist,
-				  const char *command,
-				  gboolean need_terminal);
-};
+void			 ephy_embed_persist_set_embed		(EphyEmbedPersist *persist,
+								 EphyEmbed *value);
 
-GType               ephy_embed_persist_get_type    (void);
+void			 ephy_embed_persist_set_fc_title	(EphyEmbedPersist *persist,
+								 const char *value);
 
-EphyEmbedPersist   *ephy_embed_persist_new         (EphyEmbed *embed);
+void			 ephy_embed_persist_set_fc_parent	(EphyEmbedPersist *persist,
+								 GtkWindow *value);
 
-gresult             ephy_embed_persist_set_source  (EphyEmbedPersist *persist,
-						    const char *url);
+void			 ephy_embed_persist_set_flags		(EphyEmbedPersist *persist,
+								 EmbedPersistFlags value);
 
-gresult             ephy_embed_persist_get_source  (EphyEmbedPersist *persist,
-						    const char **url);
+void			 ephy_embed_persist_set_max_size	(EphyEmbedPersist *persist,
+								 int value);
 
-gresult		    ephy_embed_persist_set_dest    (EphyEmbedPersist *persist,
-						    const char *dir);
+void			 ephy_embed_persist_set_persist_key	(EphyEmbedPersist *persist,
+								 const char *value);
 
-gresult		    ephy_embed_persist_get_dest    (EphyEmbedPersist *persist,
-						    const char **dir);
+void			 ephy_embed_persist_set_source		(EphyEmbedPersist *persist,
+								 const char *value);
 
-gresult		    ephy_embed_persist_set_handler (EphyEmbedPersist *persist,
-						    const char *handler,
-						    gboolean need_terminal);
+const char 		*ephy_embed_persist_get_dest		(EphyEmbedPersist *persist);
 
-gresult		    ephy_embed_persist_set_max_size (EphyEmbedPersist *persist,
-						     int kb_size);
+EphyEmbed		*ephy_embed_persist_get_embed		(EphyEmbedPersist *persist);
 
-gresult             ephy_embed_persist_set_embed   (EphyEmbedPersist *persist,
-		                                    EphyEmbed *embed);
+const char 		*ephy_embed_persist_get_fc_title	(EphyEmbedPersist *persist);
 
-gresult             ephy_embed_persist_get_embed   (EphyEmbedPersist *persist,
-		                                    EphyEmbed **embed);
+GtkWindow		*ephy_embed_persist_get_fc_parent	(EphyEmbedPersist *persist);
 
-gresult		    ephy_embed_persist_set_flags   (EphyEmbedPersist *persist,
-						    EmbedPersistFlags flags);
+EmbedPersistFlags	 ephy_embed_persist_get_flags		(EphyEmbedPersist *persist);
 
-gresult		    ephy_embed_persist_get_flags   (EphyEmbedPersist *persist,
-						    EmbedPersistFlags *flags);
+int			 ephy_embed_persist_get_max_size	(EphyEmbedPersist *persist);
 
-gresult		    ephy_embed_persist_save        (EphyEmbedPersist *persist);
+const char 		*ephy_embed_persist_get_persist_key	(EphyEmbedPersist *persist);
 
-gresult		    ephy_embed_persist_cancel      (EphyEmbedPersist *persist);
+const char 		*ephy_embed_persist_get_source		(EphyEmbedPersist *persist);
 
 G_END_DECLS
 
diff --git a/embed/ephy-embed-popup-control.c b/embed/ephy-embed-popup-control.c
index a300e0535..5cda121e1 100644
--- a/embed/ephy-embed-popup-control.c
+++ b/embed/ephy-embed-popup-control.c
@@ -1,5 +1,6 @@
 /*
- *  Copyright (C) 2000, 2001, 2002 Ricardo Fern�ndez Pascual
+ *  Copyright (C) 2000, 2001, 2002 Ricardo Fernández Pascual
+ *  Copyright (C) 2003 Marco Pesenti Gritti
  *
  *  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
@@ -19,8 +20,8 @@
  */
 
 #include "ephy-embed-popup-control.h"
+#include "ephy-embed-persist.h"
 #include "ephy-bonobo-extensions.h"
-#include "ephy-embed-utils.h"
 #include "ephy-prefs.h"
 #include "eel-gconf-extensions.h"
 #include "ephy-file-helpers.h"
@@ -476,6 +477,31 @@ embed_popup_copy_link_location_cmd (BonoboUIComponent *uic,
 	embed_popup_copy_to_clipboard (popup, location);
 }
 
+static void
+save_url (EphyEmbedPopupControl *popup,
+	  const char *title,
+	  gboolean ask_dest,
+	  const char *location)
+{
+	GtkWidget *widget, *window;
+	EphyEmbedPersist *persist;
+
+	widget = GTK_WIDGET (popup->priv->embed);
+	window = gtk_widget_get_toplevel (widget);
+
+	persist = ephy_embed_persist_new (popup->priv->embed);
+
+	ephy_embed_persist_set_fc_title (persist, title);
+	ephy_embed_persist_set_fc_parent (persist,GTK_WINDOW (window));
+	ephy_embed_persist_set_flags
+		(persist, ask_dest ? EMBED_PERSIST_ASK_DESTINATION : 0);
+	ephy_embed_persist_set_persist_key
+		(persist, CONF_STATE_DOWNLOADING_DIR);
+	ephy_embed_persist_set_source (persist, location);
+
+	ephy_embed_persist_save (persist);
+}
+
 static void
 save_property_url (EphyEmbedPopupControl *popup,
 		   const char *title,
@@ -485,24 +511,12 @@ save_property_url (EphyEmbedPopupControl *popup,
 	EphyEmbedEvent *info;
 	const char *location;
 	const GValue *value;
-	GtkWidget *widget;
-	GtkWidget *window;
-	EphyEmbedPersist *persist;
 
 	info = ephy_embed_popup_control_get_event (popup);
 	ephy_embed_event_get_property (info, property, &value);
 	location = g_value_get_string (value);
 
-	widget = GTK_WIDGET (popup->priv->embed);
-	window = gtk_widget_get_toplevel (widget);
-
-	persist = ephy_embed_persist_new (popup->priv->embed);
-
-	ephy_embed_persist_set_source (persist, location);
-
-	ephy_embed_utils_save (window, title,
-			       CONF_STATE_DOWNLOADING_DIR,
-			       ask_dest, persist);
+	save_url (popup, title, ask_dest, location);
 }
 
 /* commands */
@@ -553,16 +567,14 @@ background_download_completed (EphyEmbedPersist *persist,
 	const char *bg;
 	char *type;
 
-	ephy_embed_persist_get_dest (persist, &bg);
+	bg = ephy_embed_persist_get_dest (persist);
 	eel_gconf_set_string (CONF_DESKTOP_BG_PICTURE, bg);
 
 	type = eel_gconf_get_string (CONF_DESKTOP_BG_TYPE);
-	if (type || strcmp (type, "none") == 0)
+	if (type == NULL || strcmp (type, "none") == 0)
 	{
-		eel_gconf_set_string (CONF_DESKTOP_BG_TYPE,
-				      "wallpaper");
+		eel_gconf_set_string (CONF_DESKTOP_BG_TYPE, "wallpaper");
 	}
-
 	g_free (type);
 
 	g_object_unref (persist);
@@ -586,11 +598,11 @@ embed_popup_set_image_as_background_cmd (BonoboUIComponent *uic,
 	persist = ephy_embed_persist_new (popup->priv->embed);
 
 	base = g_path_get_basename (location);
-	dest = g_build_filename (ephy_dot_dir (),
-				 base, NULL);
+	dest = g_build_filename (ephy_dot_dir (), base, NULL);
 
-	ephy_embed_persist_set_source (persist, location);
 	ephy_embed_persist_set_dest (persist, dest);
+	ephy_embed_persist_set_flags (persist, EMBED_PERSIST_NO_VIEW);
+	ephy_embed_persist_set_source (persist, location);
 
 	ephy_embed_persist_save (persist);
 
@@ -617,27 +629,6 @@ embed_popup_copy_image_location_cmd (BonoboUIComponent *uic,
 	embed_popup_copy_to_clipboard (popup, location);
 }
 
-static void
-save_url (EphyEmbedPopupControl *popup,
-	  const char *title,
-	  gboolean ask_dest,
-	  const char *url)
-{
-	GtkWidget *widget;
-	GtkWidget *window;
-	EphyEmbedPersist *persist;
-
-	widget = GTK_WIDGET (popup->priv->embed);
-	window = gtk_widget_get_toplevel (widget);
-
-	persist = ephy_embed_persist_new (popup->priv->embed);
-	ephy_embed_persist_set_source (persist, url);
-
-	ephy_embed_utils_save (window, title,
-			       CONF_STATE_DOWNLOADING_DIR,
-			       ask_dest, persist);
-}
-
 static void
 embed_popup_save_page_as_cmd (BonoboUIComponent *uic,
 			      EphyEmbedPopupControl *popup,
diff --git a/embed/ephy-embed-single.c b/embed/ephy-embed-single.c
index d09377552..7c82b6000 100644
--- a/embed/ephy-embed-single.c
+++ b/embed/ephy-embed-single.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
+ *  Copyright (C) 2000, 2001, 2002, 2003 Marco Pesenti Gritti
  *
  *  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
@@ -182,42 +182,6 @@ ephy_embed_single_remove_passwords (EphyEmbedSingle *shell,
         return klass->remove_passwords (shell, passwords, type);
 }
 
-/**
- * show_file_picker: Shows a file picker. Can be configured to select a
- * file or a directory.
- * @parentWidget: Parent Widget for file picker.
- * @title: Title for file picker.
- * @directory: Initial directory to start in.
- * @file: Initial filename to show in filepicker.
- * @mode: Mode to run filepicker in (modeOpen, modeSave, modeGetFolder)
- * @ret_fullpath: On a successful return, will hold the full path to selected
- *		file or directory.
- * @file_formats: an array of FileFormat structures to fill the format chooser
- *              optionmenu. NULL if not needed. The last item must have
- *              description == NULL.
- * @ret_file_format: where to store the index of the format selected (can be
- *              NULL)
- * returns: TRUE for success, FALSE for failure.
- */
-
-gresult
-ephy_embed_single_show_file_picker (EphyEmbedSingle *shell,
-				   GtkWidget *parentWidget,
-				   const char *title,
-				   const char *directory,
-		                   const char *file,
-				   FilePickerMode mode,
-				   char **ret_fullpath,
-				   FileFormat *file_formats,
-				   int *ret_file_format)
-{
-	EphyEmbedSingleClass *klass = EPHY_EMBED_SINGLE_GET_CLASS (shell);
-        return klass->show_file_picker (shell, parentWidget, title,
-					directory, file, mode,
-					ret_fullpath,
-					file_formats, ret_file_format);
-}
-
 gresult
 ephy_embed_single_free_cookies (EphyEmbedSingle *shell,
 			       GList *cookies)
diff --git a/embed/ephy-embed-single.h b/embed/ephy-embed-single.h
index 9a6e5e873..e45b99cad 100644
--- a/embed/ephy-embed-single.h
+++ b/embed/ephy-embed-single.h
@@ -14,6 +14,8 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  $Id$
  */
 
 #ifndef EPHY_EMBED_SINGLE_H
@@ -132,15 +134,6 @@ struct EphyEmbedSingleClass
 	gresult         (* remove_passwords)    (EphyEmbedSingle *shell,
 						 GList *passwords,
 						 PasswordType type);
-	gresult         (* show_file_picker)    (EphyEmbedSingle *shell,
-						 GtkWidget *parentWidget,
-						 const char* title,
-						 const char* directory,
-						 const char* file,
-						 FilePickerMode mode,
-						 char **ret_fullpath,
-						 FileFormat *file_formats,
-						 gint *ret_file_format);
 };
 
 GType             ephy_embed_single_get_type            (void);
@@ -179,16 +172,6 @@ gresult           ephy_embed_single_remove_passwords    (EphyEmbedSingle *shell,
 							 GList *passwords,
 							 PasswordType type);
 
-gresult           ephy_embed_single_show_file_picker    (EphyEmbedSingle *shell,
-							 GtkWidget *parentWidget,
-							 const char *title,
-							 const char *directory,
-							 const char *file,
-							 FilePickerMode mode,
-							 char **ret_fullpath,
-							 FileFormat *file_formats,
-							 int *ret_file_format);
-
 G_END_DECLS
 
 #endif
diff --git a/embed/ephy-embed-utils.c b/embed/ephy-embed-utils.c
deleted file mode 100644
index 0bcd6bb52..000000000
--- a/embed/ephy-embed-utils.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- *  Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
- *
- *  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, 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, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *  $Id$
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "eel-gconf-extensions.h"
-#include "ephy-embed-utils.h"
-#include "ephy-embed-shell.h"
-#include "ephy-bonobo-extensions.h"
-#include "ephy-gui.h"
-#include "ephy-debug.h"
-#include "ephy-langs.h"
-
-#include <gtk/gtkdialog.h>
-#include <gtk/gtkmessagedialog.h>
-#include <bonobo/bonobo-i18n.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <libgnomevfs/gnome-vfs-uri.h>
-#include <string.h>
-
-/**
- * ephy_embed_utils_save:
- * @window: the referrer window. Used to parent the dialogs.
- * @title: title of the file picker
- * @default_dir_pref: the gconf path to persist the directory selected by the user.
- * @ask_dest: ask the user the destination path
- * @ask_content: show the user an option to save the content
- * of the web page (images, javascript...)
- * @persist: the #EphyEmbedPersist referring to the url
- *
- * Download a save an url asking a location to the user when requested
- **/
-void
-ephy_embed_utils_save (GtkWidget *window,
-		       const char *title,
-		       const char *default_dir_pref,
-		       gboolean ask_dest,
-		       EphyEmbedPersist *persist)
-{
-	GnomeVFSURI *uri;
-        char *retPath = NULL;
-        char *fileName = NULL;
-        char *dirName = NULL;
-	char *target;
-	const char *source;
-        gresult ret;
-	EphyEmbed *embed;
-	EmbedPersistFlags flags;
-	EphyEmbedSingle *single;
-
-	single = ephy_embed_shell_get_embed_single
-		(EPHY_EMBED_SHELL (embed_shell));
-
-	g_object_ref (G_OBJECT(persist));
-
-	ephy_embed_persist_get_flags (persist, &flags);
-
-	ephy_embed_persist_get_source (persist, &source);
-
-	if (source)
-	{
-		target = g_strdup (source);
-	}
-	else
-	{
-		ephy_embed_persist_get_embed (persist, &embed);
-		g_return_if_fail (embed != NULL);
-
-		ephy_embed_get_location (embed,
-					 flags &
-					 EMBED_PERSIST_MAINDOC,
-					 &target);
-	}
-
-        /* Get a filename from the target url */
-        uri = gnome_vfs_uri_new (target);
-        if (uri)
-        {
-                fileName = gnome_vfs_uri_extract_short_name (uri);
-                gnome_vfs_uri_unref (uri);
-        }
-
-        dirName = eel_gconf_get_string (default_dir_pref);
-        if (dirName && dirName[0] == '\0')
-        {
-		g_free (dirName);
-                dirName = NULL;
-        }
-
-        if (!dirName || strcmp (dirName,"~") == 0)
-        {
-                g_free (dirName);
-                dirName = g_strdup(g_get_home_dir ());
-        }
-
-	/* If we aren't asking for downloading dir, check that we aren't
-	 * overwriting anything.  If we are, pop up a warning dialog and show
-	 * the filepicker if the user doesn't want to overwrite the file.
-	 */
-	ret = G_FAILED;
-	if (!ask_dest)
-	{
-		retPath = g_build_filename (dirName, fileName, NULL);
-		if (ephy_gui_confirm_overwrite_file (window, retPath))
-		{
-			ret = G_OK;
-		}
-		else
-		{
-			g_free (retPath);
-			retPath = NULL;
-			ask_dest = TRUE;
-		}
-	}
-
-	if (ask_dest)
-	{
-		char *ret_dir;
-
-		/* show the file picker */
-		ret = ephy_embed_single_show_file_picker
-					(single, window, title,
-                                         dirName, fileName, modeSave, &retPath,
-                                         NULL, NULL);
-
-		if (g_file_test (retPath, G_FILE_TEST_IS_DIR))
-		{
-			ret_dir = g_strdup (retPath);
-		}
-		else
-		{
-			ret_dir = g_path_get_dirname (retPath);
-		}
-	
-		/* set default save dir */
-		eel_gconf_set_string (default_dir_pref, ret_dir);
-		g_free (ret_dir);
-	}
-
-        if (ret == G_OK)
-        {
-		ephy_embed_persist_set_flags (persist, flags);
-
-		ephy_embed_persist_set_dest (persist, retPath);
-
-		if (ephy_embed_persist_save (persist) == G_FAILED)
-		{
-			GtkWidget *dialog;
-
-			dialog = gtk_message_dialog_new
-				(GTK_WINDOW (window),
-	                         GTK_DIALOG_MODAL,
-	                         GTK_MESSAGE_ERROR,
-	                         GTK_BUTTONS_CLOSE,
-	                         _("The file has not been saved."));
-			gtk_dialog_run (GTK_DIALOG (dialog));
-			gtk_widget_destroy (dialog);
-		}
-
-	}
-
-	g_free (retPath);
-
-	g_object_unref (G_OBJECT(persist));
-
-        g_free (dirName);
-        g_free (fileName);
-	g_free (target);
-}
-
-/**
- * ephy_embed_utils_handlernotfound_dialog_run:
- * @parent: the dialog parent window
- *
- * Show a dialog to warn the user that no application capable
- * to open the specified file are found. Used in the downloader
- * and in the mime type dialog.
- **/
-void
-ephy_embed_utils_nohandler_dialog_run (GtkWidget *parent)
-{
-        GtkWidget *dialog;
-        
-	/* FIXME mime db shortcut */
-	
-	dialog = gtk_message_dialog_new 
-		(GTK_WINDOW(parent), 
-                 GTK_DIALOG_MODAL,
-                 GTK_MESSAGE_ERROR,
-                 GTK_BUTTONS_OK,
-                 _("No available applications to open "
-                   "the specified file."));
-        gtk_dialog_run (GTK_DIALOG(dialog));
-	gtk_widget_destroy (dialog);
-}
diff --git a/embed/ephy-embed-utils.h b/embed/ephy-embed-utils.h
deleted file mode 100644
index 312e51026..000000000
--- a/embed/ephy-embed-utils.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
- *
- *  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, 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, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef EPHY_EMBED_UTILS_H
-#define EPHY_EMBED_UTILS_H
-
-#include "ephy-embed-persist.h"
-
-#include <gtk/gtkwidget.h>
-#include <bonobo/bonobo-ui-component.h>
-
-G_BEGIN_DECLS
-
-void ephy_embed_utils_save			(GtkWidget *window,
-						 const char *title,
-						 const char *default_dir_pref,
-						 gboolean ask_dest,
-						 EphyEmbedPersist *persist);
-
-void ephy_embed_utils_nohandler_dialog_run      (GtkWidget *parent);
-
-G_END_DECLS
-
-#endif
diff --git a/embed/ephy-favicon-cache.c b/embed/ephy-favicon-cache.c
index da598a9e2..f0c3a0022 100644
--- a/embed/ephy-favicon-cache.c
+++ b/embed/ephy-favicon-cache.c
@@ -1,5 +1,6 @@
 /*
  *  Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org>
+ *  Copyright (C) 2003 Marco Pesenti Gritti
  *
  *  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
@@ -84,8 +85,8 @@ ephy_favicon_cache_get_type (void)
 		};
 
 		ephy_favicon_cache_type = g_type_register_static (G_TYPE_OBJECT,
-								    "EphyFaviconCache",
-								     &our_info, 0);
+								  "EphyFaviconCache",
+								  &our_info, 0);
 	}
 
 	return ephy_favicon_cache_type;
@@ -117,11 +118,7 @@ ephy_favicon_cache_class_init (EphyFaviconCacheClass *klass)
 EphyFaviconCache *
 ephy_favicon_cache_new (void)
 {
-	EphyFaviconCache *cache;
-
-	cache = EPHY_FAVICON_CACHE (g_object_new (EPHY_TYPE_FAVICON_CACHE, NULL));
-
-	return cache;
+	return EPHY_FAVICON_CACHE (g_object_new (EPHY_TYPE_FAVICON_CACHE, NULL));
 }
 
 static gboolean
@@ -133,8 +130,8 @@ icon_is_obsolete (EphyNode *node, GDate *now)
 	last_visit = ephy_node_get_property_int
 		(node, EPHY_NODE_FAVICON_PROP_LAST_USED);
 
-        g_date_clear (&date, 1);
-        g_date_set_time (&date, last_visit);
+	g_date_clear (&date, 1);
+	g_date_set_time (&date, last_visit);
 
 	return (g_date_days_between (&date, now) >=
 		EPHY_FAVICON_CACHE_OBSOLETE_DAYS);
@@ -142,8 +139,8 @@ icon_is_obsolete (EphyNode *node, GDate *now)
 
 static void
 icons_added_cb (EphyNode *node,
-	        EphyNode *child,
-	        EphyFaviconCache *eb)
+		EphyNode *child,
+		EphyFaviconCache *eb)
 {
 	g_static_rw_lock_writer_lock (eb->priv->icons_hash_lock);
 
@@ -176,8 +173,8 @@ remove_obsolete_icons (EphyFaviconCache *eb)
 	GDate current_date;
 
 	now = time (NULL);
-        g_date_clear (&current_date, 1);
-        g_date_set_time (&current_date, time (NULL));
+	g_date_clear (&current_date, 1);
+	g_date_set_time (&current_date, time (NULL));
 
 	children = ephy_node_get_children (eb->priv->icons);
 	ephy_node_thaw (eb->priv->icons);
@@ -245,8 +242,8 @@ ephy_favicon_cache_init (EphyFaviconCache *cache)
 	cache->priv->db = db;
 
 	cache->priv->xml_file = g_build_filename (ephy_dot_dir (),
-					          "ephy-favicon-cache.xml",
-					          NULL);
+						  "ephy-favicon-cache.xml",
+						  NULL);
 
 	cache->priv->directory = g_build_filename (ephy_dot_dir (),
 						   "favicon_cache/",
@@ -261,11 +258,11 @@ ephy_favicon_cache_init (EphyFaviconCache *cache)
 	}
 
 	cache->priv->icons_hash = g_hash_table_new (g_str_hash,
-			                            g_str_equal);
+						    g_str_equal);
 	cache->priv->icons_hash_lock = g_new0 (GStaticRWLock, 1);
 	g_static_rw_lock_init (cache->priv->icons_hash_lock);
 	cache->priv->downloads_hash = g_hash_table_new_full (g_str_hash,
-			                                     g_str_equal,
+							     g_str_equal,
 							     g_free,
 							     NULL);
 
@@ -273,13 +270,13 @@ ephy_favicon_cache_init (EphyFaviconCache *cache)
 	cache->priv->icons = ephy_node_new_with_id (db, ICONS_NODE_ID);
 	ephy_node_ref (cache->priv->icons);
 	ephy_node_signal_connect_object (cache->priv->icons,
-				         EPHY_NODE_CHILD_ADDED,
-				         (EphyNodeCallback) icons_added_cb,
-				         G_OBJECT (cache));
+					 EPHY_NODE_CHILD_ADDED,
+					 (EphyNodeCallback) icons_added_cb,
+					 G_OBJECT (cache));
 	ephy_node_signal_connect_object (cache->priv->icons,
-				         EPHY_NODE_CHILD_REMOVED,
-				         (EphyNodeCallback) icons_removed_cb,
-				         G_OBJECT (cache));
+					 EPHY_NODE_CHILD_REMOVED,
+					 (EphyNodeCallback) icons_removed_cb,
+					 G_OBJECT (cache));
 
 	ephy_node_db_load_from_file (cache->priv->db, cache->priv->xml_file,
 				     EPHY_FAVICON_CACHE_XML_ROOT,
@@ -356,17 +353,16 @@ static void
 favicon_download_completed_cb (EphyEmbedPersist *persist,
 			       EphyFaviconCache *cache)
 {
-	char *url;
+	const char *url;
 
-	url = g_strdup ((char *) g_object_get_data (G_OBJECT (persist), "url"));
+	url = ephy_embed_persist_get_source (persist);
 	g_return_if_fail (url != NULL);
 
 	g_hash_table_remove (cache->priv->downloads_hash, url);
-	g_object_unref (persist);
 
 	g_signal_emit (G_OBJECT (cache), ephy_favicon_cache_signals[CHANGED], 0, url);
 
-	g_free (url);
+	g_object_unref (persist);
 }
 
 static void
@@ -387,17 +383,14 @@ ephy_favicon_cache_download (EphyFaviconCache *cache,
 
 	persist = ephy_embed_persist_new (NULL);
 
+	ephy_embed_persist_set_dest (persist, dest);
+	ephy_embed_persist_set_flags
+		(persist, EMBED_PERSIST_BYPASSCACHE | EMBED_PERSIST_NO_VIEW);
 	ephy_embed_persist_set_max_size (persist, 100);
-	ephy_embed_persist_set_flags    (persist, EMBED_PERSIST_BYPASSCACHE |
-						  EMBED_PERSIST_NO_VIEW);
-	ephy_embed_persist_set_source   (persist, favicon_url);
-	ephy_embed_persist_set_dest     (persist, dest);
+	ephy_embed_persist_set_source (persist, favicon_url);
 
 	g_free (dest);
 
-	g_object_set_data_full (G_OBJECT (persist), "url",
-				g_strdup (favicon_url), g_free);
-
 	g_signal_connect (G_OBJECT (persist),
 			  "completed",
 			  G_CALLBACK (favicon_download_completed_cb),
@@ -437,13 +430,13 @@ ephy_favicon_cache_get (EphyFaviconCache *cache,
 		g_value_init (&value, G_TYPE_STRING);
 		g_value_set_string (&value, url);
 		ephy_node_set_property (icon, EPHY_NODE_FAVICON_PROP_URL,
-				        &value);
+					&value);
 		g_value_unset (&value);
 
 		g_value_init (&value, G_TYPE_STRING);
 		g_value_set_string (&value, filename);
 		ephy_node_set_property (icon, EPHY_NODE_FAVICON_PROP_FILENAME,
-				        &value);
+					&value);
 		g_value_unset (&value);
 
 		ephy_node_add_child (cache->priv->icons, icon);
@@ -456,7 +449,7 @@ ephy_favicon_cache_get (EphyFaviconCache *cache,
 	g_value_init (&value, G_TYPE_INT);
 	g_value_set_int (&value, now);
 	ephy_node_set_property (icon, EPHY_NODE_FAVICON_PROP_LAST_USED,
-			        &value);
+				&value);
 	g_value_unset (&value);
 
 	if (g_hash_table_lookup (cache->priv->downloads_hash, url) != NULL)
diff --git a/embed/mozilla/ContentHandler.cpp b/embed/mozilla/ContentHandler.cpp
index 519bff738..7da5ae25c 100644
--- a/embed/mozilla/ContentHandler.cpp
+++ b/embed/mozilla/ContentHandler.cpp
@@ -14,6 +14,8 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  $Id$
  */
 
 /*
@@ -144,41 +146,17 @@
  */
 
 #ifdef HAVE_CONFIG_H
-#include <config.h>
+#include "config.h"
 #endif
 
-extern "C" {
-#include "libgnomevfs/gnome-vfs-mime-handlers.h"
-}
-
-#include "ephy-embed-shell.h"
-#include "ephy-prefs.h"
-#include "eel-gconf-extensions.h"
-#include "ephy-glade.h"
-#include "ephy-string.h"
-#include "ephy-gui.h"
-#include "ephy-embed-utils.h"
-#include "ephy-file-helpers.h"
 #include "ContentHandler.h"
 
-#include <gtk/gtkentry.h>
-#include <gtk/gtktogglebutton.h>
-#include <gtk/gtkprogress.h>
-#include <gtk/gtkoptionmenu.h>
-#include <libgnome/gnome-exec.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnome/gnome-config.h>
-#include <libgnome/gnome-util.h>
-#include <libgnomevfs/gnome-vfs-mime.h>
-
 #include "FilePicker.h"
 #include "MozillaPrivate.h"
 
-#include "nsCRT.h"
 #include "nsCOMPtr.h"
 #include "nsISupportsArray.h"
 #include "nsIServiceManager.h"
-#include "nsWeakReference.h"
 
 #include "nsString.h"
 #include "nsIURI.h"
@@ -190,8 +168,28 @@ extern "C" {
 #include "nsIDOMWindowInternal.h"
 #include "nsIMIMEInfo.h"
 
+#include "ephy-embed-shell.h"
+#include "ephy-prefs.h"
+#include "eel-gconf-extensions.h"
+#include "ephy-glade.h"
+#include "ephy-string.h"
+#include "ephy-gui.h"
+#include "ephy-file-helpers.h"
+
+#include <gtk/gtkentry.h>
+#include <gtk/gtktogglebutton.h>
+#include <gtk/gtkprogress.h>
+#include <gtk/gtkoptionmenu.h>
+#include <gtk/gtkdialog.h>
+#include <gtk/gtkmessagedialog.h>
+#include <libgnome/gnome-exec.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-config.h>
+#include <libgnome/gnome-util.h>
+#include <libgnomevfs/gnome-vfs-mime.h>
+#include <bonobo/bonobo-i18n.h>
+
 class GContentHandler;
-//class GDownloadProgressListener;
 struct MimeAskActionDialog;
 struct HelperAppChooserDialog;
 
@@ -562,7 +560,7 @@ MimeAskActionDialog::MimeAskActionDialog(GContentHandler *aContentHandler,
 	GtkWidget *label;
 	GtkWidget *dialogWidget;
 	const char *description;
-	char ltext[255]; //philipl: Fixed length buffer == potential security problem...
+	char *ltext;
 
 	mGXml = ephy_glade_widget_new ("epiphany.glade", "mime_ask_action_dialog", 
 				      &dialogWidget, this);
@@ -579,9 +577,10 @@ MimeAskActionDialog::MimeAskActionDialog(GContentHandler *aContentHandler,
 	description = gnome_vfs_mime_get_description (aMimeType);
 	if (!description) description = aMimeType;
 	
-	g_snprintf (ltext, 255, "<b>%s</b>", description);
+	ltext = g_strdup_printf ("<b>%s</b>", description);
 	label = glade_xml_get_widget (mGXml, "mime_ask_action_description");
 	gtk_label_set_markup (GTK_LABEL (label), ltext);
+	g_free (ltext);
 
 	gtk_window_set_transient_for (GTK_WINDOW (dialogWidget), 
 				      GTK_WINDOW (aParentWidget));
@@ -646,9 +645,24 @@ mime_ask_dialog_open (MimeAskActionDialog *dialog)
 		delete dialog;
 	}
 	else
-	{	
+	{
+		GtkWidget *message_dialog;
+		
 		mime_ask_dialog_cancel (dialog);
-		ephy_embed_utils_nohandler_dialog_run (dialog->mParent);
+
+		/* FIXME mime db shortcut */
+
+		message_dialog = gtk_message_dialog_new 
+				(GTK_WINDOW (dialog->mParent), 
+				 GTK_DIALOG_MODAL,
+				 GTK_MESSAGE_ERROR,
+				 GTK_BUTTONS_OK,
+				 _("No available applications to open "
+				   "the specified file."));
+		gtk_dialog_run (GTK_DIALOG (message_dialog));
+		gtk_widget_destroy (message_dialog);
+
+		/* FIXME where is dialog deleted ? */
 	}
 }
 
diff --git a/embed/mozilla/ContentHandler.h b/embed/mozilla/ContentHandler.h
index d08cf6cbd..3c8a6225f 100644
--- a/embed/mozilla/ContentHandler.h
+++ b/embed/mozilla/ContentHandler.h
@@ -14,6 +14,8 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  $Id$
  */
 
 #ifndef __ContentHandler_h
@@ -31,6 +33,9 @@
 #include "nsIURI.h"
 #include "nsILocalFile.h"
 
+#include "nsCRT.h"
+#include "nsWeakReference.h"
+
 #include "nsCOMPtr.h"
 #include "nsISupports.h"
 #include "nsError.h"
diff --git a/embed/mozilla/EphyHeaderSniffer.cpp b/embed/mozilla/EphyHeaderSniffer.cpp
index 483f0fd01..76b71a53f 100644
--- a/embed/mozilla/EphyHeaderSniffer.cpp
+++ b/embed/mozilla/EphyHeaderSniffer.cpp
@@ -34,7 +34,10 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
- * ***** END LICENSE BLOCK ***** */
+ * ***** END LICENSE BLOCK *****
+ *
+ * $Id$
+ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -46,6 +49,9 @@
 #include "EphyHeaderSniffer.h"
 #include "netCore.h"
 
+#include "ephy-file-chooser.h"
+#include "ephy-prefs.h"
+
 #include "nsReadableUtils.h"
 #include "nsIChannel.h"
 #include "nsIHttpChannel.h"
@@ -164,7 +170,7 @@ nsresult EphyHeaderSniffer::PerformSave (nsIURI* inOriginalURI)
 	EmbedPersistFlags flags;
 	PRBool askDownloadDest;
 
-	ephy_embed_persist_get_flags (EPHY_EMBED_PERSIST (mEmbedPersist), &flags);
+	flags = ephy_embed_persist_get_flags (EPHY_EMBED_PERSIST (mEmbedPersist));
 	askDownloadDest = flags & EMBED_PERSIST_ASK_DESTINATION;
  
 	nsAutoString defaultFileName;
@@ -176,7 +182,7 @@ nsresult EphyHeaderSniffer::PerformSave (nsIURI* inOriginalURI)
 		if (index >= 0)
 		{
 			/* Take the substring following the prefix. */
-			index += 9;
+			index += strlen ("filename=");
 			nsCAutoString filename;
 			mContentDisposition.Right(filename, mContentDisposition.Length() - index);
 			defaultFileName = NS_ConvertUTF8toUCS2(filename);
@@ -232,16 +238,24 @@ nsresult EphyHeaderSniffer::PerformSave (nsIURI* inOriginalURI)
 
 	if (askDownloadDest)
 	{
-		/* FIXME show the file selector here */
+		/* FIXME */
 	}
 	else
 	{
 		/* FIXME build path from download dir */
 	}
-             
+           
+	if (defaultFileName.IsEmpty())
+	{
+		defaultFileName.AssignWithConversion(_("Untitled"));
+	}
+        
+	/* FIXME ask user if overwriting ? */
+
+	/* FIXME: how to inform user of failed save ? */
         nsCOMPtr<nsILocalFile> destFile;
        	rv = NS_NewLocalFile(defaultFileName, PR_TRUE, getter_AddRefs(destFile)); 
-        if (NS_FAILED(rv) || !destFile) return G_FAILED;
+        if (NS_FAILED(rv) || !destFile) return NS_ERROR_FAILURE;
 
 	return InitiateMozillaDownload (mDocument, mURL, destFile,
 					mContentType.get(), inOriginalURI, mEmbedPersist,
diff --git a/embed/mozilla/FilePicker.cpp b/embed/mozilla/FilePicker.cpp
index 42c17be06..74b3e7bec 100644
--- a/embed/mozilla/FilePicker.cpp
+++ b/embed/mozilla/FilePicker.cpp
@@ -1,5 +1,6 @@
 /*
  *  Copyright (C) 2001 Philip Langdale
+ *  Copyright (C) 2003 Christian Persch
  *
  *  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
@@ -14,45 +15,15 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/* Things to be aware of:
- *
- * This filepicker, like the mozilla one, does not make an attempt
- * to verify the validity of the initial directory you pass it.
- * It does check that the user doesn't give it a garbage path
- * during use, but it is the caller's responsibility to give a
- * sensible initial path.
  *
- * At the current moment, we instantiate the filepicker directly
- * in our contenthandler where there is path verification code
- * and else where through our C wrapper, which also does verification.
- * If, at a future date, you need to instantiate filepicker without
- * using the C wrapper, please verify the initial path. See
- * ContentHandler for a way to do this.
+ *  $Id$
  */
 
 #ifdef HAVE_CONFIG_H
-#include <config.h>
+#include "config.h"
 #endif
 
-#include "ephy-string.h"
-#include "ephy-gui.h"
-
-#include <glib/gconvert.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtksignal.h>
-#include <gtk/gtkmenu.h>
-#include <gtk/gtkmenuitem.h>
-#include <gtk/gtkcheckbutton.h>
-#include <gtk/gtktogglebutton.h>
-#include <gtk/gtkfilesel.h>
-#include <gtk/gtkhbbox.h>
-#include <gtk/gtkoptionmenu.h>
-#include <gtk/gtkmessagedialog.h>
-#include <libgnome/gnome-i18n.h>
-
-#include "nsIFilePicker.h"
+#include "FilePicker.h"
 
 #include "nsCRT.h"
 #include "nsCOMPtr.h"
@@ -70,364 +41,308 @@
 #include "nsILocalFile.h"
 #include "nsIPromptService.h"
 #include "nsReadableUtils.h"
+#include "nsIDOMWindow.h"
+#include "nsIDOMWindowInternal.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "nsILocalFile.h"
+#include "MozillaPrivate.h"
 
-#include <libgnome/gnome-util.h>
+#include "ephy-string.h"
+#include "ephy-prefs.h"
+#include "ephy-gui.h"
+#include "ephy-debug.h"
 
-#include "FilePicker.h"
-#include "MozillaPrivate.h"
+#include <glib/gconvert.h>
+#include <gtk/gtkfilefilter.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtkmessagedialog.h>
+#include <bonobo/bonobo-i18n.h>
+#include <libgnome/gnome-util.h>
 
-/* Implementation file */
 NS_IMPL_ISUPPORTS1(GFilePicker, nsIFilePicker)
 
 GFilePicker::GFilePicker()
 {
 	NS_INIT_ISUPPORTS();
 
-	/* member initializers and constructor code */
-	mFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID);
-	mDisplayDirectory = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID);
-	mDisplayDirectory->InitWithNativePath(nsDependentCString(g_get_home_dir()));
+	LOG ("GFilePicker constructor")
+
+	mDialog = EPHY_FILE_CHOOSER (g_object_new (EPHY_TYPE_FILE_CHOOSER,
+						   "persist-key", CONF_STATE_UPLOAD_DIR,
+						   NULL));
+
+	mMode = nsIFilePicker::modeOpen;
 }
 
 GFilePicker::~GFilePicker()
 {
-	/* destructor code */
-}
+	LOG ("GFilePicker destructor")
 
-////////////////////////////////////////////////////////////////////////////////
-// begin nsIFilePicker impl
-////////////////////////////////////////////////////////////////////////////////
+	if (mDialog)
+	{
+		gtk_widget_destroy (GTK_WIDGET (mDialog));
+	}
+}
 
 /* void init (in nsIDOMWindowInternal parent, in wstring title, in short mode); */
-NS_IMETHODIMP GFilePicker::Init(nsIDOMWindowInternal *aParent, 
-				const PRUnichar *aTitle, PRInt16 aMode)
+NS_IMETHODIMP GFilePicker::Init(nsIDOMWindowInternal *parent, const PRUnichar *title, PRInt16 mode)
 {
-	mParent = do_QueryInterface(aParent);
-	mParentWidget = MozillaFindGtkParent(mParent);
-	mTitle = NS_ConvertUCS2toUTF8(aTitle);
-	mMode = aMode;
+	nsCOMPtr<nsIDOMWindow> dw = do_QueryInterface (parent);
+	if (!dw) return NS_ERROR_FAILURE;
+
+	GtkWidget *pwin = MozillaFindGtkParent (dw);
+
+	gtk_window_set_transient_for (GTK_WINDOW (mDialog), GTK_WINDOW (pwin));
+
+	gtk_window_set_title (GTK_WINDOW (mDialog), NS_ConvertUCS2toUTF8 (title).get());
+
+	mMode = mode;
+
+	switch (mode)
+	{
+		case nsIFilePicker::modeOpen:
+		case nsIFilePicker::modeGetFolder:
+		case nsIFilePicker::modeOpenMultiple:
+			gtk_file_chooser_set_action (GTK_FILE_CHOOSER (mDialog),
+						     GTK_FILE_CHOOSER_ACTION_OPEN);
+
+			gtk_dialog_add_buttons (GTK_DIALOG (mDialog),
+						GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+						GTK_STOCK_OPEN, EPHY_RESPONSE_OPEN,
+						NULL);
+			break;
+		case nsIFilePicker::modeSave:
+			gtk_file_chooser_set_action (GTK_FILE_CHOOSER (mDialog),
+						     GTK_FILE_CHOOSER_ACTION_SAVE);
 	
+			gtk_dialog_add_buttons (GTK_DIALOG (mDialog),
+						GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+						GTK_STOCK_SAVE, EPHY_RESPONSE_SAVE,
+						NULL);
+			break;
+	}
+
+	gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (mDialog),
+					      mode == nsIFilePicker::modeOpenMultiple);
+
+	gtk_file_chooser_set_folder_mode (GTK_FILE_CHOOSER (mDialog),
+					  mode == nsIFilePicker::modeGetFolder);
+
 	return NS_OK;
 }
 
 /* void appendFilters (in long filterMask); */
-NS_IMETHODIMP GFilePicker::AppendFilters(PRInt32 aFilterMask)
+NS_IMETHODIMP GFilePicker::AppendFilters(PRInt32 filterMask)
 {
-	//This function cannot be implemented due to the crippled
-	//nature of GtkFileSelection, but NS_ERROR_NOT_IMPLEMENTED
-	//is interpreted as a terminal error by some callers.
+	// http://lxr.mozilla.org/seamonkey/source/xpfe/components/filepicker/res/locale/en-US/filepicker.properties
+	// http://lxr.mozilla.org/seamonkey/source/xpfe/components/filepicker/src/nsFilePicker.js line 131 ff
+
+	// FIXME: use filters with mimetypes instead of extensions
+
+	if (filterMask & nsIFilePicker::filterAll)
+	{
+		AppendFilter (NS_ConvertUTF8toUCS2 (_("All files")).get(),
+			      NS_LITERAL_STRING ("*").get());
+	}
+	if (filterMask & nsIFilePicker::filterHTML)
+	{
+		AppendFilter (NS_ConvertUTF8toUCS2 (_("HTML files")).get(),
+			      NS_LITERAL_STRING ("*.html; *.htm; *.shtml; *.xhtml").get());
+	}
+	if (filterMask & nsIFilePicker::filterText)
+	{
+		AppendFilter (NS_ConvertUTF8toUCS2 (_("Text files")).get(),
+			      NS_LITERAL_STRING ("*.txt; *.text").get());
+	}
+	if (filterMask & nsIFilePicker::filterImages)
+	{
+		AppendFilter (NS_ConvertUTF8toUCS2 (_("Image files")).get(),
+			      NS_LITERAL_STRING ("*.png; *.gif; *.jpeg; *.jpg").get());
+	}
+	if (filterMask & nsIFilePicker::filterXML)
+	{
+		AppendFilter (NS_ConvertUTF8toUCS2 (_("XML files")).get(),
+			      NS_LITERAL_STRING ("*.xml").get());
+	}
+	if (filterMask & nsIFilePicker::filterXUL)
+	{
+		AppendFilter (NS_ConvertUTF8toUCS2 (_("XUL files")).get(),
+			      NS_LITERAL_STRING ("*.xul").get());
+	}
+
 	return NS_OK;
 }
 
 /* void appendFilter (in wstring title, in wstring filter); */
-NS_IMETHODIMP GFilePicker::AppendFilter(const PRUnichar *aTitle,
-					const PRUnichar *aFilter)
+NS_IMETHODIMP GFilePicker::AppendFilter(const PRUnichar *title, const PRUnichar *filter)
 {
-	//GtkFileSelection is crippled, so we can't provide a short-list
-	//of filters to choose from. We provide minimal functionality
-	//by using the most recent AppendFilter call as the active filter.
-	mFilter = NS_ConvertUCS2toUTF8(aFilter);
-	return NS_OK;
-}
+	GtkFileFilter *filth;
+
+	filth = gtk_file_filter_new ();
+
+	gtk_file_filter_set_name (filth, NS_ConvertUCS2toUTF8(title).get());
+	gtk_file_filter_add_pattern (filth, NS_ConvertUCS2toUTF8(filter).get());
+
+	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (mDialog), filth);
 
-/* attribute long filterIndex; */
-NS_IMETHODIMP GFilePicker::GetFilterIndex(PRInt32 *aFilterIndex)
-{
-	return NS_ERROR_NOT_IMPLEMENTED;
-}
-NS_IMETHODIMP GFilePicker::SetFilterIndex(PRInt32 aFilterIndex)
-{
 	return NS_OK;
 }
 
 /* attribute wstring defaultString; */
-NS_IMETHODIMP GFilePicker::GetDefaultString(PRUnichar * *aDefaultString)
+NS_IMETHODIMP GFilePicker::GetDefaultString(PRUnichar **aDefaultString)
 {
-	gsize bytesWritten;
-	gchar *utf8DefaultString = g_filename_to_utf8(mDefaultString.get(), -1,
-						      NULL,
-						      &bytesWritten, NULL);
+	char *filename, *converted;
 
-	*aDefaultString = ToNewUnicode(NS_ConvertUTF8toUCS2(utf8DefaultString));
-	g_free(utf8DefaultString);
+	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (mDialog));
+	if (filename != NULL)
+	{
+		converted = g_filename_to_utf8(filename, -1, NULL, NULL, NULL);
+	
+		*aDefaultString = ToNewUnicode (NS_ConvertUTF8toUCS2 (converted));
+	
+		g_free (filename);
+		g_free (converted);
+	}
 
 	return NS_OK;
 }
+
 NS_IMETHODIMP GFilePicker::SetDefaultString(const PRUnichar *aDefaultString)
 {
 	if (aDefaultString)
 	{
-		gsize bytesWritten;
-		gchar *localeDefaultString =
-			g_filename_from_utf8(NS_ConvertUCS2toUTF8(aDefaultString).get(),
-					     -1, NULL,
-					     &bytesWritten, NULL);
-		mDefaultString = localeDefaultString;					     
-		g_free(localeDefaultString);
+		/* set_current_name takes UTF-8, not a filename */
+		gtk_file_chooser_set_current_name
+			(GTK_FILE_CHOOSER (mDialog),
+			 NS_ConvertUCS2toUTF8 (aDefaultString).get());
 	}
-	else
-		mDefaultString = "";
+
 	return NS_OK;
 }
 
 /* attribute wstring defaultExtension; */
-// Again, due to the crippled file selector, we can't really
-// do anything here.
-NS_IMETHODIMP GFilePicker::GetDefaultExtension(PRUnichar * *aDefaultExtension)
-{
-    return NS_ERROR_NOT_IMPLEMENTED;
-}
-NS_IMETHODIMP GFilePicker::SetDefaultExtension(const PRUnichar *aDefaultExtension)
-{
-    return NS_OK;
-}
-
-/* attribute nsILocalFile displayDirectory; */
-NS_IMETHODIMP GFilePicker::GetDisplayDirectory(nsILocalFile * *aDisplayDirectory)
+NS_IMETHODIMP GFilePicker::GetDefaultExtension(PRUnichar **aDefaultExtension)
 {
-	NS_IF_ADDREF(*aDisplayDirectory = mDisplayDirectory);
-	return NS_OK;
-}
-NS_IMETHODIMP GFilePicker::SetDisplayDirectory(nsILocalFile * aDisplayDirectory)
-{
-	mDisplayDirectory = aDisplayDirectory;
-	return NS_OK;
+	return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-/* readonly attribute nsILocalFile file; */
-NS_IMETHODIMP GFilePicker::GetFile(nsILocalFile * *aFile)
+NS_IMETHODIMP GFilePicker::SetDefaultExtension(const PRUnichar *aDefaultExtension)
 {
-	NS_IF_ADDREF(*aFile = mFile);
-	return NS_OK;
+	return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-/* readonly attribute nsIFileURL fileURL; */
-NS_IMETHODIMP GFilePicker::GetFileURL(nsIFileURL * *aFileURL)
+/* attribute long filterIndex; */
+NS_IMETHODIMP GFilePicker::GetFilterIndex(PRInt32 *aFilterIndex)
 {
-	nsCOMPtr<nsIFileURL> fileURL = 
-		do_CreateInstance(NS_STANDARDURL_CONTRACTID);
-	fileURL->SetFile(mFile);
-	NS_IF_ADDREF(*aFileURL = fileURL);
-	return NS_OK;
+	return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-/* readonly attribute nsISimpleEnumerator files; */
-NS_IMETHODIMP GFilePicker::GetFiles(nsISimpleEnumerator * *aFiles)
+NS_IMETHODIMP GFilePicker::SetFilterIndex(PRInt32 aFilterIndex)
 {
-    return NS_ERROR_NOT_IMPLEMENTED;
+	return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-/* short show (); */
-NS_IMETHODIMP GFilePicker::Show(PRInt16 *_retval)
+/* attribute nsILocalFile displayDirectory; */
+NS_IMETHODIMP GFilePicker::GetDisplayDirectory(nsILocalFile **aDisplayDirectory)
 {
-	mFileSelector = gtk_file_selection_new(mTitle.get());
+	char *dir = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (mDialog));
 
-	nsCAutoString cFileName;
-	if(mMode == nsIFilePicker::modeGetFolder)
-		cFileName.Assign("");
-	else
-		cFileName = mDefaultString;
-
-	nsCAutoString cDirName;
-	mDisplayDirectory->GetNativePath(cDirName);
-
-	nsCAutoString cFullPath;
-	cFullPath.Assign(cDirName + NS_LITERAL_CSTRING("/") + cFileName);
-	gtk_file_selection_set_filename(GTK_FILE_SELECTION(mFileSelector),
-				 	cFullPath.get());
-
-	if (!mFilter.IsEmpty())
-	{
-		gtk_file_selection_complete(GTK_FILE_SELECTION(mFileSelector),
-					    mFilter.get());
-	}
-
-	if (mParentWidget)
-		gtk_window_set_transient_for(GTK_WINDOW(mFileSelector),
-					     GTK_WINDOW(mParentWidget));
-
-	if (mMode == nsIFilePicker::modeGetFolder)
+	if (dir != NULL)
 	{
-		gtk_widget_set_sensitive(GTK_FILE_SELECTION(mFileSelector)
-					 ->file_list, FALSE);
-	}
-
-	gtk_window_set_modal(GTK_WINDOW(mFileSelector), TRUE);
-
-	gint retVal = gtk_dialog_run(GTK_DIALOG(mFileSelector));
+		nsCOMPtr<nsILocalFile> file = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID);
+		file->InitWithNativePath (nsDependentCString (dir));
+		NS_IF_ADDREF (*aDisplayDirectory = file);
 	
-	HandleFilePickerResult();
-
-	if (retVal != GTK_RESPONSE_OK)
-	{
-		*_retval = returnCancel;
-	}
-	else
-	{	
-		ValidateFilePickerResult(_retval);
+		g_free (dir);
 	}
 
-	gtk_widget_destroy(mFileSelector);
-
 	return NS_OK;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// begin local public methods impl
-////////////////////////////////////////////////////////////////////////////////
-
-NS_METHOD GFilePicker::InitWithGtkWidget (GtkWidget *aParentWidget, 
-					  const char *aTitle, PRInt16 aMode)
+NS_IMETHODIMP GFilePicker::SetDisplayDirectory(nsILocalFile *aDisplayDirectory)
 {
-	mParentWidget = aParentWidget;
+	nsCAutoString dir;
+	aDisplayDirectory->GetNativePath (dir);
 
-	mTitle = nsDependentCString(aTitle);
-
-	mMode = aMode;
-
-	mFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID);
+	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (mDialog),
+					     dir.get());
 
 	return NS_OK;
 }
 
-NS_METHOD GFilePicker::SanityCheck (PRBool *retIsSane)
+/* readonly attribute nsILocalFile file; */
+NS_IMETHODIMP GFilePicker::GetFile(nsILocalFile **aFile)
 {
-	*retIsSane = PR_TRUE;
-	
-	nsresult rv;
-	PRBool dirExists, fileExists = PR_TRUE;
+	char *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (mDialog));
 
-	if (mDisplayDirectory)
+	if (filename != NULL)
 	{
-		rv = mDisplayDirectory->Exists (&dirExists);
-		g_return_val_if_fail (NS_SUCCEEDED(rv), rv);
-	}
-	else
-	{
-		dirExists = PR_FALSE;
-	}
-
-	if (mMode != nsIFilePicker::modeGetFolder)
-	{
-		rv = mFile->Exists (&fileExists);
-		g_return_val_if_fail (NS_SUCCEEDED(rv), rv);
-	}
-
-	if (mMode == nsIFilePicker::modeSave && !fileExists)
-	{
-		return NS_OK;
-	}
+		nsCOMPtr<nsILocalFile> file = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID);
+		file->InitWithNativePath (nsDependentCString (filename));
+		NS_IF_ADDREF (*aFile = file);
 	
-	if (!dirExists || !fileExists)
-	{
-		GtkWidget *errorDialog = gtk_message_dialog_new (
-				NULL,
-				GTK_DIALOG_MODAL,
-				GTK_MESSAGE_ERROR,
-				GTK_BUTTONS_OK,
-				_("The specified path does not exist."));
-
-		if (mParentWidget)
-			gtk_window_set_transient_for(GTK_WINDOW(errorDialog),
-						     GTK_WINDOW(mFileSelector));
-
-		gtk_window_set_modal (GTK_WINDOW(errorDialog), TRUE);
-		gtk_dialog_run (GTK_DIALOG(errorDialog));
-		gtk_widget_destroy (errorDialog);
-		*retIsSane = PR_FALSE;
-		return NS_OK;
+		g_free (filename);
 	}
 
-	PRBool correctType;
-	char *errorText;
-	if (mMode == nsIFilePicker::modeGetFolder)
-	{
-		rv = mDisplayDirectory->IsDirectory (&correctType);
-		g_return_val_if_fail (NS_SUCCEEDED(rv), rv);
-		errorText = g_strdup (_("A file was selected when a "
-					"folder was expected."));
-	}
-	else
-	{
-		rv = mFile->IsFile (&correctType);
-		g_return_val_if_fail (NS_SUCCEEDED(rv), rv);
-		errorText = g_strdup (_("A folder was selected when a "
-				        "file was expected."));
-	}
+	return NS_OK;
+}
+
+/* readonly attribute nsIFileURL fileURL; */
+NS_IMETHODIMP GFilePicker::GetFileURL(nsIFileURL **aFileURL)
+{
+	nsCOMPtr<nsILocalFile> file;
+	GetFile (getter_AddRefs(file));
 	
-	if(!correctType)
-	{
-		GtkWidget *errorDialog = gtk_message_dialog_new (
-				NULL,
-				GTK_DIALOG_MODAL,
-				GTK_MESSAGE_ERROR,
-				GTK_BUTTONS_OK,
-				errorText);
-
-		if (mParentWidget)
-			gtk_window_set_transient_for(GTK_WINDOW(errorDialog),
-						     GTK_WINDOW(mFileSelector));
-
-		gtk_window_set_modal (GTK_WINDOW(errorDialog), TRUE);
-		gtk_dialog_run (GTK_DIALOG(errorDialog));
-		gtk_widget_destroy (errorDialog);
-		*retIsSane = PR_FALSE;
-	}
-	g_free (errorText);
+	nsCOMPtr<nsIFileURL> fileURL = do_CreateInstance (NS_STANDARDURL_CONTRACTID);
+	fileURL->SetFile(file);
+	NS_IF_ADDREF(*aFileURL = fileURL);
 
 	return NS_OK;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// begin local private methods impl
-////////////////////////////////////////////////////////////////////////////////
+/* readonly attribute nsISimpleEnumerator files; */
+NS_IMETHODIMP GFilePicker::GetFiles(nsISimpleEnumerator * *aFiles)
+{
+	// Not sure if we need to implement it at all, it's used nowhere
+	// in mozilla, but I guess a javascript might call it?
+
+	return NS_ERROR_NOT_IMPLEMENTED;
+}
 
-NS_METHOD GFilePicker::HandleFilePickerResult()
+/* short show (); */
+NS_IMETHODIMP GFilePicker::Show(PRInt16 *_retval)
 {
-	const char *fileName = gtk_file_selection_get_filename(GTK_FILE_SELECTION(mFileSelector));
+	gtk_window_set_modal (GTK_WINDOW (mDialog), TRUE);
 
-	if (!fileName || strlen(fileName) == 0) return NS_ERROR_FAILURE;
+	gtk_widget_show (GTK_WIDGET (mDialog));
 
-	const nsACString &cFileName = nsDependentCString(fileName);
-	mFile->InitWithNativePath(cFileName);
+	int response = gtk_dialog_run (GTK_DIALOG (mDialog));
 
-	if (mMode == nsIFilePicker::modeGetFolder)
+	switch (response)
 	{
-		mDisplayDirectory->InitWithNativePath(cFileName);
-		mDefaultString = "";
-	}
-	else
-	{
-		nsCOMPtr<nsIFile> directory;
-		mFile->GetParent(getter_AddRefs(directory));
-		mDisplayDirectory = do_QueryInterface(directory);
-		mFile->GetNativeLeafName(mDefaultString);
+		case EPHY_RESPONSE_OPEN:
+		case EPHY_RESPONSE_SAVE:
+			*_retval = nsIFilePicker::returnOK;
+			break;
+		default:
+			*_retval = nsIFilePicker::returnCancel;
+			break;
 	}
 
-	return NS_OK;
-}
-
-NS_METHOD GFilePicker::ValidateFilePickerResult(PRInt16 *retval)
-{
-	nsresult rv;
-	const char *fileName = gtk_file_selection_get_filename(GTK_FILE_SELECTION(mFileSelector));
+	char *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (mDialog));
 
-	*retval = returnCancel;
-
-	PRBool passesSanityCheck;
-	rv = SanityCheck(&passesSanityCheck);
-	if (NS_SUCCEEDED(rv) && !passesSanityCheck) return NS_ERROR_FAILURE;
-
-	if (mMode == nsIFilePicker::modeSave)
+	if (filename == NULL)
+	{
+		*_retval = nsIFilePicker::returnCancel;
+	}
+	else if (mMode == nsIFilePicker::modeSave
+		 && ephy_gui_confirm_overwrite_file (GTK_WIDGET (mDialog), filename) == FALSE)
 	{
-		if (!ephy_gui_confirm_overwrite_file (mFileSelector,
-					              fileName))
-		{
-			return NS_OK;
-		}
+		*_retval = nsIFilePicker::returnCancel;
 	}
 
-	*retval = returnOK;
+	g_free (filename);
 
 	return NS_OK;
 }
diff --git a/embed/mozilla/FilePicker.h b/embed/mozilla/FilePicker.h
index 430e8d854..cf6a7f68f 100644
--- a/embed/mozilla/FilePicker.h
+++ b/embed/mozilla/FilePicker.h
@@ -1,5 +1,6 @@
 /*
  *  Copyright (C) 2001 Philip Langdale
+ *  Copyright (C) 2003 Christian Persch
  *
  *  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
@@ -14,20 +15,17 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  $Id$
  */
 
-#ifndef __FilePicker_h
-#define __FilePicker_h
+#ifndef EPHY_FILEPICKER_H
+#define EPHY_FILEPICKER_H
+
+#include <nsIFilePicker.h>
+#include <nsISupports.h>
 
-#include "nsIFilePicker.h"
-#include "nsError.h"
-#include "nsIDOMWindow.h"
-#include "nsIDOMWindowInternal.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-#include "nsILocalFile.h"
-#include <gtk/gtktogglebutton.h>
-#include "ephy-embed-shell.h"
+#include "ephy-file-chooser.h"
 
 #define G_FILEPICKER_CID			     \
 { /* 3636dc79-0b42-4bad-8a3f-ae15d3671d17 */         \
@@ -37,48 +35,25 @@
     {0x8a, 0x3f, 0xae, 0x15, 0xd3, 0x67, 0x1d, 0x17} \
 }
 
-#define G_FILEPICKER_CONTRACTID "@mozilla.org/filepicker;1"
-#define G_FILEPICKER_CLASSNAME "Epiphany's File Picker Implementation"
+#define G_FILEPICKER_CONTRACTID	"@mozilla.org/filepicker;1"
+#define G_FILEPICKER_CLASSNAME	"Epiphany File Picker Implementation"
 
 class nsIFactory;
 
 extern nsresult NS_NewFilePickerFactory(nsIFactory** aFactory);
 
-/* Header file */
 class GFilePicker : public nsIFilePicker
 {
-  public:
+public:
 	NS_DECL_ISUPPORTS
 	NS_DECL_NSIFILEPICKER
-	enum {  returnOK = nsIFilePicker::returnOK,
-		returnCancel = nsIFilePicker::returnCancel,
-		returnReplace = nsIFilePicker::returnReplace };
-
+	
 	GFilePicker();
 	virtual ~GFilePicker();
 
-	/* additional members */
-	NS_METHOD InitWithGtkWidget(GtkWidget *aParentWidget, 
-				    const char *aTitle, PRInt16 aMode);
-	NS_METHOD SanityCheck(PRBool *retIsSane);
-
-  private:
-	NS_METHOD HandleFilePickerResult();
-	NS_METHOD ValidateFilePickerResult(PRInt16 *retval);
-
-	nsCOMPtr<nsIDOMWindow> mParent;
-
-	nsCString mTitle;
-	nsCString mFilter;
-	nsCString mDefaultString;
-
-	nsCOMPtr<nsILocalFile> mFile;
-	nsCOMPtr<nsILocalFile> mDisplayDirectory;
-
+private:
+	EphyFileChooser *mDialog;
 	PRInt16 mMode;
-
-	GtkWidget *mParentWidget;	
-	GtkWidget *mFileSelector;
 };
 
 #endif
diff --git a/embed/mozilla/Makefile.am b/embed/mozilla/Makefile.am
index 9f80eb1c1..d73ef4794 100644
--- a/embed/mozilla/Makefile.am
+++ b/embed/mozilla/Makefile.am
@@ -35,6 +35,7 @@ INCLUDES = \
 	-I$(MOZILLA_INCLUDE_ROOT)/webshell		\
 	-I$(MOZILLA_INCLUDE_ROOT)/widget		\
 	-I$(MOZILLA_INCLUDE_ROOT)/windowwatcher		\
+	-I$(MOZILLA_INCLUDE_ROOT)/xpcom			\
 	$(GCONF_CFLAGS)					\
 	$(EPIPHANY_DEPENDENCY_CFLAGS) 			\
 	-DG_DISABLE_DEPRECATED          		\
diff --git a/embed/mozilla/MozDownload.cpp b/embed/mozilla/MozDownload.cpp
index e6ee3d0eb..63901ee35 100644
--- a/embed/mozilla/MozDownload.cpp
+++ b/embed/mozilla/MozDownload.cpp
@@ -36,7 +36,10 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
- * ***** END LICENSE BLOCK ***** */
+ * ***** END LICENSE BLOCK *****
+ *
+ * $Id$
+ */
 
 #include "MozDownload.h"
 #include "mozilla-download.h"
@@ -85,7 +88,7 @@ MozDownload::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisp
 	{
 		EmbedPersistFlags flags;
 
-		ephy_embed_persist_get_flags (EPHY_EMBED_PERSIST (mEmbedPersist), &flags);
+		flags = ephy_embed_persist_get_flags (EPHY_EMBED_PERSIST (mEmbedPersist));
 
 		addToView = !(flags & EMBED_PERSIST_NO_VIEW);
 	}
diff --git a/embed/mozilla/mozilla-embed-persist.cpp b/embed/mozilla/mozilla-embed-persist.cpp
index 8ba3596e8..53443246f 100644
--- a/embed/mozilla/mozilla-embed-persist.cpp
+++ b/embed/mozilla/mozilla-embed-persist.cpp
@@ -18,11 +18,15 @@
  *  $Id$
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "mozilla-embed-persist.h"
+#include "mozilla-embed.h"
 #include "EphyWrapper.h"
 #include "EphyHeaderSniffer.h"
 #include "MozDownload.h"
-#include "mozilla-embed.h"
-#include "mozilla-embed-persist.h"
 
 #include <stddef.h>
 #include <nsIWebBrowserPersist.h>
@@ -49,7 +53,6 @@ impl_cancel (EphyEmbedPersist *persist);
 struct MozillaEmbedPersistPrivate
 {
 	nsCOMPtr<nsIWebBrowserPersist> mPersist;
-//	GProgressListener *mProgress;
 };
 
 static GObjectClass *parent_class = NULL;
diff --git a/embed/mozilla/mozilla-embed-single.cpp b/embed/mozilla/mozilla-embed-single.cpp
index 8f1ce3939..5c1f83040 100644
--- a/embed/mozilla/mozilla-embed-single.cpp
+++ b/embed/mozilla/mozilla-embed-single.cpp
@@ -33,7 +33,6 @@
 #include "eel-gconf-extensions.h"
 #include "ephy-embed-prefs.h"
 #include "MozRegisterComponents.h"
-#include "FilePicker.h"
 
 #include <time.h>
 #include <libgnome/gnome-i18n.h>
@@ -55,6 +54,8 @@
 #include <nsICookie.h>
 #include <nsCCookieManager.h>
 #include <nsCPasswordManager.h>
+#include <nsString.h>
+#include <nsILocalFile.h>
 
 // FIXME: For setting the locale. hopefully gtkmozembed will do itself soon
 #include <nsIChromeRegistry.h>
@@ -98,16 +99,6 @@ static gresult
 impl_remove_passwords (EphyEmbedSingle *shell,
 		       GList *passwords,
 		       PasswordType type);
-static gresult 
-impl_show_file_picker (EphyEmbedSingle *shell,
-		       GtkWidget *parentWidget, 
-		       const char *title,
-		       const char *directory,
-		       const char *file, 
-		       FilePickerMode mode,
-                       char **ret_fullpath, 
-                       FileFormat *file_formats, 
-		       int *ret_file_format);
 
 static void mozilla_embed_single_new_window_orphan_cb (GtkMozEmbedSingle *embed,
             	           		              GtkMozEmbed **retval, 
@@ -172,7 +163,6 @@ mozilla_embed_single_class_init (MozillaEmbedSingleClass *klass)
 	shell_class->remove_cookies = impl_remove_cookies;
 	shell_class->list_passwords = impl_list_passwords;
 	shell_class->remove_passwords = impl_remove_passwords;
-	shell_class->show_file_picker = impl_show_file_picker;
 
 	g_type_class_add_private (object_class, sizeof(MozillaEmbedSinglePrivate));
 }
@@ -779,61 +769,3 @@ impl_remove_passwords (EphyEmbedSingle *shell,
 	
         return G_OK;
 }
-
-static gresult 
-impl_show_file_picker (EphyEmbedSingle *shell,
-		       GtkWidget *parentWidget, 
-		       const char *title,
-		       const char *directory,
-		       const char *file, 
-		       FilePickerMode mode,
-                       char **ret_fullpath, 
-                       FileFormat *file_formats, 
-		       int *ret_file_format)
-{
-	char *expanded_directory = NULL;
-	gresult result;
-
-        GFilePicker *filePicker = new GFilePicker ();
-
-	if (directory != NULL)
-	{
-	        expanded_directory = gnome_vfs_expand_initial_tilde (directory);
-	}
-
-        /* make sure the directory exists, and use the home directory
-         * otherwise */
-        if (!expanded_directory ||
-            !g_file_test (expanded_directory, G_FILE_TEST_IS_DIR))
-        {
-                g_free (expanded_directory);
-                expanded_directory = g_strdup (g_get_home_dir());
-        }
-
-        nsCOMPtr<nsILocalFile> dir = 
-                                do_CreateInstance (NS_LOCAL_FILE_CONTRACTID);
-        dir->InitWithNativePath (nsDependentCString(expanded_directory));
-        g_free (expanded_directory);
-
-        filePicker->InitWithGtkWidget (parentWidget, title, mode);
-	if (file)
-	{
-	        filePicker->SetDefaultString (NS_ConvertUTF8toUCS2(file).get());
-	}
-        filePicker->SetDisplayDirectory (dir);
-        
-        PRInt16 retval;
-        filePicker->Show (&retval);
-
-        nsCOMPtr<nsILocalFile> local_file;
-	filePicker->GetFile (getter_AddRefs(local_file));
-	nsCAutoString tempFullPathStr;
-	local_file->GetNativePath (tempFullPathStr);
-	*ret_fullpath = g_strdup (tempFullPathStr.get());
-
-        result = (retval == nsIFilePicker::returnCancel) ? G_FAILED : G_OK;
-
-	delete filePicker;
-
-	return result;
-}
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 7caefb55d..955be57ae 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -19,6 +19,7 @@ NOINST_H_FILES = \
 	ephy-bonobo-extensions.h		\
 	ephy-debug.h				\
 	ephy-dnd.h				\
+	ephy-file-chooser.h			\
 	ephy-file-helpers.h			\
 	ephy-glade.h				\
 	ephy-gui.h				\
@@ -50,6 +51,7 @@ libephy_la_SOURCES = \
 	ephy-dialog.h				\
 	ephy-dnd.c				\
 	ephy-dnd.h				\
+	ephy-file-chooser.c			\
 	ephy-file-helpers.c			\
 	ephy-file-helpers.h			\
 	ephy-glade.c				\
diff --git a/lib/ephy-file-chooser.c b/lib/ephy-file-chooser.c
new file mode 100644
index 000000000..1f2f853d2
--- /dev/null
+++ b/lib/ephy-file-chooser.c
@@ -0,0 +1,238 @@
+/*
+ *  Copyright (C) 2003 Marco Pesenti Gritti
+ *  Copyright (C) 2003 Christian Persch
+ *
+ *  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, 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ephy-file-chooser.h"
+#include "eel-gconf-extensions.h"
+#include "ephy-state.h"
+#include "ephy-debug.h"
+
+#include <gtk/gtkstock.h>
+#include <libgnomevfs/gnome-vfs-utils.h>
+
+#define EPHY_FILE_CHOOSER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_FILE_CHOOSER, EphyFileChooserPrivate))
+
+struct EphyFileChooserPrivate
+{
+	char *persist_key;
+};
+
+static void ephy_file_chooser_class_init	(EphyFileChooserClass *klass);
+static void ephy_file_chooser_init		(EphyFileChooser *dialog);
+
+enum
+{
+	PROP_0,
+	PROP_PERSIST_KEY
+};
+
+static GObjectClass *parent_class = NULL;
+
+GType
+ephy_file_chooser_get_type (void)
+{
+	static GType ephy_file_chooser_type = 0;
+
+	if (ephy_file_chooser_type == 0)
+	{
+		static const GTypeInfo our_info =
+		{
+			sizeof (EphyFileChooserClass),
+			NULL,
+			NULL,
+			(GClassInitFunc) ephy_file_chooser_class_init,
+			NULL,
+			NULL,
+			sizeof (EphyFileChooser),
+			0,
+			(GInstanceInitFunc) ephy_file_chooser_init
+		};
+
+		ephy_file_chooser_type = g_type_register_static (GTK_TYPE_FILE_CHOOSER_DIALOG,
+								 "EphyFileChooser",
+								 &our_info, 0);
+	}
+
+	return ephy_file_chooser_type;
+}
+
+static void
+current_folder_changed_cb (GtkFileChooser *chooser, EphyFileChooser *dialog)
+{
+	if (dialog->priv->persist_key)
+	{
+		char *dir;
+
+		dir = gtk_file_chooser_get_current_folder (chooser);
+		if (dir != NULL)
+		{
+			eel_gconf_set_string (dialog->priv->persist_key, dir);
+			g_free (dir);
+		}
+	}
+}
+
+static void
+ephy_file_chooser_init (EphyFileChooser *dialog)
+{
+	dialog->priv = EPHY_FILE_CHOOSER_GET_PRIVATE (dialog);
+
+	dialog->priv->persist_key = NULL;
+
+	g_signal_connect (dialog, "current-folder-changed",
+			  G_CALLBACK (current_folder_changed_cb), dialog);
+
+	ephy_state_add_window (GTK_WIDGET (dialog), "file_chooser",
+			       400, 300,
+			       EPHY_STATE_WINDOW_SAVE_SIZE |
+			       EPHY_STATE_WINDOW_SAVE_POSITION);
+}
+
+static void
+ephy_file_chooser_finalize (GObject *object)
+{
+	EphyFileChooser *dialog = EPHY_FILE_CHOOSER (object);
+
+	g_free (dialog->priv->persist_key);
+
+	LOG ("EphyFileChooser finalised")
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+ephy_file_chooser_set_persist_key (EphyFileChooser *dialog, const char *key)
+{
+	dialog->priv->persist_key = g_strdup (key);
+
+	if (key != NULL)
+	{
+		char *uri;
+
+		uri = eel_gconf_get_string (key);
+
+		if (uri != NULL)
+		{
+			char *expanded;
+
+			expanded = gnome_vfs_expand_initial_tilde (uri);
+
+			gtk_file_chooser_set_current_folder
+				(GTK_FILE_CHOOSER (dialog), expanded);
+
+			g_free (expanded);
+			g_free (uri);
+		}
+	}
+}
+
+static void
+ephy_file_chooser_set_property (GObject *object,
+				guint prop_id,
+				const GValue *value,
+				GParamSpec *pspec)
+{
+	EphyFileChooser *dialog = EPHY_FILE_CHOOSER (object);
+	
+	switch (prop_id)
+	{
+		case PROP_PERSIST_KEY:
+			ephy_file_chooser_set_persist_key (dialog, g_value_get_string (value));
+			break;
+	}
+}
+
+static void
+ephy_file_chooser_get_property (GObject *object,
+				guint prop_id,
+				GValue *value,
+				GParamSpec *pspec)
+{
+	EphyFileChooser *dialog = EPHY_FILE_CHOOSER (object);
+
+	switch (prop_id)
+	{
+		case PROP_PERSIST_KEY:
+			g_value_set_string (value, dialog->priv->persist_key);
+			break;
+	}
+}
+
+static void
+ephy_file_chooser_class_init (EphyFileChooserClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	object_class->finalize = ephy_file_chooser_finalize;
+	object_class->get_property = ephy_file_chooser_get_property;
+	object_class->set_property = ephy_file_chooser_set_property;
+
+	g_object_class_install_property (object_class,
+					 PROP_PERSIST_KEY,
+					 g_param_spec_string ("persist-key",
+							      "Persist Key",
+							      "The gconf key to which to persist the selected directory",
+							      NULL,
+							      G_PARAM_READWRITE |
+							      G_PARAM_CONSTRUCT_ONLY));
+
+	g_type_class_add_private (object_class, sizeof (EphyFileChooserPrivate));
+}
+
+EphyFileChooser	*
+ephy_file_chooser_new (const char *title,
+		       GtkWidget *parent,
+		       GtkFileChooserAction action,
+		       const char *persist_key)
+{
+	EphyFileChooser *dialog;
+
+	dialog = EPHY_FILE_CHOOSER (g_object_new (EPHY_TYPE_FILE_CHOOSER,
+				    "local-only", TRUE,
+				    "title", title,
+				    "action", action,
+				    "persist-key", persist_key,
+				    NULL));
+
+	if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
+	{
+		gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+					GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+					GTK_STOCK_OPEN, EPHY_RESPONSE_OPEN,
+					NULL);
+	}
+	else if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
+	{
+		gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+					GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+					GTK_STOCK_SAVE, EPHY_RESPONSE_SAVE,
+					NULL);
+	}
+
+	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
+
+	return dialog;
+}
diff --git a/lib/ephy-file-chooser.h b/lib/ephy-file-chooser.h
new file mode 100644
index 000000000..f4061e9fc
--- /dev/null
+++ b/lib/ephy-file-chooser.h
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (C) 2003 Christian Persch
+ *  
+ *  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, 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  $Id$
+ */
+
+#ifndef EPHY_FILE_CHOOSER_H
+#define EPHY_FILE_CHOOSER_H
+
+#include <glib-object.h>
+
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkfilechooserdialog.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_FILE_CHOOSER		(ephy_file_chooser_get_type ())
+#define EPHY_FILE_CHOOSER(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_FILE_CHOOSER, EphyFileChooser))
+#define EPHY_FILE_CHOOSER_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST ((k), EPHY_TYPE_FILE_CHOOSER, EphyFileChooserClass))
+#define EPHY_IS_FILE_CHOOSER(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_FILE_CHOOSER))
+#define EPHY_IS_FILE_CHOOSER_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_FILE_CHOOSER))
+#define EPHY_FILE_CHOOSER_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_FILE_CHOOSER, EphyFileChooserClass))
+
+typedef struct EphyFileChooserPrivate EphyFileChooserPrivate;
+
+enum
+{
+	EPHY_RESPONSE_OPEN = 2,
+	EPHY_RESPONSE_SAVE = 3
+};
+
+typedef struct
+{
+	GtkFileChooserDialog parent;
+	EphyFileChooserPrivate *priv;
+} EphyFileChooser;
+
+typedef struct
+{
+	GtkFileChooserDialogClass parent_class;
+} EphyFileChooserClass;
+
+GType		 ephy_file_chooser_get_type	(void);
+
+EphyFileChooser	*ephy_file_chooser_new		(const char *title,
+						 GtkWidget *parent,
+						 GtkFileChooserAction action,
+						 const char *persist_key);
+
+G_END_DECLS
+
+#endif
diff --git a/lib/ephy-prefs.h b/lib/ephy-prefs.h
index 0ecb6360f..844d6f7bf 100644
--- a/lib/ephy-prefs.h
+++ b/lib/ephy-prefs.h
@@ -35,6 +35,7 @@ G_BEGIN_DECLS
 #define CONF_STATE_SAVE_IMAGE_DIR     "/apps/epiphany/directories/saveimage"
 #define CONF_STATE_OPEN_DIR           "/apps/epiphany/directories/open"
 #define CONF_STATE_DOWNLOADING_DIR    "/apps/epiphany/directories/download"
+#define CONF_STATE_UPLOAD_DIR	      "/apps/epiphany/directories/upload"
 
 /* System prefs */
 #define CONF_DESKTOP_FTP_HANDLER "/desktop/gnome/url-handlers/ftp/command"
diff --git a/src/bookmarks/ephy-bookmarks-editor.c b/src/bookmarks/ephy-bookmarks-editor.c
index e902f3bdf..0236b825b 100644
--- a/src/bookmarks/ephy-bookmarks-editor.c
+++ b/src/bookmarks/ephy-bookmarks-editor.c
@@ -49,6 +49,7 @@
 #include "ephy-prefs.h"
 #include "ephy-shell.h"
 #include "ephy-file-helpers.h"
+#include "ephy-file-chooser.h"
 #include "popup-commands.h"
 #include "ephy-state.h"
 #include "window-commands.h"
@@ -493,6 +494,27 @@ add_bookmarks_source (GtkListStore *store,
 	g_slist_free (l);
 }
 
+static void
+import_from_file_response_cb (GtkDialog *dialog, gint response,
+			      EphyBookmarksEditor *editor)
+{
+	char *filename;
+
+	if (response == EPHY_RESPONSE_OPEN)
+	{
+		filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+
+		if (filename != NULL)
+		{
+			ephy_bookmarks_import (editor->priv->bookmarks, filename);			
+
+			g_free (filename);
+		}
+	}
+
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
 static void
 import_dialog_response_cb (GtkDialog *dialog, gint response,
 			   EphyBookmarksEditor *editor)
@@ -516,15 +538,22 @@ import_dialog_response_cb (GtkDialog *dialog, gint response,
 
 		if (filename == NULL)
 		{
-			const char *title;
-			EphyEmbedSingle *single;
-
-			title = _("Import bookmarks from file");
-			single = ephy_embed_shell_get_embed_single
-				(EPHY_EMBED_SHELL (ephy_shell));
-			ephy_embed_single_show_file_picker
-				(single, GTK_WIDGET (editor), title, NULL,
-				 NULL, modeOpen, &filename, NULL, NULL);
+			EphyFileChooser *dialog;
+
+			dialog = ephy_file_chooser_new (_("Import bookmarks from file"),
+							GTK_WIDGET (editor),
+							GTK_FILE_CHOOSER_ACTION_OPEN,
+							NULL);
+			/* FIXME: set up some filters perhaps ? */
+			g_signal_connect (dialog, "response",
+					  G_CALLBACK (import_from_file_response_cb), editor);
+
+			gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+						GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+						GTK_STOCK_OPEN, GTK_RESPONSE_OK,
+						NULL);
+
+			gtk_widget_show (GTK_WIDGET (dialog));
 		}
 		else
 		{
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 3cf31c15e..4ec9a3a92 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -969,7 +969,6 @@ show_embed_popup (EphyWindow *window, EphyTab *tab, EphyEmbedEvent *event)
 	GtkAction *action;
 	EmbedEventContext context;
 	const char *popup;
-	char *path;
 	const GValue *value;
 	gboolean framed, has_background;
 	GtkWidget *widget;
@@ -991,24 +990,24 @@ show_embed_popup (EphyWindow *window, EphyTab *tab, EphyEmbedEvent *event)
 	if ((context & EMBED_CONTEXT_LINK) &&
 	    (context & EMBED_CONTEXT_IMAGE))
 	{
-		popup = "EphyImageLinkPopup";
+		popup = "/EphyImageLinkPopup";
 	}
 	else if (context & EMBED_CONTEXT_LINK)
 	{
-		popup = "EphyLinkPopup";
+		popup = "/EphyLinkPopup";
 	}
 	else if (context & EMBED_CONTEXT_IMAGE)
 	{
-		popup = "EphyImagePopup";
+		popup = "/EphyImagePopup";
 	}
-/*	else if (context & EMBED_CONTEXT_INPUT)
+	/* else if (context & EMBED_CONTEXT_INPUT)
 	{
-		popup = "EphyInputPopup";
-	}*/
+		popup = "/EphyInputPopup";
+	} */
 	else
 	{
-		popup = framed ? "EphyFramedDocumentPopup" :
-				 "EphyDocumentPopup";
+		popup = framed ? "/EphyFramedDocumentPopup" :
+				 "/EphyDocumentPopup";
 	}
 
 	action_group = window->priv->popups_action_group;
@@ -1016,10 +1015,8 @@ show_embed_popup (EphyWindow *window, EphyTab *tab, EphyEmbedEvent *event)
 	g_object_set (action, "sensitive", has_background,
 			      "visible", has_background, NULL);
 
-	path = g_strconcat ("/", popup, NULL);
 	widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER (window->ui_merge),
-				            path);
-	g_free (path);
+				            popup);
 
 	g_return_if_fail (widget != NULL);
 
diff --git a/src/popup-commands.c b/src/popup-commands.c
index e1d2a046e..02bfbea2a 100644
--- a/src/popup-commands.c
+++ b/src/popup-commands.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
+ *  Copyright (C) 2000-2003 Marco Pesenti Gritti
  *
  *  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
@@ -14,14 +14,19 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  $Id$
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "popup-commands.h"
 #include "ephy-shell.h"
 #include "ephy-new-bookmark.h"
 #include "ephy-embed-persist.h"
 #include "ephy-prefs.h"
-#include "ephy-embed-utils.h"
 #include "eel-gconf-extensions.h"
 #include "ephy-file-helpers.h"
 
@@ -267,7 +272,6 @@ save_property_url (GtkAction *action,
 	EphyEmbedEvent *info;
 	const char *location;
 	const GValue *value;
-	GtkWidget *widget;
 	EphyEmbedPersist *persist;
 	EphyEmbed *embed;
 
@@ -278,15 +282,17 @@ save_property_url (GtkAction *action,
 	ephy_embed_event_get_property (info, property, &value);
 	location = g_value_get_string (value);
 
-	widget = GTK_WIDGET (embed);
-
 	persist = ephy_embed_persist_new (embed);
 
+	ephy_embed_persist_set_fc_title (persist, title);
+	ephy_embed_persist_set_fc_parent (persist,GTK_WINDOW (window));
+	ephy_embed_persist_set_flags
+		(persist, ask_dest ? EMBED_PERSIST_ASK_DESTINATION : 0);
+	ephy_embed_persist_set_persist_key
+		(persist, CONF_STATE_DOWNLOADING_DIR);
 	ephy_embed_persist_set_source (persist, location);
 
-	ephy_embed_utils_save (GTK_WIDGET (window), title,
-			       CONF_STATE_DOWNLOADING_DIR,
-			       ask_dest, persist);
+	ephy_embed_persist_save (persist);
 
 	g_object_unref (G_OBJECT(persist));
 }
@@ -338,16 +344,14 @@ background_download_completed (EphyEmbedPersist *persist,
 	const char *bg;
 	char *type;
 
-	ephy_embed_persist_get_dest (persist, &bg);
+	bg = ephy_embed_persist_get_dest (persist);
 	eel_gconf_set_string (CONF_DESKTOP_BG_PICTURE, bg);
 
 	type = eel_gconf_get_string (CONF_DESKTOP_BG_TYPE);
-	if (type || strcmp (type, "none") == 0)
+	if (type == NULL || strcmp (type, "none") == 0)
 	{
-		eel_gconf_set_string (CONF_DESKTOP_BG_TYPE,
-				      "wallpaper");
+		eel_gconf_set_string (CONF_DESKTOP_BG_TYPE, "wallpaper");
 	}
-
 	g_free (type);
 
 	g_object_unref (persist);
@@ -374,18 +378,18 @@ popup_cmd_set_image_as_background (GtkAction *action,
 	persist = ephy_embed_persist_new (embed);
 
 	base = g_path_get_basename (location);
-	dest = g_build_filename (ephy_dot_dir (),
-				 base, NULL);
+	dest = g_build_filename (ephy_dot_dir (), base, NULL);
 
-	ephy_embed_persist_set_source (persist, location);
 	ephy_embed_persist_set_dest (persist, dest);
-
-	ephy_embed_persist_save (persist);
+	ephy_embed_persist_set_flags (persist, EMBED_PERSIST_NO_VIEW);
+	ephy_embed_persist_set_source (persist, location);
 
 	g_signal_connect (persist, "completed",
 			  G_CALLBACK (background_download_completed),
 			  NULL);
 
+	ephy_embed_persist_save (persist);
+
 	g_free (dest);
 	g_free (base);
 }
diff --git a/src/window-commands.c b/src/window-commands.c
index a4793df79..364d326e6 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -18,19 +18,22 @@
  *  $Id$
  */
 
-#include <config.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
 #include "ephy-shell.h"
+#include "ephy-embed-persist.h"
 #include "ephy-debug.h"
 #include "ephy-command-manager.h"
 #include "window-commands.h"
 #include "print-dialog.h"
 #include "eel-gconf-extensions.h"
 #include "ephy-prefs.h"
-#include "ephy-embed-utils.h"
 #include "pdm-dialog.h"
 #include "ephy-bookmarks-editor.h"
 #include "ephy-new-bookmark.h"
+#include "ephy-file-chooser.h"
 #include "ephy-file-helpers.h"
 #include "toolbar.h"
 #include "ephy-state.h"
@@ -41,6 +44,7 @@
 #include "egg-editable-toolbar.h"
 #include "egg-toolbar-editor.h"
 
+#include <glib.h>
 #include <string.h>
 #include <libgnomevfs/gnome-vfs-uri.h>
 #include <libgnomevfs/gnome-vfs-utils.h>
@@ -318,53 +322,43 @@ window_cmd_file_bookmark_page (GtkAction *action,
 	g_free (location);
 }
 
-void
-window_cmd_file_open (GtkAction *action,
-		      EphyWindow *window)
+static void
+open_response_cb (GtkDialog *dialog, gint response, EphyWindow *window)
 {
-	char *dir, *ret_dir, *file;
-	EphyEmbedShell *embed_shell;
-	gresult result;
-	EphyEmbedSingle *single;
+	if (response == EPHY_RESPONSE_OPEN)
+	{
+		char *uri, *converted;
 
-	single = ephy_embed_shell_get_embed_single
-		(EPHY_EMBED_SHELL (ephy_shell));
+		uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+		converted = g_filename_to_utf8 (uri, -1, NULL, NULL, NULL);
 
-	embed_shell = EPHY_EMBED_SHELL (ephy_shell);
+		if (converted != NULL)
+		{
+			ephy_window_load_url(window, uri);
+		}
 
-        dir = eel_gconf_get_string (CONF_STATE_OPEN_DIR);
+		g_free (converted);
+		g_free (uri);
+        }
 
-	result = ephy_embed_single_show_file_picker
-		(single, GTK_WIDGET (window),
-		 _("Open"),
-                 dir, NULL, modeOpen,
-                 &file, NULL, NULL);
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+}
 
-	/* persist directory choice */
-	/* Fix for bug 122780:
-	 * if the user selected a directory, or aborted with no filename typed,
-	 * g_path_get_dirname and gnome_vfs_uri_extract_dirname strip the last
-	 * path component, so test if the returned file is actually a directory.
-	 */
-	if (g_file_test (file, G_FILE_TEST_IS_DIR))
-	{
-		ret_dir = g_strdup (file);
-	}
-	else
-	{
-		ret_dir = g_path_get_dirname (file);
-	}
+void
+window_cmd_file_open (GtkAction *action,
+		      EphyWindow *window)
+{
+	EphyFileChooser *dialog;
 
-	eel_gconf_set_string (CONF_STATE_OPEN_DIR, ret_dir);
+	dialog = ephy_file_chooser_new (_("Open"),
+					GTK_WIDGET (window),
+					GTK_FILE_CHOOSER_ACTION_OPEN,
+					CONF_STATE_OPEN_DIR);
 
-	if (result == G_OK)
-	{
-		ephy_window_load_url(window, file);
-        }
+	g_signal_connect (dialog, "response",
+			  G_CALLBACK (open_response_cb), window);
 
-	g_free (ret_dir);
-	g_free (file);
-        g_free (dir);
+	gtk_widget_show (GTK_WIDGET (dialog));
 }
 
 void
@@ -378,13 +372,15 @@ window_cmd_file_save_as (GtkAction *action,
 	g_return_if_fail (embed != NULL);
 
 	persist = ephy_embed_persist_new (embed);
-	ephy_embed_persist_set_flags (persist,
-				      EMBED_PERSIST_MAINDOC);
 
-	ephy_embed_utils_save (GTK_WIDGET(window),
-			       _("Save As"),
-			       CONF_STATE_SAVE_DIR,
-			       TRUE, persist);
+	ephy_embed_persist_set_fc_title (persist, _("Save As"));
+	ephy_embed_persist_set_fc_parent (persist,GTK_WINDOW (window));
+	ephy_embed_persist_set_flags
+		(persist, EMBED_PERSIST_MAINDOC | EMBED_PERSIST_ASK_DESTINATION);
+	ephy_embed_persist_set_persist_key
+		(persist, CONF_STATE_SAVE_DIR);
+
+	ephy_embed_persist_save (persist);
 
 	g_object_unref (G_OBJECT(persist));
 }
diff --git a/src/window-commands.h b/src/window-commands.h
index 2fbbd540b..2f0f8bc14 100644
--- a/src/window-commands.h
+++ b/src/window-commands.h
@@ -19,7 +19,6 @@
 #include <gtk/gtkaction.h>
 
 #include "ephy-window.h"
-#include "ephy-embed-utils.h"
 
 void window_cmd_edit_find	(GtkAction *action,
 				 EphyWindow *window);
-- 
cgit