querythe user to check if they want to load any orphans we've found.

2001-07-02  Larry Ewing  <lewing@ximian.com>

	* e-msg-composer.c (autosave_query_load_orphans): querythe user to
	check if they want to load any orphans we've found.
	(autosave_query_cb): the dialog callback.
	(autosave_is_orphan): test if if a particular file is orphaned.
	(autosave_load_draft): load a message from an autosave file.
	(autosave_save_draft): save the current buffer to the autosave file.

svn path=/trunk/; revision=10761
This commit is contained in:
Larry Ewing
2001-07-03 19:17:31 +00:00
committed by Larry Ewing
parent b7dede1a27
commit 23dd7a254c
3 changed files with 188 additions and 19 deletions

View File

@ -1,3 +1,12 @@
2001-07-02 Larry Ewing <lewing@ximian.com>
* e-msg-composer.c (autosave_query_load_orphans): querythe user to
check if they want to load any orphans we've found.
(autosave_query_cb): the dialog callback.
(autosave_is_orphan): test if if a particular file is orphaned.
(autosave_load_draft): load a message from an autosave file.
(autosave_save_draft): save the current buffer to the autosave file.
2001-07-02 Christopher James Lahey <clahey@ximian.com> 2001-07-02 Christopher James Lahey <clahey@ximian.com>
* Makefile.am (INCLUDES): Added $(BONOBO_CONF_CFLAGS). * Makefile.am (INCLUDES): Added $(BONOBO_CONF_CFLAGS).

View File

