balsa r7926 - in trunk: . libbalsa src



Author: PeterB
Date: Sun May 25 19:55:07 2008
New Revision: 7926
URL: http://svn.gnome.org/viewvc/balsa?rev=7926&view=rev

Log:
option to create both text/plain and text/html versions, for the benefit of right-to-left languages

Modified:
   trunk/ChangeLog
   trunk/libbalsa/body.c
   trunk/libbalsa/body.h
   trunk/libbalsa/identity.c
   trunk/libbalsa/identity.h
   trunk/libbalsa/mime.c
   trunk/libbalsa/misc.h
   trunk/libbalsa/send.c
   trunk/src/sendmsg-window.c
   trunk/src/sendmsg-window.h

Modified: trunk/libbalsa/body.c
==============================================================================
--- trunk/libbalsa/body.c	(original)
+++ trunk/libbalsa/body.c	Sun May 25 19:55:07 2008
@@ -43,6 +43,7 @@
 
     body->message = message;
     body->buffer = NULL;
+    body->html_buffer = NULL;
     body->embhdrs = NULL;
     body->content_type = NULL;
     body->filename = NULL;
@@ -71,6 +72,7 @@
 	return;
 
     g_free(body->buffer);
+    g_free(body->html_buffer);
     libbalsa_message_headers_destroy(body->embhdrs);
     g_free(body->content_type);
     g_free(body->filename);

Modified: trunk/libbalsa/body.h
==============================================================================
--- trunk/libbalsa/body.h	(original)
+++ trunk/libbalsa/body.h	Sun May 25 19:55:07 2008
@@ -65,6 +65,7 @@
     LibBalsaMessage *message;	/* The message of which this is a part */
     /* FIXME: remove buffer and buf_len to decrease memory usage. */
     gchar *buffer;		/* holds raw data of the MIME part, or NULL */
+    gchar *html_buffer;         /* holds the html representation of the part or NULL */
     ssize_t buflen;             /* size of the block */
     LibBalsaMessageHeaders *embhdrs;  /* headers of a message/rfc822 part */
     LibBalsaMessageBodyType body_type;

Modified: trunk/libbalsa/identity.c
==============================================================================
--- trunk/libbalsa/identity.c	(original)
+++ trunk/libbalsa/identity.c	Sun May 25 19:55:07 2008
@@ -102,6 +102,7 @@
     ident->bcc = NULL;
     ident->reply_string = g_strdup(_("Re:"));
     ident->forward_string = g_strdup(_("Fwd:"));
+    ident->send_mp_alternative = FALSE;
     ident->signature_path = NULL;
     ident->sig_executable = FALSE;
     ident->sig_sending = TRUE;
@@ -252,6 +253,14 @@
 
 
 void
+libbalsa_identity_set_send_mp_alternative(LibBalsaIdentity* ident, gboolean send_mp_alternative)
+{
+    g_return_if_fail(ident != NULL);
+    ident->send_mp_alternative = send_mp_alternative;
+}
+
+
+void
 libbalsa_identity_set_signature_path(LibBalsaIdentity* ident, const gchar* path)
 {
     g_return_if_fail(ident != NULL);
@@ -982,7 +991,7 @@
                            "identity-domain");
 
     /* create the "Messages" tab */
-    table = append_ident_notebook_page(notebook, 8, _("Messages"), NULL);
+    table = append_ident_notebook_page(notebook, 9, _("Messages"), NULL);
     row = 0;
     ident_dialog_add_entry(table, row++, dialog, _("_Bcc:"), 
                            "identity-bcc");
