aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpepp <pelloux@gmail.com>2011-12-15 14:53:52 +0800
committerChenthill Palanisamy <pchenthill@novell.com>2011-12-15 15:18:26 +0800
commitd300de403de5b9b2d3c2c2f9d371f59859eeaf8c (patch)
tree508e5bc436b5d14369aaf4d9a741ff201eaeb165
parentbe607ffe63925ccaa70c33c8f7766c6bf65ad80a (diff)
downloadgsoc2013-evolution-d300de403de5b9b2d3c2c2f9d371f59859eeaf8c.tar.gz
gsoc2013-evolution-d300de403de5b9b2d3c2c2f9d371f59859eeaf8c.tar.zst
gsoc2013-evolution-d300de403de5b9b2d3c2c2f9d371f59859eeaf8c.zip
Bug 566793 - Support Drop And Drag Into Nautilus As PDF File
-rw-r--r--mail/em-format-html-print.c28
-rw-r--r--mail/em-format-html-print.h3
-rw-r--r--mail/em-format-html.c46
-rw-r--r--mail/em-format-html.h6
-rw-r--r--mail/em-utils.c252
-rw-r--r--mail/evolution-mail.schemas.in32
6 files changed, 293 insertions, 74 deletions
diff --git a/mail/em-format-html-print.c b/mail/em-format-html-print.c
index fd47275e30..d1e7dfb752 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 c33669651d..5f08b6ef82 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 960cdc1267..55f7aa9841 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 1efd7d0be6..7ded2e82f9 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 bfda4056be..96f912a153 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 f7c3844b8a..79d9c59d9e 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>