[evolution] Bug 566793 - Support Drop And Drag Into Nautilus As PDF File



commit d300de403de5b9b2d3c2c2f9d371f59859eeaf8c
Author: pepp <pelloux gmail com>
Date:   Thu Dec 15 12:23:52 2011 +0530

    Bug 566793 - Support Drop And Drag Into Nautilus As PDF File

 mail/em-format-html-print.c    |   28 ++++-
 mail/em-format-html-print.h    |    3 +
 mail/em-format-html.c          |   46 +++++++-
 mail/em-format-html.h          |    6 +
 mail/em-utils.c                |  252 ++++++++++++++++++++++++++++++----------
 mail/evolution-mail.schemas.in |   32 +++++
 6 files changed, 293 insertions(+), 74 deletions(-)
---
diff --git a/mail/em-format-html-print.c b/mail/em-format-html-print.c
index fd47275..d1e7dfb 100644
--- a/mail/em-format-html-print.c
+++ b/mail/em-format-html-print.c
@@ -45,6 +45,8 @@ efhp_finalize (GObject *object)
 {
 	EMFormatHTMLPrint *efhp = (EMFormatHTMLPrint *) object;
 
+	g_free (efhp->export_filename);
+	efhp->export_filename = NULL;
 	gtk_widget_destroy (efhp->window);
 	if (efhp->source != NULL)
 		g_object_unref (efhp->source);
@@ -90,6 +92,9 @@ em_format_html_print_init (EMFormatHTMLPrint *efhp)
 	gtk_widget_realize (GTK_WIDGET (web_view));
 	efhp->parent.show_icon = FALSE;
 	((EMFormat *) efhp)->print = TRUE;
+
+	efhp->export_filename = NULL;
+	efhp->async = TRUE;
 }
 
 EMFormatHTMLPrint *
@@ -184,6 +189,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 (
 		GTK_HTML (web_view),
 		operation, efhp->action, NULL,
@@ -213,12 +221,18 @@ em_format_html_print_message (EMFormatHTMLPrint *efhp,
 
 	em_format_html_load_images (EM_FORMAT_HTML (efhp));
 
-	g_signal_connect (
-		efhp, "complete", G_CALLBACK (emfhp_complete), efhp);
 
-	/* FIXME Not passing a GCancellable here. */
-	em_format_format_clone (
-		EM_FORMAT (efhp),
-		folder, message_uid, message,
-		EM_FORMAT (efhp->source), NULL);
+	if (efhp->async) {
+		g_signal_connect (
+			efhp, "complete", G_CALLBACK (emfhp_complete), efhp);
+		
+		/* FIXME Not passing a GCancellable here. */
+		em_format_format_clone (
+			(EMFormat *) efhp, 
+			folder, message_uid, message,
+			(EMFormat *) efhp->source, NULL);
+	} else {
+		em_format_html_clone_sync (folder, message_uid, message, (EMFormatHTML *)efhp, (EMFormat *)efhp->source);
+		emfhp_complete (efhp);
+	}
 }
diff --git a/mail/em-format-html-print.h b/mail/em-format-html-print.h
index c336696..5f08b6e 100644
--- a/mail/em-format-html-print.h
+++ b/mail/em-format-html-print.h
@@ -56,6 +56,9 @@ struct _EMFormatHTMLPrint {
 	EMFormatHTML *source;
 
 	GtkPrintOperationAction action;
+	gchar *export_filename;
+
+	gboolean async;
 };
 
 struct _EMFormatHTMLPrintClass {
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index 960cdc1..55f7aa9 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -329,7 +329,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;
@@ -343,10 +343,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 (g_queue_is_empty (&p->pending_jobs), FALSE);
@@ -400,7 +402,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, NULL, NULL);
+		}
 	}
 
 	efh->priv->format_timeout_id = 0;
@@ -666,6 +673,32 @@ efh_finalize (GObject *object)
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+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;
+
+	efh_format_helper (m, FALSE);
+	efh_format_free (m);
+}
+
 static void
 efh_format_clone (EMFormat *emf,
                   CamelFolder *folder,
@@ -3399,3 +3432,4 @@ em_format_html_get_cached_image (EMFormatHTML *efh,
 	return camel_data_cache_get (
 		emfh_http_cache, EMFH_HTTP_CACHE_PATH, image_uri, NULL);
 }
+
diff --git a/mail/em-format-html.h b/mail/em-format-html.h
index 1efd7d0..7ded2e8 100644
--- a/mail/em-format-html.h
+++ b/mail/em-format-html.h
@@ -291,6 +291,12 @@ EMFormatHTMLJob *
 						 gpointer data);
 void		em_format_html_job_queue	(EMFormatHTML *efh,
 						 EMFormatHTMLJob *job);