@@ -991,6 +1000,9 @@
     ident_dialog_add_entry(table, row++, dialog, _("F_orward String:"), 
                            "identity-forwardstring");
     ident_dialog_add_checkbutton(table, row++, dialog, 
+                                 _("send messages in both plain text and _HTML format"),
+                                 "identity-sendmpalternative", TRUE);
+    ident_dialog_add_checkbutton(table, row++, dialog, 
                                  _("request _Message Disposition Notification by default"),
                                  "identity-requestmdn", TRUE);
     ident_dialog_add_file_chooser_button(table, row++, dialog,
@@ -1469,6 +1481,7 @@
     id->reply_string    = ident_dialog_get_text(dlg, "identity-replystring");
     g_free(id->forward_string);
     id->forward_string  = ident_dialog_get_text(dlg, "identity-forwardstring");
+    id->send_mp_alternative = ident_dialog_get_bool(dlg, "identity-sendmpalternative");
 #if ENABLE_ESMTP
     if(id->smtp_server) g_object_unref(id->smtp_server);
     id->smtp_server = ident_dialog_get_value(dlg, "identity-smtp-server");
@@ -1836,6 +1849,8 @@
                             ident->reply_string);
     display_frame_set_field(dialog, "identity-forwardstring", 
                             ident->forward_string);
+    display_frame_set_boolean(dialog, "identity-sendmpalternative",
+                              ident->send_mp_alternative);
 #if ENABLE_ESMTP
     display_frame_set_server(dialog, "identity-smtp-server",
                              ident->smtp_server);
@@ -1962,6 +1977,8 @@
         g_free(ident->forward_string);
         ident->forward_string = tmpstr;
     }
+    ident->send_mp_alternative =
+        libbalsa_conf_get_bool("SendMultipartAlternative");
     
     ident->signature_path = libbalsa_conf_get_string("SignaturePath");
     ident->sig_executable = libbalsa_conf_get_bool("SigExecutable");
@@ -2001,6 +2018,7 @@
     libbalsa_conf_set_string("Bcc", ident->bcc);
     libbalsa_conf_set_string("ReplyString", ident->reply_string);
     libbalsa_conf_set_string("ForwardString", ident->forward_string);
