evolution r34956 - branches/mbarnes-composer/composer



Author: mbarnes
Date: Sun Feb  3 17:18:21 2008
New Revision: 34956
URL: http://svn.gnome.org/viewvc/evolution?rev=34956&view=rev

Log:
Split the auto-save logic into a separate module.


Added:
   branches/mbarnes-composer/composer/e-composer-autosave.c
   branches/mbarnes-composer/composer/e-composer-autosave.h
Modified:
   branches/mbarnes-composer/composer/Makefile.am
   branches/mbarnes-composer/composer/e-msg-composer.c

Modified: branches/mbarnes-composer/composer/Makefile.am
==============================================================================
--- branches/mbarnes-composer/composer/Makefile.am	(original)
+++ branches/mbarnes-composer/composer/Makefile.am	Sun Feb  3 17:18:21 2008
@@ -58,6 +58,8 @@
 libcomposer_la_SOURCES = 			\
 	$(IDL_GENERATED)			\
 	$(HTML_EDITOR_GENERATED)		\
+	e-composer-autosave.c			\
+	e-composer-autosave.h			\
 	e-composer-common.h			\
 	e-composer-header.c			\
 	e-composer-header.h			\

Added: branches/mbarnes-composer/composer/e-composer-autosave.c
==============================================================================
--- (empty file)
+++ branches/mbarnes-composer/composer/e-composer-autosave.c	Sun Feb  3 17:18:21 2008
@@ -0,0 +1,366 @@
+#include "e-composer-autosave.h"
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+
+#include <e-util/e-error.h>
+#include <camel/camel-stream-fs.h>
+
+#define AUTOSAVE_SEED		".evolution-composer.autosave-XXXXXX"
+#define AUTOSAVE_INTERVAL	60000
+
+typedef struct _AutosaveState AutosaveState;
+
+struct _AutosaveState {
+	gchar *filename;
+	gboolean enabled;
+	gint fd;
+};
+
+static GList *autosave_registry;
+static guint autosave_source_id;
+
+static const gchar *
+composer_autosave_get_dirname (void)
+{
+	/* XXX We really ought to centralize this to make sure all
+	 *     components agree on the directory for user data. */
+
+	static gchar *dirname = NULL;
+
+	if (G_UNLIKELY (dirname == NULL))
+		dirname = g_build_filename (
+			g_get_home_dir (), ".evolution", NULL);
+
+	return dirname;
+}
+
+static EMsgComposer *
+composer_autosave_registry_lookup (const gchar *basename)
+{
+	GList *iter;
+
+	/* Find the composer with the given autosave filename. */
+	for (iter = autosave_registry; iter != NULL; iter = iter->next) {
+		EMsgComposer *composer = iter->data;
+		AutosaveState *state;
+
+		state = g_object_get_data (G_OBJECT (composer), "autosave");
+		if (state == NULL || state->filename == NULL)
+			continue;
+
+		if (g_str_has_suffix (state->filename, basename))
+			return composer;
+	}
+
+	return NULL;
+}
+
+static AutosaveState *
+composer_autosave_state_new (void)
+{
+	AutosaveState *state;
+
+	state = g_slice_new (AutosaveState);
+	state->filename = NULL;
+	state->enabled = TRUE;
+	state->fd = -1;
+
+	return state;
+}
+
+static void
+composer_autosave_state_free (AutosaveState *state)
+{
+	if (state->fd >= 0)
+		close (state->fd);
+
+	g_free (state->filename);
+	g_slice_free (AutosaveState, state);
+}
+
+static gboolean
+composer_autosave_state_open (AutosaveState *state,
+                              GError **error)
+{
+	if (state->filename != NULL)
+		return TRUE;
+
+	state->filename = g_build_filename (
+		composer_autosave_get_dirname (), AUTOSAVE_SEED, NULL);
+
+	errno = 0;
+	if ((state->fd = g_mkstemp (state->filename)) >= 0)
+		return TRUE;
+
+	g_set_error (
+		error, G_FILE_ERROR,
+		g_file_error_from_errno (errno),
+		"%s: %s", state->filename, g_strerror (errno));
+
+	g_free (state->filename);
+	state->filename = NULL;
+
+	return FALSE;
+}
+
+static void
+composer_autosave_foreach (EMsgComposer *composer)
+{
+	/* Make sure the composer is still alive. */
+	g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+
+	if (e_composer_autosave_get_enabled (composer))
+		e_composer_autosave_snapshot (composer);
+}
+
+static gint
+composer_autosave_timeout (void)
+{
+	g_list_foreach (
+		autosave_registry, (GFunc)
+		composer_autosave_foreach, NULL);
+
+	return TRUE;
+}
+
+static void
+composer_autosave_notify (gpointer unused,
+                          GObject *where_the_object_was)
+{
+	/* Remove the dead composer from the registry. */
+	autosave_registry = g_list_remove (
+		autosave_registry, where_the_object_was);
+
+	/* Cancel timeouts if the registry is now empty. */
+	if (autosave_registry == NULL && autosave_source_id != 0) {
+		g_source_remove (autosave_source_id);
+		autosave_source_id = 0;
+	}
+}
+
+GList *
+e_composer_autosave_find_orphans (GError **error)
+{
+	GDir *dir;
+	const gchar *dirname;
+	const gchar *basename;
+	GList *orphans = NULL;
+
+	dirname = composer_autosave_get_dirname ();
+	dir = g_dir_open (dirname, 0, error);
+	if (dir == NULL)
+		return NULL;
+
+	/* Scan the user directory for autosave files. */
+	while ((basename = g_dir_read_name (dir)) != NULL) {
+		const gchar *errmsg;
+		gchar *filename;
+		struct stat st;
+
+		/* Is this an autosave file? */
+		if (!g_str_has_prefix (basename, AUTOSAVE_SEED))
+			continue;
+
+		/* Is this an orphaned autosave file? */
+		if (composer_autosave_registry_lookup (basename) != NULL)
+			continue;
+
+		filename = g_build_filename (dirname, basename, NULL);
+
+		/* Try to examine the autosave file.  Failure here
+		 * is non-fatal; just emit a warning and move on. */
+		errno = 0;
+		if (g_stat (filename, &st) < 0) {
+			errmsg = g_strerror (errno);
+			g_warning ("%s: %s", filename, errmsg);
+			g_free (filename);
+			continue;
+		}
+
+		/* If the file is empty, delete it.  Failure here
+		 * is non-fatal; just emit a warning and move on. */
+		if (st.st_size == 0) {
+			errno = 0;
+			if (g_unlink (filename) < 0) {
+				errmsg = g_strerror (errno);
+				g_warning ("%s: %s", filename, errmsg);
+			}
+			g_free (filename);
+			continue;
+		}
+
+		orphans = g_list_prepend (orphans, filename);
+	}
+
+	g_dir_close (dir);
+
+	return g_list_reverse (orphans);
+}
+
+void
+e_composer_autosave_register (EMsgComposer *composer)
+{
+	g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+
+	g_object_set_data_full (
+		G_OBJECT (composer), "autosave",
+		composer_autosave_state_new (),
+		(GDestroyNotify) composer_autosave_state_free);
+
+	autosave_registry = g_list_prepend (autosave_registry, composer);
+
+	g_object_weak_ref (
+		G_OBJECT (composer), (GWeakNotify)
+		composer_autosave_notify, NULL);
+
+	if (autosave_source_id == 0)
+		autosave_source_id = g_timeout_add (
+			AUTOSAVE_INTERVAL, (GSourceFunc)
+			composer_autosave_timeout, NULL);
+}
+
+gboolean
+e_composer_autosave_snapshot (EMsgComposer *composer)
+{
+	CamelMimeMessage *message;
+	AutosaveState *state;
+	CamelStream *stream;
+	gint camelfd;
+	const gchar *errmsg;
+
+	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
+
+	/* If the contents are unchanged, exit early. */
+	if (!e_msg_composer_is_dirty (composer))
+		return TRUE;
+
+	state = g_object_get_data (G_OBJECT (composer), "autosave");
+	g_return_val_if_fail (state != NULL, FALSE);
+
+	/* Open the autosave file on-demand. */
+	if (!composer_autosave_state_open (state, NULL)) {
+		errmsg = _("Could not open autosave file");
+		goto fail;
+	}
+
+	/* Extract a MIME message from the composer. */
+	message = e_msg_composer_get_message_draft (composer);
+	if (message == NULL) {
+		errmsg = _("Unable to retrieve message from editor");
+		goto fail;
+	}
+
+	/* Move to the beginning of the autosave file. */
+	if (lseek (state->fd, (off_t) 0, SEEK_SET) < 0) {
+		camel_object_unref (message);
+		errmsg = g_strerror (errno);
+		goto fail;
+	}
+
+	/* Destroy the contents of the autosave file. */
+	if (ftruncate (state->fd, (off_t) 0) < 0) {
+		camel_object_unref (message);
+		errmsg = g_strerror (errno);
+		goto fail;
+	}
+
+	/* Duplicate the file descriptor for Camel. */
+	if ((camelfd = dup (state->fd)) < 0) {
+		camel_object_unref (message);
+		errmsg = g_strerror (errno);
+		goto fail;
+	}
+
+	/* Open a CamelStream to the autosave file. */
+	stream = camel_stream_fs_new_with_fd (camelfd);
+
+	/* Write the message to the CamelStream. */
+	if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), stream) < 0) {
+		camel_object_unref (message);
+		camel_object_unref (stream);
+		errmsg = g_strerror (errno);
+		goto fail;
+	}
+
+	/* Close the CamelStream. */
+	if (camel_stream_close (CAMEL_STREAM (stream)) < 0) {
+		camel_object_unref (message);
+		camel_object_unref (stream);
+		errmsg = g_strerror (errno);
+		goto fail;
+	}
+
+	/* Snapshot was successful; set various flags. */
+	e_msg_composer_set_saved (composer);
+	e_msg_composer_unset_changed (composer);
+	e_msg_composer_set_autosaved (composer);
+
+	camel_object_unref (message);
+	camel_object_unref (stream);
+
+	return TRUE;
+
+fail:
+	e_error_run (
+		GTK_WINDOW (composer), "mail-composer:no-autosave",
+		(state->filename != NULL) ? state->filename : "",
+		errmsg, NULL);
+
+	return FALSE;
+}
+
+gint
+e_composer_autosave_get_fd (EMsgComposer *composer)
+{
+	AutosaveState *state;
+
+	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), -1);
+
+	state = g_object_get_data (G_OBJECT (composer), "autosave");
+	g_return_val_if_fail (state != NULL, -1);
+
+	return state->fd;
+}
+
+const gchar *
+e_composer_autosave_get_filename (EMsgComposer *composer)
+{
+	AutosaveState *state;
+
+	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL);
+
+	state = g_object_get_data (G_OBJECT (composer), "autosave");
+	g_return_val_if_fail (state != NULL, NULL);
+
+	return state->filename;
+}
+
+gboolean
+e_composer_autosave_get_enabled (EMsgComposer *composer)
+{
+	AutosaveState *state;
+
+	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
+
+	state = g_object_get_data (G_OBJECT (composer), "autosave");
+	g_return_val_if_fail (state != NULL, FALSE);
+
+	return state->enabled;
+}
+
+void
+e_composer_autosave_set_enabled (EMsgComposer *composer,
+                                 gboolean enabled)
+{
+	AutosaveState *state;
+
+	g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+
+	state = g_object_get_data (G_OBJECT (composer), "autosave");
+	g_return_if_fail (state != NULL);
+
+	state->enabled = enabled;
+}

