2 * Claws Mail -- A GTK based, lightweight, and fast e-mail client
4 * Copyright(C) 1999-2023 the Claws Mail Team
5 * This file Copyright (C) 2009-2014 Salvatore De Paolis
6 * <iwkse@claws-mail.org> and the Claws Mail Team
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "claws-features.h"
28 #include "stock_pixmap.h"
30 #include <fancy_viewer.h>
31 #include <fancy_prefs.h>
32 #include <alertpanel.h>
33 #include <file-utils.h>
38 static void load_changed_cb(WebKitWebView
*view
,
39 WebKitLoadEvent event
,
41 static void mouse_target_changed_cb (WebKitWebView
*view
,
42 WebKitHitTestResult
*result
,
48 load_progress_cb(WebKitWebView
*view
, GParamSpec
*param
, FancyViewer
*viewer
);
50 static MimeViewerFactory fancy_viewer_factory
;
54 fancy_text_search(MimeViewer *_viewer, gboolean backward, const gchar *str,
59 viewer_menu_handler(GtkWidget
*menuitem
, FancyViewer
*viewer
);
61 static gint
keypress_events_cb (GtkWidget
*widget
, GdkEventKey
*event
,
63 static void zoom_in_cb(GtkWidget
*widget
, GdkEvent
*ev
, FancyViewer
*viewer
);
64 static void zoom_out_cb(GtkWidget
*widget
, GdkEvent
*ev
, FancyViewer
*viewer
);
65 static gboolean
fancy_prefs_cb(GtkWidget
*widget
, GdkEventButton
*ev
, FancyViewer
*viewer
);
66 static void zoom_100_cb(GtkWidget
*widget
, GdkEvent
*ev
, FancyViewer
*viewer
);
67 static void open_in_browser_cb(GtkWidget
*widget
, FancyViewer
*viewer
);
68 static void fancy_create_popup_prefs_menu(FancyViewer
*viewer
);
69 static void fancy_show_notice(FancyViewer
*viewer
, const gchar
*message
);
70 static size_t download_file_curl_write_cb(void *buffer
, size_t size
,
71 size_t nmemb
, void *data
);
72 static void *download_file_curl (void *data
);
73 static void download_file_cb(GtkWidget
*widget
, FancyViewer
*viewer
);
74 static gboolean
fancy_set_contents(FancyViewer
*viewer
, gboolean use_defaults
);
77 static GtkWidget
*fancy_get_widget(MimeViewer
*_viewer
)
79 FancyViewer
*viewer
= (FancyViewer
*) _viewer
;
80 debug_print("fancy_get_widget: %p\n", viewer
->vbox
);
82 return GTK_WIDGET(viewer
->vbox
);
85 static void fancy_apply_prefs(FancyViewer
*viewer
)
87 g_object_set(viewer
->settings
,
88 "auto-load-images", viewer
->override_prefs_images
,
89 "enable-javascript", viewer
->override_prefs_scripts
,
90 "enable-plugins", viewer
->override_prefs_plugins
,
91 "enable-java", viewer
->override_prefs_java
,
93 "default-font-family", "Arial",
94 "cursive-font-family", "Comic Sans MS",
95 "fantasy-font-family", "Comic Sans MS",
96 "monospace-font-family", "Courier New",
97 "sans-serif-font-family", "Arial",
98 "serif-font-family", "Times New Roman",
101 if (fancy_prefs
.stylesheet
== NULL
|| strlen(fancy_prefs
.stylesheet
) == 0) {
102 gchar
**msg_font_params
= g_strsplit(prefs_common_get_prefs()->textfont
, " ", 0);
103 guint params_len
= g_strv_length(msg_font_params
);
105 if (params_len
> 0) {
106 gint msg_font_size
= g_ascii_strtoll(msg_font_params
[params_len
- 1], NULL
, 10);
107 g_object_set(viewer
->settings
, "default-font-size",
108 webkit_settings_font_size_to_pixels(msg_font_size
), NULL
);
110 g_strfreev(msg_font_params
);
112 webkit_web_view_set_settings(viewer
->view
, viewer
->settings
);
113 webkit_web_context_set_cache_model(webkit_web_context_get_default(), WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER
);
114 webkit_web_view_send_message_to_page(viewer
->view
,
115 webkit_user_message_new("LoadRemoteContent",
116 g_variant_new_boolean(viewer
->override_prefs_remote_content
)),
121 if (viewer
->override_stylesheet
) {
122 /* copied from vimb */
125 if (g_file_get_contents(viewer
->override_stylesheet
, &stylesheet
, NULL
, NULL
)) {
126 WebKitUserContentManager
*ucm
;
127 WebKitUserStyleSheet
*style
;
129 ucm
= webkit_web_view_get_user_content_manager(viewer
->view
);
130 style
= webkit_user_style_sheet_new(
131 stylesheet
, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES
,
132 WEBKIT_USER_STYLE_LEVEL_USER
, NULL
, NULL
);
134 webkit_user_content_manager_remove_all_style_sheets(ucm
);
135 webkit_user_content_manager_add_style_sheet(ucm
, style
);
136 webkit_user_style_sheet_unref(style
);
139 debug_print("Could not read style file: %s\n", viewer
->override_stylesheet
);
144 static void fancy_auto_load_images_activated(GtkCheckMenuItem
*item
, FancyViewer
*viewer
) {
145 viewer
->override_prefs_images
= gtk_check_menu_item_get_active(item
);
146 fancy_apply_prefs(viewer
);
147 fancy_set_contents(viewer
, FALSE
);
150 static void fancy_enable_remote_content_activated(GtkCheckMenuItem
*item
, FancyViewer
*viewer
) {
151 viewer
->override_prefs_remote_content
= gtk_check_menu_item_get_active(item
);
152 fancy_apply_prefs(viewer
);
153 fancy_set_contents(viewer
, FALSE
);
156 static void fancy_enable_scripts_activated(GtkCheckMenuItem
*item
, FancyViewer
*viewer
) {
157 viewer
->override_prefs_scripts
= gtk_check_menu_item_get_active(item
);
158 fancy_apply_prefs(viewer
);
159 fancy_set_contents(viewer
, FALSE
);
162 static void fancy_enable_plugins_activated(GtkCheckMenuItem
*item
, FancyViewer
*viewer
) {
163 viewer
->override_prefs_plugins
= gtk_check_menu_item_get_active(item
);
164 fancy_apply_prefs(viewer
);
165 fancy_set_contents(viewer
, FALSE
);
168 static void fancy_enable_java_activated(GtkCheckMenuItem
*item
, FancyViewer
*viewer
) {
169 viewer
->override_prefs_java
= gtk_check_menu_item_get_active(item
);
170 fancy_apply_prefs(viewer
);
171 fancy_set_contents(viewer
, FALSE
);
174 static void fancy_open_external_activated(GtkCheckMenuItem
*item
, FancyViewer
*viewer
) {
175 viewer
->override_prefs_external
= gtk_check_menu_item_get_active(item
);
176 fancy_apply_prefs(viewer
);
179 static void fancy_set_defaults(FancyViewer
*viewer
)
181 viewer
->override_prefs_remote_content
= fancy_prefs
.enable_remote_content
;
182 viewer
->override_prefs_external
= fancy_prefs
.open_external
;
183 viewer
->override_prefs_images
= fancy_prefs
.enable_images
;
184 viewer
->override_prefs_scripts
= fancy_prefs
.enable_scripts
;
185 viewer
->override_prefs_plugins
= fancy_prefs
.enable_plugins
;
186 viewer
->override_prefs_java
= fancy_prefs
.enable_java
;
191 /* Replace backslashes with forward slashes, since we'll be
192 * using this string in an URI. */
193 gchar
*tmp2
= g_strdup(fancy_prefs
.stylesheet
);
194 subst_char(tmp2
, '\\', '/');
196 /* Escape string for use in an URI, keeping dir separators
197 * and colon for Windows drive name ("C:") intact. */
198 tmp
= g_uri_escape_string(tmp2
, "/:", TRUE
);
201 /* Escape string for use in an URI, keeping dir separators
203 tmp
= g_uri_escape_string(fancy_prefs
.stylesheet
, "/", TRUE
);
205 viewer
->override_stylesheet
= g_strdup(tmp
);
207 debug_print("Using '%s' as stylesheet\n",
208 viewer
->override_stylesheet
);
210 g_signal_handlers_block_by_func(G_OBJECT(viewer
->enable_images
),
211 fancy_auto_load_images_activated
, viewer
);
212 g_signal_handlers_block_by_func(G_OBJECT(viewer
->enable_remote_content
),
213 fancy_enable_remote_content_activated
, viewer
);
214 g_signal_handlers_block_by_func(G_OBJECT(viewer
->enable_scripts
),
215 fancy_enable_scripts_activated
, viewer
);
216 g_signal_handlers_block_by_func(G_OBJECT(viewer
->enable_plugins
),
217 fancy_enable_plugins_activated
, viewer
);
218 g_signal_handlers_block_by_func(G_OBJECT(viewer
->enable_java
),
219 fancy_enable_java_activated
, viewer
);
220 g_signal_handlers_block_by_func(G_OBJECT(viewer
->open_external
),
221 fancy_open_external_activated
, viewer
);
223 gtk_check_menu_item_set_active(
224 GTK_CHECK_MENU_ITEM(viewer
->enable_images
),
225 viewer
->override_prefs_images
);
226 gtk_check_menu_item_set_active(
227 GTK_CHECK_MENU_ITEM(viewer
->enable_scripts
),
228 viewer
->override_prefs_scripts
);
229 gtk_check_menu_item_set_active(
230 GTK_CHECK_MENU_ITEM(viewer
->enable_plugins
),
231 viewer
->override_prefs_plugins
);
232 gtk_check_menu_item_set_active(
233 GTK_CHECK_MENU_ITEM(viewer
->enable_java
),
234 viewer
->override_prefs_java
);
235 gtk_check_menu_item_set_active(
236 GTK_CHECK_MENU_ITEM(viewer
->enable_remote_content
),
237 viewer
->override_prefs_remote_content
);
238 gtk_check_menu_item_set_active(
239 GTK_CHECK_MENU_ITEM(viewer
->open_external
),
240 viewer
->override_prefs_external
);
242 g_signal_handlers_unblock_by_func(G_OBJECT(viewer
->enable_images
),
243 fancy_auto_load_images_activated
, viewer
);
244 g_signal_handlers_unblock_by_func(G_OBJECT(viewer
->enable_remote_content
),
245 fancy_enable_remote_content_activated
, viewer
);
246 g_signal_handlers_unblock_by_func(G_OBJECT(viewer
->enable_scripts
),
247 fancy_enable_scripts_activated
, viewer
);
248 g_signal_handlers_unblock_by_func(G_OBJECT(viewer
->enable_plugins
),
249 fancy_enable_plugins_activated
, viewer
);
250 g_signal_handlers_unblock_by_func(G_OBJECT(viewer
->enable_java
),
251 fancy_enable_java_activated
, viewer
);
252 g_signal_handlers_unblock_by_func(G_OBJECT(viewer
->open_external
),
253 fancy_open_external_activated
, viewer
);
255 fancy_apply_prefs(viewer
);
258 static gboolean
fancy_set_contents(FancyViewer
*viewer
, gboolean use_defaults
)
260 MessageView
*messageview
= ((MimeViewer
*)viewer
)->mimeview
261 ? ((MimeViewer
*)viewer
)->mimeview
->messageview
263 MimeInfo
*partinfo
= viewer
->to_load
;
266 messageview
->updating
= TRUE
;
267 NoticeView
*noticeview
= messageview
->noticeview
;
268 noticeview_hide(noticeview
);
271 if (viewer
->filename
!= NULL
) {
272 g_unlink(viewer
->filename
);
273 g_free(viewer
->filename
);
274 viewer
->filename
= NULL
;
278 viewer
->filename
= procmime_get_tmp_file_name(partinfo
);
279 debug_print("filename: %s\n", viewer
->filename
);
280 if (!viewer
->filename
) {
283 if (procmime_get_part(viewer
->filename
, partinfo
) < 0) {
284 g_free(viewer
->filename
);
285 viewer
->filename
= NULL
;
288 const gchar
*charset
= NULL
;
289 gchar
*contents
= NULL
;
290 GBytes
*content_bytes
;
292 zoom_level
= (double) fancy_prefs
.zoom_level
/ 100;
294 if (messageview
&& messageview
->forced_charset
)
295 charset
= ((MimeViewer
*)viewer
)->mimeview
->messageview
->forced_charset
;
297 charset
= procmime_mimeinfo_get_parameter(partinfo
, "charset");
299 charset
= conv_get_locale_charset_str();
300 debug_print("using %s charset\n", charset
);
301 g_object_set(viewer
->settings
, "default-charset", charset
, NULL
);
304 debug_print("zoom_level: %f\n", zoom_level
);
306 webkit_web_view_set_zoom_level(viewer
->view
, zoom_level
);
308 fancy_set_defaults(viewer
);
311 contents
= file_read_to_str_no_recode(viewer
->filename
);
312 content_bytes
= g_bytes_new(contents
, strlen(contents
));
313 webkit_web_view_load_bytes(viewer
->view
,
319 g_bytes_unref(content_bytes
);
324 static gboolean
fancy_show_mimepart_real(MimeViewer
*_viewer
)
326 return fancy_set_contents((FancyViewer
*)_viewer
, TRUE
);
329 static void fancy_show_notice(FancyViewer
*viewer
, const gchar
*message
)
331 gtk_label_set_text(GTK_LABEL(viewer
->l_link
), message
);
334 static gboolean
fancy_show_mimepart_prepare(MimeViewer
*_viewer
)
336 FancyViewer
*viewer
= (FancyViewer
*) _viewer
;
338 g_timeout_add(5, (GSourceFunc
)fancy_show_mimepart_real
, viewer
);
342 static void fancy_show_mimepart(MimeViewer
*_viewer
, const gchar
*infile
,
345 FancyViewer
*viewer
= (FancyViewer
*) _viewer
;
346 viewer
->to_load
= partinfo
;
347 viewer
->loading
= TRUE
;
348 g_timeout_add(5, (GSourceFunc
)fancy_show_mimepart_prepare
, viewer
);
351 static void fancy_print_fail_cb(WebKitPrintOperation
*print_operation
,
353 gpointer user_data
) {
354 /* avoid warning for unused variable
355 FancyViewer *viewer = (FancyViewer *) user_data;
358 debug_print("Error printing message: %s\n",
359 error
? error
->message
: "no details");
362 static void fancy_print(MimeViewer
*_viewer
)
364 FancyViewer
*viewer
= (FancyViewer
*) _viewer
;
365 WebKitPrintOperationResponse res
;
366 WebKitPrintOperation
*printoperation
;
367 GtkPrintSettings
*printsettings
;
368 GtkPageSetup
*pagesetup
;
370 gtk_widget_realize(GTK_WIDGET(viewer
->view
));
372 while (viewer
->loading
)
375 printoperation
= webkit_print_operation_new(viewer
->view
);
376 g_signal_connect(G_OBJECT(printoperation
), "failed",
377 G_CALLBACK(fancy_print_fail_cb
), viewer
);
379 printsettings
= webkit_print_operation_get_print_settings(printoperation
);
380 if (!printsettings
) {
381 printsettings
= printing_get_settings();
382 webkit_print_operation_set_print_settings(printoperation
, printsettings
);
384 pagesetup
= webkit_print_operation_get_page_setup(printoperation
);
386 pagesetup
= printing_get_page_setup();
387 webkit_print_operation_set_page_setup(printoperation
, pagesetup
);
390 MainWindow
*mainwin
= mainwindow_get_mainwindow();
391 res
= webkit_print_operation_run_dialog(
393 mainwin
? GTK_WINDOW(mainwin
->window
):NULL
);
395 if (res
== WEBKIT_PRINT_OPERATION_RESPONSE_PRINT
) {
396 // store settings for next printing session
397 printing_store_settings(
398 webkit_print_operation_get_print_settings(printoperation
));
401 g_object_unref(printoperation
);
404 /*static gchar *fancy_get_selection (MimeViewer *_viewer)
406 debug_print("fancy_get_selection\n");
407 FancyViewer *viewer = (FancyViewer *) _viewer;
408 viewer->doc = webkit_web_page_get_dom_document(WEBKIT_WEB_VIEW(viewer->view));
409 viewer->window = webkit_dom_document_get_default_view (viewer->doc);
410 viewer->selection = webkit_dom_dom_window_get_selection (viewer->window);
411 if (viewer->selection == NULL)
413 viewer->range = webkit_dom_dom_selection_get_range_at(viewer->selection, 0, NULL);
414 if (viewer->range == NULL)
416 gchar *sel = webkit_dom_range_get_text (viewer->range);
417 if (!viewer->view || strlen(sel) == 0) {
424 static void fancy_clear_viewer(MimeViewer
*_viewer
)
426 FancyViewer
*viewer
= (FancyViewer
*) _viewer
;
428 viewer
->cur_link
= NULL
;
429 fancy_set_defaults(viewer
);
431 webkit_web_view_load_uri(viewer
->view
, "about:blank");
433 debug_print("fancy_clear_viewer\n");
434 fancy_prefs
.zoom_level
= (int) webkit_web_view_get_zoom_level(viewer
->view
) * 100;
435 viewer
->to_load
= NULL
;
436 vadj
= gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(viewer
->scrollwin
));
437 gtk_adjustment_set_value(vadj
, 0.0);
438 g_signal_emit_by_name(G_OBJECT(vadj
), "value-changed", 0);
441 static void fancy_destroy_viewer(MimeViewer
*_viewer
)
443 FancyViewer
*viewer
= (FancyViewer
*) _viewer
;
444 fancy_prefs
.zoom_level
= (int) webkit_web_view_get_zoom_level(viewer
->view
) * 100;
445 debug_print("fancy_destroy_viewer\n");
446 g_free(viewer
->filename
);
451 navigation_policy_cb (WebKitWebView
*web_view
,
452 WebKitPolicyDecision
*policy_decision
,
453 WebKitPolicyDecisionType policy_decision_type
,
456 if (policy_decision_type
== WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION
|| policy_decision_type
== WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION
) {
457 WebKitNavigationPolicyDecision
*navigation_decision
= WEBKIT_NAVIGATION_POLICY_DECISION(policy_decision
);
458 WebKitNavigationAction
*navigation_action
= webkit_navigation_policy_decision_get_navigation_action(navigation_decision
);
459 viewer
->cur_link
= webkit_uri_request_get_uri(webkit_navigation_action_get_request(navigation_action
));
461 debug_print("navigation requested to %s\n", viewer
->cur_link
);
463 if (viewer
->cur_link
) {
464 if (!strncmp(viewer
->cur_link
, "mailto:", 7)) {
465 debug_print("Opening message window\n");
466 compose_new(NULL
, viewer
->cur_link
+ 7, NULL
);
467 webkit_policy_decision_ignore(policy_decision
);
468 } else if (!strncmp(viewer
->cur_link
, "file://", 7) || !strcmp(viewer
->cur_link
, "about:blank")) {
469 debug_print("local navigation request ACCEPTED\n");
470 webkit_policy_decision_use(policy_decision
);
471 } else if (viewer
->override_prefs_external
&& webkit_navigation_action_get_navigation_type(navigation_action
) == WEBKIT_NAVIGATION_TYPE_LINK_CLICKED
) {
472 debug_print("remote navigation request OPENED\n");
473 open_uri(viewer
->cur_link
, prefs_common_get_uri_cmd());
474 webkit_policy_decision_ignore(policy_decision
);
475 } else if (viewer
->override_prefs_remote_content
) {
476 debug_print("remote navigation request ACCEPTED\n");
477 webkit_policy_decision_use(policy_decision
);
479 debug_print("remote navigation request IGNORED\n");
480 fancy_show_notice(viewer
, _("Remote content loading is disabled."));
481 webkit_policy_decision_ignore(policy_decision
);
490 static void load_content_cb(WebKitURISchemeRequest
*request
, gpointer viewer
)
493 MimeInfo
*partinfo
= ((FancyViewer
*)viewer
)->to_load
;
495 GInputStream
*stream
;
498 image
= g_strconcat("<", webkit_uri_scheme_request_get_path(request
), ">", NULL
);
499 while ((partinfo
= procmime_mimeinfo_next(partinfo
)) != NULL
) {
500 if (partinfo
->id
&& !g_ascii_strcasecmp(image
, partinfo
->id
)) {
501 mimetype
= procmime_get_content_type_str(partinfo
->type
, partinfo
->subtype
);
502 stream
= procmime_get_part_as_inputstream(partinfo
);
503 webkit_uri_scheme_request_finish(request
, stream
, partinfo
->length
,
505 g_object_unref(stream
);
512 error
= g_error_new(G_FILE_ERROR
, 0, _("Couldn't save the part of multipart message: %s"), image
);
513 webkit_uri_scheme_request_finish_error(request
, error
);
518 static void resource_request_starting_cb(WebKitWebView
*view
,
519 WebKitWebResource
*resource
,
520 WebKitURIRequest
*request
,
521 WebKitURIResponse
*response
,
524 const gchar
*uri
= webkit_uri_request_get_uri(request
);
528 MimeInfo
*partinfo
= viewer
->to_load
;
530 filename
= viewer
->filename
;
531 if ((!g_ascii_strncasecmp(uri
, "cid:", 4)) || (!g_ascii_strncasecmp(uri
, "mid:", 4))) {
532 image
= g_strconcat("<", uri
+ 4, ">", NULL
);
533 while ((partinfo
= procmime_mimeinfo_next(partinfo
)) != NULL
) {
534 if (partinfo
->id
&& !g_ascii_strcasecmp(image
, partinfo
->id
)) {
535 filename
= procmime_get_tmp_file_name(partinfo
);
540 if ((err
= procmime_get_part(filename
, partinfo
)) < 0)
541 alertpanel_error(_("Couldn't save the part of multipart message: %s"),
543 gchar
*file_uri
= g_filename_to_uri(filename
, NULL
, NULL
);
544 webkit_uri_request_set_uri(request
, file_uri
);
553 /* refresh URI that may have changed */
554 uri
= webkit_uri_request_get_uri(request
);
555 if (!viewer
->override_prefs_remote_content
556 && strncmp(uri
, "file://", 7) && strncmp(uri
, "data:", 5)) {
557 debug_print("Preventing load of %s\n", uri
);
558 webkit_uri_request_set_uri(request
, "about:blank");
561 debug_print("Starting request of %"G_GSIZE_FORMAT
" %s\n", strlen(uri
), uri
);
564 /*static gboolean fancy_text_search(MimeViewer *_viewer, gboolean backward,
565 const gchar *str, gboolean case_sens)
567 return webkit_web_view_search_text(((FancyViewer*)_viewer)->view, str,
568 case_sens, !backward, TRUE);
571 static gboolean
fancy_prefs_cb(GtkWidget
*widget
, GdkEventButton
*ev
, FancyViewer
*viewer
)
573 if ((ev
->button
== 1) && (ev
->type
== GDK_BUTTON_PRESS
)) {
574 gtk_menu_popup_at_widget(GTK_MENU(viewer
->fancy_prefs_menu
),
575 widget
, GDK_GRAVITY_CENTER
, GDK_GRAVITY_SOUTH_WEST
, NULL
);
581 static void fancy_create_popup_prefs_menu(FancyViewer
*viewer
) {
582 GtkWidget
*enable_images
;
583 GtkWidget
*enable_remote_content
;
584 GtkWidget
*enable_scripts
;
585 GtkWidget
*enable_plugins
;
586 GtkWidget
*enable_java
;
587 GtkWidget
*open_external
;
589 enable_images
= gtk_check_menu_item_new_with_label(_("Load images"));
591 enable_remote_content
= gtk_check_menu_item_new_with_label(_("Enable remote content"));
593 enable_scripts
= gtk_check_menu_item_new_with_label(_("Enable Javascript"));
595 enable_plugins
= gtk_check_menu_item_new_with_label(_("Enable Plugins"));
597 enable_java
= gtk_check_menu_item_new_with_label(_("Enable Java"));
599 open_external
= gtk_check_menu_item_new_with_label(_("Open links with external browser"));
601 gtk_menu_shell_append(GTK_MENU_SHELL(viewer
->fancy_prefs_menu
), enable_images
);
602 gtk_menu_shell_append(GTK_MENU_SHELL(viewer
->fancy_prefs_menu
), enable_remote_content
);
603 gtk_menu_shell_append(GTK_MENU_SHELL(viewer
->fancy_prefs_menu
), enable_scripts
);
604 gtk_menu_shell_append(GTK_MENU_SHELL(viewer
->fancy_prefs_menu
), enable_plugins
);
605 gtk_menu_shell_append(GTK_MENU_SHELL(viewer
->fancy_prefs_menu
), enable_java
);
606 gtk_menu_shell_append(GTK_MENU_SHELL(viewer
->fancy_prefs_menu
), open_external
);
608 gtk_menu_attach_to_widget(GTK_MENU(viewer
->fancy_prefs_menu
), viewer
->ev_fancy_prefs
, NULL
);
609 gtk_widget_show_all(viewer
->fancy_prefs_menu
);
611 viewer
->enable_images
= enable_images
;
612 viewer
->enable_scripts
= enable_scripts
;
613 viewer
->enable_plugins
= enable_plugins
;
614 viewer
->enable_java
= enable_java
;
615 viewer
->enable_remote_content
= enable_remote_content
;
616 viewer
->open_external
= open_external
;
618 /* Set sensitivity according to preferences and overrides */
620 g_signal_connect(G_OBJECT(enable_images
), "toggled",
621 G_CALLBACK (fancy_auto_load_images_activated
), viewer
);
622 g_signal_connect(G_OBJECT(enable_remote_content
), "toggled",
623 G_CALLBACK (fancy_enable_remote_content_activated
), viewer
);
624 g_signal_connect(G_OBJECT(enable_scripts
), "toggled",
625 G_CALLBACK (fancy_enable_scripts_activated
), viewer
);
626 g_signal_connect(G_OBJECT(enable_plugins
), "toggled",
627 G_CALLBACK (fancy_enable_plugins_activated
), viewer
);
628 g_signal_connect(G_OBJECT(enable_java
), "toggled",
629 G_CALLBACK (fancy_enable_java_activated
), viewer
);
630 g_signal_connect(G_OBJECT(open_external
), "toggled",
631 G_CALLBACK (fancy_open_external_activated
), viewer
);
633 fancy_apply_prefs(viewer
);
636 static gboolean
fancy_scroll_page(MimeViewer
*_viewer
, gboolean up
)
638 FancyViewer
*viewer
= (FancyViewer
*)_viewer
;
639 GtkAdjustment
*vadj
= gtk_scrolled_window_get_vadjustment(
640 GTK_SCROLLED_WINDOW(viewer
->scrollwin
));
642 if (viewer
->view
== NULL
)
645 return gtkutils_scroll_page(GTK_WIDGET(viewer
->view
), vadj
, up
);
648 static void fancy_scroll_one_line(MimeViewer
*_viewer
, gboolean up
)
650 FancyViewer
*viewer
= (FancyViewer
*)_viewer
;
651 GtkAdjustment
*vadj
= gtk_scrolled_window_get_vadjustment(
652 GTK_SCROLLED_WINDOW(viewer
->scrollwin
));
654 if (viewer
->view
== NULL
)
657 gtkutils_scroll_one_line(GTK_WIDGET(viewer
->view
), vadj
, up
);
660 static void load_changed_cb(WebKitWebView
*view
,
661 WebKitLoadEvent event
,
664 FancyViewer
*viewer
= (FancyViewer
*)user_data
;
667 case WEBKIT_LOAD_STARTED
:
668 gtk_widget_show(viewer
->progress
);
669 gtk_widget_show(viewer
->ev_stop_loading
);
672 case WEBKIT_LOAD_FINISHED
:
673 viewer
->loading
= FALSE
;
674 gtk_widget_hide(viewer
->progress
);
675 gtk_widget_hide(viewer
->ev_stop_loading
);
676 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(viewer
->progress
),
678 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(viewer
->progress
), "");
685 static void mouse_target_changed_cb(WebKitWebView
*view
,
686 WebKitHitTestResult
*result
,
690 FancyViewer
*viewer
= (FancyViewer
*)user_data
;
692 cm_return_if_fail(result
!= NULL
);
694 /* Display the link in the bottom statusbar, or erase it
695 * if the cursor left the link. */
696 if (!webkit_hit_test_result_context_is_link(result
)) {
697 gtk_label_set_text(GTK_LABEL(viewer
->l_link
), NULL
);
701 gtk_label_set_text(GTK_LABEL(viewer
->l_link
),
702 webkit_hit_test_result_get_link_uri(result
));
705 static void load_progress_cb(WebKitWebView
*view
, GParamSpec
*param
,
708 // WebKitLoadEvent status = webkit_web_view_get_load_status(viewer->view);
709 // gdouble pbar = webkit_web_view_get_progress(viewer->view);
710 // const gchar *uri = webkit_web_view_get_uri(viewer->view);
712 gdouble progress
= webkit_web_view_get_estimated_load_progress(view
);
713 gchar
*label
= g_strdup_printf("%d%% Loading...", (gint
)(progress
* 100));
714 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(viewer
->progress
), progress
);
715 gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(viewer
->progress
), TRUE
);
716 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(viewer
->progress
),
717 (const gchar
*)label
);
721 case WEBKIT_LOAD_COMMITTED:
723 case WEBKIT_LOAD_FINISHED:
724 debug_print("Load finished: %s\n", uri);
729 static void stop_loading_cb(GtkWidget
*widget
, GdkEvent
*ev
,
732 webkit_web_view_stop_loading (viewer
->view
);
733 gtk_widget_hide(viewer
->progress
);
734 gtk_widget_hide(viewer
->ev_stop_loading
);
737 static void search_the_web_cb(GtkWidget *widget, FancyViewer *viewer)
739 debug_print("Clicked on Search on Web\n");
740 if (webkit_web_view_has_selection(viewer->view)) {
742 viewer->doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(viewer->view));
743 viewer->window = webkit_dom_document_get_default_view (viewer->doc);
744 viewer->selection = webkit_dom_dom_window_get_selection (viewer->window);
745 viewer->range = webkit_dom_dom_selection_get_range_at(viewer->selection, 0, NULL);
746 gchar *tmp = webkit_dom_range_get_text (viewer->range);
747 search = g_strconcat(GOOGLE_SEARCH, tmp, NULL);
749 webkit_web_view_load_uri(viewer->view, search);
755 static void open_in_browser_cb(GtkWidget
*widget
, FancyViewer
*viewer
)
757 debug_print("open outer: %s\n", viewer
->cur_link
);
759 open_uri(viewer
->cur_link
, prefs_common_get_uri_cmd());
762 static size_t download_file_curl_write_cb(void *buffer
, size_t size
,
763 size_t nmemb
, void *data
)
765 FancyViewer
*viewer
= (FancyViewer
*)data
;
766 if (!viewer
->stream
) {
767 viewer
->stream
= claws_fopen(viewer
->curlfile
, "wb");
771 return claws_fwrite(buffer
, size
, nmemb
, viewer
->stream
);
773 static void *download_file_curl (void *data
)
777 FancyViewer
*viewer
= (FancyViewer
*)data
;
779 curl_global_init(CURL_GLOBAL_DEFAULT
);
780 curl
= curl_easy_init();
783 curl_easy_setopt(curl
, CURLOPT_URL
, viewer
->cur_link
);
784 curl_easy_setopt(curl
, CURLOPT_WRITEFUNCTION
, download_file_curl_write_cb
);
785 curl_easy_setopt(curl
, CURLOPT_WRITEDATA
, viewer
);
786 curl_easy_setopt(curl
, CURLOPT_VERBOSE
, 1L);
787 curl_easy_setopt(curl
, CURLOPT_FOLLOWLOCATION
, 1L);
789 curl_easy_setopt(curl
, CURLOPT_CAINFO
, claws_ssl_get_cert_file());
791 res
= curl_easy_perform(curl
);
792 curl_easy_cleanup(curl
);
795 alertpanel_error(_("An error occurred: %d\n"), res
);
797 claws_safe_fclose(viewer
->stream
);
798 curl_global_cleanup();
806 static void download_file_cb(GtkWidget
*widget
, FancyViewer
*viewer
)
812 const gchar
*link
= viewer
->cur_link
;
813 gchar
*filename
= g_utf8_strchr(link
, -1, g_utf8_get_char("/"));
814 filename
= g_strconcat(get_home_dir(), filename
, NULL
);
815 gchar
*fname
= filesel_select_file_save(_("Save as"), filename
);
821 if (viewer
->curlfile
) viewer
->curlfile
= NULL
;
822 if (viewer
->stream
) viewer
->stream
= NULL
;
823 viewer
->curlfile
= (const gchar
*)g_strdup(fname
);
827 if (!viewer
->curlfile
) return;
830 result
= pthread_create(&curljob
, NULL
, download_file_curl
, (void *)viewer
);
832 alertpanel_error("ERROR; return code from pthread_create() is %d\n", result
);
834 download_file_curl((void *)viewer
);
838 static void save_image_cb(GtkWidget
*widget
, FancyViewer
*viewer
)
840 debug_print("Not Yet Implemented\n");
843 static void open_image_cb(GtkWidget
*widget
, FancyViewer
*viewer
)
845 debug_print("Not Yet Implemented\n");
848 static void copy_image_cb(GtkWidget
*widget
, FancyViewer
*viewer
)
850 debug_print("Not Yet Implemented\n");
852 static void import_feed_cb(GtkWidget
*widget
, FancyViewer
*viewer
)
854 if (!folder_subscribe(viewer
->cur_link
))
855 alertpanel_error(_("%s is a malformed or not supported feed"), viewer
->cur_link
);
857 static void viewer_menu_handler(GtkWidget
*menuitem
, FancyViewer
*viewer
)
859 const gchar
*g_name
= gtk_widget_get_name(GTK_WIDGET(menuitem
));
860 if (!g_ascii_strcasecmp(g_name
, "GtkMenuItem")) {
862 GtkWidget
*menul
= gtk_bin_get_child(GTK_BIN(menuitem
));
864 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul)),
866 gtk_label_set_text(GTK_LABEL(menul), _("Search the Web"));
867 viewer->cur_link = NULL;
868 GtkMenuItem *m_search = GTK_MENU_ITEM(menuitem);
869 g_signal_connect(G_OBJECT(m_search), "activate",
870 G_CALLBACK(search_the_web_cb),
871 (gpointer *) viewer);
874 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul
)),
877 gtk_label_set_text(GTK_LABEL(menul
), _("Open in Viewer"));
879 GtkMenuItem
*m_new
= GTK_MENU_ITEM(menuitem
);
880 gtk_widget_set_sensitive(GTK_WIDGET(m_new
), viewer
->override_prefs_remote_content
);
883 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul
)),
884 "Open Link in New Window" )) {
886 gtk_label_set_text(GTK_LABEL(menul
), _("Open in Browser"));
888 GtkMenuItem
*m_new
= GTK_MENU_ITEM(menuitem
);
889 g_signal_connect(G_OBJECT(m_new
), "activate",
890 G_CALLBACK(open_in_browser_cb
),
891 (gpointer
*) viewer
);
894 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul
)),
895 "Open Image in New Window" )) {
896 gtk_label_set_text(GTK_LABEL(menul
), _("Open Image"));
897 GtkMenuItem
*m_image
= GTK_MENU_ITEM(menuitem
);
898 g_signal_connect(G_OBJECT(m_image
), "activate",
899 G_CALLBACK(open_image_cb
),
900 (gpointer
*) viewer
);
903 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul
)),
904 "Copy Link Location" )) {
905 gtk_label_set_text(GTK_LABEL(menul
), _("Copy Link"));
908 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul
)),
909 "Download Linked File" )) {
910 gtk_label_set_text(GTK_LABEL(menul
), _("Download Link"));
912 GtkMenuItem
*m_dlink
= GTK_MENU_ITEM(menuitem
);
913 g_signal_connect(G_OBJECT(m_dlink
), "activate",
914 G_CALLBACK(download_file_cb
),
915 (gpointer
*) viewer
);
918 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul
)),
921 gtk_label_set_text(GTK_LABEL(menul
), _("Save Image As"));
923 GtkMenuItem
*m_simage
= GTK_MENU_ITEM(menuitem
);
924 g_signal_connect(G_OBJECT(m_simage
), "activate",
925 G_CALLBACK(save_image_cb
),
926 (gpointer
*) viewer
);
929 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul
)),
931 gtk_label_set_text(GTK_LABEL(menul
), _("Copy Image"));
932 GtkMenuItem
*m_cimage
= GTK_MENU_ITEM(menuitem
);
933 g_signal_connect(G_OBJECT(m_cimage
), "activate",
934 G_CALLBACK(copy_image_cb
),
935 (gpointer
*) viewer
);
941 static gboolean
context_menu_cb (WebKitWebView
*view
, WebKitContextMenu
*menu
,
942 GdkEvent
*event
, WebKitHitTestResult
*hit_test_result
,
945 FancyViewer
*viewer
= (FancyViewer
*)user_data
;
946 Plugin
*plugin
= plugin_get_loaded_by_name("RSSyl");
947 WebKitHitTestResultContext context
;
948 const gchar
*link_uri
= NULL
;
950 context
= webkit_hit_test_result_get_context(hit_test_result
);
952 link_uri
= webkit_hit_test_result_get_link_uri(hit_test_result
);
954 debug_print("context %d, link-uri '%s'\n", context
,
955 (link_uri
!= NULL
? link_uri
: "(null)"));
956 if (context
& WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK
&&
958 if (viewer
!= NULL
&& viewer
->cur_link
!= NULL
) {
959 /* g_object_get() already made a copy, no need to strdup() here */
960 viewer
->cur_link
= link_uri
;
964 gtk_container_foreach(GTK_CONTAINER(menu
),
965 (GtkCallback
)viewer_menu_handler
,
969 GtkWidget
*rssyl
= gtk_menu_item_new_with_label(_("Import feed"));
970 gtk_widget_show(GTK_WIDGET(rssyl
));
971 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), rssyl
);
972 g_signal_connect(G_OBJECT(rssyl
), "activate",
973 G_CALLBACK(import_feed_cb
),
974 (gpointer
*) viewer
);
980 static gint
keypress_events_cb (GtkWidget
*widget
, GdkEventKey
*event
,
983 if (event
->state
== CTRL_KEY
) {
984 switch (event
->keyval
) {
986 zoom_in_cb(viewer
->ev_zoom_in
, NULL
, viewer
);
989 zoom_100_cb(viewer
->ev_zoom_100
, NULL
, viewer
);
992 zoom_out_cb(viewer
->ev_zoom_out
, NULL
, viewer
);
999 /*static gboolean release_button_cb (WebKitWebView *view, GdkEvent *ev, FancyViewer *viewer)
1001 if (ev->button.button == 1 && viewer->cur_link && viewer->override_prefs_external) {
1003 WebKitHitTestResult *result;
1004 result = webkit_web_view_get_hit_test_result(view, (GdkEventButton *)ev);
1005 g_object_get(G_OBJECT(result),
1009 *//* If this button release is end of a drag or selection event
1010 * (button press happened on different coordinates), we do not
1011 * want to open the link. *//*
1012 if ((x != viewer->click_x || y != viewer->click_y))
1015 open_uri(viewer->cur_link, prefs_common_get_uri_cmd());
1021 static gboolean press_button_cb (WebKitWebView *view, GdkEvent *ev,
1022 FancyViewer *viewer)
1027 WebKitHitTestResult *result =
1028 webkit_web_view_get_hit_test_result(view, (GdkEventButton *)ev);
1030 g_object_get(G_OBJECT(result),
1032 "x", &viewer->click_x,
1033 "y", &viewer->click_y,
1037 if (type & WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION)
1040 if (viewer->cur_link) {
1041 g_free(viewer->cur_link);
1042 viewer->cur_link = NULL;
1045 debug_print("press on %s\n", link);
1046 viewer->cur_link = link;i*/ /* g_context returned a newly-allocated string
1049 viewer->doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(viewer->view));
1050 viewer->window = webkit_dom_document_get_default_view (viewer->doc);
1051 viewer->selection = webkit_dom_dom_window_get_selection (viewer->window);
1052 if (viewer->selection != NULL)
1053 webkit_dom_dom_selection_empty(viewer->selection);
1057 static void zoom_100_cb(GtkWidget
*widget
, GdkEvent
*ev
, FancyViewer
*viewer
)
1059 gtk_widget_grab_focus(widget
);
1060 webkit_web_view_set_zoom_level(viewer
->view
, 1);
1063 static void zoom_in_cb(GtkWidget
*widget
, GdkEvent
*ev
, FancyViewer
*viewer
)
1065 gtk_widget_grab_focus(widget
);
1066 fancy_prefs
.zoom_level
+= 10;
1068 zoom_level
= (double) fancy_prefs
.zoom_level
/ 100;
1069 webkit_web_view_set_zoom_level(viewer
->view
, zoom_level
);
1071 static void zoom_out_cb(GtkWidget
*widget
, GdkEvent
*ev
, FancyViewer
*viewer
)
1074 gtk_widget_grab_focus(widget
);
1075 fancy_prefs
.zoom_level
-= 10;
1076 zoom_level
= (double) fancy_prefs
.zoom_level
/ 100;
1077 if (fancy_prefs
.zoom_level
)
1078 webkit_web_view_set_zoom_level(viewer
->view
, zoom_level
);
1081 static void resource_load_failed_cb(WebKitWebView
*web_view
,
1082 WebKitWebResource
*web_resource
,
1084 FancyViewer
*viewer
)
1086 debug_print("Loading error: %s\n", error
->message
);
1089 static MimeViewer
*fancy_viewer_create(void)
1091 FancyViewer
*viewer
;
1094 debug_print("fancy_viewer_create\n");
1096 viewer
= g_new0(FancyViewer
, 1);
1097 viewer
->mimeviewer
.factory
= &fancy_viewer_factory
;
1098 viewer
->mimeviewer
.get_widget
= fancy_get_widget
;
1099 // viewer->mimeviewer.get_selection = fancy_get_selection;
1100 viewer
->mimeviewer
.show_mimepart
= fancy_show_mimepart
;
1101 viewer
->mimeviewer
.print
= fancy_print
;
1102 viewer
->mimeviewer
.clear_viewer
= fancy_clear_viewer
;
1103 viewer
->mimeviewer
.destroy_viewer
= fancy_destroy_viewer
;
1104 // viewer->mimeviewer.text_search = fancy_text_search;
1105 viewer
->mimeviewer
.scroll_page
= fancy_scroll_page
;
1106 viewer
->mimeviewer
.scroll_one_line
= fancy_scroll_one_line
;
1107 viewer
->view
= WEBKIT_WEB_VIEW(webkit_web_view_new());
1109 viewer
->settings
= webkit_settings_new();
1110 g_object_set(viewer
->settings
, "user-agent", "Fancy Viewer", NULL
);
1111 viewer
->scrollwin
= gtk_scrolled_window_new(NULL
, NULL
);
1112 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(viewer
->scrollwin
),
1113 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1114 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(viewer
->scrollwin
),
1116 gtk_container_add(GTK_CONTAINER(viewer
->scrollwin
),
1117 GTK_WIDGET(viewer
->view
));
1119 viewer
->vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 0);
1120 gtk_widget_set_name(GTK_WIDGET(viewer
->vbox
), "fancy_viewer");
1121 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
1122 viewer
->progress
= gtk_progress_bar_new();
1123 gtk_widget_set_size_request(GTK_WIDGET(viewer
->progress
), 120, -1);
1125 viewer
->zoom_100
= stock_pixmap_widget(STOCK_PIXMAP_ZOOM_FIT
);
1126 viewer
->zoom_in
= stock_pixmap_widget(STOCK_PIXMAP_ZOOM_IN
);
1127 viewer
->zoom_out
= stock_pixmap_widget(STOCK_PIXMAP_ZOOM_OUT
);
1128 viewer
->stop_loading
= stock_pixmap_widget(STOCK_PIXMAP_CANCEL
);
1129 /* Event Widgets for the Zoom Widgets */
1130 viewer
->ev_zoom_100
= gtk_event_box_new();
1131 viewer
->ev_zoom_in
= gtk_event_box_new();
1132 viewer
->ev_zoom_out
= gtk_event_box_new();
1133 viewer
->ev_stop_loading
= gtk_event_box_new();
1136 viewer
->l_link
= gtk_label_new("");
1137 gtk_label_set_ellipsize(GTK_LABEL(viewer
->l_link
), PANGO_ELLIPSIZE_END
);
1139 /* Preferences Widgets to override preferences on the fly */
1140 viewer
->fancy_prefs
= stock_pixmap_widget(STOCK_PIXMAP_PREFERENCES
);
1141 viewer
->ev_fancy_prefs
= gtk_event_box_new();
1143 /* Popup Menu for preferences */
1144 viewer
->fancy_prefs_menu
= gtk_menu_new();
1145 fancy_create_popup_prefs_menu(viewer
);
1147 gtk_event_box_set_visible_window(GTK_EVENT_BOX(viewer
->ev_zoom_100
), FALSE
);
1148 gtk_event_box_set_visible_window(GTK_EVENT_BOX(viewer
->ev_zoom_in
), FALSE
);
1149 gtk_event_box_set_visible_window(GTK_EVENT_BOX(viewer
->ev_zoom_out
), FALSE
);
1150 gtk_event_box_set_visible_window(GTK_EVENT_BOX(viewer
->ev_fancy_prefs
), FALSE
);
1151 gtk_event_box_set_visible_window(GTK_EVENT_BOX(viewer
->ev_stop_loading
), FALSE
);
1153 gtk_container_add(GTK_CONTAINER(viewer
->ev_zoom_100
), viewer
->zoom_100
);
1154 gtk_container_add(GTK_CONTAINER(viewer
->ev_zoom_in
), viewer
->zoom_in
);
1155 gtk_container_add(GTK_CONTAINER(viewer
->ev_zoom_out
), viewer
->zoom_out
);
1156 gtk_container_add(GTK_CONTAINER(viewer
->ev_fancy_prefs
), viewer
->fancy_prefs
);
1157 gtk_container_add(GTK_CONTAINER(viewer
->ev_stop_loading
), viewer
->stop_loading
);
1159 gtk_box_pack_start(GTK_BOX(hbox
), viewer
->ev_zoom_100
, FALSE
, FALSE
, 1);
1160 gtk_box_pack_start(GTK_BOX(hbox
), viewer
->ev_zoom_in
, FALSE
, FALSE
, 2);
1161 gtk_box_pack_start(GTK_BOX(hbox
), viewer
->ev_zoom_out
, FALSE
, FALSE
, 2);
1162 gtk_box_pack_start(GTK_BOX(hbox
), viewer
->ev_fancy_prefs
, FALSE
, FALSE
, 2);
1163 gtk_box_pack_start(GTK_BOX(hbox
), viewer
->l_link
, FALSE
, FALSE
, 8);
1164 gtk_box_pack_end(GTK_BOX(hbox
), viewer
->progress
, FALSE
, FALSE
, 0);
1165 gtk_box_pack_end(GTK_BOX(hbox
), viewer
->ev_stop_loading
, FALSE
, FALSE
, 0);
1167 gtk_box_pack_start(GTK_BOX(viewer
->vbox
), viewer
->scrollwin
, TRUE
, TRUE
,
1169 gtk_box_pack_start(GTK_BOX(viewer
->vbox
), hbox
, FALSE
, FALSE
, 0);
1171 gtk_widget_show(viewer
->ev_zoom_100
);
1172 gtk_widget_show(viewer
->ev_zoom_in
);
1173 gtk_widget_show(viewer
->ev_zoom_out
);
1174 gtk_widget_show(viewer
->ev_fancy_prefs
);
1176 gtk_widget_show(viewer
->scrollwin
);
1177 gtk_widget_show(viewer
->zoom_100
);
1178 gtk_widget_show(viewer
->zoom_in
);
1179 gtk_widget_show(viewer
->zoom_out
);
1180 gtk_widget_show(viewer
->fancy_prefs
);
1181 gtk_widget_show(viewer
->stop_loading
);
1183 gtk_widget_show(viewer
->l_link
);
1184 gtk_widget_show(viewer
->vbox
);
1185 gtk_widget_show(hbox
);
1186 gtk_widget_show(GTK_WIDGET(viewer
->view
));
1188 g_signal_connect(G_OBJECT(viewer
->view
), "load-changed",
1189 G_CALLBACK(load_changed_cb
), viewer
);
1190 g_signal_connect(G_OBJECT(viewer
->view
), "mouse-target-changed",
1191 G_CALLBACK(mouse_target_changed_cb
), viewer
);
1193 g_signal_connect(G_OBJECT(viewer
->view
), "notify::estimated-load-progress",
1194 G_CALLBACK(load_progress_cb
), viewer
);
1196 g_signal_connect(G_OBJECT(viewer
->view
), "decide-policy",
1197 G_CALLBACK(navigation_policy_cb
), viewer
);
1199 g_signal_connect(G_OBJECT(viewer
->view
), "resource-request-starting",
1200 G_CALLBACK(resource_request_starting_cb
), viewer
);
1201 g_signal_connect(G_OBJECT(viewer
->view
), "context-menu",
1202 G_CALLBACK(context_menu_cb
), viewer
);
1203 /* g_signal_connect(G_OBJECT(viewer->view), "button-press-event",
1204 G_CALLBACK(press_button_cb), viewer);
1205 g_signal_connect(G_OBJECT(viewer->view), "button-release-event",
1206 G_CALLBACK(release_button_cb), viewer);*/
1207 g_signal_connect(G_OBJECT(viewer
->ev_zoom_100
), "button-press-event",
1208 G_CALLBACK(zoom_100_cb
), (gpointer
*)viewer
);
1209 g_signal_connect(G_OBJECT(viewer
->ev_zoom_in
), "button-press-event",
1210 G_CALLBACK(zoom_in_cb
), (gpointer
*)viewer
);
1211 g_signal_connect(G_OBJECT(viewer
->ev_zoom_out
), "button-press-event",
1212 G_CALLBACK(zoom_out_cb
), (gpointer
*)viewer
);
1213 g_signal_connect(G_OBJECT(viewer
->ev_fancy_prefs
), "button-press-event",
1214 G_CALLBACK(fancy_prefs_cb
), (gpointer
*)viewer
);
1215 g_signal_connect(G_OBJECT(viewer
->ev_stop_loading
), "button-press-event",
1216 G_CALLBACK(stop_loading_cb
), viewer
);
1217 g_signal_connect(G_OBJECT(viewer
->view
), "key_press_event",
1218 G_CALLBACK(keypress_events_cb
), viewer
);
1220 g_signal_connect(G_OBJECT(viewer
->view
), "resource-load-failed",
1221 G_CALLBACK(resource_load_failed_cb
), viewer
);
1223 webkit_web_context_register_uri_scheme(webkit_web_context_get_default(),
1224 "cid", load_content_cb
, viewer
, NULL
);
1226 viewer
->filename
= NULL
;
1227 return (MimeViewer
*) viewer
;
1230 static gchar
*content_types
[] = {"text/html", NULL
};
1232 static MimeViewerFactory fancy_viewer_factory
=
1236 fancy_viewer_create
,
1239 gint
plugin_init(gchar
**error
)
1241 if (!check_plugin_version(MAKE_NUMERIC_VERSION(3,0,0,0),
1242 VERSION_NUMERIC
, _("Fancy"), error
))
1244 gchar
*directory
= g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S
,
1246 if (!is_dir_exist(directory
))
1247 if (make_dir (directory
) < 0) {
1253 gchar
*web_ext_filename
= g_strconcat(FANCY_WEB_EXTENSION_FILE
,
1257 gchar
*web_ext_file
= g_build_path(G_DIR_SEPARATOR_S
,
1258 FANCY_WEB_EXTENSIONS_DIR
,
1262 if (!g_file_test(web_ext_file
, G_FILE_TEST_EXISTS
)) {
1263 *error
= g_strdup_printf(_("Failed to find the companion WebKit extension %s"), web_ext_file
);
1264 g_free(web_ext_filename
);
1265 g_free(web_ext_file
);
1269 g_free(web_ext_filename
);
1270 g_free(web_ext_file
);
1272 webkit_web_context_set_web_extensions_directory(webkit_web_context_get_default(),
1273 FANCY_WEB_EXTENSIONS_DIR
);
1277 mimeview_register_viewer_factory(&fancy_viewer_factory
);
1282 gboolean
plugin_done(void)
1284 mimeview_unregister_viewer_factory(&fancy_viewer_factory
);
1289 const gchar
*plugin_name(void)
1291 /* TRANSLATORS: 'Fancy' here is name of the plugin, not the english word. */
1292 return _("Fancy HTML Viewer");
1295 const gchar
*plugin_desc(void)
1297 return g_strdup_printf(_("This plugin renders HTML mail using the WebKit "
1298 "%d.%d.%d library.\nBy default all remote content is "
1300 "can be found in /Configuration/Preferences/Plugins/Fancy"),
1301 WEBKIT_MAJOR_VERSION
, WEBKIT_MINOR_VERSION
,
1302 WEBKIT_MICRO_VERSION
);
1305 const gchar
*plugin_type(void)
1310 const gchar
*plugin_licence(void)
1315 const gchar
*plugin_version(void)
1320 struct PluginFeature
*plugin_provides(void)
1322 static struct PluginFeature features
[] = {
1323 {PLUGIN_MIMEVIEWER
, "text/html"},
1324 {PLUGIN_NOTHING
, NULL
}