@ -42,6 +42,8 @@
#include <errno.h> #include <errno.h>
#include <ctype.h> #include <ctype.h>
#include <stdlib.h>
#include <dirent.h>
#include <libgnome/gnome-defs.h> #include <libgnome/gnome-defs.h>
#include <libgnomeui/gnome-app.h> #include <libgnomeui/gnome-app.h>
#include <libgnomeui/gnome-uidefs.h> #include <libgnomeui/gnome-uidefs.h>
@ -116,9 +118,10 @@ static const int num_drop_types = sizeof (drop_types) / sizeof (drop_types[0]);
static GnomeAppClass *parent_class = NULL; static GnomeAppClass *parent_class = NULL;
/* local prototypes */ /* local prototypes */
static GList *add_recipients (GList *list, const char *recips, gboolean decode); static GList *add_recipients (GList *list, const char *recips, gboolean decode);
static void free_recipients (GList *list); static void free_recipients (GList *list);
static void handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, int depth); static void handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, int depth);
static void message_rfc822_dnd (EMsgComposer *composer, CamelStream *stream);
static GByteArray * static GByteArray *
@ -948,7 +951,6 @@ save_draft (EMsgComposer *composer, int quitok)
CamelMessageInfo *info; CamelMessageInfo *info;
const MailConfigAccount *account; const MailConfigAccount *account;
struct _save_info *si; struct _save_info *si;
gboolean old_send_html;
CamelFolder *folder = NULL; CamelFolder *folder = NULL;
account = e_msg_composer_get_preferred_account (composer); account = e_msg_composer_get_preferred_account (composer);
@ -972,20 +974,8 @@ save_draft (EMsgComposer *composer, int quitok)
} else } else
folder = drafts_folder; folder = drafts_folder;
/* always save drafts as HTML to preserve formatting */ msg = e_msg_composer_get_message_draft (composer);
old_send_html = composer->send_html;
composer->send_html = TRUE;
msg = e_msg_composer_get_message (composer);
composer->send_html = old_send_html;
/* Attach whether this message was written in HTML */
camel_medium_set_header (CAMEL_MEDIUM (msg), "X-Evolution-Format",
composer->send_html ? "text/html" : "text/plain");
/* Attach account info to the draft. */
if (account && account->name)
camel_medium_set_header (CAMEL_MEDIUM (msg), "X-Evolution-Account", account->name);
info = g_new0 (CamelMessageInfo, 1); info = g_new0 (CamelMessageInfo, 1);
info->flags = CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_SEEN; info->flags = CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_SEEN;
@ -998,6 +988,144 @@ save_draft (EMsgComposer *composer, int quitok)
camel_object_unref (CAMEL_OBJECT (msg)); camel_object_unref (CAMEL_OBJECT (msg));
} }
#define AUTOSAVE_SEED ".evolution-composer.autosave-XXXXXX"
#define AUTOSAVE_INTERVAL 600
static void
autosave_save_draft (EMsgComposer *composer)
{
CamelMimeMessage *msg;
CamelStream *stream;
char *file;
gint fd;
if (composer->autosave_file == NULL) {
composer->autosave_file = g_strdup_printf ("%s/%s", g_get_home_dir(), AUTOSAVE_SEED);
composer->autosave_fd = mkstemp (composer->autosave_file);
}
fd = composer->autosave_fd;
file = composer->autosave_file;
if (fd == -1) {
e_notice (GTK_WINDOW (composer), GNOME_MESSAGE_BOX_ERROR,
_("Error opening file: %s"), file);
return;
}
msg = e_msg_composer_get_message_draft (composer);
if (ftruncate (fd, (off_t)0) == -1) {
e_notice (GTK_WINDOW (composer), GNOME_MESSAGE_BOX_ERROR,
_("Unable to truncate file: %s\n%s"), file, strerror(errno));
return;
}
/* this does an lseek so we don't have to */
stream = camel_stream_fs_new_with_fd(fd);
if (camel_data_wrapper_write_to_stream((CamelDataWrapper *)msg, stream) == -1
|| camel_stream_flush((CamelStream *)stream) == -1) {
e_notice (GTK_WINDOW (composer), GNOME_MESSAGE_BOX_ERROR,
_("Error autosaving message: %s\n %s"), file, strerror(errno));
}
/* set the fd to -1 in the stream so camel doesn't close it we want to keep it open */
CAMEL_STREAM_FS (stream)->fd = -1;
camel_object_unref((CamelObject *)stream);
}
static EMsgComposer *
autosave_load_draft (const char *filename)
{
CamelStream *stream;
CamelMimeMessage *msg;
EMsgComposer *composer;
g_warning ("filename = \"%s\"", filename);
stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0);
msg = camel_mime_message_new ();
camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg), stream);
composer = e_msg_composer_new_with_message (msg);
gtk_widget_show (GTK_WIDGET (composer));
return composer;
}
static gboolean
autosave_is_orphan (const char *file)
{
g_warning ("I am a bug");
return (rand()%2);
}
static void
autosave_query_cb (gint reply, gpointer data)
{
int *ok = data;
*ok = !reply;
}
static GList *
autosave_query_load_orphans (EMsgComposer *composer)
{
GtkWidget *dialog;
DIR *dir;
struct dirent *d;
GList *matches = NULL;
gint len = strlen (AUTOSAVE_SEED);
gint pre_len;
gint ok;
/* length of the seed minus the XXXXXX */
pre_len = len - 6;
dir = opendir (g_get_home_dir());
if (!dir) {
return NULL;
}
while ((d = readdir (dir))) {
if ((!strncmp (d->d_name, AUTOSAVE_SEED, pre_len) )
&& (strlen (d->d_name) == len)
&& (strcmp (d->d_name + pre_len, composer->autosave_file + pre_len))
&& (autosave_is_orphan (d->d_name))) {
dialog = gnome_ok_cancel_dialog_parented (_("Evolution has detected an editor buffer from a previous session.\n"
"Would you like to recover this buffer?"),
autosave_query_cb, &ok, GTK_WINDOW (composer));
gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
if (ok) {
autosave_load_draft (d->d_name);
}
}
}
return matches;
}
static gint
autosave_timeout_run (gpointer data)
{
EMsgComposer *composer = E_MSG_COMPOSER (data);
autosave_save_draft (composer);
}
static void
autosave_timeout_start (EMsgComposer *composer)
{
if (!composer->autosave_id)
composer->autosave_id = gtk_timeout_add (AUTOSAVE_INTERVAL, autosave_timeout_run, composer);
}
static void
autosave_timeout_stop (EMsgComposer *composer)
{
if (composer->autosave_id)
gtk_timeout_remove (composer->autosave_id);
}
static void static void
menu_file_save_draft_cb (BonoboUIComponent *uic, void *data, const char *path) menu_file_save_draft_cb (BonoboUIComponent *uic, void *data, const char *path)
{ {
@ -1826,6 +1954,8 @@ init (EMsgComposer *composer)
composer->has_changed = FALSE; composer->has_changed = FALSE;
composer->charset = NULL; composer->charset = NULL;
composer->autosave_file = NULL;
composer->autosave_fd = -1;
} }
@ -2657,6 +2787,31 @@ e_msg_composer_get_message (EMsgComposer *composer)
return build_message (composer); return build_message (composer);
} }
CamelMimeMessage *
e_msg_composer_get_message_draft (EMsgComposer *composer)
{
CamelMimeMessage *msg;
const MailConfigAccount *account;
gint old_send_html;
/* always save drafts as HTML to preserve formatting */
old_send_html = composer->send_html;
composer->send_html = TRUE;
msg = e_msg_composer_get_message (composer);
composer->send_html = old_send_html;
/* Attach whether this message was written in HTML */
camel_medium_set_header (CAMEL_MEDIUM (msg), "X-Evolution-Format",
composer->send_html ? "text/html" : "text/plain");
/* Attach account info to the draft. */
account = e_msg_composer_get_preferred_account (composer);
if (account && account->name)
camel_medium_set_header (CAMEL_MEDIUM (msg), "X-Evolution-Account", account->name);
return msg;
}
static void static void

View File

@ -75,7 +75,11 @@ struct _EMsgComposer {
Bonobo_ConfigDatabase config_db; Bonobo_ConfigDatabase config_db;
char *charset; char *charset;
char *autosave_file;
int autosave_fd;
guint autosave_id;
gboolean attachment_bar_visible : 1; gboolean attachment_bar_visible : 1;
gboolean send_html : 1; gboolean send_html : 1;
gboolean pgp_sign : 1; gboolean pgp_sign : 1;
@ -122,6 +126,7 @@ void e_msg_composer_add_header (EMsgComposer *compose
void e_msg_composer_attach (EMsgComposer *composer, void e_msg_composer_attach (EMsgComposer *composer,
CamelMimePart *attachment); CamelMimePart *attachment);
CamelMimeMessage *e_msg_composer_get_message (EMsgComposer *composer); CamelMimeMessage *e_msg_composer_get_message (EMsgComposer *composer);
CamelMimeMessage *e_msg_composer_get_message_draft (EMsgComposer *composer);
void e_msg_composer_show_sig_file (EMsgComposer *composer); void e_msg_composer_show_sig_file (EMsgComposer *composer);
gboolean e_msg_composer_get_send_html (EMsgComposer *composer); gboolean e_msg_composer_get_send_html (EMsgComposer *composer);
void e_msg_composer_set_send_html (EMsgComposer *composer, void e_msg_composer_set_send_html (EMsgComposer *composer,