Improve some sieve-related translations
[claws.git] / src / plugins / fancy / fancy_viewer.c
blob6701e8bd9860535056f7795febb1f748a3a29ba7
1 /*
2 * Claws Mail -- A GTK based, lightweight, and fast e-mail client
3 * == Fancy Plugin ==
4 * Copyright(C) 1999-2022 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/>.
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #include "claws-features.h"
26 #endif
28 #include "stock_pixmap.h"
30 #include <fancy_viewer.h>
31 #include <fancy_prefs.h>
32 #include <alertpanel.h>
33 #include <file-utils.h>
34 #include <utils.h>
36 #include <printing.h>
38 static void load_changed_cb(WebKitWebView *view,
39 WebKitLoadEvent event,
40 gpointer user_data);
41 static void mouse_target_changed_cb (WebKitWebView *view,
42 WebKitHitTestResult *result,
43 guint modifiers,
44 gpointer user_data);
47 static void
48 load_progress_cb(WebKitWebView *view, GParamSpec *param, FancyViewer *viewer);
50 static MimeViewerFactory fancy_viewer_factory;
53 static gboolean
54 fancy_text_search(MimeViewer *_viewer, gboolean backward, const gchar *str,
55 gboolean case_sens);
58 static void
59 viewer_menu_handler(GtkWidget *menuitem, FancyViewer *viewer);
61 static gint keypress_events_cb (GtkWidget *widget, GdkEventKey *event,
62 FancyViewer *viewer);
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);
76 /*------*/
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,
92 #ifdef G_OS_WIN32
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",
99 #endif
100 NULL);
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 if (viewer->override_prefs_remote_content)
114 webkit_web_context_set_network_proxy_settings(webkit_web_context_get_default(), WEBKIT_NETWORK_PROXY_MODE_DEFAULT, NULL);
115 else
116 webkit_web_context_set_network_proxy_settings(webkit_web_context_get_default(), WEBKIT_NETWORK_PROXY_MODE_CUSTOM, viewer->no_remote_content_proxy_settings);
118 if (viewer->override_stylesheet) {
119 /* copied from vimb */
120 gchar *stylesheet;
122 if (g_file_get_contents(viewer->override_stylesheet, &stylesheet, NULL, NULL)) {
123 WebKitUserContentManager *ucm;
124 WebKitUserStyleSheet *style;
126 ucm = webkit_web_view_get_user_content_manager(viewer->view);
127 style = webkit_user_style_sheet_new(
128 stylesheet, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES,
129 WEBKIT_USER_STYLE_LEVEL_USER, NULL, NULL);
131 webkit_user_content_manager_remove_all_style_sheets(ucm);
132 webkit_user_content_manager_add_style_sheet(ucm, style);
133 webkit_user_style_sheet_unref(style);
134 g_free(stylesheet);
135 } else {
136 debug_print("Could not read style file: %s\n", viewer->override_stylesheet);
141 static void fancy_auto_load_images_activated(GtkCheckMenuItem *item, FancyViewer *viewer) {
142 viewer->override_prefs_images = gtk_check_menu_item_get_active(item);
143 fancy_apply_prefs(viewer);
144 fancy_set_contents(viewer, FALSE);
147 static void fancy_enable_remote_content_activated(GtkCheckMenuItem *item, FancyViewer *viewer) {
148 viewer->override_prefs_remote_content = gtk_check_menu_item_get_active(item);
149 fancy_apply_prefs(viewer);
150 fancy_set_contents(viewer, FALSE);
153 static void fancy_enable_scripts_activated(GtkCheckMenuItem *item, FancyViewer *viewer) {
154 viewer->override_prefs_scripts = gtk_check_menu_item_get_active(item);
155 fancy_apply_prefs(viewer);
156 fancy_set_contents(viewer, FALSE);
159 static void fancy_enable_plugins_activated(GtkCheckMenuItem *item, FancyViewer *viewer) {
160 viewer->override_prefs_plugins = gtk_check_menu_item_get_active(item);
161 fancy_apply_prefs(viewer);
162 fancy_set_contents(viewer, FALSE);
165 static void fancy_enable_java_activated(GtkCheckMenuItem *item, FancyViewer *viewer) {
166 viewer->override_prefs_java = gtk_check_menu_item_get_active(item);
167 fancy_apply_prefs(viewer);
168 fancy_set_contents(viewer, FALSE);
171 static void fancy_open_external_activated(GtkCheckMenuItem *item, FancyViewer *viewer) {
172 viewer->override_prefs_external = gtk_check_menu_item_get_active(item);
173 fancy_apply_prefs(viewer);
176 static void fancy_set_defaults(FancyViewer *viewer)
178 viewer->override_prefs_remote_content = fancy_prefs.enable_remote_content;
179 viewer->override_prefs_external = fancy_prefs.open_external;
180 viewer->override_prefs_images = fancy_prefs.enable_images;
181 viewer->override_prefs_scripts = fancy_prefs.enable_scripts;
182 viewer->override_prefs_plugins = fancy_prefs.enable_plugins;
183 viewer->override_prefs_java = fancy_prefs.enable_java;
185 gchar *tmp;
187 #ifdef G_OS_WIN32
188 /* Replace backslashes with forward slashes, since we'll be
189 * using this string in an URI. */
190 gchar *tmp2 = g_strdup(fancy_prefs.stylesheet);
191 subst_char(tmp2, '\\', '/');
193 /* Escape string for use in an URI, keeping dir separators
194 * and colon for Windows drive name ("C:") intact. */
195 tmp = g_uri_escape_string(tmp2, "/:", TRUE);
196 g_free(tmp2);
197 #else
198 /* Escape string for use in an URI, keeping dir separators
199 * intact. */
200 tmp = g_uri_escape_string(fancy_prefs.stylesheet, "/", TRUE);
201 #endif
202 viewer->override_stylesheet = g_strdup(tmp);
203 g_free(tmp);
204 debug_print("Using '%s' as stylesheet\n",
205 viewer->override_stylesheet);
207 g_signal_handlers_block_by_func(G_OBJECT(viewer->enable_images),
208 fancy_auto_load_images_activated, viewer);
209 g_signal_handlers_block_by_func(G_OBJECT(viewer->enable_remote_content),
210 fancy_enable_remote_content_activated, viewer);
211 g_signal_handlers_block_by_func(G_OBJECT(viewer->enable_scripts),
212 fancy_enable_scripts_activated, viewer);
213 g_signal_handlers_block_by_func(G_OBJECT(viewer->enable_plugins),
214 fancy_enable_plugins_activated, viewer);
215 g_signal_handlers_block_by_func(G_OBJECT(viewer->enable_java),
216 fancy_enable_java_activated, viewer);
217 g_signal_handlers_block_by_func(G_OBJECT(viewer->open_external),
218 fancy_open_external_activated, viewer);
220 gtk_check_menu_item_set_active(
221 GTK_CHECK_MENU_ITEM(viewer->enable_images),
222 viewer->override_prefs_images);
223 gtk_check_menu_item_set_active(
224 GTK_CHECK_MENU_ITEM(viewer->enable_scripts),
225 viewer->override_prefs_scripts);
226 gtk_check_menu_item_set_active(
227 GTK_CHECK_MENU_ITEM(viewer->enable_plugins),
228 viewer->override_prefs_plugins);
229 gtk_check_menu_item_set_active(
230 GTK_CHECK_MENU_ITEM(viewer->enable_java),
231 viewer->override_prefs_java);
232 gtk_check_menu_item_set_active(
233 GTK_CHECK_MENU_ITEM(viewer->enable_remote_content),
234 viewer->override_prefs_remote_content);
235 gtk_check_menu_item_set_active(
236 GTK_CHECK_MENU_ITEM(viewer->open_external),
237 viewer->override_prefs_external);
239 g_signal_handlers_unblock_by_func(G_OBJECT(viewer->enable_images),
240 fancy_auto_load_images_activated, viewer);
241 g_signal_handlers_unblock_by_func(G_OBJECT(viewer->enable_remote_content),
242 fancy_enable_remote_content_activated, viewer);
243 g_signal_handlers_unblock_by_func(G_OBJECT(viewer->enable_scripts),
244 fancy_enable_scripts_activated, viewer);
245 g_signal_handlers_unblock_by_func(G_OBJECT(viewer->enable_plugins),
246 fancy_enable_plugins_activated, viewer);
247 g_signal_handlers_unblock_by_func(G_OBJECT(viewer->enable_java),
248 fancy_enable_java_activated, viewer);
249 g_signal_handlers_unblock_by_func(G_OBJECT(viewer->open_external),
250 fancy_open_external_activated, viewer);
252 fancy_apply_prefs(viewer);
255 static gboolean fancy_set_contents(FancyViewer *viewer, gboolean use_defaults)
257 MessageView *messageview = ((MimeViewer *)viewer)->mimeview
258 ? ((MimeViewer *)viewer)->mimeview->messageview
259 : NULL;
260 MimeInfo *partinfo = viewer->to_load;
262 if (messageview) {
263 messageview->updating = TRUE;
264 NoticeView *noticeview = messageview->noticeview;
265 noticeview_hide(noticeview);
268 if (viewer->filename != NULL) {
269 g_unlink(viewer->filename);
270 g_free(viewer->filename);
271 viewer->filename = NULL;
274 if (partinfo)
275 viewer->filename = procmime_get_tmp_file_name(partinfo);
276 debug_print("filename: %s\n", viewer->filename);
277 if (!viewer->filename) {
278 return FALSE;
280 if (procmime_get_part(viewer->filename, partinfo) < 0) {
281 g_free(viewer->filename);
282 viewer->filename = NULL;
284 else {
285 const gchar *charset = NULL;
286 gchar *contents = NULL;
287 GBytes *content_bytes;
288 gdouble zoom_level;
289 zoom_level = (double) fancy_prefs.zoom_level / 100;
291 if (messageview && messageview->forced_charset)
292 charset = ((MimeViewer *)viewer)->mimeview->messageview->forced_charset;
293 else
294 charset = procmime_mimeinfo_get_parameter(partinfo, "charset");
295 if (!charset)
296 charset = conv_get_locale_charset_str();
297 debug_print("using %s charset\n", charset);
298 g_object_set(viewer->settings, "default-charset", charset, NULL);
300 if (use_defaults) {
301 debug_print("zoom_level: %f\n", zoom_level);
303 webkit_web_view_set_zoom_level(viewer->view, zoom_level);
305 fancy_set_defaults(viewer);
308 contents = file_read_to_str_no_recode(viewer->filename);
309 content_bytes = g_bytes_new(contents, strlen(contents));
310 webkit_web_view_load_bytes(viewer->view,
311 content_bytes,
312 "text/html",
313 charset,
314 NULL);
315 g_free(contents);
316 g_bytes_unref(content_bytes);
318 return FALSE;
321 static gboolean fancy_show_mimepart_real(MimeViewer *_viewer)
323 return fancy_set_contents((FancyViewer *)_viewer, TRUE);
326 static void fancy_show_notice(FancyViewer *viewer, const gchar *message)
328 gtk_label_set_text(GTK_LABEL(viewer->l_link), message);
331 static gboolean fancy_show_mimepart_prepare(MimeViewer *_viewer)
333 FancyViewer *viewer = (FancyViewer *) _viewer;
335 g_timeout_add(5, (GSourceFunc)fancy_show_mimepart_real, viewer);
336 return FALSE;
339 static void fancy_show_mimepart(MimeViewer *_viewer, const gchar *infile,
340 MimeInfo *partinfo)
342 FancyViewer *viewer = (FancyViewer *) _viewer;
343 viewer->to_load = partinfo;
344 viewer->loading = TRUE;
345 g_timeout_add(5, (GSourceFunc)fancy_show_mimepart_prepare, viewer);
348 static void fancy_print_fail_cb(WebKitPrintOperation *print_operation,
349 GError *error,
350 gpointer user_data) {
351 /* avoid warning for unused variable
352 FancyViewer *viewer = (FancyViewer *) user_data;
355 debug_print("Error printing message: %s\n",
356 error ? error->message : "no details");
359 static void fancy_print(MimeViewer *_viewer)
361 FancyViewer *viewer = (FancyViewer *) _viewer;
362 WebKitPrintOperationResponse res;
363 WebKitPrintOperation *printoperation;
364 GtkPrintSettings *printsettings;
365 GtkPageSetup *pagesetup;
367 gtk_widget_realize(GTK_WIDGET(viewer->view));
369 while (viewer->loading)
370 claws_do_idle();
372 printoperation = webkit_print_operation_new(viewer->view);
373 g_signal_connect(G_OBJECT(printoperation), "failed",
374 G_CALLBACK(fancy_print_fail_cb), viewer);
376 printsettings = webkit_print_operation_get_print_settings(printoperation);
377 if (!printsettings) {
378 printsettings = printing_get_settings();
379 webkit_print_operation_set_print_settings(printoperation, printsettings);
381 pagesetup = webkit_print_operation_get_page_setup(printoperation);
382 if (!pagesetup) {
383 pagesetup = printing_get_page_setup();
384 webkit_print_operation_set_page_setup(printoperation, pagesetup);
387 MainWindow *mainwin = mainwindow_get_mainwindow();
388 res = webkit_print_operation_run_dialog(
389 printoperation,
390 mainwin ? GTK_WINDOW(mainwin->window):NULL);
392 if (res == WEBKIT_PRINT_OPERATION_RESPONSE_PRINT) {
393 // store settings for next printing session
394 printing_store_settings(
395 webkit_print_operation_get_print_settings(printoperation));
398 g_object_unref(printoperation);
401 /*static gchar *fancy_get_selection (MimeViewer *_viewer)
403 debug_print("fancy_get_selection\n");
404 FancyViewer *viewer = (FancyViewer *) _viewer;
405 viewer->doc = webkit_web_page_get_dom_document(WEBKIT_WEB_VIEW(viewer->view));
406 viewer->window = webkit_dom_document_get_default_view (viewer->doc);
407 viewer->selection = webkit_dom_dom_window_get_selection (viewer->window);
408 if (viewer->selection == NULL)
409 return NULL;
410 viewer->range = webkit_dom_dom_selection_get_range_at(viewer->selection, 0, NULL);
411 if (viewer->range == NULL)
412 return NULL;
413 gchar *sel = webkit_dom_range_get_text (viewer->range);
414 if (!viewer->view || strlen(sel) == 0) {
415 g_free(sel);
416 return NULL;
418 return sel;
421 static void fancy_clear_viewer(MimeViewer *_viewer)
423 FancyViewer *viewer = (FancyViewer *) _viewer;
424 GtkAdjustment *vadj;
425 viewer->cur_link = NULL;
426 fancy_set_defaults(viewer);
428 webkit_web_view_load_uri(viewer->view, "about:blank");
430 debug_print("fancy_clear_viewer\n");
431 fancy_prefs.zoom_level = (int) webkit_web_view_get_zoom_level(viewer->view) * 100;
432 viewer->to_load = NULL;
433 vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(viewer->scrollwin));
434 gtk_adjustment_set_value(vadj, 0.0);
435 g_signal_emit_by_name(G_OBJECT(vadj), "value-changed", 0);
438 static void fancy_destroy_viewer(MimeViewer *_viewer)
440 FancyViewer *viewer = (FancyViewer *) _viewer;
441 fancy_prefs.zoom_level = (int) webkit_web_view_get_zoom_level(viewer->view) * 100;
442 debug_print("fancy_destroy_viewer\n");
443 g_free(viewer->filename);
444 g_free(viewer);
447 static gboolean
448 navigation_policy_cb (WebKitWebView *web_view,
449 WebKitPolicyDecision *policy_decision,
450 WebKitPolicyDecisionType policy_decision_type,
451 FancyViewer *viewer)
453 if (policy_decision_type == WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION || policy_decision_type == WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION) {
454 WebKitNavigationPolicyDecision *navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION(policy_decision);
455 WebKitNavigationAction *navigation_action = webkit_navigation_policy_decision_get_navigation_action(navigation_decision);
456 viewer->cur_link = webkit_uri_request_get_uri(webkit_navigation_action_get_request(navigation_action));
458 debug_print("navigation requested to %s\n", viewer->cur_link);
460 if (viewer->cur_link) {
461 if (!strncmp(viewer->cur_link, "mailto:", 7)) {
462 debug_print("Opening message window\n");
463 compose_new(NULL, viewer->cur_link + 7, NULL);
464 webkit_policy_decision_ignore(policy_decision);
465 } else if (!strncmp(viewer->cur_link, "file://", 7) || !strcmp(viewer->cur_link, "about:blank")) {
466 debug_print("local navigation request ACCEPTED\n");
467 webkit_policy_decision_use(policy_decision);
468 } else if (viewer->override_prefs_external && webkit_navigation_action_get_navigation_type(navigation_action) == WEBKIT_NAVIGATION_TYPE_LINK_CLICKED) {
469 debug_print("remote navigation request OPENED\n");
470 open_uri(viewer->cur_link, prefs_common_get_uri_cmd());
471 webkit_policy_decision_ignore(policy_decision);
472 } else if (viewer->override_prefs_remote_content) {
473 debug_print("remote navigation request ACCEPTED\n");
474 webkit_policy_decision_use(policy_decision);
475 } else {
476 debug_print("remote navigation request IGNORED\n");
477 fancy_show_notice(viewer, _("Remote content loading is disabled."));
478 webkit_policy_decision_ignore(policy_decision);
481 return TRUE;
482 } else {
483 return FALSE;
487 static void load_content_cb(WebKitURISchemeRequest *request, gpointer viewer)
489 gchar *image;
490 MimeInfo *partinfo = ((FancyViewer *)viewer)->to_load;
491 gchar *mimetype;
492 GInputStream *stream;
493 GError *error;
495 image = g_strconcat("<", webkit_uri_scheme_request_get_path(request), ">", NULL);
496 while ((partinfo = procmime_mimeinfo_next(partinfo)) != NULL) {
497 if (partinfo->id && !g_ascii_strcasecmp(image, partinfo->id)) {
498 mimetype = procmime_get_content_type_str(partinfo->type, partinfo->subtype);
499 stream = procmime_get_part_as_inputstream(partinfo);
500 webkit_uri_scheme_request_finish(request, stream, partinfo->length,
501 mimetype);
502 g_object_unref(stream);
503 g_free(mimetype);
504 g_free(image);
505 return;
509 error = g_error_new(0, 0, _("Couldn't save the part of multipart message: %s"), image);
510 webkit_uri_scheme_request_finish_error(request, error);
511 g_error_free(error);
512 g_free(image);
515 static void resource_request_starting_cb(WebKitWebView *view,
516 WebKitWebResource *resource,
517 WebKitURIRequest *request,
518 WebKitURIResponse *response,
519 FancyViewer *viewer)
521 const gchar *uri = webkit_uri_request_get_uri(request);
522 gchar *filename;
523 gchar *image;
524 gint err;
525 MimeInfo *partinfo = viewer->to_load;
527 filename = viewer->filename;
528 if ((!g_ascii_strncasecmp(uri, "cid:", 4)) || (!g_ascii_strncasecmp(uri, "mid:", 4))) {
529 image = g_strconcat("<", uri + 4, ">", NULL);
530 while ((partinfo = procmime_mimeinfo_next(partinfo)) != NULL) {
531 if (partinfo->id && !g_ascii_strcasecmp(image, partinfo->id)) {
532 filename = procmime_get_tmp_file_name(partinfo);
533 if (!filename) {
534 g_free(image);
535 return;
537 if ((err = procmime_get_part(filename, partinfo)) < 0)
538 alertpanel_error(_("Couldn't save the part of multipart message: %s"),
539 g_strerror(-err));
540 gchar *file_uri = g_filename_to_uri(filename, NULL, NULL);
541 webkit_uri_request_set_uri(request, file_uri);
542 g_free(file_uri);
543 g_free(filename);
544 break;
547 g_free(image);
550 /* refresh URI that may have changed */
551 uri = webkit_uri_request_get_uri(request);
552 if (!viewer->override_prefs_remote_content
553 && strncmp(uri, "file://", 7) && strncmp(uri, "data:", 5)) {
554 debug_print("Preventing load of %s\n", uri);
555 webkit_uri_request_set_uri(request, "about:blank");
557 else
558 debug_print("Starting request of %"G_GSIZE_FORMAT" %s\n", strlen(uri), uri);
561 /*static gboolean fancy_text_search(MimeViewer *_viewer, gboolean backward,
562 const gchar *str, gboolean case_sens)
564 return webkit_web_view_search_text(((FancyViewer*)_viewer)->view, str,
565 case_sens, !backward, TRUE);
568 static gboolean fancy_prefs_cb(GtkWidget *widget, GdkEventButton *ev, FancyViewer *viewer)
570 if ((ev->button == 1) && (ev->type == GDK_BUTTON_PRESS)) {
571 gtk_menu_popup_at_widget(GTK_MENU(viewer->fancy_prefs_menu),
572 widget, GDK_GRAVITY_CENTER, GDK_GRAVITY_SOUTH_WEST, NULL);
573 return TRUE;
575 return FALSE;
578 static void fancy_create_popup_prefs_menu(FancyViewer *viewer) {
579 GtkWidget *enable_images;
580 GtkWidget *enable_remote_content;
581 GtkWidget *enable_scripts;
582 GtkWidget *enable_plugins;
583 GtkWidget *enable_java;
584 GtkWidget *open_external;
586 enable_images = gtk_check_menu_item_new_with_label(_("Load images"));
588 enable_remote_content = gtk_check_menu_item_new_with_label(_("Enable remote content"));
590 enable_scripts = gtk_check_menu_item_new_with_label(_("Enable Javascript"));
592 enable_plugins = gtk_check_menu_item_new_with_label(_("Enable Plugins"));
594 enable_java = gtk_check_menu_item_new_with_label(_("Enable Java"));
596 open_external = gtk_check_menu_item_new_with_label(_("Open links with external browser"));
598 gtk_menu_shell_append(GTK_MENU_SHELL(viewer->fancy_prefs_menu), enable_images);
599 gtk_menu_shell_append(GTK_MENU_SHELL(viewer->fancy_prefs_menu), enable_remote_content);
600 gtk_menu_shell_append(GTK_MENU_SHELL(viewer->fancy_prefs_menu), enable_scripts);
601 gtk_menu_shell_append(GTK_MENU_SHELL(viewer->fancy_prefs_menu), enable_plugins);
602 gtk_menu_shell_append(GTK_MENU_SHELL(viewer->fancy_prefs_menu), enable_java);
603 gtk_menu_shell_append(GTK_MENU_SHELL(viewer->fancy_prefs_menu), open_external);
605 gtk_menu_attach_to_widget(GTK_MENU(viewer->fancy_prefs_menu), viewer->ev_fancy_prefs, NULL);
606 gtk_widget_show_all(viewer->fancy_prefs_menu);
608 viewer->enable_images = enable_images;
609 viewer->enable_scripts = enable_scripts;
610 viewer->enable_plugins = enable_plugins;
611 viewer->enable_java = enable_java;
612 viewer->enable_remote_content = enable_remote_content;
613 viewer->open_external = open_external;
615 /* Set sensitivity according to preferences and overrides */
617 g_signal_connect(G_OBJECT(enable_images), "toggled",
618 G_CALLBACK (fancy_auto_load_images_activated), viewer);
619 g_signal_connect(G_OBJECT(enable_remote_content), "toggled",
620 G_CALLBACK (fancy_enable_remote_content_activated), viewer);
621 g_signal_connect(G_OBJECT(enable_scripts), "toggled",
622 G_CALLBACK (fancy_enable_scripts_activated), viewer);
623 g_signal_connect(G_OBJECT(enable_plugins), "toggled",
624 G_CALLBACK (fancy_enable_plugins_activated), viewer);
625 g_signal_connect(G_OBJECT(enable_java), "toggled",
626 G_CALLBACK (fancy_enable_java_activated), viewer);
627 g_signal_connect(G_OBJECT(open_external), "toggled",
628 G_CALLBACK (fancy_open_external_activated), viewer);
630 fancy_apply_prefs(viewer);
633 static gboolean fancy_scroll_page(MimeViewer *_viewer, gboolean up)
635 FancyViewer *viewer = (FancyViewer *)_viewer;
636 GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment(
637 GTK_SCROLLED_WINDOW(viewer->scrollwin));
639 if (viewer->view == NULL)
640 return FALSE;
642 return gtkutils_scroll_page(GTK_WIDGET(viewer->view), vadj, up);
645 static void fancy_scroll_one_line(MimeViewer *_viewer, gboolean up)
647 FancyViewer *viewer = (FancyViewer *)_viewer;
648 GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment(
649 GTK_SCROLLED_WINDOW(viewer->scrollwin));
651 if (viewer->view == NULL)
652 return;
654 gtkutils_scroll_one_line(GTK_WIDGET(viewer->view), vadj, up);
657 static void load_changed_cb(WebKitWebView *view,
658 WebKitLoadEvent event,
659 gpointer user_data)
661 FancyViewer *viewer = (FancyViewer *)user_data;
663 switch (event) {
664 case WEBKIT_LOAD_STARTED:
665 gtk_widget_show(viewer->progress);
666 gtk_widget_show(viewer->ev_stop_loading);
667 break;
669 case WEBKIT_LOAD_FINISHED:
670 viewer->loading = FALSE;
671 gtk_widget_hide(viewer->progress);
672 gtk_widget_hide(viewer->ev_stop_loading);
673 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(viewer->progress),
674 (gdouble) 0.0);
675 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(viewer->progress), "");
676 break;
677 default:
678 break;
682 static void mouse_target_changed_cb(WebKitWebView *view,
683 WebKitHitTestResult *result,
684 guint modifiers,
685 gpointer user_data)
687 FancyViewer *viewer = (FancyViewer *)user_data;
689 cm_return_if_fail(result != NULL);
691 /* Display the link in the bottom statusbar, or erase it
692 * if the cursor left the link. */
693 if (!webkit_hit_test_result_context_is_link(result)) {
694 gtk_label_set_text(GTK_LABEL(viewer->l_link), NULL);
695 return;
698 gtk_label_set_text(GTK_LABEL(viewer->l_link),
699 webkit_hit_test_result_get_link_uri(result));
702 static void load_progress_cb(WebKitWebView *view, GParamSpec *param,
703 FancyViewer *viewer)
705 // WebKitLoadEvent status = webkit_web_view_get_load_status(viewer->view);
706 // gdouble pbar = webkit_web_view_get_progress(viewer->view);
707 // const gchar *uri = webkit_web_view_get_uri(viewer->view);
709 gdouble progress = webkit_web_view_get_estimated_load_progress(view);
710 gchar *label = g_strdup_printf("%d%% Loading...", (gint)(progress * 100));
711 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(viewer->progress), progress);
712 gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(viewer->progress), TRUE);
713 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(viewer->progress),
714 (const gchar*)label);
715 g_free(label);
717 /* switch (status) {
718 case WEBKIT_LOAD_COMMITTED:
719 break;
720 case WEBKIT_LOAD_FINISHED:
721 debug_print("Load finished: %s\n", uri);
722 break;
726 static void stop_loading_cb(GtkWidget *widget, GdkEvent *ev,
727 FancyViewer *viewer)
729 webkit_web_view_stop_loading (viewer->view);
730 gtk_widget_hide(viewer->progress);
731 gtk_widget_hide(viewer->ev_stop_loading);
734 static void search_the_web_cb(GtkWidget *widget, FancyViewer *viewer)
736 debug_print("Clicked on Search on Web\n");
737 if (webkit_web_view_has_selection(viewer->view)) {
738 gchar *search;
739 viewer->doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(viewer->view));
740 viewer->window = webkit_dom_document_get_default_view (viewer->doc);
741 viewer->selection = webkit_dom_dom_window_get_selection (viewer->window);
742 viewer->range = webkit_dom_dom_selection_get_range_at(viewer->selection, 0, NULL);
743 gchar *tmp = webkit_dom_range_get_text (viewer->range);
744 search = g_strconcat(GOOGLE_SEARCH, tmp, NULL);
746 webkit_web_view_load_uri(viewer->view, search);
747 g_free(search);
748 g_free(tmp);
752 static void open_in_browser_cb(GtkWidget *widget, FancyViewer *viewer)
754 debug_print("open outer: %s\n", viewer->cur_link);
755 if(viewer->cur_link)
756 open_uri(viewer->cur_link, prefs_common_get_uri_cmd());
759 static size_t download_file_curl_write_cb(void *buffer, size_t size,
760 size_t nmemb, void *data)
762 FancyViewer *viewer = (FancyViewer *)data;
763 if (!viewer->stream) {
764 viewer->stream = claws_fopen(viewer->curlfile, "wb");
765 if (!viewer->stream)
766 return -1;
768 return claws_fwrite(buffer, size, nmemb, viewer->stream);
770 static void *download_file_curl (void *data)
772 CURL *curl;
773 CURLcode res;
774 FancyViewer *viewer = (FancyViewer *)data;
776 curl_global_init(CURL_GLOBAL_DEFAULT);
777 curl = curl_easy_init();
779 if (curl) {
780 curl_easy_setopt(curl, CURLOPT_URL, viewer->cur_link);
781 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, download_file_curl_write_cb);
782 curl_easy_setopt(curl, CURLOPT_WRITEDATA, viewer);
783 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
784 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
785 #ifdef G_OS_WIN32
786 curl_easy_setopt(curl, CURLOPT_CAINFO, claws_ssl_get_cert_file());
787 #endif
788 res = curl_easy_perform(curl);
789 curl_easy_cleanup(curl);
791 if (CURLE_OK != res)
792 alertpanel_error(_("An error occurred: %d\n"), res);
793 if (viewer->stream)
794 claws_safe_fclose(viewer->stream);
795 curl_global_cleanup();
797 #ifdef USE_PTHREAD
798 pthread_exit(NULL);
799 #else
800 return NULL;
801 #endif
803 static void download_file_cb(GtkWidget *widget, FancyViewer *viewer)
805 #ifdef USE_PTHREAD
806 pthread_t curljob;
807 gint result;
808 #endif
809 const gchar *link = viewer->cur_link;
810 gchar *filename = g_utf8_strchr(link, -1, g_utf8_get_char("/"));
811 filename = g_strconcat(get_home_dir(), filename, NULL);
812 gchar *fname = filesel_select_file_save(_("Save as"), filename);
813 if (!fname) {
814 g_free(filename);
815 return;
818 if (viewer->curlfile) viewer->curlfile = NULL;
819 if (viewer->stream) viewer->stream = NULL;
820 viewer->curlfile = (const gchar *)g_strdup(fname);
821 g_free(filename);
822 g_free(fname);
824 if (!viewer->curlfile) return;
826 #ifdef USE_PTHREAD
827 result = pthread_create(&curljob, NULL, download_file_curl, (void *)viewer);
828 if (result)
829 alertpanel_error("ERROR; return code from pthread_create() is %d\n", result);
830 #else
831 download_file_curl((void *)viewer);
832 #endif
835 static void save_image_cb(GtkWidget *widget, FancyViewer *viewer)
837 debug_print("Not Yet Implemented\n");
840 static void open_image_cb(GtkWidget *widget, FancyViewer *viewer)
842 debug_print("Not Yet Implemented\n");
845 static void copy_image_cb(GtkWidget *widget, FancyViewer *viewer)
847 debug_print("Not Yet Implemented\n");
849 static void import_feed_cb(GtkWidget *widget, FancyViewer *viewer)
851 if (!folder_subscribe(viewer->cur_link))
852 alertpanel_error(_("%s is a malformed or not supported feed"), viewer->cur_link);
854 static void viewer_menu_handler(GtkWidget *menuitem, FancyViewer *viewer)
856 const gchar *g_name = gtk_widget_get_name(GTK_WIDGET(menuitem));
857 if (!g_ascii_strcasecmp(g_name, "GtkMenuItem")) {
859 GtkWidget *menul = gtk_bin_get_child(GTK_BIN(menuitem));
861 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul)),
862 "Search the Web")) {
863 gtk_label_set_text(GTK_LABEL(menul), _("Search the Web"));
864 viewer->cur_link = NULL;
865 GtkMenuItem *m_search = GTK_MENU_ITEM(menuitem);
866 g_signal_connect(G_OBJECT(m_search), "activate",
867 G_CALLBACK(search_the_web_cb),
868 (gpointer *) viewer);
871 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul)),
872 "Open Link" )) {
874 gtk_label_set_text(GTK_LABEL(menul), _("Open in Viewer"));
876 GtkMenuItem *m_new = GTK_MENU_ITEM(menuitem);
877 gtk_widget_set_sensitive(GTK_WIDGET(m_new), viewer->override_prefs_remote_content);
880 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul)),
881 "Open Link in New Window" )) {
883 gtk_label_set_text(GTK_LABEL(menul), _("Open in Browser"));
885 GtkMenuItem *m_new = GTK_MENU_ITEM(menuitem);
886 g_signal_connect(G_OBJECT(m_new), "activate",
887 G_CALLBACK(open_in_browser_cb),
888 (gpointer *) viewer);
891 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul)),
892 "Open Image in New Window" )) {
893 gtk_label_set_text(GTK_LABEL(menul), _("Open Image"));
894 GtkMenuItem *m_image = GTK_MENU_ITEM(menuitem);
895 g_signal_connect(G_OBJECT(m_image), "activate",
896 G_CALLBACK(open_image_cb),
897 (gpointer *) viewer);
900 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul)),
901 "Copy Link Location" )) {
902 gtk_label_set_text(GTK_LABEL(menul), _("Copy Link"));
905 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul)),
906 "Download Linked File" )) {
907 gtk_label_set_text(GTK_LABEL(menul), _("Download Link"));
909 GtkMenuItem *m_dlink = GTK_MENU_ITEM(menuitem);
910 g_signal_connect(G_OBJECT(m_dlink), "activate",
911 G_CALLBACK(download_file_cb),
912 (gpointer *) viewer);
915 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul)),
916 "Save Image As" )) {
918 gtk_label_set_text(GTK_LABEL(menul), _("Save Image As"));
920 GtkMenuItem *m_simage = GTK_MENU_ITEM(menuitem);
921 g_signal_connect(G_OBJECT(m_simage), "activate",
922 G_CALLBACK(save_image_cb),
923 (gpointer *) viewer);
926 if (!g_ascii_strcasecmp(gtk_label_get_text(GTK_LABEL(menul)),
927 "Copy Image" )) {
928 gtk_label_set_text(GTK_LABEL(menul), _("Copy Image"));
929 GtkMenuItem *m_cimage = GTK_MENU_ITEM(menuitem);
930 g_signal_connect(G_OBJECT(m_cimage), "activate",
931 G_CALLBACK(copy_image_cb),
932 (gpointer *) viewer);
938 static gboolean context_menu_cb (WebKitWebView *view, WebKitContextMenu *menu,
939 GdkEvent *event, WebKitHitTestResult *hit_test_result,
940 gpointer user_data)
942 FancyViewer *viewer = (FancyViewer *)user_data;
943 Plugin *plugin = plugin_get_loaded_by_name("RSSyl");
944 WebKitHitTestResultContext context;
945 const gchar *link_uri = NULL;
947 context = webkit_hit_test_result_get_context(hit_test_result);
949 link_uri = webkit_hit_test_result_get_link_uri(hit_test_result);
951 debug_print("context %d, link-uri '%s'\n", context,
952 (link_uri != NULL ? link_uri : "(null)"));
953 if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK &&
954 link_uri != NULL) {
955 if (viewer != NULL && viewer->cur_link != NULL) {
956 /* g_object_get() already made a copy, no need to strdup() here */
957 viewer->cur_link = link_uri;
961 gtk_container_foreach(GTK_CONTAINER(menu),
962 (GtkCallback)viewer_menu_handler,
963 viewer);
965 if (plugin) {
966 GtkWidget *rssyl = gtk_menu_item_new_with_label(_("Import feed"));
967 gtk_widget_show(GTK_WIDGET(rssyl));
968 gtk_menu_shell_append(GTK_MENU_SHELL(menu), rssyl);
969 g_signal_connect(G_OBJECT(rssyl), "activate",
970 G_CALLBACK(import_feed_cb),
971 (gpointer *) viewer);
974 return FALSE;
977 static gint keypress_events_cb (GtkWidget *widget, GdkEventKey *event,
978 FancyViewer *viewer)
980 if (event->state == CTRL_KEY) {
981 switch (event->keyval) {
982 case GDK_KEY_plus:
983 zoom_in_cb(viewer->ev_zoom_in, NULL, viewer);
984 break;
985 case GDK_KEY_period:
986 zoom_100_cb(viewer->ev_zoom_100, NULL, viewer);
987 break;
988 case GDK_KEY_minus:
989 zoom_out_cb(viewer->ev_zoom_out, NULL, viewer);
990 break;
993 return FALSE;
996 /*static gboolean release_button_cb (WebKitWebView *view, GdkEvent *ev, FancyViewer *viewer)
998 if (ev->button.button == 1 && viewer->cur_link && viewer->override_prefs_external) {
999 gint x, y;
1000 WebKitHitTestResult *result;
1001 result = webkit_web_view_get_hit_test_result(view, (GdkEventButton *)ev);
1002 g_object_get(G_OBJECT(result),
1003 "x", &x, "y", &y,
1004 NULL);
1006 *//* If this button release is end of a drag or selection event
1007 * (button press happened on different coordinates), we do not
1008 * want to open the link. *//*
1009 if ((x != viewer->click_x || y != viewer->click_y))
1010 return FALSE;
1012 open_uri(viewer->cur_link, prefs_common_get_uri_cmd());
1013 return TRUE;
1015 return FALSE;
1018 static gboolean press_button_cb (WebKitWebView *view, GdkEvent *ev,
1019 FancyViewer *viewer)
1021 gint type = 0;
1022 gchar *link = NULL;
1024 WebKitHitTestResult *result =
1025 webkit_web_view_get_hit_test_result(view, (GdkEventButton *)ev);
1027 g_object_get(G_OBJECT(result),
1028 "context", &type,
1029 "x", &viewer->click_x,
1030 "y", &viewer->click_y,
1031 "link-uri", &link,
1032 NULL);
1034 if (type & WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION)
1035 return FALSE;
1037 if (viewer->cur_link) {
1038 g_free(viewer->cur_link);
1039 viewer->cur_link = NULL;
1041 if (link != NULL) {
1042 debug_print("press on %s\n", link);
1043 viewer->cur_link = link;i*/ /* g_context returned a newly-allocated string
1046 viewer->doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(viewer->view));
1047 viewer->window = webkit_dom_document_get_default_view (viewer->doc);
1048 viewer->selection = webkit_dom_dom_window_get_selection (viewer->window);
1049 if (viewer->selection != NULL)
1050 webkit_dom_dom_selection_empty(viewer->selection);
1051 return FALSE;
1054 static void zoom_100_cb(GtkWidget *widget, GdkEvent *ev, FancyViewer *viewer)
1056 gtk_widget_grab_focus(widget);
1057 webkit_web_view_set_zoom_level(viewer->view, 1);
1060 static void zoom_in_cb(GtkWidget *widget, GdkEvent *ev, FancyViewer *viewer)
1062 gtk_widget_grab_focus(widget);
1063 fancy_prefs.zoom_level += 10;
1064 gdouble zoom_level;
1065 zoom_level = (double) fancy_prefs.zoom_level / 100;
1066 webkit_web_view_set_zoom_level(viewer->view, zoom_level);
1068 static void zoom_out_cb(GtkWidget *widget, GdkEvent *ev, FancyViewer *viewer)
1070 gdouble zoom_level;
1071 gtk_widget_grab_focus(widget);
1072 fancy_prefs.zoom_level -= 10;
1073 zoom_level = (double) fancy_prefs.zoom_level / 100;
1074 if (fancy_prefs.zoom_level)
1075 webkit_web_view_set_zoom_level(viewer->view, zoom_level);
1078 static void resource_load_failed_cb(WebKitWebView *web_view,
1079 WebKitWebResource *web_resource,
1080 GError *error,
1081 FancyViewer *viewer)
1083 debug_print("Loading error: %s\n", error->message);
1086 static MimeViewer *fancy_viewer_create(void)
1088 FancyViewer *viewer;
1089 GtkWidget *hbox;
1091 debug_print("fancy_viewer_create\n");
1093 viewer = g_new0(FancyViewer, 1);
1094 viewer->mimeviewer.factory = &fancy_viewer_factory;
1095 viewer->mimeviewer.get_widget = fancy_get_widget;
1096 // viewer->mimeviewer.get_selection = fancy_get_selection;
1097 viewer->mimeviewer.show_mimepart = fancy_show_mimepart;
1098 viewer->mimeviewer.print = fancy_print;
1099 viewer->mimeviewer.clear_viewer = fancy_clear_viewer;
1100 viewer->mimeviewer.destroy_viewer = fancy_destroy_viewer;
1101 // viewer->mimeviewer.text_search = fancy_text_search;
1102 viewer->mimeviewer.scroll_page = fancy_scroll_page;
1103 viewer->mimeviewer.scroll_one_line = fancy_scroll_one_line;
1104 viewer->view = WEBKIT_WEB_VIEW(webkit_web_view_new());
1106 /*#ifdef HAVE_LIBSOUP_GNOME
1107 TODO webkit_get_default_session() missing
1108 * enum WebKitNetworkProxySettings
1109 * */
1110 /* Use GNOME proxy settings through libproxy */
1111 /* if (fancy_prefs.enable_gnome_proxy) {
1112 SoupSession *session = webkit_get_default_session();
1113 soup_session_add_feature_by_type (session, SOUP_TYPE_PROXY_RESOLVER_GNOME);
1115 #endif
1117 if (fancy_prefs.enable_proxy) {
1118 SoupSession *session = webkit_get_default_session();
1119 SoupURI* pURI = soup_uri_new(fancy_prefs.proxy_str);
1120 g_object_set(session, "proxy-uri", pURI, NULL);
1123 viewer->settings = webkit_settings_new();
1124 // Proxy "" makes libsoup backend think that there is no way
1125 // to connect, which is ideal.
1126 viewer->no_remote_content_proxy_settings = webkit_network_proxy_settings_new("", NULL);
1127 g_object_set(viewer->settings, "user-agent", "Fancy Viewer", NULL);
1128 viewer->scrollwin = gtk_scrolled_window_new(NULL, NULL);
1129 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(viewer->scrollwin),
1130 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1131 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(viewer->scrollwin),
1132 GTK_SHADOW_IN);
1133 gtk_container_add(GTK_CONTAINER(viewer->scrollwin),
1134 GTK_WIDGET(viewer->view));
1136 viewer->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
1137 gtk_widget_set_name(GTK_WIDGET(viewer->vbox), "fancy_viewer");
1138 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
1139 viewer->progress = gtk_progress_bar_new();
1140 gtk_widget_set_size_request(GTK_WIDGET(viewer->progress), 120, -1);
1141 /* Zoom Widgets */
1142 viewer->zoom_100 = stock_pixmap_widget(STOCK_PIXMAP_ZOOM_FIT);
1143 viewer->zoom_in = stock_pixmap_widget(STOCK_PIXMAP_ZOOM_IN);
1144 viewer->zoom_out = stock_pixmap_widget(STOCK_PIXMAP_ZOOM_OUT);
1145 viewer->stop_loading = stock_pixmap_widget(STOCK_PIXMAP_CANCEL);
1146 /* Event Widgets for the Zoom Widgets */
1147 viewer->ev_zoom_100 = gtk_event_box_new();
1148 viewer->ev_zoom_in = gtk_event_box_new();
1149 viewer->ev_zoom_out = gtk_event_box_new();
1150 viewer->ev_stop_loading = gtk_event_box_new();
1152 /* Link Label */
1153 viewer->l_link = gtk_label_new("");
1154 gtk_label_set_ellipsize(GTK_LABEL(viewer->l_link), PANGO_ELLIPSIZE_END);
1156 /* Preferences Widgets to override preferences on the fly */
1157 viewer->fancy_prefs = stock_pixmap_widget(STOCK_PIXMAP_PREFERENCES);
1158 viewer->ev_fancy_prefs = gtk_event_box_new();
1160 /* Popup Menu for preferences */
1161 viewer->fancy_prefs_menu = gtk_menu_new();
1162 fancy_create_popup_prefs_menu(viewer);
1164 gtk_event_box_set_visible_window(GTK_EVENT_BOX(viewer->ev_zoom_100), FALSE);
1165 gtk_event_box_set_visible_window(GTK_EVENT_BOX(viewer->ev_zoom_in), FALSE);
1166 gtk_event_box_set_visible_window(GTK_EVENT_BOX(viewer->ev_zoom_out), FALSE);
1167 gtk_event_box_set_visible_window(GTK_EVENT_BOX(viewer->ev_fancy_prefs), FALSE);
1168 gtk_event_box_set_visible_window(GTK_EVENT_BOX(viewer->ev_stop_loading), FALSE);
1170 gtk_container_add(GTK_CONTAINER(viewer->ev_zoom_100), viewer->zoom_100);
1171 gtk_container_add(GTK_CONTAINER(viewer->ev_zoom_in), viewer->zoom_in);
1172 gtk_container_add(GTK_CONTAINER(viewer->ev_zoom_out), viewer->zoom_out);
1173 gtk_container_add(GTK_CONTAINER(viewer->ev_fancy_prefs), viewer->fancy_prefs);
1174 gtk_container_add(GTK_CONTAINER(viewer->ev_stop_loading), viewer->stop_loading);
1176 gtk_box_pack_start(GTK_BOX(hbox), viewer->ev_zoom_100, FALSE, FALSE, 1);
1177 gtk_box_pack_start(GTK_BOX(hbox), viewer->ev_zoom_in, FALSE, FALSE, 2);
1178 gtk_box_pack_start(GTK_BOX(hbox), viewer->ev_zoom_out, FALSE, FALSE, 2);
1179 gtk_box_pack_start(GTK_BOX(hbox), viewer->ev_fancy_prefs, FALSE, FALSE, 2);
1180 gtk_box_pack_start(GTK_BOX(hbox), viewer->l_link, FALSE, FALSE, 8);
1181 gtk_box_pack_end(GTK_BOX(hbox), viewer->progress, FALSE, FALSE, 0);
1182 gtk_box_pack_end(GTK_BOX(hbox), viewer->ev_stop_loading, FALSE, FALSE, 0);
1184 gtk_box_pack_start(GTK_BOX(viewer->vbox), viewer->scrollwin, TRUE, TRUE,
1186 gtk_box_pack_start(GTK_BOX(viewer->vbox), hbox, FALSE, FALSE, 0);
1188 gtk_widget_show(viewer->ev_zoom_100);
1189 gtk_widget_show(viewer->ev_zoom_in);
1190 gtk_widget_show(viewer->ev_zoom_out);
1191 gtk_widget_show(viewer->ev_fancy_prefs);
1193 gtk_widget_show(viewer->scrollwin);
1194 gtk_widget_show(viewer->zoom_100);
1195 gtk_widget_show(viewer->zoom_in);
1196 gtk_widget_show(viewer->zoom_out);
1197 gtk_widget_show(viewer->fancy_prefs);
1198 gtk_widget_show(viewer->stop_loading);
1200 gtk_widget_show(viewer->l_link);
1201 gtk_widget_show(viewer->vbox);
1202 gtk_widget_show(hbox);
1203 gtk_widget_show(GTK_WIDGET(viewer->view));
1205 g_signal_connect(G_OBJECT(viewer->view), "load-changed",
1206 G_CALLBACK(load_changed_cb), viewer);
1207 g_signal_connect(G_OBJECT(viewer->view), "mouse-target-changed",
1208 G_CALLBACK(mouse_target_changed_cb), viewer);
1210 g_signal_connect(G_OBJECT(viewer->view), "notify::estimated-load-progress",
1211 G_CALLBACK(load_progress_cb), viewer);
1213 g_signal_connect(G_OBJECT(viewer->view), "decide-policy",
1214 G_CALLBACK(navigation_policy_cb), viewer);
1216 g_signal_connect(G_OBJECT(viewer->view), "resource-request-starting",
1217 G_CALLBACK(resource_request_starting_cb), viewer);
1218 g_signal_connect(G_OBJECT(viewer->view), "context-menu",
1219 G_CALLBACK(context_menu_cb), viewer);
1220 /* g_signal_connect(G_OBJECT(viewer->view), "button-press-event",
1221 G_CALLBACK(press_button_cb), viewer);
1222 g_signal_connect(G_OBJECT(viewer->view), "button-release-event",
1223 G_CALLBACK(release_button_cb), viewer);*/
1224 g_signal_connect(G_OBJECT(viewer->ev_zoom_100), "button-press-event",
1225 G_CALLBACK(zoom_100_cb), (gpointer*)viewer);
1226 g_signal_connect(G_OBJECT(viewer->ev_zoom_in), "button-press-event",
1227 G_CALLBACK(zoom_in_cb), (gpointer *)viewer);
1228 g_signal_connect(G_OBJECT(viewer->ev_zoom_out), "button-press-event",
1229 G_CALLBACK(zoom_out_cb), (gpointer *)viewer);
1230 g_signal_connect(G_OBJECT(viewer->ev_fancy_prefs), "button-press-event",
1231 G_CALLBACK(fancy_prefs_cb), (gpointer *)viewer);
1232 g_signal_connect(G_OBJECT(viewer->ev_stop_loading), "button-press-event",
1233 G_CALLBACK(stop_loading_cb), viewer);
1234 g_signal_connect(G_OBJECT(viewer->view), "key_press_event",
1235 G_CALLBACK(keypress_events_cb), viewer);
1237 g_signal_connect(G_OBJECT(viewer->view), "resource-load-failed",
1238 G_CALLBACK(resource_load_failed_cb), viewer);
1240 webkit_web_context_register_uri_scheme(webkit_web_context_get_default(),
1241 "cid", load_content_cb, viewer, NULL);
1243 viewer->filename = NULL;
1244 return (MimeViewer *) viewer;
1247 static gchar *content_types[] = {"text/html", NULL};
1249 static MimeViewerFactory fancy_viewer_factory =
1251 content_types,
1253 fancy_viewer_create,
1256 gint plugin_init(gchar **error)
1258 if (!check_plugin_version(MAKE_NUMERIC_VERSION(3,0,0,0),
1259 VERSION_NUMERIC, _("Fancy"), error))
1260 return -1;
1261 gchar *directory = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
1262 "fancy", NULL);
1263 if (!is_dir_exist(directory))
1264 if (make_dir (directory) < 0) {
1265 g_free(directory);
1266 return -1;
1268 g_free(directory);
1270 fancy_prefs_init();
1272 mimeview_register_viewer_factory(&fancy_viewer_factory);
1274 return 0;
1277 gboolean plugin_done(void)
1279 mimeview_unregister_viewer_factory(&fancy_viewer_factory);
1280 fancy_prefs_done();
1281 return FALSE;
1284 const gchar *plugin_name(void)
1286 /* TRANSLATORS: 'Fancy' here is name of the plugin, not the english word. */
1287 return _("Fancy HTML Viewer");
1290 const gchar *plugin_desc(void)
1292 return g_strdup_printf(_("This plugin renders HTML mail using the WebKit "
1293 "%d.%d.%d library.\nBy default all remote content is "
1294 "blocked. Options "
1295 "can be found in /Configuration/Preferences/Plugins/Fancy"),
1296 WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION,
1297 WEBKIT_MICRO_VERSION);
1300 const gchar *plugin_type(void)
1302 return "GTK3";
1305 const gchar *plugin_licence(void)
1307 return "GPL3";
1310 const gchar *plugin_version(void)
1312 return VERSION;
1315 struct PluginFeature *plugin_provides(void)
1317 static struct PluginFeature features[] = {
1318 {PLUGIN_MIMEVIEWER, "text/html"},
1319 {PLUGIN_NOTHING, NULL}
1321 return features;