commit b5310390a885631e93978762c3e45a94d33edc0c
Author: Matthew Barnes <mbarnes@redhat.com>
Date:   Tue Jul 14 16:18:59 2009 -0400

    Adapt pepp's patch to current master.

diff --git a/mail/em-format-html-print.c b/mail/em-format-html-print.c
index c5c99bc..76c3feb 100644
--- a/mail/em-format-html-print.c
+++ b/mail/em-format-html-print.c
@@ -42,6 +42,8 @@ efhp_finalize (GObject *o)
 {
 	EMFormatHTMLPrint *efhp = (EMFormatHTMLPrint *)o;
 
+	g_free (efhp->export_filename);
+	efhp->export_filename = NULL;
 	gtk_widget_destroy (efhp->window);
 	if (efhp->source != NULL)
 		g_object_unref (efhp->source);
@@ -72,6 +74,9 @@ efhp_init (GObject *o)
 	gtk_widget_realize (html);
 	efhp->parent.show_icon = FALSE;
 	((EMFormat *)efhp)->print = TRUE;
+
+	efhp->export_filename = NULL;
+	efhp->async = TRUE;
 }
 
 GType
@@ -188,6 +193,9 @@ emfhp_complete (EMFormatHTMLPrint *efhp)
 
 	operation = e_print_operation_new ();
 
+	if (efhp->action == GTK_PRINT_OPERATION_ACTION_EXPORT)
+		gtk_print_operation_set_export_filename (operation, efhp->export_filename);
+
 	gtk_html_print_operation_run (
 		efhp->parent.html, operation, efhp->action, NULL,
 		(GtkHTMLPrintCalcHeight) NULL,
@@ -214,11 +222,16 @@ emfhp_got_message (CamelFolder *folder, const gchar *uid,
 		((EMFormatHTML *)efhp)->load_http =
 			efhp->source->load_http_now;
 
-	g_signal_connect (
-		efhp, "complete", G_CALLBACK (emfhp_complete), efhp);
-	em_format_format_clone (
-		(EMFormat *) efhp, folder, uid, msg,
-		(EMFormat *) efhp->source);
+	if (efhp->async) {
+		g_signal_connect (
+			efhp, "complete", G_CALLBACK (emfhp_complete), efhp);
+		em_format_format_clone (
+			(EMFormat *) efhp, folder, uid, msg,
+			(EMFormat *) efhp->source);
+	} else {
+		em_format_html_clone_sync(folder, uid, msg, (EMFormatHTML *)efhp, (EMFormat *)efhp->source);
+		emfhp_complete(efhp);
+	}
 }
 
 void
diff --git a/mail/em-format-html-print.h b/mail/em-format-html-print.h
index 2abdc82..95135d7 100644
--- a/mail/em-format-html-print.h
+++ b/mail/em-format-html-print.h
@@ -53,6 +53,9 @@ struct _EMFormatHTMLPrint {
 	EMFormatHTML *source; /* used for print_message */
 
 	GtkPrintOperationAction action;
+	gchar *export_filename;
+
+	gboolean async;
 };
 
 struct _EMFormatHTMLPrintClass {
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index d769127..a365544 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -1368,7 +1368,7 @@ static MailMsgInfo efh_format_info = {
 };
 
 static gboolean
-efh_format_timeout(struct _format_msg *m)
+efh_format_helper(struct _format_msg *m, gboolean async)
 {
 	GtkHTMLStream *hstream;
 	EMFormatHTML *efh = m->format;
@@ -1379,10 +1379,12 @@ efh_format_timeout(struct _format_msg *m)
 		return FALSE;
 	}
 
-	d(printf("timeout called ...\n"));
-	if (p->format_id != -1) {
-		d(printf(" still waiting for cancellation to take effect, waiting ...\n"));
-		return TRUE;
+	if (async) {
+		d(printf("timeout called ...\n"));
+		if (p->format_id != -1) {
+			d(printf(" still waiting for cancellation to take effect, waiting ...\n"));
+			return TRUE;
+		}
 	}
 
 	g_return_val_if_fail (e_dlist_empty(&p->pending_jobs), FALSE);
@@ -1429,7 +1431,12 @@ efh_format_timeout(struct _format_msg *m)
 		}
 
 		efh->priv->format_id = m->base.seq;
-		mail_msg_unordered_push (m);
+
+		if (async) {
+			mail_msg_unordered_push (m);
+		} else {
+			efh_format_exec(m);
+		}
 	}
 
 	efh->priv->format_timeout_id = 0;
@@ -1438,6 +1445,34 @@ efh_format_timeout(struct _format_msg *m)
 	return FALSE;
 }
 
