[evolution] Attached meeting invitations not shown properly



commit 4213ff83129b445b3d6f0508f1c7f6d3c057aa70
Author: Milan Crha <mcrha redhat com>
Date:   Thu Dec 15 14:53:14 2016 +0100

    Attached meeting invitations not shown properly
    
    The problem was with the itip-view trying to attach to the DOM
    too early, possibly when the attachment had been still collapsed,
    thus not part of the DOM at all.

 src/em-format/e-mail-formatter-attachment.c   |    6 +-
 src/em-format/e-mail-part-headers.c           |    4 +-
 src/em-format/e-mail-part.c                   |    6 +-
 src/em-format/e-mail-part.h                   |    4 +-
 src/mail/e-mail-display.c                     |   87 +++++++++++++++++++++++--
 src/modules/itip-formatter/e-mail-part-itip.c |   26 +++----
 src/modules/vcard-inline/e-mail-part-vcard.c  |   32 ++++++---
 src/web-extensions/e-web-extension.c          |   29 ++++++++
 8 files changed, 152 insertions(+), 42 deletions(-)
---
diff --git a/src/em-format/e-mail-formatter-attachment.c b/src/em-format/e-mail-formatter-attachment.c
index 348656d..ad12eeb 100644
--- a/src/em-format/e-mail-formatter-attachment.c
+++ b/src/em-format/e-mail-formatter-attachment.c
@@ -304,10 +304,8 @@ emfe_attachment_format (EMailFormatterExtension *extension,
 
                        inner_html_data = g_markup_escape_text (data, size);
 
-                       g_string_append_printf (
-                               buffer,
-                               " inner-html-data=\"%s\">",
-                               inner_html_data);
+                       g_string_append_printf (buffer, " related-part-id=\"%s\" inner-html-data=\"%s\">",
+                               attachment_part_id, inner_html_data);
 
                        g_free (inner_html_data);
                }
