diff options
Diffstat (limited to 'widgets/misc/e-web-view-gtkhtml.c')
-rw-r--r-- | widgets/misc/e-web-view-gtkhtml.c | 2318 |
1 files changed, 0 insertions, 2318 deletions
diff --git a/widgets/misc/e-web-view-gtkhtml.c b/widgets/misc/e-web-view-gtkhtml.c deleted file mode 100644 index fddbd9ee90..0000000000 --- a/widgets/misc/e-web-view-gtkhtml.c +++ /dev/null @@ -1,2318 +0,0 @@ -/* - * e-web-view-gtkhtml.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-web-view-gtkhtml.h" - -#include <string.h> -#include <glib/gi18n-lib.h> - -#include <camel/camel.h> -#include <libebackend/libebackend.h> - -#include <e-util/e-util.h> -#include <e-util/e-plugin-ui.h> -#include <libevolution-utils/e-alert-dialog.h> -#include <libevolution-utils/e-alert-sink.h> - -#include "e-popup-action.h" -#include "e-selectable.h" - -#define E_WEB_VIEW_GTKHTML_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_WEB_VIEW_GTKHTML, EWebViewGtkHTMLPrivate)) - -typedef struct _EWebViewGtkHTMLRequest EWebViewGtkHTMLRequest; - -struct _EWebViewGtkHTMLPrivate { - GList *requests; - GtkUIManager *ui_manager; - gchar *selected_uri; - GdkPixbufAnimation *cursor_image; - - GtkAction *open_proxy; - GtkAction *print_proxy; - GtkAction *save_as_proxy; - - GtkTargetList *copy_target_list; - GtkTargetList *paste_target_list; - - /* Lockdown Options */ - guint disable_printing : 1; - guint disable_save_to_disk : 1; -}; - -struct _EWebViewGtkHTMLRequest { - GFile *file; - EWebViewGtkHTML *web_view; - GCancellable *cancellable; - GInputStream *input_stream; - GtkHTMLStream *output_stream; - gchar buffer[4096]; -}; - -enum { - PROP_0, - PROP_ANIMATE, - PROP_CARET_MODE, - PROP_COPY_TARGET_LIST, - PROP_DISABLE_PRINTING, - PROP_DISABLE_SAVE_TO_DISK, - PROP_EDITABLE, - PROP_INLINE_SPELLING, - PROP_MAGIC_LINKS, - PROP_MAGIC_SMILEYS, - PROP_OPEN_PROXY, - PROP_PASTE_TARGET_LIST, - PROP_PRINT_PROXY, - PROP_SAVE_AS_PROXY, - PROP_SELECTED_URI, - PROP_CURSOR_IMAGE -}; - -enum { - COPY_CLIPBOARD, - CUT_CLIPBOARD, - PASTE_CLIPBOARD, - POPUP_EVENT, - STATUS_MESSAGE, - STOP_LOADING, - UPDATE_ACTIONS, - PROCESS_MAILTO, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -static const gchar *ui = -"<ui>" -" <popup name='context'>" -" <menuitem action='copy-clipboard'/>" -" <separator/>" -" <placeholder name='custom-actions-1'>" -" <menuitem action='open'/>" -" <menuitem action='save-as'/>" -" <menuitem action='http-open'/>" -" <menuitem action='send-message'/>" -" <menuitem action='print'/>" -" </placeholder>" -" <placeholder name='custom-actions-2'>" -" <menuitem action='uri-copy'/>" -" <menuitem action='mailto-copy'/>" -" <menuitem action='image-copy'/>" -" </placeholder>" -" <placeholder name='custom-actions-3'/>" -" <separator/>" -" <menuitem action='select-all'/>" -" </popup>" -"</ui>"; - -/* Forward Declarations */ -static void e_web_view_gtkhtml_alert_sink_init (EAlertSinkInterface *interface); -static void e_web_view_gtkhtml_selectable_init (ESelectableInterface *interface); - -G_DEFINE_TYPE_WITH_CODE ( - EWebViewGtkHTML, - e_web_view_gtkhtml, - GTK_TYPE_HTML, - G_IMPLEMENT_INTERFACE ( - E_TYPE_EXTENSIBLE, NULL) - G_IMPLEMENT_INTERFACE ( - E_TYPE_ALERT_SINK, - e_web_view_gtkhtml_alert_sink_init) - G_IMPLEMENT_INTERFACE ( - E_TYPE_SELECTABLE, - e_web_view_gtkhtml_selectable_init)) - -static EWebViewGtkHTMLRequest * -web_view_gtkhtml_request_new (EWebViewGtkHTML *web_view, - const gchar *uri, - GtkHTMLStream *stream) -{ - EWebViewGtkHTMLRequest *request; - GList *list; - - request = g_slice_new (EWebViewGtkHTMLRequest); - - /* Try to detect file paths posing as URIs. */ - if (*uri == '/') - request->file = g_file_new_for_path (uri); - else - request->file = g_file_new_for_uri (uri); - - request->web_view = g_object_ref (web_view); - request->cancellable = g_cancellable_new (); - request->input_stream = NULL; - request->output_stream = stream; - - list = request->web_view->priv->requests; - list = g_list_prepend (list, request); - request->web_view->priv->requests = list; - - return request; -} - -static void -web_view_gtkhtml_request_free (EWebViewGtkHTMLRequest *request) -{ - GList *list; - - list = request->web_view->priv->requests; - list = g_list_remove (list, request); - request->web_view->priv->requests = list; - - g_object_unref (request->file); - g_object_unref (request->web_view); - g_object_unref (request->cancellable); - - if (request->input_stream != NULL) - g_object_unref (request->input_stream); - - g_slice_free (EWebViewGtkHTMLRequest, request); -} - -static void -web_view_gtkhtml_request_cancel (EWebViewGtkHTMLRequest *request) -{ - g_cancellable_cancel (request->cancellable); -} - -static gboolean -web_view_gtkhtml_request_check_for_error (EWebViewGtkHTMLRequest *request, - GError *error) -{ - GtkHTML *html; - GtkHTMLStream *stream; - - if (error == NULL) - return FALSE; - - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) { - /* use this error, but do not close the stream */ - g_error_free (error); - return TRUE; - } - - /* XXX Should we log errors that are not cancellations? */ - - html = GTK_HTML (request->web_view); - stream = request->output_stream; - - gtk_html_end (html, stream, GTK_HTML_STREAM_ERROR); - web_view_gtkhtml_request_free (request); - g_error_free (error); - - return TRUE; -} - -static void -web_view_gtkhtml_request_stream_read_cb (GInputStream *input_stream, - GAsyncResult *result, - EWebViewGtkHTMLRequest *request) -{ - gssize bytes_read; - GError *error = NULL; - - bytes_read = g_input_stream_read_finish (input_stream, result, &error); - - if (web_view_gtkhtml_request_check_for_error (request, error)) - return; - - if (bytes_read == 0) { - gtk_html_end ( - GTK_HTML (request->web_view), - request->output_stream, GTK_HTML_STREAM_OK); - web_view_gtkhtml_request_free (request); - return; - } - - gtk_html_write ( - GTK_HTML (request->web_view), - request->output_stream, request->buffer, bytes_read); - - g_input_stream_read_async ( - request->input_stream, request->buffer, - sizeof (request->buffer), G_PRIORITY_DEFAULT, - request->cancellable, (GAsyncReadyCallback) - web_view_gtkhtml_request_stream_read_cb, request); -} - -static void -web_view_gtkhtml_request_read_cb (GFile *file, - GAsyncResult *result, - EWebViewGtkHTMLRequest *request) -{ - GFileInputStream *input_stream; - GError *error = NULL; - - /* Input stream might be NULL, so don't use cast macro. */ - input_stream = g_file_read_finish (file, result, &error); - request->input_stream = (GInputStream *) input_stream; - - if (web_view_gtkhtml_request_check_for_error (request, error)) - return; - - g_input_stream_read_async ( - request->input_stream, request->buffer, - sizeof (request->buffer), G_PRIORITY_DEFAULT, - request->cancellable, (GAsyncReadyCallback) - web_view_gtkhtml_request_stream_read_cb, request); -} - -static void -action_copy_clipboard_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - e_web_view_gtkhtml_copy_clipboard (web_view); -} - -static void -action_http_open_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - const gchar *uri; - gpointer parent; - - parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - uri = e_web_view_gtkhtml_get_selected_uri (web_view); - g_return_if_fail (uri != NULL); - - e_show_uri (parent, uri); -} - -static void -action_mailto_copy_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - CamelURL *curl; - CamelInternetAddress *inet_addr; - GtkClipboard *clipboard; - const gchar *uri; - gchar *text; - - uri = e_web_view_gtkhtml_get_selected_uri (web_view); - g_return_if_fail (uri != NULL); - - /* This should work because we checked it in update_actions(). */ - curl = camel_url_new (uri, NULL); - g_return_if_fail (curl != NULL); - - inet_addr = camel_internet_address_new (); - camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path); - text = camel_address_format (CAMEL_ADDRESS (inet_addr)); - if (text == NULL || *text == '\0') - text = g_strdup (uri + strlen ("mailto:")); - - g_object_unref (inet_addr); - camel_url_free (curl); - - clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY); - gtk_clipboard_set_text (clipboard, text, -1); - gtk_clipboard_store (clipboard); - - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); - gtk_clipboard_set_text (clipboard, text, -1); - gtk_clipboard_store (clipboard); - - g_free (text); -} - -static void -action_select_all_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - e_web_view_gtkhtml_select_all (web_view); -} - -static void -action_send_message_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - const gchar *uri; - gpointer parent; - gboolean handled; - - parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - uri = e_web_view_gtkhtml_get_selected_uri (web_view); - g_return_if_fail (uri != NULL); - - handled = FALSE; - g_signal_emit (web_view, signals[PROCESS_MAILTO], 0, uri, &handled); - - if (!handled) - e_show_uri (parent, uri); -} - -static void -action_uri_copy_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - GtkClipboard *clipboard; - const gchar *uri; - - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); - uri = e_web_view_gtkhtml_get_selected_uri (web_view); - g_return_if_fail (uri != NULL); - - gtk_clipboard_set_text (clipboard, uri, -1); - gtk_clipboard_store (clipboard); -} - -static void -action_image_copy_cb (GtkAction *action, - EWebViewGtkHTML *web_view) -{ - GtkClipboard *clipboard; - GdkPixbufAnimation *animation; - GdkPixbuf *pixbuf; - - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); - animation = e_web_view_gtkhtml_get_cursor_image (web_view); - g_return_if_fail (animation != NULL); - - pixbuf = gdk_pixbuf_animation_get_static_image (animation); - if (!pixbuf) - return; - - gtk_clipboard_set_image (clipboard, pixbuf); - gtk_clipboard_store (clipboard); -} - -static GtkActionEntry uri_entries[] = { - - { "uri-copy", - GTK_STOCK_COPY, - N_("_Copy Link Location"), - NULL, - N_("Copy the link to the clipboard"), - G_CALLBACK (action_uri_copy_cb) } -}; - -static GtkActionEntry http_entries[] = { - - { "http-open", - "emblem-web", - N_("_Open Link in Browser"), - NULL, - N_("Open the link in a web browser"), - G_CALLBACK (action_http_open_cb) } -}; - -static GtkActionEntry mailto_entries[] = { - - { "mailto-copy", - GTK_STOCK_COPY, - N_("_Copy Email Address"), - NULL, - N_("Copy the email address to the clipboard"), - G_CALLBACK (action_mailto_copy_cb) }, - - { "send-message", - "mail-message-new", - N_("_Send New Message To..."), - NULL, - N_("Send a mail message to this address"), - G_CALLBACK (action_send_message_cb) } -}; - -static GtkActionEntry image_entries[] = { - - { "image-copy", - GTK_STOCK_COPY, - N_("_Copy Image"), - NULL, - N_("Copy the image to the clipboard"), - G_CALLBACK (action_image_copy_cb) } -}; - -static GtkActionEntry selection_entries[] = { - - { "copy-clipboard", - GTK_STOCK_COPY, - NULL, - NULL, - N_("Copy the selection"), - G_CALLBACK (action_copy_clipboard_cb) }, -}; - -static GtkActionEntry standard_entries[] = { - - { "select-all", - GTK_STOCK_SELECT_ALL, - NULL, - NULL, - N_("Select all text and images"), - G_CALLBACK (action_select_all_cb) } -}; - -static gboolean -web_view_gtkhtml_button_press_event_cb (EWebViewGtkHTML *web_view, - GdkEventButton *event, - GtkHTML *frame) -{ - gboolean event_handled = FALSE; - gchar *uri = NULL; - - if (event) { - GdkPixbufAnimation *anim; - - if (frame == NULL) - frame = GTK_HTML (web_view); - - anim = gtk_html_get_image_at (frame, event->x, event->y); - e_web_view_gtkhtml_set_cursor_image (web_view, anim); - if (anim != NULL) - g_object_unref (anim); - } - - if (event != NULL && event->button != 3) - return FALSE; - - /* Only extract a URI if no selection is active. Selected text - * implies the user is more likely to want to copy the selection - * to the clipboard than open a link within the selection. */ - if (!e_web_view_gtkhtml_is_selection_active (web_view)) - uri = e_web_view_gtkhtml_extract_uri (web_view, event, frame); - - if (uri != NULL && g_str_has_prefix (uri, "##")) { - g_free (uri); - return FALSE; - } - - g_signal_emit ( - web_view, signals[POPUP_EVENT], 0, - event, uri, &event_handled); - - g_free (uri); - - return event_handled; -} - -static void -web_view_gtkhtml_menu_item_select_cb (EWebViewGtkHTML *web_view, - GtkWidget *widget) -{ - GtkAction *action; - GtkActivatable *activatable; - const gchar *tooltip; - - activatable = GTK_ACTIVATABLE (widget); - action = gtk_activatable_get_related_action (activatable); - tooltip = gtk_action_get_tooltip (action); - - if (tooltip == NULL) - return; - - e_web_view_gtkhtml_status_message (web_view, tooltip); -} - -static void -web_view_gtkhtml_menu_item_deselect_cb (EWebViewGtkHTML *web_view) -{ - e_web_view_gtkhtml_status_message (web_view, NULL); -} - -static void -web_view_gtkhtml_connect_proxy_cb (EWebViewGtkHTML *web_view, - GtkAction *action, - GtkWidget *proxy) -{ - if (!GTK_IS_MENU_ITEM (proxy)) - return; - - g_signal_connect_swapped ( - proxy, "select", - G_CALLBACK (web_view_gtkhtml_menu_item_select_cb), web_view); - - g_signal_connect_swapped ( - proxy, "deselect", - G_CALLBACK (web_view_gtkhtml_menu_item_deselect_cb), web_view); -} - -static void -web_view_gtkhtml_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ANIMATE: - e_web_view_gtkhtml_set_animate ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_CARET_MODE: - e_web_view_gtkhtml_set_caret_mode ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_DISABLE_PRINTING: - e_web_view_gtkhtml_set_disable_printing ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_DISABLE_SAVE_TO_DISK: - e_web_view_gtkhtml_set_disable_save_to_disk ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_EDITABLE: - e_web_view_gtkhtml_set_editable ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_INLINE_SPELLING: - e_web_view_gtkhtml_set_inline_spelling ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_MAGIC_LINKS: - e_web_view_gtkhtml_set_magic_links ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_MAGIC_SMILEYS: - e_web_view_gtkhtml_set_magic_smileys ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_boolean (value)); - return; - - case PROP_OPEN_PROXY: - e_web_view_gtkhtml_set_open_proxy ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_object (value)); - return; - - case PROP_PRINT_PROXY: - e_web_view_gtkhtml_set_print_proxy ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_object (value)); - return; - - case PROP_SAVE_AS_PROXY: - e_web_view_gtkhtml_set_save_as_proxy ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_object (value)); - return; - - case PROP_SELECTED_URI: - e_web_view_gtkhtml_set_selected_uri ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_string (value)); - return; - case PROP_CURSOR_IMAGE: - e_web_view_gtkhtml_set_cursor_image ( - E_WEB_VIEW_GTKHTML (object), - g_value_get_object (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -web_view_gtkhtml_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_ANIMATE: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_animate ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_CARET_MODE: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_caret_mode ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_COPY_TARGET_LIST: - g_value_set_boxed ( - value, e_web_view_gtkhtml_get_copy_target_list ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_DISABLE_PRINTING: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_disable_printing ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_DISABLE_SAVE_TO_DISK: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_disable_save_to_disk ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_EDITABLE: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_editable ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_INLINE_SPELLING: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_inline_spelling ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_MAGIC_LINKS: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_magic_links ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_MAGIC_SMILEYS: - g_value_set_boolean ( - value, e_web_view_gtkhtml_get_magic_smileys ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_OPEN_PROXY: - g_value_set_object ( - value, e_web_view_gtkhtml_get_open_proxy ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_PASTE_TARGET_LIST: - g_value_set_boxed ( - value, e_web_view_gtkhtml_get_paste_target_list ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_PRINT_PROXY: - g_value_set_object ( - value, e_web_view_gtkhtml_get_print_proxy ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_SAVE_AS_PROXY: - g_value_set_object ( - value, e_web_view_gtkhtml_get_save_as_proxy ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_SELECTED_URI: - g_value_set_string ( - value, e_web_view_gtkhtml_get_selected_uri ( - E_WEB_VIEW_GTKHTML (object))); - return; - - case PROP_CURSOR_IMAGE: - g_value_set_object ( - value, e_web_view_gtkhtml_get_cursor_image ( - E_WEB_VIEW_GTKHTML (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -web_view_gtkhtml_dispose (GObject *object) -{ - EWebViewGtkHTMLPrivate *priv; - - priv = E_WEB_VIEW_GTKHTML_GET_PRIVATE (object); - - if (priv->ui_manager != NULL) { - g_object_unref (priv->ui_manager); - priv->ui_manager = NULL; - } - - if (priv->open_proxy != NULL) { - g_object_unref (priv->open_proxy); - priv->open_proxy = NULL; - } - - if (priv->print_proxy != NULL) { - g_object_unref (priv->print_proxy); - priv->print_proxy = NULL; - } - - if (priv->save_as_proxy != NULL) { - g_object_unref (priv->save_as_proxy); - priv->save_as_proxy = NULL; - } - - if (priv->copy_target_list != NULL) { - gtk_target_list_unref (priv->copy_target_list); - priv->copy_target_list = NULL; - } - - if (priv->paste_target_list != NULL) { - gtk_target_list_unref (priv->paste_target_list); - priv->paste_target_list = NULL; - } - - if (priv->cursor_image != NULL) { - g_object_unref (priv->cursor_image); - priv->cursor_image = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_web_view_gtkhtml_parent_class)->dispose (object); -} - -static void -web_view_gtkhtml_finalize (GObject *object) -{ - EWebViewGtkHTMLPrivate *priv; - - priv = E_WEB_VIEW_GTKHTML_GET_PRIVATE (object); - - /* All URI requests should be complete or cancelled by now. */ - if (priv->requests != NULL) - g_warning ("Finalizing EWebViewGtkHTML with active URI requests"); - - g_free (priv->selected_uri); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_web_view_gtkhtml_parent_class)->finalize (object); -} - -static void -web_view_gtkhtml_constructed (GObject *object) -{ -#ifndef G_OS_WIN32 - GSettings *settings; - - settings = g_settings_new ("org.gnome.desktop.lockdown"); - - g_settings_bind ( - settings, "disable-printing", - object, "disable-printing", - G_SETTINGS_BIND_GET); - - g_settings_bind ( - settings, "disable-save-to-disk", - object, "disable-save-to-disk", - G_SETTINGS_BIND_GET); - - g_object_unref (settings); -#endif - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_web_view_gtkhtml_parent_class)->constructed (object); -} - -static gboolean -web_view_gtkhtml_button_press_event (GtkWidget *widget, - GdkEventButton *event) -{ - GtkWidgetClass *widget_class; - EWebViewGtkHTML *web_view; - - web_view = E_WEB_VIEW_GTKHTML (widget); - - if (web_view_gtkhtml_button_press_event_cb (web_view, event, NULL)) - return TRUE; - - /* Chain up to parent's button_press_event() method. */ - widget_class = GTK_WIDGET_CLASS (e_web_view_gtkhtml_parent_class); - return widget_class->button_press_event (widget, event); -} - -static gboolean -web_view_gtkhtml_scroll_event (GtkWidget *widget, - GdkEventScroll *event) -{ - if (event->state & GDK_CONTROL_MASK) { - GdkScrollDirection direction = event->direction; - - #if GTK_CHECK_VERSION(3,3,18) - if (direction == GDK_SCROLL_SMOOTH) { - static gdouble total_delta_y = 0.0; - - total_delta_y += event->delta_y; - - if (total_delta_y >= 1.0) { - total_delta_y = 0.0; - direction = GDK_SCROLL_DOWN; - } else if (total_delta_y <= -1.0) { - total_delta_y = 0.0; - direction = GDK_SCROLL_UP; - } else { - return FALSE; - } - } - #endif - - switch (direction) { - case GDK_SCROLL_UP: - gtk_html_zoom_in (GTK_HTML (widget)); - return TRUE; - case GDK_SCROLL_DOWN: - gtk_html_zoom_out (GTK_HTML (widget)); - return TRUE; - default: - break; - } - } - - return FALSE; -} - -static void -web_view_gtkhtml_url_requested (GtkHTML *html, - const gchar *uri, - GtkHTMLStream *stream) -{ - EWebViewGtkHTMLRequest *request; - - request = web_view_gtkhtml_request_new (E_WEB_VIEW_GTKHTML (html), uri, stream); - - g_file_read_async ( - request->file, G_PRIORITY_DEFAULT, - request->cancellable, (GAsyncReadyCallback) - web_view_gtkhtml_request_read_cb, request); -} - -static void -web_view_gtkhtml_gtkhtml_link_clicked (GtkHTML *html, - const gchar *uri) -{ - EWebViewGtkHTMLClass *class; - EWebViewGtkHTML *web_view; - - web_view = E_WEB_VIEW_GTKHTML (html); - - class = E_WEB_VIEW_GTKHTML_GET_CLASS (web_view); - g_return_if_fail (class->link_clicked != NULL); - - class->link_clicked (web_view, uri); -} - -static void -web_view_gtkhtml_on_url (GtkHTML *html, - const gchar *uri) -{ - EWebViewGtkHTMLClass *class; - EWebViewGtkHTML *web_view; - - web_view = E_WEB_VIEW_GTKHTML (html); - - class = E_WEB_VIEW_GTKHTML_GET_CLASS (web_view); - g_return_if_fail (class->hovering_over_link != NULL); - - /* XXX WebKit would supply a title here. */ - class->hovering_over_link (web_view, NULL, uri); -} - -static void -web_view_gtkhtml_iframe_created (GtkHTML *html, - GtkHTML *iframe) -{ - g_signal_connect_swapped ( - iframe, "button-press-event", - G_CALLBACK (web_view_gtkhtml_button_press_event_cb), html); -} - -static gchar * -web_view_gtkhtml_extract_uri (EWebViewGtkHTML *web_view, - GdkEventButton *event, - GtkHTML *html) -{ - gchar *uri; - - if (event != NULL) - uri = gtk_html_get_url_at (html, event->x, event->y); - else - uri = gtk_html_get_cursor_url (html); - - return uri; -} - -static void -web_view_gtkhtml_hovering_over_link (EWebViewGtkHTML *web_view, - const gchar *title, - const gchar *uri) -{ - CamelInternetAddress *address; - CamelURL *curl; - const gchar *format = NULL; - gchar *message = NULL; - gchar *who; - - if (uri == NULL || *uri == '\0') - goto exit; - - if (g_str_has_prefix (uri, "mailto:")) - format = _("Click to mail %s"); - else if (g_str_has_prefix (uri, "callto:")) - format = _("Click to call %s"); - else if (g_str_has_prefix (uri, "h323:")) - format = _("Click to call %s"); - else if (g_str_has_prefix (uri, "sip:")) - format = _("Click to call %s"); - else if (g_str_has_prefix (uri, "##")) - message = g_strdup (_("Click to hide/unhide addresses")); - else - message = g_strdup_printf (_("Click to open %s"), uri); - - if (format == NULL) - goto exit; - - /* XXX Use something other than Camel here. Surely - * there's other APIs around that can do this. */ - curl = camel_url_new (uri, NULL); - address = camel_internet_address_new (); - camel_address_decode (CAMEL_ADDRESS (address), curl->path); - who = camel_address_format (CAMEL_ADDRESS (address)); - g_object_unref (address); - camel_url_free (curl); - - if (who == NULL) - who = g_strdup (strchr (uri, ':') + 1); - - message = g_strdup_printf (format, who); - - g_free (who); - -exit: - e_web_view_gtkhtml_status_message (web_view, message); - - g_free (message); -} - -static void -web_view_gtkhtml_link_clicked (EWebViewGtkHTML *web_view, - const gchar *uri) -{ - gpointer parent; - - parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - e_show_uri (parent, uri); -} - -static void -web_view_gtkhtml_load_string (EWebViewGtkHTML *web_view, - const gchar *string) -{ - if (string != NULL && *string != '\0') - gtk_html_load_from_string (GTK_HTML (web_view), string, -1); - else - e_web_view_gtkhtml_clear (web_view); -} - -static void -web_view_gtkhtml_copy_clipboard (EWebViewGtkHTML *web_view) -{ - gtk_html_command (GTK_HTML (web_view), "copy"); -} - -static void -web_view_gtkhtml_cut_clipboard (EWebViewGtkHTML *web_view) -{ - if (e_web_view_gtkhtml_get_editable (web_view)) - gtk_html_command (GTK_HTML (web_view), "cut"); -} - -static void -web_view_gtkhtml_paste_clipboard (EWebViewGtkHTML *web_view) -{ - if (e_web_view_gtkhtml_get_editable (web_view)) - gtk_html_command (GTK_HTML (web_view), "paste"); -} - -static gboolean -web_view_gtkhtml_popup_event (EWebViewGtkHTML *web_view, - GdkEventButton *event, - const gchar *uri) -{ - e_web_view_gtkhtml_set_selected_uri (web_view, uri); - e_web_view_gtkhtml_show_popup_menu (web_view, event, NULL, NULL); - - return TRUE; -} - -static void -web_view_gtkhtml_stop_loading (EWebViewGtkHTML *web_view) -{ - g_list_foreach ( - web_view->priv->requests, (GFunc) - web_view_gtkhtml_request_cancel, NULL); - - gtk_html_stop (GTK_HTML (web_view)); -} - -static void -web_view_gtkhtml_update_actions (EWebViewGtkHTML *web_view) -{ - GtkActionGroup *action_group; - gboolean have_selection; - gboolean scheme_is_http = FALSE; - gboolean scheme_is_mailto = FALSE; - gboolean uri_is_valid = FALSE; - gboolean has_cursor_image; - gboolean visible; - const gchar *group_name; - const gchar *uri; - - uri = e_web_view_gtkhtml_get_selected_uri (web_view); - have_selection = e_web_view_gtkhtml_is_selection_active (web_view); - has_cursor_image = e_web_view_gtkhtml_get_cursor_image (web_view) != NULL; - - /* Parse the URI early so we know if the actions will work. */ - if (uri != NULL) { - CamelURL *curl; - - curl = camel_url_new (uri, NULL); - uri_is_valid = (curl != NULL); - camel_url_free (curl); - - scheme_is_http = - (g_ascii_strncasecmp (uri, "http:", 5) == 0) || - (g_ascii_strncasecmp (uri, "https:", 6) == 0); - - scheme_is_mailto = - (g_ascii_strncasecmp (uri, "mailto:", 7) == 0); - } - - /* Allow copying the URI even if it's malformed. */ - group_name = "uri"; - visible = (uri != NULL) && !scheme_is_mailto; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "http"; - visible = uri_is_valid && scheme_is_http; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "mailto"; - visible = uri_is_valid && scheme_is_mailto; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "image"; - visible = has_cursor_image; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "selection"; - visible = have_selection; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "standard"; - visible = (uri == NULL); - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "lockdown-printing"; - visible = (uri == NULL) && !web_view->priv->disable_printing; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); - - group_name = "lockdown-save-to-disk"; - visible = (uri == NULL) && !web_view->priv->disable_save_to_disk; - action_group = e_web_view_gtkhtml_get_action_group (web_view, group_name); - gtk_action_group_set_visible (action_group, visible); -} - -static void -web_view_gtkhtml_submit_alert (EAlertSink *alert_sink, - EAlert *alert) -{ - GtkIconInfo *icon_info; - EWebViewGtkHTML *web_view; - GtkWidget *dialog; - GString *buffer; - const gchar *icon_name = NULL; - const gchar *filename; - gpointer parent; - gchar *icon_uri; - gint size = 0; - GError *error = NULL; - - web_view = E_WEB_VIEW_GTKHTML (alert_sink); - - parent = gtk_widget_get_toplevel (GTK_WIDGET (web_view)); - parent = gtk_widget_is_toplevel (parent) ? parent : NULL; - - /* We use equivalent named icons instead of stock IDs, - * since it's easier to get the filename of the icon. */ - switch (e_alert_get_message_type (alert)) { - case GTK_MESSAGE_INFO: - icon_name = "dialog-information"; - break; - - case GTK_MESSAGE_WARNING: - icon_name = "dialog-warning"; - break; - - case GTK_MESSAGE_ERROR: - icon_name = "dialog-error"; - break; - - default: - dialog = e_alert_dialog_new (parent, alert); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - return; - } - - gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &size, NULL); - - icon_info = gtk_icon_theme_lookup_icon ( - gtk_icon_theme_get_default (), - icon_name, size, GTK_ICON_LOOKUP_NO_SVG); - g_return_if_fail (icon_info != NULL); - - filename = gtk_icon_info_get_filename (icon_info); - icon_uri = g_filename_to_uri (filename, NULL, &error); - - if (error != NULL) { - g_warning ("%s", error->message); - g_clear_error (&error); - } - - buffer = g_string_sized_new (512); - - g_string_append ( - buffer, - "<html>" - "<head>" - "<meta http-equiv=\"content-type\"" - " content=\"text/html; charset=utf-8\">" - "</head>" - "<body>"); - - g_string_append ( - buffer, - "<table bgcolor='#000000' width='100%'" - " cellpadding='1' cellspacing='0'>" - "<tr>" - "<td>" - "<table bgcolor='#dddddd' width='100%' cellpadding='6'>" - "<tr>"); - - g_string_append_printf ( - buffer, - "<tr>" - "<td valign='top'>" - "<img src='%s'/>" - "</td>" - "<td align='left' width='100%%'>" - "<h3>%s</h3>" - "%s" - "</td>" - "</tr>", - icon_uri, - e_alert_get_primary_text (alert), - e_alert_get_secondary_text (alert)); - - g_string_append ( - buffer, - "</table>" - "</td>" - "</tr>" - "</table>" - "</body>" - "</html>"); - - e_web_view_gtkhtml_load_string (web_view, buffer->str); - - g_string_free (buffer, TRUE); - - gtk_icon_info_free (icon_info); - g_free (icon_uri); -} - -static void -web_view_gtkhtml_selectable_update_actions (ESelectable *selectable, - EFocusTracker *focus_tracker, - GdkAtom *clipboard_targets, - gint n_clipboard_targets) -{ - EWebViewGtkHTML *web_view; - GtkAction *action; - /*GtkTargetList *target_list;*/ - gboolean can_paste = FALSE; - gboolean editable; - gboolean have_selection; - gboolean sensitive; - const gchar *tooltip; - /*gint ii;*/ - - web_view = E_WEB_VIEW_GTKHTML (selectable); - editable = e_web_view_gtkhtml_get_editable (web_view); - have_selection = e_web_view_gtkhtml_is_selection_active (web_view); - - /* XXX GtkHtml implements its own clipboard instead of using - * GDK_SELECTION_CLIPBOARD, so we don't get notifications - * when the clipboard contents change. The logic below - * is what we would do if GtkHtml worked properly. - * Instead, we need to keep the Paste action sensitive so - * its accelerator overrides GtkHtml's key binding. */ -#if 0 - target_list = e_selectable_get_paste_target_list (selectable); - for (ii = 0; ii < n_clipboard_targets && !can_paste; ii++) - can_paste = gtk_target_list_find ( - target_list, clipboard_targets[ii], NULL); -#endif - can_paste = TRUE; - - action = e_focus_tracker_get_cut_clipboard_action (focus_tracker); - sensitive = editable && have_selection; - tooltip = _("Cut the selection"); - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, tooltip); - - action = e_focus_tracker_get_copy_clipboard_action (focus_tracker); - sensitive = have_selection; - tooltip = _("Copy the selection"); - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, tooltip); - - action = e_focus_tracker_get_paste_clipboard_action (focus_tracker); - sensitive = editable && can_paste; - tooltip = _("Paste the clipboard"); - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, tooltip); - - action = e_focus_tracker_get_select_all_action (focus_tracker); - sensitive = TRUE; - tooltip = _("Select all text and images"); - gtk_action_set_sensitive (action, sensitive); - gtk_action_set_tooltip (action, tooltip); -} - -static void -web_view_gtkhtml_selectable_cut_clipboard (ESelectable *selectable) -{ - e_web_view_gtkhtml_cut_clipboard (E_WEB_VIEW_GTKHTML (selectable)); -} - -static void -web_view_gtkhtml_selectable_copy_clipboard (ESelectable *selectable) -{ - e_web_view_gtkhtml_copy_clipboard (E_WEB_VIEW_GTKHTML (selectable)); -} - -static void -web_view_gtkhtml_selectable_paste_clipboard (ESelectable *selectable) -{ - e_web_view_gtkhtml_paste_clipboard (E_WEB_VIEW_GTKHTML (selectable)); -} - -static void -web_view_gtkhtml_selectable_select_all (ESelectable *selectable) -{ - e_web_view_gtkhtml_select_all (E_WEB_VIEW_GTKHTML (selectable)); -} - -static void -e_web_view_gtkhtml_class_init (EWebViewGtkHTMLClass *class) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkHTMLClass *html_class; - - g_type_class_add_private (class, sizeof (EWebViewGtkHTMLPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = web_view_gtkhtml_set_property; - object_class->get_property = web_view_gtkhtml_get_property; - object_class->dispose = web_view_gtkhtml_dispose; - object_class->finalize = web_view_gtkhtml_finalize; - object_class->constructed = web_view_gtkhtml_constructed; - - widget_class = GTK_WIDGET_CLASS (class); - widget_class->button_press_event = web_view_gtkhtml_button_press_event; - widget_class->scroll_event = web_view_gtkhtml_scroll_event; - - html_class = GTK_HTML_CLASS (class); - html_class->url_requested = web_view_gtkhtml_url_requested; - html_class->link_clicked = web_view_gtkhtml_gtkhtml_link_clicked; - html_class->on_url = web_view_gtkhtml_on_url; - html_class->iframe_created = web_view_gtkhtml_iframe_created; - - class->extract_uri = web_view_gtkhtml_extract_uri; - class->hovering_over_link = web_view_gtkhtml_hovering_over_link; - class->link_clicked = web_view_gtkhtml_link_clicked; - class->load_string = web_view_gtkhtml_load_string; - class->copy_clipboard = web_view_gtkhtml_copy_clipboard; - class->cut_clipboard = web_view_gtkhtml_cut_clipboard; - class->paste_clipboard = web_view_gtkhtml_paste_clipboard; - class->popup_event = web_view_gtkhtml_popup_event; - class->stop_loading = web_view_gtkhtml_stop_loading; - class->update_actions = web_view_gtkhtml_update_actions; - - g_object_class_install_property ( - object_class, - PROP_ANIMATE, - g_param_spec_boolean ( - "animate", - "Animate Images", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_CARET_MODE, - g_param_spec_boolean ( - "caret-mode", - "Caret Mode", - NULL, - FALSE, - G_PARAM_READWRITE)); - - /* Inherited from ESelectableInterface */ - g_object_class_override_property ( - object_class, - PROP_COPY_TARGET_LIST, - "copy-target-list"); - - g_object_class_install_property ( - object_class, - PROP_DISABLE_PRINTING, - g_param_spec_boolean ( - "disable-printing", - "Disable Printing", - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_DISABLE_SAVE_TO_DISK, - g_param_spec_boolean ( - "disable-save-to-disk", - "Disable Save-to-Disk", - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); - - g_object_class_install_property ( - object_class, - PROP_EDITABLE, - g_param_spec_boolean ( - "editable", - "Editable", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_INLINE_SPELLING, - g_param_spec_boolean ( - "inline-spelling", - "Inline Spelling", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MAGIC_LINKS, - g_param_spec_boolean ( - "magic-links", - "Magic Links", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_MAGIC_SMILEYS, - g_param_spec_boolean ( - "magic-smileys", - "Magic Smileys", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_OPEN_PROXY, - g_param_spec_object ( - "open-proxy", - "Open Proxy", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); - - /* Inherited from ESelectableInterface */ - g_object_class_override_property ( - object_class, - PROP_PASTE_TARGET_LIST, - "paste-target-list"); - - g_object_class_install_property ( - object_class, - PROP_PRINT_PROXY, - g_param_spec_object ( - "print-proxy", - "Print Proxy", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SAVE_AS_PROXY, - g_param_spec_object ( - "save-as-proxy", - "Save As Proxy", - NULL, - GTK_TYPE_ACTION, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_SELECTED_URI, - g_param_spec_string ( - "selected-uri", - "Selected URI", - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_CURSOR_IMAGE, - g_param_spec_object ( - "cursor-image", - "Image animation at the mouse cursor", - NULL, - GDK_TYPE_PIXBUF_ANIMATION, - G_PARAM_READWRITE)); - - signals[COPY_CLIPBOARD] = g_signal_new ( - "copy-clipboard", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, copy_clipboard), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[CUT_CLIPBOARD] = g_signal_new ( - "cut-clipboard", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, cut_clipboard), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[PASTE_CLIPBOARD] = g_signal_new ( - "paste-clipboard", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, paste_clipboard), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[POPUP_EVENT] = g_signal_new ( - "popup-event", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, popup_event), - g_signal_accumulator_true_handled, NULL, - e_marshal_BOOLEAN__BOXED_STRING, - G_TYPE_BOOLEAN, 2, - GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_STRING); - - signals[STATUS_MESSAGE] = g_signal_new ( - "status-message", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, status_message), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); - - signals[STOP_LOADING] = g_signal_new ( - "stop-loading", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, stop_loading), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[UPDATE_ACTIONS] = g_signal_new ( - "update-actions", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, update_actions), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /* return TRUE when a signal handler processed the mailto URI */ - signals[PROCESS_MAILTO] = g_signal_new ( - "process-mailto", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EWebViewGtkHTMLClass, process_mailto), - NULL, NULL, - e_marshal_BOOLEAN__STRING, - G_TYPE_BOOLEAN, 1, G_TYPE_STRING); -} - -static void -e_web_view_gtkhtml_alert_sink_init (EAlertSinkInterface *interface) -{ - interface->submit_alert = web_view_gtkhtml_submit_alert; -} - -static void -e_web_view_gtkhtml_selectable_init (ESelectableInterface *interface) -{ - interface->update_actions = web_view_gtkhtml_selectable_update_actions; - interface->cut_clipboard = web_view_gtkhtml_selectable_cut_clipboard; - interface->copy_clipboard = web_view_gtkhtml_selectable_copy_clipboard; - interface->paste_clipboard = web_view_gtkhtml_selectable_paste_clipboard; - interface->select_all = web_view_gtkhtml_selectable_select_all; -} - -static void -e_web_view_gtkhtml_init (EWebViewGtkHTML *web_view) -{ - GtkUIManager *ui_manager; - GtkActionGroup *action_group; - GtkTargetList *target_list; - EPopupAction *popup_action; - const gchar *domain = GETTEXT_PACKAGE; - const gchar *id; - GError *error = NULL; - - web_view->priv = E_WEB_VIEW_GTKHTML_GET_PRIVATE (web_view); - - ui_manager = gtk_ui_manager_new (); - web_view->priv->ui_manager = ui_manager; - - g_signal_connect_swapped ( - ui_manager, "connect-proxy", - G_CALLBACK (web_view_gtkhtml_connect_proxy_cb), web_view); - - target_list = gtk_target_list_new (NULL, 0); - web_view->priv->copy_target_list = target_list; - - target_list = gtk_target_list_new (NULL, 0); - web_view->priv->paste_target_list = target_list; - - action_group = gtk_action_group_new ("uri"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, uri_entries, - G_N_ELEMENTS (uri_entries), web_view); - - action_group = gtk_action_group_new ("http"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, http_entries, - G_N_ELEMENTS (http_entries), web_view); - - action_group = gtk_action_group_new ("mailto"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, mailto_entries, - G_N_ELEMENTS (mailto_entries), web_view); - - action_group = gtk_action_group_new ("image"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, image_entries, - G_N_ELEMENTS (image_entries), web_view); - - action_group = gtk_action_group_new ("selection"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, selection_entries, - G_N_ELEMENTS (selection_entries), web_view); - - action_group = gtk_action_group_new ("standard"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - gtk_action_group_add_actions ( - action_group, standard_entries, - G_N_ELEMENTS (standard_entries), web_view); - - popup_action = e_popup_action_new ("open"); - gtk_action_group_add_action (action_group, GTK_ACTION (popup_action)); - g_object_unref (popup_action); - - g_object_bind_property ( - web_view, "open-proxy", - popup_action, "related-action", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - /* Support lockdown. */ - - action_group = gtk_action_group_new ("lockdown-printing"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - popup_action = e_popup_action_new ("print"); - gtk_action_group_add_action (action_group, GTK_ACTION (popup_action)); - g_object_unref (popup_action); - - g_object_bind_property ( - web_view, "print-proxy", - popup_action, "related-action", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - action_group = gtk_action_group_new ("lockdown-save-to-disk"); - gtk_action_group_set_translation_domain (action_group, domain); - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - g_object_unref (action_group); - - popup_action = e_popup_action_new ("save-as"); - gtk_action_group_add_action (action_group, GTK_ACTION (popup_action)); - g_object_unref (popup_action); - - g_object_bind_property ( - web_view, "save-as-proxy", - popup_action, "related-action", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - - /* Because we are loading from a hard-coded string, there is - * no chance of I/O errors. Failure here implies a malformed - * UI definition. Full stop. */ - gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); - if (error != NULL) - g_error ("%s", error->message); - - id = "org.gnome.evolution.webview"; - e_plugin_ui_register_manager (ui_manager, id, web_view); - e_plugin_ui_enable_manager (ui_manager, id); - - e_extensible_load_extensions (E_EXTENSIBLE (web_view)); -} - -GtkWidget * -e_web_view_gtkhtml_new (void) -{ - return g_object_new (E_TYPE_WEB_VIEW_GTKHTML, NULL); -} - -void -e_web_view_gtkhtml_clear (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_load_empty (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_load_string (EWebViewGtkHTML *web_view, - const gchar *string) -{ - EWebViewGtkHTMLClass *class; - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - class = E_WEB_VIEW_GTKHTML_GET_CLASS (web_view); - g_return_if_fail (class->load_string != NULL); - - class->load_string (web_view, string); -} - -gboolean -e_web_view_gtkhtml_get_animate (EWebViewGtkHTML *web_view) -{ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_animate(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_get_animate (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_set_animate (EWebViewGtkHTML *web_view, - gboolean animate) -{ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_animate() - * so we can get a "notify::animate" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_set_animate (GTK_HTML (web_view), animate); - - g_object_notify (G_OBJECT (web_view), "animate"); -} - -gboolean -e_web_view_gtkhtml_get_caret_mode (EWebViewGtkHTML *web_view) -{ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_caret_mode(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_get_caret_mode (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_set_caret_mode (EWebViewGtkHTML *web_view, - gboolean caret_mode) -{ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_caret_mode() - * so we can get a "notify::caret-mode" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_set_caret_mode (GTK_HTML (web_view), caret_mode); - - g_object_notify (G_OBJECT (web_view), "caret-mode"); -} - -GtkTargetList * -e_web_view_gtkhtml_get_copy_target_list (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - return web_view->priv->copy_target_list; -} - -gboolean -e_web_view_gtkhtml_get_disable_printing (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return web_view->priv->disable_printing; -} - -void -e_web_view_gtkhtml_set_disable_printing (EWebViewGtkHTML *web_view, - gboolean disable_printing) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - web_view->priv->disable_printing = disable_printing; - - g_object_notify (G_OBJECT (web_view), "disable-printing"); -} - -gboolean -e_web_view_gtkhtml_get_disable_save_to_disk (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return web_view->priv->disable_save_to_disk; -} - -void -e_web_view_gtkhtml_set_disable_save_to_disk (EWebViewGtkHTML *web_view, - gboolean disable_save_to_disk) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - web_view->priv->disable_save_to_disk = disable_save_to_disk; - - g_object_notify (G_OBJECT (web_view), "disable-save-to-disk"); -} - -gboolean -e_web_view_gtkhtml_get_editable (EWebViewGtkHTML *web_view) -{ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_editable(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_get_editable (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_set_editable (EWebViewGtkHTML *web_view, - gboolean editable) -{ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_editable() - * so we can get a "notify::editable" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_set_editable (GTK_HTML (web_view), editable); - - g_object_notify (G_OBJECT (web_view), "editable"); -} - -gboolean -e_web_view_gtkhtml_get_inline_spelling (EWebViewGtkHTML *web_view) -{ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_inline_spelling(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_get_inline_spelling (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_set_inline_spelling (EWebViewGtkHTML *web_view, - gboolean inline_spelling) -{ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_inline_spelling() - * so we get a "notify::inline-spelling" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_set_inline_spelling (GTK_HTML (web_view), inline_spelling); - - g_object_notify (G_OBJECT (web_view), "inline-spelling"); -} - -gboolean -e_web_view_gtkhtml_get_magic_links (EWebViewGtkHTML *web_view) -{ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_magic_links(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_get_magic_links (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_set_magic_links (EWebViewGtkHTML *web_view, - gboolean magic_links) -{ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_magic_links() - * so we can get a "notify::magic-links" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_set_magic_links (GTK_HTML (web_view), magic_links); - - g_object_notify (G_OBJECT (web_view), "magic-links"); -} - -gboolean -e_web_view_gtkhtml_get_magic_smileys (EWebViewGtkHTML *web_view) -{ - /* XXX This is just here to maintain symmetry - * with e_web_view_set_magic_smileys(). */ - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_get_magic_smileys (GTK_HTML (web_view)); -} - -void -e_web_view_gtkhtml_set_magic_smileys (EWebViewGtkHTML *web_view, - gboolean magic_smileys) -{ - /* XXX GtkHTML does not utilize GObject properties as well - * as it could. This just wraps gtk_html_set_magic_smileys() - * so we can get a "notify::magic-smileys" signal. */ - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_set_magic_smileys (GTK_HTML (web_view), magic_smileys); - - g_object_notify (G_OBJECT (web_view), "magic-smileys"); -} - -const gchar * -e_web_view_gtkhtml_get_selected_uri (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - return web_view->priv->selected_uri; -} - -void -e_web_view_gtkhtml_set_selected_uri (EWebViewGtkHTML *web_view, - const gchar *selected_uri) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_free (web_view->priv->selected_uri); - web_view->priv->selected_uri = g_strdup (selected_uri); - - g_object_notify (G_OBJECT (web_view), "selected-uri"); -} - -GdkPixbufAnimation * -e_web_view_gtkhtml_get_cursor_image (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - return web_view->priv->cursor_image; -} - -void -e_web_view_gtkhtml_set_cursor_image (EWebViewGtkHTML *web_view, - GdkPixbufAnimation *image) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - if (image != NULL) - g_object_ref (image); - - if (web_view->priv->cursor_image != NULL) - g_object_unref (web_view->priv->cursor_image); - - web_view->priv->cursor_image = image; - - g_object_notify (G_OBJECT (web_view), "cursor-image"); -} - -GtkAction * -e_web_view_gtkhtml_get_open_proxy (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return web_view->priv->open_proxy; -} - -void -e_web_view_gtkhtml_set_open_proxy (EWebViewGtkHTML *web_view, - GtkAction *open_proxy) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - if (open_proxy != NULL) { - g_return_if_fail (GTK_IS_ACTION (open_proxy)); - g_object_ref (open_proxy); - } - - if (web_view->priv->open_proxy != NULL) - g_object_unref (web_view->priv->open_proxy); - - web_view->priv->open_proxy = open_proxy; - - g_object_notify (G_OBJECT (web_view), "open-proxy"); -} - -GtkTargetList * -e_web_view_gtkhtml_get_paste_target_list (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - return web_view->priv->paste_target_list; -} - -GtkAction * -e_web_view_gtkhtml_get_print_proxy (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return web_view->priv->print_proxy; -} - -void -e_web_view_gtkhtml_set_print_proxy (EWebViewGtkHTML *web_view, - GtkAction *print_proxy) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - if (print_proxy != NULL) { - g_return_if_fail (GTK_IS_ACTION (print_proxy)); - g_object_ref (print_proxy); - } - - if (web_view->priv->print_proxy != NULL) - g_object_unref (web_view->priv->print_proxy); - - web_view->priv->print_proxy = print_proxy; - - g_object_notify (G_OBJECT (web_view), "print-proxy"); -} - -GtkAction * -e_web_view_gtkhtml_get_save_as_proxy (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return web_view->priv->save_as_proxy; -} - -void -e_web_view_gtkhtml_set_save_as_proxy (EWebViewGtkHTML *web_view, - GtkAction *save_as_proxy) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - if (save_as_proxy != NULL) { - g_return_if_fail (GTK_IS_ACTION (save_as_proxy)); - g_object_ref (save_as_proxy); - } - - if (web_view->priv->save_as_proxy != NULL) - g_object_unref (web_view->priv->save_as_proxy); - - web_view->priv->save_as_proxy = save_as_proxy; - - g_object_notify (G_OBJECT (web_view), "save-as-proxy"); -} - -GtkAction * -e_web_view_gtkhtml_get_action (EWebViewGtkHTML *web_view, - const gchar *action_name) -{ - GtkUIManager *ui_manager; - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - g_return_val_if_fail (action_name != NULL, NULL); - - ui_manager = e_web_view_gtkhtml_get_ui_manager (web_view); - - return e_lookup_action (ui_manager, action_name); -} - -GtkActionGroup * -e_web_view_gtkhtml_get_action_group (EWebViewGtkHTML *web_view, - const gchar *group_name) -{ - GtkUIManager *ui_manager; - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - g_return_val_if_fail (group_name != NULL, NULL); - - ui_manager = e_web_view_gtkhtml_get_ui_manager (web_view); - - return e_lookup_action_group (ui_manager, group_name); -} - -gchar * -e_web_view_gtkhtml_extract_uri (EWebViewGtkHTML *web_view, - GdkEventButton *event, - GtkHTML *frame) -{ - EWebViewGtkHTMLClass *class; - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - if (frame == NULL) - frame = GTK_HTML (web_view); - - class = E_WEB_VIEW_GTKHTML_GET_CLASS (web_view); - g_return_val_if_fail (class->extract_uri != NULL, NULL); - - return class->extract_uri (web_view, event, frame); -} - -void -e_web_view_gtkhtml_copy_clipboard (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_signal_emit (web_view, signals[COPY_CLIPBOARD], 0); -} - -void -e_web_view_gtkhtml_cut_clipboard (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_signal_emit (web_view, signals[CUT_CLIPBOARD], 0); -} - -gboolean -e_web_view_gtkhtml_is_selection_active (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_command (GTK_HTML (web_view), "is-selection-active"); -} - -void -e_web_view_gtkhtml_paste_clipboard (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_signal_emit (web_view, signals[PASTE_CLIPBOARD], 0); -} - -gboolean -e_web_view_gtkhtml_scroll_forward (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_command (GTK_HTML (web_view), "scroll-forward"); -} - -gboolean -e_web_view_gtkhtml_scroll_backward (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), FALSE); - - return gtk_html_command (GTK_HTML (web_view), "scroll-backward"); -} - -void -e_web_view_gtkhtml_select_all (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_command (GTK_HTML (web_view), "select-all"); -} - -void -e_web_view_gtkhtml_unselect_all (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_command (GTK_HTML (web_view), "unselect-all"); -} - -void -e_web_view_gtkhtml_zoom_100 (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_command (GTK_HTML (web_view), "zoom-reset"); -} - -void -e_web_view_gtkhtml_zoom_in (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_command (GTK_HTML (web_view), "zoom-in"); -} - -void -e_web_view_gtkhtml_zoom_out (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - gtk_html_command (GTK_HTML (web_view), "zoom-out"); -} - -GtkUIManager * -e_web_view_gtkhtml_get_ui_manager (EWebViewGtkHTML *web_view) -{ - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - return web_view->priv->ui_manager; -} - -GtkWidget * -e_web_view_gtkhtml_get_popup_menu (EWebViewGtkHTML *web_view) -{ - GtkUIManager *ui_manager; - GtkWidget *menu; - - g_return_val_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view), NULL); - - ui_manager = e_web_view_gtkhtml_get_ui_manager (web_view); - menu = gtk_ui_manager_get_widget (ui_manager, "/context"); - g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - - return menu; -} - -void -e_web_view_gtkhtml_show_popup_menu (EWebViewGtkHTML *web_view, - GdkEventButton *event, - GtkMenuPositionFunc func, - gpointer user_data) -{ - GtkWidget *menu; - - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - e_web_view_gtkhtml_update_actions (web_view); - - menu = e_web_view_gtkhtml_get_popup_menu (web_view); - - if (event != NULL) - gtk_menu_popup ( - GTK_MENU (menu), NULL, NULL, func, - user_data, event->button, event->time); - else - gtk_menu_popup ( - GTK_MENU (menu), NULL, NULL, func, - user_data, 0, gtk_get_current_event_time ()); -} - -void -e_web_view_gtkhtml_status_message (EWebViewGtkHTML *web_view, - const gchar *status_message) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_signal_emit (web_view, signals[STATUS_MESSAGE], 0, status_message); -} - -void -e_web_view_gtkhtml_stop_loading (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_signal_emit (web_view, signals[STOP_LOADING], 0); -} - -void -e_web_view_gtkhtml_update_actions (EWebViewGtkHTML *web_view) -{ - g_return_if_fail (E_IS_WEB_VIEW_GTKHTML (web_view)); - - g_signal_emit (web_view, signals[UPDATE_ACTIONS], 0); -} |