aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDiego Escalante Urrelo <diegoe@gnome.org>2009-12-29 14:13:18 +0800
committerDiego Escalante Urrelo <diegoe@gnome.org>2009-12-30 04:20:43 +0800
commit03ad276917dd0ffb1a6098d5d352dee63c89b7f2 (patch)
tree4734f9a6f7980d59395f9814fa2e35bf1b52d010
parent915203e369ffadb94ecf895f6c328dcba91a7789 (diff)
downloadgsoc2013-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.c20
-rw-r--r--embed/ephy-embed.c81
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