diff --git a/src/Makefile.am b/src/Makefile.am
index f17050f..ef6cc95 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -37,6 +37,7 @@ NOINST_H_FILES =			\
 	eog-plugin-manager.h            \
 	eog-plugin-engine.h             \
 	uta.h				\
+	eog-close-confirmation-dialog.h	\
 	zoom.h
 
 if ENABLE_PYTHON
@@ -104,6 +105,7 @@ libeog_la_SOURCES =			\
 	eog-print-preview.c           	\
 	eog-print.c			\
 	eog-module.c            	\
+	eog-close-confirmation-dialog.c \
 	eog-plugin.c            	\
 	eog-plugin-manager.c            \
 	eog-plugin-engine.c            	\
diff --git a/src/eog-close-confirmation-dialog.c b/src/eog-close-confirmation-dialog.c
new file mode 100644
index 0000000..daff42b
--- /dev/null
+++ b/src/eog-close-confirmation-dialog.c
@@ -0,0 +1,648 @@
+/*
+ * eog-close-confirmation-dialog.c
+ * This file is part of eog
+ *
+ * Author: Marcus Carlson <marcus@mejlamej.nu>
+ *
+ * Based on gedit code (gedit/gedit-close-confirmation.c) by gedit Team
+ *
+ * Copyright (C) 2004-2005 GNOME Foundation 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA. 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+
+#include "eog-close-confirmation-dialog.h"
+#include <eog-window.h>
+
+/* Properties */
+enum 
+{
+	PROP_0,	
+	PROP_UNSAVED_IMAGES
+};
+
+/* Mode */
+enum
+{
+	SINGLE_IMG_MODE,
+	MULTIPLE_IMGS_MODE
+};
+
+/* Columns */
+enum
+{
+	SAVE_COLUMN,
+	IMAGE_COLUMN,
+	NAME_COLUMN,
+	IMG_COLUMN, /* a handy pointer to the image */
+	N_COLUMNS
+};
+
+struct _EogCloseConfirmationDialogPrivate 
+{
+	GList       *unsaved_images;
+	
+	GList       *selected_images;
+
+	GtkTreeModel *list_store;
+};
+
+#define EOG_CLOSE_CONFIRMATION_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+							EOG_TYPE_CLOSE_CONFIRMATION_DIALOG, \
+							EogCloseConfirmationDialogPrivate))
+
+#define GET_MODE(priv) (((priv->unsaved_images != NULL) && \
+			 (priv->unsaved_images->next == NULL)) ? \
+			  SINGLE_IMG_MODE : MULTIPLE_IMGS_MODE)
+
+#define IMAGE_COLUMN_HEIGHT 40
+
+G_DEFINE_TYPE(EogCloseConfirmationDialog, eog_close_confirmation_dialog, GTK_TYPE_DIALOG)
+
+static void 	 set_unsaved_image 		(EogCloseConfirmationDialog *dlg,
+						 const GList                  *list);
+
+static GList 	*get_selected_imgs 		(GtkTreeModel                 *store);
+
+/*  Since we connect in the costructor we are sure this handler will be called 
+ *  before the user ones
+ */
+static void
+response_cb (EogCloseConfirmationDialog *dlg,
+             gint                        response_id,
+             gpointer                    data)
+{
+	EogCloseConfirmationDialogPrivate *priv;
+
+	g_return_if_fail (EOG_IS_CLOSE_CONFIRMATION_DIALOG (dlg));
+
+	priv = dlg->priv;
+	
+	if (priv->selected_images != NULL)
+		g_list_free (priv->selected_images);
+
+	if (response_id == GTK_RESPONSE_YES)
+	{
+		if (GET_MODE (priv) == SINGLE_IMG_MODE)
+		{
+			priv->selected_images = 
+				g_list_copy (priv->unsaved_images);
+		}
+		else
+		{
+			g_return_if_fail (priv->list_store);
+
+			priv->selected_images =
+				get_selected_imgs (priv->list_store);
+		}
+	}
+	else
+		priv->selected_images = NULL;
+}
+
+static void
+add_buttons (EogCloseConfirmationDialog *dlg)
+{
+	gtk_dialog_add_button (GTK_DIALOG (dlg),
+			       _("Close _without Saving"),
+			       GTK_RESPONSE_NO);
+
+	gtk_dialog_add_button (GTK_DIALOG (dlg),
+			       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+	
+	gtk_dialog_add_button (GTK_DIALOG (dlg),
+			       GTK_STOCK_SAVE,
+			       GTK_RESPONSE_YES);
+
+	gtk_dialog_set_default_response	(GTK_DIALOG (dlg), 
+					 GTK_RESPONSE_YES);
+}
+
+static void 
+eog_close_confirmation_dialog_init (EogCloseConfirmationDialog *dlg)
+{
+	AtkObject *atk_obj;
+
+	dlg->priv = EOG_CLOSE_CONFIRMATION_DIALOG_GET_PRIVATE (dlg);
+
+	gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);		
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->vbox), 14);
+	gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE);
+	gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
+	gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dlg), TRUE);
+	
+	gtk_window_set_title (GTK_WINDOW (dlg), "");
+
+	gtk_window_set_modal (GTK_WINDOW (dlg), TRUE);
+	gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE);
+
+	atk_obj = gtk_widget_get_accessible (GTK_WIDGET (dlg));
+	atk_object_set_role (atk_obj, ATK_ROLE_ALERT);
+	atk_object_set_name (atk_obj, _("Question"));
+	
+	g_signal_connect (dlg,
+			  "response",
+			  G_CALLBACK (response_cb),
+			  NULL);
+}
+
+static void 
+eog_close_confirmation_dialog_finalize (GObject *object)
+{
+	EogCloseConfirmationDialogPrivate *priv;
+
+	priv = EOG_CLOSE_CONFIRMATION_DIALOG (object)->priv;
+
+	if (priv->unsaved_images != NULL)
+		g_list_free (priv->unsaved_images);
+
+	if (priv->selected_images != NULL)
+		g_list_free (priv->selected_images);
+
+	/* Call the parent's destructor */
+	G_OBJECT_CLASS (eog_close_confirmation_dialog_parent_class)->finalize (object);
+}
+
+static void
+eog_close_confirmation_dialog_set_property (GObject      *object, 
+					      guint         prop_id, 
+					      const GValue *value, 
+					      GParamSpec   *pspec)
+{
+	EogCloseConfirmationDialog *dlg;
+
+	dlg = EOG_CLOSE_CONFIRMATION_DIALOG (object);
+
+	switch (prop_id)
+	{
+		case PROP_UNSAVED_IMAGES:
+			set_unsaved_image (dlg, g_value_get_pointer (value));
+			break;
+			
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
+eog_close_confirmation_dialog_get_property (GObject    *object, 
+					      guint       prop_id, 
+					      GValue     *value, 
+					      GParamSpec *pspec)
+{
+	EogCloseConfirmationDialogPrivate *priv;
+
+	priv = EOG_CLOSE_CONFIRMATION_DIALOG (object)->priv;
+
+	switch( prop_id )
+	{
+		case PROP_UNSAVED_IMAGES:
+			g_value_set_pointer (value, priv->unsaved_images);
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+static void 
+eog_close_confirmation_dialog_class_init (EogCloseConfirmationDialogClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+	gobject_class->set_property = eog_close_confirmation_dialog_set_property;
+	gobject_class->get_property = eog_close_confirmation_dialog_get_property;
+	gobject_class->finalize = eog_close_confirmation_dialog_finalize;
+
+	g_type_class_add_private (klass, sizeof (EogCloseConfirmationDialogPrivate));
+
+	g_object_class_install_property (gobject_class,
+					 PROP_UNSAVED_IMAGES,
+					 g_param_spec_pointer ("unsaved_images",
+						 	       "Unsaved Images",
+							       "List of Unsaved Images",
+							       (G_PARAM_READWRITE | 
+							        G_PARAM_CONSTRUCT_ONLY)));
+}
+
+static GList *
+get_selected_imgs (GtkTreeModel *store)
+{
+	GList       *list;
+	gboolean     valid;
+	GtkTreeIter  iter;
+
+	list = NULL;
+	valid = gtk_tree_model_get_iter_first (store, &iter);
+
+	while (valid)
+	{
+		gboolean to_save;
+		EogImage *img;
+
+		gtk_tree_model_get (store, &iter, 
+				    SAVE_COLUMN, &to_save,
+				    IMG_COLUMN, &img,
+				    -1);
+		if (to_save)
+			list = g_list_prepend (list, img);
+
+		valid = gtk_tree_model_iter_next (store, &iter);
+	}
+
+	list = g_list_reverse (list);
+
+	return list;
+}
+
+GList *
+eog_close_confirmation_dialog_get_selected_images (EogCloseConfirmationDialog *dlg)
+{
+	g_return_val_if_fail (EOG_IS_CLOSE_CONFIRMATION_DIALOG (dlg), NULL);
+
+	return g_list_copy (dlg->priv->selected_images);
+}
+
+GtkWidget *
+eog_close_confirmation_dialog_new (GtkWindow *parent, 
+				   GList     *unsaved_images)
+{
+	GtkWidget *dlg;
+	GtkWindowGroup *wg;
+
+	g_return_val_if_fail (unsaved_images != NULL, NULL);
+
+	dlg = GTK_WIDGET (g_object_new (EOG_TYPE_CLOSE_CONFIRMATION_DIALOG,
+				        "unsaved_images", unsaved_images,
+				        NULL));
+	g_return_val_if_fail (dlg != NULL, NULL);
+
+	if (parent != NULL)
+	{
+		wg = parent->group;
+
+		if (wg == NULL) {
+			wg = gtk_window_group_new ();
+			gtk_window_group_add_window (wg, parent);
+		}
+
+		gtk_window_group_add_window (wg,
+					     GTK_WINDOW (dlg));
+		
+		gtk_window_set_transient_for (GTK_WINDOW (dlg), parent);					     
+	}
+
+	return dlg;
+}
+
+GtkWidget *
+eog_close_confirmation_dialog_new_single (GtkWindow     *parent, 
+					  EogImage	*image)
+{
+	GtkWidget *dlg;
+	GList *unsaved_images;
+	g_return_val_if_fail (image != NULL, NULL);
+	
+	unsaved_images = g_list_prepend (NULL, image);
+
+	dlg = eog_close_confirmation_dialog_new (parent, 
+						 unsaved_images);
+	
+	g_list_free (unsaved_images);
+
+	return dlg;
+}
+
+static gchar *
+get_text_secondary_label (EogImage *image)
+{
+	gchar *secondary_msg;
+	
+	secondary_msg = g_strdup (_("If you don't save, changes made to the image "
+				    "will permanently be lost."));
+	
+	return secondary_msg;
+}
+
+static void
+build_single_img_dialog (EogCloseConfirmationDialog *dlg)
+{
+	GtkWidget     *hbox;
+	GtkWidget     *vbox;
+	GtkWidget     *primary_label;
+	GtkWidget     *secondary_label;
+	GtkWidget     *image;
+	EogImage      *img;
+	const gchar   *image_name;
+	gchar         *str;
+	gchar         *markup_str;
+
+	g_return_if_fail (dlg->priv->unsaved_images->data != NULL);
+	img = EOG_IMAGE (dlg->priv->unsaved_images->data);
+
+	/* Image */
+	image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, 
+					  GTK_ICON_SIZE_DIALOG);
+	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
+
+	/* Primary label */
+	primary_label = gtk_label_new (NULL);
+	gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
+	gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (primary_label), 0.0, 0.5);
+	gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
+
+	image_name = eog_image_get_caption (img);
+
+	str = g_markup_printf_escaped (_("Save changes to image \"%s\" before closing?"),
+				       image_name);
+	markup_str = g_strconcat ("<span weight=\"bold\" size=\"larger\">", str, "</span>", NULL);
+	g_free (str);
+
+	gtk_label_set_markup (GTK_LABEL (primary_label), markup_str);
+	g_free (markup_str);
+
+	/* Secondary label */
+	str = get_text_secondary_label (img);
+
+	secondary_label = gtk_label_new (str);
+	g_free (str);
+	gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (secondary_label), 0.0, 0.5);
+	gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
+
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+
+	gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+
+	vbox = gtk_vbox_new (FALSE, 12);
+	
+	gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
+
+	gtk_box_pack_start (GTK_BOX (vbox), primary_label, FALSE, FALSE, 0);
+		      
+	gtk_box_pack_start (GTK_BOX (vbox), secondary_label, FALSE, FALSE, 0);
+
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), 
+			    hbox, 
+	                    FALSE, 
+			    FALSE, 
+			    0);
+
+	add_buttons (dlg);
+
+	gtk_widget_show_all (hbox);
+}
+
+static void
+populate_model (GtkTreeModel *store, GList *imgs)
+{
+	GtkTreeIter iter;
+
+	while (imgs != NULL)
+	{
+		EogImage *img;
+		const gchar *name;
+		GdkPixbuf *buf;
+		GdkPixbuf *buf_scaled;
+		int width;
+		double ratio;
+
+		img = EOG_IMAGE (imgs->data);
+
+		name = eog_image_get_caption (img);
+		buf = eog_image_get_thumbnail (img);
+
+		ratio = IMAGE_COLUMN_HEIGHT / (double) gdk_pixbuf_get_height (buf);
+		width = (int) (gdk_pixbuf_get_width (buf) * ratio);
+		buf_scaled = gdk_pixbuf_scale_simple (buf, width, IMAGE_COLUMN_HEIGHT, GDK_INTERP_BILINEAR);
+
+		gtk_list_store_append (GTK_LIST_STORE (store), &iter);
+		gtk_list_store_set (GTK_LIST_STORE (store), &iter,
+				    SAVE_COLUMN, TRUE,
+				    IMAGE_COLUMN, buf_scaled,
+				    NAME_COLUMN, name,
+				    IMG_COLUMN, img,
+			            -1);
+
+		imgs = g_list_next (imgs);
+	}
+}
+
+static void
+save_toggled (GtkCellRendererToggle *renderer, gchar *path_str, GtkTreeModel *store)
+{
+	GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
+	GtkTreeIter iter;
+	gboolean active;
+
+	gtk_tree_model_get_iter (store, &iter, path);
+	gtk_tree_model_get (store, &iter, SAVE_COLUMN, &active, -1);
+
+	active ^= 1;
+
+	gtk_list_store_set (GTK_LIST_STORE (store), &iter,
+			    SAVE_COLUMN, active, -1);
+
+	gtk_tree_path_free (path);
+}
+
+static GtkWidget *
+create_treeview (EogCloseConfirmationDialogPrivate *priv)
+{
+	GtkListStore *store;
+	GtkWidget *treeview;
+	GtkCellRenderer *renderer;
+	GtkTreeViewColumn *column;
+
+	treeview = gtk_tree_view_new ();
+	gtk_widget_set_size_request (treeview, 260, 120);
+	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
+	gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), FALSE);
+
+	/* Create and populate the model */
+	store = gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
+	populate_model (GTK_TREE_MODEL (store), priv->unsaved_images);
+
+	/* Set model to the treeview */
+	gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store));
+	g_object_unref (store);
+
+	priv->list_store = GTK_TREE_MODEL (store);
+	
+	/* Add columns */
+	renderer = gtk_cell_renderer_toggle_new ();
+	g_signal_connect (renderer, "toggled",
+			  G_CALLBACK (save_toggled), store);
+
+	column = gtk_tree_view_column_new_with_attributes ("Save?",
+							   renderer,
+							   "active",
+							   SAVE_COLUMN,
+							   NULL);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+	renderer = gtk_cell_renderer_pixbuf_new ();
+
+	column = gtk_tree_view_column_new_with_attributes ("Image",
+							   renderer,
+							   "pixbuf",
+							   IMAGE_COLUMN,
+							   NULL);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+	
+
+	renderer = gtk_cell_renderer_text_new ();
+	column = gtk_tree_view_column_new_with_attributes ("Name",
+							   renderer,
+							   "text",
+							   NAME_COLUMN,
+							   NULL);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+	return treeview;
+}
+
+static void
+build_multiple_imgs_dialog (EogCloseConfirmationDialog *dlg)
+{
+	EogCloseConfirmationDialogPrivate *priv;
+	GtkWidget *hbox;
+	GtkWidget *image;
+	GtkWidget *vbox;
+	GtkWidget *primary_label;
+	GtkWidget *vbox2;
+	GtkWidget *select_label;
+	GtkWidget *scrolledwindow;
+	GtkWidget *treeview;
+	GtkWidget *secondary_label;
+	gchar     *str;
+	gchar     *markup_str;
+
+	priv = dlg->priv;
+
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+  	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), 
+			    hbox, TRUE, TRUE, 0);
+
+	/* Image */
+	image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, 
+					  GTK_ICON_SIZE_DIALOG);
+	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
+	gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+
+	vbox = gtk_vbox_new (FALSE, 12);
+	gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+
+	/* Primary label */
+	primary_label = gtk_label_new (NULL);
+	gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
+	gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (primary_label), 0.0, 0.5);
+	gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
+
+	str = g_strdup_printf (
+			ngettext ("There is %d image with unsaved changes. "
+				  "Save changes before closing?",
+				  "There are %d images with unsaved changes. "
+				  "Save changes before closing?",
+				  g_list_length (priv->unsaved_images)),
+			g_list_length (priv->unsaved_images));
+
+	markup_str = g_strconcat ("<span weight=\"bold\" size=\"larger\">", str, "</span>", NULL);
+	g_free (str);
+	
+	gtk_label_set_markup (GTK_LABEL (primary_label), markup_str);
+	g_free (markup_str);
+	gtk_box_pack_start (GTK_BOX (vbox), primary_label, FALSE, FALSE, 0);
+	
+	vbox2 = gtk_vbox_new (FALSE, 8);
+	gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
+
+	select_label = gtk_label_new_with_mnemonic (_("S_elect the images you want to save:"));
+
+	gtk_box_pack_start (GTK_BOX (vbox2), select_label, FALSE, FALSE, 0);
+	gtk_label_set_line_wrap (GTK_LABEL (select_label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (select_label), 0.0, 0.5);
+
+	scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
+	gtk_box_pack_start (GTK_BOX (vbox2), scrolledwindow, TRUE, TRUE, 0);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), 
+					GTK_POLICY_AUTOMATIC, 
+					GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow), 
+					     GTK_SHADOW_IN);
+
+	treeview = create_treeview (priv);
+	gtk_container_add (GTK_CONTAINER (scrolledwindow), treeview);
+
+	/* Secondary label */
+	secondary_label = gtk_label_new (_("If you don't save, "
+					   "all your changes will be permanently lost."));
+
+	gtk_box_pack_start (GTK_BOX (vbox2), secondary_label, FALSE, FALSE, 0);
+	gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (secondary_label), 0, 0.5);
+	gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
+
+	gtk_label_set_mnemonic_widget (GTK_LABEL (select_label), treeview);
+
+	add_buttons (dlg);
+
+	gtk_widget_show_all (hbox);
+}
+
+static void
+set_unsaved_image (EogCloseConfirmationDialog *dlg,
+		   const GList                *list)
+{
+	EogCloseConfirmationDialogPrivate *priv;
+
+	g_return_if_fail (list != NULL);	
+
+	priv = dlg->priv;
+	g_return_if_fail (priv->unsaved_images == NULL);
+
+	priv->unsaved_images = g_list_copy ((GList *)list);
+
+	if (GET_MODE (priv) == SINGLE_IMG_MODE)
+	{
+		build_single_img_dialog (dlg);
+	}
+	else
+	{
+		build_multiple_imgs_dialog (dlg);
+	}	
+}
+
+const GList *
+eog_close_confirmation_dialog_get_unsaved_images (EogCloseConfirmationDialog *dlg)
+{
+	g_return_val_if_fail (EOG_IS_CLOSE_CONFIRMATION_DIALOG (dlg), NULL);
+
+	return dlg->priv->unsaved_images;
+}
diff --git a/src/eog-close-confirmation-dialog.h b/src/eog-close-confirmation-dialog.h
new file mode 100644
index 0000000..ecd82ed
--- /dev/null
+++ b/src/eog-close-confirmation-dialog.h
@@ -0,0 +1,71 @@
+/*
+ * eog-close-confirmation-dialog.h
+ * This file is part of eog
+ *
+ * Author: Marcus Carlson <marcus@mejlamej.nu>
+ *
+ * Based on gedit code (gedit/gedit-close-confirmation.h) by gedit Team
+ *
+ * Copyright (C) 2004-2005 GNOME Foundation 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA. 
+ */
+
+#ifndef __EOG_CLOSE_CONFIRMATION_DIALOG_H__
+#define __EOG_CLOSE_CONFIRMATION_DIALOG_H__
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include <eog-image.h>
+
+#define EOG_TYPE_CLOSE_CONFIRMATION_DIALOG		(eog_close_confirmation_dialog_get_type ())
+#define EOG_CLOSE_CONFIRMATION_DIALOG(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), EOG_TYPE_CLOSE_CONFIRMATION_DIALOG, EogCloseConfirmationDialog))
+#define EOG_CLOSE_CONFIRMATION_DIALOG_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), EOG_TYPE_CLOSE_CONFIRMATION_DIALOG, EogCloseConfirmationDialogClass))
+#define EOG_IS_CLOSE_CONFIRMATION_DIALOG(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), EOG_TYPE_CLOSE_CONFIRMATION_DIALOG))
+#define EOG_IS_CLOSE_CONFIRMATION_DIALOG_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), EOG_TYPE_CLOSE_CONFIRMATION_DIALOG))
+#define EOG_CLOSE_CONFIRMATION_DIALOG_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj),EOG_TYPE_CLOSE_CONFIRMATION_DIALOG, EogCloseConfirmationDialogClass))
+
+typedef struct _EogCloseConfirmationDialog 		EogCloseConfirmationDialog;
+typedef struct _EogCloseConfirmationDialogClass 	EogCloseConfirmationDialogClass;
+typedef struct _EogCloseConfirmationDialogPrivate 	EogCloseConfirmationDialogPrivate;
+
+struct _EogCloseConfirmationDialog 
+{
+	GtkDialog parent;
+
+	/*< private > */
+	EogCloseConfirmationDialogPrivate *priv;
+};
+
+struct _EogCloseConfirmationDialogClass 
+{
+	GtkDialogClass parent_class;
+};
+
+GType 		 eog_close_confirmation_dialog_get_type		(void) G_GNUC_CONST;
+
+GtkWidget	*eog_close_confirmation_dialog_new			(GtkWindow     *parent,
+									 GList         *unsaved_documents);
+GtkWidget 	*eog_close_confirmation_dialog_new_single 		(GtkWindow     *parent, 
+									 EogImage      *image);
+
+const GList	*eog_close_confirmation_dialog_get_unsaved_images	(EogCloseConfirmationDialog *dlg);
+
+GList		*eog_close_confirmation_dialog_get_selected_images	(EogCloseConfirmationDialog *dlg);
+
+#endif /* __EOG_CLOSE_CONFIRMATION_DIALOG_H__ */
+
diff --git a/src/eog-window.c b/src/eog-window.c
index 3ab58e8..83ab2e0 100644
--- a/src/eog-window.c
+++ b/src/eog-window.c
@@ -52,6 +52,7 @@
 #include "eog-util.h"
 #include "eog-save-as-dialog-helper.h"
 #include "eog-plugin-engine.h"
