diff options
author | Diego Escalante Urrelo <diegoe@gnome.org> | 2009-12-29 14:13:18 +0800 |
---|---|---|
committer | Diego Escalante Urrelo <diegoe@gnome.org> | 2009-12-30 04:20:43 +0800 |
commit | 03ad276917dd0ffb1a6098d5d352dee63c89b7f2 (patch) | |
tree | 4734f9a6f7980d59395f9814fa2e35bf1b52d010 | |
parent | 915203e369ffadb94ecf895f6c328dcba91a7789 (diff) | |
download | gsoc2013-epiphany-03ad276917dd0ffb1a6098d5d352dee63c89b7f2.tar.gz gsoc2013-epiphany-03ad276917dd0ffb1a6098d5d352dee63c89b7f2.tar.zst gsoc2013-epiphany-03ad276917dd0ffb1a6098d5d352dee63c89b7f2.zip |
Implement replace action for downloads
Always download to a temporary location, only move the file to the final
destination after it has been downloaded completely.
Bug #594192
-rw-r--r-- | embed/downloader-view.c | 20 | ||||
-rw-r--r-- | embed/ephy-embed.c | 81 |
2 files changed, 81 insertions, 20 deletions
diff --git a/embed/downloader-view.c b/embed/downloader-view.c index 3ecb4a29d..b23d0426e 100644 --- a/embed/downloader-view.c +++ b/embed/downloader-view.c @@ -366,13 +366,17 @@ static char * ephy_download_get_name (WebKitDownload *download) { const char *target; + char *user_destination; char *result; target = webkit_download_get_destination_uri (download); + user_destination = g_object_get_data (G_OBJECT (download), + "user-destination-uri"); - if (target) + if (user_destination || target) { - result = g_path_get_basename (target); + result = g_path_get_basename (user_destination ? + user_destination : target); } else { @@ -410,10 +414,18 @@ do_open_downloaded_file (DownloaderView *dv, WebKitDownload *download, gboolean { DownloaderViewPrivate *priv = dv->priv; GdkDisplay *gdk_display; - const char *destination_uri = webkit_download_get_destination_uri (download); - GFile *downloaded_file = g_file_new_for_uri (destination_uri); + const char *destination_uri; + char *user_destination; + GFile *downloaded_file; gdk_display = gtk_widget_get_display (priv->window); + + destination_uri = webkit_download_get_destination_uri (download); + user_destination = g_object_get_data (G_OBJECT (download), + "user-destination-uri"); + + downloaded_file = g_file_new_for_uri (user_destination ? + user_destination : destination_uri); if (open_location) { ephy_file_browse_to (downloaded_file, diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c index 249576ef3..072a9b5df 100644 --- a/embed/ephy-embed.c +++ b/embed/ephy-embed.c @@ -398,9 +398,8 @@ download_requested_dialog_response_cb (GtkDialog *dialog, DownloaderView *dview; char *uri; - uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER(dialog)); - webkit_download_set_destination_uri (download, uri); - g_free (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); @@ -410,6 +409,8 @@ download_requested_dialog_response_cb (GtkDialog *dialog, } 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); } @@ -629,6 +630,8 @@ confirm_action_response_cb (GtkWidget *dialog, } 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; @@ -774,20 +777,63 @@ download_status_changed_cb (GObject *object, { WebKitDownload *download = WEBKIT_DOWNLOAD (object); - g_return_if_fail (webkit_download_get_status (download) == WEBKIT_DOWNLOAD_STATUS_STARTED); + if (webkit_download_get_status (download) == WEBKIT_DOWNLOAD_STATUS_FINISHED) + { + GFile *destination; + GFile *temp; + char *destination_uri; + const char *temp_uri; - g_signal_handlers_disconnect_by_func (download, - download_status_changed_cb, - web_view); + temp_uri = webkit_download_get_destination_uri (download); + destination_uri = g_object_get_data (G_OBJECT (download), + "user-destination-uri"); - /* Is auto-download enabled? */ - if (eel_gconf_get_boolean (CONF_AUTO_DOWNLOADS)) { - perform_auto_download (download); - return; + /* 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)); - g_object_ref (download); /* balanced in confirm_action_response_cb */ - confirm_action_from_mime (web_view, download, DOWNLOAD_ACTION_DOWNLOAD); + if (eel_gconf_get_boolean (CONF_AUTO_DOWNLOADS)) { + perform_auto_download (download); + /* User won't select a destination, unfreeze. */ + g_object_thaw_notify (G_OBJECT (download)); + return; + } + + g_object_ref (download); /* balanced in confirm_action_response_cb */ + confirm_action_from_mime (web_view, download, DOWNLOAD_ACTION_DOWNLOAD); + } +} + +static gboolean +download_error_cb (WebKitDownload *download, + gint error_code, + gint error_detail, + const gchar *reason, + WebKitWebView *view) +{ + /* FIXME: handle download errors and notify the user */ + return FALSE; } static gboolean @@ -800,9 +846,12 @@ download_requested_cb (WebKitWebView *web_view, /* 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), - web_view); + g_signal_connect_object (download, "notify::status", + G_CALLBACK (download_status_changed_cb), + web_view, 0); + g_signal_connect_object (download, "error", + G_CALLBACK (download_error_cb), + web_view, 0); /* 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 |