+static gboolean
+efh_format_timeout (struct _format_msg *m)
+{
+	return efh_format_helper (m, TRUE);
+}
+
+void
+em_format_html_clone_sync (CamelFolder *folder,
+                           const gchar *uid,
+                           CamelMimeMessage *msg,
+                           EMFormatHTML *efh,
+                           EMFormat *source)
+{
+	struct _format_msg *m;
+
+	m = mail_msg_new (&efh_format_info);
+	m->format = efh;
+	m->format_source = source;
+	m->folder = folder;
+	m->uid = g_strdup (uid);
+	m->message = msg;
+
+	EM_FORMAT (efh)->show_photo = FALSE;
+
+	efh_format_helper (m, FALSE);
+	efh_format_free (m);
+}
+
 static void efh_format_clone(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, EMFormat *emfsource)
 {
 	EMFormatHTML *efh = (EMFormatHTML *)emf;
@@ -2146,3 +2181,4 @@ efh_busy(EMFormat *emf)
 {
 	return (((EMFormatHTML *)emf)->priv->format_id != -1);
 }
+
diff --git a/mail/em-format-html.h b/mail/em-format-html.h
index 81a6811..8146b42 100644
--- a/mail/em-format-html.h
+++ b/mail/em-format-html.h
@@ -268,6 +268,11 @@ EMFormatHTMLJob *
 						 gpointer data);
 void		em_format_html_job_queue	(EMFormatHTML *efh,
 						 EMFormatHTMLJob *job);
+void		em_format_html_clone_sync	(CamelFolder *folder,
+						 const gchar *uid,
+						 CamelMimeMessage *msg,
+						 EMFormatHTML *efh,
+						 EMFormat *source);
 
 G_END_DECLS
 
diff --git a/mail/em-utils.c b/mail/em-utils.c
index b1cc782..38ca322 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -77,6 +77,7 @@
 #include "em-composer-utils.h"
 #include "em-folder-view.h"
 #include "em-format-quote.h"
+#include "em-format-html-print.h"
 #include "em-account-editor.h"
 #include "e-attachment.h"
 #include "e-activity-handler.h"
