diff options
-rw-r--r-- | mail/ChangeLog | 25 | ||||
-rw-r--r-- | mail/folder-browser-factory.c | 2 | ||||
-rw-r--r-- | mail/folder-browser.c | 4 | ||||
-rw-r--r-- | mail/mail-callbacks.c | 37 | ||||
-rw-r--r-- | mail/mail-callbacks.h | 2 | ||||
-rw-r--r-- | mail/mail-ops.c | 342 | ||||
-rw-r--r-- | mail/mail-ops.h | 5 | ||||
-rw-r--r-- | mail/mail-view.c | 2 |
8 files changed, 343 insertions, 76 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index cf75d8b921..03b9784f45 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,28 @@ +2000-11-15 Jeffrey Stedfast <fejj@helixcode.com> + + * folder-browser-factory.c: Added a new Forward as Attachment + bonobo menu item verb. + + * mail-view.c (view_forward_msg): Updated to reflect changes to + mail_do_forward_message(). It now forwards the message without + attaching it - is this what we want? + + * mail-ops.c (mail_do_view_message_sources): New async function to + display message source dialog windows. + (setup_forward_messages): If we were asked not to forward the + message(s) as attachment(s) and the user chose more than a single + message, then default to making each message an attachment. + (cleanup_forward_messages): If we aren't forwarding the message as + an attachment, then quote the text and set the composer's body + with it. + + * mail-callbacks.c (view_source): New callback to view the message + source of all messages that are currently selected. + (forward_attach): New callback to forward a message as an + attachment (forward_msg is now for forwarding a message without it + being an attachment). + (forward_message): Convenience function for forwarding messages. + 2000-11-13 Jeffrey Stedfast <fejj@helixcode.com> * subscribe-dialog.c (subscribe_do_subscribe_folder): Take a diff --git a/mail/folder-browser-factory.c b/mail/folder-browser-factory.c index 71a57b8d9b..d500c1cfb5 100644 --- a/mail/folder-browser-factory.c +++ b/mail/folder-browser-factory.c @@ -58,7 +58,7 @@ BonoboUIVerb verbs [] = { BONOBO_UI_UNSAFE_VERB ("MessageReplySndr", reply_to_sender), BONOBO_UI_UNSAFE_VERB ("MessageReplyAll", reply_to_all), BONOBO_UI_UNSAFE_VERB ("MessageForward", forward_msg), - /*BONOBO_UI_UNSAFE_VERB ("MessageForwardAttach", forward_msg),*/ + BONOBO_UI_UNSAFE_VERB ("MessageForwardAttach", forward_attach), BONOBO_UI_UNSAFE_VERB ("MessageMarkAsRead", mark_as_seen), BONOBO_UI_UNSAFE_VERB ("MessageMarkAsUnRead", mark_as_unseen), diff --git a/mail/folder-browser.c b/mail/folder-browser.c index d8989cdbeb..f6c1b94963 100644 --- a/mail/folder-browser.c +++ b/mail/folder-browser.c @@ -466,7 +466,7 @@ on_right_click (ETableScrolled *table, gint row, gint col, GdkEvent *event, Fold { _("Reply to Sender"), NULL, GTK_SIGNAL_FUNC (reply_to_sender), NULL, 0 }, { _("Reply to All"), NULL, GTK_SIGNAL_FUNC (reply_to_all), NULL, 0 }, { _("Forward"), NULL, GTK_SIGNAL_FUNC (forward_msg), NULL, 0 }, - /*{ _("Forward as Attachment"), NULL, GTK_SIGNAL_FUNC (forward_msg), NULL, 0 },*/ + { _("Forward as Attachment"), NULL, GTK_SIGNAL_FUNC (forward_attach), NULL, 0 }, { "", NULL, GTK_SIGNAL_FUNC (NULL), NULL, 0 }, { _("Mark as Read"), NULL, GTK_SIGNAL_FUNC (mark_as_seen), NULL, 4 }, { _("Mark as Unread"), NULL, GTK_SIGNAL_FUNC (mark_as_unseen), NULL, 8 }, @@ -481,6 +481,8 @@ on_right_click (ETableScrolled *table, gint row, gint col, GdkEvent *event, Fold { _("Apply Filters"), NULL, GTK_SIGNAL_FUNC (apply_filters), NULL, 0 }, { "", NULL, GTK_SIGNAL_FUNC (NULL), NULL, 0 }, { _("Create Rule From Message"), NULL, GTK_SIGNAL_FUNC (NULL), filter_menu, 2 }, + { "", NULL, GTK_SIGNAL_FUNC (NULL), NULL, 0 }, + { _("View Message Source"), NULL, GTK_SIGNAL_FUNC (view_source), NULL, 0 }, { NULL, NULL, NULL, NULL, 0 } }; diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c index 6581463c88..8286735f5b 100644 --- a/mail/mail-callbacks.c +++ b/mail/mail-callbacks.c @@ -483,11 +483,9 @@ enumerate_msg (MessageList *ml, const char *uid, gpointer data) g_ptr_array_add ((GPtrArray *) data, g_strdup (uid)); } - -void -forward_msg (GtkWidget *widget, gpointer user_data) +static void +forward_message (FolderBrowser *fb, gboolean attach) { - FolderBrowser *fb = FOLDER_BROWSER (user_data); EMsgComposer *composer; CamelMimeMessage *cursor_msg; GPtrArray *uids; @@ -510,8 +508,19 @@ forward_msg (GtkWidget *widget, gpointer user_data) mail_do_forward_message (cursor_msg, fb->message_list->folder, - uids, - composer); + uids, composer, attach); +} + +void +forward_msg (GtkWidget *widget, gpointer user_data) +{ + forward_message (FOLDER_BROWSER (user_data), FALSE); +} + +void +forward_attach (GtkWidget *widget, gpointer user_data) +{ + forward_message (FOLDER_BROWSER (user_data), TRUE); } static void @@ -912,7 +921,7 @@ manage_subscriptions (BonoboUIComponent *uih, void *user_data, const char *path) } void -configure_folder(BonoboUIComponent *uih, void *user_data, const char *path) +configure_folder (BonoboUIComponent *uih, void *user_data, const char *path) { FolderBrowser *fb = FOLDER_BROWSER(user_data); @@ -920,6 +929,20 @@ configure_folder(BonoboUIComponent *uih, void *user_data, const char *path) } void +view_source (GtkWidget *widget, gpointer user_data) +{ + FolderBrowser *fb = user_data; + GPtrArray *uids; + + if (!fb->folder) + return; + + uids = g_ptr_array_new (); + message_list_foreach (fb->message_list, enumerate_msg, uids); + mail_do_view_message_sources (fb->folder, uids, fb); +} + +void view_msg (GtkWidget *widget, gpointer user_data) { FolderBrowser *fb = user_data; diff --git a/mail/mail-callbacks.h b/mail/mail-callbacks.h index 7995581be2..23e7f13d75 100644 --- a/mail/mail-callbacks.h +++ b/mail/mail-callbacks.h @@ -42,6 +42,7 @@ void send_receieve_mail (GtkWidget *widget, gpointer user_data); void compose_msg (GtkWidget *widget, gpointer user_data); void send_to_url (const char *url); void forward_msg (GtkWidget *widget, gpointer user_data); +void forward_attach (GtkWidget *widget, gpointer user_data); void reply_to_sender (GtkWidget *widget, gpointer user_data); void reply_to_all (GtkWidget *widget, gpointer user_data); void delete_msg (GtkWidget *widget, gpointer user_data); @@ -53,6 +54,7 @@ void print_msg (GtkWidget *widget, gpointer user_data); void print_preview_msg (GtkWidget *widget, gpointer user_data); void edit_msg (GtkWidget *widget, gpointer user_data); void view_msg (GtkWidget *widget, gpointer user_data); +void view_source (GtkWidget *widget, gpointer user_data); void select_all (BonoboUIComponent *uih, void *user_data, const char *path); void invert_selection (BonoboUIComponent *uih, void *user_data, const char *path); diff --git a/mail/mail-ops.c b/mail/mail-ops.c index 891bbacf1f..5b60be09f8 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -34,6 +34,7 @@ #include "mail-ops.h" #include "composer/e-msg-composer.h" #include "folder-browser.h" +#include "e-util/e-html-utils.h" /* ** FETCH MAIL ********************************************************** */ @@ -1475,21 +1476,18 @@ mail_do_attach_message (CamelFolder *folder, const char *uid, /* ** FORWARD MESSAGES **************************************************** */ -typedef struct forward_messages_input_s -{ +typedef struct forward_messages_input_s { CamelMimeMessage *basis; CamelFolder *source; GPtrArray *uids; EMsgComposer *composer; -} -forward_messages_input_t; + gboolean attach; +} forward_messages_input_t; -typedef struct forward_messages_data_s -{ +typedef struct forward_messages_data_s { gchar *subject; GPtrArray *parts; -} -forward_messages_data_t; +} forward_messages_data_t; static gchar * describe_forward_messages (gpointer in_data, gboolean gerund) @@ -1501,16 +1499,14 @@ describe_forward_messages (gpointer in_data, gboolean gerund) return g_strdup_printf (_("Forwarding messages \"%s\""), input->basis->subject); else - return - g_strdup_printf + return g_strdup_printf (_("Forwarding a message without a subject")); } else { if (input->basis->subject) return g_strdup_printf (_("Forward message \"%s\""), input->basis->subject); else - return - g_strdup_printf + return g_strdup_printf (_("Forward a message without a subject")); } } @@ -1520,7 +1516,14 @@ setup_forward_messages (gpointer in_data, gpointer op_data, CamelException *ex) { forward_messages_input_t *input = (forward_messages_input_t *) in_data; - + + if (!input->attach && input->uids->len > 1) { + /* Hmmm, this behavior is undefined so lets default + back to forwarding each message as an attachment. */ + + input->attach = TRUE; + } + camel_object_ref (CAMEL_OBJECT (input->basis)); camel_object_ref (CAMEL_OBJECT (input->source)); gtk_object_ref (GTK_OBJECT (input->composer)); @@ -1531,51 +1534,65 @@ do_forward_messages (gpointer in_data, gpointer op_data, CamelException *ex) { forward_messages_input_t *input = (forward_messages_input_t *) in_data; forward_messages_data_t *data = (forward_messages_data_t *) op_data; - time_t last_update = 0; CamelMimeMessage *message; - CamelMimePart *part; - int i; - + data->parts = g_ptr_array_new (); - + mail_tool_camel_lock_up (); - for (i = 0; i < input->uids->len; i++) { - const int last_message = (i+1 == input->uids->len); - time_t now; - - /* - * Update the time display ever 2 seconds - */ - time (&now); - if (last_message || ((now - last_update) > 2)){ - mail_op_set_message (_("Retrieving message number %d of %d (uid \"%s\")"), - i + 1, input->uids->len, (char *) input->uids->pdata[i]); - last_update = now; - } - + + if (input->attach) { + CamelMimePart *part; + time_t last_update = 0; + int i; - message = - camel_folder_get_message (input->source, - input->uids->pdata[i], ex); - g_free (input->uids->pdata[i]); - if (!message) { - mail_tool_camel_lock_down (); - return; + for (i = 0; i < input->uids->len; i++) { + const int last_message = (i+1 == input->uids->len); + time_t now; + + /* + * Update the time display every 2 seconds + */ + time (&now); + if (last_message || ((now - last_update) > 2)){ + mail_op_set_message (_("Retrieving message number %d of %d (uid \"%s\")"), + i + 1, input->uids->len, (char *) input->uids->pdata[i]); + last_update = now; + } + + message = camel_folder_get_message (input->source, + input->uids->pdata[i], ex); + g_free (input->uids->pdata[i]); + if (!message) { + mail_tool_camel_lock_down (); + return; + } + + part = mail_tool_make_message_attachment (message); + if (!part) { + camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, + _("Failed to generate mime part from " + "message while generating forwarded message.")); + mail_tool_camel_lock_down (); + return; + } + + camel_object_unref (CAMEL_OBJECT (message)); + g_ptr_array_add (data->parts, part); } - part = mail_tool_make_message_attachment (message); - if (!part) { - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("Failed to generate mime part from " - "message while generating forwarded message.")); + } else { + message = camel_folder_get_message (input->source, + input->uids->pdata[0], ex); + g_free (input->uids->pdata[0]); + if (!message) { mail_tool_camel_lock_down (); return; } - camel_object_unref (CAMEL_OBJECT (message)); - g_ptr_array_add (data->parts, part); + + g_ptr_array_add (data->parts, message); } - + mail_tool_camel_lock_down (); - + data->subject = mail_tool_generate_forward_subject (input->basis); } @@ -1583,23 +1600,85 @@ static void cleanup_forward_messages (gpointer in_data, gpointer op_data, CamelException *ex) { - forward_messages_input_t *input = - - (forward_messages_input_t *) in_data; + forward_messages_input_t *input = (forward_messages_input_t *) in_data; forward_messages_data_t *data = (forward_messages_data_t *) op_data; - - int i; - - for (i = 0; i < data->parts->len; i++) { - e_msg_composer_attach (input->composer, - data->parts->pdata[i]); - camel_object_unref (CAMEL_OBJECT (data->parts->pdata[i])); + + if (input->attach) { + int i; + + for (i = 0; i < data->parts->len; i++) { + e_msg_composer_attach (input->composer, data->parts->pdata[i]); + camel_object_unref (CAMEL_OBJECT (data->parts->pdata[i])); + } + } else { + CamelMimeMessage *message = data->parts->pdata[0]; + CamelDataWrapper *contents; + gboolean want_plain, is_html; + char *text; + + want_plain = !mail_config_send_html (); + contents = camel_medium_get_content_object (CAMEL_MEDIUM (message)); + text = mail_get_message_body (contents, want_plain, &is_html); + + /* FIXME: we should share this code with Reply */ + + /* Set the quoted reply text. */ + if (text) { + char *repl_text; + + if (is_html) { + repl_text = g_strdup_printf ("<blockquote><i>\n%s\n" + "</i></blockquote>\n", + text); + } else { + char *s, *d, *quoted_text; + int lines, len; + + /* Count the number of lines in the body. If + * the text ends with a \n, this will be one + * too high, but that's ok. Allocate enough + * space for the text and the "> "s. + */ + for (s = text, lines = 0; s; s = strchr (s + 1, '\n')) + lines++; + quoted_text = g_malloc (strlen (text) + lines * 2); + + s = text; + d = quoted_text; + + /* Copy text to quoted_text line by line, + * prepending "> ". + */ + while (1) { + len = strcspn (s, "\n"); + if (len == 0 && !*s) + break; + sprintf (d, "> %.*s\n", len, s); + s += len; + if (!*s++) + break; + d += len + 3; + } + *d = '\0'; + + /* Now convert that to HTML. */ + repl_text = e_text_to_html (quoted_text, E_TEXT_TO_HTML_PRE); + g_free (quoted_text); + } + + e_msg_composer_set_body_text (input->composer, repl_text); + g_free (repl_text); + g_free (text); + } + + camel_object_unref (CAMEL_OBJECT (message)); } + camel_object_unref (CAMEL_OBJECT (input->source)); - + e_msg_composer_set_headers (input->composer, NULL, NULL, NULL, data->subject); - + gtk_object_unref (GTK_OBJECT (input->composer)); g_free (data->subject); g_ptr_array_free (data->parts, TRUE); @@ -1618,21 +1697,24 @@ static const mail_operation_spec op_forward_messages = { void mail_do_forward_message (CamelMimeMessage *basis, CamelFolder *source, - GPtrArray *uids, EMsgComposer *composer) + GPtrArray *uids, + EMsgComposer *composer, + gboolean attach) { forward_messages_input_t *input; - + g_return_if_fail (CAMEL_IS_MIME_MESSAGE (basis)); g_return_if_fail (CAMEL_IS_FOLDER (source)); g_return_if_fail (uids != NULL); g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - + input = g_new (forward_messages_input_t, 1); input->basis = basis; input->source = source; input->uids = uids; input->composer = composer; - + input->attach = attach; + mail_operation_queue (&op_forward_messages, input, TRUE); } @@ -2314,3 +2396,135 @@ mail_do_view_messages (CamelFolder *folder, GPtrArray *uids, mail_operation_queue (&op_view_messages, input, TRUE); } + +/* ** VIEW MESSAGE SOURCE ******************************************************* */ + +typedef struct view_message_sources_input_s { + CamelFolder *folder; + GPtrArray *uids; + FolderBrowser *fb; +} view_message_sources_input_t; + +typedef struct view_message_sources_data_s { + GPtrArray *messages; +} view_message_sources_data_t; + +static gchar * +describe_view_message_sources (gpointer in_data, gboolean gerund) +{ + view_message_sources_input_t *input = (view_message_sources_input_t *) in_data; + + if (gerund) + return g_strdup_printf + (_("Viewing message sources from folder \"%s\""), + mail_tool_get_folder_name (input->folder)); + else + return g_strdup_printf (_("View message sources from \"%s\""), + mail_tool_get_folder_name (input->folder)); +} + +static void +setup_view_message_sources (gpointer in_data, gpointer op_data, CamelException *ex) +{ + view_message_sources_input_t *input = (view_message_sources_input_t *) in_data; + + camel_object_ref (CAMEL_OBJECT (input->folder)); + gtk_object_ref (GTK_OBJECT (input->fb)); +} + +static void +do_view_message_sources (gpointer in_data, gpointer op_data, CamelException *ex) +{ + view_message_sources_input_t *input = (view_message_sources_input_t *) in_data; + view_message_sources_data_t *data = (view_message_sources_data_t *) op_data; + int i; + + data->messages = g_ptr_array_new (); + + for (i = 0; i < input->uids->len; i++) { + CamelMimeMessage *message; + + mail_op_set_message (_("Retrieving message %d of %d (uid \"%s\")"), + i + 1, input->uids->len, (char *)input->uids->pdata[i]); + + mail_tool_camel_lock_up (); + message = camel_folder_get_message (input->folder, input->uids->pdata[i], ex); + mail_tool_camel_lock_down (); + + g_ptr_array_add (data->messages, message); + } +} + +static void +cleanup_view_message_sources (gpointer in_data, gpointer op_data, + CamelException *ex) +{ + view_message_sources_input_t *input = (view_message_sources_input_t *) in_data; + view_message_sources_data_t *data = (view_message_sources_data_t *) op_data; + int i; + + for (i = 0; i < data->messages->len; i++) { + CamelMimeMessage *msg; + CamelStream *stream; + GtkWidget *dialog; + GtkWidget *source; + + if (data->messages->pdata[i] == NULL) + continue; + + msg = data->messages->pdata[i]; + + stream = camel_stream_mem_new (); + camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (msg), stream); + + dialog = gnome_dialog_new (camel_mime_message_get_subject (msg), GNOME_STOCK_BUTTON_OK, NULL); + gtk_window_set_policy (GTK_WINDOW (dialog), FALSE, TRUE, FALSE); + source = gtk_text_new (NULL, NULL); + gtk_text_set_editable (GTK_TEXT (source), FALSE); + gtk_text_freeze (GTK_TEXT (source)); + gtk_text_insert (GTK_TEXT (source), NULL, NULL, NULL, + CAMEL_STREAM_MEM (stream)->buffer->data, + CAMEL_STREAM_MEM (stream)->buffer->len); + gtk_text_thaw (GTK_TEXT (source)); + gtk_widget_show (source); + gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), source, TRUE, TRUE, 0); + + /* FIXME: this blocks, we should probably not use a run_and_close */ + gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); + + camel_object_unref (CAMEL_OBJECT (stream)); + camel_object_unref (CAMEL_OBJECT (data->messages->pdata[i])); + g_free (input->uids->pdata[i]); + } + + g_ptr_array_free (input->uids, TRUE); + g_ptr_array_free (data->messages, TRUE); + camel_object_unref (CAMEL_OBJECT (input->folder)); + gtk_object_unref (GTK_OBJECT (input->fb)); +} + +static const mail_operation_spec op_view_message_sources = { + describe_view_message_sources, + sizeof (view_message_sources_data_t), + setup_view_message_sources, + do_view_message_sources, + cleanup_view_message_sources +}; + +void +mail_do_view_message_sources (CamelFolder *folder, GPtrArray *uids, + FolderBrowser *fb) +{ + view_message_sources_input_t *input; + + g_return_if_fail (CAMEL_IS_FOLDER (folder)); + g_return_if_fail (uids != NULL); + g_return_if_fail (IS_FOLDER_BROWSER (fb)); + + input = g_new (view_message_sources_input_t, 1); + input->folder = folder; + input->uids = uids; + input->fb = fb; + + mail_operation_queue (&op_view_message_sources, input, TRUE); +} diff --git a/mail/mail-ops.h b/mail/mail-ops.h index 262cfcfc18..0209d10529 100644 --- a/mail/mail-ops.h +++ b/mail/mail-ops.h @@ -59,7 +59,7 @@ void mail_do_attach_message (CamelFolder *folder, const char *uid, EMsgComposer *composer); void mail_do_forward_message (CamelMimeMessage *basis, CamelFolder *source, GPtrArray *uids, /*array of allocated gchar *, will all be freed */ - EMsgComposer *composer); + EMsgComposer *composer, gboolean attach); void mail_do_load_folder (FolderBrowser *fb, const char *url); void mail_do_create_folder (const GNOME_Evolution_ShellComponentListener listener, const char *uri, const char *type); @@ -71,4 +71,5 @@ void mail_do_edit_messages (CamelFolder *folder, GPtrArray *uids, void mail_do_setup_folder (const char *name, CamelFolder **folder); void mail_do_view_messages (CamelFolder *folder, GPtrArray *uids, FolderBrowser *fb); - +void mail_do_view_message_sources (CamelFolder *folder, GPtrArray *uids, + FolderBrowser *fb); diff --git a/mail/mail-view.c b/mail/mail-view.c index 2d95fb4f24..54ec02de32 100644 --- a/mail/mail-view.c +++ b/mail/mail-view.c @@ -114,7 +114,7 @@ view_forward_msg (GtkWidget *widget, gpointer user_data) gtk_signal_connect (GTK_OBJECT (composer), "send", GTK_SIGNAL_FUNC (composer_send_cb), NULL); - mail_do_forward_message (data->msg, data->source, uids, composer); + mail_do_forward_message (data->msg, data->source, uids, composer, FALSE); } static void |