+    libbalsa_conf_set_bool("SendMultipartAlternative", ident->send_mp_alternative);
 #if ENABLE_ESMTP
     libbalsa_conf_set_string("SmtpServer",
                              libbalsa_smtp_server_get_name(ident->

Modified: trunk/libbalsa/identity.h
==============================================================================
--- trunk/libbalsa/identity.h	(original)
+++ trunk/libbalsa/identity.h	Sun May 25 19:55:07 2008
@@ -68,6 +68,7 @@
         gchar* bcc;
         gchar* reply_string;
         gchar* forward_string;
+        gboolean send_mp_alternative;
 
         gchar* signature_path;
         gboolean sig_executable;
@@ -109,6 +110,7 @@
     void libbalsa_identity_set_bcc(LibBalsaIdentity*, const gchar*);
     void libbalsa_identity_set_reply_string(LibBalsaIdentity* , const gchar*);
     void libbalsa_identity_set_forward_string(LibBalsaIdentity*, const gchar*);
+    void libbalsa_identity_set_send_mp_alternative(LibBalsaIdentity*, gboolean);
     void libbalsa_identity_set_signature_path(LibBalsaIdentity*, const gchar*);
     void libbalsa_identity_set_sig_executable(LibBalsaIdentity*, gboolean);
     void libbalsa_identity_set_sig_sending(LibBalsaIdentity*, gboolean);

Modified: trunk/libbalsa/mime.c
==============================================================================
--- trunk/libbalsa/mime.c	(original)
+++ trunk/libbalsa/mime.c	Sun May 25 19:55:07 2008
@@ -1420,3 +1420,171 @@
     return c > 0;
 }
 #endif                          /* USE_GREGEX */
+
+
+GString *
+libbalsa_html_encode_hyperlinks(GString * paragraph)
+{
+    GString * retval;
+    gchar * p;
+#if USE_GREGEX
+    GRegex *url_reg = get_url_reg();
+    GMatchInfo *url_match;
+#else
+    regex_t *url_reg = get_url_reg();
+    regmatch_t url_match;
+#endif
+    gboolean match;
+    gchar * markup;
+
+    /* check for any url */
+    if (!prescanner(paragraph->str)) {
+        markup = g_markup_escape_text(paragraph->str, -1);
+        g_string_assign(paragraph, markup);
+        g_free(markup);
+        return paragraph;
+    }
+
+    /* got some url's... */
+    retval = g_string_new("");
+    p = paragraph->str;
+
+#if USE_GREGEX
+    match = g_regex_match(url_reg, p, 0, &url_match);
+#else
+    match = regexec(url_reg, p, 1, &url_match, 0) == 0;
+#endif
+
+    while (match) {
+        gint start_pos, end_pos;
+
+#if USE_GREGEX
+        if (!g_match_info_fetch_pos(url_match, 0, &start_pos, &end_pos))
+            break;
+#else
+        start_pos = url_match.rm_so;
+        end_pos   = url_match.rm_eo;
+#endif
+
+        /* add the url to the result */
+        if (start_pos > 0) {
+            markup = g_markup_escape_text(p, start_pos);
+            retval = g_string_append(retval, markup);
+            g_free(markup);
+        }
+        retval = g_string_append(retval, "<a href=\"");
+        retval = g_string_append_len(retval, p + start_pos, end_pos - start_pos);
+        retval = g_string_append(retval, "\">");
+        retval = g_string_append_len(retval, p + start_pos, end_pos - start_pos);
+        retval = g_string_append(retval, "</a>");
+
+        /* find next (if any) */
+        p += end_pos;
+        if (prescanner(p)) {
+#if USE_GREGEX
+            g_match_info_free(url_match);
+            match = g_regex_match(url_reg, p, 0, &url_match);
+#else
+            match = regexec(url_reg, p, 1, &url_match, 0) == 0;
+#endif
+        } else
+            match = FALSE;
+    }
+#if USE_GREGEX
+    g_match_info_free(url_match);
+#endif                          /* USE_GREGEX */
+
+    /* copy remainder */
+    if (*p != '\0') {
+        markup = g_markup_escape_text(p, -1);
+        retval = g_string_append(retval, markup);
+        g_free(markup);
+    }
+
+    /* done - free original, return new */
+    g_string_free(paragraph, TRUE);
+    return retval;
+}
+
+
+gchar *
+libbalsa_text_to_html(const gchar * title, const gchar * body, const gchar * lang)
+{
+    GString * html_body =
+        g_string_new("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n");
+    gchar * html_subject;
+    const gchar * start = body;
+    gchar * html_lang;
+    gchar * p;
+
+    /* set the html header, including the primary language and the title */
+    if (lang) {
+        html_lang = g_strdup(lang);
+        if ((p = strchr(html_lang, '_')))
+            *p = '-';
+    } else
+        html_lang = g_strdup("x-unknown");
+    html_subject = g_markup_escape_text(title, -1);
+    g_string_append_printf(html_body, 
+                           "<html lang=\"%s\"><head>\n"
+                           "<title>%s</title>\n"
+                           "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"
+                           "<style type=\"text/css\">\n"
+                           "  p { margin-top: 0px; margin-bottom: 0px; }\n"
+                           "</style></head>\n"
+                           "<body>\n", html_lang, html_subject);
+    g_free(html_subject);
+    g_free(html_lang);
+
+    /* add the lines of the message body */
+    while (*start) {
+        const gchar * eol = strchr(start, '\n');
+        const gchar * p = start;
+        PangoDirection direction = PANGO_DIRECTION_NEUTRAL;
+        GString * html;
+        gsize idx;
+
+        if (!eol)
+            eol = start + strlen(start);
+
+        /* find the first real char to determine the paragraph direction */
+        while (p < eol && direction == PANGO_DIRECTION_NEUTRAL) {
+            direction = pango_unichar_direction(g_utf8_get_char(p));
+            p = g_utf8_next_char(p);
+        }
+
+        /* html escape the line */
+        html = g_string_new_len(start, eol - start);
+
+        /* encode hyperlinks */
+        html = libbalsa_html_encode_hyperlinks(html);
+
+        /* replace a series of n spaces by (n - 1) &nbsp; and one space */
+        idx = 0;
+        while (idx < html->len) {
+            if (html->str[idx] == ' ' && (idx == 0 || html->str[idx + 1] == ' ')) {
+                html->str[idx++] = '&';
+                html = g_string_insert(html, idx, "nbsp;");
+                idx += 5;
+            } else
+                idx = g_utf8_next_char(html->str + idx) - html->str;
+        }
+
+        /* append the paragraph, always stating the proper direction */
+        g_string_append_printf(html_body, "<p dir=\"%s\">%s</p>\n",
+                               direction == PANGO_DIRECTION_RTL ? "rtl" : "ltr",
+                               *html->str ? html->str : "&nbsp;");
+        g_string_free(html, TRUE);
+
+        /* next line */
+        start = eol;
+        if (*start)
+            start++;
+    }
+
+    /* close the html context */
+    html_body = g_string_append(html_body, "</body></html>\n");
+    
+    /* return the utf-8 encoded text/html */
+    return g_string_free(html_body, FALSE);
+}

Modified: trunk/libbalsa/misc.h
==============================================================================
--- trunk/libbalsa/misc.h	(original)
+++ trunk/libbalsa/misc.h	Sun May 25 19:55:07 2008
@@ -187,4 +187,7 @@
 
 gboolean libbalsa_path_is_below_dir(const gchar * path, const gchar * dir);
 
+gchar * libbalsa_text_to_html(const gchar * title, const gchar * body, const gchar * lang);
+GString * libbalsa_html_encode_hyperlinks(GString * paragraph);
+
 #endif				/* __LIBBALSA_MISC_H__ */

Modified: trunk/libbalsa/send.c
==============================================================================
--- trunk/libbalsa/send.c	(original)
+++ trunk/libbalsa/send.c	Sun May 25 19:55:07 2008
@@ -197,7 +197,7 @@
 
 #if HAVE_GPGME
 static LibBalsaMsgCreateResult
-libbalsa_create_rfc2440_buffer(LibBalsaMessageBody *body, GMimePart *mime_part,
+libbalsa_create_rfc2440_buffer(LibBalsaMessage *message, GMimePart *mime_part,
 			       GtkWindow * parent, GError ** error);
 static LibBalsaMsgCreateResult
 do_multipart_crypto(LibBalsaMessage * message, GMimeObject ** mime_root,
@@ -301,12 +301,22 @@
     g_object_unref(wrapper);
 }
 
+#ifdef HAVE_GPGME
+static GMimeObject *
+add_mime_body_plain(LibBalsaMessageBody *body, gboolean flow, gboolean postpone,
+                    guint use_gpg_mode,
+                    LibBalsaMsgCreateResult * crypt_res, GError ** error)
+#else
 static GMimeObject *
-add_mime_body_plain(LibBalsaMessageBody *body, gboolean flow)
+add_mime_body_plain(LibBalsaMessageBody *body, gboolean flow, gboolean postpone)
+#endif
 {
     GMimePart *mime_part;
     const gchar * charset;
-  
+#ifdef HAVE_GPGME
+    GtkWindow * parent = g_object_get_data(G_OBJECT(body->message), "parent-window");
+#endif
+
     g_return_val_if_fail(body, NULL);
     
     charset=body->charset;
@@ -369,7 +379,55 @@
     } else
 	lbs_set_content(mime_part, body->buffer);
 
-    return GMIME_OBJECT(mime_part);
+#ifdef HAVE_GPGME
+    /* rfc 2440 sign/encrypt if requested */
+    if (use_gpg_mode != 0) {
+        *crypt_res =
+            libbalsa_create_rfc2440_buffer(body->message,
+                                           GMIME_PART(mime_part),
+                                           parent, error);
+
+        if (*crypt_res != LIBBALSA_MESSAGE_CREATE_OK) {
+            g_object_unref(G_OBJECT(mime_part));
+            return NULL;
+        }
+    }
+#endif
+
+    /* if requested, add a text/html version in a multipart/alternative */
+    if (body->html_buffer && !postpone) {
+        GMimeMultipart *mpa = g_mime_multipart_new_with_subtype("alternative");
+
+        g_mime_multipart_add_part(mpa, GMIME_OBJECT(mime_part));
+        g_object_unref(G_OBJECT(mime_part));
+
+        mime_part = g_mime_part_new_with_type("text", "html");
+        g_mime_multipart_add_part(mpa, GMIME_OBJECT(mime_part));
+        g_object_unref(G_OBJECT(mime_part));
+        g_mime_part_set_content_disposition(mime_part, GMIME_DISPOSITION_INLINE);
+        g_mime_part_set_encoding(mime_part, GMIME_PART_ENCODING_QUOTEDPRINTABLE);
+        g_mime_object_set_content_type_parameter(GMIME_OBJECT(mime_part),
+                                                 "charset", "UTF-8");
+	lbs_set_content(mime_part, body->html_buffer);
+
+#ifdef HAVE_GPGME
+        if (use_gpg_mode != 0 &&
+            (use_gpg_mode & LIBBALSA_PROTECT_MODE) != LIBBALSA_PROTECT_SIGN) {
+            *crypt_res =
+                libbalsa_create_rfc2440_buffer(body->message,
+                                               GMIME_PART(mime_part),
+                                               parent, error);
+
+            if (*crypt_res != LIBBALSA_MESSAGE_CREATE_OK) {
+                g_object_unref(G_OBJECT(mpa));
+                return NULL;
+            }
+        }
+#endif
+
+        return GMIME_OBJECT(mpa);
+    } else
+        return GMIME_OBJECT(mime_part);
 }
 
 #if 0
@@ -1741,25 +1799,25 @@
 	    g_strfreev(mime_type);
 	} else if (body->buffer) {
 #ifdef HAVE_GPGME
-	    mime_part = add_mime_body_plain(body, flow);
+            guint use_gpg_mode;
+            LibBalsaMsgCreateResult crypt_res = LIBBALSA_MESSAGE_CREATE_OK;
+
 	    /* in '2440 mode, touch *only* the first body! */
 	    if (!postponing && body == body->message->body_list &&
 		message->gpg_mode > 0 &&
-		(message->gpg_mode & LIBBALSA_PROTECT_OPENPGP) != 0) {
-		LibBalsaMsgCreateResult crypt_res =
-		    libbalsa_create_rfc2440_buffer(body,
-			                           GMIME_PART(mime_part),
-						   parent, error);
-
-		if (crypt_res != LIBBALSA_MESSAGE_CREATE_OK) {
-		    g_object_unref(G_OBJECT(mime_part));
-		    if (mime_root)
-			g_object_unref(G_OBJECT(mime_root));
-		    return crypt_res;
-		}
-	    }
+		(message->gpg_mode & LIBBALSA_PROTECT_OPENPGP) != 0)
+                use_gpg_mode = message->gpg_mode;
+            else
+                use_gpg_mode = 0;
+            mime_part = add_mime_body_plain(body, flow, postponing, use_gpg_mode,
+                                            &crypt_res, error);
+            if (!mime_part) {
+                if (mime_root)
+                    g_object_unref(G_OBJECT(mime_root));
+                return crypt_res;
+            }
 #else
