[evolution] Bug 755418 - "Load Remote Content" info bar is too distracting



commit 7c7eb401f2b65a4cfbe831af6f97e749ff524962
Author: Milan Crha <mcrha redhat com>
Date:   Wed Oct 9 15:30:34 2019 +0200

    Bug 755418 - "Load Remote Content" info bar is too distracting
    
    Closes https://bugzilla.gnome.org/show_bug.cgi?id=755418

 po/POTFILES.in                           |   1 +
 src/em-format/e-mail-formatter-headers.c |  32 ++-
 src/mail/CMakeLists.txt                  |   2 +
 src/mail/e-mail-browser.c                |   2 -
 src/mail/e-mail-display.c                |  49 +++-
 src/mail/e-mail-paned-view.c             |   2 -
 src/mail/e-mail-reader.c                 | 382 ++--------------------------
 src/mail/e-mail-reader.h                 |   2 -
 src/mail/e-mail-remote-content-popover.c | 421 +++++++++++++++++++++++++++++++
 src/mail/e-mail-remote-content-popover.h |  32 +++
 src/mail/mail.error.xml                  |   5 -
 11 files changed, 548 insertions(+), 382 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ef47b85b06..6443ac9378 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -347,6 +347,7 @@ src/mail/e-mail-print-config-headers.c
 src/mail/e-mail-printer.c
 src/mail/e-mail-reader.c
 src/mail/e-mail-reader-utils.c
+src/mail/e-mail-remote-content-popover.c
 src/mail/e-mail-request.c
 src/mail/e-mail-tag-editor.c
 src/mail/e-mail-templates-store.c
