[evolution] I#1373 - itip-view: Offer to show other parts from multipart/alternative ][



commit aa788e38660164e2308a5a32876dcf833cd81220
Author: Milan Crha <mcrha redhat com>
Date:   Tue Mar 1 15:59:15 2022 +0100

    I#1373 - itip-view: Offer to show other parts from multipart/alternative ][
    
    Change how the alternative HTML is present to the user, to avoid
    hiding meeting details when the sender-provided description
    does not contain it.
    
    Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/1373

 .../org.gnome.evolution.plugin.itip.gschema.xml.in |   4 +-
 src/modules/itip-formatter/e-mail-formatter-itip.c |  41 +++++
 src/modules/itip-formatter/e-mail-part-itip.c      |  58 ++++++-
 src/modules/itip-formatter/e-mail-part-itip.h      |   1 +
 src/modules/itip-formatter/itip-view.c             | 180 ++++++++++++++-------
 5 files changed, 222 insertions(+), 62 deletions(-)
---
diff --git a/data/org.gnome.evolution.plugin.itip.gschema.xml.in 
b/data/org.gnome.evolution.plugin.itip.gschema.xml.in
index 9c767da406..7bb344dfe9 100644
--- a/data/org.gnome.evolution.plugin.itip.gschema.xml.in
+++ b/data/org.gnome.evolution.plugin.itip.gschema.xml.in
@@ -11,9 +11,9 @@
       <_description>Whether to preset option to preserve existing reminder by default</_description>
     </key>
     <key name="show-message-description" type="b">
-      <default>true</default>
+      <default>false</default>
       <_summary>Show invitation description provided by the sender</_summary>
-      <_description>Set to true to show invitation description as provided by the sender, if such is 
available; otherwise generate the invitation description from the iCalendar component</_description>
+      <_description>Set to true to show invitation description as provided by the sender, if such is 
available</_description>
     </key>
   </schema>
 </schemalist>
diff --git a/src/modules/itip-formatter/e-mail-formatter-itip.c 
b/src/modules/itip-formatter/e-mail-formatter-itip.c
index 67146534c0..c8fb703dcf 100644
--- a/src/modules/itip-formatter/e-mail-formatter-itip.c
+++ b/src/modules/itip-formatter/e-mail-formatter-itip.c
@@ -48,6 +48,29 @@ static const gchar *formatter_mime_types[] = {
        NULL
 };
 