diff --git a/src/em-format/e-mail-part-headers.c b/src/em-format/e-mail-part-headers.c
index f56edaa..c509040 100644
--- a/src/em-format/e-mail-part-headers.c
+++ b/src/em-format/e-mail-part-headers.c
@@ -216,10 +216,12 @@ mail_part_headers_constructed (GObject *object)
 
 static void
 mail_part_headers_bind_dom_element (EMailPart *part,
-                                    GDBusProxy *web_extension,
+                                    EWebView *web_view,
                                     guint64 page_id,
                                     const gchar *element_id)
 {
+       GDBusProxy *web_extension = e_web_view_get_web_extension_proxy (web_view);
+
        if (web_extension) {
                e_util_invoke_g_dbus_proxy_call_with_error_check (
                        web_extension,
diff --git a/src/em-format/e-mail-part.c b/src/em-format/e-mail-part.c
index 3b16025..4aca446 100644
--- a/src/em-format/e-mail-part.c
+++ b/src/em-format/e-mail-part.c
@@ -583,21 +583,21 @@ e_mail_part_set_is_attachment (EMailPart *part,
 
 void
 e_mail_part_bind_dom_element (EMailPart *part,
-                              GDBusProxy *web_extension,
+                              EWebView *web_view,
                               guint64 page_id,
                               const gchar *element_id)
 {
        EMailPartClass *class;
 
        g_return_if_fail (E_IS_MAIL_PART (part));
-       g_return_if_fail (web_extension);
+       g_return_if_fail (E_IS_WEB_VIEW (web_view));
        g_return_if_fail (page_id != 0);
        g_return_if_fail (element_id && *element_id);
 
        class = E_MAIL_PART_GET_CLASS (part);
 
        if (class->bind_dom_element != NULL)
-               class->bind_dom_element (part, web_extension, page_id, element_id);
+               class->bind_dom_element (part, web_view, page_id, element_id);
 }
 
 void
diff --git a/src/em-format/e-mail-part.h b/src/em-format/e-mail-part.h
index 72e17ad..db13f05 100644
--- a/src/em-format/e-mail-part.h
+++ b/src/em-format/e-mail-part.h
@@ -86,7 +86,7 @@ struct _EMailPartClass {
        GObjectClass parent_class;
 
        void            (*bind_dom_element)     (EMailPart *part,
-                                                GDBusProxy *web_extension,
+                                                EWebView *web_view,
                                                 guint64 page_id,
                                                 const gchar *element_id);
        void            (*web_view_loaded)      (EMailPart *part,
@@ -124,7 +124,7 @@ gboolean    e_mail_part_get_is_attachment   (EMailPart *part);
 void           e_mail_part_set_is_attachment   (EMailPart *part,
                                                 gboolean is_attachment);
 void           e_mail_part_bind_dom_element    (EMailPart *part,
-                                                GDBusProxy *web_extension,
+                                                EWebView *web_view,
                                                 guint64 page_id,
                                                 const gchar *element_id);
 void           e_mail_part_web_view_loaded     (EMailPart *part,
diff --git a/src/mail/e-mail-display.c b/src/mail/e-mail-display.c
index 27d1f3c..d92d667 100644
--- a/src/mail/e-mail-display.c
+++ b/src/mail/e-mail-display.c
@@ -86,6 +86,7 @@ struct _EMailDisplayPrivate {
        GHashTable *skipped_remote_content_sites;
 
        guint web_extension_headers_collapsed_signal_id;
+       guint web_extension_mail_part_appeared_signal_id;
 
        GtkAllocation attachment_popup_position;
 };
@@ -535,6 +536,41 @@ headers_collapsed_signal_cb (GDBusConnection *connection,
 }
 
 static void
+mail_display_mail_part_appeared_signal_cb (GDBusConnection *connection,
+                                          const gchar *sender_name,
+                                          const gchar *object_path,
+                                          const gchar *interface_name,
+                                          const gchar *signal_name,
+                                          GVariant *parameters,
+                                          gpointer user_data)
+{
+       EMailDisplay *display = user_data;
+       const gchar *part_id = NULL;
+       guint64 page_id = 0;
+       EMailPart *part;
+
+       if (g_strcmp0 (signal_name, "MailPartAppeared") != 0)
+               return;
+
+       g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+       if (!parameters || !display->priv->part_list)
+               return;
+
+       g_variant_get (parameters, "(t&s)", &page_id, &part_id);
+
+       if (!part_id || !*part_id || page_id != webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (display)))
+               return;
+
+       part = e_mail_part_list_ref_part (display->priv->part_list, part_id);
+       if (part && g_strcmp0 (e_mail_part_get_id (part), part_id) == 0) {
+               e_mail_part_bind_dom_element (part, E_WEB_VIEW (display), page_id, part_id);
+       }
+
+       g_clear_object (&part);
+}
+
+static void
 setup_dom_bindings (EMailDisplay *display)
 {
        GDBusProxy *web_extension;
@@ -557,6 +593,21 @@ setup_dom_bindings (EMailDisplay *display)
                                        NULL);
                }
 
+               if (display->priv->web_extension_mail_part_appeared_signal_id == 0) {
+                       display->priv->web_extension_mail_part_appeared_signal_id =
+                               g_dbus_connection_signal_subscribe (
+                                       g_dbus_proxy_get_connection (web_extension),
+                                       g_dbus_proxy_get_name (web_extension),
+                                       E_WEB_EXTENSION_INTERFACE,
+                                       "MailPartAppeared",
+                                       E_WEB_EXTENSION_OBJECT_PATH,
+                                       NULL,
+                                       G_DBUS_SIGNAL_FLAGS_NONE,
+                                       mail_display_mail_part_appeared_signal_cb,
+                                       display,
+                                       NULL);
+               }
+
                e_util_invoke_g_dbus_proxy_call_with_error_check (
                        web_extension,
                        "EMailDisplayBindDOM",
@@ -1091,19 +1142,25 @@ mail_display_attachment_removed_cb (EAttachmentStore *store,
        g_hash_table_remove (display->priv->attachment_flags, attachment);
 }
 
+typedef struct _MailElementExistsData {
+       EWebView *web_view;
+       EMailPart *part;
+} MailElementExistsData;
+
 static void
 mail_element_exists_cb (GObject *source_object,
                         GAsyncResult *result,
                         gpointer user_data)
 {
        GDBusProxy *web_extension;
-       EMailPart *part = user_data;
+       MailElementExistsData *meed = user_data;
        gboolean element_exists = FALSE;
        GVariant *result_variant;
        guint64 page_id;
        GError *error = NULL;
 
        g_return_if_fail (G_IS_DBUS_PROXY (source_object));
+       g_return_if_fail (meed != NULL);
 
        web_extension = G_DBUS_PROXY (source_object);
 
@@ -1115,12 +1172,14 @@ mail_element_exists_cb (GObject *source_object,
 
        if (element_exists)
                e_mail_part_bind_dom_element (
-                       part,
-                       web_extension,
+                       meed->part,
+                       meed->web_view,
                        page_id,
-                       e_mail_part_get_id (part));
+                       e_mail_part_get_id (meed->part));
 
-       g_object_unref (part);
+       g_object_unref (meed->web_view);
+       g_object_unref (meed->part);
+       g_free (meed);
 
        if (error)
                g_dbus_error_strip_remote_error (error);
@@ -1155,6 +1214,7 @@ mail_parts_bind_dom (EMailDisplay *display)
        head = g_queue_peek_head_link (&queue);
 
        for (link = head; link != NULL; link = g_list_next (link)) {
+               MailElementExistsData *meed;
                EMailPart *part = E_MAIL_PART (link->data);
                const gchar *part_id;
 
@@ -1164,6 +1224,10 @@ mail_parts_bind_dom (EMailDisplay *display)
 
                e_mail_part_web_view_loaded (part, web_view);
 
+               meed = g_new0 (MailElementExistsData, 1);
+               meed->web_view = g_object_ref (web_view);
+               meed->part = g_object_ref (part);
+
                g_dbus_proxy_call (
                        web_extension,
                        "ElementExists",
@@ -1176,7 +1240,7 @@ mail_parts_bind_dom (EMailDisplay *display)
                        -1,
                        NULL,
                        mail_element_exists_cb,
-                       g_object_ref (part));
+                       meed);
        }
 
        while (!g_queue_is_empty (&queue))
@@ -1350,6 +1414,17 @@ mail_display_dispose (GObject *object)
                priv->web_extension_headers_collapsed_signal_id = 0;
        }
 
+       if (priv->web_extension_mail_part_appeared_signal_id > 0) {
+               GDBusProxy *web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (object));
+
+               if (web_extension != NULL) {
+                       g_dbus_connection_signal_unsubscribe (
+                               g_dbus_proxy_get_connection (web_extension),
+                               priv->web_extension_mail_part_appeared_signal_id);
+               }
+               priv->web_extension_mail_part_appeared_signal_id = 0;
+       }
+
        if (priv->attachment_store) {
                /* To have called the mail_display_attachment_removed_cb() before it's disconnected */
                e_attachment_store_remove_all (priv->attachment_store);
diff --git a/src/modules/itip-formatter/e-mail-part-itip.c b/src/modules/itip-formatter/e-mail-part-itip.c
index 7b1f7dd..e991da0 100644
--- a/src/modules/itip-formatter/e-mail-part-itip.c
+++ b/src/modules/itip-formatter/e-mail-part-itip.c
@@ -70,29 +70,25 @@ mail_part_itip_finalize (GObject *object)
 }
 
 static void
-mail_part_itip_web_view_loaded (EMailPart *mail_part,
-                               EWebView *web_view)
+mail_part_itip_bind_dom_element (EMailPart *part,
+                                EWebView *web_view,
+                                guint64 page_id,
+                                const gchar *element_id)
 {
        EMailPartItip *pitip;
        ItipView *itip_view;
 
-       g_return_if_fail (E_IS_MAIL_PART_ITIP (mail_part));
+       g_return_if_fail (E_IS_MAIL_PART_ITIP (part));
        g_return_if_fail (E_IS_WEB_VIEW (web_view));
 
-       pitip = E_MAIL_PART_ITIP (mail_part);
+       if (g_strcmp0 (element_id, e_mail_part_get_id (part)) != 0)
+               return;
 
-       /* FIXME WK2 - it can sometimes happen that the pitip members, like the folder, message_uid and 
message,
-          are not initialized yet, because the internal frame in the main EWebView is not passed
-          through the EMailFormatter, where these are set. This requires a new signal on the WebKitWebView,
-          ideally, to call this only after the iframe is truly loaded (these pitip members are only a side
-          effect of a whole issue with non-knowing that a particular iframe was fully loaded).
+       pitip = E_MAIL_PART_ITIP (part);
 
-          Also retest what happens when the same meeting is opened in multiple windows; it could crash in 
gtk+
-          when a button was clicked in one or the other, but also not always.
-       */
        itip_view = itip_view_new (
-               webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view)),
-               e_mail_part_get_id (mail_part),
+               page_id,
+               e_mail_part_get_id (part),
                pitip,
                pitip->folder,
                pitip->message_uid,
@@ -119,7 +115,7 @@ e_mail_part_itip_class_init (EMailPartItipClass *class)
        object_class->finalize = mail_part_itip_finalize;
 
        mail_part_class = E_MAIL_PART_CLASS (class);
-       mail_part_class->web_view_loaded = mail_part_itip_web_view_loaded;
+       mail_part_class->bind_dom_element = mail_part_itip_bind_dom_element;
 }
 
 static void
diff --git a/src/modules/vcard-inline/e-mail-part-vcard.c b/src/modules/vcard-inline/e-mail-part-vcard.c
index db7e790..c940724 100644
--- a/src/modules/vcard-inline/e-mail-part-vcard.c
+++ b/src/modules/vcard-inline/e-mail-part-vcard.c
@@ -253,6 +253,8 @@ mail_part_vcard_dispose (GObject *object)
                part->priv->save_vcard_button_pressed_signal_id = 0;
        }
 
+       g_clear_object (&part->priv->web_extension);
+
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (e_mail_part_vcard_parent_class)->dispose (object);
 }
@@ -295,24 +297,32 @@ mail_part_vcard_constructed (GObject *object)
 
 static void
 mail_part_vcard_bind_dom_element (EMailPart *part,
-                                  GDBusProxy *evolution_web_extension,
+                                  EWebView *web_view,
                                   guint64 page_id,
                                   const gchar *element_id)
 {
        EMailPartVCard *vcard_part;
+       GDBusProxy *web_extension;
+
+       g_return_if_fail (E_IS_WEB_VIEW (web_view));
+       g_return_if_fail (E_IS_MAIL_PART_VCARD (part));
+
+       web_extension = e_web_view_get_web_extension_proxy (web_view);
+       if (!web_extension)
+               return;
 
        vcard_part = E_MAIL_PART_VCARD (part);
 
-       vcard_part->priv->web_extension = evolution_web_extension;
+       vcard_part->priv->web_extension = g_object_ref (web_extension);
        vcard_part->priv->page_id = page_id;
 
        vcard_part->priv->display_mode_toggled_signal_id =
                g_dbus_connection_signal_subscribe (
-                       g_dbus_proxy_get_connection (evolution_web_extension),
-                       g_dbus_proxy_get_name (evolution_web_extension),
-                       g_dbus_proxy_get_interface_name (evolution_web_extension),
+                       g_dbus_proxy_get_connection (web_extension),
+                       g_dbus_proxy_get_name (web_extension),
+                       g_dbus_proxy_get_interface_name (web_extension),
                        "VCardInlineDisplayModeToggled",
-                       g_dbus_proxy_get_object_path (evolution_web_extension),
+                       g_dbus_proxy_get_object_path (web_extension),
                        NULL,
                        G_DBUS_SIGNAL_FLAGS_NONE,
                        (GDBusSignalCallback) display_mode_toggle_cb,
@@ -321,11 +331,11 @@ mail_part_vcard_bind_dom_element (EMailPart *part,
 
        vcard_part->priv->save_vcard_button_pressed_signal_id =
                g_dbus_connection_signal_subscribe (
-                       g_dbus_proxy_get_connection (evolution_web_extension),
-                       g_dbus_proxy_get_name (evolution_web_extension),
-                       g_dbus_proxy_get_interface_name (evolution_web_extension),
+                       g_dbus_proxy_get_connection (web_extension),
+                       g_dbus_proxy_get_name (web_extension),
+                       g_dbus_proxy_get_interface_name (web_extension),
                        "VCardInlineSaveButtonPressed",
-                       g_dbus_proxy_get_object_path (evolution_web_extension),
+                       g_dbus_proxy_get_object_path (web_extension),
                        NULL,
                        G_DBUS_SIGNAL_FLAGS_NONE,
                        (GDBusSignalCallback) save_vcard_cb,
@@ -333,7 +343,7 @@ mail_part_vcard_bind_dom_element (EMailPart *part,
                        NULL);
 
        e_util_invoke_g_dbus_proxy_call_with_error_check (
-               vcard_part->priv->web_extension,
+               web_extension,
                "VCardInlineBindDOM",
                g_variant_new (
                        "(ts)",
diff --git a/src/web-extensions/e-web-extension.c b/src/web-extensions/e-web-extension.c
index c827be9..1d3254f 100644
--- a/src/web-extensions/e-web-extension.c
+++ b/src/web-extensions/e-web-extension.c
@@ -191,6 +191,10 @@ static const char introspection_xml[] =
 "      <arg type='t' name='page_id' direction='out'/>"
 "      <arg type='u' name='flags' direction='out'/>"
 "    </signal>"
+"    <signal name='MailPartAppeared'>"
+"      <arg type='t' name='page_id' direction='out'/>"
+"      <arg type='s' name='part_id' direction='out'/>"
+"    </signal>"
 "  </interface>"
 "</node>";
 
@@ -571,8 +575,33 @@ handle_method_call (GDBusConnection *connection,
 
                                        inner_html_data = webkit_dom_element_get_attribute (element, 
"inner-html-data");
                                        if (inner_html_data && *inner_html_data) {
+                                               gchar *related_part_id;
+
                                                webkit_dom_element_set_inner_html (element, inner_html_data, 
NULL);
                                                webkit_dom_element_remove_attribute (element, 
"inner-html-data");
+
+                                               related_part_id = webkit_dom_element_get_attribute (element, 
"related-part-id");
+                                               webkit_dom_element_remove_attribute (element, 
"related-part-id");
+
+                                               if (related_part_id && *related_part_id) {
+                                                       GError *error = NULL;
+
+                                                       g_dbus_connection_emit_signal (
+                                                               extension->priv->dbus_connection,
+                                                               NULL,
+                                                               E_WEB_EXTENSION_OBJECT_PATH,
+                                                               E_WEB_EXTENSION_INTERFACE,
+                                                               "MailPartAppeared",
+                                                               g_variant_new ("(ts)", page_id, 
related_part_id),
+                                                               &error);
+
+                                                       if (error) {
+                                                               g_warning ("Error emitting signal 
MailPartAppeared: %s", error->message);
+                                                               g_error_free (error);
+                                                       }
+                                               }
+
+                                               g_free (related_part_id);
                                        }
 
                                        g_free (inner_html_data);


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