diff options
Diffstat (limited to 'embed/ephy-embed.c')
-rw-r--r-- | embed/ephy-embed.c | 476 |
1 files changed, 12 insertions, 464 deletions
diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c index ebd34d163..6f008f565 100644 --- a/embed/ephy-embed.c +++ b/embed/ephy-embed.c @@ -25,14 +25,13 @@ #include "config.h" -#include "downloader-view.h" #include "ephy-adblock-manager.h" #include "ephy-debug.h" +#include "ephy-download.h" #include "ephy-embed.h" #include "ephy-embed-event.h" #include "ephy-embed-shell.h" #include "ephy-embed-single.h" -#include "ephy-embed-persist.h" #include "ephy-embed-prefs.h" #include "ephy-embed-utils.h" #include "ephy-file-chooser.h" @@ -359,458 +358,14 @@ ephy_embed_inspect_close_cb (WebKitWebInspector *inspector, return TRUE; } -static void -download_requested_dialog_response_cb (GtkDialog *dialog, - int response_id, - WebKitDownload *download) -{ - if (response_id == GTK_RESPONSE_ACCEPT) { - DownloaderView *dview; - char *uri; - - uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog)); - g_object_set_data (G_OBJECT (download), "user-destination-uri", uri); - - dview = EPHY_DOWNLOADER_VIEW (ephy_embed_shell_get_downloader_view (embed_shell)); - downloader_view_add_download (dview, download); - } else { - webkit_download_cancel (download); - ephy_file_delete_uri (webkit_download_get_destination_uri (download)); - } - - gtk_widget_destroy (GTK_WIDGET (dialog)); - /* User provided us with a destination or cancelled, unfreeze. */ - g_object_thaw_notify (G_OBJECT (download)); - g_object_unref (download); -} - -static void -request_destination_uri (WebKitWebView *web_view, - WebKitDownload *download) -{ - EphyFileChooser *dialog; - GtkWidget *window; - const char *suggested_filename; - - suggested_filename = webkit_download_get_suggested_filename (download); - - /* - * Try to get the toplevel window related to the WebView that caused - * the download, and use NULL otherwise; we don't want to pass the - * WebView or other widget as a parent window. - */ - window = gtk_widget_get_toplevel (GTK_WIDGET (web_view)); - if (!gtk_widget_is_toplevel (window)) - window = NULL; - - dialog = ephy_file_chooser_new (_("Save"), - window, - GTK_FILE_CHOOSER_ACTION_SAVE, - EPHY_PREFS_STATE_SAVE_DIR, - EPHY_FILE_FILTER_ALL_SUPPORTED); - gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); - gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), suggested_filename); - - g_signal_connect (dialog, "response", - G_CALLBACK (download_requested_dialog_response_cb), download); - - gtk_widget_show_all (GTK_WIDGET (dialog)); -} - -/* From the old embed/mozilla/MozDownload.cpp */ -static const char* -file_is_compressed (const char *filename) -{ - int i; - static const char * const compression[] = {".gz", ".bz2", ".Z", ".lz", NULL}; - - for (i = 0; compression[i] != NULL; i++) { - if (g_str_has_suffix (filename, compression[i])) - return compression[i]; - } - - return NULL; -} - -static const char* -parse_extension (const char *filename) -{ - const char *compression; - const char *last_separator; - - compression = file_is_compressed (filename); - - /* if the file is compressed we might have a double extension */ - if (compression != NULL) { - int i; - static const char * const extensions[] = {"tar", "ps", "xcf", "dvi", "txt", "text", NULL}; - - for (i = 0; extensions[i] != NULL; i++) { - char *suffix; - suffix = g_strdup_printf (".%s%s", extensions[i], compression); - - if (g_str_has_suffix (filename, suffix)) { - char *p; - - p = g_strrstr (filename, suffix); - g_free (suffix); - - return p; - } - - g_free (suffix); - } - } - - /* no compression, just look for the last dot in the filename */ - last_separator = strrchr (filename, G_DIR_SEPARATOR); - return strrchr ((last_separator) ? last_separator : filename, '.'); -} - -static gboolean -define_destination_uri (WebKitDownload *download, - gboolean temporary) -{ - char *tmp_dir; - char *destination_filename; - char *destination_uri; - const char *suggested_filename; - - suggested_filename = webkit_download_get_suggested_filename (download); - - /* If we are not doing an automatic download, use a temporary file - * to start the download while we ask the user for the location to - * where the file must go. - */ - if (temporary) - tmp_dir = g_build_filename (ephy_dot_dir (), "downloads", NULL); - else - tmp_dir = ephy_file_get_downloads_dir (); - - /* Make sure the download directory exists */ - if (g_mkdir_with_parents (tmp_dir, 0700) == -1) { - g_critical ("Could not create downloads directory \"%s\": %s", - tmp_dir, strerror (errno)); - g_free (tmp_dir); - return FALSE; - } - - destination_filename = g_build_filename (tmp_dir, suggested_filename, NULL); - - if (g_file_test (destination_filename, G_FILE_TEST_EXISTS)) { - int i = 1; - const char *dot_pos; - gssize position; - char *serial = NULL; - GString *tmp_filename; - - dot_pos = parse_extension (destination_filename); - if (dot_pos) - position = dot_pos - destination_filename; - else - position = strlen (destination_filename); - - tmp_filename = g_string_new (NULL); - - do { - serial = g_strdup_printf ("(%d)", i++); - - g_string_assign (tmp_filename, destination_filename); - g_string_insert (tmp_filename, position, serial); - - g_free (serial); - } while (g_file_test (tmp_filename->str, G_FILE_TEST_EXISTS)); - - destination_filename = g_strdup (tmp_filename->str); - g_string_free (tmp_filename, TRUE); - } - - destination_uri = g_strconcat ("file://", destination_filename, NULL); - - LOG ("define_destination_uri: Downloading to %s", destination_filename); - - webkit_download_set_destination_uri (download, destination_uri); - - g_free (tmp_dir); - g_free (destination_filename); - g_free (destination_uri); - - return TRUE; -} - -static gboolean -perform_auto_download (WebKitDownload *download) -{ - DownloaderView *dview; - - if (!define_destination_uri (download, FALSE)) { - webkit_download_cancel (download); - ephy_file_delete_uri (webkit_download_get_destination_uri (download)); - return FALSE; - } - - dview = EPHY_DOWNLOADER_VIEW (ephy_embed_shell_get_downloader_view (embed_shell)); - - g_object_set_data (G_OBJECT(download), "download-action", GINT_TO_POINTER(DOWNLOAD_ACTION_OPEN)); - downloader_view_add_download (dview, download); - - return TRUE; -} - void ephy_embed_auto_download_url (EphyEmbed *embed, const char *url) { - WebKitNetworkRequest *request; - WebKitDownload *download; - - request = webkit_network_request_new (url); - download = webkit_download_new (request); - g_object_unref (request); - - if (perform_auto_download (download)) - webkit_download_start (download); -} - -static void -confirm_action_response_cb (GtkWidget *dialog, - int response, - WebKitDownload *download) -{ - WebKitWebView *web_view = g_object_get_data (G_OBJECT(dialog), "webkit-view"); - DownloaderView *dview; - - gtk_widget_destroy (dialog); - - if (response > 0) { - switch (response) { - case DOWNLOAD_ACTION_OPEN: - g_object_set_data (G_OBJECT (download), "download-action", - GINT_TO_POINTER (DOWNLOAD_ACTION_OPEN)); - break; - case DOWNLOAD_ACTION_DOWNLOAD: - case DOWNLOAD_ACTION_OPEN_LOCATION: - g_object_set_data (G_OBJECT (download), "download-action", - GINT_TO_POINTER (DOWNLOAD_ACTION_OPEN_LOCATION)); - break; - } - - if (response == DOWNLOAD_ACTION_DOWNLOAD) { - /* balanced in download_requested_dialog_response_cb */ - g_object_ref (download); - request_destination_uri (web_view, download); - } else { - if (!define_destination_uri (download, FALSE)) { - goto cleanup; - } - dview = EPHY_DOWNLOADER_VIEW (ephy_embed_shell_get_downloader_view (embed_shell)); - downloader_view_add_download (dview, download); - /* User selected "Open", he won't be providing a destination, unfreeze. */ - g_object_thaw_notify (G_OBJECT (download)); - } - g_object_unref (download); - return; - } + EphyDownload *download; -cleanup: - webkit_download_cancel (download); - ephy_file_delete_uri (webkit_download_get_destination_uri (download)); - g_object_unref (download); -} - -static void -confirm_action_from_mime (WebKitWebView *web_view, - WebKitDownload *download, - DownloadAction action) -{ - GtkWidget *parent_window; - GtkWidget *dialog; - const char *action_label; - char *mime_description; - EphyMimePermission mime_permission; - GAppInfo *helper_app; - const char *suggested_filename; - int default_response; - WebKitNetworkResponse *response; - SoupMessage *message; - GtkMessageType mtype; - char *title; - char *secondary; - - parent_window = gtk_widget_get_toplevel (GTK_WIDGET(web_view)); - if (!gtk_widget_is_toplevel (parent_window)) - parent_window = NULL; - - helper_app = NULL; - mime_description = NULL; - mime_permission = EPHY_MIME_PERMISSION_SAFE; - - response = webkit_download_get_network_response (download); - message = webkit_network_response_get_message (response); - - if (message) { - const char *content_type = soup_message_headers_get_content_type (message->response_headers, NULL); - - if (content_type) { - mime_description = g_content_type_get_description (content_type); - helper_app = g_app_info_get_default_for_type (content_type, FALSE); - mime_permission = ephy_file_check_mime (content_type); - - if (helper_app) - action = DOWNLOAD_ACTION_OPEN; - } - } - - if (mime_description == NULL) { - mime_description = g_strdup (C_("file type", "Unknown")); - action = DOWNLOAD_ACTION_OPEN_LOCATION; - } - - /* Sometimes downloads can have a mime_description but a NULL helper_app - * in that case action is never changed so DOWNLOAD_ACTION_DOWNLOAD remains - * as action value. This is the same response value as Save as... - * button, which is wrong for the Download button. - */ - if (helper_app == NULL) - action = DOWNLOAD_ACTION_OPEN_LOCATION; - - action_label = (action == DOWNLOAD_ACTION_OPEN) ? GTK_STOCK_OPEN : STOCK_DOWNLOAD; - suggested_filename = webkit_download_get_suggested_filename (download); - - if (mime_permission != EPHY_MIME_PERMISSION_SAFE && helper_app) { - title = _("Download this potentially unsafe file?"); - mtype = GTK_MESSAGE_WARNING; - /* translators: First %s is the file type description, second %s is the - * file name */ - secondary = g_strdup_printf (_("File Type: “%s”.\n\nIt is unsafe to open " - "“%s” as it could potentially damage your " - "documents or invade your privacy. " - "You can download it instead."), - mime_description, suggested_filename); - - action_label = STOCK_DOWNLOAD; - } else if (action == DOWNLOAD_ACTION_OPEN && helper_app) { - title = _("Open this file?"); - mtype = GTK_MESSAGE_QUESTION; - /* translators: First %s is the file type description, second %s is the - * file name, third %s is the application used to open the file */ - secondary = g_strdup_printf (_("File Type: “%s”.\n\nYou can open “%s” " - "using “%s” or save it."), - mime_description, suggested_filename, - g_app_info_get_name (helper_app)); - } else { - title = _("Download this file?"); - mtype = GTK_MESSAGE_QUESTION; - /* translators: First %s is the file type description, second %s is the - * file name */ - secondary = g_strdup_printf (_("File Type: “%s”.\n\nYou have no " - "application able to open “%s”. " - "You can download it instead."), - mime_description, suggested_filename); - } - - dialog = gtk_message_dialog_new (GTK_WINDOW (parent_window), - GTK_DIALOG_DESTROY_WITH_PARENT, - mtype, GTK_BUTTONS_NONE, - title); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - secondary, NULL); - - g_free (mime_description); - - gtk_dialog_add_button (GTK_DIALOG (dialog), - GTK_STOCK_SAVE_AS, DOWNLOAD_ACTION_DOWNLOAD); - gtk_dialog_add_button (GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - gtk_dialog_add_button (GTK_DIALOG (dialog), - action_label, action); - - gtk_window_set_icon_name (GTK_WINDOW (dialog), EPHY_STOCK_EPHY); - - default_response = (action == DOWNLOAD_ACTION_NONE) ? - (int) GTK_RESPONSE_CANCEL : (int) action; - - gtk_dialog_set_default_response (GTK_DIALOG (dialog), default_response); - - g_object_set_data (G_OBJECT (dialog), "webkit-view", web_view); - g_signal_connect (dialog, "response", - G_CALLBACK (confirm_action_response_cb), - download); - - gtk_window_present (GTK_WINDOW (dialog)); -} - -static void -download_status_changed_cb (GObject *object, - GParamSpec *pspec, - EphyEmbed *embed) -{ - WebKitDownload *download = WEBKIT_DOWNLOAD (object); - - if (webkit_download_get_status (download) == WEBKIT_DOWNLOAD_STATUS_FINISHED) - { - GFile *destination; - GFile *temp; - char *destination_uri; - const char *temp_uri; - - temp_uri = webkit_download_get_destination_uri (download); - destination_uri = g_object_get_data (G_OBJECT (download), - "user-destination-uri"); - - LOG ("download_status_changed_cb: finished, moving temp file %s to %s", - temp_uri, destination_uri); - - /* No user-destination-uri is set, hence this is an auto download and we - * have nothing else to do. */ - if (destination_uri == NULL) return; - - temp = g_file_new_for_uri (temp_uri); - destination = g_file_new_for_uri (destination_uri); - - ephy_file_switch_temp_file (destination, temp); - - g_object_unref (destination); - g_object_unref (temp); - } - else if (webkit_download_get_status (download) == WEBKIT_DOWNLOAD_STATUS_STARTED) - { - /* Prevent this callback from being called before the user has selected a - * destination. It is freed either here or in - * download_requested_dialog_response_cb(). Both situations are mutually - * exclusive. - * - * This freeze is removed either here below, in - * download_requested_dialog_response_cb() or confirm_action_response_cb(). - */ - g_object_freeze_notify (G_OBJECT (download)); - - if (g_settings_get_boolean (EPHY_SETTINGS_MAIN, - EPHY_PREFS_AUTO_DOWNLOADS)) { - perform_auto_download (download); - /* User won't select a destination, unfreeze. */ - g_object_thaw_notify (G_OBJECT (download)); - return; - } - - /* Balanced in confirm_action_response_cb. */ - g_object_ref (download); - - confirm_action_from_mime (EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed), - download, DOWNLOAD_ACTION_DOWNLOAD); - } -} - -static gboolean -download_error_cb (WebKitDownload *download, - gint error_code, - gint error_detail, - const gchar *reason, - EphyEmbed *embed) -{ - /* FIXME: handle download errors and notify the user. */ - LOG ("download_error_cb: Error (%d:%d): %s", error_code, error_detail, reason); - - return FALSE; + download = ephy_download_new_for_uri (url); + ephy_download_set_auto_destination (download); + ephy_download_set_action (download, EPHY_DOWNLOAD_ACTION_OPEN); } static gboolean @@ -818,26 +373,19 @@ download_requested_cb (WebKitWebView *web_view, WebKitDownload *download, EphyEmbed *embed) { + EphyDownload *ed; + GtkWidget *window; + /* Is download locked down? */ if (g_settings_get_boolean (EPHY_SETTINGS_LOCKDOWN, EPHY_PREFS_LOCKDOWN_SAVE_TO_DISK)) return FALSE; - /* Wait for the request to be sent in all cases, so that we have a - * response which may contain a suggested filename */ - g_signal_connect (download, "notify::status", - G_CALLBACK (download_status_changed_cb), - embed); - g_signal_connect (download, "error", - G_CALLBACK (download_error_cb), - embed); + window = gtk_widget_get_toplevel (GTK_WIDGET (embed)); - /* If we are not performing an auto-download, we will ask the user - * where they want the file to go to; we will start downloading to a - * temporary location while the user decides. - */ - if (!define_destination_uri (download, TRUE)) - return FALSE; + ed = ephy_download_new_for_download (download); + ephy_download_set_window (ed, window); + ephy_download_set_auto_destination (ed); return TRUE; } |