diff --git a/src/em-format/e-mail-formatter-headers.c b/src/em-format/e-mail-formatter-headers.c
index 7a4e9e8699..7b796b73bb 100644
--- a/src/em-format/e-mail-formatter-headers.c
+++ b/src/em-format/e-mail-formatter-headers.c
@@ -62,6 +62,7 @@ format_short_headers (EMailFormatter *formatter,
        struct _camel_header_address *addrs = NULL;
        const CamelNameValueArray *headers;
        guint ii, len;
+       gint icon_width, icon_height;
        GString *from;
 
        if (g_cancellable_is_cancelled (cancellable))
@@ -134,9 +135,22 @@ format_short_headers (EMailFormatter *formatter,
        g_string_append (buffer, "</strong>");
        if (from->len > 0)
                g_string_append_printf (buffer, " (%s)", from->str);
-       g_string_append (buffer, "</td></tr>");
+       g_string_append (buffer, "</td>");
+
+       if (!gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, &icon_height)) {
+               icon_width = 16;
+               icon_height = 16;
+       }
+
+       g_string_append (buffer, "<td align=\"right\" valign=\"top\">");
+       g_string_append_printf (buffer,
+               "<img src=\"gtk-stock://dialog-information/?size=%d\" width=\"%dpx\" height=\"%dpx\""
+               " id=\"__evo-remote-content-img-small\" class=\"__evo-remote-content-img\" title=\"%s\" 
style=\"cursor:pointer;\" hidden/>",
+               GTK_ICON_SIZE_MENU, icon_width, icon_height,
+               _("Remote content download had been blocked for this message."));
+       g_string_append (buffer, "</td>");
 
-       g_string_append (buffer, "</table>");
+       g_string_append (buffer, "</tr></table>");
 
        g_free (subject);
        if (addrs)
@@ -229,6 +243,7 @@ format_full_headers (EMailFormatter *formatter,
        const gchar *direction;
        guint ii, len;
        guint32 formatting_flag = 0;
+       gint icon_width, icon_height;
 
        g_return_if_fail (E_IS_MAIL_PART_HEADERS (part));
 
@@ -486,6 +501,19 @@ format_full_headers (EMailFormatter *formatter,
                g_object_unref (image_part);
        }
 
+       if (!gtk_icon_size_lookup (GTK_ICON_SIZE_LARGE_TOOLBAR, &icon_width, &icon_height)) {
+               icon_width = 24;
+               icon_height = 24;
+       }
+
+       g_string_append (buffer, "<td align=\"right\" valign=\"top\">");
+       g_string_append_printf (buffer,
+               "<img src=\"gtk-stock://dialog-information/?size=%d\" width=\"%dpx\" height=\"%dpx\""
+               " id=\"__evo-remote-content-img-large\" class=\"__evo-remote-content-img\" title=\"%s\" 
style=\"cursor:pointer;\" hidden/>",
+               GTK_ICON_SIZE_LARGE_TOOLBAR, icon_width, icon_height,
+               _("Remote content download had been blocked for this message."));
+       g_string_append (buffer, "</td>");
+
        g_string_append (buffer, "</tr></table>");
 
        g_free (face_header_value);
diff --git a/src/mail/CMakeLists.txt b/src/mail/CMakeLists.txt
index a51c1ed251..7c77827b12 100644
--- a/src/mail/CMakeLists.txt
+++ b/src/mail/CMakeLists.txt
@@ -85,6 +85,7 @@ set(SOURCES
        e-mail-reader-utils.c
        e-mail-reader.c
        e-mail-remote-content.c
+       e-mail-remote-content-popover.c
        e-mail-request.c
        e-mail-send-account-override.c
        e-mail-sidebar.c
@@ -175,6 +176,7 @@ set(HEADERS
        e-mail-reader-utils.h
        e-mail-reader.h
        e-mail-remote-content.h
+       e-mail-remote-content-popover.h
        e-mail-request.h
        e-mail-send-account-override.h
        e-mail-sidebar.h
diff --git a/src/mail/e-mail-browser.c b/src/mail/e-mail-browser.c
index 113b2dec97..c6e6096120 100644
--- a/src/mail/e-mail-browser.c
+++ b/src/mail/e-mail-browser.c
@@ -809,8 +809,6 @@ mail_browser_constructed (GObject *object)
                ui_manager, "connect-proxy",
                G_CALLBACK (mail_browser_connect_proxy_cb), object);
 
-       e_mail_reader_connect_remote_content (reader);
-
        /* Configure an EFocusTracker to manage selection actions. */
 
        focus_tracker = e_focus_tracker_new (GTK_WINDOW (object));
diff --git a/src/mail/e-mail-display.c b/src/mail/e-mail-display.c
index c343f32ddd..95c7b6e21b 100644
--- a/src/mail/e-mail-display.c
+++ b/src/mail/e-mail-display.c
@@ -103,8 +103,16 @@ enum {
        PROP_REMOTE_CONTENT
 };
 
+enum {
+       REMOTE_CONTENT_CLICKED,
+       LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
 static CamelDataCache *emd_global_http_cache = NULL;
 
+G_DEFINE_TYPE (EMailDisplay, e_mail_display, E_TYPE_WEB_VIEW)
+
 static const gchar *ui =
 "<ui>"
 "  <popup name='context'>"
@@ -161,11 +169,6 @@ static GtkActionEntry mailto_entries[] = {
          NULL }
 };
 
-G_DEFINE_TYPE (
-       EMailDisplay,
-       e_mail_display,
-       E_TYPE_WEB_VIEW);
-
 static const gchar *attachment_popup_ui =
 "<ui>"
 "  <popup name='context'>"
@@ -1076,6 +1079,20 @@ mail_display_attachment_removed_cb (EAttachmentStore *store,
        g_hash_table_remove (display->priv->attachment_flags, attachment);
 }
 
+static void
+mail_display_remote_content_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)
+{
+       g_return_if_fail (E_IS_MAIL_DISPLAY (web_view));
+
+       g_signal_emit (web_view, signals[REMOTE_CONTENT_CLICKED], 0, element_position, NULL);
+}
+
 static void
 mail_display_load_changed_cb (WebKitWebView *wk_web_view,
                              WebKitLoadEvent load_event,
@@ -1112,6 +1129,8 @@ mail_display_content_loaded_cb (EWebView *web_view,
                        mail_display_attachment_expander_clicked_cb, NULL);
                e_web_view_register_element_clicked (web_view, "attachment-menu",
                        mail_display_attachment_menu_clicked_cb, NULL);
+               e_web_view_register_element_clicked (web_view, "__evo-remote-content-img",
+                       mail_display_remote_content_clicked_cb, NULL);
        }
 
        e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (web_view), e_web_view_get_cancellable (web_view),
@@ -1144,6 +1163,16 @@ mail_display_content_loaded_cb (EWebView *web_view,
                        g_clear_object (&part);
                }
        }
+
+       if (e_mail_display_has_skipped_remote_content_sites (mail_display)) {
+               e_web_view_jsc_set_element_hidden (WEBKIT_WEB_VIEW (web_view),
+                       "", "__evo-remote-content-img-small", FALSE,
+                       e_web_view_get_cancellable (web_view));
+
+               e_web_view_jsc_set_element_hidden (WEBKIT_WEB_VIEW (web_view),
+                       "", "__evo-remote-content-img-large", FALSE,
+                       e_web_view_get_cancellable (web_view));
+       }
 }
 
 static void
@@ -2051,6 +2080,16 @@ e_mail_display_class_init (EMailDisplayClass *class)
                        E_TYPE_MAIL_REMOTE_CONTENT,
                        G_PARAM_READWRITE |
                        G_PARAM_STATIC_STRINGS));
+
+       signals[REMOTE_CONTENT_CLICKED] = g_signal_new (
+               "remote-content-clicked",
+               G_TYPE_FROM_CLASS (class),
+               G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+               0,
+               NULL, NULL,
+               g_cclosure_marshal_VOID__BOXED,
+               G_TYPE_NONE, 1,
+               GDK_TYPE_RECTANGLE);
 }
 
 static void
diff --git a/src/mail/e-mail-paned-view.c b/src/mail/e-mail-paned-view.c
index 410cfd0188..ab2959de70 100644
--- a/src/mail/e-mail-paned-view.c
+++ b/src/mail/e-mail-paned-view.c
@@ -942,8 +942,6 @@ mail_paned_view_constructed (GObject *object)
         * set_preview_visible() method relies on it. */
        e_mail_view_set_preview_visible (view, TRUE);
 
-       e_mail_reader_connect_remote_content (reader);
-
        e_extensible_load_extensions (E_EXTENSIBLE (object));
 
        /* Chain up to parent's constructed() method. */