-	    mime_part = add_mime_body_plain(body, flow);
+            mime_part = add_mime_body_plain(body, flow, postponing);
 #endif /* HAVE_GPGME */
 	}
 
@@ -1998,10 +2056,9 @@
 }
 
 static LibBalsaMsgCreateResult
-libbalsa_create_rfc2440_buffer(LibBalsaMessageBody *body, GMimePart *mime_part,
+libbalsa_create_rfc2440_buffer(LibBalsaMessage *message, GMimePart *mime_part,
 			       GtkWindow * parent, GError ** error)
 {
-    LibBalsaMessage *message = body->message;
     gint mode = message->gpg_mode;
     gboolean always_trust = (mode & LIBBALSA_PROTECT_ALWAYS_TRUST) != 0;
 

Modified: trunk/src/sendmsg-window.c
==============================================================================
--- trunk/src/sendmsg-window.c	(original)
+++ trunk/src/sendmsg-window.c	Sun May 25 19:55:07 2008
@@ -129,6 +129,8 @@
                                     BalsaSendmsg * bsmsg);
 static void toggle_format_cb       (GtkToggleAction * toggle_action,
                                     BalsaSendmsg * bsmsg);
+static void toggle_mp_alt_cb       (GtkToggleAction * toggle_action,
+                                    BalsaSendmsg * bsmsg);
 #ifdef HAVE_GPGME
 static void toggle_sign_cb         (GtkToggleAction * toggle_action,
                                     BalsaSendmsg * bsmsg);
@@ -419,6 +421,8 @@
      NULL, G_CALLBACK(toggle_reqdispnotify_cb), FALSE},
     {"Flowed", NULL, N_("_Format = Flowed"), NULL,
      NULL, G_CALLBACK(toggle_format_cb), FALSE},