+static gboolean
+emfe_itip_get_use_alternative_html (const gchar *uri)
+{
+       SoupURI *soup_uri;
+       gboolean res = FALSE;
+
+       if (!uri)
+               return FALSE;
+
+       soup_uri = soup_uri_new (uri);
+       if (soup_uri) {
+               GHashTable *query;
+
+               query = soup_form_decode (soup_uri->query);
+               res = query && g_strcmp0 (g_hash_table_lookup (query, "e-itip-view-alternative-html"), "1") 
== 0;
+               if (query)
+                       g_hash_table_destroy (query);
+               soup_uri_free (soup_uri);
+       }
+
+       return res;
+}
+
 static gboolean
 emfe_itip_format (EMailFormatterExtension *extension,
                   EMailFormatter *formatter,
@@ -58,12 +81,18 @@ emfe_itip_format (EMailFormatterExtension *extension,
 {
        GString *buffer;
        EMailPartItip *itip_part;
+       gboolean use_alternative_html;
 
        /* This can be called with attachment parts too, thus
           return silently in that case */
        if (!E_IS_MAIL_PART_ITIP (part))
                return FALSE;
 
+       use_alternative_html = emfe_itip_get_use_alternative_html (context->uri);
+
+       if (use_alternative_html && context->mode != E_MAIL_FORMATTER_MODE_RAW)
+               return TRUE;
+
        itip_part = (EMailPartItip *) part;
 
        if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) {
@@ -83,6 +112,17 @@ emfe_itip_format (EMailFormatterExtension *extension,
                itip_view_write_for_printing (itip_view, buffer);
 
        } else if (context->mode == E_MAIL_FORMATTER_MODE_RAW) {
+               if (use_alternative_html) {
+                       if (itip_part->alternative_html) {
+                               g_output_stream_write_all (stream,
+                                       itip_part->alternative_html,
+                                       strlen (itip_part->alternative_html),
+                                       NULL, cancellable, NULL);
+                       }
+
+                       return TRUE;
+               }
+
                buffer = g_string_sized_new (2048);
 
                itip_view_write (itip_part, formatter, buffer);
@@ -114,6 +154,7 @@ emfe_itip_format (EMailFormatterExtension *extension,
                itip_part->folder = folder ? g_object_ref (folder) : NULL;
                itip_part->message = g_object_ref (message);
                itip_part->message_uid = g_strdup (message_uid);
+               g_clear_pointer (&itip_part->alternative_html, g_free);
 
                g_clear_object (&old_folder);
                g_clear_object (&old_message);
diff --git a/src/modules/itip-formatter/e-mail-part-itip.c b/src/modules/itip-formatter/e-mail-part-itip.c
index 3a1777b2f0..1df7aaf7c3 100644
--- a/src/modules/itip-formatter/e-mail-part-itip.c
+++ b/src/modules/itip-formatter/e-mail-part-itip.c
@@ -42,11 +42,9 @@ mail_part_itip_dispose (GObject *object)
 
        g_cancellable_cancel (part->cancellable);
 
-       g_free (part->message_uid);
-       part->message_uid = NULL;
-
-       g_free (part->vcalendar);
-       part->vcalendar = NULL;
+       g_clear_pointer (&part->message_uid, g_free);
+       g_clear_pointer (&part->vcalendar, g_free);
+       g_clear_pointer (&part->alternative_html, g_free);
 
        g_clear_object (&part->folder);
        g_clear_object (&part->message);
@@ -69,6 +67,54 @@ mail_part_itip_finalize (GObject *object)
        G_OBJECT_CLASS (e_mail_part_itip_parent_class)->finalize (object);
 }
 
+static void
+itip_view_alternative_html_clicked_cb (EWebView *web_view,
+                                      const gchar *iframe_id,
+                                      const gchar *element_id,
+                                      const gchar *element_class,
+                                      const gchar *element_value,
+                                      const GtkAllocation *element_position,
+                                      gpointer user_data)
+{
+       EMailPart *mail_part = user_data;
+       gchar tmp[128];
+
+       g_return_if_fail (E_IS_MAIL_PART_ITIP (mail_part));
+
+       if (!element_id || !element_value)
+               return;
+
+       g_return_if_fail (g_snprintf (tmp, sizeof (tmp), "%p:", mail_part) < sizeof (tmp));
+
+       if (g_str_has_prefix (element_id, tmp)) {
+               gchar spn[128];
+
+               g_return_if_fail (g_snprintf (spn, sizeof (spn), "%s-spn", element_value) < sizeof (spn));
+               g_return_if_fail (g_snprintf (tmp, sizeof (tmp), "%s-img", element_value) < sizeof (tmp));
+
+               e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
+                       "var elem = Evo.FindElement(%s, %s);\n"
+                       "if (elem) {\n"
+                       "       elem.hidden = !elem.hidden;\n"
+                       "}\n"
+                       "elem = Evo.FindElement(%s, %s);\n"
+                       "if (elem) {\n"
+                       "       var tmp = elem.src;\n"
+                       "       elem.src = elem.getAttribute(\"othersrc\");\n"
+                       "       elem.setAttribute(\"othersrc\", tmp);\n"
+                       "}\n"
+                       "elem = Evo.FindElement(%s, %s);\n"
+                       "if (elem) {\n"
+                       "       var tmp = elem.innerText;\n"
+                       "       elem.innerText = elem.getAttribute(\"othertext\");\n"
+                       "       elem.setAttribute(\"othertext\", tmp);\n"
+                       "}\n",
+                       iframe_id, element_value,
+                       iframe_id, tmp,
+                       iframe_id, spn);
+       }
+}
+
 static void
 mail_part_itip_content_loaded (EMailPart *part,
                               EWebView *web_view,
@@ -116,6 +162,8 @@ mail_part_itip_content_loaded (EMailPart *part,
 
                pitip->priv->views = g_slist_prepend (pitip->priv->views, itip_view);
        }
+
+       e_web_view_register_element_clicked (web_view, "itip-view-alternative-html", 
itip_view_alternative_html_clicked_cb, pitip);
 }
 
 static void
diff --git a/src/modules/itip-formatter/e-mail-part-itip.h b/src/modules/itip-formatter/e-mail-part-itip.h
index 49f5374328..fe37c4798a 100644
--- a/src/modules/itip-formatter/e-mail-part-itip.h
+++ b/src/modules/itip-formatter/e-mail-part-itip.h
@@ -59,6 +59,7 @@ struct _EMailPartItip {
        gchar *message_uid;
        CamelMimePart *itip_mime_part;
        gchar *vcalendar;
+       gchar *alternative_html;
 
        /* cancelled when freeing the puri */
        GCancellable *cancellable;
diff --git a/src/modules/itip-formatter/itip-view.c b/src/modules/itip-formatter/itip-view.c
index f4f4ec7385..45292d47c1 100644
--- a/src/modules/itip-formatter/itip-view.c
+++ b/src/modules/itip-formatter/itip-view.c
@@ -38,6 +38,7 @@
 #include <mail/em-config.h>
 #include <mail/em-utils.h>
 #include <em-format/e-mail-formatter-utils.h>
+#include <em-format/e-mail-part-utils.h>
 
 #include "itip-view.h"
 #include "e-mail-part-itip.h"
@@ -1859,67 +1860,59 @@ itip_view_write (gpointer itip_part_ptr,
                 EMailFormatter *formatter,
                  GString *buffer)
 {
+       EMailPartItip *itip_part = itip_part_ptr;
        gint icon_width, icon_height;
-       GSettings *settings;
        gchar *header;
-       gchar *alternative_html;
 
        header = e_mail_formatter_get_html_header (formatter);
        g_string_append (buffer, header);
        g_free (header);
 
-       settings = e_util_ref_settings ("org.gnome.evolution.plugin.itip");
-
-       if (g_settings_get_boolean (settings, "show-message-description"))
-               alternative_html = itip_view_dup_alternative_html (itip_part_ptr);
-       else
-               alternative_html = NULL;
+       g_clear_pointer (&itip_part->alternative_html, g_free);
 
-       g_clear_object (&settings);
+       itip_part->alternative_html = itip_view_dup_alternative_html (itip_part_ptr);
 
-       if (!alternative_html) {
-               if (!gtk_icon_size_lookup (GTK_ICON_SIZE_BUTTON, &icon_width, &icon_height)) {
-                       icon_width = 16;
-                       icon_height = 16;
-               }
+       if (!gtk_icon_size_lookup (GTK_ICON_SIZE_BUTTON, &icon_width, &icon_height)) {
+               icon_width = 16;
+               icon_height = 16;
+       }
 
-               g_string_append_printf (
-                       buffer,
-                       "<img src=\"gtk-stock://%s?size=%d\" class=\"itip icon\" width=\"%dpx\" 
height=\"%dpx\"/>\n",
-                               MEETING_ICON, GTK_ICON_SIZE_BUTTON, icon_width, icon_height);
+       g_string_append_printf (
+               buffer,
+               "<img src=\"gtk-stock://%s?size=%d\" class=\"itip icon\" width=\"%dpx\" height=\"%dpx\"/>\n",
+                       MEETING_ICON, GTK_ICON_SIZE_BUTTON, icon_width, icon_height);
 
-               g_string_append (
-                       buffer,
-                       "<div class=\"itip content\" id=\"" DIV_ITIP_CONTENT "\">\n");
+       g_string_append (
+               buffer,
+               "<div class=\"itip content\" id=\"" DIV_ITIP_CONTENT "\">\n");
 
-               /* The first section listing the sender */
-               /* FIXME What to do if the send and organizer do not match */
-               g_string_append (
-                       buffer,
-                       "<div id=\"" TEXT_ROW_SENDER "\" class=\"itip sender\"></div>\n");
+       /* The first section listing the sender */
+       /* FIXME What to do if the send and organizer do not match */
+       g_string_append (
+               buffer,
+               "<div id=\"" TEXT_ROW_SENDER "\" class=\"itip sender\"></div>\n");
 
-               g_string_append (buffer, "<hr>\n");
+       g_string_append (buffer, "<hr>\n");
 
-               /* Elementary event information */
-               g_string_append (
-                       buffer,
-                       "<table class=\"itip table\" border=\"0\" "
-                       "cellspacing=\"5\" cellpadding=\"0\">\n");
+       /* Elementary event information */
+       g_string_append (
+               buffer,
+               "<table class=\"itip table\" border=\"0\" "
+               "cellspacing=\"5\" cellpadding=\"0\">\n");
 
-               append_text_table_row (buffer, TABLE_ROW_SUMMARY, NULL, NULL);
-               append_text_table_row (buffer, TABLE_ROW_LOCATION, _("Location:"), NULL);
-               append_text_table_row (buffer, TABLE_ROW_URL, _("URL:"), NULL);
-               append_text_table_row (buffer, TABLE_ROW_START_DATE, _("Start time:"), NULL);
-               append_text_table_row (buffer, TABLE_ROW_END_DATE, _("End time:"), NULL);
-               append_text_table_row (buffer, TABLE_ROW_DUE_DATE, _("Due date:"), NULL);
-               append_text_table_row (buffer, TABLE_ROW_ESTIMATED_DURATION, _("Estimated duration:"), NULL);
-               append_text_table_row (buffer, TABLE_ROW_STATUS, _("Status:"), NULL);
-               append_text_table_row (buffer, TABLE_ROW_COMMENT, _("Comment:"), NULL);
-               append_text_table_row (buffer, TABLE_ROW_CATEGORIES, _("Categories:"), NULL);
-               append_text_table_row (buffer, TABLE_ROW_ATTENDEES, _("Attendees:"), NULL);
+       append_text_table_row (buffer, TABLE_ROW_SUMMARY, NULL, NULL);
+       append_text_table_row (buffer, TABLE_ROW_LOCATION, _("Location:"), NULL);
+       append_text_table_row (buffer, TABLE_ROW_URL, _("URL:"), NULL);
+       append_text_table_row (buffer, TABLE_ROW_START_DATE, _("Start time:"), NULL);
+       append_text_table_row (buffer, TABLE_ROW_END_DATE, _("End time:"), NULL);
+       append_text_table_row (buffer, TABLE_ROW_DUE_DATE, _("Due date:"), NULL);
+       append_text_table_row (buffer, TABLE_ROW_ESTIMATED_DURATION, _("Estimated duration:"), NULL);
+       append_text_table_row (buffer, TABLE_ROW_STATUS, _("Status:"), NULL);
+       append_text_table_row (buffer, TABLE_ROW_COMMENT, _("Comment:"), NULL);
+       append_text_table_row (buffer, TABLE_ROW_CATEGORIES, _("Categories:"), NULL);
+       append_text_table_row (buffer, TABLE_ROW_ATTENDEES, _("Attendees:"), NULL);
 
-               g_string_append (buffer, "</table>\n");
-       }
+       g_string_append (buffer, "</table>\n");
 
        /* Upper Info items */
        g_string_append (
@@ -1927,17 +1920,96 @@ itip_view_write (gpointer itip_part_ptr,
                "<table class=\"itip info\" id=\"" TABLE_UPPER_ITIP_INFO "\" border=\"0\" "
                "cellspacing=\"5\" cellpadding=\"0\">");
 
-       if (alternative_html) {
-               g_string_append (buffer, alternative_html);
-       } else {
-               /* Description */
-               g_string_append (
-                       buffer,
-                       "<div id=\"" TABLE_ROW_DESCRIPTION "\" class=\"itip description\" 
hidden=\"\"></div>\n");
-       }
+       /* Description */
+       g_string_append (
+               buffer,
+               "<div id=\"" TABLE_ROW_DESCRIPTION "\" class=\"itip description\" hidden=\"\"></div>\n");
 
        g_string_append (buffer, "<hr>\n");
 
+       if (itip_part->alternative_html) {
+               EMailPart *part = E_MAIL_PART (itip_part);
+               GSettings *settings;
+               const gchar *default_charset, *charset;
+               const gchar *text, *other_text;
+               const gchar *img, *other_img;
+               gboolean expand;
+               gchar *uri;
+
+               settings = e_util_ref_settings ("org.gnome.evolution.plugin.itip");
+               expand = g_settings_get_boolean (settings, "show-message-description");
+               g_clear_object (&settings);
+
+               text = _("Show description provided by the sender");
+               other_text = _("Hide description provided by the sender");
+               img = "pan-end-symbolic";
+               other_img = "pan-down-symbolic";
+
+               if (expand) {
+                       #define SWAP(a,b) { const gchar *tmp = a; a = b; b = tmp; }
+                       SWAP (text, other_text);
+                       SWAP (img, other_img);
+                       #undef SWAP
+               }
+
+               if (!gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, &icon_height)) {
+                       icon_width = 16;
+                       icon_height = 16;
+               }
+
+               e_util_markup_append_escaped (buffer,
+                       "<span class=\"itip-view-alternative-html\" id=\"%p:spn\" 
value=\"itip-view-alternative-html-%p\" style=\"vertical-align:bottom;\">"
+                       "<img id=\"itip-view-alternative-html-%p-img\" style=\"vertical-align:middle;\" 
width=\"%dpx\" height=\"%dpx\""
+                       " src=\"gtk-stock://%s?size=%d\" othersrc=\"gtk-stock://%s?size=%d\" 
style=\"vertical-align:center;\">&nbsp;"
+                       "<span id=\"itip-view-alternative-html-%p-spn\" othertext=\"%s\" 
style=\"vertical-align:center;\">%s</span></span><br>",
+                       itip_part, itip_part, itip_part, icon_width, icon_height,
+                       img, GTK_ICON_SIZE_MENU,
+                       other_img, GTK_ICON_SIZE_MENU,
+                       itip_part,
+                       other_text, text);
+
+               default_charset = e_mail_formatter_get_default_charset (formatter);
+               charset = e_mail_formatter_get_charset (formatter);
+
+               if (!default_charset)
+                       default_charset = "";
+               if (!charset)
+                       charset = "";
+
+               uri = e_mail_part_build_uri (
+                       itip_part->folder, itip_part->message_uid,
+                       "part_id", G_TYPE_STRING, e_mail_part_get_id (part),
+                       "mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW,
+                       "formatter_default_charset", G_TYPE_STRING, default_charset,
+                       "formatter_charset", G_TYPE_STRING, charset,
+                       "e-itip-view-alternative-html", G_TYPE_STRING, "1",
+                       NULL);
+
+               settings = e_util_ref_settings ("org.gnome.evolution.mail");
+
+               g_string_append_printf (
+                       buffer,
+                       "<div class=\"part-container-nostyle\" id=\"itip-view-alternative-html-%p\"%s>"
+                       "<iframe width=\"100%%\" height=\"10\" "
+                       " frameborder=\"0\" src=\"%s\" "
+                       " id=\"%s.iframe\" name=\"%s\" "
+                       " class=\"-e-mail-formatter-frame-color\" "
+                       " %s>"
+                       "</iframe>"
+                       "</div>",
+                       itip_part,
+                       expand ? "" : " hidden",
+                       uri,
+                       e_mail_part_get_id (part),
+                       e_mail_part_get_id (part),
+                       g_settings_get_boolean (settings, "preview-unset-html-colors") ? 
"x-e-unset-colors=\"1\"" : "style=\"background-color: #ffffff;\"");
+
+               g_clear_object (&settings);
+               g_free (uri);
+
+               g_string_append (buffer, "<hr>\n");
+       }
+
        /* Lower Info items */
        g_string_append (
                buffer,
@@ -1991,8 +2063,6 @@ itip_view_write (gpointer itip_part_ptr,
        g_string_append (buffer, "<div class=\"itip error\" id=\"" DIV_ITIP_ERROR "\"></div>");
 
        g_string_append (buffer, "</body></html>");
-
-       g_free (alternative_html);
 }
 
 void


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