/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright © 2000-2003 Marco Pesenti Gritti * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "config.h" #include "popup-commands.h" #include "ephy-bookmarks-ui.h" #include "ephy-download.h" #include "ephy-embed-container.h" #include "ephy-embed-utils.h" #include "ephy-file-chooser.h" #include "ephy-file-helpers.h" #include "ephy-prefs.h" #include "ephy-private.h" #include "ephy-settings.h" #include "ephy-shell.h" #include "ephy-web-view.h" #include #include #include #ifdef HAVE_WEBKIT2 #include #else #include #endif void popup_cmd_link_in_new_window (GtkAction *action, EphyWindow *window) { EphyEmbedEvent *event; EphyEmbed *embed; GValue value = { 0, }; embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window)); event = ephy_window_get_context_event (window); g_return_if_fail (event != NULL); ephy_embed_event_get_property (event, "link-uri", &value); ephy_shell_new_tab (ephy_shell_get_default (), NULL, embed, g_value_get_string (&value), EPHY_NEW_TAB_OPEN_PAGE | EPHY_NEW_TAB_IN_NEW_WINDOW); g_value_unset (&value); } void popup_cmd_link_in_new_tab (GtkAction *action, EphyWindow *window) { EphyEmbedEvent *event; EphyEmbed *embed; GValue value = { 0, }; embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window)); event = ephy_window_get_context_event (window); g_return_if_fail (event != NULL); ephy_embed_event_get_property (event, "link-uri", &value); ephy_shell_new_tab (ephy_shell_get_default (), window, embed, g_value_get_string (&value), EPHY_NEW_TAB_OPEN_PAGE | EPHY_NEW_TAB_IN_EXISTING_WINDOW | EPHY_NEW_TAB_APPEND_AFTER); g_value_unset (&value); } void popup_cmd_bookmark_link (GtkAction *action, EphyWindow *window) { #ifdef HAVE_WEBKIT2 EphyEmbedEvent *event; WebKitHitTestResult *result; const char *title; const char *location; event = ephy_window_get_context_event (window); result = ephy_embed_event_get_hit_test_result (event); if (!webkit_hit_test_result_context_is_link (result)) { return; } location = webkit_hit_test_result_get_link_uri (result); title = webkit_hit_test_result_get_link_title (result); if (!title) { title = webkit_hit_test_result_get_link_label (result); } ephy_bookmarks_ui_add_bookmark (GTK_WINDOW (window), location, title); #else EphyEmbedEvent *event; char *title; char *location = NULL; guint context; WebKitHitTestResult *result; WebKitDOMNode *node, *first_child; event = ephy_window_get_context_event (window); g_return_if_fail (event != NULL); result = ephy_embed_event_get_hit_test_result (event); g_object_get (result, "context", &context, NULL); g_object_get (result, "inner-node", &node, NULL); if (context != WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK) { node = WEBKIT_DOM_NODE (webkit_dom_node_get_parent_element (WEBKIT_DOM_NODE (node))); if (WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node)) location = webkit_dom_html_anchor_element_get_href (WEBKIT_DOM_HTML_ANCHOR_ELEMENT (node)); } else { g_object_get (result, "link-uri", &location, NULL); } if (!node || !location) return; title = webkit_dom_html_element_get_title (WEBKIT_DOM_HTML_ELEMENT (node)); if (title == NULL || title[0] == '\0') { title = webkit_dom_html_anchor_element_get_text (WEBKIT_DOM_HTML_ANCHOR_ELEMENT (node)); } /* Sometimes boorkmaklets are presented as images inside a * link, try that. */ if (title == NULL || title[0] == '\0') { first_child = webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (node)); if (first_child && WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT (first_child)) { title = webkit_dom_html_image_element_get_alt (WEBKIT_DOM_HTML_IMAGE_ELEMENT (first_child)); if (title == NULL || title[0] == '\0') title = webkit_dom_html_image_element_get_name (WEBKIT_DOM_HTML_IMAGE_ELEMENT (first_child)); } } if (title == NULL || title[0] == '\0') { title = location; } ephy_bookmarks_ui_add_bookmark (GTK_WINDOW (window), location, title); g_free (title); g_free (location); #endif } static void popup_cmd_copy_to_clipboard (EphyWindow *window, const char *text) { gtk_clipboard_set_text (gtk_clipboard_get (GDK_NONE), text, -1); gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY), text, -1); } void popup_cmd_copy_link_address (GtkAction *action, EphyWindow *window) { EphyEmbedEvent *event; guint context; const char *address; GValue value = { 0, }; event = ephy_window_get_context_event (window); g_return_if_fail (event != NULL); context = ephy_embed_event_get_context (event); if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK) { ephy_embed_event_get_property (event, "link-uri", &value); address = g_value_get_string (&value); if (g_str_has_prefix (address, "mailto:")) address = address + 7; popup_cmd_copy_to_clipboard (window, address); g_value_unset (&value); } } static void save_property_url_to_destination (EphyWindow *window, const char *location, const char *destination) { EphyDownload *download; download = ephy_download_new_for_uri (location, GTK_WINDOW (window)); if (destination) ephy_download_set_destination_uri (download, destination); else ephy_download_set_auto_destination (download); ephy_download_start (download); } static void response_cb (GtkDialog *dialog, int response_id, char *location) { if (response_id == GTK_RESPONSE_ACCEPT) { char *uri; GtkWindow *window; window = gtk_window_get_transient_for (GTK_WINDOW (dialog)); uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog)); save_property_url_to_destination (EPHY_WINDOW (window), location, uri); g_free (uri); } g_free (location); gtk_widget_destroy (GTK_WIDGET (dialog)); } static void save_property_url (GtkAction *action, const char *title, EphyWindow *window, gboolean ask_dest, const char *property) { EphyEmbedEvent *event; const char *location; GValue value = { 0, }; event = ephy_window_get_context_event (window); g_return_if_fail (event != NULL); ephy_embed_event_get_property (event, property, &value); location = g_value_get_string (&value); if (ask_dest) { EphyFileChooser *dialog; char *base; base = g_path_get_basename (location); dialog = ephy_file_chooser_new (title, GTK_WIDGET (window), GTK_FILE_CHOOSER_ACTION_SAVE, EPHY_FILE_FILTER_NONE); gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), base); g_signal_connect (dialog, "response", G_CALLBACK (response_cb), g_strdup (location)); gtk_widget_show (GTK_WIDGET (dialog)); g_free (base); } else { save_property_url_to_destination (window, location, NULL); } } void popup_cmd_open_link (GtkAction *action, EphyWindow *window) { EphyEmbedEvent *event; const char *location; GValue value = { 0, }; EphyEmbed *embed; embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window)); g_return_if_fail (embed != NULL); event = ephy_window_get_context_event (window); ephy_embed_event_get_property (event, "link-uri", &value); location = g_value_get_string (&value); ephy_web_view_load_url (ephy_embed_get_web_view (embed), location); g_value_unset (&value); } void popup_cmd_download_link (GtkAction *action, EphyWindow *window) { save_property_url (action, _("Download Link"), window, FALSE, "link-uri"); } void popup_cmd_download_link_as (GtkAction *action, EphyWindow *window) { save_property_url (action, _("Save Link As"), window, TRUE, "link-uri"); } void popup_cmd_save_image_as (GtkAction *action, EphyWindow *window) { save_property_url (action, _("Save Image As"), window, TRUE, "image-uri"); } static void background_download_completed (EphyDownload *download, GtkWidget *window) { const char *uri; GSettings *settings; uri = ephy_download_get_destination_uri (download); settings = ephy_settings_get ("org.gnome.desktop.background"); g_settings_set_string (settings, "picture-uri", uri); } void popup_cmd_set_image_as_background (GtkAction *action, EphyWindow *window) { EphyEmbedEvent *event; const char *location; char *dest_uri, *dest, *base, *base_converted; GValue value = { 0, }; EphyDownload *download; event = ephy_window_get_context_event (window); g_return_if_fail (event != NULL); ephy_embed_event_get_property (event, "image-uri", &value); location = g_value_get_string (&value); download = ephy_download_new_for_uri (location, GTK_WINDOW (window)); base = g_path_get_basename (location); base_converted = g_filename_from_utf8 (base, -1, NULL, NULL, NULL); dest = g_build_filename (g_get_user_special_dir (G_USER_DIRECTORY_PICTURES), base_converted, NULL); dest_uri = g_filename_to_uri (dest, NULL, NULL); ephy_download_set_destination_uri (download, dest_uri); ephy_download_set_action (download, EPHY_DOWNLOAD_ACTION_DO_NOTHING); g_signal_connect (download, "completed", G_CALLBACK (background_download_completed), window); ephy_download_start (download); g_value_unset (&value); g_free (base); g_free (base_converted); g_free (dest); g_free (dest_uri); } void popup_cmd_copy_image_location (GtkAction *action, EphyWindow *window) { EphyEmbedEvent *event; const char *location; GValue value = { 0, }; event = ephy_window_get_context_event (window); ephy_embed_event_get_property (event, "image-uri", &value); location = g_value_get_string (&value); popup_cmd_copy_to_clipboard (window, location); g_value_unset (&value); } /* Opens an image URI using its associated handler. Or, if that * doesn't work, fallback to open the URI in a new browser window. */ static void image_open_uri (GFile *file, const char *remote_address, guint32 user_time) { gboolean success; success = ephy_file_launch_handler (NULL, file, user_time); if (!success) { ephy_shell_new_tab (ephy_shell_get_default (), NULL, NULL, remote_address, EPHY_NEW_TAB_OPEN_PAGE | EPHY_NEW_TAB_IN_NEW_WINDOW); } if (strcmp (remote_address, g_file_get_uri (file)) != 0) { if (success) ephy_file_delete_on_exit (file); else g_file_delete (file, NULL, NULL); } } static void save_source_completed_cb (EphyDownload *download) { const char *dest; const char *source; guint32 user_time; GFile *file; user_time = ephy_download_get_start_time (download); dest = ephy_download_get_destination_uri (download); source = ephy_download_get_source_uri (download); g_return_if_fail (dest != NULL); file = g_file_new_for_uri (dest); image_open_uri (file, source, user_time); g_object_unref (file); } static void save_temp_source (const char *address) { EphyDownload *download; const char *static_temp_dir; char *base, *tmp_name, *tmp_path, *dest, *dest_uri; if (address == NULL) return; static_temp_dir = ephy_file_tmp_dir (); if (static_temp_dir == NULL) return; base = g_path_get_basename (address); tmp_name = g_strconcat (base, ".XXXXXX", NULL); g_free (base); tmp_path = g_build_filename (static_temp_dir, tmp_name, NULL); g_free (tmp_name); dest = ephy_file_tmp_filename (tmp_path, NULL); g_free (tmp_path); if (dest == NULL) return; dest_uri = g_filename_to_uri (dest, NULL, NULL); download = ephy_download_new_for_uri (address, NULL); ephy_download_set_destination_uri (download, dest_uri); g_signal_connect (download, "completed", G_CALLBACK (save_source_completed_cb), NULL); ephy_download_start (download); g_free (dest); g_free (dest_uri); } void popup_replace_spelling (GtkAction *action, EphyWindow *window) { #ifndef HAVE_WEBKIT2 EphyEmbed *embed; WebKitWebView *view; WebKitWebFrame *frame; WebKitDOMDOMSelection *selection; WebKitDOMDocument *document; WebKitDOMDOMWindow *default_view; embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window)); g_return_if_fail (embed != NULL); view = WEBKIT_WEB_VIEW (ephy_embed_get_web_view (embed)); g_return_if_fail (view != NULL); document = webkit_web_view_get_dom_document (view); default_view = webkit_dom_document_get_default_view (document); selection = webkit_dom_dom_window_get_selection (default_view); webkit_dom_dom_selection_modify (selection, "move", "backward", "word"); webkit_dom_dom_selection_modify (selection, "extend", "forward", "word"); frame = webkit_web_view_get_focused_frame (view); webkit_web_frame_replace_selection (frame, gtk_action_get_label (action)); #endif } void popup_cmd_open_image (GtkAction *action, EphyWindow *window) { EphyEmbedEvent *event; const char *address; char *scheme = NULL; GValue value = { 0, }; EphyEmbed *embed; event = ephy_window_get_context_event (window); g_return_if_fail (event != NULL); embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window)); g_return_if_fail (embed != NULL); ephy_embed_event_get_property (event, "image-uri", &value); address = g_value_get_string (&value); scheme = g_uri_parse_scheme (address); if (scheme == NULL) goto out; if (strcmp (scheme, "file") == 0) { GFile *file; file = g_file_new_for_uri (address); image_open_uri (file, address, gtk_get_current_event_time ()); g_object_unref (file); } else { save_temp_source (address); } out: g_value_unset (&value); g_free (scheme); } void popup_cmd_inspect_element (GtkAction *action, EphyWindow *window) { #ifndef HAVE_WEBKIT2 EphyEmbedEvent *event; EphyEmbed *embed; WebKitWebInspector *inspector; guint x, y; embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window)); event = ephy_window_get_context_event (window); g_return_if_fail (event != NULL); inspector = webkit_web_view_get_inspector (EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed)); ephy_embed_event_get_coords (event, &x, &y); webkit_web_inspector_inspect_coordinates (inspector, (gdouble)x, (gdouble)y); #endif }