+#include "eog-close-confirmation-dialog.h"
 
 #include "egg-toolbar-editor.h"
 #include "egg-editable-toolbar.h"
@@ -212,6 +213,8 @@ static void eog_window_list_store_image_removed (GtkTreeModel *tree_model,
                  				 GtkTreePath  *path,
 						 gpointer      user_data);
 static void eog_window_set_wallpaper (EogWindow *window, const gchar *filename);
+static gboolean eog_window_save_images (EogWindow *window, GList *images);
+static void eog_window_finish_saving (EogWindow *window);
 
 static GQuark
 eog_window_error_quark (void)
@@ -2433,11 +2436,121 @@ eog_window_cmd_file_open (GtkAction *action, gpointer user_data)
 }
 
 static void
+eog_job_close_save_cb (EogJobSave *job, gpointer user_data)
+{
+	EogWindow *window = EOG_WINDOW (user_data);
+
+	g_signal_handlers_disconnect_by_func (job,
+					      eog_job_close_save_cb,
+					      window);
+
+	gtk_widget_destroy (GTK_WIDGET (window));
+}
+
+static void
+close_confirmation_dialog_response_handler (EogCloseConfirmationDialog *dlg,
+					    gint                        response_id,
+					    EogWindow                  *window)
+{
+	GList *selected_images;
+	EogWindowPrivate *priv;
+
+	priv = window->priv;
+
+	switch (response_id)
+	{
+		case GTK_RESPONSE_YES:
+			/* save selected images */
+			selected_images = eog_close_confirmation_dialog_get_selected_images (dlg);
+
+			if (eog_window_save_images (window, selected_images)) {
+				g_signal_connect (priv->save_job,
+							  "finished",
+							  G_CALLBACK (eog_job_close_save_cb),
+							  window);
+
+				eog_job_queue_add_job (priv->save_job);
+			}
+
+			break;
+
+		case GTK_RESPONSE_NO:
+			/* dont save */
+			gtk_widget_destroy (GTK_WIDGET (window));
+			break;
+
+		default:
+			/* Cancel */
+			break;
+	}
+
+	gtk_widget_destroy (GTK_WIDGET (dlg));
+}
+
+static gboolean
+eog_window_unsaved_images_confirm (EogWindow *window)
+{
+	EogWindowPrivate *priv;
+	GtkWidget *dialog;
+	GList *list;
+	EogImage *image;
+	GtkTreeIter iter;
+
+	priv = window->priv;
+
+	if (window->priv->save_disabled) {
+		return FALSE;
+	}
+
+	list = NULL;
+	if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->store), &iter)) {
+		do {
+			gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
+					    EOG_LIST_STORE_EOG_IMAGE, &image,
+					    -1);
+			if (!image)
+				continue;
+
+			if (eog_image_is_modified (image)) {
+				list = g_list_append (list, image);
+			}
+		} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->store), &iter));
+	}		
+
+	if (list) {	
+		dialog = eog_close_confirmation_dialog_new (GTK_WINDOW (window),
+							    list);
+	
+		g_signal_connect (dialog,
+				  "response",
+				  G_CALLBACK (close_confirmation_dialog_response_handler),
+				  window);
+
+		gtk_widget_show (dialog);
+		return TRUE;
+
+	}
+	return FALSE;
+}
+
+static void
 eog_window_cmd_close_window (GtkAction *action, gpointer user_data)
 {
+	EogWindow *window;
+	EogWindowPrivate *priv;
+
 	g_return_if_fail (EOG_IS_WINDOW (user_data));
 
-	gtk_widget_destroy (GTK_WIDGET (user_data));
+	window = EOG_WINDOW (user_data);
+	priv = window->priv;
+
+	if (priv->save_job != NULL) {
+		eog_window_finish_saving (window);
+	}
+
+	if (!eog_window_unsaved_images_confirm (window)) {
+		gtk_widget_destroy (GTK_WIDGET (user_data));
+	}
 }
 
 static void
