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
This commit is contained 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>
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,85 +1860,156 @@ 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");
|
||||
g_clear_pointer (&itip_part->alternative_html, g_free);
|
||||
|
||||
if (g_settings_get_boolean (settings, "show-message-description"))
|
||||
alternative_html = itip_view_dup_alternative_html (itip_part_ptr);
|
||||
else
|
||||
alternative_html = NULL;
|
||||
itip_part->alternative_html = itip_view_dup_alternative_html (itip_part_ptr);
|
||||
|
||||
g_clear_object (&settings);
|
||||
|
||||
if (!alternative_html) {
|
||||
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 (
|
||||
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");
|
||||
|
||||
g_string_append (buffer, "<hr>\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);
|
||||
|
||||
g_string_append (buffer, "</table>\n");
|
||||
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 (
|
||||
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");
|
||||
|
||||
g_string_append (buffer, "<hr>\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);
|
||||
|
||||
g_string_append (buffer, "</table>\n");
|
||||
|
||||
/* Upper Info items */
|
||||
g_string_append (
|
||||
buffer,
|
||||
"<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;\"> "
|
||||
"<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
|
||||
|
Reference in New Issue
Block a user