281
mail_display_link_clicked (GtkHTML *html,
370
mail_display_link_clicked (WebKitWebView *web_view,
371
WebKitWebFrame *frame,
372
WebKitNetworkRequest *request,
373
WebKitWebNavigationAction *navigation_action,
374
WebKitWebPolicyDecision *policy_decision,
284
EMailDisplayPrivate *priv;
286
priv = E_MAIL_DISPLAY_GET_PRIVATE (html);
287
g_return_if_fail (priv->formatter != NULL);
289
if (g_str_has_prefix (uri, "##")) {
292
flags = priv->formatter->header_wrap_flags;
294
if (strcmp (uri, "##TO##") == 0) {
295
if (!(flags & EM_FORMAT_HTML_HEADER_TO))
296
flags |= EM_FORMAT_HTML_HEADER_TO;
298
flags &= ~EM_FORMAT_HTML_HEADER_TO;
299
} else if (strcmp (uri, "##CC##") == 0) {
300
if (!(flags & EM_FORMAT_HTML_HEADER_CC))
301
flags |= EM_FORMAT_HTML_HEADER_CC;
303
flags &= ~EM_FORMAT_HTML_HEADER_CC;
304
} else if (strcmp (uri, "##BCC##") == 0) {
305
if (!(flags & EM_FORMAT_HTML_HEADER_BCC))
306
flags |= EM_FORMAT_HTML_HEADER_BCC;
308
flags &= ~EM_FORMAT_HTML_HEADER_BCC;
309
} else if (strcmp (uri, "##HEADERS##") == 0) {
310
EMFormatHTMLHeadersState state;
312
state = em_format_html_get_headers_state (
315
if (state == EM_FORMAT_HTML_HEADERS_STATE_COLLAPSED)
316
state = EM_FORMAT_HTML_HEADERS_STATE_EXPANDED;
318
state = EM_FORMAT_HTML_HEADERS_STATE_COLLAPSED;
320
em_format_html_set_headers_state (
321
priv->formatter, state);
377
const gchar *uri = webkit_network_request_get_uri (request);
379
if (g_str_has_prefix (uri, "file://")) {
381
filename = g_filename_from_uri (uri, NULL, NULL);
383
if (g_file_test (filename, G_FILE_TEST_IS_DIR)) {
384
webkit_web_policy_decision_ignore (policy_decision);
385
webkit_network_request_set_uri (request, "about:blank");
324
priv->formatter->header_wrap_flags = flags;
325
em_format_queue_redraw (EM_FORMAT (priv->formatter));
327
} else if (mail_display_process_mailto (E_WEB_VIEW (html), uri)) {
393
if (mail_display_process_mailto (E_WEB_VIEW (web_view), uri, NULL)) {
328
394
/* do nothing, function handled the "mailto:" uri already */
329
} else if (*uri == '#')
330
gtk_html_jump_to_anchor (html, uri + 1);
332
else if (g_ascii_strncasecmp (uri, "thismessage:", 12) == 0)
335
else if (g_ascii_strncasecmp (uri, "cid:", 4) == 0)
339
/* Chain up to parent's link_clicked() method. */
340
GTK_HTML_CLASS (e_mail_display_parent_class)->
341
link_clicked (html, uri);
395
webkit_web_policy_decision_ignore (policy_decision);
398
} else if (g_ascii_strncasecmp (uri, "thismessage:", 12) == 0) {
400
webkit_web_policy_decision_ignore (policy_decision);
403
} else if (g_ascii_strncasecmp (uri, "cid:", 4) == 0) {
405
webkit_web_policy_decision_ignore (policy_decision);
410
/* Let webkit handle it */
415
webkit_request_load_from_file (WebKitNetworkRequest *request,
421
gchar *b64, *new_uri;
424
status = g_file_get_contents (path, &data, &length, NULL);
428
b64 = g_base64_encode ((guchar *) data, length);
429
ct = g_content_type_guess (path, NULL, 0, NULL);
431
new_uri = g_strdup_printf ("data:%s;base64,%s", ct, b64);
432
webkit_network_request_set_uri (request, new_uri);
441
mail_display_resource_requested (WebKitWebView *web_view,
442
WebKitWebFrame *frame,
443
WebKitWebResource *resource,
444
WebKitNetworkRequest *request,
445
WebKitNetworkResponse *response,
448
EMailDisplay *display = E_MAIL_DISPLAY (web_view);
449
EMailPartList *part_list;
450
const gchar *uri = webkit_network_request_get_uri (request);
452
part_list = display->priv->part_list;
457
/* Redirect cid:part_id to mail://mail_id/cid:part_id */
458
if (g_str_has_prefix (uri, "cid:")) {
460
/* Always write raw content of CID object */
461
gchar *new_uri = e_mail_part_build_uri (
462
part_list->folder, part_list->message_uid,
463
"part_id", G_TYPE_STRING, uri,
464
"mode", G_TYPE_INT, E_MAIL_FORMATTER_MODE_RAW, NULL);
466
webkit_network_request_set_uri (request, new_uri);
470
/* WebKit won't allow to load a local file when displaing "remote" mail://,
471
protocol, so we need to handle this manually */
472
} else if (g_str_has_prefix (uri, "file:")) {
475
path = g_filename_from_uri (uri, NULL, NULL);
479
webkit_request_load_from_file (request, path);
483
/* Redirect http(s) request to evo-http(s) protocol. See EMailRequest for
484
* further details about this. */
485
} else if (g_str_has_prefix (uri, "http:") || g_str_has_prefix (uri, "https")) {
487
gchar *new_uri, *mail_uri, *enc;
492
EMailImageLoadingPolicy image_policy;
494
/* Open Evolution's cache */
495
uri_md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1);
496
stream = camel_data_cache_get (
497
emd_global_http_cache, "http", uri_md5, NULL);
500
/* If the URI is not cached and we are not allowed to load it
501
* then redirect to invalid URI, so that webkit would display
502
* a native placeholder for it. */
503
image_policy = e_mail_formatter_get_image_loading_policy (
504
display->priv->formatter);
505
if (!stream && !display->priv->force_image_load &&
506
(image_policy == E_MAIL_IMAGE_LOADING_POLICY_NEVER)) {
507
webkit_network_request_set_uri (request, "about:blank");
511
new_uri = g_strconcat ("evo-", uri, NULL);
512
mail_uri = e_mail_part_build_uri (part_list->folder,
513
part_list->message_uid, NULL, NULL);
515
soup_uri = soup_uri_new (new_uri);
516
if (soup_uri->query) {
517
query = soup_form_decode (soup_uri->query);
519
query = g_hash_table_new_full (g_str_hash, g_str_equal,
522
enc = soup_uri_encode (mail_uri, NULL);
523
g_hash_table_insert (query, g_strdup ("__evo-mail"), enc);
525
if (display->priv->force_image_load) {
526
g_hash_table_insert (query,
527
g_strdup ("__evo-load-images"),
533
soup_uri_set_query_from_form (soup_uri, query);
536
new_uri = soup_uri_to_string (soup_uri, FALSE);
537
webkit_network_request_set_uri (request, new_uri);
540
soup_uri_free (soup_uri);
541
g_hash_table_unref (query);
545
static WebKitDOMElement *
546
find_element_by_id (WebKitDOMDocument *document,
549
WebKitDOMNodeList *frames;
550
WebKitDOMElement *element;
553
if (!WEBKIT_DOM_IS_DOCUMENT (document))
556
/* Try to look up the element in this DOM document */
557
element = webkit_dom_document_get_element_by_id (document, id);
561
/* If the element is not here then recursively scan all frames */
562
frames = webkit_dom_document_get_elements_by_tag_name(document, "iframe");
563
length = webkit_dom_node_list_get_length (frames);
564
for (i = 0; i < length; i++) {
566
WebKitDOMHTMLIFrameElement *iframe =
567
WEBKIT_DOM_HTML_IFRAME_ELEMENT (
568
webkit_dom_node_list_item (frames, i));
570
WebKitDOMDocument *frame_doc =
571
webkit_dom_html_iframe_element_get_content_document (iframe);
573
WebKitDOMElement *el =
574
find_element_by_id (frame_doc, id);
584
mail_display_plugin_widget_resize (GObject *object,
586
EMailDisplay *display)
589
WebKitDOMElement *parent_element;
593
widget = GTK_WIDGET (object);
594
parent_element = g_object_get_data (object, "parent_element");
596
if (!parent_element || !WEBKIT_DOM_IS_ELEMENT (parent_element)) {
597
d(printf("%s: %s does not have (valid) parent element!\n",
598
G_STRFUNC, (gchar *) g_object_get_data (object, "uri")));
602
/* For attachment bar, we need to ask for height it's parent,
603
* GtkBox, because EAttachmentBar itself lies about it's real height. */
604
if (E_IS_ATTACHMENT_BAR (widget)) {
605
widget = gtk_widget_get_parent (widget);
608
gtk_widget_get_preferred_height (widget, &height, NULL);
611
dim = g_strdup_printf ("%d", height);
613
/* Set height of the containment <object> to match height of the
614
* GtkWidget it contains */
615
webkit_dom_html_object_element_set_height (
616
WEBKIT_DOM_HTML_OBJECT_ELEMENT (parent_element), dim);
621
mail_display_plugin_widget_realize_cb (GtkWidget *widget,
624
WebKitDOMHTMLElement *el;
626
if (GTK_IS_BOX (widget)) {
629
children = gtk_container_get_children (GTK_CONTAINER (widget));
630
if (children && children->data &&
631
E_IS_ATTACHMENT_BAR (children->data)) {
632
widget = children->data;
635
g_list_free (children);
638
/* First check if we are actually supposed to be visible */
639
el = g_object_get_data (G_OBJECT (widget), "parent_element");
640
if (!el || !WEBKIT_DOM_IS_HTML_ELEMENT (el)) {
641
g_warning ("UAAAAA");
643
if (webkit_dom_html_element_get_hidden (el)) {
644
gtk_widget_hide (widget);
649
/* Initial resize of the <object> element when the widget
650
* is displayed for the first time. */
651
mail_display_plugin_widget_resize (G_OBJECT (widget), NULL, user_data);
655
plugin_widget_set_parent_element (GtkWidget *widget,
656
EMailDisplay *display)
659
WebKitDOMDocument *document;
660
WebKitDOMElement *element;
662
uri = g_object_get_data (G_OBJECT (widget), "uri");
666
document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (display));
667
element = find_element_by_id (document, uri);
669
if (!element || !WEBKIT_DOM_IS_ELEMENT (element)) {
670
g_warning ("Failed to find parent <object> for '%s' - no ID set?", uri);
674
/* Assign the WebKitDOMElement to "parent_element" data of the GtkWidget
675
* and the GtkWidget to "widget" data of the DOM Element */
676
g_object_set_data (G_OBJECT (widget), "parent_element", element);
677
g_object_set_data (G_OBJECT (element), "widget", widget);
679
g_object_bind_property (
682
G_BINDING_SYNC_CREATE |
683
G_BINDING_INVERT_BOOLEAN);
687
toggle_widget_visibility (EAttachmentButton *button,
688
EMailDisplay *display,
689
WebKitDOMElement *element)
694
id = webkit_dom_html_element_get_id (WEBKIT_DOM_HTML_ELEMENT (element));
699
if (!display->priv->widgets) {
704
widget = g_hash_table_lookup (display->priv->widgets, id);
710
/* If the widget encapsulates EAttachmentBar then check, whether
711
* the attachment bar is not empty. We want to display it only
712
* when there's at least one attachment */
713
if (GTK_IS_BOX (widget)) {
716
children = gtk_container_get_children (GTK_CONTAINER (widget));
717
if (children && children->data && E_IS_ATTACHMENT_BAR (children->data)) {
718
EAttachmentStore *store;
720
store = e_attachment_bar_get_store (
721
E_ATTACHMENT_BAR (children->data));
723
g_list_free (children);
725
/* Don't allow to display such attachment bar,
726
* but always allow to hide it */
727
if (e_attachment_button_get_expanded (button) &&
728
(e_attachment_store_get_num_attachments (store) == 0)) {
734
webkit_dom_html_element_set_hidden (
735
WEBKIT_DOM_HTML_ELEMENT (element),
736
!e_attachment_button_get_expanded (button));
738
if (e_attachment_button_get_expanded (button)) {
739
gtk_widget_show (widget);
741
gtk_widget_hide (widget);
746
* @button: An #EAttachmentButton
747
* @iframe: An iframe element containing document with an attachment
748
* represented by the @button
751
bind_iframe_content_visibility (WebKitDOMElement *iframe,
752
EMailDisplay *display,
753
EAttachmentButton *button)
755
WebKitDOMDocument *document;
756
WebKitDOMNodeList *nodes;
759
if (!iframe || !WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (iframe))
762
document = webkit_dom_html_iframe_element_get_content_document (
763
WEBKIT_DOM_HTML_IFRAME_ELEMENT (iframe));
764
if (!WEBKIT_DOM_IS_DOCUMENT (document))
767
nodes = webkit_dom_document_get_elements_by_tag_name (document, "object");
768
length = webkit_dom_node_list_get_length (nodes);
771
gchar *name = webkit_dom_html_iframe_element_get_name (
772
WEBKIT_DOM_HTML_IFRAME_ELEMENT (iframe));
773
printf("Found %ld objects within iframe %s\n", length, name);
777
/* Iterate through all <object>s and bind visibility of their widget
778
* with expanded-state of related attachment button */
779
for (i = 0; i < length; i++) {
781
WebKitDOMNode *node = webkit_dom_node_list_item (nodes, i);
784
toggle_widget_visibility (button, display, WEBKIT_DOM_ELEMENT (node));
789
attachment_button_expanded (GObject *object,
793
EAttachmentButton *button = E_ATTACHMENT_BUTTON (object);
794
EMailDisplay *display = user_data;
795
WebKitDOMDocument *document;
796
WebKitDOMElement *element;
797
WebKitDOMCSSStyleDeclaration *css;
801
d(printf("Attachment button %s has been %s!\n",
802
(gchar *) g_object_get_data (object, "uri"),
803
(e_attachment_button_get_expanded (button) ? "expanded" : "collapsed")));
805
expanded = e_attachment_button_get_expanded (button) &&
806
gtk_widget_get_visible (GTK_WIDGET (button));
808
document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (display));
809
element = find_element_by_id (document, g_object_get_data (object, "attachment_id"));
811
if (!WEBKIT_DOM_IS_ELEMENT (element)) {
812
d(printf("%s: Content <div> of attachment %s does not exist!!\n",
813
G_STRFUNC, (gchar *) g_object_get_data (object, "uri")));
817
/* Show or hide the DIV which contains the attachment (iframe, image...) */
818
css = webkit_dom_element_get_style (element);
819
webkit_dom_css_style_declaration_set_property (
820
css, "display", expanded ? "block" : "none", "", NULL);
822
id = g_strconcat (g_object_get_data (object, "attachment_id"), ".iframe", NULL);
823
element = find_element_by_id (document, id);
826
if (!WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element)) {
827
d(printf("%s: No <iframe> found\n",
828
(gchar *) g_object_get_data (object, "attachment_id")));
831
bind_iframe_content_visibility (element, display, button);
835
mail_display_attachment_count_changed (EAttachmentStore *store,
839
WebKitDOMHTMLElement *element;
842
children = gtk_container_get_children (GTK_CONTAINER (box));
843
g_return_if_fail (children && children->data);
845
element = g_object_get_data (children->data, "parent_element");
846
g_list_free (children);
848
g_return_if_fail (WEBKIT_DOM_IS_HTML_ELEMENT (element));
850
if (e_attachment_store_get_num_attachments (store) == 0) {
851
gtk_widget_hide (box);
852
webkit_dom_html_element_set_hidden (element, TRUE);
854
gtk_widget_show (box);
855
webkit_dom_html_element_set_hidden (element, FALSE);
860
mail_display_plugin_widget_requested (WebKitWebView *web_view,
866
EMailDisplay *display;
867
EMailExtensionRegistry *reg;
868
EMailFormatterExtension *extension;
873
gchar *part_id, *type, *object_uri;
875
part_id = g_hash_table_lookup (param, "data");
876
if (!part_id || !g_str_has_prefix (uri, "mail://"))
879
type = g_hash_table_lookup (param, "type");
883
display = E_MAIL_DISPLAY (web_view);
885
if ((widget = g_hash_table_lookup (display->priv->widgets, part_id)) != NULL) {
886
d(printf("Handeled %s widget request from cache\n", part_id));
890
/* Findt EMailPart representing requested widget */
891
part = e_mail_part_list_find_part (display->priv->part_list, part_id);
896
reg = e_mail_formatter_get_extension_registry (display->priv->formatter);
897
extensions = e_mail_extension_registry_get_for_mime_type (reg, type);
902
for (iter = g_queue_peek_head_link (extensions); iter; iter = iter->next) {
904
extension = iter->data;
908
if (e_mail_formatter_extension_has_widget (extension))
915
/* Get the widget from formatter */
916
widget = e_mail_formatter_extension_get_widget (
917
extension, display->priv->part_list, part, param);
918
d(printf("Created widget %s (%p) for part %s\n",
919
G_OBJECT_TYPE_NAME (widget), widget, part_id));
921
/* Should not happen! WebKit will display an ugly 'Plug-in not available'
922
* placeholder instead of hiding the <object> element */
926
/* Attachment button has URI different then the actual PURI because
927
* that URI identifies the attachment itself */
928
if (E_IS_ATTACHMENT_BUTTON (widget)) {
929
EMailPartAttachment *empa = (EMailPartAttachment *) part;
930
gchar *attachment_part_id;
932
if (empa->attachment_view_part_id)
933
attachment_part_id = empa->attachment_view_part_id;
935
attachment_part_id = part_id;
937
object_uri = g_strconcat (attachment_part_id, ".attachment_button", NULL);
938
g_object_set_data_full (G_OBJECT (widget), "attachment_id",
939
g_strdup (attachment_part_id), (GDestroyNotify) g_free);
941
object_uri = g_strdup (part_id);
944
/* Store the uri as data of the widget */
945
g_object_set_data_full (G_OBJECT (widget), "uri",
946
object_uri, (GDestroyNotify) g_free);
948
/* Set pointer to the <object> element as GObject data "parent_element"
949
* and set pointer to the widget as GObject data "widget" to the <object>
951
plugin_widget_set_parent_element (widget, display);
953
/* Resizing a GtkWidget requires changing size of parent
954
* <object> HTML element in DOM. */
955
g_signal_connect (widget, "realize",
956
G_CALLBACK (mail_display_plugin_widget_realize_cb), display);
957
g_signal_connect (widget, "size-allocate",
958
G_CALLBACK (mail_display_plugin_widget_resize), display);
960
if (E_IS_ATTACHMENT_BAR (widget)) {
961
GtkWidget *box = NULL;
962
EAttachmentStore *store;
964
/* Only when packed in box (grid does not work),
965
* EAttachmentBar reports correct height */
966
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
967
gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 0);
969
/* When EAttachmentBar is expanded/collapsed it does not
970
* emit size-allocate signal despite it changes it's height. */
971
g_signal_connect (widget, "notify::expanded",
972
G_CALLBACK (mail_display_plugin_widget_resize), display);
973
g_signal_connect (widget, "notify::active-view",
974
G_CALLBACK (mail_display_plugin_widget_resize), display);
976
/* Always hide an attachment bar without attachments */
977
store = e_attachment_bar_get_store (E_ATTACHMENT_BAR (widget));
978
g_signal_connect (store, "notify::num-attachments",
979
G_CALLBACK (mail_display_attachment_count_changed), box);
981
gtk_widget_show (widget);
982
gtk_widget_show (box);
985
mail_display_attachment_count_changed (store, NULL, box);
989
} else if (E_IS_ATTACHMENT_BUTTON (widget)) {
991
/* Bind visibility of DOM element containing related
992
* attachment with 'expanded' property of this
993
* attachment button. */
994
WebKitDOMElement *attachment;
995
WebKitDOMDocument *document;
996
EMailPartAttachment *empa = (EMailPartAttachment *) part;
997
gchar *attachment_part_id;
999
if (empa->attachment_view_part_id)
1000
attachment_part_id = empa->attachment_view_part_id;
1002
attachment_part_id = part_id;
1004
/* Find attachment-wrapper div which contains the content of the
1005
* attachment (iframe) */
1006
document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (display));
1007
attachment = find_element_by_id (document, attachment_part_id);
1009
/* None found? Attachment cannot be expanded */
1011
e_attachment_button_set_expandable (
1012
E_ATTACHMENT_BUTTON (widget), FALSE);
1014
const CamelContentDisposition *disposition;
1016
e_attachment_button_set_expandable (
1017
E_ATTACHMENT_BUTTON (widget), TRUE);
1019
/* Show/hide the attachment when the EAttachmentButton
1020
* * is expanded/collapsed or shown/hidden */
1021
g_signal_connect (widget, "notify::expanded",
1022
G_CALLBACK (attachment_button_expanded), display);
1023
g_signal_connect (widget, "notify::visible",
1024
G_CALLBACK (attachment_button_expanded), display);
1026
/* Automatically expand attachments that have inline
1027
* disposition or the EMailParts have specific force_inline
1030
camel_mime_part_get_content_disposition (part->part);
1031
if (!part->force_collapse &&
1032
(part->force_inline ||
1033
(g_strcmp0 (empa->snoop_mime_type, "message/rfc822") == 0) ||
1034
(disposition && disposition->disposition &&
1035
g_ascii_strncasecmp (
1036
disposition->disposition, "inline", 6) == 0))) {
1038
e_attachment_button_set_expanded (
1039
E_ATTACHMENT_BUTTON (widget), TRUE);
1041
e_attachment_button_set_expanded (
1042
E_ATTACHMENT_BUTTON (widget), FALSE);
1043
attachment_button_expanded (
1044
G_OBJECT (widget), NULL, display);
1049
g_hash_table_insert (
1050
display->priv->widgets,
1051
g_strdup (object_uri), g_object_ref (widget));
1057
toggle_headers_visibility (WebKitDOMElement *button,
1058
WebKitDOMEvent *event,
1059
WebKitWebView *web_view)
1061
WebKitDOMDocument *document;
1062
WebKitDOMElement *short_headers, *full_headers;
1063
WebKitDOMCSSStyleDeclaration *css_short, *css_full;
1068
document = webkit_web_view_get_dom_document (web_view);
1070
short_headers = webkit_dom_document_get_element_by_id (
1071
document, "__evo-short-headers");
1075
css_short = webkit_dom_element_get_style (short_headers);
1077
full_headers = webkit_dom_document_get_element_by_id (
1078
document, "__evo-full-headers");
1082
css_full = webkit_dom_element_get_style (full_headers);
1083
css_value = webkit_dom_css_style_declaration_get_property_value (
1084
css_full, "display");
1085
expanded = (g_strcmp0 (css_value, "block") == 0);
1088
webkit_dom_css_style_declaration_set_property (css_full, "display",
1089
expanded ? "none" : "block", "", NULL);
1090
webkit_dom_css_style_declaration_set_property (css_short, "display",
1091
expanded ? "block" : "none", "", NULL);
1094
path = "evo-file://" EVOLUTION_IMAGESDIR "/plus.png";
1096
path = "evo-file://" EVOLUTION_IMAGESDIR "/minus.png";
1098
webkit_dom_html_image_element_set_src (
1099
WEBKIT_DOM_HTML_IMAGE_ELEMENT (button), path);
1101
e_mail_display_set_headers_collapsed (E_MAIL_DISPLAY (web_view), expanded);
1103
d(printf("Headers %s!\n", expanded ? "collapsed" : "expanded"));
1106
static const gchar* addresses[] = { "to", "cc", "bcc" };
1109
toggle_address_visibility (WebKitDOMElement *button,
1110
WebKitDOMEvent *event,
1111
const gchar *address)
1113
WebKitDOMElement *full_addr, *ellipsis;
1114
WebKitDOMCSSStyleDeclaration *css_full, *css_ellipsis;
1115
WebKitDOMDocument *document;
1120
document = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (button));
1122
id = g_strconcat ("__evo-moreaddr-", address, NULL);
1123
full_addr = webkit_dom_document_get_element_by_id (document, id);
1129
css_full = webkit_dom_element_get_style (full_addr);
1131
id = g_strconcat ("__evo-moreaddr-ellipsis-", address, NULL);
1132
ellipsis = webkit_dom_document_get_element_by_id (document, id);
1138
css_ellipsis = webkit_dom_element_get_style (ellipsis);
1140
expanded = (g_strcmp0 (
1141
webkit_dom_css_style_declaration_get_property_value (
1142
css_full, "display"), "inline") == 0);
1144
webkit_dom_css_style_declaration_set_property (
1145
css_full, "display", (expanded ? "none" : "inline"), "", NULL);
1146
webkit_dom_css_style_declaration_set_property (
1147
css_ellipsis, "display", (expanded ? "inline" : "none"), "", NULL);
1150
path = "evo-file://" EVOLUTION_IMAGESDIR "/plus.png";
1152
path = "evo-file://" EVOLUTION_IMAGESDIR "/minus.png";
1155
if (!WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (button)) {
1156
id = g_strconcat ("__evo-moreaddr-img-", address, NULL);
1157
button = webkit_dom_document_get_element_by_id (document, id);
1164
webkit_dom_html_image_element_set_src (
1165
WEBKIT_DOM_HTML_IMAGE_ELEMENT (button), path);
1170
setup_DOM_bindings (GObject *object,
1174
WebKitWebView *web_view;
1175
WebKitWebFrame *frame;
1176
WebKitLoadStatus load_status;
1177
WebKitDOMDocument *document;
1178
WebKitDOMElement *button;
1181
frame = WEBKIT_WEB_FRAME (object);
1182
load_status = webkit_web_frame_get_load_status (frame);
1183
if (load_status != WEBKIT_LOAD_FINISHED)
1186
web_view = webkit_web_frame_get_web_view (frame);
1187
document = webkit_web_view_get_dom_document (web_view);
1189
button = webkit_dom_document_get_element_by_id (
1190
document, "__evo-collapse-headers-img");
1194
d(printf("Conntecting to __evo-collapsable-headers-img::click event\n"));
1196
webkit_dom_event_target_add_event_listener (
1197
WEBKIT_DOM_EVENT_TARGET (button), "click",
1198
G_CALLBACK (toggle_headers_visibility), FALSE, web_view);
1200
for (i = 0; i < 3; i++) {
1202
id = g_strconcat ("__evo-moreaddr-img-", addresses[i], NULL);
1203
button = webkit_dom_document_get_element_by_id (document, id);
1209
webkit_dom_event_target_add_event_listener (
1210
WEBKIT_DOM_EVENT_TARGET (button), "click",
1211
G_CALLBACK (toggle_address_visibility), FALSE,
1212
(gpointer) addresses[i]);
1214
id = g_strconcat ("__evo-moreaddr-ellipsis-", addresses[i], NULL);
1215
button = webkit_dom_document_get_element_by_id (document, id);
1221
webkit_dom_event_target_add_event_listener (
1222
WEBKIT_DOM_EVENT_TARGET (button), "click",
1223
G_CALLBACK (toggle_address_visibility), FALSE,
1224
(gpointer) addresses[i]);
1229
mail_parts_bind_dom (GObject *object,
1233
WebKitWebFrame *frame;
1234
WebKitLoadStatus load_status;
1235
WebKitWebView *web_view;
1236
WebKitDOMDocument *document;
1237
EMailDisplay *display;
1239
const gchar *frame_name;
1241
frame = WEBKIT_WEB_FRAME (object);
1242
load_status = webkit_web_frame_get_load_status (frame);
1244
if (load_status != WEBKIT_LOAD_FINISHED)
1247
web_view = webkit_web_frame_get_web_view (frame);
1248
display = E_MAIL_DISPLAY (web_view);
1249
if (display->priv->part_list == NULL)
1252
frame_name = webkit_web_frame_get_name (frame);
1253
if (!frame_name || !*frame_name)
1254
frame_name = ".message.headers";
1256
for (iter = display->priv->part_list->list; iter; iter = iter->next) {
1258
EMailPart *part = iter->data;
1262
if (g_strcmp0 (part->id, frame_name) == 0)
1266
document = webkit_web_view_get_dom_document (web_view);
1269
EMailPart *part = iter->data;
1275
/* Iterate only the parts rendered in the frame and all it's subparts */
1276
if (!g_str_has_prefix (part->id, frame_name))
1279
if (part->bind_func) {
1280
WebKitDOMElement *el = find_element_by_id (document, part->id);
1282
d(printf("/*bind_func*/ for %s\n", part->id));
1283
part->bind_func (part, el);
1292
mail_display_frame_created (WebKitWebView *web_view,
1293
WebKitWebFrame *frame,
1296
d(printf("Frame %s created!\n", webkit_web_frame_get_name (frame)));
1298
/* Call bind_func of all parts written in this frame */
1299
g_signal_connect (frame, "notify::load-status",
1300
G_CALLBACK (mail_parts_bind_dom), NULL);
1304
mail_display_uri_changed (EMailDisplay *display,
1308
d(printf("EMailDisplay URI changed, recreating widgets hashtable\n"));
1310
if (display->priv->widgets)
1311
g_hash_table_destroy (display->priv->widgets);
1313
display->priv->widgets = g_hash_table_new_full (
1314
g_str_hash, g_str_equal,
1315
(GDestroyNotify) g_free,
1316
(GDestroyNotify) g_object_unref);
1320
mail_display_set_fonts (EWebView *web_view,
1321
PangoFontDescription **monospace,
1322
PangoFontDescription **variable)
1324
EMailDisplay *display = E_MAIL_DISPLAY (web_view);
1325
gboolean use_custom_font;
1326
gchar *monospace_font, *variable_font;
1328
use_custom_font = g_settings_get_boolean (display->priv->settings, "use-custom-font");
1329
if (!use_custom_font) {
1335
monospace_font = g_settings_get_string (
1336
display->priv->settings,
1338
variable_font = g_settings_get_string (
1339
display->priv->settings,
1340
"variable-width-font");
1342
*monospace = monospace_font ? pango_font_description_from_string (monospace_font) : NULL;
1343
*variable = variable_font ? pango_font_description_from_string (variable_font) : NULL;
1346
g_free (monospace_font);
1348
g_free (variable_font);
346
1352
e_mail_display_class_init (EMailDisplayClass *class)
348
1354
GObjectClass *object_class;
1355
EWebViewClass *web_view_class;
349
1356
GtkWidgetClass *widget_class;
350
EWebViewClass *web_view_class;
351
GtkHTMLClass *html_class;
353
1358
g_type_class_add_private (class, sizeof (EMailDisplayPrivate));
357
1362
object_class->get_property = mail_display_get_property;
358
1363
object_class->dispose = mail_display_dispose;
1365
web_view_class = E_WEB_VIEW_CLASS (class);
1366
web_view_class->set_fonts = mail_display_set_fonts;
1367
web_view_class->update_actions = mail_display_update_actions;
360
1369
widget_class = GTK_WIDGET_CLASS (class);
361
1370
widget_class->realize = mail_display_realize;
362
1371
widget_class->style_set = mail_display_style_set;
364
web_view_class = E_WEB_VIEW_CLASS (class);
365
web_view_class->load_string = mail_display_load_string;
366
web_view_class->process_mailto = mail_display_process_mailto;
368
html_class = GTK_HTML_CLASS (class);
369
html_class->url_requested = mail_display_url_requested;
370
html_class->link_clicked = mail_display_link_clicked;
372
g_object_class_install_property (
375
g_param_spec_object (
1373
g_object_class_install_property (
1376
g_param_spec_pointer (
1380
G_PARAM_READWRITE));
1382
g_object_class_install_property (
1389
E_MAIL_FORMATTER_MODE_INVALID,
1391
E_MAIL_FORMATTER_MODE_NORMAL,
1392
G_PARAM_READWRITE));
1394
g_object_class_install_property (
1396
PROP_HEADERS_COLLAPSABLE,
1397
g_param_spec_boolean (
1398
"headers-collapsable",
1399
"Headers Collapsable",
1402
G_PARAM_READWRITE));
1404
g_object_class_install_property (
1406
PROP_HEADERS_COLLAPSED,
1407
g_param_spec_boolean (
1408
"headers-collapsed",
1409
"Headers Collapsed",
380
1412
G_PARAM_READWRITE));
384
1416
e_mail_display_init (EMailDisplay *display)
387
1418
GtkUIManager *ui_manager;
388
GtkActionGroup *action_group;
389
GError *error = NULL;
391
web_view = E_WEB_VIEW (display);
1419
const gchar *user_cache_dir;
1420
WebKitWebSettings *settings;
1421
WebKitWebFrame *main_frame;
1422
GtkActionGroup *actions;
393
1424
display->priv = E_MAIL_DISPLAY_GET_PRIVATE (display);
395
/* EWebView's action groups are added during its instance
396
* initialization function (like what we're in now), so it
397
* is safe to fetch them this early in construction. */
398
action_group = e_web_view_get_action_group (web_view, "mailto");
400
/* We don't actually handle the actions we're adding.
401
* EMailReader handles them. How devious is that? */
402
gtk_action_group_add_actions (
403
action_group, mailto_entries,
404
G_N_ELEMENTS (mailto_entries), display);
406
/* Because we are loading from a hard-coded string, there is
407
* no chance of I/O errors. Failure here implies a malformed
408
* UI definition. Full stop. */
409
ui_manager = e_web_view_get_ui_manager (web_view);
410
gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
412
g_error ("%s", error->message);
416
e_mail_display_get_formatter (EMailDisplay *display)
418
g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
420
return display->priv->formatter;
424
e_mail_display_set_formatter (EMailDisplay *display,
425
EMFormatHTML *formatter)
427
g_return_if_fail (E_IS_MAIL_DISPLAY (display));
428
g_return_if_fail (EM_IS_FORMAT_HTML (formatter));
430
if (display->priv->formatter != NULL)
431
g_object_unref (display->priv->formatter);
433
display->priv->formatter = g_object_ref (formatter);
435
g_object_notify (G_OBJECT (display), "formatter");
1426
/* Set invalid mode so that MODE property initialization is run
1427
* completely (see e_mail_display_set_mode) */
1428
display->priv->mode = E_MAIL_FORMATTER_MODE_INVALID;
1429
e_mail_display_set_mode (display, E_MAIL_FORMATTER_MODE_NORMAL);
1430
display->priv->force_image_load = FALSE;
1432
webkit_web_view_set_full_content_zoom (WEBKIT_WEB_VIEW (display), TRUE);
1434
settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (display));
1435
g_object_set (settings, "enable-frame-flattening", TRUE, NULL);
1437
g_signal_connect (display, "navigation-policy-decision-requested",
1438
G_CALLBACK (mail_display_link_clicked), NULL);
1439
g_signal_connect (display, "resource-request-starting",
1440
G_CALLBACK (mail_display_resource_requested), NULL);
1441
g_signal_connect (display, "process-mailto",
1442
G_CALLBACK (mail_display_process_mailto), NULL);
1443
g_signal_connect (display, "create-plugin-widget",
1444
G_CALLBACK (mail_display_plugin_widget_requested), NULL);
1445
g_signal_connect (display, "frame-created",
1446
G_CALLBACK (mail_display_frame_created), NULL);
1447
g_signal_connect (display, "notify::uri",
1448
G_CALLBACK (mail_display_uri_changed), NULL);
1450
display->priv->settings = g_settings_new ("org.gnome.evolution.mail");
1451
g_signal_connect_swapped (
1452
display->priv->settings , "changed::monospace-font",
1453
G_CALLBACK (e_web_view_update_fonts), display);
1454
g_signal_connect_swapped (
1455
display->priv->settings , "changed::variable-width-font",
1456
G_CALLBACK (e_web_view_update_fonts), display);
1457
g_signal_connect_swapped (
1458
display->priv->settings , "changed::use-custom-font",
1459
G_CALLBACK (e_web_view_update_fonts), display);
1461
e_web_view_update_fonts (E_WEB_VIEW (display));
1463
main_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (display));
1464
g_signal_connect (main_frame, "notify::load-status",
1465
G_CALLBACK (setup_DOM_bindings), NULL);
1466
main_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (display));
1467
g_signal_connect (main_frame, "notify::load-status",
1468
G_CALLBACK (mail_parts_bind_dom), NULL);
1470
actions = e_web_view_get_action_group (E_WEB_VIEW (display), "mailto");
1471
gtk_action_group_add_actions (
1472
actions, mailto_entries, G_N_ELEMENTS (mailto_entries), display);
1473
ui_manager = e_web_view_get_ui_manager (E_WEB_VIEW (display));
1474
gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, NULL);
1476
actions = e_web_view_get_action_group (E_WEB_VIEW (display), "image");
1477
gtk_action_group_add_actions (
1478
actions, image_entries, G_N_ELEMENTS (image_entries), display);
1479
gtk_ui_manager_add_ui_from_string (ui_manager, image_ui, -1, NULL);
1481
e_web_view_install_request_handler (E_WEB_VIEW (display), E_TYPE_MAIL_REQUEST);
1482
e_web_view_install_request_handler (E_WEB_VIEW (display), E_TYPE_HTTP_REQUEST);
1483
e_web_view_install_request_handler (E_WEB_VIEW (display), E_TYPE_FILE_REQUEST);
1484
e_web_view_install_request_handler (E_WEB_VIEW (display), E_TYPE_STOCK_REQUEST);
1486
/* cache expiry - 2 hour access, 1 day max */
1487
user_cache_dir = e_get_user_cache_dir ();
1488
emd_global_http_cache = camel_data_cache_new (user_cache_dir, NULL);
1489
if (emd_global_http_cache) {
1490
camel_data_cache_set_expire_age (emd_global_http_cache, 24 * 60 * 60);
1491
camel_data_cache_set_expire_access (emd_global_http_cache, 2 * 60 * 60);
1496
e_mail_display_get_mode (EMailDisplay *display)
1498
g_return_val_if_fail (E_IS_MAIL_DISPLAY (display),
1499
E_MAIL_FORMATTER_MODE_NORMAL);
1501
return display->priv->mode;
1505
reload_display (EMailDisplay *display)
1507
e_mail_display_reload (display);
1512
schedule_display_reload (EMailDisplay *display)
1514
if (display->priv->reload_scheduled)
1517
g_idle_add ((GSourceFunc) reload_display, display);
1518
display->priv->reload_scheduled = TRUE;
1522
e_mail_display_set_mode (EMailDisplay *display,
1523
EMailFormatterMode mode)
1525
EMailFormatter *formatter;
1526
g_return_if_fail (E_IS_MAIL_DISPLAY (display));
1528
if (display->priv->mode == mode)
1531
display->priv->mode = mode;
1533
if (display->priv->mode == E_MAIL_FORMATTER_MODE_PRINTING) {
1534
formatter = e_mail_formatter_print_new ();
1536
formatter = e_mail_formatter_new ();
1539
g_clear_object (&display->priv->formatter);
1540
display->priv->formatter = formatter;
1541
mail_display_update_formatter_colors (display);
1543
g_signal_connect (formatter, "notify::image-loading-policy",
1544
G_CALLBACK (formatter_image_loading_policy_changed_cb), display);
1546
g_object_connect (formatter,
1547
"swapped-signal::notify::charset",
1548
G_CALLBACK (schedule_display_reload), display,
1549
"swapped-signal::notify::image-loading-policy",
1550
G_CALLBACK (schedule_display_reload), display,
1551
"swapped-signal::notify::mark-citations",
1552
G_CALLBACK (schedule_display_reload), display,
1553
"swapped-signal::notify::only-local-photos",
1554
G_CALLBACK (schedule_display_reload), display,
1555
"swapped-signal::notify::show-sender-photo",
1556
G_CALLBACK (schedule_display_reload), display,
1557
"swapped-signal::notify::show-real-date",
1558
G_CALLBACK (schedule_display_reload), display,
1559
"swapped-signal::notify::animate-images",
1560
G_CALLBACK (schedule_display_reload), display,
1561
"swapped-signal::notify::text-color",
1562
G_CALLBACK (schedule_display_reload), display,
1563
"swapped-signal::notify::body-color",
1564
G_CALLBACK (schedule_display_reload), display,
1565
"swapped-signal::notify::citation-color",
1566
G_CALLBACK (schedule_display_reload), display,
1567
"swapped-signal::notify::content-color",
1568
G_CALLBACK (schedule_display_reload), display,
1569
"swapped-signal::notify::frame-color",
1570
G_CALLBACK (schedule_display_reload), display,
1571
"swapped-signal::notify::header-color",
1572
G_CALLBACK (schedule_display_reload), display,
1573
"swapped-signal::need-redraw",
1574
G_CALLBACK (schedule_display_reload), display,
1577
e_mail_display_reload (display);
1579
g_object_notify (G_OBJECT (display), "mode");
1583
e_mail_display_get_parts_list (EMailDisplay *display)
1585
g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
1587
return display->priv->part_list;
1591
e_mail_display_set_parts_list (EMailDisplay *display,
1592
EMailPartList *part_list)
1594
g_return_if_fail (E_IS_MAIL_DISPLAY (display));
1596
if (display->priv->part_list == part_list)
1600
g_return_if_fail (E_IS_MAIL_PART_LIST (part_list));
1601
g_object_ref (part_list);
1604
if (display->priv->part_list)
1605
g_object_unref (display->priv->part_list);
1607
display->priv->part_list = part_list;
1609
g_object_notify (G_OBJECT (display), "part-list");
1613
e_mail_display_get_headers_collapsable (EMailDisplay *display)
1615
g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), FALSE);
1617
return display->priv->headers_collapsable;
1621
e_mail_display_set_headers_collapsable (EMailDisplay *display,
1622
gboolean collapsable)
1624
g_return_if_fail (E_IS_MAIL_DISPLAY (display));
1626
if ((display->priv->headers_collapsable ? 1 : 0) == (collapsable ? 1 : 0))
1629
display->priv->headers_collapsable = collapsable;
1630
e_mail_display_reload (display);
1632
g_object_notify (G_OBJECT (display), "headers-collapsable");
1636
e_mail_display_get_headers_collapsed (EMailDisplay *display)
1638
g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), FALSE);
1640
if (display->priv->headers_collapsable)
1641
return display->priv->headers_collapsed;
1647
e_mail_display_set_headers_collapsed (EMailDisplay *display,
1650
g_return_if_fail (E_IS_MAIL_DISPLAY (display));
1652
if ((display->priv->headers_collapsed ? 1 : 0) == (collapsed ? 1 : 0))
1655
display->priv->headers_collapsed = collapsed;
1657
g_object_notify (G_OBJECT (display), "headers-collapsed");
1661
e_mail_display_load (EMailDisplay *display,
1662
const gchar *msg_uri)
1665
EMailPartList *part_list;
1667
g_return_if_fail (E_IS_MAIL_DISPLAY (display));
1669
display->priv->force_image_load = FALSE;
1671
part_list = display->priv->part_list;
1673
e_web_view_clear (E_WEB_VIEW (display));
1677
uri = e_mail_part_build_uri (
1678
part_list->folder, part_list->message_uid,
1679
"mode", G_TYPE_INT, display->priv->mode,
1680
"headers_collapsable", G_TYPE_BOOLEAN, display->priv->headers_collapsable,
1681
"headers_collapsed", G_TYPE_BOOLEAN, display->priv->headers_collapsed,
1684
e_web_view_load_uri (E_WEB_VIEW (display), uri);
1690
e_mail_display_reload (EMailDisplay *display)
1697
GHashTableIter table_iter;
1700
g_return_if_fail (E_IS_MAIL_DISPLAY (display));
1702
web_view = E_WEB_VIEW (display);
1703
uri = e_web_view_get_uri (web_view);
1705
display->priv->reload_scheduled = FALSE;
1710
if (strstr(uri, "?") == NULL) {
1711
e_web_view_reload (web_view);
1715
base = g_strndup (uri, strstr (uri, "?") - uri + 1);
1716
new_uri = g_string_new (base);
1719
table = soup_form_decode (strstr (uri, "?") + 1);
1720
g_hash_table_replace (table, g_strdup ("mode"), g_strdup_printf ("%d", display->priv->mode));
1721
g_hash_table_replace (table, g_strdup ("headers_collapsable"), g_strdup_printf ("%d", display->priv->headers_collapsable));
1722
g_hash_table_replace (table, g_strdup ("headers_collapsed"), g_strdup_printf ("%d", display->priv->headers_collapsed));
1724
g_hash_table_iter_init (&table_iter, table);
1725
while (g_hash_table_iter_next (&table_iter, &key, &val)) {
1726
g_string_append_printf (new_uri, "%s=%s&",
1727
(gchar *) key, (gchar *) val);
1729
/* Free the value as Soup constructs the GHashTable without
1730
* value_destroy_func */
1734
e_web_view_load_uri (web_view, new_uri->str);
1736
g_string_free (new_uri, TRUE);
1737
g_hash_table_destroy (table);
1742
e_mail_display_get_action (EMailDisplay *display,
1743
const gchar *action_name)
1747
g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
1748
g_return_val_if_fail (action_name != NULL, NULL);
1750
action = e_web_view_get_action (E_WEB_VIEW (display), action_name);
1756
e_mail_display_set_status (EMailDisplay *display,
1757
const gchar *status)
1761
g_return_if_fail (E_IS_MAIL_DISPLAY (display));
1763
str = g_strdup_printf (
1766
"<head><title>Evolution Mail Display</title></head>"
1768
"<table border=\"0\" width=\"100%%\" height=\"100%%\">"
1769
"<tr height=\"100%%\" valign=\"middle\">"
1770
"<td width=\"100%%\" align=\"center\">"
1771
"<strong>%s</strong>"
1778
e_web_view_load_string (E_WEB_VIEW (display), str);
1781
gtk_widget_show_all (GTK_WIDGET (display));
1785
e_mail_display_get_selection_plain_text (EMailDisplay *display,
1789
WebKitWebFrame *frame;
1790
const gchar *frame_name;
1795
g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
1797
web_view = E_WEB_VIEW (display);
1798
frame = webkit_web_view_get_focused_frame (WEBKIT_WEB_VIEW (web_view));
1799
frame_name = webkit_web_frame_get_name (frame);
1801
type = e_web_view_frame_exec_script (web_view, frame_name, "window.getSelection().toString()", &value);
1802
g_return_val_if_fail (type == G_TYPE_STRING, NULL);
1804
str = g_value_get_string (&value);
1807
*len = strlen (str);
1809
return g_strdup (str);
1813
e_mail_display_load_images (EMailDisplay *display)
1815
g_return_if_fail (E_IS_MAIL_DISPLAY (display));
1817
display->priv->force_image_load = TRUE;
1818
e_web_view_reload (E_WEB_VIEW (display));
1822
e_mail_display_set_force_load_images (EMailDisplay *display,
1823
gboolean force_load_images)
1825
g_return_if_fail (E_IS_MAIL_DISPLAY (display));
1827
display->priv->force_image_load = force_load_images;