[evolution/wip/webkit2] Replace EAttachmentButton with a native HTML code and change the EAttachmentBar position
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/webkit2] Replace EAttachmentButton with a native HTML code and change the EAttachmentBar position
- Date: Wed, 1 Jun 2016 21:59:50 +0000 (UTC)
commit c8660c0a37918cf3edd96ec1a4736f9fd9cd39f9
Author: Milan Crha <mcrha redhat com>
Date: Wed Jun 1 23:57:39 2016 +0200
Replace EAttachmentButton with a native HTML code and change the EAttachmentBar position
No more EMailFormatterClass:get_widget(). There are new FIXME WK2,
unfortunately, but to be done soon.
data/org.gnome.evolution.mail.gschema.xml.in | 5 +
e-util/Makefile.am | 2 -
e-util/e-attachment-button.c | 929 ----------------------
e-util/e-attachment-button.h | 95 ---
e-util/e-attachment-store.c | 53 ++-
e-util/e-attachment-store.h | 11 +
e-util/e-stock-request.c | 35 +
e-util/e-util.h | 1 -
e-util/e-web-view.c | 97 +++
e-util/e-web-view.h | 15 +
em-format/Makefile.am | 4 -
em-format/e-mail-formatter-attachment-bar.c | 104 ---
em-format/e-mail-formatter-attachment.c | 246 ++----
em-format/e-mail-formatter-audio.c | 2 +-
em-format/e-mail-formatter-extension.c | 61 --
em-format/e-mail-formatter-extension.h | 11 -
em-format/e-mail-formatter.c | 21 +-
em-format/e-mail-formatter.h | 6 +-
em-format/e-mail-parser-attachment-bar.c | 78 --
em-format/e-mail-parser-message.c | 6 -
em-format/e-mail-parser.c | 2 -
em-format/e-mail-part-attachment-bar.c | 98 ---
em-format/e-mail-part-attachment-bar.h | 70 --
em-format/e-mail-part-attachment.h | 2 +-
em-format/e-mail-part-utils.c | 5 +
mail/e-mail-browser.c | 14 +
mail/e-mail-display.c | 1083 +++++++++++---------------
mail/e-mail-display.h | 9 +
mail/e-mail-request.c | 91 +++
modules/mail/e-mail-shell-content.c | 57 ++-
modules/mail/e-mail-shell-content.h | 2 +
modules/mail/e-mail-shell-view-actions.c | 32 +
modules/mail/e-mail-shell-view-actions.h | 2 +
po/POTFILES.in | 1 +
ui/evolution-mail.ui | 1 +
web-extensions/e-dom-utils.c | 51 +-
web-extensions/e-web-extension.c | 159 ++++
37 files changed, 1161 insertions(+), 2300 deletions(-)
---
diff --git a/data/org.gnome.evolution.mail.gschema.xml.in b/data/org.gnome.evolution.mail.gschema.xml.in
index 24d18e0..7b90aa0 100644
--- a/data/org.gnome.evolution.mail.gschema.xml.in
+++ b/data/org.gnome.evolution.mail.gschema.xml.in
@@ -294,6 +294,11 @@
<_summary>Timeout for marking messages as seen</_summary>
<_description>Timeout in milliseconds for marking messages as seen.</_description>
</key>
+ <key name="show-attachment-bar" type="b">
+ <default>true</default>
+ <_summary>Show Attachment Bar</_summary>
+ <_description>Show Attachment Bar below the message preview pane when the message has
attachments.</_description>
+ </key>
<key name="show-email" type="b">
<default>false</default>
<_summary>Sender email-address column in the message list</_summary>
diff --git a/e-util/Makefile.am b/e-util/Makefile.am
index 40ae077..721e6b0 100644
--- a/e-util/Makefile.am
+++ b/e-util/Makefile.am
@@ -119,7 +119,6 @@ evolution_util_include_HEADERS = \
e-alert-sink.h \
e-alert.h \
e-attachment-bar.h \
- e-attachment-button.h \
e-attachment-dialog.h \
e-attachment-handler-image.h \
e-attachment-handler.h \
@@ -395,7 +394,6 @@ libevolution_util_la_SOURCES = \
e-alert-sink.c \
e-alert.c \
e-attachment-bar.c \
- e-attachment-button.c \
e-attachment-dialog.c \
e-attachment-handler-image.c \
e-attachment-handler.c \
diff --git a/e-util/e-attachment-store.c b/e-util/e-attachment-store.c
index f0648db..ab6247d 100644
--- a/e-util/e-attachment-store.c
+++ b/e-util/e-attachment-store.c
@@ -53,6 +53,14 @@ enum {
PROP_TOTAL_SIZE
};
+enum {
+ ATTACHMENT_ADDED,
+ ATTACHMENT_REMOVED,
+ LAST_SIGNAL
+};
+
+static gulong signals[LAST_SIGNAL];
+
G_DEFINE_TYPE (
EAttachmentStore,
e_attachment_store,
@@ -159,6 +167,22 @@ e_attachment_store_class_init (EAttachmentStoreClass *class)
G_MAXUINT64,
0,
G_PARAM_READABLE));
+
+ signals[ATTACHMENT_ADDED] = g_signal_new (
+ "attachment-added",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAttachmentStoreClass, attachment_added),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1, E_TYPE_ATTACHMENT);
+
+ signals[ATTACHMENT_REMOVED] = g_signal_new (
+ "attachment-removed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAttachmentStoreClass, attachment_removed),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1, E_TYPE_ATTACHMENT);
}
static void
@@ -232,6 +256,8 @@ e_attachment_store_add_attachment (EAttachmentStore *store,
g_object_notify (G_OBJECT (store), "num-attachments");
g_object_notify (G_OBJECT (store), "total-size");
g_object_thaw_notify (G_OBJECT (store));
+
+ g_signal_emit (store, signals[ATTACHMENT_ADDED], 0, attachment);
}
gboolean
@@ -243,6 +269,7 @@ e_attachment_store_remove_attachment (EAttachmentStore *store,
GtkTreeModel *model;
GtkTreePath *path;
GtkTreeIter iter;
+ gboolean removed;
g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), FALSE);
g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE);
@@ -254,7 +281,8 @@ e_attachment_store_remove_attachment (EAttachmentStore *store,
return FALSE;
if (!gtk_tree_row_reference_valid (reference)) {
- g_hash_table_remove (hash_table, attachment);
+ if (g_hash_table_remove (hash_table, attachment))
+ g_signal_emit (store, signals[ATTACHMENT_REMOVED], 0, attachment);
return FALSE;
}
@@ -267,13 +295,16 @@ e_attachment_store_remove_attachment (EAttachmentStore *store,
gtk_tree_path_free (path);
gtk_list_store_remove (GTK_LIST_STORE (store), &iter);
- g_hash_table_remove (hash_table, attachment);
+ removed = g_hash_table_remove (hash_table, attachment);
g_object_freeze_notify (G_OBJECT (store));
g_object_notify (G_OBJECT (store), "num-attachments");
g_object_notify (G_OBJECT (store), "total-size");
g_object_thaw_notify (G_OBJECT (store));
+ if (removed)
+ g_signal_emit (store, signals[ATTACHMENT_REMOVED], 0, attachment);
+
return TRUE;
}
@@ -307,6 +338,8 @@ e_attachment_store_remove_all (EAttachmentStore *store)
e_attachment_set_reference (attachment, NULL);
g_warn_if_fail (g_hash_table_remove (store->priv->attachment_index, attachment));
+
+ g_signal_emit (store, signals[ATTACHMENT_REMOVED], 0, attachment);
}
g_list_foreach (list, (GFunc) g_object_unref, NULL);
@@ -780,6 +813,22 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store,
return destination;
}
+gboolean
+e_attachment_store_transform_num_attachments_to_visible_boolean (GBinding *binding,
+ const GValue *from_value,
+ GValue *to_value,
+ gpointer user_data)
+{
+ g_return_val_if_fail (from_value != NULL, FALSE);
+ g_return_val_if_fail (to_value != NULL, FALSE);
+ g_return_val_if_fail (G_VALUE_HOLDS_UINT (from_value), FALSE);
+ g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (to_value), FALSE);
+
+ g_value_set_boolean (to_value, g_value_get_uint (from_value) != 0);
+
+ return TRUE;
+}
+
/******************** e_attachment_store_get_uris_async() ********************/
typedef struct _UriContext UriContext;
diff --git a/e-util/e-attachment-store.h b/e-util/e-attachment-store.h
index 584110c..2e68aa9 100644
--- a/e-util/e-attachment-store.h
+++ b/e-util/e-attachment-store.h
@@ -60,6 +60,12 @@ struct _EAttachmentStore {
struct _EAttachmentStoreClass {
GtkListStoreClass parent_class;
+
+ /* Signals */
+ void (* attachment_added) (EAttachmentStore *store,
+ EAttachment *attachment);
+ void (* attachment_removed) (EAttachmentStore *store,
+ EAttachment *attachment);
};
enum {
@@ -104,6 +110,11 @@ GFile * e_attachment_store_run_save_dialog
GList *attachment_list,
GtkWindow *parent);
+gboolean e_attachment_store_transform_num_attachments_to_visible_boolean
+ (GBinding *binding,
+ const GValue *from_value,
+ GValue *to_value,
+ gpointer user_data);
/* Asynchronous Operations */
void e_attachment_store_get_uris_async
(EAttachmentStore *store,
diff --git a/e-util/e-stock-request.c b/e-util/e-stock-request.c
index dac07ed..c550a2c 100644
--- a/e-util/e-stock-request.c
+++ b/e-util/e-stock-request.c
@@ -166,6 +166,41 @@ process_stock_request_idle_cb (gpointer user_data)
}
gtk_icon_info_free (icon_info);
+ } else if (g_strcmp0 (suri->host, "x-evolution-arrow-down") == 0) {
+ GdkPixbuf *pixbuf;
+ GdkRGBA rgba;
+ guchar *data;
+ gint stride;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, size);
+ buff_len = stride * size;
+ data = g_malloc0 (buff_len);
+ surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_RGB24, size, size,
stride);
+
+ cr = cairo_create (surface);
+
+ if (gtk_style_context_lookup_color (context, "color", &rgba))
+ gdk_cairo_set_source_rgba (cr, &rgba);
+ else
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
+
+ gtk_render_background (context, cr, 0, 0, size, size);
+ gtk_render_arrow (context, cr, G_PI, 0, 0, size);
+
+ cairo_destroy (cr);
+
+ cairo_surface_flush (surface);
+
+ pixbuf = gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, TRUE, 8, size, size,
stride, NULL, NULL);
+ gdk_pixbuf_save_to_buffer (
+ pixbuf, &buffer, &buff_len,
+ "png", &local_error, NULL);
+ g_object_unref (pixbuf);
+
+ cairo_surface_destroy (surface);
+ g_free (data);
}
}
diff --git a/e-util/e-util.h b/e-util/e-util.h
index 25f0330..1e7b4fd 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -32,7 +32,6 @@
#include <e-util/e-alert-sink.h>
#include <e-util/e-alert.h>
#include <e-util/e-attachment-bar.h>
-#include <e-util/e-attachment-button.h>
#include <e-util/e-attachment-dialog.h>
#include <e-util/e-attachment-handler-image.h>
#include <e-util/e-attachment-handler.h>
diff --git a/e-util/e-web-view.c b/e-util/e-web-view.c
index 2020478..bebd007 100644
--- a/e-util/e-web-view.c
+++ b/e-util/e-web-view.c
@@ -4395,3 +4395,100 @@ e_web_view_unregister_element_clicked (EWebView *web_view,
}
}
}
+
+void
+e_web_view_set_element_hidden (EWebView *web_view,
+ const gchar *element_id,
+ gboolean hidden)
+{
+ GDBusProxy *web_extension;
+
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+ g_return_if_fail (element_id && *element_id);
+
+ web_extension = e_web_view_get_web_extension_proxy (web_view);
+ if (!web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ web_extension,
+ "SetElementHidden",
+ g_variant_new (
+ "(tsb)",
+ webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view)),
+ element_id,
+ hidden),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+}
+
+void
+e_web_view_set_element_style_property (EWebView *web_view,
+ const gchar *element_id,
+ const gchar *property_name,
+ const gchar *value,
+ const gchar *priority)
+{
+ GDBusProxy *web_extension;
+
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+ g_return_if_fail (element_id && *element_id);
+ g_return_if_fail (property_name && *property_name);
+
+ web_extension = e_web_view_get_web_extension_proxy (web_view);
+ if (!web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ web_extension,
+ "SetElementStyleProperty",
+ g_variant_new (
+ "(tssss)",
+ webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view)),
+ element_id,
+ property_name,
+ value ? value : "",
+ priority ? priority : ""),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+}
+
+void
+e_web_view_set_element_attribute (EWebView *web_view,
+ const gchar *element_id,
+ const gchar *namespace_uri,
+ const gchar *qualified_name,
+ const gchar *value)
+{
+ GDBusProxy *web_extension;
+
+ g_return_if_fail (E_IS_WEB_VIEW (web_view));
+ g_return_if_fail (element_id && *element_id);
+ g_return_if_fail (qualified_name && *qualified_name);
+
+ web_extension = e_web_view_get_web_extension_proxy (web_view);
+ if (!web_extension)
+ return;
+
+ g_dbus_proxy_call (
+ web_extension,
+ "SetElementAttribute",
+ g_variant_new (
+ "(tssss)",
+ webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (web_view)),
+ element_id,
+ namespace_uri ? namespace_uri : "",
+ qualified_name,
+ value ? value : ""),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+}
diff --git a/e-util/e-web-view.h b/e-util/e-web-view.h
index 73e3bcc..62203d2 100644
--- a/e-util/e-web-view.h
+++ b/e-util/e-web-view.h
@@ -276,6 +276,21 @@ void e_web_view_unregister_element_clicked
const gchar *element_class,
EWebViewElementClickedFunc callback,
gpointer user_data);
+void e_web_view_set_element_hidden (EWebView *web_view,
+ const gchar *element_id,
+ gboolean hidden);
+void e_web_view_set_element_style_property
+ (EWebView *web_view,
+ const gchar *element_id,
+ const gchar *property_name,
+ const gchar *value,
+ const gchar *priority);
+void e_web_view_set_element_attribute
+ (EWebView *web_view,
+ const gchar *element_id,
+ const gchar *namespace_uri,
+ const gchar *qualified_name,
+ const gchar *value);
G_END_DECLS
#endif /* E_WEB_VIEW_H */
diff --git a/em-format/Makefile.am b/em-format/Makefile.am
index 8939280..ca80983 100644
--- a/em-format/Makefile.am
+++ b/em-format/Makefile.am
@@ -34,7 +34,6 @@ evolution_mail_formatter_include_HEADERS = \
e-mail-parser.h \
e-mail-part.h \
e-mail-part-attachment.h \
- e-mail-part-attachment-bar.h \
e-mail-part-audio.h \
e-mail-part-headers.h \
e-mail-part-image.h \
@@ -70,7 +69,6 @@ libevolution_mail_formatter_la_SOURCES = \
e-mail-formatter-quote.c \
e-mail-formatter-utils.c \
e-mail-formatter-attachment.c \
- e-mail-formatter-attachment-bar.c \
e-mail-formatter-audio.c \
e-mail-formatter-enumtypes.c \
e-mail-formatter-error.c \
@@ -93,7 +91,6 @@ libevolution_mail_formatter_la_SOURCES = \
e-mail-parser-extension.c \
e-mail-parser.c \
e-mail-parser-application-mbox.c \
- e-mail-parser-attachment-bar.c \
e-mail-parser-audio.c \
e-mail-parser-headers.c \
e-mail-parser-image.c \
@@ -117,7 +114,6 @@ libevolution_mail_formatter_la_SOURCES = \
e-mail-parser-text-plain.c \
e-mail-part.c \
e-mail-part-attachment.c \
- e-mail-part-attachment-bar.c \
e-mail-part-audio.c \
e-mail-part-headers.c \
e-mail-part-image.c \
diff --git a/em-format/e-mail-formatter-attachment.c b/em-format/e-mail-formatter-attachment.c
index 2a2f2c9..01109cd 100644
--- a/em-format/e-mail-formatter-attachment.c
+++ b/em-format/e-mail-formatter-attachment.c
@@ -26,7 +26,6 @@
#include "e-mail-formatter-extension.h"
#include "e-mail-inline-filter.h"
-#include "e-mail-part-attachment-bar.h"
#include "e-mail-part-attachment.h"
#include "e-mail-part-utils.h"
@@ -44,70 +43,10 @@ G_DEFINE_TYPE (
static const gchar *formatter_mime_types[] = {
E_MAIL_PART_ATTACHMENT_MIME_TYPE,
- "application/vnd.evolution.widget.attachment-button",
+ "application/vnd.evolution.attachment-button",
NULL
};
-static EAttachmentStore *
-find_attachment_store (EMailPartList *part_list,
- EMailPart *start)
-{
- EAttachmentStore *store = NULL;
- GQueue queue = G_QUEUE_INIT;
- GList *head, *link;
- const gchar *start_id;
- gchar *tmp, *pos;
- EMailPart *part;
- gchar *id;
-
- start_id = e_mail_part_get_id (start);
-
- e_mail_part_list_queue_parts (part_list, NULL, &queue);
-
- head = g_queue_peek_head_link (&queue);
-
- id = g_strconcat (start_id, ".attachment-bar", NULL);
- tmp = g_strdup (id);
- part = NULL;
- do {
- d (printf ("Looking up attachment bar as %s\n", id));
-
- for (link = head; link != NULL; link = g_list_next (link)) {
- EMailPart *p = link->data;
- const gchar *p_id;
-
- p_id = e_mail_part_get_id (p);
-
- if (g_strcmp0 (p_id, id) == 0) {
- part = p;
- break;
- }
- }
-
- pos = g_strrstr (tmp, ".");
- if (!pos)
- break;
-
- g_free (id);
- g_free (tmp);
- tmp = g_strndup (start_id, pos - tmp);
- id = g_strdup_printf ("%s.attachment-bar", tmp);
-
- } while (pos && !part);
-
- g_free (id);
- g_free (tmp);
-
- if (part != NULL)
- store = e_mail_part_attachment_bar_get_store (
- E_MAIL_PART_ATTACHMENT_BAR (part));
-
- while (!g_queue_is_empty (&queue))
- g_object_unref (g_queue_pop_head (&queue));
-
- return store;
-}
-
static gboolean
emfe_attachment_format (EMailFormatterExtension *extension,
EMailFormatter *formatter,
@@ -118,13 +57,16 @@ emfe_attachment_format (EMailFormatterExtension *extension,
{
gchar *text, *html;
gchar *button_id;
- EAttachmentStore *store;
EMailExtensionRegistry *registry;
GQueue *extensions;
EMailPartAttachment *empa;
CamelMimePart *mime_part;
CamelMimeFilterToHTMLFlags flags;
+ GOutputStream *content_stream = NULL;
GString *buffer;
+ gint icon_width, icon_height;
+ gchar *icon_uri;
+ gpointer attachment_ptr = NULL;
const gchar *attachment_part_id;
const gchar *part_id;
@@ -139,8 +81,8 @@ emfe_attachment_format (EMailFormatterExtension *extension,
EAttachment *attachment;
GList *head, *link;
- attachment = e_mail_part_attachment_ref_attachment (
- E_MAIL_PART_ATTACHMENT (part));
+ attachment = e_mail_part_attachment_ref_attachment (E_MAIL_PART_ATTACHMENT (part));
+ attachment_ptr = attachment;
head = g_queue_peek_head_link (&part->validities);
@@ -161,17 +103,9 @@ emfe_attachment_format (EMailFormatterExtension *extension,
pair->validity->encrypt.status);
}
- store = find_attachment_store (context->part_list, part);
- if (store) {
- GList *attachments = e_attachment_store_get_attachments (store);
- if (!g_list_find (attachments, attachment)) {
- e_attachment_store_add_attachment (
- store, attachment);
- }
- g_list_free_full (attachments, g_object_unref);
- } else {
- g_warning ("Failed to locate attachment-bar for %s", part_id);
- }
+ e_attachment_set_shown (attachment, e_mail_part_should_show_inline (part));
+
+ e_mail_formatter_claim_attachment (formatter, attachment);
g_object_unref (attachment);
}
@@ -262,26 +196,12 @@ emfe_attachment_format (EMailFormatterExtension *extension,
button_id = g_strconcat (attachment_part_id, ".attachment_button", NULL);
- /* XXX Wild guess at the initial size. */
- buffer = g_string_sized_new (8192);
-
- g_string_append_printf (
- buffer,
- "<div class=\"attachment\">"
- "<table width=\"100%%\" border=\"0\">"
- "<tr valign=\"middle\">"
- "<td align=\"left\" width=\"100\">"
- "<object type=\"application/vnd.evolution.widget.attachment-button\" "
- "height=\"20\" width=\"100\" data=\"%s\" id=\"%s\"></object>"
- "</td>"
- "<td align=\"left\">%s</td>"
- "</tr>", part_id, button_id, html);
-
- g_free (button_id);
- g_free (html);
+ if (!gtk_icon_size_lookup (GTK_ICON_SIZE_BUTTON, &icon_width, &icon_height)) {
+ icon_width = 16;
+ icon_height = 16;
+ }
if (extensions != NULL) {
- GOutputStream *content_stream;
gboolean success = FALSE;
content_stream = g_memory_output_stream_new_resizable ();
@@ -322,51 +242,85 @@ emfe_attachment_format (EMailFormatterExtension *extension,
}
}
- if (success) {
- gchar *wrapper_element_id;
- gconstpointer data;
- gsize size;
+ e_mail_part_attachment_set_expandable (empa, success);
+ }
- wrapper_element_id = g_strconcat (
- attachment_part_id, ".wrapper", NULL);
+ icon_uri = e_mail_part_build_uri (
+ e_mail_part_list_get_folder (context->part_list),
+ e_mail_part_list_get_message_uid (context->part_list),
+ "part_id", G_TYPE_STRING, part_id,
+ "attachment_icon", G_TYPE_POINTER, attachment_ptr,
+ "size", G_TYPE_INT, icon_width,
+ NULL);
- data = g_memory_output_stream_get_data (
- G_MEMORY_OUTPUT_STREAM (content_stream));
- size = g_memory_output_stream_get_data_size (
- G_MEMORY_OUTPUT_STREAM (content_stream));
+ /* XXX Wild guess at the initial size. */
+ buffer = g_string_sized_new (8192);
- g_string_append_printf (
- buffer,
- "<tr><td colspan=\"2\">"
- "<div class=\"attachment-wrapper\" id=\"%s\"",
- wrapper_element_id);
+ g_string_append_printf (
+ buffer,
+ "<div class=\"attachment\">"
+ "<table width=\"100%%\" border=\"0\">"
+ "<tr valign=\"middle\">"
+ "<td align=\"left\" width=\"1px\" style=\"white-space:pre;\">"
+ "<button type=\"button\" class=\"attachment-expander\" id=\"%s\" value=\"%p\" data=\"%s\"
style=\"vertical-align:middle; margin:0px;\" %s>"
+ "<img id=\"attachment-expander-img-%p\" src=\"gtk-stock://%s?size=%d\" width=\"%dpx\"
height=\"%dpx\" style=\"vertical-align:middle;\">"
+ "<img src=\"%s\" width=\"%dpx\" height=\"%dpx\" style=\"vertical-align:middle;\">"
+ "</button>"
+ "<button type=\"button\" class=\"attachment-menu\" id=\"%s\" value=\"%p\"
style=\"vertical-align:middle; margin:0px;\">"
+ "<img src=\"gtk-stock://x-evolution-arrow-down?size=%d\" width=\"%dpx\" height=\"%dpx\"
style=\"vertical-align:middle;\">"
+ "</button>"
+ "</td><td align=\"left\">%s</td></tr>",
+ part_id, attachment_ptr, html, e_mail_part_attachment_get_expandable (empa) ? "" : "disabled",
+ attachment_ptr, e_mail_part_should_show_inline (part) ? "go-down" : "go-next",
GTK_ICON_SIZE_BUTTON, icon_width, icon_height,
+ icon_uri, icon_width, icon_height,
+ part_id, attachment_ptr, GTK_ICON_SIZE_BUTTON, icon_width, icon_height,
+ html);
+
+ g_free (icon_uri);
+ g_free (button_id);
+ g_free (html);
- if (e_mail_part_should_show_inline (part)) {
- g_string_append (buffer, ">");
- g_string_append_len (buffer, data, size);
- } else {
- gchar *inner_html_data;
+ if (content_stream && e_mail_part_attachment_get_expandable (empa)) {
+ gchar *wrapper_element_id;
+ gconstpointer data;
+ gsize size;
- inner_html_data = g_markup_escape_text (data, size);
+ wrapper_element_id = g_strdup_printf ("attachment-wrapper-%p", attachment_ptr);
- g_string_append_printf (
- buffer,
- " inner-html-data=\"%s\">",
- inner_html_data);
+ data = g_memory_output_stream_get_data (
+ G_MEMORY_OUTPUT_STREAM (content_stream));
+ size = g_memory_output_stream_get_data_size (
+ G_MEMORY_OUTPUT_STREAM (content_stream));
- g_free (inner_html_data);
- }
+ g_string_append_printf (
+ buffer,
+ "<tr><td colspan=\"2\">"
+ "<div class=\"attachment-wrapper\" id=\"%s\"",
+ wrapper_element_id);
- g_string_append (buffer, "</div></td></tr>");
+ if (e_mail_part_should_show_inline (part)) {
+ g_string_append (buffer, ">");
+ g_string_append_len (buffer, data, size);
+ } else {
+ gchar *inner_html_data;
- e_mail_part_attachment_set_expandable (empa, TRUE);
+ inner_html_data = g_markup_escape_text (data, size);
- g_free (wrapper_element_id);
+ g_string_append_printf (
+ buffer,
+ " inner-html-data=\"%s\">",
+ inner_html_data);
+
+ g_free (inner_html_data);
}
- g_object_unref (content_stream);
+ g_string_append (buffer, "</div></td></tr>");
+
+ g_free (wrapper_element_id);
}
+ g_clear_object (&content_stream);
+
g_string_append (buffer, "</table></div>");
g_output_stream_write_all (
@@ -377,47 +331,6 @@ emfe_attachment_format (EMailFormatterExtension *extension,
return TRUE;
}
-static GtkWidget *
-emfe_attachment_get_widget (EMailFormatterExtension *extension,
- EMailPartList *context,
- EMailPart *part,
- GHashTable *params)
-{
- EAttachment *attachment;
- EAttachmentStore *store;
- EAttachmentView *view;
- GtkWidget *widget;
- const gchar *part_id;
-
- g_return_val_if_fail (E_IS_MAIL_PART_ATTACHMENT (part), NULL);
-
- attachment = e_mail_part_attachment_ref_attachment (
- E_MAIL_PART_ATTACHMENT (part));
-
- part_id = e_mail_part_get_id (part);
-
- store = find_attachment_store (context, part);
- widget = e_attachment_button_new ();
- g_object_set_data_full (
- G_OBJECT (widget),
- "uri", g_strdup (part_id),
- (GDestroyNotify) g_free);
- e_attachment_button_set_attachment (
- E_ATTACHMENT_BUTTON (widget), attachment);
-
- view = g_object_get_data (G_OBJECT (store), "attachment-bar");
- if (view != NULL)
- e_attachment_button_set_view (
- E_ATTACHMENT_BUTTON (widget), view);
-
- gtk_widget_set_can_focus (widget, TRUE);
- gtk_widget_show (widget);
-
- g_object_unref (attachment);
-
- return widget;
-}
-
static void
e_mail_formatter_attachment_class_init (EMailFormatterExtensionClass *class)
{
@@ -426,7 +339,6 @@ e_mail_formatter_attachment_class_init (EMailFormatterExtensionClass *class)
class->mime_types = formatter_mime_types;
class->priority = G_PRIORITY_LOW;
class->format = emfe_attachment_format;
- class->get_widget = emfe_attachment_get_widget;
}
static void
diff --git a/em-format/e-mail-formatter-audio.c b/em-format/e-mail-formatter-audio.c
index cf980f8..2837000 100644
--- a/em-format/e-mail-formatter-audio.c
+++ b/em-format/e-mail-formatter-audio.c
@@ -40,7 +40,7 @@ G_DEFINE_TYPE (
E_TYPE_MAIL_FORMATTER_EXTENSION)
static const gchar *formatter_mime_types[] = {
- "application/vnd.evolution.widget.audio",
+ "application/vnd.evolution.audio",
"audio/ac3",
"audio/x-ac3",
"audio/basic",
diff --git a/em-format/e-mail-formatter-extension.c b/em-format/e-mail-formatter-extension.c
index 55b481b..3a2dd52 100644
--- a/em-format/e-mail-formatter-extension.c
+++ b/em-format/e-mail-formatter-extension.c
@@ -78,64 +78,3 @@ e_mail_formatter_extension_format (EMailFormatterExtension *extension,
return class->format (
extension, formatter, context, part, stream, cancellable);
}
-
-/**
- * e_mail_formatter_extension_has_widget:
- * @extension: an #EMailFormatterExtension
- *
- * Returns whether the extension can provide a GtkWidget.
- *
- * Returns: Returns %TRUE when @extension reimplements get_widget(), %FALSE
- * otherwise.
- */
-gboolean
-e_mail_formatter_extension_has_widget (EMailFormatterExtension *extension)
-{
- EMailFormatterExtensionClass *class;
-
- g_return_val_if_fail (E_IS_MAIL_FORMATTER_EXTENSION (extension), FALSE);
-
- class = E_MAIL_FORMATTER_EXTENSION_GET_CLASS (extension);
-
- return (class->get_widget != NULL);
-}
-
-/**
- * e_mail_formatter_extension_get_widget:
- * @extension: an #EMailFormatterExtension
- * @part: an #EMailPart
- * @params: a #GHashTable
- *
- * A virtual function reimplemented in some mail formatter extensions. The
- * function should construct a #GtkWidget for given @part. The @params hash
- * table can contain additional parameters listed in the <object> HTML
- * element that has requested the widget.
- *
- * When @bind_dom_func is not %NULL, the callee will set a callback function
- * which should be called when the webpage is completely rendered to setup
- * bindings between DOM events and the widget.
- *
- * Returns: Returns a #GtkWidget or %NULL, when error occurs or given
- * @extension does not reimplement this method.
- */
-GtkWidget *
-e_mail_formatter_extension_get_widget (EMailFormatterExtension *extension,
- EMailPartList *context,
- EMailPart *part,
- GHashTable *params)
-{
- EMailFormatterExtensionClass *class;
- GtkWidget *widget = NULL;
-
- g_return_val_if_fail (E_IS_MAIL_FORMATTER_EXTENSION (extension), NULL);
- g_return_val_if_fail (part != NULL, NULL);
- g_return_val_if_fail (params != NULL, NULL);
-
- class = E_MAIL_FORMATTER_EXTENSION_GET_CLASS (extension);
-
- if (class->get_widget != NULL)
- widget = class->get_widget (extension, context, part, params);
-
- return widget;
-}
-
diff --git a/em-format/e-mail-formatter-extension.h b/em-format/e-mail-formatter-extension.h
index adfe98f..8e46deb 100644
--- a/em-format/e-mail-formatter-extension.h
+++ b/em-format/e-mail-formatter-extension.h
@@ -83,10 +83,6 @@ struct _EMailFormatterExtensionClass {
EMailPart *part,
GOutputStream *stream,
GCancellable *cancellable);
- GtkWidget * (*get_widget) (EMailFormatterExtension *extension,
- EMailPartList *context,
- EMailPart *part,
- GHashTable *params);
};
GType e_mail_formatter_extension_get_type
@@ -98,13 +94,6 @@ gboolean e_mail_formatter_extension_format
EMailPart *part,
GOutputStream *stream,
GCancellable *cancellable);
-gboolean e_mail_formatter_extension_has_widget
- (EMailFormatterExtension *extension);
-GtkWidget * e_mail_formatter_extension_get_widget
- (EMailFormatterExtension *extension,
- EMailPartList *context,
- EMailPart *part,
- GHashTable *params);
G_END_DECLS
diff --git a/em-format/e-mail-formatter.c b/em-format/e-mail-formatter.c
index abbc93c..559872f 100644
--- a/em-format/e-mail-formatter.c
+++ b/em-format/e-mail-formatter.c
@@ -63,7 +63,6 @@ struct _AsyncContext {
/* internal formatter extensions */
GType e_mail_formatter_attachment_get_type (void);
-GType e_mail_formatter_attachment_bar_get_type (void);
GType e_mail_formatter_audio_get_type (void);
GType e_mail_formatter_error_get_type (void);
GType e_mail_formatter_headers_get_type (void);
@@ -96,6 +95,7 @@ enum {
enum {
NEED_REDRAW,
+ CLAIM_ATTACHMENT,
LAST_SIGNAL
};
@@ -560,7 +560,6 @@ e_mail_formatter_base_init (EMailFormatterClass *class)
/* Register internal extensions. */
g_type_ensure (e_mail_formatter_attachment_get_type ());
- g_type_ensure (e_mail_formatter_attachment_bar_get_type ());
g_type_ensure (e_mail_formatter_audio_get_type ());
g_type_ensure (e_mail_formatter_error_get_type ());
g_type_ensure (e_mail_formatter_headers_get_type ());
@@ -773,6 +772,14 @@ e_mail_formatter_class_init (EMailFormatterClass *class)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
+ signals[CLAIM_ATTACHMENT] = g_signal_new (
+ "claim-attachment",
+ E_TYPE_MAIL_FORMATTER,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMailFormatterClass, claim_attachment),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1, E_TYPE_ATTACHMENT);
+
signals[NEED_REDRAW] = g_signal_new (
"need-redraw",
E_TYPE_MAIL_FORMATTER,
@@ -837,6 +844,16 @@ e_mail_formatter_get_type (void)
}
void
+e_mail_formatter_claim_attachment (EMailFormatter *formatter,
+ EAttachment *attachment)
+{
+ g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
+ g_return_if_fail (E_IS_ATTACHMENT (attachment));
+
+ g_signal_emit (formatter, signals[CLAIM_ATTACHMENT], 0, attachment);
+}
+
+void
e_mail_formatter_format_sync (EMailFormatter *formatter,
EMailPartList *part_list,
GOutputStream *stream,
diff --git a/em-format/e-mail-formatter.h b/em-format/e-mail-formatter.h
index a05755c..777e31a 100644
--- a/em-format/e-mail-formatter.h
+++ b/em-format/e-mail-formatter.h
@@ -85,13 +85,17 @@ struct _EMailFormatterClass {
/* Signals */
void (*need_redraw) (EMailFormatter *formatter);
+ void (*claim_attachment) (EMailFormatter *formatter,
+ EAttachment *attachment);
};
GType e_mail_formatter_get_type (void);
EMailFormatter *
e_mail_formatter_new (void);
-
+void e_mail_formatter_claim_attachment
+ (EMailFormatter *formatter,
+ EAttachment *attachment);
void e_mail_formatter_format_sync (EMailFormatter *formatter,
EMailPartList *part_list,
GOutputStream *stream,
diff --git a/em-format/e-mail-parser-message.c b/em-format/e-mail-parser-message.c
index 282cef4..0a3b77f 100644
--- a/em-format/e-mail-parser-message.c
+++ b/em-format/e-mail-parser-message.c
@@ -63,12 +63,6 @@ empe_message_parse (EMailParserExtension *extension,
"application/vnd.evolution.headers",
cancellable, out_mail_parts);
- /* Attachment Bar */
- e_mail_parser_parse_part_as (
- parser, part, part_id,
- "application/vnd.evolution.widget.attachment-bar",
- cancellable, out_mail_parts);
-
ct = camel_mime_part_get_content_type (part);
mime_type = camel_content_type_simple (ct);
diff --git a/em-format/e-mail-parser.c b/em-format/e-mail-parser.c
index c78cb70..c45291a 100644
--- a/em-format/e-mail-parser.c
+++ b/em-format/e-mail-parser.c
@@ -53,7 +53,6 @@ enum {
/* internal parser extensions */
GType e_mail_parser_application_mbox_get_type (void);
-GType e_mail_parser_attachment_bar_get_type (void);
GType e_mail_parser_audio_get_type (void);
GType e_mail_parser_headers_get_type (void);
GType e_mail_parser_message_get_type (void);
@@ -221,7 +220,6 @@ e_mail_parser_base_init (EMailParserClass *class)
/* Register internal extensions. */
g_type_ensure (e_mail_parser_application_mbox_get_type ());
- g_type_ensure (e_mail_parser_attachment_bar_get_type ());
g_type_ensure (e_mail_parser_audio_get_type ());
g_type_ensure (e_mail_parser_headers_get_type ());
g_type_ensure (e_mail_parser_message_get_type ());
diff --git a/em-format/e-mail-part-attachment.h b/em-format/e-mail-part-attachment.h
index bdf859c..0bfeb7e 100644
--- a/em-format/e-mail-part-attachment.h
+++ b/em-format/e-mail-part-attachment.h
@@ -52,7 +52,7 @@ struct _EMailPartAttachment {
EMailPart parent;
EMailPartAttachmentPrivate *priv;
- gchar *attachment_view_part_id;
+ gchar *attachment_view_part_id; /* FIXME WK2: maybe drop this property */
gboolean shown;
const gchar *snoop_mime_type;
diff --git a/em-format/e-mail-part-utils.c b/em-format/e-mail-part-utils.c
index afc28f4..6fef915 100644
--- a/em-format/e-mail-part-utils.c
+++ b/em-format/e-mail-part-utils.c
@@ -485,6 +485,11 @@ e_mail_part_build_uri (CamelFolder *folder,
g_free (escaped);
break;
}
+ case G_TYPE_POINTER: {
+ gpointer val = va_arg (ap, gpointer);
+ tmp2 = g_strdup_printf ("%s%c%s=%p", tmp, separator, name, val);
+ break;
+ }
default:
g_warning ("Invalid param type %s", g_type_name (type));
va_end (ap);
diff --git a/mail/e-mail-browser.c b/mail/e-mail-browser.c
index b733caf..6bd0d09 100644
--- a/mail/e-mail-browser.c
+++ b/mail/e-mail-browser.c
@@ -604,6 +604,7 @@ mail_browser_constructed (GObject *object)
EShellBackend *shell_backend;
EShell *shell;
EFocusTracker *focus_tracker;
+ EAttachmentStore *attachment_store;
GtkAccelGroup *accel_group;
GtkActionGroup *action_group;
GtkAction *action;
@@ -752,6 +753,19 @@ mail_browser_constructed (GObject *object)
browser->priv->preview_pane,
TRUE, TRUE, 0);
+ attachment_store = e_mail_display_get_attachment_store (E_MAIL_DISPLAY (display));
+ widget = e_attachment_bar_new (attachment_store);
+ e_mail_display_set_attachment_view (E_MAIL_DISPLAY (display), E_ATTACHMENT_VIEW (widget));
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ e_binding_bind_property_full (
+ attachment_store, "num-attachments",
+ widget, "visible",
+ G_BINDING_SYNC_CREATE,
+ e_attachment_store_transform_num_attachments_to_visible_boolean,
+ NULL, NULL, NULL);
+
id = "org.gnome.evolution.mail.browser";
e_plugin_ui_register_manager (ui_manager, id, object);
e_plugin_ui_enable_manager (ui_manager, id);
diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c
index 24a080e..5bea493 100644
--- a/mail/e-mail-display.c
+++ b/mail/e-mail-display.c
@@ -52,6 +52,8 @@
((obj), E_TYPE_MAIL_DISPLAY, EMailDisplayPrivate))
struct _EMailDisplayPrivate {
+ EAttachmentStore *attachment_store;
+ GWeakRef *attachment_view; /* EAttachmentView * */
EMailPartList *part_list;
EMailFormatterMode mode;
EMailFormatter *formatter;
@@ -62,8 +64,6 @@ struct _EMailDisplayPrivate {
GSettings *settings;
- GHashTable *widgets;
-
guint scheduled_reload;
GHashTable *old_settings;
@@ -73,10 +73,14 @@ struct _EMailDisplayPrivate {
GHashTable *skipped_remote_content_sites;
guint web_extension_headers_collapsed_signal_id;
+
+ GtkAllocation attachment_popup_position;
};
enum {
PROP_0,
+ PROP_ATTACHMENT_STORE,
+ PROP_ATTACHMENT_VIEW,
PROP_FORMATTER,
PROP_HEADERS_COLLAPSABLE,
PROP_HEADERS_COLLAPSED,
@@ -278,30 +282,6 @@ mail_display_update_formatter_colors (EMailDisplay *display)
e_mail_formatter_update_style (formatter, state_flags);
}
-#if 0
-static void
-mail_display_plugin_widget_disconnect_children (GtkWidget *widget,
- gpointer mail_display)
-{
- g_signal_handlers_disconnect_by_data (widget, mail_display);
-}
-
-static void
-mail_display_plugin_widget_disconnect (gpointer widget_uri,
- gpointer widget,
- gpointer mail_display)
-{
- if (E_IS_ATTACHMENT_BAR (widget))
- g_signal_handlers_disconnect_by_data (widget, mail_display);
- else if (E_IS_ATTACHMENT_BUTTON (widget))
- g_signal_handlers_disconnect_by_data (widget, mail_display);
- else if (GTK_IS_CONTAINER (widget))
- gtk_container_foreach (
- widget,
- mail_display_plugin_widget_disconnect_children,
- mail_display);
-}
-#endif
static gboolean
mail_display_process_mailto (EWebView *web_view,
const gchar *mailto_uri,
@@ -390,542 +370,8 @@ decide_policy_cb (WebKitWebView *web_view,
/* Let WebKit handle it. */
return FALSE;
}
-#if 0 /* FIXME WK2 */
-static WebKitDOMElement *
-find_element_by_id (WebKitDOMDocument *document,
- const gchar *id)
-{
- WebKitDOMNodeList *frames;
- WebKitDOMElement *element = NULL;
- gulong ii, length;
-
- if (!WEBKIT_DOM_IS_DOCUMENT (document))
- return NULL;
-
- /* Try to look up the element in this DOM document */
- element = webkit_dom_document_get_element_by_id (document, id);
- if (element != NULL)
- return element;
-
- /* If the element is not here then recursively scan all frames */
- frames = webkit_dom_document_get_elements_by_tag_name (
- document, "iframe");
- length = webkit_dom_node_list_get_length (frames);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMHTMLIFrameElement *iframe;
- WebKitDOMDocument *frame_doc;
- WebKitDOMElement *element;
-
- iframe = WEBKIT_DOM_HTML_IFRAME_ELEMENT (
- webkit_dom_node_list_item (frames, ii));
-
- frame_doc = webkit_dom_html_iframe_element_get_content_document (iframe);
-
- element = find_element_by_id (frame_doc, id);
-
- if (element != NULL)
- goto out;
- }
- out:
- g_object_unref (frames);
-
- return element;
-}
-
-static void
-mail_display_plugin_widget_resize (GtkWidget *widget,
- gpointer dummy,
- EMailDisplay *display)
-{
- WebKitDOMElement *parent_element;
- gchar *dim;
- gint height, width;
- gfloat scale;
-
- parent_element = g_object_get_data (
- G_OBJECT (widget), "parent_element");
-
- if (!WEBKIT_DOM_IS_ELEMENT (parent_element)) {
- d (
- printf ("%s: %s does not have (valid) parent element!\n",
- G_STRFUNC, (gchar *) g_object_get_data (G_OBJECT (widget), "uri")));
- return;
- }
-
- scale = webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW (display));
- width = gtk_widget_get_allocated_width (widget);
- gtk_widget_get_preferred_height_for_width (widget, width, &height, NULL);
-
- /* When zooming WebKit does not change dimensions of the elements,
- * but only scales them on the canvas. GtkWidget can't be scaled
- * though so we need to cope with the dimension changes to keep the
- * the widgets the correct size. Due to inaccuracy in rounding
- * (float -> int) it still acts a bit funny, but at least it does
- * not cause widgets in WebKit to go crazy when zooming. */
- height = height * (1 / scale);
-
- /* Int -> Str */
- dim = g_strdup_printf ("%d", height);
-
- /* Set height of the containment <object> to match height of the
- * GtkWidget it contains */
- webkit_dom_html_object_element_set_height (
- WEBKIT_DOM_HTML_OBJECT_ELEMENT (parent_element), dim);
- g_free (dim);
-}
-
-static void
-plugin_widget_set_parent_element (GtkWidget *widget,
- EMailDisplay *display)
-{
- const gchar *uri;
- WebKitDOMDocument *document;
- WebKitDOMElement *element;
-
- uri = g_object_get_data (G_OBJECT (widget), "uri");
- if (uri == NULL || *uri == '\0')
- return;
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (display));
- element = find_element_by_id (document, uri);
-
- if (!WEBKIT_DOM_IS_ELEMENT (element)) {
- g_warning ("Failed to find parent <object> for '%s' - no ID set?", uri);
- return;
- }
-
- /* Assign the WebKitDOMElement to "parent_element" data of the
- * GtkWidget and the GtkWidget to "widget" data of the DOM Element. */
- g_object_set_data (G_OBJECT (widget), "parent_element", element);
- g_object_set_data (G_OBJECT (element), "widget", widget);
-
- e_binding_bind_property (
- element, "hidden",
- widget, "visible",
- G_BINDING_SYNC_CREATE |
- G_BINDING_INVERT_BOOLEAN);
-}
-
-static void
-attachment_button_expanded (GObject *object,
- GParamSpec *pspec,
- gpointer user_data)
-{
- EAttachmentButton *button = E_ATTACHMENT_BUTTON (object);
- EMailDisplay *display = user_data;
- WebKitDOMDocument *document;
- WebKitDOMElement *element, *iframe;
- WebKitDOMCSSStyleDeclaration *css;
- const gchar *attachment_part_id;
- gchar *element_id;
- gboolean expanded;
-
- d (
- printf ("Attachment button %s has been %s!\n",
- (gchar *) g_object_get_data (object, "uri"),
- (e_attachment_button_get_expanded (button) ? "expanded" : "collapsed")));
-
- expanded =
- e_attachment_button_get_expanded (button) &&
- gtk_widget_get_visible (GTK_WIDGET (button));
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (display));
- attachment_part_id = g_object_get_data (object, "attachment_id");
-
- element_id = g_strconcat (attachment_part_id, ".wrapper", NULL);
- element = find_element_by_id (document, element_id);
- g_free (element_id);
-
- if (!WEBKIT_DOM_IS_ELEMENT (element)) {
- d (
- printf ("%s: Content <div> of attachment %s does not exist!!\n",
- G_STRFUNC, (gchar *) g_object_get_data (object, "uri")));
- return;
- }
-
- if (WEBKIT_DOM_IS_HTML_ELEMENT (element) && expanded &&
- webkit_dom_element_get_child_element_count (element) == 0) {
- gchar *inner_html_data;
-
- inner_html_data = webkit_dom_element_get_attribute (element, "inner-html-data");
- if (inner_html_data && *inner_html_data) {
- WebKitDOMHTMLElement *html_element;
-
- html_element = WEBKIT_DOM_HTML_ELEMENT (element);
- webkit_dom_html_element_set_inner_html (html_element, inner_html_data, NULL);
-
- webkit_dom_element_remove_attribute (element, "inner-html-data");
- }
-
- g_free (inner_html_data);
- }
-
- /* Hide/Show all the GtkWidgets inside an attachment, otherwise they could
- * be visible even if the wrapper is hidden. */
- if ((iframe = webkit_dom_element_query_selector (element, "iframe", NULL))) {
- WebKitDOMDocument *content_document;
-
- content_document = webkit_dom_html_iframe_element_get_content_document
- (WEBKIT_DOM_HTML_IFRAME_ELEMENT (iframe));
-
- if (content_document) {
- gint length, ii;
- WebKitDOMNodeList *list;
-
- list = webkit_dom_document_get_elements_by_tag_name (content_document, "object");
- length = webkit_dom_node_list_get_length (list);
-
- for (ii = 0; ii < length; ii++) {
- WebKitDOMNode *item;
-
- item = webkit_dom_node_list_item (list, ii);
-
- css = webkit_dom_element_get_style (WEBKIT_DOM_ELEMENT (item));
- if (expanded)
- g_free (webkit_dom_css_style_declaration_remove_property (css,
"display", NULL));
- else
- webkit_dom_css_style_declaration_set_property (css, "display",
"none", "", NULL);
- g_clear_object (&css);
- }
- g_object_unref (list);
- }
- }
-
- /* Show or hide the DIV which contains
- * the attachment (iframe, image...). */
- css = webkit_dom_element_get_style (element);
- webkit_dom_css_style_declaration_set_property (
- css, "display", expanded ? "block" : "none", "", NULL);
-}
static void
-attachment_button_zoom_to_window_cb (GObject *object,
- GParamSpec *pspec,
- gpointer user_data)
-{
- EAttachmentButton *button = E_ATTACHMENT_BUTTON (object);
- EMailDisplay *display = user_data;
- WebKitDOMDocument *document;
- WebKitDOMElement *element, *child;
- WebKitDOMCSSStyleDeclaration *css;
- const gchar *attachment_part_id;
- gchar *element_id;
- gboolean zoom_to_window;
-
- d (
- printf ("Attachment button %s has been set to %s!\n",
- (gchar *) g_object_get_data (object, "uri"),
- (e_attachment_botton_get_zoom_to_window (attachment) ? "zoom-to-window" : "zoom to 100%")));
-
- if (!gtk_widget_get_visible (GTK_WIDGET (button)))
- return;
-
- zoom_to_window = e_attachment_button_get_zoom_to_window (button);
-
- document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (display));
- attachment_part_id = g_object_get_data (object, "attachment_id");
-
- element_id = g_strconcat (attachment_part_id, ".wrapper", NULL);
- element = find_element_by_id (document, element_id);
- g_free (element_id);
-
- if (!WEBKIT_DOM_IS_ELEMENT (element)) {
- d (
- printf ("%s: Content <div> of attachment %s does not exist!!\n",
- G_STRFUNC, (gchar *) g_object_get_data (object, "uri")));
- return;
- }
-
- child = webkit_dom_element_get_first_element_child (element);
- if (!child || !WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (child)) {
- d (
- printf ("%s: Content <div> of attachment %s does not contain image, but %s\n",
- G_STRFUNC, (gchar *) g_object_get_data (object, "uri"),
- child ? G_OBJECT_TYPE_NAME (child) : "[null]"));
- g_clear_object (&child);
- return;
- }
-
- css = webkit_dom_element_get_style (child);
- if (zoom_to_window) {
- webkit_dom_css_style_declaration_set_property (css, "max-width", "100%", "", NULL);
- } else {
- g_free (webkit_dom_css_style_declaration_remove_property (css, "max-width", NULL));
- }
- g_object_unref (css);
- g_clear_object (&child);
-}
-
-static void
-mail_display_attachment_count_changed (EAttachmentStore *store,
- GParamSpec *pspec,
- GtkWidget *box)
-{
- WebKitDOMHTMLElement *element;
- GList *children;
-
- children = gtk_container_get_children (GTK_CONTAINER (box));
- g_return_if_fail (children && children->data);
-
- element = g_object_get_data (children->data, "parent_element");
- g_list_free (children);
-
- g_return_if_fail (WEBKIT_DOM_IS_HTML_ELEMENT (element));
-
- if (e_attachment_store_get_num_attachments (store) == 0) {
- gtk_widget_hide (box);
- webkit_dom_html_element_set_hidden (element, TRUE);
- } else {
- gtk_widget_show (box);
- webkit_dom_html_element_set_hidden (element, FALSE);
- }
-}
-
-typedef struct _NumAttachmentsData {
- EAttachmentStore *store;
- gulong handler_id;
-} NumAttachmentsData;
-
-static void
-attachment_bar_box_gone_cb (gpointer data,
- GObject *gone_box)
-{
- NumAttachmentsData *nad = data;
-
- if (nad) {
- g_signal_handler_disconnect (nad->store, nad->handler_id);
- g_object_unref (nad->store);
- g_free (nad);
- }
-}
-
-static GtkWidget *
-mail_display_plugin_widget_requested (WebKitWebView *web_view,
- gchar *mime_type,
- gchar *uri,
- GHashTable *param,
- gpointer user_data)
-{
- EMailDisplay *display;
- EMailExtensionRegistry *reg;
- EMailFormatterExtension *extension;
- GQueue *extensions;
- GList *head, *link;
- EMailPart *part = NULL;
- GtkWidget *widget = NULL;
- GWeakRef *weakref;
- gchar *part_id, *type, *object_uri;
-
- part_id = g_hash_table_lookup (param, "data");
- if (part_id == NULL || !g_str_has_prefix (uri, "mail://"))
- return NULL;
-
- type = g_hash_table_lookup (param, "type");
- if (type == NULL)
- return NULL;
-
- display = E_MAIL_DISPLAY (web_view);
-
- weakref = g_hash_table_lookup (display->priv->widgets, part_id);
- if (weakref)
- widget = g_weak_ref_get (weakref);
-
- if (widget != NULL) {
- /* This cannot be the last reference; thread-safety is assured,
- because this runs in the main thread only. */
- g_object_unref (widget);
- d (printf ("Handeled %s widget request from cache\n", part_id));
- return widget;
- }
-
- /* Find the EMailPart representing the requested widget. */
- part = e_mail_part_list_ref_part (display->priv->part_list, part_id);
- if (part == NULL)
- return NULL;
-
- reg = e_mail_formatter_get_extension_registry (display->priv->formatter);
- extensions = e_mail_extension_registry_get_for_mime_type (reg, type);
- if (extensions == NULL)
- goto exit;
-
- extension = NULL;
- head = g_queue_peek_head_link (extensions);
- for (link = head; link != NULL; link = g_list_next (link)) {
- extension = link->data;
-
- if (extension == NULL)
- continue;
-
- if (e_mail_formatter_extension_has_widget (extension))
- break;
- }
-
- if (extension == NULL)
- goto exit;
-
- /* Get the widget from formatter */
- widget = e_mail_formatter_extension_get_widget (
- extension, display->priv->part_list, part, param);
- d (
- printf ("Created widget %s (%p) for part %s\n",
- G_OBJECT_TYPE_NAME (widget), widget, part_id));
-
- /* Should not happen! WebKit will display an ugly 'Plug-in not
- * available' placeholder instead of hiding the <object> element. */
- if (widget == NULL)
- goto exit;
-
- /* Attachment button has URI different then the actual PURI because
- * that URI identifies the attachment itself */
- if (E_IS_ATTACHMENT_BUTTON (widget)) {
- EMailPartAttachment *empa = (EMailPartAttachment *) part;
- EAttachment *attachment;
- gchar *attachment_part_id;
-
- if (empa->attachment_view_part_id)
- attachment_part_id = empa->attachment_view_part_id;
- else
- attachment_part_id = part_id;
-
- object_uri = g_strconcat (
- attachment_part_id, ".attachment_button", NULL);
- g_object_set_data_full (
- G_OBJECT (widget), "attachment_id",
- g_strdup (attachment_part_id),
- (GDestroyNotify) g_free);
-
- attachment = e_mail_part_attachment_ref_attachment (empa);
- if (attachment && e_attachment_is_mail_note (attachment)) {
- CamelFolder *folder;
- const gchar *message_uid;
-
- folder = e_mail_part_list_get_folder (display->priv->part_list);
- message_uid = e_mail_part_list_get_message_uid (display->priv->part_list);
-
- if (folder && message_uid) {
- CamelMessageInfo *info;
-
- info = camel_folder_get_message_info (folder, message_uid);
- if (info) {
- if (!camel_message_info_user_flag (info, E_MAIL_NOTES_USER_FLAG))
- camel_message_info_set_user_flag (info,
E_MAIL_NOTES_USER_FLAG, TRUE);
- camel_message_info_unref (info);
- }
- }
- }
-
- g_clear_object (&attachment);
- } else {
- object_uri = g_strdup (part_id);
- }
-
- /* Store the uri as data of the widget */
- g_object_set_data_full (
- G_OBJECT (widget), "uri",
- object_uri, (GDestroyNotify) g_free);
-
- /* Set pointer to the <object> element as GObject data
- * "parent_element" and set pointer to the widget as GObject
- * data "widget" to the <object> element. */
- plugin_widget_set_parent_element (widget, display);
-
- /* Resizing a GtkWidget requires changing size of parent
- * <object> HTML element in DOM. */
- g_signal_connect (
- widget, "size-allocate",
- G_CALLBACK (mail_display_plugin_widget_resize), display);
-
- if (E_IS_ATTACHMENT_BAR (widget)) {
- GtkWidget *box = NULL;
- EAttachmentStore *store;
- NumAttachmentsData *nad;
-
- /* Only when packed in box (grid does not work),
- * EAttachmentBar reports correct height */
- box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 0);
-
- /* When EAttachmentBar is expanded/collapsed it does not
- * emit size-allocate signal despite it changes it's height. */
- g_signal_connect (
- widget, "notify::expanded",
- G_CALLBACK (mail_display_plugin_widget_resize),
- display);
- g_signal_connect (
- widget, "notify::active-view",
- G_CALLBACK (mail_display_plugin_widget_resize),
- display);
-
- /* Always hide an attachment bar without attachments */
- store = e_attachment_bar_get_store (E_ATTACHMENT_BAR (widget));
-
- nad = g_new0 (NumAttachmentsData, 1);
- nad->store = g_object_ref (store);
- nad->handler_id = g_signal_connect (
- store, "notify::num-attachments",
- G_CALLBACK (mail_display_attachment_count_changed),
- box);
-
- g_object_weak_ref (G_OBJECT (box), attachment_bar_box_gone_cb, nad);
-
- gtk_widget_show (widget);
- gtk_widget_show (box);
-
- /* Initial sync */
- mail_display_attachment_count_changed (store, NULL, box);
-
- widget = box;
-
- } else if (E_IS_ATTACHMENT_BUTTON (widget)) {
-
- /* Bind visibility of DOM element containing related
- * attachment with 'expanded' property of this
- * attachment button. */
- EMailPartAttachment *empa = (EMailPartAttachment *) part;
-
- e_attachment_button_set_expandable (E_ATTACHMENT_BUTTON (widget),
- e_mail_part_attachment_get_expandable (empa));
-
- if (e_mail_part_attachment_get_expandable (empa)) {
- /* Show/hide the attachment when the EAttachmentButton
- * is expanded/collapsed or shown/hidden. */
- g_signal_connect (
- widget, "notify::expanded",
- G_CALLBACK (attachment_button_expanded),
- display);
- g_signal_connect (
- widget, "notify::visible",
- G_CALLBACK (attachment_button_expanded),
- display);
- g_signal_connect (
- widget, "notify::zoom-to-window",
- G_CALLBACK (attachment_button_zoom_to_window_cb),
- display);
-
- if (e_mail_part_should_show_inline (part)) {
- e_attachment_button_set_expanded (
- E_ATTACHMENT_BUTTON (widget), TRUE);
- } else {
- e_attachment_button_set_expanded (
- E_ATTACHMENT_BUTTON (widget), FALSE);
- attachment_button_expanded (
- G_OBJECT (widget), NULL, display);
- }
- }
- }
-
- g_hash_table_insert (
- display->priv->widgets,
- g_strdup (object_uri), e_weak_ref_new (widget));
-
-exit:
- if (part != NULL)
- g_object_unref (part);
-
- return widget;
-}
-#endif
-static void
add_color_css_rule_for_web_view (EWebView *view,
const gchar *color_name,
const gchar *color_value)
@@ -1061,19 +507,11 @@ headers_collapsed_signal_cb (GDBusConnection *connection,
}
static void
-setup_dom_bindings (WebKitWebView *web_view,
- WebKitLoadEvent load_event,
- gpointer user_data)
+setup_dom_bindings (EMailDisplay *display)
{
GDBusProxy *web_extension;
- EMailDisplay *display;
-
- if (load_event != WEBKIT_LOAD_FINISHED)
- return;
- display = E_MAIL_DISPLAY (web_view);
-
- web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (web_view));
+ web_extension = e_web_view_get_web_extension_proxy (E_WEB_VIEW (display));
if (web_extension) {
if (display->priv->web_extension_headers_collapsed_signal_id == 0) {
@@ -1096,7 +534,7 @@ setup_dom_bindings (WebKitWebView *web_view,
"EMailDisplayBindDOM",
g_variant_new (
"(t)",
- webkit_web_view_get_page_id (web_view)),
+ webkit_web_view_get_page_id (WEBKIT_WEB_VIEW (display))),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
@@ -1105,6 +543,281 @@ setup_dom_bindings (WebKitWebView *web_view,
}
}
+static EAttachment *
+mail_display_ref_attachment_from_element (EMailDisplay *display,
+ const gchar *element_value)
+{
+ EAttachment *attachment = NULL;
+ GQueue queue = G_QUEUE_INIT;
+ GList *head, *link;
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+ g_return_val_if_fail (element_value != NULL, NULL);
+
+ e_mail_part_list_queue_parts (display->priv->part_list, NULL, &queue);
+ head = g_queue_peek_head_link (&queue);
+
+ for (link = head; link != NULL; link = g_list_next (link)) {
+ EMailPart *part = E_MAIL_PART (link->data);
+
+ if (E_IS_MAIL_PART_ATTACHMENT (part)) {
+ EAttachment *adept;
+ gboolean can_use;
+ gchar *tmp;
+
+ adept = e_mail_part_attachment_ref_attachment (E_MAIL_PART_ATTACHMENT (part));
+
+ tmp = g_strdup_printf ("%p", adept);
+ can_use = g_strcmp0 (tmp, element_value) == 0;
+ g_free (tmp);
+
+ if (can_use) {
+ attachment = adept;
+ break;
+ }
+
+ g_clear_object (&adept);
+ }
+ }
+
+ while (!g_queue_is_empty (&queue))
+ g_object_unref (g_queue_pop_head (&queue));
+
+ return attachment;
+}
+
+static void
+mail_display_attachment_expander_clicked_cb (EWebView *web_view,
+ const gchar *element_class,
+ const gchar *element_value,
+ const GtkAllocation *element_position,
+ gpointer user_data)
+{
+ EMailDisplay *display;
+ EAttachmentView *view;
+ EAttachment *attachment;
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (web_view));
+ g_return_if_fail (element_class != NULL);
+ g_return_if_fail (element_value != NULL);
+ g_return_if_fail (element_position != NULL);
+
+ display = E_MAIL_DISPLAY (web_view);
+ view = e_mail_display_ref_attachment_view (display);
+ attachment = mail_display_ref_attachment_from_element (display, element_value);
+
+ if (view && attachment) {
+ /* mail_display_attachment_notify_cb() takes care of the HTML part */
+ e_attachment_set_shown (attachment, !e_attachment_get_shown (attachment));
+ }
+
+ g_clear_object (&attachment);
+ g_clear_object (&view);
+}
+
+static void
+mail_display_attachment_menu_deactivate_cb (GtkMenuShell *menu,
+ gpointer user_data)
+{
+ EMailDisplay *display = user_data;
+ EAttachmentView *view;
+ GtkActionGroup *action_group;
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ view = e_mail_display_ref_attachment_view (display);
+ action_group = e_attachment_view_get_action_group (view, "inline");
+
+ gtk_action_group_set_visible (action_group, FALSE);
+
+ g_signal_handlers_disconnect_by_func (menu,
+ G_CALLBACK (mail_display_attachment_menu_deactivate_cb), display);
+}
+
+static void
+mail_display_attachment_menu_position_cb (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ gpointer user_data)
+{
+ GtkRequisition menu_requisition;
+ GtkTextDirection direction;
+ GtkAllocation allocation;
+ GdkRectangle monitor;
+ GdkScreen *screen;
+ GdkWindow *window;
+ GtkWidget *widget;
+ EMailDisplay *display = user_data;
+ gint monitor_num;
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ widget = GTK_WIDGET (display);
+ gtk_widget_get_preferred_size (GTK_WIDGET (menu), &menu_requisition, NULL);
+
+ window = gtk_widget_get_parent_window (widget);
+ screen = gtk_widget_get_screen (GTK_WIDGET (menu));
+ monitor_num = gdk_screen_get_monitor_at_window (screen, window);
+ if (monitor_num < 0)
+ monitor_num = 0;
+ gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+
+ allocation = display->priv->attachment_popup_position;
+
+ gdk_window_get_origin (window, x, y);
+ *x += allocation.x;
+ *y += allocation.y + allocation.height;
+
+ direction = gtk_widget_get_direction (widget);
+ if (direction == GTK_TEXT_DIR_LTR)
+ *x += MAX (allocation.width - menu_requisition.width, 0);
+ else if (menu_requisition.width > allocation.width)
+ *x -= menu_requisition.width - allocation.width;
+
+ *push_in = FALSE;
+}
+
+static void
+mail_display_attachment_select_path (EAttachmentView *view,
+ EAttachment *attachment)
+{
+ GtkTreeRowReference *reference;
+ GtkTreePath *path;
+
+ g_return_if_fail (E_IS_ATTACHMENT_VIEW (view));
+ g_return_if_fail (E_IS_ATTACHMENT (attachment));
+
+ reference = e_attachment_get_reference (attachment);
+ g_return_if_fail (gtk_tree_row_reference_valid (reference));
+
+ path = gtk_tree_row_reference_get_path (reference);
+
+ e_attachment_view_unselect_all (view);
+ e_attachment_view_select_path (view, path);
+
+ gtk_tree_path_free (path);
+}
+
+static void
+mail_display_attachment_menu_clicked_cb (EWebView *web_view,
+ const gchar *element_class,
+ const gchar *element_value,
+ const GtkAllocation *element_position,
+ gpointer user_data)
+{
+ EMailDisplay *display;
+ EAttachmentView *view;
+ EAttachment *attachment;
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (web_view));
+ g_return_if_fail (element_class != NULL);
+ g_return_if_fail (element_value != NULL);
+ g_return_if_fail (element_position != NULL);
+
+ display = E_MAIL_DISPLAY (web_view);
+ view = e_mail_display_ref_attachment_view (display);
+ attachment = mail_display_ref_attachment_from_element (display, element_value);
+
+ if (view && attachment) {
+ GtkActionGroup *action_group;
+ GtkWidget *popup_menu;
+
+ popup_menu = e_attachment_view_get_popup_menu (view);
+
+ g_signal_connect (
+ popup_menu, "deactivate",
+ G_CALLBACK (mail_display_attachment_menu_deactivate_cb), display);
+
+ action_group = e_attachment_view_get_action_group (view, "inline");
+
+ mail_display_attachment_select_path (view, attachment);
+ display->priv->attachment_popup_position = *element_position;
+
+ e_attachment_view_show_popup_menu (view, NULL,
+ mail_display_attachment_menu_position_cb, display);
+
+ gtk_action_group_set_visible (action_group, TRUE);
+ }
+
+ g_clear_object (&attachment);
+ g_clear_object (&view);
+}
+
+static void
+mail_display_attachment_notify_cb (GObject *attachment,
+ GParamSpec *param,
+ gpointer user_data)
+{
+ EMailDisplay *display = user_data;
+ gchar *element_id = NULL;
+
+ g_return_if_fail (E_IS_ATTACHMENT (attachment));
+ g_return_if_fail (param != NULL);
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ if (g_str_equal (param->name, "shown")) {
+ gboolean shown;
+ gchar *uri;
+
+ shown = e_attachment_get_shown (E_ATTACHMENT (attachment));
+
+ element_id = g_strdup_printf ("attachment-wrapper-%p", attachment);
+ e_web_view_set_element_hidden (E_WEB_VIEW (display), element_id, !shown);
+
+ g_free (element_id);
+ element_id = g_strdup_printf ("attachment-expander-img-%p", attachment);
+ uri = g_strdup_printf ("gtk-stock://%s?size=%d", shown ? "go-down" : "go-next",
GTK_ICON_SIZE_BUTTON);
+
+ e_web_view_set_element_attribute (E_WEB_VIEW (display), element_id, NULL, "src", uri);
+
+ g_free (uri);
+ } else if (g_str_equal (param->name, "zoom-to-window")) {
+ const gchar *value;
+
+ if (e_attachment_get_zoom_to_window (E_ATTACHMENT (attachment)))
+ value = "100%";
+ else
+ value = NULL;
+
+ element_id = g_strdup_printf ("attachment-wrapper-%p::child", attachment);
+
+ e_web_view_set_element_style_property (E_WEB_VIEW (display), element_id, "max-width", value,
"");
+ }
+
+ g_free (element_id);
+}
+
+static void
+mail_display_attachment_added_cb (EAttachmentStore *store,
+ EAttachment *attachment,
+ gpointer user_data)
+{
+ EMailDisplay *display = user_data;
+
+ g_return_if_fail (E_IS_ATTACHMENT_STORE (store));
+ g_return_if_fail (E_IS_ATTACHMENT (attachment));
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ g_signal_connect (attachment, "notify",
+ G_CALLBACK (mail_display_attachment_notify_cb), display);
+}
+
+static void
+mail_display_attachment_removed_cb (EAttachmentStore *store,
+ EAttachment *attachment,
+ gpointer user_data)
+{
+ EMailDisplay *display = user_data;
+
+ g_return_if_fail (E_IS_ATTACHMENT_STORE (store));
+ g_return_if_fail (E_IS_ATTACHMENT (attachment));
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ g_signal_handlers_disconnect_by_func (attachment,
+ G_CALLBACK (mail_display_attachment_notify_cb), display);
+}
+
static void
mail_element_exists_cb (GDBusProxy *web_extension,
GAsyncResult *result,
@@ -1131,25 +844,15 @@ mail_element_exists_cb (GDBusProxy *web_extension,
}
static void
-mail_parts_bind_dom (WebKitWebView *wk_web_view,
- WebKitLoadEvent load_event,
- gpointer user_data)
+mail_parts_bind_dom (EMailDisplay *display)
{
- EMailDisplay *display;
EWebView *web_view;
GQueue queue = G_QUEUE_INIT;
GList *head, *link;
GDBusProxy *web_extension;
+ gboolean has_attachment = FALSE;
- display = E_MAIL_DISPLAY (wk_web_view);
-
- if (load_event == WEBKIT_LOAD_STARTED) {
- e_mail_display_cleanup_skipped_uris (display);
- return;
- }
-
- if (load_event != WEBKIT_LOAD_FINISHED)
- return;
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
if (display->priv->part_list == NULL)
return;
@@ -1171,6 +874,8 @@ mail_parts_bind_dom (WebKitWebView *wk_web_view,
part_id = e_mail_part_get_id (part);
+ has_attachment = has_attachment || E_IS_MAIL_PART_ATTACHMENT (part);
+
e_mail_part_web_view_loaded (part, web_view);
g_dbus_proxy_call (
@@ -1190,29 +895,38 @@ mail_parts_bind_dom (WebKitWebView *wk_web_view,
while (!g_queue_is_empty (&queue))
g_object_unref (g_queue_pop_head (&queue));
+
+ if (has_attachment) {
+ e_web_view_register_element_clicked (web_view, "attachment-expander",
+ mail_display_attachment_expander_clicked_cb, NULL);
+ e_web_view_register_element_clicked (web_view, "attachment-menu",
+ mail_display_attachment_menu_clicked_cb, NULL);
+ }
}
-#if 0
+
static void
-mail_display_uri_changed (EMailDisplay *display,
- GParamSpec *pspec,
- gpointer dummy)
+mail_display_load_changed_cb (WebKitWebView *wk_web_view,
+ WebKitLoadEvent load_event,
+ gpointer user_data)
{
- d (printf ("EMailDisplay URI changed, recreating widgets hashtable\n"));
+ EMailDisplay *display;
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (wk_web_view));
+
+ display = E_MAIL_DISPLAY (wk_web_view);
- if (display->priv->widgets != NULL) {
- g_hash_table_foreach (
- display->priv->widgets,
- mail_display_plugin_widget_disconnect, display);
- g_hash_table_destroy (display->priv->widgets);
+ if (load_event == WEBKIT_LOAD_STARTED) {
+ e_mail_display_cleanup_skipped_uris (display);
+ e_attachment_store_remove_all (display->priv->attachment_store);
+ return;
}
- display->priv->widgets = g_hash_table_new_full (
- (GHashFunc) g_str_hash,
- (GEqualFunc) g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) e_weak_ref_free);
+ if (load_event == WEBKIT_LOAD_FINISHED) {
+ setup_dom_bindings (display);
+ mail_parts_bind_dom (display);
+ }
}
-#endif
+
static void
mail_display_set_property (GObject *object,
guint property_id,
@@ -1220,6 +934,12 @@ mail_display_set_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
+ case PROP_ATTACHMENT_VIEW:
+ e_mail_display_set_attachment_view (
+ E_MAIL_DISPLAY (object),
+ g_value_get_object (value));
+ return;
+
case PROP_HEADERS_COLLAPSABLE:
e_mail_display_set_headers_collapsable (
E_MAIL_DISPLAY (object),
@@ -1261,6 +981,20 @@ mail_display_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
+ case PROP_ATTACHMENT_STORE:
+ g_value_set_object (
+ value,
+ e_mail_display_get_attachment_store (
+ E_MAIL_DISPLAY (object)));
+ return;
+
+ case PROP_ATTACHMENT_VIEW:
+ g_value_take_object (
+ value,
+ e_mail_display_ref_attachment_view (
+ E_MAIL_DISPLAY (object)));
+ return;
+
case PROP_FORMATTER:
g_value_set_object (
value,
@@ -1318,15 +1052,7 @@ mail_display_dispose (GObject *object)
g_source_remove (priv->scheduled_reload);
priv->scheduled_reload = 0;
}
-#if 0
- if (priv->widgets != NULL) {
- g_hash_table_foreach (
- priv->widgets,
- mail_display_plugin_widget_disconnect, object);
- g_hash_table_destroy (priv->widgets);
- priv->widgets = NULL;
- }
-#endif
+
if (priv->settings != NULL)
g_signal_handlers_disconnect_matched (
priv->settings, G_SIGNAL_MATCH_DATA,
@@ -1340,9 +1066,21 @@ mail_display_dispose (GObject *object)
priv->web_extension_headers_collapsed_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);
+
+ g_signal_handlers_disconnect_by_func (priv->attachment_store,
+ G_CALLBACK (mail_display_attachment_added_cb), object);
+
+ g_signal_handlers_disconnect_by_func (priv->attachment_store,
+ G_CALLBACK (mail_display_attachment_removed_cb), object);
+ }
+
g_clear_object (&priv->part_list);
g_clear_object (&priv->formatter);
g_clear_object (&priv->settings);
+ g_clear_object (&priv->attachment_store);
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_mail_display_parent_class)->dispose (object);
@@ -1369,6 +1107,7 @@ mail_display_finalize (GObject *object)
g_clear_object (&priv->remote_content);
g_mutex_unlock (&priv->remote_content_lock);
g_mutex_clear (&priv->remote_content_lock);
+ e_weak_ref_free (priv->attachment_view);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (e_mail_display_parent_class)->finalize (object);
@@ -1803,6 +1542,28 @@ e_mail_display_class_init (EMailDisplayClass *class)
g_object_class_install_property (
object_class,
+ PROP_ATTACHMENT_STORE,
+ g_param_spec_object (
+ "attachment-store",
+ "Attachment Store",
+ NULL,
+ E_TYPE_ATTACHMENT_STORE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ATTACHMENT_VIEW,
+ g_param_spec_object (
+ "attachment-view",
+ "Attachment View",
+ NULL,
+ E_TYPE_ATTACHMENT_VIEW,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
PROP_FORMATTER,
g_param_spec_pointer (
"formatter",
@@ -1875,8 +1636,25 @@ e_mail_display_init (EMailDisplay *display)
display->priv = E_MAIL_DISPLAY_GET_PRIVATE (display);
+ /* FIXME WK2: EAttachment::row-reference cannot be used. Steps:
+ a) open one message with attachments in the Mail window with the preview panel on
+ b) open the same message in a separate window
+ * observation - changing properties on the attachment are shown in both windows
(expand/collapse/zoom)
+ c) close the separate window
+ d) click the arrow-down on the attachment to get its popup menu
+ A runtime warning:
+ evolution-mail-CRITICAL **: mail_display_attachment_select_path: assertion
'gtk_tree_row_reference_valid (reference)' failed
+ is shown on the console and the popup menu is empty. Expand/collapse using the left part of the
attachment button still works.
+ */
+ display->priv->attachment_store = E_ATTACHMENT_STORE (e_attachment_store_new ());
+ display->priv->attachment_view = e_weak_ref_new (NULL);
display->priv->old_settings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) g_variant_unref);
+ g_signal_connect (display->priv->attachment_store, "attachment-added",
+ G_CALLBACK (mail_display_attachment_added_cb), display);
+ g_signal_connect (display->priv->attachment_store, "attachment-removed",
+ G_CALLBACK (mail_display_attachment_removed_cb), display);
+
/* Set invalid mode so that MODE property initialization is run
* completely (see e_mail_display_set_mode) */
display->priv->mode = E_MAIL_FORMATTER_MODE_INVALID;
@@ -1892,18 +1670,6 @@ e_mail_display_init (EMailDisplay *display)
display, "process-mailto",
G_CALLBACK (mail_display_process_mailto), NULL);
#if 0
- g_signal_connect (
- display, "create-plugin-widget",
- G_CALLBACK (mail_display_plugin_widget_requested), NULL);
- e_signal_connect_notify (
- display, "notify::uri",
- G_CALLBACK (mail_display_uri_changed), NULL);
- g_signal_connect (
- display, "document-load-finished",
- G_CALLBACK (setup_dom_bindings), NULL);
- g_signal_connect (
- display, "document-load-finished",
- G_CALLBACK (initialize_web_view_colors), NULL);
g_signal_connect_after (
display, "drag-data-get",
G_CALLBACK (mail_display_drag_data_get), display);
@@ -1921,10 +1687,7 @@ e_mail_display_init (EMailDisplay *display)
g_signal_connect (
display, "load-changed",
- G_CALLBACK (setup_dom_bindings), NULL);
- g_signal_connect (
- display, "load-changed",
- G_CALLBACK (mail_parts_bind_dom), NULL);
+ G_CALLBACK (mail_display_load_changed_cb), NULL);
actions = e_web_view_get_action_group (E_WEB_VIEW (display), "mailto");
gtk_action_group_add_actions (
@@ -1985,6 +1748,46 @@ e_mail_display_update_colors (EMailDisplay *display,
g_free (color_value);
}
+static void
+e_mail_display_claim_attachment (EMailFormatter *formatter,
+ EAttachment *attachment,
+ gpointer user_data)
+{
+ EMailDisplay *display = user_data;
+ GList *attachments;
+
+ g_return_if_fail (E_IS_MAIL_FORMATTER (formatter));
+ g_return_if_fail (E_IS_ATTACHMENT (attachment));
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ attachments = e_attachment_store_get_attachments (display->priv->attachment_store);
+
+ if (!g_list_find (attachments, attachment)) {
+ e_attachment_store_add_attachment (display->priv->attachment_store, attachment);
+
+ if (e_attachment_is_mail_note (attachment)) {
+ CamelFolder *folder;
+ const gchar *message_uid;
+
+ folder = e_mail_part_list_get_folder (display->priv->part_list);
+ message_uid = e_mail_part_list_get_message_uid (display->priv->part_list);
+
+ if (folder && message_uid) {
+ CamelMessageInfo *info;
+
+ info = camel_folder_get_message_info (folder, message_uid);
+ if (info) {
+ if (!camel_message_info_user_flag (info, E_MAIL_NOTES_USER_FLAG))
+ camel_message_info_set_user_flag (info,
E_MAIL_NOTES_USER_FLAG, TRUE);
+ camel_message_info_unref (info);
+ }
+ }
+ }
+ }
+
+ g_list_free_full (attachments, g_object_unref);
+}
+
GtkWidget *
e_mail_display_new (EMailRemoteContent *remote_content)
{
@@ -1993,6 +1796,34 @@ e_mail_display_new (EMailRemoteContent *remote_content)
NULL);
}
+EAttachmentStore *
+e_mail_display_get_attachment_store (EMailDisplay *display)
+{
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+
+ return display->priv->attachment_store;
+}
+
+void
+e_mail_display_set_attachment_view (EMailDisplay *display,
+ EAttachmentView *view)
+{
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+ g_return_if_fail (E_IS_ATTACHMENT_VIEW (view));
+
+ g_weak_ref_set (display->priv->attachment_view, view);
+
+ g_object_notify (G_OBJECT (display), "attachment-view");
+}
+
+EAttachmentView *
+e_mail_display_ref_attachment_view (EMailDisplay *display)
+{
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+
+ return g_weak_ref_get (display->priv->attachment_view);
+}
+
EMailFormatterMode
e_mail_display_get_mode (EMailDisplay *display)
{
@@ -2075,6 +1906,8 @@ e_mail_display_set_mode (EMailDisplay *display,
G_CALLBACK (e_mail_display_reload), display,
NULL);
+ g_signal_connect (formatter, "claim-attachment", G_CALLBACK (e_mail_display_claim_attachment),
display);
+
e_mail_display_reload (display);
g_object_notify (G_OBJECT (display), "mode");
diff --git a/mail/e-mail-display.h b/mail/e-mail-display.h
index 63d7a6b..a850eab 100644
--- a/mail/e-mail-display.h
+++ b/mail/e-mail-display.h
@@ -62,6 +62,15 @@ struct _EMailDisplayClass {
GType e_mail_display_get_type (void) G_GNUC_CONST;
GtkWidget * e_mail_display_new (EMailRemoteContent *remote_content);
+EAttachmentStore *
+ e_mail_display_get_attachment_store
+ (EMailDisplay *display);
+void e_mail_display_set_attachment_view
+ (EMailDisplay *display,
+ EAttachmentView *view);
+EAttachmentView *
+ e_mail_display_ref_attachment_view
+ (EMailDisplay *display);
EMailFormatterMode
e_mail_display_get_mode (EMailDisplay *display);
void e_mail_display_set_mode (EMailDisplay *display,
diff --git a/mail/e-mail-request.c b/mail/e-mail-request.c
index ce890e8..816227f 100644
--- a/mail/e-mail-request.c
+++ b/mail/e-mail-request.c
@@ -32,6 +32,7 @@
#include "em-format/e-mail-formatter-print.h"
#include "em-utils.h"
+#include "e-mail-display.h"
#include "e-mail-ui-session.h"
#include "e-mail-request.h"
@@ -56,6 +57,35 @@ e_mail_request_can_process_uri (EContentRequest *request,
return g_ascii_strncasecmp (uri, "mail:", 5) == 0;
}
+static void
+save_gicon_to_stream (GIcon *icon,
+ gint size,
+ GOutputStream *output_stream,
+ gchar **out_mime_type)
+{
+ GtkIconInfo *icon_info;
+ GdkPixbuf *pixbuf;
+
+ if (size < 16)
+ size = 16;
+
+ icon_info = gtk_icon_theme_lookup_by_gicon (gtk_icon_theme_get_default (), icon, size,
GTK_ICON_LOOKUP_FORCE_SIZE);
+ if (!icon_info)
+ return;
+
+ pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
+ if (pixbuf) {
+ if (gdk_pixbuf_save_to_stream (
+ pixbuf, output_stream,
+ "png", NULL, NULL, NULL)) {
+ *out_mime_type = g_strdup ("image/png");
+ }
+ g_object_unref (pixbuf);
+ }
+
+ g_object_unref (icon);
+}
+
static gboolean
mail_request_process_mail_sync (EContentRequest *request,
SoupURI *suri,
@@ -120,6 +150,8 @@ mail_request_process_mail_sync (EContentRequest *request,
if (context.mode == E_MAIL_FORMATTER_MODE_PRINTING)
formatter = e_mail_formatter_print_new ();
+ else if (E_IS_MAIL_DISPLAY (requester))
+ formatter = g_object_ref (e_mail_display_get_formatter (E_MAIL_DISPLAY (requester)));
else
formatter = e_mail_formatter_new ();
@@ -130,6 +162,65 @@ mail_request_process_mail_sync (EContentRequest *request,
output_stream = g_memory_output_stream_new_resizable ();
+ val = g_hash_table_lookup (uri_query, "attachment_icon");
+ if (val) {
+ gchar *attachment_id;
+
+ attachment_id = soup_uri_decode (val);
+ if (E_IS_MAIL_DISPLAY (requester)) {
+ EMailDisplay *mail_display = E_MAIL_DISPLAY (requester);
+ EAttachmentStore *attachment_store;
+ GList *attachments, *link;
+
+ attachment_store = e_mail_display_get_attachment_store (mail_display);
+ attachments = e_attachment_store_get_attachments (attachment_store);
+ for (link = attachments; link; link = g_list_next (link)) {
+ EAttachment *attachment = link->data;
+ gboolean can_use;
+
+ tmp = g_strdup_printf ("%p", attachment);
+ can_use = g_strcmp0 (tmp, attachment_id) == 0;
+ g_free (tmp);
+
+ if (can_use) {
+ GtkTreeRowReference *reference;
+
+ reference = e_attachment_get_reference (attachment);
+ if (gtk_tree_row_reference_valid (reference)) {
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ path = gtk_tree_row_reference_get_path (reference);
+ if (gtk_tree_model_get_iter (GTK_TREE_MODEL
(attachment_store), &iter, path)) {
+ GIcon *icon = NULL;
+
+ gtk_tree_model_get (GTK_TREE_MODEL
(attachment_store), &iter,
+ E_ATTACHMENT_STORE_COLUMN_ICON, &icon,
+ -1);
+
+ if (icon) {
+ const gchar *size = g_hash_table_lookup
(uri_query, "size");
+ if (!size)
+ size = "16";
+
+ save_gicon_to_stream (icon, atoi (size),
output_stream, &use_mime_type);
+ }
+ }
+ gtk_tree_path_free (path);
+ }
+
+ break;
+ }
+ }
+
+ g_list_free_full (attachments, g_object_unref);
+ }
+
+ g_free (attachment_id);
+
+ goto no_part;
+ }
+
val = g_hash_table_lookup (uri_query, "part_id");
if (val != NULL) {
EMailPart *part;
diff --git a/modules/mail/e-mail-shell-content.c b/modules/mail/e-mail-shell-content.c
index 66a79c1..55a2891 100644
--- a/modules/mail/e-mail-shell-content.c
+++ b/modules/mail/e-mail-shell-content.c
@@ -43,6 +43,7 @@
struct _EMailShellContentPrivate {
EMailView *mail_view;
+ GtkWidget *attachment_bar; /* not referenced */
};
enum {
@@ -67,6 +68,27 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED (
E_TYPE_MAIL_READER,
e_mail_shell_content_reader_init))
+static gboolean
+mail_shell_content_transform_num_attachments_to_visible_boolean_with_settings (GBinding *binding,
+ const GValue *from_value,
+ GValue *to_value,
+ gpointer user_data)
+{
+ GSettings *settings;
+ gboolean res = TRUE;
+
+ settings = e_util_ref_settings ("org.gnome.evolution.mail");
+
+ if (g_settings_get_boolean (settings, "show-attachment-bar"))
+ res = e_attachment_store_transform_num_attachments_to_visible_boolean (binding, from_value,
to_value, user_data);
+ else
+ g_value_set_boolean (to_value, FALSE);
+
+ g_clear_object (&settings);
+
+ return res;
+}
+
static void
reconnect_changed_event (EMailReader *child,
EMailReader *parent)
@@ -179,9 +201,11 @@ mail_shell_content_constructed (GObject *object)
EMailShellContentPrivate *priv;
EShellContent *shell_content;
EShellView *shell_view;
+ EAttachmentStore *attachment_store;
+ EMailDisplay *display;
GtkWindow *window;
- GtkWidget *container;
GtkWidget *widget;
+ GtkBox *vbox;
priv = E_MAIL_SHELL_CONTENT_GET_PRIVATE (object);
@@ -193,11 +217,15 @@ mail_shell_content_constructed (GObject *object)
/* Build content widgets. */
- container = GTK_WIDGET (object);
+ widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
+ gtk_container_add (GTK_CONTAINER (shell_content), widget);
+ gtk_widget_show (widget);
+
+ vbox = GTK_BOX (widget);
widget = e_mail_paned_view_new (shell_view);
+ gtk_box_pack_start (vbox, widget, TRUE, TRUE, 0);
- gtk_container_add (GTK_CONTAINER (container), widget);
priv->mail_view = g_object_ref (widget);
gtk_widget_show (widget);
@@ -208,6 +236,21 @@ mail_shell_content_constructed (GObject *object)
widget, "folder-loaded",
G_CALLBACK (reconnect_folder_loaded_event), object);
+ display = e_mail_reader_get_mail_display (E_MAIL_READER (object));
+ attachment_store = e_mail_display_get_attachment_store (display);
+ widget = e_attachment_bar_new (attachment_store);
+ e_mail_display_set_attachment_view (display, E_ATTACHMENT_VIEW (widget));
+ gtk_box_pack_start (vbox, widget, FALSE, FALSE, 0);
+
+ priv->attachment_bar = widget;
+
+ e_binding_bind_property_full (
+ attachment_store, "num-attachments",
+ widget, "visible",
+ G_BINDING_SYNC_CREATE,
+ mail_shell_content_transform_num_attachments_to_visible_boolean_with_settings,
+ NULL, NULL, NULL);
+
window = e_mail_reader_get_window (E_MAIL_READER (object));
widget = e_mail_reader_get_message_list (E_MAIL_READER (object));
@@ -512,6 +555,14 @@ e_mail_shell_content_get_mail_view (EMailShellContent *mail_shell_content)
return mail_shell_content->priv->mail_view;
}
+GtkWidget *
+e_mail_shell_content_get_attachment_bar (EMailShellContent *mail_shell_content)
+{
+ g_return_val_if_fail (E_IS_MAIL_SHELL_CONTENT (mail_shell_content), NULL);
+
+ return mail_shell_content->priv->attachment_bar;
+}
+
EShellSearchbar *
e_mail_shell_content_get_searchbar (EMailShellContent *mail_shell_content)
{
diff --git a/modules/mail/e-mail-shell-content.h b/modules/mail/e-mail-shell-content.h
index db9ef85..f9dce15 100644
--- a/modules/mail/e-mail-shell-content.h
+++ b/modules/mail/e-mail-shell-content.h
@@ -67,6 +67,8 @@ GtkWidget * e_mail_shell_content_new
(EShellView *shell_view);
EMailView * e_mail_shell_content_get_mail_view
(EMailShellContent *mail_shell_content);
+GtkWidget * e_mail_shell_content_get_attachment_bar
+ (EMailShellContent *mail_shell_content);
EShellSearchbar *
e_mail_shell_content_get_searchbar
(EMailShellContent *mail_shell_content);
diff --git a/modules/mail/e-mail-shell-view-actions.c b/modules/mail/e-mail-shell-view-actions.c
index f1159cf..48cefd4 100644
--- a/modules/mail/e-mail-shell-view-actions.c
+++ b/modules/mail/e-mail-shell-view-actions.c
@@ -256,6 +256,25 @@ action_mail_create_search_folder_cb (GtkAction *action,
}
static void
+action_mail_attachment_bar_cb (GtkAction *action,
+ EMailShellView *mail_shell_view)
+{
+ GtkWidget *attachment_bar;
+
+ attachment_bar = e_mail_shell_content_get_attachment_bar (mail_shell_view->priv->mail_shell_content);
+ if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
+ EAttachmentStore *store;
+ guint num_attachments;
+
+ store = e_attachment_bar_get_store (E_ATTACHMENT_BAR (attachment_bar));
+ num_attachments = e_attachment_store_get_num_attachments (store);
+ gtk_widget_set_visible (attachment_bar, num_attachments > 0);
+ } else {
+ gtk_widget_hide (attachment_bar);
+ }
+}
+
+static void
action_mail_download_finished_cb (CamelStore *store,
GAsyncResult *result,
EActivity *activity)
@@ -1991,6 +2010,14 @@ static GtkToggleActionEntry mail_toggle_entries[] = {
NULL, /* Handled by property bindings */
TRUE },
+ { "mail-attachment-bar",
+ NULL,
+ N_("Show _Attachment Bar"),
+ NULL,
+ N_("Show Attachment Bar below the message preview pane when the message has attachments"),
+ G_CALLBACK (action_mail_attachment_bar_cb),
+ TRUE },
+
{ "mail-show-deleted",
NULL,
N_("Show _Deleted Messages"),
@@ -2300,6 +2327,11 @@ e_mail_shell_view_actions_init (EMailShellView *mail_shell_view)
ACTION (MAIL_VFOLDER_UNMATCHED_ENABLE), "active",
G_SETTINGS_BIND_DEFAULT);
+ g_settings_bind (
+ settings, "show-attachment-bar",
+ ACTION (MAIL_ATTACHMENT_BAR), "active",
+ G_SETTINGS_BIND_DEFAULT);
+
g_object_unref (settings);
/* Fine tuning. */
diff --git a/modules/mail/e-mail-shell-view-actions.h b/modules/mail/e-mail-shell-view-actions.h
index 866cc98..5459f73 100644
--- a/modules/mail/e-mail-shell-view-actions.h
+++ b/modules/mail/e-mail-shell-view-actions.h
@@ -34,6 +34,8 @@
E_SHELL_WINDOW_ACTION ((window), "mail-account-refresh")
#define E_SHELL_WINDOW_ACTION_MAIL_ADD_SENDER(window) \
E_SHELL_WINDOW_ACTION ((window), "mail-add-sender")
+#define E_SHELL_WINDOW_ACTION_MAIL_ATTACHMENT_BAR(window) \
+ E_SHELL_WINDOW_ACTION ((window), "mail-attachment-bar")
#define E_SHELL_WINDOW_ACTION_MAIL_CARET_MODE(window) \
E_SHELL_WINDOW_ACTION ((window), "mail-caret-mode")
#define E_SHELL_WINDOW_ACTION_MAIL_CHECK_FOR_JUNK(window) \
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 643b2a7..6ccae22 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -191,6 +191,7 @@ e-util/e-charset-combo-box.c
e-util/e-client-cache.c
e-util/e-color-chooser-widget.c
e-util/e-color-combo.c
+e-util/e-content-editor.c
e-util/e-dateedit.c
e-util/e-datetime-format.c
e-util/e-dialog-utils.c
diff --git a/ui/evolution-mail.ui b/ui/evolution-mail.ui
index b58d222..bf26e03 100644
--- a/ui/evolution-mail.ui
+++ b/ui/evolution-mail.ui
@@ -19,6 +19,7 @@
<placeholder name='view-custom-menus'>
<menu action='mail-preview-menu'>
<menuitem action='mail-preview'/>
+ <menuitem action='mail-attachment-bar'/>
<separator/>
<menuitem action='mail-view-classic'/>
<menuitem action='mail-view-vertical'/>
diff --git a/web-extensions/e-dom-utils.c b/web-extensions/e-dom-utils.c
index f855c3f..2a05697 100644
--- a/web-extensions/e-dom-utils.c
+++ b/web-extensions/e-dom-utils.c
@@ -962,38 +962,11 @@ gboolean
e_dom_utils_element_exists (WebKitDOMDocument *document,
const gchar *element_id)
{
- WebKitDOMHTMLCollection *frames;
- gboolean element_exists = FALSE;
- gulong ii, length;
-
- /* Try to look up the element in this DOM document */
- if (webkit_dom_document_get_element_by_id (document, element_id))
- return TRUE;
-
- /* If the element is not here then recursively scan all frames */
- frames = webkit_dom_document_get_elements_by_tag_name_as_html_collection (document, "iframe");
- length = webkit_dom_html_collection_get_length (frames);
- for (ii = 0; ii < length; ii++) {
- WebKitDOMHTMLIFrameElement *iframe;
- WebKitDOMDocument *content_document;
-
- iframe = WEBKIT_DOM_HTML_IFRAME_ELEMENT (
- webkit_dom_html_collection_item (frames, ii));
-
- content_document = webkit_dom_html_iframe_element_get_content_document (iframe);
- if (!content_document)
- continue;
-
- element_exists = e_dom_utils_element_exists (content_document, element_id);
+ WebKitDOMElement *element;
- if (element_exists) {
- g_object_unref (frames);
- return TRUE;
- }
- }
+ element = e_dom_utils_find_element_by_id (document, element_id);
- g_object_unref (frames);
- return FALSE;
+ return element != NULL;
}
gchar *
@@ -1066,7 +1039,7 @@ e_dom_utils_element_set_inner_html (WebKitDOMDocument *document,
{
WebKitDOMElement *element;
- element = webkit_dom_document_get_element_by_id (document, element_id);
+ element = e_dom_utils_find_element_by_id (document, element_id);
if (!element)
return;
@@ -1080,7 +1053,7 @@ e_dom_utils_remove_element (WebKitDOMDocument *document,
{
WebKitDOMElement *element;
- element = webkit_dom_document_get_element_by_id (document, element_id);
+ element = e_dom_utils_find_element_by_id (document, element_id);
if (!element)
return;
@@ -1096,8 +1069,13 @@ e_dom_utils_element_remove_child_nodes (WebKitDOMDocument *document,
const gchar *element_id)
{
WebKitDOMNode *node;
+ WebKitDOMElement *element;
- node = WEBKIT_DOM_NODE (webkit_dom_document_get_element_by_id (document, element_id));
+ element = e_dom_utils_find_element_by_id (document, element_id);
+ if (!element)
+ return;
+
+ node = WEBKIT_DOM_NODE (element);
if (!node)
return;
@@ -1117,7 +1095,7 @@ e_dom_utils_hide_element (WebKitDOMDocument *document,
{
WebKitDOMElement *element;
- element = webkit_dom_document_get_element_by_id (document, element_id);
+ element = e_dom_utils_find_element_by_id (document, element_id);
if (!element)
return;
@@ -1132,13 +1110,12 @@ e_dom_utils_element_is_hidden (WebKitDOMDocument *document,
{
WebKitDOMElement *element;
- element = webkit_dom_document_get_element_by_id (document, element_id);
+ element = e_dom_utils_find_element_by_id (document, element_id);
if (!element)
return FALSE;
- return webkit_dom_html_element_get_hidden (
- WEBKIT_DOM_HTML_ELEMENT (element));
+ return webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (element));
}
static void
diff --git a/web-extensions/e-web-extension.c b/web-extensions/e-web-extension.c
index b0ebdb9..b4e9784 100644
--- a/web-extensions/e-web-extension.c
+++ b/web-extensions/e-web-extension.c
@@ -69,6 +69,25 @@ static const char introspection_xml[] =
" <arg type='i' name='position_width' direction='out'/>"
" <arg type='i' name='position_height' direction='out'/>"
" </signal>"
+" <method name='SetElementHidden'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='s' name='element_id' direction='in'/>"
+" <arg type='b' name='hidden' direction='in'/>"
+" </method>"
+" <method name='SetElementStyleProperty'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='s' name='element_id' direction='in'/>"
+" <arg type='s' name='property_name' direction='in'/>"
+" <arg type='s' name='value' direction='in'/>"
+" <arg type='s' name='priority' direction='in'/>"
+" </method>"
+" <method name='SetElementAttribute'>"
+" <arg type='t' name='page_id' direction='in'/>"
+" <arg type='s' name='element_id' direction='in'/>"
+" <arg type='s' name='namespace_uri' direction='in'/>"
+" <arg type='s' name='qualified_name' direction='in'/>"
+" <arg type='s' name='value' direction='in'/>"
+" </method>"
" <signal name='HeadersCollapsed'>"
" <arg type='b' name='expanded' direction='out'/>"
" </signal>"
@@ -334,6 +353,146 @@ handle_method_call (GDBusConnection *connection,
}
g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "SetElementHidden") == 0) {
+ const gchar *element_id = NULL;
+ gboolean hidden = FALSE;
+
+ g_variant_get (parameters, "(t&sb)", &page_id, &element_id, &hidden);
+
+ web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ if (!web_page)
+ return;
+
+ if (!element_id || !*element_id) {
+ g_warn_if_fail (element_id && *element_id);
+ } else {
+ document = webkit_web_page_get_dom_document (web_page);
+
+ /* A secret short-cut, to not have two functions for basically the same thing ("hide
attachment" and "hide element") */
+ if (!hidden && g_str_has_prefix (element_id, "attachment-wrapper-")) {
+ WebKitDOMElement *element;
+
+ element = e_dom_utils_find_element_by_id (document, element_id);
+
+ if (WEBKIT_DOM_IS_HTML_ELEMENT (element) &&
+ webkit_dom_element_get_child_element_count (element) == 0) {
+ gchar *inner_html_data;
+
+ inner_html_data = webkit_dom_element_get_attribute (element,
"inner-html-data");
+ if (inner_html_data && *inner_html_data) {
+ WebKitDOMHTMLElement *html_element;
+
+ html_element = WEBKIT_DOM_HTML_ELEMENT (element);
+ webkit_dom_html_element_set_inner_html (html_element,
inner_html_data, NULL);
+
+ webkit_dom_element_remove_attribute (element,
"inner-html-data");
+ }
+
+ g_free (inner_html_data);
+ }
+ }
+
+ e_dom_utils_hide_element (document, element_id, hidden);
+ }
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "SetElementStyleProperty") == 0) {
+ const gchar *element_id = NULL, *property_name = NULL, *value = NULL, *priority = NULL;
+
+ g_variant_get (parameters, "(t&s&s&s&s)", &page_id, &element_id, &property_name, &value,
&priority);
+
+ web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ if (!web_page)
+ return;
+
+ if (!element_id || !*element_id || !property_name || !*property_name) {
+ g_warn_if_fail (element_id && *element_id);
+ g_warn_if_fail (property_name && *property_name);
+ } else {
+ WebKitDOMElement *element;
+ gboolean use_child = FALSE;
+ gchar *tmp = NULL;
+
+ /* element_id can be also of the form: "id::child", where the change will
+ be done on the first child of it */
+ use_child = g_str_has_suffix (element_id, "::child");
+ if (use_child) {
+ tmp = g_strdup (element_id);
+ tmp[strlen (tmp) - 7] = '\0';
+
+ element_id = tmp;
+ }
+
+ document = webkit_web_page_get_dom_document (web_page);
+ element = e_dom_utils_find_element_by_id (document, element_id);
+
+ if (use_child && element)
+ element = webkit_dom_element_get_first_element_child (element);
+
+ if (element) {
+ WebKitDOMCSSStyleDeclaration *css;
+
+ css = webkit_dom_element_get_style (element);
+
+ if (value && *value)
+ webkit_dom_css_style_declaration_set_property (css, property_name,
value, priority, NULL);
+ else
+ g_free (webkit_dom_css_style_declaration_remove_property (css,
property_name, NULL));
+
+ g_clear_object (&css);
+ }
+
+ g_free (tmp);
+ }
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ } else if (g_strcmp0 (method_name, "SetElementAttribute") == 0) {
+ const gchar *element_id = NULL, *namespace_uri = NULL, *qualified_name = NULL, *value = NULL;
+
+ g_variant_get (parameters, "(t&s&s&s&s)", &page_id, &element_id, &namespace_uri,
&qualified_name, &value);
+
+ web_page = get_webkit_web_page_or_return_dbus_error (invocation, web_extension, page_id);
+ if (!web_page)
+ return;
+
+ if (!element_id || !*element_id || !qualified_name || !*qualified_name) {
+ g_warn_if_fail (element_id && *element_id);
+ g_warn_if_fail (qualified_name && *qualified_name);
+ } else {
+ WebKitDOMElement *element;
+ gboolean use_child = FALSE;
+ gchar *tmp = NULL;
+
+ /* element_id can be also of the form: "id::child", where the change will
+ be done on the first child of it */
+ use_child = g_str_has_suffix (element_id, "::child");
+ if (use_child) {
+ tmp = g_strdup (element_id);
+ tmp[strlen (tmp) - 7] = '\0';
+
+ element_id = tmp;
+ }
+
+ if (namespace_uri && !*namespace_uri)
+ namespace_uri = NULL;
+
+ document = webkit_web_page_get_dom_document (web_page);
+ element = e_dom_utils_find_element_by_id (document, element_id);
+
+ if (use_child && element)
+ element = webkit_dom_element_get_first_element_child (element);
+
+ if (element) {
+ if (value && *value)
+ webkit_dom_element_set_attribute_ns (element, namespace_uri,
qualified_name, value, NULL);
+ else
+ webkit_dom_element_remove_attribute_ns (element, namespace_uri,
qualified_name);
+ }
+
+ g_free (tmp);
+ }
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
} else if (g_strcmp0 (method_name, "DocumentHasSelection") == 0) {
gboolean has_selection;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]