aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustavo Noronha Silva <kov@debian.org>2009-05-23 05:42:46 +0800
committerGustavo Noronha Silva <kov@debian.org>2009-05-23 05:42:46 +0800
commit9365ffd004d6260e656453143eb32f333ae888a2 (patch)
tree911b14b0468173bb4b19961bf8aa5c99b8acd7a3
parent36a1ff182877766efa44d8b61eb0bc27e7716db1 (diff)
downloadgsoc2013-epiphany-9365ffd004d6260e656453143eb32f333ae888a2.tar.gz
gsoc2013-epiphany-9365ffd004d6260e656453143eb32f333ae888a2.tar.zst
gsoc2013-epiphany-9365ffd004d6260e656453143eb32f333ae888a2.zip
Reimplement the original download logic and dialog.
We are still missing some of the MIME logic, pending on a WebKit feature landing.
-rw-r--r--embed/downloader-view.c51
-rw-r--r--embed/downloader-view.h17
-rw-r--r--embed/webkit/webkit-embed.c164
3 files changed, 229 insertions, 3 deletions
diff --git a/embed/downloader-view.c b/embed/downloader-view.c
index b15459204..3bb56c13f 100644
--- a/embed/downloader-view.c
+++ b/embed/downloader-view.c
@@ -416,6 +416,39 @@ ephy_download_get_remaining_time (WebKitDownload *download)
}
static void
+do_open_downloaded_file (DownloaderView *dv, WebKitDownload *download, gboolean open_location)
+{
+ 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);
+
+ gdk_display = gtk_widget_get_display (priv->window);
+ if (open_location)
+ {
+ ephy_file_browse_to (downloaded_file, gdk_x11_display_get_user_time (gdk_display));
+ }
+ else
+ {
+ ephy_file_launch_handler (NULL, downloaded_file,
+ gdk_x11_display_get_user_time (gdk_display));
+ }
+ g_object_unref (downloaded_file);
+}
+
+static void
+open_downloaded_file (DownloaderView *dv, WebKitDownload *download)
+{
+ do_open_downloaded_file (dv, download, FALSE);
+}
+
+static void
+open_downloaded_file_location (DownloaderView *dv, WebKitDownload *download)
+{
+ do_open_downloaded_file (dv, download, TRUE);
+}
+
+static void
update_download_row (DownloaderView *dv, WebKitDownload *download)
{
GtkTreeRowReference *row_ref;
@@ -427,7 +460,7 @@ update_download_row (DownloaderView *dv, WebKitDownload *download)
char *remaining, *file, *cur_progress, *name;
struct tm;
int percent = 0;
-
+ DownloadAction action;
#ifdef HAVE_LIBNOTIFY
char *downloaded;
#endif
@@ -451,6 +484,22 @@ update_download_row (DownloaderView *dv, WebKitDownload *download)
downloader_view_remove_download (dv, download);
return;
case WEBKIT_DOWNLOAD_STATUS_FINISHED:
+ action = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(download),
+ "download-action"));
+
+ switch (action)
+ {
+ case DOWNLOAD_ACTION_OPEN:
+ open_downloaded_file (dv, download);
+ break;
+ case DOWNLOAD_ACTION_OPEN_LOCATION:
+ open_downloaded_file_location (dv, download);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
downloader_view_remove_download (dv, download);
#ifdef HAVE_LIBNOTIFY
downloaded = g_strdup_printf (_("The file “%s” has been downloaded."),
diff --git a/embed/downloader-view.h b/embed/downloader-view.h
index 82cb101f0..e331cca02 100644
--- a/embed/downloader-view.h
+++ b/embed/downloader-view.h
@@ -52,6 +52,23 @@ struct _DownloaderViewClass
EphyDialogClass parent_class;
};
+/* These represent actions to be performed after the download is
+ * successfully completed; NONE means no download will happen,
+ * DOWNLOAD is just a way to tell the mime content handler that a file
+ * chooser should be displayed so that the user can select where to
+ * download to, and is usually turned into OPEN_LOCATION after that
+ * happens (in other words, DOWNLOAD will never be an action when the
+ * download is finished). OPEN will try to run the default application
+ * that handles that file type.
+ */
+typedef enum
+{
+ DOWNLOAD_ACTION_NONE,
+ DOWNLOAD_ACTION_DOWNLOAD,
+ DOWNLOAD_ACTION_OPEN,
+ DOWNLOAD_ACTION_OPEN_LOCATION
+} DownloadAction;
+
GType downloader_view_get_type (void);
DownloaderView *downloader_view_new (void);
diff --git a/embed/webkit/webkit-embed.c b/embed/webkit/webkit-embed.c
index 87173fb71..a04abc245 100644
--- a/embed/webkit/webkit-embed.c
+++ b/embed/webkit/webkit-embed.c
@@ -36,6 +36,7 @@
#include "ephy-embed-shell.h"
#include "ephy-embed-single.h"
#include "ephy-embed-persist.h"
+#include "ephy-stock-icons.h"
#include "ephy-string.h"
#include "ephy-embed-event.h"
#include "ephy-embed-utils.h"
@@ -436,6 +437,7 @@ download_requested_dialog_response_cb (GtkDialog *dialog,
}
gtk_widget_destroy (GTK_WIDGET (dialog));
+ g_object_unref (download);
}
static void
@@ -453,7 +455,7 @@ request_destination_uri (WebKitWebView *web_view,
* 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));
+ window = gtk_widget_get_toplevel (GTK_WIDGET (web_view));
if (!GTK_WIDGET_TOPLEVEL (window))
window = NULL;
@@ -523,9 +525,161 @@ perform_auto_download (WebKitDownload *download)
}
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);
}
+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 = EPHY_DOWNLOADER_VIEW (ephy_embed_shell_get_downloader_view (embed_shell));
+
+ 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;
+ }
+ downloader_view_add_download (dview, download);
+ }
+ g_object_unref (download);
+ return;
+ }
+
+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, *button, *image;
+ const char *action_label;
+ char *mime_description;
+ EphyMimePermission mime_permission;
+ GAppInfo *helper_app;
+ const char *suggested_filename;
+
+ parent_window = gtk_widget_get_toplevel (GTK_WIDGET(web_view));
+ if (!GTK_WIDGET_TOPLEVEL (parent_window))
+ parent_window = NULL;
+
+ /* FIXME: we still have no way of getting the content type from
+ * webkit yet; we need to have a proper WebKitNetworkRequest
+ * implementation to do this here; see
+ * https://bugs.webkit.org/show_bug.cgi?id=18608
+ */
+ helper_app = NULL;
+ mime_description = NULL;
+ mime_permission = EPHY_MIME_PERMISSION_SAFE;
+ if (mime_description == NULL) {
+ /* Translators: The text before the "|" is context to help you decide on
+ * the correct translation. You MUST OMIT it in the translated string. */
+ mime_description = g_strdup (Q_("File Type:|Unknown"));
+ action = DOWNLOAD_ACTION_OPEN_LOCATION;
+ }
+
+ /* OPEN will never happen here, for now; see comment about
+ * WebKitNetworkRequest above!
+ */
+ 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) {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (parent_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE,
+ _("Download this potentially unsafe file?"));
+
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ /* translators: First %s is the file type description,
+ Second %s is the file name */
+ _("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);
+ } else if (action == DOWNLOAD_ACTION_OPEN && helper_app) {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (parent_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
+ _("Open this file?"));
+
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ /* translators: First %s is the file type description,
+ Second %s is the file name,
+ Third %s is the application used to open the file */
+ _("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 {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (parent_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
+ _("Download this file?"));
+
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ /* translators: First %s is the file type description,
+ Second %s is the file name */
+ _("File Type: “%s”.\n\nYou have no application able to open “%s”. "
+ "You can download it instead."),
+ mime_description, suggested_filename);
+ }
+
+ g_free (mime_description);
+
+ button = gtk_button_new_with_label (_("_Save As..."));
+ image = gtk_image_new_from_stock (GTK_STOCK_SAVE_AS, GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (button), image);
+ /* don't show the image! see bug #307818 */
+ gtk_widget_show (button);
+ gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, 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);
+
+ int 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 gboolean
download_requested_cb (WebKitWebView *web_view,
WebKitDownload *download)
@@ -547,7 +701,13 @@ download_requested_cb (WebKitWebView *web_view,
if (!define_destination_uri (download, TRUE))
return FALSE;
- request_destination_uri (web_view, download);
+ /* FIXME: when we are able to obtain the MIME information from
+ * WebKit, we will want to decide earlier whether we want to open or
+ * open the location to where the file was downloaded. See
+ * perform_auto_download, too.
+ */
+ g_object_ref (download); /* balanced in confirm_action_response_cb */
+ confirm_action_from_mime (web_view, download, DOWNLOAD_ACTION_DOWNLOAD);
return TRUE;
}