+    {"SendMPAlt", NULL, N_("Send as plain text and _HTML"), NULL,
+     NULL, G_CALLBACK(toggle_mp_alt_cb), FALSE},
 #ifdef HAVE_GPGME
 #if !defined(ENABLE_TOUCH_UI)
     {"SignMessage", BALSA_PIXMAP_GPG_SIGN, N_("_Sign Message"), NULL,
@@ -508,6 +512,7 @@
 "    <menu action='OptionsMenu'>"
 "      <menuitem action='RequestMDN'/>"
 "      <menuitem action='Flowed'/>"
+"      <menuitem action='SendMPAlt'/>"
 #ifdef HAVE_GPGME
 "      <separator/>"
 "      <menuitem action='SignMessage'/>"
@@ -1611,6 +1616,7 @@
         }
         g_strfreev(message_split);
     }
+    sw_set_active(bsmsg, "SendMPAlt", bsmsg->ident->send_mp_alternative);
     
 #ifdef HAVE_GPGME
     bsmsg_update_gpg_ui_on_ident_change(bsmsg, ident);
@@ -4591,6 +4597,7 @@
 
     bsmsg->flow = !balsa_app.wordwrap;
     sw_set_sensitive(bsmsg, "Reflow", bsmsg->flow);
+    bsmsg->send_mp_alt = FALSE;
 
     sw_set_sensitive(bsmsg, "SelectIdentity",
                      balsa_app.identities->next != NULL);