Added: branches/mbarnes-composer/composer/e-composer-autosave.h
==============================================================================
--- (empty file)
+++ branches/mbarnes-composer/composer/e-composer-autosave.h	Sun Feb  3 17:18:21 2008
@@ -0,0 +1,21 @@
+#ifndef E_COMPOSER_AUTOSAVE_H
+#define E_COMPOSER_AUTOSAVE_H
+
+#include "e-composer-common.h"
+#include "e-msg-composer.h"
+
+G_BEGIN_DECLS
+
+GList *		e_composer_autosave_find_orphans (GError **error);
+
+void		e_composer_autosave_register	 (EMsgComposer *composer);
+gboolean	e_composer_autosave_snapshot	 (EMsgComposer *composer);
+gint		e_composer_autosave_get_fd	 (EMsgComposer *composer);
+const gchar *	e_composer_autosave_get_filename (EMsgComposer *composer);
+gboolean	e_composer_autosave_get_enabled  (EMsgComposer *composer);
+void		e_composer_autosave_set_enabled	 (EMsgComposer *composer,
+						  gboolean enabled);
+
+G_END_DECLS
+
+#endif /* E_COMPOSER_AUTOSAVE_H */

Modified: branches/mbarnes-composer/composer/e-msg-composer.c
==============================================================================
--- branches/mbarnes-composer/composer/e-msg-composer.c	(original)
+++ branches/mbarnes-composer/composer/e-msg-composer.c	Sun Feb  3 17:18:21 2008
@@ -118,6 +118,7 @@
 #include "e-msg-composer.h"
 #include "e-attachment.h"
 #include "e-attachment-bar.h"