diff --git a/src/mail/e-mail-reader.c b/src/mail/e-mail-reader.c
index e9edcd857e..e556516679 100644
--- a/src/mail/e-mail-reader.c
+++ b/src/mail/e-mail-reader.c
@@ -45,6 +45,7 @@
 #include "e-mail-label-list-store.h"
 #include "e-mail-notes.h"
 #include "e-mail-reader-utils.h"
+#include "e-mail-remote-content-popover.h"
 #include "e-mail-ui-session.h"
 #include "e-mail-view.h"
 #include "em-composer-utils.h"
@@ -99,8 +100,6 @@ struct _EMailReaderPrivate {
        gboolean schedule_mark_seen;
        guint schedule_mark_seen_interval;
 
-       gpointer remote_content_alert; /* EAlert */
-
        gpointer followup_alert; /* weak pointer to an EAlert */
 
        GSList *ongoing_operations; /* GCancellable * */
@@ -3344,6 +3343,19 @@ mail_reader_load_changed_cb (EMailReader *reader,
        }
 }
 
+static void
+mail_reader_remote_content_clicked_cb (EMailReader *reader,
+                                      const GdkRectangle *position,
+                                      gpointer user_data)
+{
+       GtkWidget *mail_display = user_data;
+
+       g_return_if_fail (E_IS_MAIL_READER (reader));
+       g_return_if_fail (E_IS_MAIL_DISPLAY (mail_display));
+
+       e_mail_remote_content_popover_run (reader, mail_display, position);
+}
+
 static void
 maybe_schedule_timeout_mark_seen (EMailReader *reader)
 {
@@ -5245,6 +5257,10 @@ connect_signals:
                display, "load-changed",
                G_CALLBACK (mail_reader_load_changed_cb), reader);
 
+       g_signal_connect_swapped (
+               display, "remote-content-clicked",
+               G_CALLBACK (mail_reader_remote_content_clicked_cb), reader);
+
        g_signal_connect_swapped (
                message_list, "message-selected",
                G_CALLBACK (mail_reader_message_selected_cb), reader);
@@ -6141,368 +6157,6 @@ e_mail_reader_composer_created (EMailReader *reader,
                reader, signals[COMPOSER_CREATED], 0, composer, message);
 }
 