@@ -4606,6 +4613,7 @@
     bsmsg->req_dispnotify = FALSE;
 
     sw_set_active(bsmsg, "Flowed", bsmsg->flow);
+    sw_set_active(bsmsg, "SendMPAlt", bsmsg->ident->send_mp_alternative);
 
 #ifdef HAVE_GPGME
     bsmsg_setup_gpg_ui(bsmsg);
@@ -5022,6 +5030,9 @@
     if ((postpone_hdr =
          libbalsa_message_get_user_header(message, "X-Balsa-Format")))
         sw_set_active(bsmsg, "Flowed", strcmp(postpone_hdr, "Fixed"));
+    if ((postpone_hdr =
+         libbalsa_message_get_user_header(message, "X-Balsa-MP-Alt")))
+        sw_set_active(bsmsg, "SendMPAlt", !strcmp(postpone_hdr, "yes"));
 
     for (list = message->references; list; list = list->next)
         refs = g_list_prepend(refs, g_strdup(list->data));
@@ -5554,10 +5565,15 @@
     gtk_text_buffer_get_bounds(bsmsg->buffer2, &start, &end);
     body->buffer = gtk_text_iter_get_text(&start, &end);
 #endif                          /* HAVE_GTKSOURCEVIEW */
+    if (bsmsg->send_mp_alt)
+        body->html_buffer = 
+            libbalsa_text_to_html(message->subj, body->buffer,
+                                  bsmsg->spell_check_lang);
     if (bsmsg->flow)
 	body->buffer =
 	    libbalsa_wrap_rfc2646(body->buffer, balsa_app.wraplength,
                                   TRUE, FALSE, TRUE);
+
 #if !HAVE_GTKSOURCEVIEW
     /* Disable undo and redo, because buffer2 was changed. */
     sw_buffer_set_undo(bsmsg, FALSE, FALSE);
@@ -5834,26 +5850,48 @@
     if (!check_suggest_encryption(bsmsg))
 	return FALSE;
 