@@ -2786,20 +2899,15 @@ eog_job_copy_cb (EogJobCopy *job, gpointer user_data)
 	g_object_unref (job);
 }
 
-static void
-eog_window_cmd_save (GtkAction *action, gpointer user_data)
+static gboolean
+eog_window_save_images (EogWindow *window, GList *images)
 {
 	EogWindowPrivate *priv;
-	EogWindow *window;
-	GList *images;
 
-	window = EOG_WINDOW (user_data);
 	priv = window->priv;
 
 	if (window->priv->save_job != NULL)
-		return;
-
-	images = eog_thumb_view_get_selected_images (EOG_THUMB_VIEW (priv->thumbview));
+		return FALSE;
 
 	priv->save_job = eog_job_save_new (images);
 
@@ -2813,7 +2921,27 @@ eog_window_cmd_save (GtkAction *action, gpointer user_data)
 			  G_CALLBACK (eog_job_save_progress_cb),
 			  window);
 
-	eog_job_queue_add_job (priv->save_job);
+	return TRUE;
+}
+
+static void
+eog_window_cmd_save (GtkAction *action, gpointer user_data)
+{
+	EogWindowPrivate *priv;
+	EogWindow *window;
+	GList *images;
+
+	window = EOG_WINDOW (user_data);
+	priv = window->priv;
+
+	if (window->priv->save_job != NULL)
+		return;
+
+	images = eog_thumb_view_get_selected_images (EOG_THUMB_VIEW (priv->thumbview));
+
+	if (eog_window_save_images (window, images)) {
+		eog_job_queue_add_job (priv->save_job);
+	}
 }
 
 static GFile*
@@ -4599,6 +4727,10 @@ eog_window_delete (GtkWidget *widget, GdkEventAny *event)
 		eog_window_finish_saving (window);
 	}
 
+	if (eog_window_unsaved_images_confirm (window)) {
+		return TRUE;
+	}
+
 	gtk_widget_destroy (widget);
 
 	return TRUE;
