Index: src/eog-list-store.c
===================================================================
--- src/eog-list-store.c	(revisión: 4305)
+++ src/eog-list-store.c	(copia de trabajo)
@@ -32,6 +32,12 @@
 #define EOG_LIST_STORE_GET_PRIVATE(object) \
 	(G_TYPE_INSTANCE_GET_PRIVATE ((object), EOG_TYPE_LIST_STORE, EogListStorePrivate))
 
+typedef struct {
+	EogListStore *store;
+	EogListStoreForeachFunc func;
+	gpointer data;
+} EogListStoreForeachContext;
+
 G_DEFINE_TYPE (EogListStore, eog_list_store, GTK_TYPE_LIST_STORE);
 
 typedef struct {
@@ -804,3 +810,39 @@ eog_list_store_thumbnail_refresh (EogLis
 	eog_list_store_remove_thumbnail_job (store, iter);
 	eog_list_store_add_thumbnail_job (store, iter);
 }
+
+static gboolean
+eog_list_store_foreach_helper (GtkTreeModel *model,
+			       GtkTreePath *path,
+			       GtkTreeIter *iter,
+			       gpointer data)
+{
+	EogImage *image;
+	EogListStoreForeachContext *ctx;
+
+	ctx = (EogListStoreForeachContext *)data;
+	
+	gtk_tree_model_get (GTK_TREE_MODEL (ctx->store), iter, 
+			    EOG_LIST_STORE_EOG_IMAGE, &image,
+			    -1);
+
+	return (*ctx->func) (ctx->store, image, ctx->data);
+}
+
+void
+eog_list_store_foreach (EogListStore *store,
+			EogListStoreForeachFunc func,
+			gpointer data)
+{
+	EogListStoreForeachContext *ctx = g_new0 (EogListStoreForeachContext, 1);
+
+	ctx->store = store;
+	ctx->func  = func;
+	ctx->data  = data;
+	
+	gtk_tree_model_foreach (GTK_TREE_MODEL (store),
+				eog_list_store_foreach_helper,
+				ctx);
+
+	g_free (ctx);
+}
Index: src/eog-list-store.h
===================================================================
--- src/eog-list-store.h	(revisión: 4305)
+++ src/eog-list-store.h	(copia de trabajo)
@@ -39,6 +39,10 @@ typedef struct _EogListStore EogListStor
 typedef struct _EogListStoreClass EogListStoreClass;
 typedef struct _EogListStorePrivate EogListStorePrivate;
 
+typedef gboolean (* EogListStoreForeachFunc) (EogListStore *store,
+					      EogImage *image,
+					      gpointer data);
+
 #define EOG_TYPE_LIST_STORE            eog_list_store_get_type()
 #define EOG_LIST_STORE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), EOG_TYPE_LIST_STORE, EogListStore))
 #define EOG_LIST_STORE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  EOG_TYPE_LIST_STORE, EogListStoreClass))
@@ -97,6 +101,10 @@ gint            eog_list_store_get_pos_b
 
 gint            eog_list_store_length                (EogListStore *store);
 
+void            eog_list_store_foreach               (EogListStore *store,
+						      EogListStoreForeachFunc func,
+						      gpointer data);
+
 gint            eog_list_store_get_initial_pos 	     (EogListStore *store);
 
 void            eog_list_store_thumbnail_set         (EogListStore *store, 
Index: src/eog-window.c
===================================================================
--- src/eog-window.c	(revisión: 4305)
+++ src/eog-window.c	(copia de trabajo)
@@ -206,6 +206,7 @@ static void fullscreen_clear_timeout (Eo
 static void update_action_groups_state (EogWindow *window);
 static void open_with_launch_application_cb (GtkAction *action, gpointer callback_data);
 static void eog_window_update_openwith_menu (EogWindow *window, EogImage *image);
+static gboolean eog_window_save_unsaved_images (EogWindow *window);
 
 static GQuark
 eog_window_error_quark (void)
@@ -4358,6 +4359,10 @@ eog_window_delete (GtkWidget *widget, Gd
 	window = EOG_WINDOW (widget);
 	priv = window->priv;
 
+	if (!eog_window_save_unsaved_images (window)) {
+	  return FALSE;
+	}
+	
 	if (priv->save_job != NULL) {
 		eog_window_finish_saving (window);
 	}	
@@ -4928,3 +4933,74 @@ eog_window_is_empty (EogWindow *window)
 
         return empty;
 }
+
+static gboolean
+eog_window_confirm_save_image (EogImage *image)
+{
+	GtkWidget *dialog;
+	gint response;
+	gboolean cancel = FALSE;
+
+	dialog = gtk_message_dialog_new (NULL,
+					 GTK_DIALOG_MODAL,
+					 GTK_MESSAGE_QUESTION,
+					 GTK_BUTTONS_NONE,
+					 _("Save the changes to image \"%s\" before closing?"),
+					 eog_image_get_caption (image));
+
+	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+						  _("The image %s has unsaved changes, if you close now they will be lost. "
+						    "Do you want to save the image before closing?"),
+						  eog_image_get_caption (image));
+	
+	gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+				_("Close without saving"), GTK_RESPONSE_NO,
+				GTK_STOCK_SAVE, GTK_RESPONSE_YES,
+				GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
+
+	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
+
+	response = gtk_dialog_run (GTK_DIALOG (dialog));
+	switch (response) {
+	case GTK_RESPONSE_NO:
+		break;
+	case GTK_RESPONSE_YES:
+		g_print ("here we are supposed to save\n");
+		break;
+	case GTK_RESPONSE_CANCEL:
+		cancel = TRUE;
+		break;
+	}
+	gtk_widget_destroy (dialog);
+
+	return cancel;
+}
+
+static gboolean
+save_unsaved_images_foreach (EogListStore *store,
+			     EogImage *image,
+			     gpointer data)
+{
+	gboolean *user_cancelled = (gboolean*) data;
+	
+	if (eog_image_is_modified (image)) {
+		*user_cancelled = eog_window_confirm_save_image (image);
+	}
+	
+	return *user_cancelled;
+}
+
+static gboolean
+eog_window_save_unsaved_images (EogWindow *window)
+{
+	EogWindowPrivate *priv;
+	gboolean user_canceled = FALSE;
+	
+	priv = window->priv;
+
+	eog_list_store_foreach (priv->store,
+				save_unsaved_images_foreach,
+				&user_canceled);
+
+	return !user_canceled;
+}
