From d8c95a55bc0d7dc465ce11070cd237c8b53c53fa Mon Sep 17 00:00:00 2001 From: Not Zed Date: Sun, 28 Jan 2001 03:53:08 +0000 Subject: Changed to use mail_save_part to save the data in another thread. 2001-01-28 Not Zed * mail-display.c (write_data_to_file): Changed to use mail_save_part to save the data in another thread. (save_data_cb): Hide the fileselector once we have a button press, and are saving stuff. * mail-ops.c (mail_save_part): New function to save a part content asynchronously. svn path=/trunk/; revision=7867 --- mail/ChangeLog | 10 +++++ mail/mail-display.c | 75 +++++++++---------------------------- mail/mail-ops.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++ mail/mail-ops.h | 2 + 4 files changed, 135 insertions(+), 57 deletions(-) diff --git a/mail/ChangeLog b/mail/ChangeLog index c95612464c..148c4ac2bc 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,13 @@ +2001-01-28 Not Zed + + * mail-display.c (write_data_to_file): Changed to use + mail_save_part to save the data in another thread. + (save_data_cb): Hide the fileselector once we have a button press, + and are saving stuff. + + * mail-ops.c (mail_save_part): New function to save a part content + asynchronously. + 2001-01-27 Christopher James Lahey * folder-browser.c (etable_key): Don't handle home and end keys diff --git a/mail/mail-display.c b/mail/mail-display.c index 7d2cff4a8b..fbca3bc8c1 100644 --- a/mail/mail-display.c +++ b/mail/mail-display.c @@ -22,6 +22,9 @@ #include "mail.h" #include "art/empty.xpm" +#include "mail-ops.h" +#include "mail-mt.h" + #include #include #include @@ -55,20 +58,22 @@ struct _PixbufLoader { * Callbacks *----------------------------------------------------------------------*/ +static void +write_data_written(CamelMimePart *part, char *name, int done, void *data) +{ + int *ret = data; + + /* should we popup a dialogue to say its done too? */ + *ret = done; +} + static gboolean write_data_to_file (CamelMimePart *part, const char *name, gboolean unique) { - CamelMimeFilterCharset *charsetfilter; - CamelContentType *content_type; - CamelStreamFilter *filtered_stream; - CamelStream *stream_fs; - CamelDataWrapper *data; - const char *charset; int fd; int ret = FALSE; g_return_val_if_fail (CAMEL_IS_MIME_PART (part), FALSE); - data = camel_medium_get_content_object (CAMEL_MEDIUM (part)); fd = open (name, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); if (fd == -1 && errno == EEXIST && !unique) { @@ -86,58 +91,12 @@ write_data_to_file (CamelMimePart *part, const char *name, gboolean unique) if (gnome_dialog_run_and_close (GNOME_DIALOG (dlg)) != 0) return FALSE; - - fd = open (name, O_WRONLY | O_TRUNC); - } - - if (fd == -1 - || (stream_fs = camel_stream_fs_new_with_fd (fd)) == NULL) { - char *msg; - - msg = g_strdup_printf (_("Could not open file %s:\n%s"), - name, strerror (errno)); - gnome_error_dialog (msg); - g_free (msg); - return FALSE; - } - - - /* we only convert text/ parts, and we only convert if we have to - null charset param == us-ascii == utf8 always, and utf8 == utf8 obviously */ - /* this will also let "us-ascii that isn't really" parts pass out in - proper format, without us trying to treat it as what it isn't, which is - the same algorithm camel uses */ - - content_type = camel_mime_part_get_content_type (part); - if (header_content_type_is(content_type, "text", "*") - && (charset = header_content_type_param (content_type, "charset")) - && strcasecmp(charset, "utf-8") != 0) { - charsetfilter = camel_mime_filter_charset_new_convert ("utf-8", charset); - filtered_stream = camel_stream_filter_new_with_stream (stream_fs); - camel_stream_filter_add (filtered_stream, CAMEL_MIME_FILTER (charsetfilter)); - camel_object_unref (CAMEL_OBJECT (charsetfilter)); - } else { - /* no we can't use a CAMEL_BLAH() cast here, since its not true, HOWEVER - we only treat it as a normal stream from here on, so it is OK */ - filtered_stream = (CamelStreamFilter *)stream_fs; - camel_object_ref (CAMEL_OBJECT (stream_fs)); - } - - if (camel_data_wrapper_write_to_stream (data, CAMEL_STREAM (filtered_stream)) == -1 - || camel_stream_flush (CAMEL_STREAM (filtered_stream)) == -1) { - char *msg; - - msg = g_strdup_printf (_("Could not write data: %s"), - strerror (errno)); - gnome_error_dialog (msg); - g_free (msg); - ret = FALSE; - } else { - ret = TRUE; } + if (fd != -1) + close(fd); - camel_object_unref (CAMEL_OBJECT (filtered_stream)); - camel_object_unref (CAMEL_OBJECT (stream_fs)); + /* should this have progress of what its doing? */ + mail_msg_wait(mail_save_part(part, name, write_data_written, &ret)); return ret; } @@ -173,6 +132,8 @@ save_data_cb (GtkWidget *widget, gpointer user_data) GtkFileSelection *file_select = (GtkFileSelection *) gtk_widget_get_ancestor (widget, GTK_TYPE_FILE_SELECTION); + /* uh, this doesn't really feel right, but i dont know what to do better */ + gtk_widget_hide (GTK_WIDGET (file_select)); write_data_to_file (user_data, gtk_file_selection_get_filename (file_select), FALSE); diff --git a/mail/mail-ops.c b/mail/mail-ops.c index 8be18a34e2..d24c47dd85 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -1927,3 +1927,108 @@ mail_save_messages(CamelFolder *folder, GPtrArray *uids, const char *path, return id; } + +/* ** SAVE PART ******************************************************* */ + +struct _save_part_msg { + struct _mail_msg msg; + + CamelMimePart *part; + char *path; + void (*done)(CamelMimePart *part, char *path, int saved, void *data); + void *data; +}; + +static char *save_part_desc(struct _mail_msg *mm, int done) +{ + return g_strdup(_("Saving attachment")); +} + +static void save_part_save(struct _mail_msg *mm) +{ + struct _save_part_msg *m = (struct _save_part_msg *)mm; + CamelMimeFilterCharset *charsetfilter; + CamelContentType *content_type; + CamelStreamFilter *filtered_stream; + CamelStream *stream_fs; + CamelDataWrapper *data; + const char *charset; + + stream_fs = camel_stream_fs_new_with_name(m->path, O_WRONLY|O_CREAT, 0600); + if (stream_fs == NULL) { + camel_exception_setv(&mm->ex, 1, _("Cannot create output file: %s:\n %s"), m->path, strerror(errno)); + return; + } + + /* we only convert text/ parts, and we only convert if we have to + null charset param == us-ascii == utf8 always, and utf8 == utf8 obviously */ + /* this will also let "us-ascii that isn't really" parts pass out in + proper format, without us trying to treat it as what it isn't, which is + the same algorithm camel uses */ + + data = camel_medium_get_content_object((CamelMedium *)m->part); + content_type = camel_mime_part_get_content_type(m->part); + if (header_content_type_is(content_type, "text", "*") + && (charset = header_content_type_param(content_type, "charset")) + && strcasecmp(charset, "utf-8") != 0) { + charsetfilter = camel_mime_filter_charset_new_convert("utf-8", charset); + filtered_stream = camel_stream_filter_new_with_stream(stream_fs); + camel_stream_filter_add(filtered_stream, CAMEL_MIME_FILTER(charsetfilter)); + camel_object_unref(CAMEL_OBJECT(charsetfilter)); + } else { + /* no we can't use a CAMEL_BLAH() cast here, since its not true, HOWEVER + we only treat it as a normal stream from here on, so it is OK */ + filtered_stream = (CamelStreamFilter *)stream_fs; + camel_object_ref(CAMEL_OBJECT(stream_fs)); + } + + if (camel_data_wrapper_write_to_stream(data, CAMEL_STREAM(filtered_stream)) == -1 + || camel_stream_flush (CAMEL_STREAM(filtered_stream)) == -1) + camel_exception_setv(&mm->ex, 1, _("Could not write data: %s"), strerror(errno)); + + camel_object_unref (CAMEL_OBJECT (filtered_stream)); + camel_object_unref (CAMEL_OBJECT (stream_fs)); +} + +static void save_part_saved(struct _mail_msg *mm) +{ + struct _save_part_msg *m = (struct _save_part_msg *)mm; + + if (m->done) + m->done(m->part, m->path, !camel_exception_is_set(&mm->ex), m->data); +} + +static void save_part_free(struct _mail_msg *mm) +{ + struct _save_part_msg *m = (struct _save_part_msg *)mm; + + camel_object_unref((CamelObject *)m->part); + g_free(m->path); +} + +static struct _mail_msg_op save_part_op = { + save_part_desc, + save_part_save, + save_part_saved, + save_part_free, +}; + +int +mail_save_part(CamelMimePart *part, const char *path, + void (*done)(CamelMimePart *part, char *path, int saved, void *data), void *data) +{ + struct _save_part_msg *m; + int id; + + m = mail_msg_new(&save_part_op, NULL, sizeof(*m)); + m->part = part; + camel_object_ref((CamelObject *)part); + m->path = g_strdup(path); + m->data = data; + m->done = done; + + id = m->msg.seq; + e_thread_put(mail_thread_queued, (EMsg *)m); + + return id; +} diff --git a/mail/mail-ops.h b/mail/mail-ops.h index e39a1a9c41..7b4fe0ec36 100644 --- a/mail/mail-ops.h +++ b/mail/mail-ops.h @@ -78,6 +78,8 @@ void mail_create_folder(const char *uri, /* save messages */ int mail_save_messages(CamelFolder *folder, GPtrArray *uids, const char *path, void (*done) (CamelFolder *folder, GPtrArray *uids, char *path, void *data), void *data); +int mail_save_part(CamelMimePart *part, const char *path, + void (*done)(CamelMimePart *part, char *path, int saved, void *data), void *data); int mail_send_mail(const char *uri, CamelMimeMessage *message, void (*done) (char *uri, CamelMimeMessage *message, gboolean sent, void *data), void *data); -- cgit v1.2.3