-static void
-e_mail_reader_load_remote_content_clicked_cb (GtkButton *button,
-                                             EMailReader *reader)
-{
-       EMailDisplay *mail_display;
-
-       g_return_if_fail (E_IS_MAIL_READER (reader));
-
-       mail_display = e_mail_reader_get_mail_display (reader);
-
-       /* This causes reload, thus also alert removal */
-       e_mail_display_load_images (mail_display);
-}
-
-static GList *
-e_mail_reader_get_from_mails (EMailDisplay *mail_display)
-{
-       EMailPartList *part_list;
-       CamelMimeMessage *message;
-       CamelInternetAddress *from;
-       GList *mails = NULL;
-
-       g_return_val_if_fail (E_IS_MAIL_DISPLAY (mail_display), NULL);
-
-       part_list = e_mail_display_get_part_list (mail_display);
-       if (!part_list)
-               return NULL;
-
-       message = e_mail_part_list_get_message (part_list);
-       if (!message)
-               return NULL;
-
-       from = camel_mime_message_get_from (message);
-       if (from) {
-               GHashTable *domains;
-               GHashTableIter iter;
-               gpointer key, value;
-               gint ii, len;
-
-               domains = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
-
-               len = camel_address_length (CAMEL_ADDRESS (from));
-               for (ii = 0; ii < len; ii++) {
-                       const gchar *mail = NULL;
-
-                       if (!camel_internet_address_get (from, ii, NULL, &mail))
-                               break;
-
-                       if (mail && *mail) {
-                               const gchar *at;
-
-                               mails = g_list_prepend (mails, g_strdup (mail));
-
-                               at = strchr (mail, '@');
-                               if (at && at != mail && at[1])
-                                       g_hash_table_insert (domains, (gpointer) at, NULL);
-                       }
-               }
-
-               g_hash_table_iter_init (&iter, domains);
-               while (g_hash_table_iter_next (&iter, &key, &value)) {
-                       const gchar *domain = key;
-
-                       mails = g_list_prepend (mails, g_strdup (domain));
-               }
-
-               g_hash_table_destroy (domains);
-       }
-
-       return g_list_reverse (mails);
-}
-
-static void
-e_mail_reader_remote_content_menu_deactivate_cb (GtkMenuShell *popup_menu,
-                                                GtkToggleButton *toggle_button)
-{
-       g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
-
-       gtk_toggle_button_set_active (toggle_button, FALSE);
-       gtk_menu_detach (GTK_MENU (popup_menu));
-}
-
-#define REMOTE_CONTENT_KEY_IS_MAIL     "remote-content-key-is-mail"
-#define REMOTE_CONTENT_KEY_VALUE       "remote-content-key-value"
-
-static void
-e_mail_reader_remote_content_menu_activate_cb (GObject *item,
-                                              EMailReader *reader)
-{
-       EMailDisplay *mail_display;
-       EMailRemoteContent *remote_content;
-       gboolean is_mail;
-       const gchar *value;
-
-       g_return_if_fail (GTK_IS_MENU_ITEM (item));
-       g_return_if_fail (E_IS_MAIL_READER (reader));
-
-       is_mail = GPOINTER_TO_INT (g_object_get_data (item, REMOTE_CONTENT_KEY_IS_MAIL)) == 1;
-       value = g_object_get_data (item, REMOTE_CONTENT_KEY_VALUE);
-
-       g_return_if_fail (value && *value);
-
-       mail_display = e_mail_reader_get_mail_display (reader);
-       if (!mail_display)
-               return;
-
-       remote_content = e_mail_display_ref_remote_content (mail_display);
-       if (!remote_content)
-               return;
-
-       if (is_mail)
-               e_mail_remote_content_add_mail (remote_content, value);
-       else
-               e_mail_remote_content_add_site (remote_content, value);
-
-       g_clear_object (&remote_content);
-
-       e_mail_display_reload (mail_display);
-}
-
-static void
-e_mail_reader_remote_content_disable_activate_cb (GObject *item,
-                                                 EMailReader *reader)
-{
-       EMailDisplay *mail_display;
-       GSettings *settings;
-
-       g_return_if_fail (E_IS_MAIL_READER (reader));
-
-       settings = e_util_ref_settings ("org.gnome.evolution.mail");
-       g_settings_set_boolean (settings, "notify-remote-content", FALSE);
-       g_clear_object (&settings);
-
-       mail_display = e_mail_reader_get_mail_display (reader);
-       if (mail_display)
-               e_mail_display_reload (mail_display);
-}
-
-static void
-e_mail_reader_add_remote_content_menu_item (EMailReader *reader,
-                                           GtkWidget *popup_menu,
-                                           const gchar *label,
-                                           gboolean is_mail,
-                                           const gchar *value)
-{
-       GtkWidget *item;
-       GObject *object;
-
-       g_return_if_fail (E_IS_MAIL_READER (reader));
-       g_return_if_fail (GTK_IS_MENU (popup_menu));
-       g_return_if_fail (label != NULL);
-       g_return_if_fail (value != NULL);
-
-       item = gtk_menu_item_new_with_label (label);
-       object = G_OBJECT (item);
-
-       g_object_set_data (object, REMOTE_CONTENT_KEY_IS_MAIL, is_mail ? GINT_TO_POINTER (1) : NULL);
-       g_object_set_data_full (object, REMOTE_CONTENT_KEY_VALUE, g_strdup (value), g_free);
-
-       g_signal_connect (item, "activate", G_CALLBACK (e_mail_reader_remote_content_menu_activate_cb), 
reader);
-
-       gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
-}
-
-static void
-e_mail_reader_show_remote_content_popup (EMailReader *reader,
-                                        GdkEventButton *event,
-                                        GtkToggleButton *toggle_button)
-{
-       EMailDisplay *mail_display;
-       GList *mails, *sites, *link;
-       GtkWidget *popup_menu = NULL;
-
-       g_return_if_fail (E_IS_MAIL_READER (reader));
-
-       mail_display = e_mail_reader_get_mail_display (reader);
-       mails = e_mail_reader_get_from_mails (mail_display);
-       sites = e_mail_display_get_skipped_remote_content_sites (mail_display);
-
-       for (link = mails; link; link = g_list_next (link)) {
-               const gchar *mail = link->data;
-               gchar *label;
-
-               if (!mail || !*mail)
-                       continue;
-
-               if (!popup_menu)
-                       popup_menu = gtk_menu_new ();
-
-               if (*mail == '@')
-                       label = g_strdup_printf (_("Allow remote content for anyone from %s"), mail);
-               else
-                       label = g_strdup_printf (_("Allow remote content for %s"), mail);
-
-               e_mail_reader_add_remote_content_menu_item (reader, popup_menu, label, TRUE, mail);
-
-               g_free (label);
-       }
-
-       for (link = sites; link; link = g_list_next (link)) {
-               const gchar *site = link->data;
-               gchar *label;
-
-               if (!site || !*site)
-                       continue;
-
-               if (!popup_menu)
-                       popup_menu = gtk_menu_new ();
-
-               label = g_strdup_printf (_("Allow remote content from %s"), site);
-
-               e_mail_reader_add_remote_content_menu_item (reader, popup_menu, label, FALSE, site);
-
-               g_free (label);
-       }
-
-       g_list_free_full (mails, g_free);
-       g_list_free_full (sites, g_free);
-
-       if (popup_menu) {
-               GtkWidget *box = gtk_widget_get_parent (GTK_WIDGET (toggle_button));
-               GtkWidget *item;
-
-               item = gtk_separator_menu_item_new ();
-               gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
-
-               item = gtk_menu_item_new_with_label (_("Do not show this message again"));
-               gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
-               g_signal_connect (item, "activate", G_CALLBACK 
(e_mail_reader_remote_content_disable_activate_cb), reader);
-
-               gtk_toggle_button_set_active (toggle_button, TRUE);
-
-               g_signal_connect (
-                       popup_menu, "deactivate",
-                       G_CALLBACK (e_mail_reader_remote_content_menu_deactivate_cb), toggle_button);
-
-               gtk_widget_show_all (popup_menu);
-
-               gtk_menu_attach_to_widget (GTK_MENU (popup_menu), box, NULL);
-
-               g_object_set (popup_menu,
-                             "anchor-hints", (GDK_ANCHOR_FLIP_Y |
-                                              GDK_ANCHOR_SLIDE |
-                                              GDK_ANCHOR_RESIZE),
-                             NULL);
-
-               gtk_menu_popup_at_widget (GTK_MENU (popup_menu),
-                                         box,
-                                         GDK_GRAVITY_SOUTH_WEST,
-                                         GDK_GRAVITY_NORTH_WEST,
-                                         (const GdkEvent *) event);
-       }
-}
-
-static gboolean
-e_mail_reader_options_remote_content_button_press_cb (GtkToggleButton *toggle_button,
-                                                     GdkEventButton *event,
-                                                     EMailReader *reader)
-{
-       g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
-
-       if (event && event->button == 1) {
-               e_mail_reader_show_remote_content_popup (reader, event, toggle_button);
-               return TRUE;
-       }
-
-       return FALSE;
-}
-
-static GtkWidget *
-e_mail_reader_create_remote_content_alert_button (EMailReader *reader)
-{
-       GtkWidget *box, *button, *arrow;
-
-       box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-
-       gtk_style_context_add_class (gtk_widget_get_style_context (box), "linked");
-
-       button = gtk_button_new_with_label (_("Load remote content"));
-       gtk_container_add (GTK_CONTAINER (box), button);
-
-       g_signal_connect (button, "clicked",
-               G_CALLBACK (e_mail_reader_load_remote_content_clicked_cb), reader);
-
-       button = gtk_toggle_button_new ();
-       gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
-
-       g_signal_connect (button, "button-press-event",
-               G_CALLBACK (e_mail_reader_options_remote_content_button_press_cb), reader);
-
-       arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
-       gtk_container_add (GTK_CONTAINER (button), arrow);
-
-       gtk_widget_show_all (box);
-
-       return box;
-}
-
-static void
-mail_reader_display_load_changed_cb (EMailDisplay *mail_display,
-                                    WebKitLoadEvent load_event,
-                                    EMailReader *reader)
-{
-       EMailReaderPrivate *priv;
-
-       g_return_if_fail (E_IS_MAIL_DISPLAY (mail_display));
-       g_return_if_fail (E_IS_MAIL_READER (reader));
-
-       priv = E_MAIL_READER_GET_PRIVATE (reader);
-       g_return_if_fail (priv != NULL);
-
-       if (load_event == WEBKIT_LOAD_STARTED) {
-               if (priv->remote_content_alert)
-                       e_alert_response (priv->remote_content_alert, GTK_RESPONSE_CLOSE);
-               return;
-       }
-
-       if (load_event != WEBKIT_LOAD_FINISHED)
-               return;
-
-       if (!e_mail_display_has_skipped_remote_content_sites (mail_display))
-               return;
-
-       if (!priv->remote_content_alert) {
-               EPreviewPane *preview_pane;
-               GtkWidget *button;
-               EAlert *alert;
-
-               alert = e_alert_new ("mail:remote-content-info", NULL);
-               button = e_mail_reader_create_remote_content_alert_button (reader);
-               e_alert_add_widget (alert, button); /* button is consumed by the alert */
-               preview_pane = e_mail_reader_get_preview_pane (reader);
-               e_alert_sink_submit_alert (E_ALERT_SINK (preview_pane), alert);
-
-               priv->remote_content_alert = alert;
-               g_object_add_weak_pointer (G_OBJECT (priv->remote_content_alert), 
&priv->remote_content_alert);
-
-               g_object_unref (alert);
-       }
-}
-
-/**
- * e_mail_reader_connect_remote_content:
- * @reader: an #EMailReader
- *
- * Connects signal handlers to manage remote content download around
- * the internal #EMailDisplay.
- **/
-void
-e_mail_reader_connect_remote_content (EMailReader *reader)
-{
-       EMailDisplay *mail_display;
-
-       g_return_if_fail (E_IS_MAIL_READER (reader));
-
-       mail_display = e_mail_reader_get_mail_display (reader);
-       g_return_if_fail (E_IS_MAIL_DISPLAY (mail_display));
-
-       g_signal_connect (mail_display, "load-changed",
-               G_CALLBACK (mail_reader_display_load_changed_cb), reader);
-}
-
 void
 e_mail_reader_reload (EMailReader *reader)
 {
diff --git a/src/mail/e-mail-reader.h b/src/mail/e-mail-reader.h
index de17f70bf5..05818e9a07 100644
--- a/src/mail/e-mail-reader.h
+++ b/src/mail/e-mail-reader.h
@@ -213,8 +213,6 @@ void                e_mail_reader_unset_folder_just_selected
 void           e_mail_reader_composer_created  (EMailReader *reader,
                                                 EMsgComposer *composer,
                                                 CamelMimeMessage *message);
-void           e_mail_reader_connect_remote_content
-                                               (EMailReader *reader);
 void           e_mail_reader_reload            (EMailReader *reader);
 void           e_mail_reader_remove_ui         (EMailReader *reader);
 
diff --git a/src/mail/e-mail-remote-content-popover.c b/src/mail/e-mail-remote-content-popover.c
new file mode 100644
index 0000000000..3616e8dcc6
--- /dev/null
+++ b/src/mail/e-mail-remote-content-popover.c
@@ -0,0 +1,421 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2019 Red Hat (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of version 2.1. of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "evolution-config.h"
+
+#include <glib/gi18n-lib.h>
+
+#include "e-util/e-util.h"
+#include "e-mail-reader.h"
+
+#include "e-mail-remote-content-popover.h"
+
+#define REMOTE_CONTENT_KEY_POPOVER     "remote-content-key-popover"
+#define REMOTE_CONTENT_KEY_IS_MAIL     "remote-content-key-is-mail"
+#define REMOTE_CONTENT_KEY_VALUE       "remote-content-key-value"
+
+static void
+destroy_remote_content_popover (EMailReader *reader)
+{
+       g_return_if_fail (E_IS_MAIL_READER (reader));
+
+       g_object_set_data (G_OBJECT (reader), REMOTE_CONTENT_KEY_POPOVER, NULL);
+}
+
+static void
+load_remote_content_clicked_cb (GtkButton *button,
+                               EMailReader *reader)
+{
+       EMailDisplay *mail_display;
+
+       g_return_if_fail (E_IS_MAIL_READER (reader));
+
+       destroy_remote_content_popover (reader);
+
+       mail_display = e_mail_reader_get_mail_display (reader);
+
+       /* This causes reload, thus also alert removal */
+       e_mail_display_load_images (mail_display);
+}
+
+static GList *
+get_from_mail_addresses (EMailDisplay *mail_display)
+{
+       EMailPartList *part_list;
+       CamelMimeMessage *message;
+       CamelInternetAddress *from;
+       GList *mails = NULL;
+
+       g_return_val_if_fail (E_IS_MAIL_DISPLAY (mail_display), NULL);
+
+       part_list = e_mail_display_get_part_list (mail_display);
+       if (!part_list)
+               return NULL;
+
+       message = e_mail_part_list_get_message (part_list);
+       if (!message)
+               return NULL;
+
+       from = camel_mime_message_get_from (message);
+       if (from) {
+               GHashTable *domains;
+               GHashTableIter iter;
+               gpointer key, value;
+               gint ii, len;
+
+               domains = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
+
+               len = camel_address_length (CAMEL_ADDRESS (from));
+               for (ii = 0; ii < len; ii++) {
+                       const gchar *mail = NULL;
+
+                       if (!camel_internet_address_get (from, ii, NULL, &mail))
+                               break;
+
+                       if (mail && *mail) {
+                               const gchar *at;
+
+                               mails = g_list_prepend (mails, g_strdup (mail));
+
+                               at = strchr (mail, '@');
+                               if (at && at != mail && at[1])
+                                       g_hash_table_insert (domains, (gpointer) at, NULL);
+                       }
+               }
+
+               g_hash_table_iter_init (&iter, domains);
+               while (g_hash_table_iter_next (&iter, &key, &value)) {
+                       const gchar *domain = key;
+
+                       mails = g_list_prepend (mails, g_strdup (domain));
+               }
+
+               g_hash_table_destroy (domains);
+       }
+
+       return g_list_reverse (mails);
+}
+
+static void
+remote_content_menu_deactivate_cb (GtkMenuShell *popup_menu,
+                                  GtkToggleButton *toggle_button)
+{
+       g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
+
+       gtk_toggle_button_set_active (toggle_button, FALSE);
+       gtk_menu_detach (GTK_MENU (popup_menu));
+}
+
+static void
+remote_content_menu_activate_cb (GObject *item,
+                                EMailReader *reader)
+{
+       EMailDisplay *mail_display;
+       EMailRemoteContent *remote_content;
+       gboolean is_mail;
+       const gchar *value;
+
+       g_return_if_fail (GTK_IS_MENU_ITEM (item));
+       g_return_if_fail (E_IS_MAIL_READER (reader));
+
+       is_mail = GPOINTER_TO_INT (g_object_get_data (item, REMOTE_CONTENT_KEY_IS_MAIL)) == 1;
+       value = g_object_get_data (item, REMOTE_CONTENT_KEY_VALUE);
+
+       destroy_remote_content_popover (reader);
+
+       g_return_if_fail (value && *value);
+
+       mail_display = e_mail_reader_get_mail_display (reader);
+       if (!mail_display)
+               return;
+
+       remote_content = e_mail_display_ref_remote_content (mail_display);
+       if (!remote_content)
+               return;
+
+       if (is_mail)
+               e_mail_remote_content_add_mail (remote_content, value);
+       else
+               e_mail_remote_content_add_site (remote_content, value);
+
+       g_clear_object (&remote_content);
+
+       e_mail_display_reload (mail_display);
+}
+
+static void
+remote_content_disable_activate_cb (GObject *item,
+                                   EMailReader *reader)
+{
+       EMailDisplay *mail_display;
+       GSettings *settings;
+
+       g_return_if_fail (E_IS_MAIL_READER (reader));
+
+       settings = e_util_ref_settings ("org.gnome.evolution.mail");
+       g_settings_set_boolean (settings, "notify-remote-content", FALSE);
+       g_clear_object (&settings);
+
+       destroy_remote_content_popover (reader);
+
+       mail_display = e_mail_reader_get_mail_display (reader);
+       if (mail_display)
+               e_mail_display_reload (mail_display);
+}
+
+static void
+add_remote_content_menu_item (EMailReader *reader,
+                             GtkWidget *popup_menu,
+                             const gchar *label,
+                             gboolean is_mail,
+                             const gchar *value)
+{
+       GtkWidget *item;
+       GObject *object;
+
+       g_return_if_fail (E_IS_MAIL_READER (reader));
+       g_return_if_fail (GTK_IS_MENU (popup_menu));
+       g_return_if_fail (label != NULL);
+       g_return_if_fail (value != NULL);
+
+       item = gtk_menu_item_new_with_label (label);
+       object = G_OBJECT (item);
+
+       g_object_set_data (object, REMOTE_CONTENT_KEY_IS_MAIL, is_mail ? GINT_TO_POINTER (1) : NULL);
+       g_object_set_data_full (object, REMOTE_CONTENT_KEY_VALUE, g_strdup (value), g_free);
+
+       g_signal_connect (item, "activate", G_CALLBACK (remote_content_menu_activate_cb), reader);
+
+       gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
+}
+
+static void
+show_remote_content_popup (EMailReader *reader,
+                          GdkEventButton *event,
+                          GtkToggleButton *toggle_button)
+{
+       EMailDisplay *mail_display;
+       GList *mails, *sites, *link;
+       GtkWidget *popup_menu = NULL;
+
+       g_return_if_fail (E_IS_MAIL_READER (reader));
+
+       mail_display = e_mail_reader_get_mail_display (reader);
+       mails = get_from_mail_addresses (mail_display);
+       sites = e_mail_display_get_skipped_remote_content_sites (mail_display);
+
+       for (link = mails; link; link = g_list_next (link)) {
+               const gchar *mail = link->data;
+               gchar *label;
+
+               if (!mail || !*mail)
+                       continue;
+
+               if (!popup_menu)
+                       popup_menu = gtk_menu_new ();
+
+               if (*mail == '@')
+                       label = g_strdup_printf (_("Allow remote content for anyone from %s"), mail);
+               else
+                       label = g_strdup_printf (_("Allow remote content for %s"), mail);
+
+               add_remote_content_menu_item (reader, popup_menu, label, TRUE, mail);
+
+               g_free (label);
+       }
+
+       for (link = sites; link; link = g_list_next (link)) {
+               const gchar *site = link->data;
+               gchar *label;
+
+               if (!site || !*site)
+                       continue;
+
+               if (!popup_menu)
+                       popup_menu = gtk_menu_new ();
+
+               label = g_strdup_printf (_("Allow remote content from %s"), site);
+
+               add_remote_content_menu_item (reader, popup_menu, label, FALSE, site);
+
+               g_free (label);
+       }
+
+       g_list_free_full (mails, g_free);
+       g_list_free_full (sites, g_free);
+
+       if (popup_menu) {
+               GtkWidget *box = gtk_widget_get_parent (GTK_WIDGET (toggle_button));
+               GtkWidget *item;
+
+               item = gtk_separator_menu_item_new ();
+               gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
+
+               item = gtk_menu_item_new_with_label (_("Do not show this message again"));
+               gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
+               g_signal_connect (item, "activate", G_CALLBACK (remote_content_disable_activate_cb), reader);
+
+               gtk_toggle_button_set_active (toggle_button, TRUE);
+
+               g_signal_connect (
+                       popup_menu, "deactivate",
+                       G_CALLBACK (remote_content_menu_deactivate_cb), toggle_button);
+
+               gtk_widget_show_all (popup_menu);
+
+               gtk_menu_attach_to_widget (GTK_MENU (popup_menu), box, NULL);
+
+               g_object_set (popup_menu,
+                             "anchor-hints", (GDK_ANCHOR_FLIP_Y |
+                                              GDK_ANCHOR_SLIDE |
+                                              GDK_ANCHOR_RESIZE),
+                             NULL);
+
+               gtk_menu_popup_at_widget (GTK_MENU (popup_menu),
+                                         box,
+                                         GDK_GRAVITY_SOUTH_WEST,
+                                         GDK_GRAVITY_NORTH_WEST,
+                                         (const GdkEvent *) event);
+       }
+}
+
+static gboolean
+options_remote_content_button_press_cb (GtkToggleButton *toggle_button,
+                                       GdkEventButton *event,
+                                       EMailReader *reader)
+{
+       g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
+
+       if (event && event->button == 1) {
+               show_remote_content_popup (reader, event, toggle_button);
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+static GtkWidget *
+create_remote_content_alert_button (EMailReader *reader)
+{
+       GtkWidget *box, *button, *arrow;
+
+       box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+
+       gtk_style_context_add_class (gtk_widget_get_style_context (box), "linked");
+
+       button = gtk_button_new_with_label (_("Load remote content"));
+       gtk_container_add (GTK_CONTAINER (box), button);
+
+       g_signal_connect (button, "clicked",
+               G_CALLBACK (load_remote_content_clicked_cb), reader);
+
+       button = gtk_toggle_button_new ();
+       gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
+
+       g_signal_connect (button, "button-press-event",
+               G_CALLBACK (options_remote_content_button_press_cb), reader);
+
+       arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
+       gtk_container_add (GTK_CONTAINER (button), arrow);
+
+       gtk_widget_show_all (box);
+
+       return box;
+}
+
+void
+e_mail_remote_content_popover_run (EMailReader *reader,
+                                  GtkWidget *relative_to,
+                                  const GtkAllocation *position)
+{
+       GtkPopover *popover;
+       GtkWidget *hbox, *vbox, *widget;
+       PangoAttrList *bold;
+
+       g_return_if_fail (E_IS_MAIL_READER (reader));
+       g_return_if_fail (GTK_IS_WIDGET (relative_to));
+       g_return_if_fail (position != NULL);
+
+       popover = GTK_POPOVER (gtk_popover_new (relative_to));
+
+       gtk_popover_set_position (popover, GTK_POS_BOTTOM);
+       gtk_popover_set_pointing_to (popover, position);
+       gtk_popover_set_modal (popover, TRUE);
+
+       gtk_container_set_border_width (GTK_CONTAINER (popover), 12);
+
+       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
+       gtk_container_add (GTK_CONTAINER (popover), hbox);
+
+       widget = gtk_image_new_from_icon_name ("dialog-information", GTK_ICON_SIZE_DND);
+       g_object_set (G_OBJECT (widget),
+               "valign", GTK_ALIGN_START,
+               "vexpand", FALSE,
+               NULL);
+       gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+
+       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
+       g_object_set (G_OBJECT (vbox),
+               "halign", GTK_ALIGN_FILL,
+               "hexpand", TRUE,
+               NULL);
+       gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+
+       bold = pango_attr_list_new ();
+       pango_attr_list_insert (bold, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
+
+       widget = gtk_label_new (_("Remote content download had been blocked for this message."));
+       g_object_set (G_OBJECT (widget),
+               "halign", GTK_ALIGN_FILL,
+               "hexpand", TRUE,
+               "attributes", bold,
+               "wrap", TRUE,
+               "width-chars", 20,
+               "max-width-chars", 80,
+               "xalign", 0.0,
+               NULL);
+       gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
+
+       pango_attr_list_unref (bold);
+
+       widget = gtk_label_new (_("You can download remote content manually, or set to remember to download 
remote content for this sender or used sites."));
+       g_object_set (G_OBJECT (widget),
+               "halign", GTK_ALIGN_FILL,
+               "hexpand", TRUE,
+               "wrap", TRUE,
+               "width-chars", 20,
+               "max-width-chars", 80,
+               "xalign", 0.0,
+               NULL);
+       gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
+
+       widget = create_remote_content_alert_button (reader);
+       g_object_set (G_OBJECT (widget),
+               "halign", GTK_ALIGN_END,
+               "hexpand", TRUE,
+               NULL);
+       gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
+
+       gtk_widget_show_all (hbox);
+
+       g_object_set_data_full (G_OBJECT (reader), REMOTE_CONTENT_KEY_POPOVER, popover, (GDestroyNotify) 
gtk_widget_destroy);
+
+       g_signal_connect_object (popover, "closed",
+               G_CALLBACK (destroy_remote_content_popover), reader, G_CONNECT_SWAPPED);
+
+       gtk_popover_popup (popover);
+}
diff --git a/src/mail/e-mail-remote-content-popover.h b/src/mail/e-mail-remote-content-popover.h
new file mode 100644
index 0000000000..f729a1cb74
--- /dev/null
+++ b/src/mail/e-mail-remote-content-popover.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2019 Red Hat (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of version 2.1. of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef E_MAIL_REMOTE_CONTENT_POPOVER_H
+#define E_MAIL_REMOTE_CONTENT_POPOVER_H
+
+#include <gtk/gtk.h>
+#include <mail/e-mail-reader.h>
+
+G_BEGIN_DECLS
+
+void           e_mail_remote_content_popover_run       (EMailReader *reader,
+                                                        GtkWidget *parent,
+                                                        const GtkAllocation *position);
+
+G_END_DECLS
+
+#endif /* E_MAIL_REMOTE_CONTENT_POPOVER_H */
diff --git a/src/mail/mail.error.xml b/src/mail/mail.error.xml
index 0d7f054b30..17e27a74d4 100644
--- a/src/mail/mail.error.xml
+++ b/src/mail/mail.error.xml
@@ -596,11 +596,6 @@ in the folder will be available in offline mode.</_secondary>
     <secondary>{1}</secondary>
   </error>
 
-  <error id="remote-content-info" type="info">
-    <_primary>Remote content download had been blocked for this message.</_primary>
-    <_secondary>You can download remote content manually, or set to remember to download remote content for 
this sender or used sites.</_secondary>
-  </error>
-
   <error id="follow-up-flag-info" type="info">
     <secondary>{0}</secondary>
   </error>


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