[evolution] Calendar: Show probable HTML-formatted component DESCRIPTION as formatted text
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] Calendar: Show probable HTML-formatted component DESCRIPTION as formatted text
- Date: Thu, 7 May 2020 15:54:38 +0000 (UTC)
commit 3bb9beb38b1641af09b041d089f56a7adb4c7228
Author: Milan Crha <mcrha redhat com>
Date: Thu May 7 17:48:04 2020 +0200
Calendar: Show probable HTML-formatted component DESCRIPTION as formatted text
This covers the component editor and the itip-formatter, aka meeting
invitations. The component editor can switch between viewing the DESCRIPTION
as HTML and editing it as text. There is no editing as HTML.
For example Google produces DESCRIPTION with mixed HTML
content and plain text data, without any clue that the DESCRIPTION
is with HTML tags (the DESCRIPTION itself is plain text, according
to RFC 5545 (see section 3.8.1.5 and section 3.3.11)). Showing the HTML
tags can make the DESCRIPTION human-unreadable.
Partly related to https://gitlab.gnome.org/GNOME/evolution/-/issues/724
src/calendar/gui/e-comp-editor-event.c | 4 +-
src/calendar/gui/e-comp-editor-memo.c | 4 +-
src/calendar/gui/e-comp-editor-property-part.c | 56 +++++--
src/calendar/gui/e-comp-editor-property-part.h | 4 +
src/calendar/gui/e-comp-editor-property-parts.c | 201 +++++++++++++++++++++++-
src/calendar/gui/e-comp-editor-task.c | 4 +-
src/modules/itip-formatter/itip-view.c | 44 ++++--
7 files changed, 278 insertions(+), 39 deletions(-)
---
diff --git a/src/calendar/gui/e-comp-editor-event.c b/src/calendar/gui/e-comp-editor-event.c
index 0c566d056b..de257a30f2 100644
--- a/src/calendar/gui/e-comp-editor-event.c
+++ b/src/calendar/gui/e-comp-editor-event.c
@@ -188,8 +188,8 @@ ece_event_sensitize_widgets (ECompEditor *comp_editor,
/* Make the Description read-only, not completely insensitive,
thus it can be read and scrolled through and so on */
- widget = e_comp_editor_property_part_get_edit_widget (event_editor->priv->description);
- gtk_text_view_set_editable (GTK_TEXT_VIEW (gtk_bin_get_child (GTK_BIN (widget))),
gtk_widget_get_sensitive (widget));
+ widget = e_comp_editor_property_part_string_get_real_edit_widget (E_COMP_EDITOR_PROPERTY_PART_STRING
(event_editor->priv->description));
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (widget), gtk_widget_get_sensitive (widget));
gtk_widget_set_sensitive (widget, TRUE);
action = e_comp_editor_get_action (comp_editor, "all-day-event");
diff --git a/src/calendar/gui/e-comp-editor-memo.c b/src/calendar/gui/e-comp-editor-memo.c
index ee1bb04060..8c2aef6638 100644
--- a/src/calendar/gui/e-comp-editor-memo.c
+++ b/src/calendar/gui/e-comp-editor-memo.c
@@ -202,8 +202,8 @@ ece_memo_sensitize_widgets (ECompEditor *comp_editor,
/* Make the Description read-only, not completely insensitive,
thus it can be read and scrolled through and so on */
- widget = e_comp_editor_property_part_get_edit_widget (memo_editor->priv->description);
- gtk_text_view_set_editable (GTK_TEXT_VIEW (gtk_bin_get_child (GTK_BIN (widget))),
gtk_widget_get_sensitive (widget));
+ widget = e_comp_editor_property_part_string_get_real_edit_widget (E_COMP_EDITOR_PROPERTY_PART_STRING
(memo_editor->priv->description));
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (widget), gtk_widget_get_sensitive (widget));
gtk_widget_set_sensitive (widget, TRUE);
if (memo_editor->priv->insensitive_info_alert)
diff --git a/src/calendar/gui/e-comp-editor-property-part.c b/src/calendar/gui/e-comp-editor-property-part.c
index 1cbef9352c..35577132c3 100644
--- a/src/calendar/gui/e-comp-editor-property-part.c
+++ b/src/calendar/gui/e-comp-editor-property-part.c
@@ -401,8 +401,8 @@ ecepp_string_fill_widget (ECompEditorPropertyPart *property_part,
g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_STRING (property_part));
g_return_if_fail (I_CAL_IS_COMPONENT (component));
- edit_widget = e_comp_editor_property_part_get_edit_widget (property_part);
- g_return_if_fail (GTK_IS_ENTRY (edit_widget) || GTK_IS_SCROLLED_WINDOW (edit_widget));
+ edit_widget = e_comp_editor_property_part_string_get_real_edit_widget
(E_COMP_EDITOR_PROPERTY_PART_STRING (property_part));
+ g_return_if_fail (GTK_IS_ENTRY (edit_widget) || GTK_IS_TEXT_VIEW (edit_widget));
klass = E_COMP_EDITOR_PROPERTY_PART_STRING_GET_CLASS (property_part);
g_return_if_fail (klass != NULL);
@@ -442,10 +442,10 @@ ecepp_string_fill_widget (ECompEditorPropertyPart *property_part,
if (GTK_IS_ENTRY (edit_widget)) {
gtk_entry_set_text (GTK_ENTRY (edit_widget), text ? text : "");
- } else /* if (GTK_IS_SCROLLED_WINDOW (edit_widget)) */ {
+ } else /* if (GTK_IS_TEXT_VIEW (edit_widget)) */ {
GtkTextBuffer *buffer;
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (gtk_bin_get_child (GTK_BIN (edit_widget))));
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (edit_widget));
gtk_text_buffer_set_text (buffer, text ? text : "", -1);
}
@@ -466,8 +466,8 @@ ecepp_string_fill_component (ECompEditorPropertyPart *property_part,
g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_STRING (property_part));
g_return_if_fail (I_CAL_IS_COMPONENT (component));
- edit_widget = e_comp_editor_property_part_get_edit_widget (property_part);
- g_return_if_fail (GTK_IS_ENTRY (edit_widget) || GTK_IS_SCROLLED_WINDOW (edit_widget));
+ edit_widget = e_comp_editor_property_part_string_get_real_edit_widget
(E_COMP_EDITOR_PROPERTY_PART_STRING (property_part));
+ g_return_if_fail (GTK_IS_ENTRY (edit_widget) || GTK_IS_TEXT_VIEW (edit_widget));
klass = E_COMP_EDITOR_PROPERTY_PART_STRING_GET_CLASS (property_part);
g_return_if_fail (klass != NULL);
@@ -477,11 +477,11 @@ ecepp_string_fill_component (ECompEditorPropertyPart *property_part,
if (GTK_IS_ENTRY (edit_widget)) {
value = g_strdup (gtk_entry_get_text (GTK_ENTRY (edit_widget)));
- } else /* if (GTK_IS_SCROLLED_WINDOW (edit_widget)) */ {
+ } else /* if (GTK_IS_TEXT_VIEW (edit_widget)) */ {
GtkTextBuffer *buffer;
GtkTextIter text_iter_start, text_iter_end;
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (gtk_bin_get_child (GTK_BIN (edit_widget))));
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (edit_widget));
gtk_text_buffer_get_start_iter (buffer, &text_iter_start);
gtk_text_buffer_get_end_iter (buffer, &text_iter_end);
value = gtk_text_buffer_get_text (buffer, &text_iter_start, &text_iter_end, FALSE);
@@ -533,6 +533,14 @@ ecepp_string_fill_component (ECompEditorPropertyPart *property_part,
g_free (value);
}
+static GtkWidget *
+ecepp_string_get_real_edit_widget (ECompEditorPropertyPartString *part_string)
+{
+ g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_STRING (part_string), NULL);
+
+ return e_comp_editor_property_part_get_edit_widget (E_COMP_EDITOR_PROPERTY_PART (part_string));
+}
+
static void
e_comp_editor_property_part_string_init (ECompEditorPropertyPartString *part_string)
{
@@ -555,6 +563,7 @@ e_comp_editor_property_part_string_class_init (ECompEditorPropertyPartStringClas
klass->i_cal_new_func = NULL;
klass->i_cal_set_func = NULL;
klass->i_cal_get_func = NULL;
+ klass->get_real_edit_widget = ecepp_string_get_real_edit_widget;
part_class = E_COMP_EDITOR_PROPERTY_PART_CLASS (klass);
part_class->create_widgets = ecepp_string_create_widgets;
@@ -575,13 +584,10 @@ e_comp_editor_property_part_string_attach_focus_tracker (ECompEditorPropertyPart
g_return_if_fail (E_IS_FOCUS_TRACKER (focus_tracker));
- edit_widget = e_comp_editor_property_part_get_edit_widget (E_COMP_EDITOR_PROPERTY_PART (part_string));
- if (edit_widget) {
- if (GTK_IS_SCROLLED_WINDOW (edit_widget))
- e_widget_undo_attach (gtk_bin_get_child (GTK_BIN (edit_widget)), focus_tracker);
- else
- e_widget_undo_attach (edit_widget, focus_tracker);
- }
+ edit_widget = e_comp_editor_property_part_string_get_real_edit_widget (part_string);
+
+ if (edit_widget)
+ e_widget_undo_attach (edit_widget, focus_tracker);
}
void
@@ -601,6 +607,26 @@ e_comp_editor_property_part_string_is_multivalue (ECompEditorPropertyPartString
return part_string->priv->is_multivalue;
}
+GtkWidget *
+e_comp_editor_property_part_string_get_real_edit_widget (ECompEditorPropertyPartString *part_string)
+{
+ ECompEditorPropertyPartStringClass *klass;
+ GtkWidget *edit_widget;
+
+ g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_STRING (part_string), NULL);
+
+ klass = E_COMP_EDITOR_PROPERTY_PART_STRING_GET_CLASS (part_string);
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->get_real_edit_widget != NULL, NULL);
+
+ edit_widget = klass->get_real_edit_widget (part_string);
+
+ if (GTK_IS_SCROLLED_WINDOW (edit_widget))
+ edit_widget = gtk_bin_get_child (GTK_BIN (edit_widget));
+
+ return edit_widget;
+}
+
/* ************************************************************************* */
struct _ECompEditorPropertyPartDatetimePrivate {
diff --git a/src/calendar/gui/e-comp-editor-property-part.h b/src/calendar/gui/e-comp-editor-property-part.h
index cf29a09beb..96f0062f3e 100644
--- a/src/calendar/gui/e-comp-editor-property-part.h
+++ b/src/calendar/gui/e-comp-editor-property-part.h
@@ -218,6 +218,8 @@ struct _ECompEditorPropertyPartStringClass {
void (* i_cal_set_func) (ICalProperty *prop,
const gchar *value);
const gchar * (* i_cal_get_func) (ICalProperty *prop);
+
+ GtkWidget * (* get_real_edit_widget)(ECompEditorPropertyPartString *part_string);
};
GType e_comp_editor_property_part_string_get_type (void) G_GNUC_CONST;
@@ -229,6 +231,8 @@ void e_comp_editor_property_part_string_set_is_multivalue
gboolean is_multivalue);
gboolean e_comp_editor_property_part_string_is_multivalue
(ECompEditorPropertyPartString *part_string);
+GtkWidget * e_comp_editor_property_part_string_get_real_edit_widget
+ (ECompEditorPropertyPartString *part_string);
/* ************************************************************************* */
diff --git a/src/calendar/gui/e-comp-editor-property-parts.c b/src/calendar/gui/e-comp-editor-property-parts.c
index fbc97e0ab0..b27c6b3278 100644
--- a/src/calendar/gui/e-comp-editor-property-parts.c
+++ b/src/calendar/gui/e-comp-editor-property-parts.c
@@ -538,6 +538,13 @@ typedef struct _ECompEditorPropertyPartDescriptionClass ECompEditorPropertyPartD
struct _ECompEditorPropertyPartDescription {
ECompEditorPropertyPartString parent;
+
+ gboolean has_html;
+ gboolean mode_html;
+ GtkWidget *real_edit_widget;
+ GtkWidget *view_as_label;
+ GtkWidget *web_view_scrolled_window;
+ GtkWidget *web_view;
};
struct _ECompEditorPropertyPartDescriptionClass {
@@ -548,13 +555,85 @@ GType e_comp_editor_property_part_description_get_type (void) G_GNUC_CONST;
G_DEFINE_TYPE (ECompEditorPropertyPartDescription, e_comp_editor_property_part_description,
E_TYPE_COMP_EDITOR_PROPERTY_PART_STRING)
+static GtkWidget *
+ecepp_description_get_real_edit_widget (ECompEditorPropertyPartString *part_string)
+{
+ g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DESCRIPTION (part_string), NULL);
+
+ return E_COMP_EDITOR_PROPERTY_PART_DESCRIPTION (part_string)->real_edit_widget;
+}
+
+static void
+ecepp_description_update_view_mode (ECompEditorPropertyPartDescription *description_part)
+{
+ if (description_part->has_html) {
+ gchar *markup;
+
+ markup = g_markup_printf_escaped ("<a href=\"evo-switch-view-mode\">%s</a>",
+ description_part->mode_html ? _("Edit as text") : _("View as HTML"));
+
+ gtk_label_set_markup (GTK_LABEL (description_part->view_as_label), markup);
+
+ g_free (markup);
+
+ gtk_widget_show (description_part->view_as_label);
+
+ if (description_part->mode_html) {
+ GtkTextBuffer *buffer;
+ GtkTextIter text_iter_start, text_iter_end;
+ GtkWidget *edit_widget;
+ gchar *value;
+
+ edit_widget = e_comp_editor_property_part_string_get_real_edit_widget
(E_COMP_EDITOR_PROPERTY_PART_STRING (description_part));
+ g_return_if_fail (GTK_IS_TEXT_VIEW (edit_widget));
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (edit_widget));
+ gtk_text_buffer_get_start_iter (buffer, &text_iter_start);
+ gtk_text_buffer_get_end_iter (buffer, &text_iter_end);
+ value = gtk_text_buffer_get_text (buffer, &text_iter_start, &text_iter_end, FALSE);
+
+ e_web_view_load_string (E_WEB_VIEW (description_part->web_view), value ? value : "");
+
+ g_free (value);
+
+ gtk_widget_hide (description_part->real_edit_widget);
+ gtk_widget_show (description_part->web_view_scrolled_window);
+ } else {
+ gtk_widget_hide (description_part->web_view_scrolled_window);
+ gtk_widget_show (description_part->real_edit_widget);
+ }
+ } else {
+ gtk_widget_hide (description_part->view_as_label);
+ gtk_widget_hide (description_part->web_view_scrolled_window);
+ gtk_widget_show (description_part->real_edit_widget);
+ }
+}
+
+static gboolean
+ecepp_description_flip_view_as_cb (GtkLabel *label,
+ const gchar *uri,
+ gpointer user_data)
+{
+ ECompEditorPropertyPartDescription *description_part = user_data;
+
+ g_return_val_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DESCRIPTION (description_part), FALSE);
+
+ description_part->mode_html = !description_part->mode_html;
+
+ ecepp_description_update_view_mode (description_part);
+
+ return TRUE;
+}
+
static void
ecepp_description_create_widgets (ECompEditorPropertyPart *property_part,
GtkWidget **out_label_widget,
GtkWidget **out_edit_widget)
{
ECompEditorPropertyPartClass *part_class;
+ ECompEditorPropertyPartDescription *description_part;
GtkTextView *text_view;
+ GtkWidget *box, *label;
g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DESCRIPTION (property_part));
g_return_if_fail (out_label_widget != NULL);
@@ -564,14 +643,18 @@ ecepp_description_create_widgets (ECompEditorPropertyPart *property_part,
g_return_if_fail (part_class != NULL);
g_return_if_fail (part_class->create_widgets != NULL);
+ description_part = E_COMP_EDITOR_PROPERTY_PART_DESCRIPTION (property_part);
+
*out_label_widget = NULL;
part_class->create_widgets (property_part, out_label_widget, out_edit_widget);
g_return_if_fail (*out_label_widget == NULL);
g_return_if_fail (*out_edit_widget != NULL);
- *out_label_widget = gtk_label_new_with_mnemonic (C_("ECompEditor", "_Description:"));
- gtk_label_set_mnemonic_widget (GTK_LABEL (*out_label_widget), *out_edit_widget);
+ description_part->real_edit_widget = *out_edit_widget;
+
+ label = gtk_label_new_with_mnemonic (C_("ECompEditor", "_Description:"));
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), *out_edit_widget);
text_view = GTK_TEXT_VIEW (gtk_bin_get_child (GTK_BIN (*out_edit_widget)));
gtk_text_view_set_wrap_mode (text_view, GTK_WRAP_WORD);
@@ -579,7 +662,7 @@ ecepp_description_create_widgets (ECompEditorPropertyPart *property_part,
e_buffer_tagger_connect (text_view);
e_spell_text_view_attach (text_view);
- g_object_set (G_OBJECT (*out_label_widget),
+ g_object_set (G_OBJECT (label),
"hexpand", FALSE,
"halign", GTK_ALIGN_END,
"vexpand", FALSE,
@@ -594,7 +677,92 @@ ecepp_description_create_widgets (ECompEditorPropertyPart *property_part,
"height-request", 100,
NULL);
- gtk_widget_show (*out_label_widget);
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+
+ g_object_set (G_OBJECT (box),
+ "hexpand", FALSE,
+ "halign", GTK_ALIGN_END,
+ "vexpand", FALSE,
+ "valign", GTK_ALIGN_START,
+ NULL);
+
+ gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
+
+ description_part->view_as_label = gtk_label_new ("");
+
+ g_object_set (G_OBJECT (description_part->view_as_label),
+ "hexpand", FALSE,
+ "halign", GTK_ALIGN_END,
+ "vexpand", FALSE,
+ "valign", GTK_ALIGN_START,
+ "track-visited-links", FALSE,
+ NULL);
+
+ g_signal_connect (description_part->view_as_label, "activate-link",
+ G_CALLBACK (ecepp_description_flip_view_as_cb), description_part);
+
+ gtk_box_pack_start (GTK_BOX (box), description_part->view_as_label, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (box);
+
+ *out_label_widget = box;
+
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+
+ g_object_set (G_OBJECT (box),
+ "hexpand", TRUE,
+ "halign", GTK_ALIGN_FILL,
+ "vexpand", TRUE,
+ "valign", GTK_ALIGN_FILL,
+ "visible", TRUE,
+ NULL);
+
+ gtk_box_pack_start (GTK_BOX (box), description_part->real_edit_widget, TRUE, TRUE, 0);
+
+ description_part->web_view = e_web_view_new ();
+ description_part->web_view_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+
+ gtk_container_add (GTK_CONTAINER (description_part->web_view_scrolled_window),
description_part->web_view);
+
+ g_object_set (G_OBJECT (description_part->web_view),
+ "hexpand", TRUE,
+ "halign", GTK_ALIGN_FILL,
+ "vexpand", TRUE,
+ "valign", GTK_ALIGN_FILL,
+ "visible", TRUE,
+ NULL);
+
+ g_object_set (G_OBJECT (description_part->web_view_scrolled_window),
+ "hexpand", TRUE,
+ "halign", GTK_ALIGN_FILL,
+ "vexpand", TRUE,
+ "valign", GTK_ALIGN_FILL,
+ "shadow-type", GTK_SHADOW_IN,
+ "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ "visible", FALSE,
+ NULL);
+
+ gtk_box_pack_start (GTK_BOX (box), description_part->web_view_scrolled_window, TRUE, TRUE, 0);
+
+ *out_edit_widget = box;
+}
+
+static gboolean
+ecepp_description_contains_html (const gchar *value)
+{
+ if (!value || !*value)
+ return FALSE;
+
+ return camel_strstrcase (value, "<br>") ||
+ camel_strstrcase (value, "<span>") ||
+ camel_strstrcase (value, "<b>") ||
+ camel_strstrcase (value, "<i>") ||
+ camel_strstrcase (value, "<u>") ||
+ camel_strstrcase (value, " ") ||
+ camel_strstrcase (value, "<ul>") ||
+ camel_strstrcase (value, "<li>") ||
+ camel_strstrcase (value, "</a>");
}
static void
@@ -602,7 +770,11 @@ ecepp_description_fill_widget (ECompEditorPropertyPart *property_part,
ICalComponent *component)
{
ECompEditorPropertyPartClass *part_class;
+ ECompEditorPropertyPartDescription *description_part;
+ GtkTextBuffer *buffer;
+ GtkTextIter text_iter_start, text_iter_end;
GtkWidget *edit_widget;
+ gchar *value;
g_return_if_fail (E_IS_COMP_EDITOR_PROPERTY_PART_DESCRIPTION (property_part));
g_return_if_fail (I_CAL_IS_COMPONENT (component));
@@ -611,17 +783,31 @@ ecepp_description_fill_widget (ECompEditorPropertyPart *property_part,
g_return_if_fail (part_class != NULL);
g_return_if_fail (part_class->fill_widget != NULL);
+ description_part = E_COMP_EDITOR_PROPERTY_PART_DESCRIPTION (property_part);
+
part_class->fill_widget (property_part, component);
- edit_widget = e_comp_editor_property_part_get_edit_widget (property_part);
- g_return_if_fail (GTK_IS_SCROLLED_WINDOW (edit_widget));
+ edit_widget = e_comp_editor_property_part_string_get_real_edit_widget
(E_COMP_EDITOR_PROPERTY_PART_STRING (property_part));
+ g_return_if_fail (GTK_IS_TEXT_VIEW (edit_widget));
+
+ e_buffer_tagger_update_tags (GTK_TEXT_VIEW (edit_widget));
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (edit_widget));
+ gtk_text_buffer_get_start_iter (buffer, &text_iter_start);
+ gtk_text_buffer_get_end_iter (buffer, &text_iter_end);
+ value = gtk_text_buffer_get_text (buffer, &text_iter_start, &text_iter_end, FALSE);
+
+ description_part->has_html = ecepp_description_contains_html (value);
+
+ ecepp_description_update_view_mode (description_part);
- e_buffer_tagger_update_tags (GTK_TEXT_VIEW (gtk_bin_get_child (GTK_BIN (edit_widget))));
+ g_free (value);
}
static void
e_comp_editor_property_part_description_init (ECompEditorPropertyPartDescription *part_description)
{
+ part_description->mode_html = TRUE;
}
static void
@@ -636,6 +822,7 @@ e_comp_editor_property_part_description_class_init (ECompEditorPropertyPartDescr
part_string_class->i_cal_new_func = i_cal_property_new_description;
part_string_class->i_cal_set_func = i_cal_property_set_description;
part_string_class->i_cal_get_func = i_cal_property_get_description;
+ part_string_class->get_real_edit_widget = ecepp_description_get_real_edit_widget;
part_class = E_COMP_EDITOR_PROPERTY_PART_CLASS (klass);
part_class->create_widgets = ecepp_description_create_widgets;
diff --git a/src/calendar/gui/e-comp-editor-task.c b/src/calendar/gui/e-comp-editor-task.c
index 4280ae6c8b..6c94f79b12 100644
--- a/src/calendar/gui/e-comp-editor-task.c
+++ b/src/calendar/gui/e-comp-editor-task.c
@@ -511,8 +511,8 @@ ece_task_sensitize_widgets (ECompEditor *comp_editor,
/* Make the Description read-only, not completely insensitive,
thus it can be read and scrolled through and so on */
- widget = e_comp_editor_property_part_get_edit_widget (task_editor->priv->description);
- gtk_text_view_set_editable (GTK_TEXT_VIEW (gtk_bin_get_child (GTK_BIN (widget))),
gtk_widget_get_sensitive (widget));
+ widget = e_comp_editor_property_part_string_get_real_edit_widget (E_COMP_EDITOR_PROPERTY_PART_STRING
(task_editor->priv->description));
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (widget), gtk_widget_get_sensitive (widget));
gtk_widget_set_sensitive (widget, TRUE);
action = e_comp_editor_get_action (comp_editor, "all-day-task");
diff --git a/src/modules/itip-formatter/itip-view.c b/src/modules/itip-formatter/itip-view.c
index 3475125622..a5d5ceeab4 100644
--- a/src/modules/itip-formatter/itip-view.c
+++ b/src/modules/itip-formatter/itip-view.c
@@ -6554,18 +6554,40 @@ itip_view_init_view (ItipView *view)
g_slist_free_full (list, e_cal_component_text_free);
if (gstring) {
- gchar *html;
-
- html = camel_text_to_html (
- gstring->str,
- CAMEL_MIME_FILTER_TOHTML_CONVERT_NL |
- CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES |
- CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS |
- CAMEL_MIME_FILTER_TOHTML_MARK_CITATION |
- CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES,
- 0);
+ gchar *html = NULL;
+
+ /* Google encodes HTML into the description, without giving a clue about it,
+ but try to guess whether it can be an HTML blob or not. */
+ if (camel_strstrcase (gstring->str, "<br>") ||
+ camel_strstrcase (gstring->str, "<span>") ||
+ camel_strstrcase (gstring->str, "<b>") ||
+ camel_strstrcase (gstring->str, "<i>") ||
+ camel_strstrcase (gstring->str, "<u>") ||
+ camel_strstrcase (gstring->str, " ") ||
+ camel_strstrcase (gstring->str, "<ul>") ||
+ camel_strstrcase (gstring->str, "<li>") ||
+ camel_strstrcase (gstring->str, "</a>")) {
+ gchar *ptr = gstring->str;
+ /* To make things easier, Google mixes HTML '<br>' with plain text '\n'... */
+ while (ptr = strchr (ptr, '\n'), ptr) {
+ gssize pos = ptr - gstring->str;
+
+ g_string_insert (gstring, pos, "<br>");
+
+ ptr = gstring->str + pos + 4 + 1;
+ }
+ } else {
+ html = camel_text_to_html (
+ gstring->str,
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_NL |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS |
+ CAMEL_MIME_FILTER_TOHTML_MARK_CITATION |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES,
+ 0);
+ }
- itip_view_set_description (view, html);
+ itip_view_set_description (view, html ? html : gstring->str);
g_string_free (gstring, TRUE);
g_free (html);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]