@@ -85,6 +86,12 @@ static void emu_save_part_done (CamelMimePart *part, gchar *name, gint done, gpo
 
 extern CamelSession *session;
 
+/* drag and drop resulting file naming possibilities */
+enum {
+	DND_USE_SENT_DATE = 1, /* YYYYMMDDhhmmssms_<title> and use email sent date */
+	DND_USE_DND_DATE  = 2,  /*  YYYYMMDDhhmmssms_<title> and drag'drop date */
+};
+
 #define d(x)
 
 /**
@@ -993,6 +1000,30 @@ em_utils_write_messages_to_stream(CamelFolder *folder, GPtrArray *uids, CamelStr
 	return res;
 }
 
+static gboolean
+em_utils_print_messages_to_file (CamelFolder *folder, const gchar * uid, const gchar *filename)
+{
+	EMFormatHTMLPrint *efhp;
+	CamelMimeMessage *message;
+
+	message = camel_folder_get_message(folder, uid, NULL);
+	if (message == NULL)
+		return FALSE;
+
+	efhp = em_format_html_print_new (
+		NULL, GTK_PRINT_OPERATION_ACTION_EXPORT);
+	efhp->export_filename = g_strdup (filename);
+	efhp->async = FALSE;
+	em_format_set_session ((EMFormat *) efhp, session);
+
+	em_format_html_print_raw_message (efhp, message);
+
+	g_object_unref (efhp);
+	camel_object_unref(message);
+
+	return TRUE;
+}
+
 /* This kind of sucks, because for various reasons most callers need to run synchronously
    in the gui thread, however this could take a long, blocking time, to run */
 static gint
@@ -1185,6 +1216,55 @@ em_utils_selection_get_uidlist(GtkSelectionData *data, CamelFolder *dest, gint m
 	em_utils_uids_free(uids);
 }
 
+static gchar *
+em_utils_build_export_filename(CamelFolder *folder, const gchar * uid, const gchar * exporttype, gint exportname, const gchar * tmpdir)
+{
+	CamelMessageInfo *info;
+	gchar *file, *tmpfile;
+	struct tm  *ts;
+	gchar datetmp[15];
+
+	/* Try to get the drop filename from the message or folder */
+	info = camel_folder_get_message_info(folder, uid);
+	if (info) {
+		if (camel_message_info_subject (info)) {
+			time_t reftime;
+			reftime = camel_message_info_date_sent (info);
+			if (exportname==DND_USE_DND_DATE) {
+				reftime = time(NULL);
+			}
+
+			ts = localtime(&reftime);
+			strftime(datetmp, 15, "%Y%m%d%H%M%S", ts);
+
+			if (g_ascii_strcasecmp (exporttype, "pdf")==0)
+				file = g_strdup_printf ("%s_%s.pdf", datetmp, camel_message_info_subject (info));
+			else
+				file = g_strdup_printf ("%s_%s", datetmp, camel_message_info_subject(info));
+
+		}
+		camel_folder_free_message_info(folder, info);
+	} else {
+		time_t reftime;
+		reftime = time(NULL);
+		ts = localtime(&reftime);
+		strftime(datetmp, 15, "%Y%m%d%H%M%S", ts);
+		if (g_ascii_strcasecmp (exporttype, "pdf")==0)
+			file = g_strdup_printf ("%s_Untitled Message.pdf", datetmp);
+		else
+			file = g_strdup_printf ("%s_Untitled Message", datetmp);
+
+	}
+
+	e_filename_make_safe(file);
+
+	tmpfile = g_build_filename(tmpdir, file, NULL);
+
+	g_free(file);
+
+	return tmpfile;
+}
+
 /**
  * em_utils_selection_set_urilist:
  * @data:
@@ -1199,59 +1279,111 @@ void
 em_utils_selection_set_urilist(GtkSelectionData *data, CamelFolder *folder, GPtrArray *uids)
 {
 	gchar *tmpdir;
-	CamelStream *fstream;
-	gchar *uri, *file = NULL, *tmpfile;
+	gchar *uri;
 	gint fd;
-	CamelMessageInfo *info;
+	GConfClient *client;
+	gchar *exporttype;
+	gint exportname;
 
 	tmpdir = e_mkdtemp("drag-n-drop-XXXXXX");
 	if (tmpdir == NULL)
 		return;
 
-	/* Try to get the drop filename from the message or folder */
-	if (uids->len == 1) {
-		info = camel_folder_get_message_info(folder, uids->pdata[0]);
-		if (info) {
-			file = g_strdup(camel_message_info_subject(info));
-			camel_folder_free_message_info(folder, info);
+	client = mail_config_get_gconf_client ();
+	exporttype = gconf_client_get_string (
+		client, "/apps/evolution/mail/save_file_format", NULL);
+	if (exporttype == NULL)
+		exporttype = g_strdup ("mbox");
+	exportname = gconf_client_get_int (
+		client, "/apps/evolution/mail/save_name_format", NULL);
+
+	if (g_ascii_strcasecmp (exporttype, "mbox")==0) {
+		gchar * file = NULL;
+		CamelStream *fstream;
+
+		if(uids->len>1) {
+			gchar * tmp = g_strdup_printf(_("Messages from %s"), folder->name);
+			e_filename_make_safe(tmp);
+			file = g_build_filename(tmpdir, tmp, NULL);
+			g_free(tmp);
+		} else {
+			file = em_utils_build_export_filename(folder, uids->pdata[0], exporttype, exportname, tmpdir);
 		}
-	}
-
-	/* TODO: Handle conflicts? */
-	if (file == NULL) {
-		/* Drop filename for messages from a mailbox */
-		file = g_strdup_printf(_("Messages from %s"), folder->name);
-	}
 
-	e_filename_make_safe(file);
+		g_free(tmpdir);
+		fd = g_open(file, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0666);
+		if (fd == -1) {
+			g_free(file);
+			g_free(exporttype);
+			return;
+		}
 
-	tmpfile = g_build_filename(tmpdir, file, NULL);
-	g_free(tmpdir);
-	g_free(file);
+		uri = g_filename_to_uri(file, NULL, NULL);
+		fstream = camel_stream_fs_new_with_fd(fd);
+		if (fstream) {
+			if (em_utils_write_messages_to_stream(folder, uids, fstream) == 0) {
+				/* terminate with \r\n to be compliant with the spec */
+				gchar *uri_crlf = g_strconcat(uri, "\r\n", NULL);
+				gtk_selection_data_set(data, data->target, 8, (guchar *)uri_crlf, strlen(uri_crlf));
+				g_free(uri_crlf);
+			}
+			camel_object_unref(fstream);
+		} else
+			close(fd);
 
-	fd = g_open(tmpfile, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0666);
-	if (fd == -1) {
-		g_free(tmpfile);
-		return;
-	}
+		g_free(exporttype);
+		g_free(file);
+		g_free(uri);
+	} else if(g_ascii_strcasecmp (exporttype, "pdf")==0) {
+		gchar ** filenames, **uris;
+		gint i, uris_count=0;
+
+		filenames = g_new(gchar *, uids->len);
+		uris = g_new(gchar *, uids->len + 1);
+		for(i=0; i<uids->len; i++) {
+			filenames[i] = em_utils_build_export_filename(folder, uids->pdata[i], exporttype, exportname, tmpdir);
+			/* validity test */
+			fd = g_open(filenames[i], O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0666);
+			if (fd == -1) {
+				gint j;
+				for(j=0; j<=i; j++) {
+					g_free(filenames[j]);
+				}
+				g_free(filenames);
+				g_free(uris);
+				g_free(tmpdir);
+				g_free(exporttype);
+				return;
+			}
+			close(fd);
+
+			/* export */
+			if (em_utils_print_messages_to_file (folder, uids->pdata[i], filenames[i])) {
+				/* terminate with \r\n to be compliant with the spec */
+				uri = g_filename_to_uri(filenames[i], NULL, NULL);
+				uris[uris_count++] = g_strconcat(uri, "\r\n", NULL);
+				g_free(uri);
+			}
+		}
 
-	uri = g_filename_to_uri(tmpfile, NULL, NULL);
-	g_free(tmpfile);
-	fstream = camel_stream_fs_new_with_fd(fd);
-	if (fstream) {
-		if (em_utils_write_messages_to_stream(folder, uids, fstream) == 0) {
-			/* terminate with \r\n to be compliant with the spec */
-			gchar *uri_crlf = g_strconcat(uri, "\r\n", NULL);
+		uris[uris_count] = NULL;
+		gtk_selection_data_set_uris(data, uris);
 
-			gtk_selection_data_set(data, data->target, 8, (guchar *)uri_crlf, strlen(uri_crlf));
-			g_free(uri_crlf);
+		g_free(tmpdir);
+		for(i=0; i<uids->len; i++) {
+			g_free(filenames[i]);
 		}
+		g_free(filenames);
+		for(i=0; i<uris_count; i++) {
+			g_free(uris[i]);
+		}
+		g_free(uris);
+		g_free(exporttype);
 
-		camel_object_unref(fstream);
-	} else
-		close(fd);
-
-	g_free(uri);
+	} else {
+		g_free(tmpdir);
+		g_free(exporttype);
+	}
 }
 
 /**
diff --git a/mail/evolution-mail.schemas.in b/mail/evolution-mail.schemas.in
index fbc23eb..2777f04 100644
--- a/mail/evolution-mail.schemas.in
+++ b/mail/evolution-mail.schemas.in
@@ -1368,6 +1368,38 @@
       </locale>
     </schema>
 
+    <!-- email drag'n'drop settings -->
+
+    <schema>
+      <key>/schemas/apps/evolution/mail/save_file_format</key>
+      <applyto>/apps/evolution/mail/save_file_format</applyto>
+      <owner>evolution-mail</owner>
+      <type>string</type>
+      <default>mbox</default>
+      <locale name="C">
+         <short>Drag'n'drop export format</short>
+         <long>
+           Define the email export format when doing drag'n'drop.
+           Possible values are : mbox or pdf
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/evolution/mail/save_name_format</key>
+      <applyto>/apps/evolution/mail/save_name_format</applyto>
+      <owner>evolution-mail</owner>
+      <type>int</type>
+     <default>1</default>
+      <locale name="C">
+         <short>Format of the drag'n'drop export filename</short>
+         <long>
+           Exported file name will be : YYYmmDDHHMMSS_email_title
+           Possible values : 1 (: email sent date), 2 (: drag'n'drop date)
+         </long>
+      </locale>
+    </schema>
+
     <!-- Others -->
 
     <schema>
