/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* * Copyright © 2000-2003 Marco Pesenti Gritti * Copyright © 2017 Igalia S.L. * * This file is part of Epiphany. * * Epiphany 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 3 of the License, or * (at your option) any later version. * * Epiphany 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 Epiphany. If not, see . */ #include "config.h" #include "popup-commands.h" #include "ephy-downloads-manager.h" #include "ephy-embed-container.h" #include "ephy-embed-utils.h" #include "ephy-file-chooser.h" #include "ephy-file-helpers.h" #include "ephy-flatpak-utils.h" #include "ephy-prefs.h" #include "ephy-settings.h" #include "ephy-shell.h" #include "ephy-web-view.h" #include #include #include #include typedef enum { NEW_WINDOW, NEW_TAB } LinkDestination; static void view_in_destination (EphyWindow *window, const char *property_name, LinkDestination destination) { WebKitHitTestResult *hit_test_result; g_autofree char *value = NULL; EphyEmbed *embed; EphyEmbed *new_embed; EphyWebView *new_view; WebKitWebViewSessionState *session_state; EphyWindow *dest_window = window; EphyNewTabFlags flags = 0; hit_test_result = ephy_window_get_context_event (window); g_assert (hit_test_result != NULL); embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window)); g_assert (embed != NULL); g_object_get (hit_test_result, property_name, &value, NULL); switch (destination) { case NEW_WINDOW: dest_window = ephy_window_new (); break; case NEW_TAB: flags |= EPHY_NEW_TAB_APPEND_AFTER; if (g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_SWITCH_TO_NEW_TAB)) flags |= EPHY_NEW_TAB_JUMP; break; default: g_assert_not_reached (); } new_embed = ephy_shell_new_tab (ephy_shell_get_default (), dest_window, embed, flags); new_view = ephy_embed_get_web_view (new_embed); session_state = webkit_web_view_get_session_state (WEBKIT_WEB_VIEW (ephy_embed_get_web_view (embed))); webkit_web_view_restore_session_state (WEBKIT_WEB_VIEW (new_view), session_state); webkit_web_view_session_state_unref (session_state); ephy_web_view_load_url (new_view, value); } void popup_cmd_link_in_new_window (GSimpleAction *action, GVariant *parameter, gpointer user_data) { view_in_destination (EPHY_WINDOW (user_data), "link-uri", NEW_WINDOW); } void popup_cmd_media_in_new_window (GSimpleAction *action, GVariant *parameter, gpointer user_data) { view_in_destination (EPHY_WINDOW (user_data), "media-uri", NEW_WINDOW); } static void popup_cmd_copy_to_clipboard (EphyWindow *window, const char *text) { gtk_clipboard_set_text (gtk_clipboard_get_default (gdk_display_get_default ()), text, -1); } void popup_cmd_copy_link_address (GSimpleAction *action, GVariant *parameter, gpointer user_data) { WebKitHitTestResult *hit_test_result; guint context; const char *address; hit_test_result = ephy_window_get_context_event (EPHY_WINDOW (user_data)); g_assert (hit_test_result != NULL); context = webkit_hit_test_result_get_context (hit_test_result); if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK) { address = webkit_hit_test_result_get_link_uri (hit_test_result); if (g_str_has_prefix (address, "mailto:")) address = address + 7; popup_cmd_copy_to_clipboard (EPHY_WINDOW (user_data), address); } } static gboolean cancel_download_idle_cb (EphyDownload *download) { ephy_download_cancel (download); return FALSE; } typedef struct { char *title; EphyWindow *window; EphyDownload *download; } SavePropertyURLData; static void filename_confirmed_cb (GtkFileChooser *dialog, GtkResponseType response, SavePropertyURLData *data) { gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (dialog)); if (response == GTK_RESPONSE_ACCEPT) { g_autoptr (GFile) file = NULL; g_autoptr (GFile) current_folder = NULL; g_autofree char *uri = NULL; g_autofree char *current_folder_path = NULL; WebKitDownload *webkit_download; file = gtk_file_chooser_get_file (dialog); uri = g_file_get_uri (file); ephy_download_set_destination_uri (data->download, uri); webkit_download = ephy_download_get_webkit_download (data->download); webkit_download_set_allow_overwrite (webkit_download, TRUE); ephy_downloads_manager_add_download (ephy_embed_shell_get_downloads_manager (ephy_embed_shell_get_default ()), data->download); current_folder = gtk_file_chooser_get_current_folder_file (dialog); current_folder_path = g_file_get_path (current_folder); g_settings_set_string (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_LAST_DOWNLOAD_DIRECTORY, current_folder_path); } else { g_idle_add_full (G_PRIORITY_DEFAULT, (GSourceFunc)cancel_download_idle_cb, g_object_ref (data->download), g_object_unref); } g_free (data->title); g_object_unref (data->window); g_object_unref (data->download); g_free (data); } static void filename_suggested_cb (EphyDownload *download, const char *suggested_filename, SavePropertyURLData *data) { GtkFileChooser *dialog; const char *last_directory_path; char *sanitized_filename; dialog = ephy_create_file_chooser (data->title, GTK_WIDGET (data->window), GTK_FILE_CHOOSER_ACTION_SAVE, EPHY_FILE_FILTER_NONE); gtk_file_chooser_set_do_overwrite_confirmation (dialog, TRUE); last_directory_path = g_settings_get_string (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_LAST_DOWNLOAD_DIRECTORY); if (last_directory_path && last_directory_path[0]) { g_autoptr (GFile) last_directory = NULL; g_autoptr (GError) error = NULL; last_directory = g_file_new_for_path (last_directory_path); gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog), last_directory, &error); if (error) g_warning ("Failed to set current folder %s: %s", last_directory_path, error->message); } sanitized_filename = ephy_sanitize_filename (g_strdup (suggested_filename)); gtk_file_chooser_set_current_name (dialog, sanitized_filename); g_free (sanitized_filename); g_signal_connect (dialog, "response", G_CALLBACK (filename_confirmed_cb), data); gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog)); } static void save_property_url (const char *title, EphyWindow *window, const char *property) { WebKitHitTestResult *hit_test_result; g_autofree char *location = NULL; EphyDownload *download; SavePropertyURLData *data; hit_test_result = ephy_window_get_context_event (window); g_assert (hit_test_result != NULL); g_object_get (hit_test_result, property, &location, NULL); download = ephy_download_new_for_uri (location); data = g_new (SavePropertyURLData, 1); data->title = g_strdup (title); data->window = g_object_ref (window); data->download = download; g_signal_connect (download, "filename-suggested", G_CALLBACK (filename_suggested_cb), data); } void popup_cmd_download_link_as (GSimpleAction *action, GVariant *parameter, gpointer user_data) { save_property_url (_("Save Link As"), EPHY_WINDOW (user_data), "link-uri"); } void popup_cmd_save_image_as (GSimpleAction *action, GVariant *parameter, gpointer user_data) { save_property_url (_("Save Image As"), EPHY_WINDOW (user_data), "image-uri"); } void popup_cmd_save_media_as (GSimpleAction *action, GVariant *parameter, gpointer user_data) { save_property_url (_("Save Media As"), EPHY_WINDOW (user_data), "media-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 (GSimpleAction *action, GVariant *parameter, gpointer user_data) { WebKitHitTestResult *hit_test_result; const char *location; char *dest_uri, *dest, *base, *base_converted; EphyDownload *download; if (ephy_is_running_inside_sandbox ()) return; hit_test_result = ephy_window_get_context_event (EPHY_WINDOW (user_data)); g_assert (hit_test_result != NULL); location = webkit_hit_test_result_get_image_uri (hit_test_result); download = ephy_download_new_for_uri (location); 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_downloads_manager_add_download (ephy_embed_shell_get_downloads_manager (ephy_embed_shell_get_default ()), download); g_object_unref (download); g_signal_connect (download, "completed", G_CALLBACK (background_download_completed), user_data); g_free (base); g_free (base_converted); g_free (dest); g_free (dest_uri); } static void popup_cmd_copy_location (EphyWindow *window, const char *property_name) { WebKitHitTestResult *hit_test_result; g_autofree char *location = NULL; hit_test_result = ephy_window_get_context_event (window); g_object_get (hit_test_result, property_name, &location, NULL); popup_cmd_copy_to_clipboard (window, location); } void popup_cmd_copy_image_location (GSimpleAction *action, GVariant *parameter, gpointer user_data) { popup_cmd_copy_location (EPHY_WINDOW (user_data), "image-uri"); } void popup_cmd_copy_media_location (GSimpleAction *action, GVariant *parameter, gpointer user_data) { popup_cmd_copy_location (EPHY_WINDOW (user_data), "media-uri"); } void popup_cmd_link_in_new_tab (GSimpleAction *action, GVariant *parameter, gpointer user_data) { view_in_destination (EPHY_WINDOW (user_data), "link-uri", NEW_TAB); } void popup_cmd_view_image_in_new_tab (GSimpleAction *action, GVariant *parameter, gpointer user_data) { view_in_destination (EPHY_WINDOW (user_data), "image-uri", NEW_TAB); } void popup_cmd_media_in_new_tab (GSimpleAction *action, GVariant *parameter, gpointer user_data) { view_in_destination (EPHY_WINDOW (user_data), "media-uri", NEW_TAB); } void popup_cmd_link_in_incognito_window (GSimpleAction *action, GVariant *parameter, gpointer user_data) { WebKitHitTestResult *hit_test_result; const char *link_uri; hit_test_result = ephy_window_get_context_event (EPHY_WINDOW (user_data)); g_assert (hit_test_result != NULL); link_uri = webkit_hit_test_result_get_link_uri (hit_test_result); ephy_open_incognito_window (link_uri); } void popup_cmd_search_selection (GSimpleAction *action, GVariant *parameter, gpointer user_data) { EphyEmbed *embed, *new_embed; const char *search_term; char *search_url; embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (user_data)); g_assert (EPHY_IS_EMBED (embed)); search_term = g_variant_get_string (parameter, NULL); search_url = ephy_embed_utils_autosearch_address (search_term); new_embed = ephy_shell_new_tab (ephy_shell_get_default (), EPHY_WINDOW (user_data), embed, EPHY_NEW_TAB_APPEND_AFTER | EPHY_NEW_TAB_JUMP); ephy_web_view_load_url (ephy_embed_get_web_view (new_embed), search_url); g_free (search_url); } void popup_cmd_open_selection (GSimpleAction *action, GVariant *parameter, gpointer user_data) { EphyEmbed *embed; const char *open_term; embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (user_data)); g_assert (EPHY_IS_EMBED (embed)); open_term = g_variant_get_string (parameter, NULL); ephy_web_view_load_url (ephy_embed_get_web_view (embed), open_term); } void popup_cmd_open_selection_in_new_tab (GSimpleAction *action, GVariant *parameter, gpointer user_data) { EphyEmbed *embed, *new_embed; const char *open_term; embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (user_data)); g_assert (EPHY_IS_EMBED (embed)); open_term = g_variant_get_string (parameter, NULL); new_embed = ephy_shell_new_tab (ephy_shell_get_default (), EPHY_WINDOW (user_data), embed, EPHY_NEW_TAB_APPEND_AFTER | EPHY_NEW_TAB_JUMP); ephy_web_view_load_url (ephy_embed_get_web_view (new_embed), open_term); } void popup_cmd_open_selection_in_new_window (GSimpleAction *action, GVariant *parameter, gpointer user_data) { EphyEmbed *embed, *new_embed; const char *open_term; embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (user_data)); g_assert (EPHY_IS_EMBED (embed)); open_term = g_variant_get_string (parameter, NULL); new_embed = ephy_shell_new_tab (ephy_shell_get_default (), ephy_window_new (), embed, 0); ephy_web_view_load_url (ephy_embed_get_web_view (new_embed), open_term); } void popup_cmd_open_selection_in_incognito_window (GSimpleAction *action, GVariant *parameter, gpointer user_data) { const char *open_term; open_term = g_variant_get_string (parameter, NULL); ephy_open_incognito_window (open_term); }