+#include "e-composer-autosave.h"
 #include "e-composer-header-table.h"
 #include "e-msg-composer-select-file.h"
 
@@ -206,10 +207,6 @@
 
 	gchar *mime_type, *mime_body, *charset;
 
-	gchar *autosave_file;
-	gint   autosave_fd;
-	guint32 enable_autosave        : 1;
-
 	guint32 attachment_bar_visible : 1;
 	guint32 send_html              : 1;
 	guint32 is_alternative         : 1;
@@ -1676,83 +1673,6 @@
 	CORBA_exception_free (&ev);
 }
 
-#define AUTOSAVE_SEED ".evolution-composer.autosave-XXXXXX"
-#define AUTOSAVE_INTERVAL 60000
-
-typedef struct _AutosaveManager AutosaveManager;
-struct _AutosaveManager {
-	GHashTable *table;
-	guint id;
-	gboolean ask;
-};
-
-static AutosaveManager *am = NULL;
-static void autosave_manager_start (AutosaveManager *am);
-static void autosave_manager_stop (AutosaveManager *am);
-
-static gboolean
-autosave_save_draft (EMsgComposer *composer)
-{
-	EMsgComposerPrivate *p = composer->priv;
-	CamelMimeMessage *message;
-	CamelStream *stream;
-	gchar *file;
-	gint fd, camelfd;
-	gboolean success = TRUE;
-
-	if (!e_msg_composer_is_dirty (composer))
-		return TRUE;
-
-	fd = p->autosave_fd;
-	file = p->autosave_file;
-
-	if (fd == -1) {
-		/* This code is odd, the fd is opened elsewhere but a failure is ignored */
-		e_error_run ((GtkWindow *)composer, "mail-composer:no-autosave",
-			    file, _ ("Could not open file"), NULL);
-		return FALSE;
-	}
-
-	message = e_msg_composer_get_message_draft (composer);
-
-	if (message == NULL) {
-		e_error_run ((GtkWindow *)composer, "mail-composer:no-autosave",
-			    file, _ ("Unable to retrieve message from editor"), NULL);
-		return FALSE;
-	}
-
-	if (lseek (fd, (off_t)0, SEEK_SET) == -1
-	    || ftruncate (fd, (off_t)0) == -1
-	    || (camelfd = dup (fd)) == -1) {
-		camel_object_unref (message);
-		e_error_run ((GtkWindow *)composer, "mail-composer:no-autosave",
-			    file, g_strerror (errno), NULL);
-		return FALSE;
-	}
-
-	/* this does an lseek so we don't have to */
-	stream = camel_stream_fs_new_with_fd (camelfd);
-	if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), stream) == -1
-	    || camel_stream_close (CAMEL_STREAM (stream)) == -1) {
-		e_error_run ((GtkWindow *)composer, "mail-composer:no-autosave",
-			    file, g_strerror (errno), NULL);
-		success = FALSE;
-	} else {
-		CORBA_Environment ev;
-		CORBA_exception_init (&ev);
-		GNOME_GtkHTML_Editor_Engine_runCommand (p->eeditor_engine, "saved", &ev);
-		CORBA_exception_free (&ev);
-		e_msg_composer_unset_changed (composer);
-		e_msg_composer_set_autosaved (composer);
-	}
-
-	camel_object_unref (stream);
-
-	camel_object_unref (message);
-
-	return success;
-}
-
 static EMsgComposer *
 autosave_load_draft (const gchar *filename)
 {
@@ -1773,7 +1693,7 @@
 
 	composer = e_msg_composer_new_with_message (msg);
 	if (composer) {
-		if (autosave_save_draft (composer))
+		if (e_composer_autosave_snapshot (composer))
 			g_unlink (filename);
 
 		g_signal_connect (GTK_OBJECT (composer), "send",
@@ -1788,193 +1708,27 @@
 	return composer;
 }
 
-static gboolean
-autosave_is_owned (AutosaveManager *am, const gchar *file)
-{
-	return g_hash_table_lookup (am->table, file) != NULL;
-}
-
 static void
-autosave_manager_query_load_orphans (AutosaveManager *am, GtkWindow *parent)
+autosave_manager_unregister (EMsgComposer *composer)
 {
-	GDir *dir;
-	const gchar *dname;
-	GSList *match = NULL;
-	gint len = strlen (AUTOSAVE_SEED);
-	gint load = FALSE;
-	gchar *dirname;
-
-	dirname = g_build_filename (g_get_home_dir (), ".evolution", NULL);
-	dir = g_dir_open (dirname, 0, NULL);
-	if (!dir) {
-		return;
-	}
-
-	while ((dname = g_dir_read_name (dir))) {
-		if ((!strncmp (dname, AUTOSAVE_SEED, len - 6))
-		    && (strlen (dname) == len)
-		    && (!autosave_is_owned (am, dname))) {
-			gchar *filename;
-			struct stat st;
-
-			filename = g_build_filename (dirname, dname, NULL);
-
-			/*
-			 * check if the file has any length,  It is a valid case if it doesn't
-			 * so we simply don't ask then.
-			 */
-			if (g_stat (filename, &st) == -1 || st.st_size == 0) {
-				g_unlink (filename);
-				g_free (filename);
-				continue;
-			}
-			match = g_slist_prepend (match, filename);
-		}
-	}
-
-	g_dir_close (dir);
-	g_free (dirname);
-
-	if (match != NULL)
-		load = e_error_run (parent, "mail-composer:recover-autosave", NULL) == GTK_RESPONSE_YES;
-
-	while (match != NULL) {
-		GSList *next = match->next;
-		gchar *filename = match->data;
-		EMsgComposer *composer;
-
-		if (load) {
-			/* FIXME: composer is never used */
-			composer = autosave_load_draft (filename);
-		} else {
-			g_unlink (filename);
-		}
-
-		g_free (filename);
-		g_slist_free_1 (match);
-		match = next;
-	}
-}
-
-static void
-autosave_run_foreach_cb (gpointer key, gpointer value, gpointer data)
-{
-	EMsgComposer *composer = E_MSG_COMPOSER (value);
-	EMsgComposerPrivate *p = composer->priv;
-
-	if (p->enable_autosave)
-		autosave_save_draft (composer);
-}
-
-static gint
-autosave_run (gpointer data)
-{
-	AutosaveManager *am = data;
-
-	g_hash_table_foreach (am->table, (GHFunc)autosave_run_foreach_cb, am);
-
-	autosave_manager_stop (am);
-	autosave_manager_start (am);
-
-	return FALSE;
-}
-
-static gboolean
-autosave_init_file (EMsgComposer *composer)
-{
-	EMsgComposerPrivate *p = composer->priv;
-	if (p->autosave_file == NULL) {
-		p->autosave_file = g_build_filename (
-			g_get_home_dir (), ".evolution", AUTOSAVE_SEED, NULL);
-		p->autosave_fd = g_mkstemp (p->autosave_file);
-		return TRUE;
-	}
-	return FALSE;
-}
-
-static void
-autosave_manager_start (AutosaveManager *am)
-{
-	if (am->id == 0)
-		am->id = g_timeout_add (AUTOSAVE_INTERVAL, autosave_run, am);
-}
-
-static void
-autosave_manager_stop (AutosaveManager *am)
-{
-	if (am->id) {
-		g_source_remove (am->id);
-		am->id = 0;
-	}
-}
-
-static AutosaveManager *
-autosave_manager_new (void)
-{
-	AutosaveManager *am;
-	GHashTable *table;
-
-	table = g_hash_table_new_full (
-		g_str_hash, g_str_equal,
-		(GDestroyNotify) g_free,
-		(GDestroyNotify) NULL);
-
-	am = g_new (AutosaveManager, 1);
-	am->table = table;
-	am->id = 0;
-	am->ask = TRUE;
-
-	return am;
-}
-
-static void
-autosave_manager_register (AutosaveManager *am, EMsgComposer *composer)
-{
-	gchar *key;
-	EMsgComposerPrivate *p = composer->priv;
-
-	g_return_if_fail (composer != NULL);
-
-	if (autosave_init_file (composer)) {
-		key = g_path_get_basename (p->autosave_file);
-		g_hash_table_insert (am->table, key, composer);
-		if (am->ask) {
-			/* keep recursion out of our bedrooms. */
-			am->ask = FALSE;
-			autosave_manager_query_load_orphans (am, (GtkWindow *)composer);
-			am->ask = TRUE;
-		}
-	}
-	autosave_manager_start (am);
-}
+	const gchar *filename;
+	gint fd;
 
-static void
-autosave_manager_unregister (AutosaveManager *am, EMsgComposer *composer)
-{
-	EMsgComposerPrivate *p = composer->priv;
-	gchar *key;
+	filename = e_composer_autosave_get_filename (composer);
+	fd = e_composer_autosave_get_fd (composer);
 
-	if (!p->autosave_file)
+	if (filename == NULL)
 		return;
 
-	key = g_path_get_basename (p->autosave_file);
-	g_hash_table_remove (am->table, key);
-	g_free (key);
-
 	/* only remove the file if we can successfully save it */
 	/* FIXME this test could probably be more efficient */
-	if (autosave_save_draft (composer)) {
+	if (e_composer_autosave_snapshot (composer)) {
 		/* Close before unlinking necessary on Win32 */
-		close (p->autosave_fd);
-		g_unlink (p->autosave_file);
+		close (fd);
+		g_unlink (filename);
 	} else {
-		close (p->autosave_fd);
+		close (fd);
 	}
-	g_free (p->autosave_file);
-	p->autosave_file = NULL;
-
-	if (g_hash_table_size (am->table) == 0)
-		autosave_manager_stop (am);
 }
 
 static void
@@ -2893,7 +2647,7 @@
 	 * (including the remote editor control) will already have
 	 * been destroyed, so we have to do this here.
 	 */
-	autosave_manager_unregister (am, E_MSG_COMPOSER (object));
+	autosave_manager_unregister (E_MSG_COMPOSER (object));
 
 	/* Chain up to parent's dispose () method. */
 	G_OBJECT_CLASS (parent_class)->dispose (object);
@@ -3434,9 +3188,6 @@
 	composer->priv->inline_images = inline_images;
 	composer->priv->inline_images_by_url = inline_images_by_url;
 
-	composer->priv->enable_autosave = TRUE;
-	composer->priv->autosave_fd = -1;
-
 	/** @HookPoint-EMMenu: Main Mail Menu
 	 * @Id: org.gnome.evolution.mail.composer
 	 * @Class: org.gnome.evolution.mail.bonobomenu:1.0
@@ -4144,10 +3895,8 @@
 
 	g_signal_connect (composer, "map", (GCallback) map_default_cb, NULL);
 
-	if (am == NULL)
-		am = autosave_manager_new ();
-
-	autosave_manager_register (am, composer);
+	e_composer_autosave_register (composer);
+	e_msg_composer_check_autosave (GTK_WINDOW (composer));
 
 	p->has_changed = FALSE;
 
@@ -6452,10 +6201,7 @@
 void
 e_msg_composer_set_enable_autosave  (EMsgComposer *composer, gboolean enabled)
 {
-	EMsgComposerPrivate *p = composer->priv;
-	g_return_if_fail (E_IS_MSG_COMPOSER (composer));
-
-	p->enable_autosave = enabled;
+	e_composer_autosave_set_enabled (composer, enabled);
 }
 
 void
@@ -6489,13 +6235,38 @@
 void
 e_msg_composer_check_autosave (GtkWindow *parent)
 {
-	if (am == NULL)
-		am = autosave_manager_new ();
+	GList *orphans = NULL;
+	gint response;
+	GError *error = NULL;
+
+	/* Look for orphaned autosave files. */
+	orphans = e_composer_autosave_find_orphans (&error);
+	if (orphans == NULL) {
+		if (error != NULL) {
+			g_warning ("%s", error->message);
+			g_error_free (error);
+		}
+		return;
+	}
+
+	/* Ask if the user wants to recover the orphaned files. */
+	response = e_error_run (
+		parent, "mail-composer:recover-autosave", NULL);
+
+	/* Based on the user's response, recover or delete them. */
+	while (orphans != NULL) {
+		const gchar *filename = orphans->data;
+		EMsgComposer *composer;
+
+		if (response == GTK_RESPONSE_YES) {
+			/* FIXME: composer is never used */
+			composer = autosave_load_draft (filename);
+		} else {
+			g_unlink (filename);
+		}
 
-	if (am->ask) {
-		am->ask = FALSE;
-		autosave_manager_query_load_orphans (am, parent);
-		am->ask = TRUE;
+		g_free (orphans->data);
+		orphans = g_list_delete_link (orphans, orphans);
 	}
 }
 



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