-    if ((bsmsg->gpg_mode & LIBBALSA_PROTECT_OPENPGP) != 0 &&
-        (bsmsg->gpg_mode & LIBBALSA_PROTECT_MODE) != 0 &&
-	gtk_tree_model_get_iter_first(BALSA_MSG_ATTACH_MODEL(bsmsg), &iter)) {
-	/* we are going to RFC2440 sign/encrypt a multipart... */
-	GtkWidget *dialog;
-	gint choice;
-
-	dialog = gtk_message_dialog_new
-            (GTK_WINDOW(bsmsg->window),
-             GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
-             GTK_MESSAGE_QUESTION,
-             GTK_BUTTONS_OK_CANCEL,
-             _("You selected OpenPGP mode for a message with attachments. "
-               "In this mode, only the first part will be signed and/or "
-               "encrypted. You should select MIME mode if the complete "
-               "message shall be protected. Do you really want to proceed?"));
-	choice = gtk_dialog_run(GTK_DIALOG(dialog));
-	gtk_widget_destroy(dialog);
-	if (choice != GTK_RESPONSE_OK)
-	    return FALSE;
+    if ((bsmsg->gpg_mode & LIBBALSA_PROTECT_OPENPGP) != 0) {
+        gboolean warn_mp;
+        gboolean warn_html_sign;
+
+        warn_mp = (bsmsg->gpg_mode & LIBBALSA_PROTECT_MODE) != 0 &&
+            gtk_tree_model_get_iter_first(BALSA_MSG_ATTACH_MODEL(bsmsg), &iter);
+        warn_html_sign = (bsmsg->gpg_mode & LIBBALSA_PROTECT_MODE) == LIBBALSA_PROTECT_SIGN &&
+            bsmsg->send_mp_alt;
+            
+        if (warn_mp || warn_html_sign) {
+            /* we are going to RFC2440 sign/encrypt a multipart, or to
+             * RFC2440 sign a multipart/alternative... */
+            GtkWidget *dialog;
+            gint choice;
+            GString * message =
+                g_string_new(_("You selected OpenPGP security for this message.\n"));
+
+            if (warn_html_sign)
+                message =
+                    g_string_append(message,
+                        _("The message text will be sent as plain text and as "
+                          "HTML, but only the plain part can be signed.\n"));
+            if (warn_mp)
+                message =
+                    g_string_append(message,
+                        _("The message contains attachments, which cannot be "
+                          "signed or encrypted\n."));
+            message = 
+                g_string_append(message, 
+                    _("You should select MIME mode if the complete "
+                      "message shall be protected. Do you really want to proceed?"));
+            dialog = gtk_message_dialog_new
+                (GTK_WINDOW(bsmsg->window),
+                 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
+                 GTK_MESSAGE_QUESTION,
+                 GTK_BUTTONS_OK_CANCEL, message->str);
+            g_string_free(message, TRUE);
+            choice = gtk_dialog_run(GTK_DIALOG(dialog));
+            gtk_widget_destroy(dialog);
+            if (choice != GTK_RESPONSE_OK)
+                return FALSE;
+        }
     }
 #endif
 
@@ -5988,6 +6026,8 @@
 #endif /* HAVE_GTKSPELL */
     g_ptr_array_add(headers, g_strdup("X-Balsa-Format"));
     g_ptr_array_add(headers, g_strdup(bsmsg->flow ? "Flowed" : "Fixed"));
+    g_ptr_array_add(headers, g_strdup("X-Balsa-MP-Alt"));
+    g_ptr_array_add(headers, g_strdup(bsmsg->send_mp_alt ? "yes" : "no"));
     g_ptr_array_add(headers, NULL);
 
     if ((bsmsg->type == SEND_REPLY || bsmsg->type == SEND_REPLY_ALL ||
@@ -6475,6 +6515,12 @@
     sw_set_sensitive(bsmsg, "Reflow", bsmsg->flow);
 }
 
+static void
+toggle_mp_alt_cb(GtkToggleAction * toggle_action, BalsaSendmsg * bsmsg)
+{
+    bsmsg->send_mp_alt = gtk_toggle_action_get_active(toggle_action);
+}
+
 #ifdef HAVE_GPGME
 static void
 toggle_gpg_helper(GtkToggleAction * action, BalsaSendmsg * bsmsg,

Modified: trunk/src/sendmsg-window.h
==============================================================================
--- trunk/src/sendmsg-window.h	(original)
+++ trunk/src/sendmsg-window.h	Sun May 25 19:55:07 2008
@@ -87,6 +87,7 @@
         SendmsgState state;
         gulong identities_changed_id;
 	gboolean flow;          /* send format=flowed */ 
+	gboolean send_mp_alt;   /* send multipart/alternative (plain and html) */ 
 	gboolean req_dispnotify; /* send a MDN */ 
 	gboolean quit_on_close; /* quit balsa after the compose window */
 	                        /* is closed.                          */



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