+void		em_format_html_clone_sync	(CamelFolder *folder,
+						 const gchar *message_uid,
+						 CamelMimeMessage *message,
+						 EMFormatHTML *efh,
+						 EMFormat *source);
+
 gboolean	em_format_html_get_show_real_date
 						(EMFormatHTML *efh);
 void		em_format_html_set_show_real_date
diff --git a/mail/em-utils.c b/mail/em-utils.c
index bfda405..96f912a 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -70,6 +70,7 @@
 #include "em-utils.h"
 #include "em-composer-utils.h"
 #include "em-format-quote.h"
+#include "em-format-html-print.h"
 #include "e-mail-folder-utils.h"
 #include "e-mail-session.h"
 
@@ -81,6 +82,12 @@ extern const gchar *shell_builtin_backend;
 /* Used in em_util_ask_open_many() */
 #define TOO_MANY 10
 
+/* 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)
 
 gboolean
@@ -603,6 +610,30 @@ em_utils_write_messages_to_stream (CamelFolder *folder,
 	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_sync (folder, uid, NULL, 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_html_print_message (efhp, message, folder, uid);
+
+	g_object_unref (efhp);
+	g_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. */
@@ -846,6 +877,59 @@ em_utils_selection_get_uidlist (GtkSelectionData *selection_data,
 	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:
@@ -861,69 +945,115 @@ em_utils_selection_set_urilist (GtkSelectionData *data,
                                 CamelFolder *folder,
                                 GPtrArray *uids)
 {
-	gchar *tmpdir;
-	CamelStream *fstream;
-	gchar *uri, *file = NULL, *tmpfile;
-	gint fd;
-	CamelMessageInfo *info;
-
-	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) {
-		const gchar *message_uid;
-
-		message_uid = g_ptr_array_index (uids, 0);
-		info = camel_folder_get_message_info (folder, message_uid);
-		if (info) {
-			file = g_strdup (camel_message_info_subject (info));
-			camel_folder_free_message_info (folder, info);
+ 	gchar *tmpdir;
+	gchar *uri;
+ 	gint fd;
+	GConfClient *client;
+	gchar *exporttype;
+	gint exportname;
+ 
+ 	tmpdir = e_mkdtemp("drag-n-drop-XXXXXX");
+ 	if (tmpdir == NULL)
+ 		return;
+ 
+	client = gconf_client_get_default ();
+	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"), camel_folder_get_display_name (folder));
+			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);
+ 		}
+		
+		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;
+ 		}
+ 
+		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) {
+				GdkAtom type;
+				/* terminate with \r\n to be compliant with the spec */
+				gchar *uri_crlf = g_strconcat(uri, "\r\n", NULL);
+
+				type = gtk_selection_data_get_target (data);
+				gtk_selection_data_set(data, type, 8, (guchar *) uri_crlf, strlen(uri_crlf));
+				g_free(uri_crlf);
+			}
+			g_object_unref (fstream);
+		} else
+			close(fd);
+ 
+		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);
+			}
+ 		}
+ 
+		uris[uris_count] = NULL;
+		gtk_selection_data_set_uris(data, uris);
+ 
+		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);
+ 
+	} else {
+		g_free(tmpdir);
+		g_free(exporttype);
 	}
-
-	/* TODO: Handle conflicts? */
-	if (file == NULL) {
-		/* Drop filename for messages from a mailbox */
-		file = g_strdup_printf (
-			_("Messages from %s"),
-			camel_folder_get_display_name (folder));
-	}
-
-	e_filename_make_safe (file);
-
-	tmpfile = g_build_filename (tmpdir, file, NULL);
-	g_free (tmpdir);
-	g_free (file);
-
-	fd = g_open (tmpfile, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0666);
-	if (fd == -1) {
-		g_free (tmpfile);
-		return;
-	}
-
-	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);
-			GdkAtom target;
-
-			target = gtk_selection_data_get_target (data);
-			gtk_selection_data_set (
-				data, target, 8, (guchar *)
-				uri_crlf, strlen (uri_crlf));
-			g_free (uri_crlf);
-		}
-
-		g_object_unref (fstream);
-	} else
-		close (fd);
-
-	g_free (uri);
 }
 
 /**
diff --git a/mail/evolution-mail.schemas.in b/mail/evolution-mail.schemas.in
index f7c3844..79d9c59 100644
--- a/mail/evolution-mail.schemas.in
+++ b/mail/evolution-mail.schemas.in
@@ -1775,6 +1775,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>



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