[epiphany/webkit2: 11/17] Port downloads to WebKit2



commit 6ea6fc8156e74d1c1d4eee2974170d145e15c6ce
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Tue Jun 5 08:58:48 2012 +0200

    Port downloads to WebKit2

 embed/ephy-download.c              |  253 ++++++++++++++++++++++++------------
 embed/ephy-embed.c                 |    4 +-
 embed/ephy-web-view.c              |   20 +++-
 lib/widgets/ephy-download-widget.c |  195 ++++++++++++++++++++-------
 lib/widgets/ephy-download-widget.h |    8 +-
 src/ephy-shell.c                   |   31 +++++
 src/ephy-window.c                  |   24 +---
 src/window-commands.c              |   41 ++++++-
 8 files changed, 410 insertions(+), 166 deletions(-)
---
diff --git a/embed/ephy-download.c b/embed/ephy-download.c
index a1821f2..6830f75 100644
--- a/embed/ephy-download.c
+++ b/embed/ephy-download.c
@@ -153,49 +153,55 @@ char *
 ephy_download_get_content_type (EphyDownload *download)
 {
 #ifdef HAVE_WEBKIT2
-  /* TODO: Downloads */
-  return NULL;
+  WebKitURIResponse *response;
 #else
   WebKitNetworkResponse *response;
   SoupMessage *message;
+#endif
   char *content_type = NULL;
-
-  GFile *destination;
-  GFileInfo *info;
   GError *error = NULL;
 
-  destination = g_file_new_for_uri (download->priv->destination);
-  info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
-                            G_FILE_QUERY_INFO_NONE, NULL, &error);
-
-  if (error) {
-    LOG ("ephy_download_get_content_type: error getting file "
-         "content-type: %s", error->message);
-    g_error_free (error);
+  if (download->priv->destination) {
+    GFile *destination;
+    GFileInfo *info;
+
+    destination = g_file_new_for_uri (download->priv->destination);
+    info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+                              G_FILE_QUERY_INFO_NONE, NULL, &error);
+    if (info) {
+      content_type = g_strdup (g_file_info_get_content_type (info));
+      LOG ("ephy_download_get_content_type: GIO: %s", content_type);
+      g_object_unref (info);
+    } else {
+      LOG ("ephy_download_get_content_type: error getting file "
+           "content-type: %s", error->message);
+      g_error_free (error);
+    }
 
-    /* Fallback to Soup */
-    response = webkit_download_get_network_response (download->priv->download);
-    message = webkit_network_response_get_message (response);
+    g_object_unref (destination);
+  }
 
-    if (message != NULL)
-       content_type = g_strdup (soup_message_headers_get_content_type (message->response_headers, NULL));
+  if (content_type)
+    return content_type;
 
-    LOG ("ephy_download_get_content_type: Soup: %s", content_type);
-  } else {
-    content_type = g_strdup (g_file_info_get_content_type (info));
-    LOG ("ephy_download_get_content_type: GIO: %s", content_type);
-  }
+  /* Fallback to Soup */
+#ifdef HAVE_WEBKIT2
+  response = webkit_download_get_response (download->priv->download);
+  if (response)
+    content_type = g_strdup (webkit_uri_response_get_mime_type (response));
+#else
+  response = webkit_download_get_network_response (download->priv->download);
+  message = webkit_network_response_get_message (response);
 
-  if (info)
-    g_object_unref (info);
+  if (message != NULL)
+    content_type = g_strdup (soup_message_headers_get_content_type (message->response_headers, NULL));
+#endif
 
-  if (destination)
-    g_object_unref (destination);
+  LOG ("ephy_download_get_content_type: Soup: %s", content_type);
 
   LOG ("ephy_download_get_content_type: %s", content_type);
 
   return content_type;
-#endif
 }
 
 
@@ -281,20 +287,13 @@ parse_extension (const char *filename)
 }
 
 static char *
-define_destination_uri (EphyDownload *download)
+define_destination_uri (EphyDownload *download, const char *suggested_filename)
 {
   char *dest_dir;
   char *dest_name;
   char *destination_filename;
   char *destination_uri;
-  const char *suggested_filename;
 
-#ifdef HAVE_WEBKIT2
-  /* TODO: Downloads */
-  suggested_filename = NULL;
-#else
-  suggested_filename = webkit_download_get_suggested_filename (download->priv->download);
-#endif
   dest_dir = ephy_file_get_downloads_dir ();
 
   /* Make sure the download directory exists */
@@ -378,9 +377,7 @@ ephy_download_set_destination_uri (EphyDownload *download,
 
   priv->destination = g_strdup (destination);
 
-#ifdef HAVE_WEBKIT2
-  /* TODO: Downloads */
-#else
+#ifndef HAVE_WEBKIT2
   webkit_download_set_destination_uri (priv->download, priv->destination);
 #endif
   g_object_notify (G_OBJECT (download), "destination");
@@ -395,14 +392,19 @@ ephy_download_set_destination_uri (EphyDownload *download,
 void
 ephy_download_set_auto_destination (EphyDownload *download)
 {
+#ifdef HAVE_WEBKIT2
+  /* In WebKit2 priv->destination == NULL means auto_destination */
+#else
   char *dest;
 
   g_return_if_fail (EPHY_IS_DOWNLOAD (download));
 
-  dest = define_destination_uri (download);
+  dest = define_destination_uri (download,
+                                 webkit_download_get_suggested_filename (download->priv->download));
   ephy_download_set_destination_uri (download, dest);
 
   g_free (dest);
+#endif
 }
 
 /**
@@ -608,9 +610,7 @@ ephy_download_start (EphyDownload *download)
 
   if (priv->destination == NULL)
     ephy_download_set_auto_destination (download);
-#ifdef HAVE_WEBKIT2
-  /* TODO: Downloads */
-#else
+#ifndef HAVE_WEBKIT2
   webkit_download_start (priv->download);
 #endif
 }
@@ -649,12 +649,14 @@ ephy_download_do_download_action (EphyDownload *download,
     const char *destination_uri;
     EphyDownloadPrivate *priv;
     gboolean ret = FALSE;
-#ifdef HAVE_WEBKIT2
-    /* TODO: Downloads */
-#else
+
     priv = download->priv;
 
+#ifdef HAVE_WEBKIT2
+    destination_uri = webkit_download_get_destination (priv->download);
+#else
     destination_uri = webkit_download_get_destination_uri (priv->download);
+#endif
     destination = g_file_new_for_uri (destination_uri);
 
     switch ((action ? action : priv->action)) {
@@ -680,7 +682,7 @@ ephy_download_do_download_action (EphyDownload *download,
         break;
     }
     g_object_unref (destination);
-#endif
+
     return ret;
 }
 
@@ -899,7 +901,54 @@ ephy_download_init (EphyDownload *download)
 }
 
 #ifdef HAVE_WEBKIT2
-/* TODO: Downloads */
+static gboolean
+download_decide_destination_cb (WebKitDownload *wk_download,
+                                const gchar *suggested_filename,
+                                EphyDownload *download)
+{
+  char *dest;
+
+  if (download->priv->destination) {
+    webkit_download_set_destination (wk_download, download->priv->destination);
+    return TRUE;
+  }
+
+  dest = define_destination_uri (download, suggested_filename);
+  if (!dest)
+    return FALSE;
+
+  ephy_download_set_destination_uri (download, dest);
+  webkit_download_set_destination (wk_download, dest);
+  g_free (dest);
+
+  return TRUE;
+}
+
+static void
+download_created_destination_cb (WebKitDownload *wk_download,
+                                 const gchar *destination,
+                                 EphyDownload *download)
+{
+  if (download->priv->destination)
+    return;
+
+  ephy_download_set_destination_uri (download, destination);
+}
+
+static void
+download_finished_cb (WebKitDownload *wk_download,
+                      EphyDownload *download)
+{
+  g_signal_emit_by_name (download, "completed");
+
+  if (g_settings_get_boolean (EPHY_SETTINGS_MAIN, EPHY_PREFS_AUTO_DOWNLOADS)) {
+    ephy_download_do_download_action (download, EPHY_DOWNLOAD_ACTION_AUTO);
+  } else {
+    ephy_download_do_download_action (download, EPHY_DOWNLOAD_ACTION_NONE);
+  }
+
+  ephy_embed_shell_remove_download (embed_shell, download);
+}
 #else
 static void
 download_status_changed_cb (GObject *object,
@@ -929,7 +978,20 @@ download_status_changed_cb (GObject *object,
     ephy_embed_shell_add_download (embed_shell, download);
   }
 }
+#endif
 
+#ifdef HAVE_WEBKIT2
+static void
+download_failed_cb (WebKitDownload *wk_download,
+                    GError *error,
+                    EphyDownload *download)
+{
+  gboolean ret = FALSE;
+
+  LOG ("error (%d - %d)! %s", error->code, 0, error->message);
+  g_signal_emit_by_name (download, "error", 0, error->code, error->message, &ret);
+}
+#else
 static gboolean
 download_error_cb (WebKitDownload *download,
                    gint error_code,
@@ -965,53 +1027,62 @@ ephy_download_new (void)
   return g_object_new (EPHY_TYPE_DOWNLOAD, NULL);
 }
 
-static EphyDownload *
-_ephy_download_new (WebKitDownload *webkit_download, const char *uri)
+/**
+ * ephy_download_new_for_download:
+ * @download: a #WebKitDownload to wrap
+ *
+ * Wraps @download in an #EphyDownload.
+ *
+ * Returns: an #EphyDownload.
+ **/
+EphyDownload *
+ephy_download_new_for_download (WebKitDownload *download)
 {
   EphyDownload *ephy_download;
-  ephy_download = ephy_download_new ();
-
 #ifdef HAVE_WEBKIT2
-  /* TODO: Downloads */
-#else
-  if (webkit_download == NULL) {
-    WebKitNetworkRequest *request;
+  WebKitURIRequest *request;
+#endif
 
-    request = webkit_network_request_new (uri);
-    webkit_download = webkit_download_new (request);
+  g_return_val_if_fail (WEBKIT_IS_DOWNLOAD (download), NULL);
 
-    g_return_val_if_fail (webkit_download != NULL, NULL);
-    g_object_unref (request);
-  }
+  ephy_download = ephy_download_new ();
 
-  g_signal_connect (webkit_download, "notify::status",
+#ifdef HAVE_WEBKIT2
+  g_signal_connect (download, "decide-destination",
+                    G_CALLBACK (download_decide_destination_cb),
+                    ephy_download);
+  g_signal_connect (download, "created-destination",
+                    G_CALLBACK (download_created_destination_cb),
+                    ephy_download);
+  g_signal_connect (download, "finished",
+                    G_CALLBACK (download_finished_cb),
+                    ephy_download);
+  g_signal_connect (download, "failed",
+                    G_CALLBACK (download_failed_cb),
+                    ephy_download);
+#else
+  g_signal_connect (download, "notify::status",
                     G_CALLBACK (download_status_changed_cb),
                     ephy_download);
-  g_signal_connect (webkit_download, "error",
+  g_signal_connect (download, "error",
                     G_CALLBACK (download_error_cb),
                     ephy_download);
-
-  ephy_download->priv->download = g_object_ref (webkit_download);
-  ephy_download->priv->source = g_strdup (webkit_download_get_uri (webkit_download));
 #endif
 
-  return ephy_download;
-}
+  ephy_download->priv->download = g_object_ref (download);
+#ifdef HAVE_WEBKIT2
+  request = webkit_download_get_request (download);
+  ephy_download->priv->source = g_strdup (webkit_uri_request_get_uri (request));
+#else
+  ephy_download->priv->source = g_strdup (webkit_download_get_uri (download));
+#endif
 
-/**
- * ephy_download_new_for_download:
- * @download: a #WebKitDownload to wrap
- *
- * Wraps @download in an #EphyDownload.
- *
- * Returns: an #EphyDownload.
- **/
-EphyDownload *
-ephy_download_new_for_download (WebKitDownload *download)
-{
-  g_return_val_if_fail (WEBKIT_IS_DOWNLOAD (download), NULL);
+#ifdef HAVE_WEBKIT2
+  /* In WebKit2 the download has already started */
+  ephy_embed_shell_add_download (embed_shell, ephy_download);
+#endif
 
-  return _ephy_download_new (download, NULL);
+  return ephy_download;
 }
 
 /**
@@ -1025,7 +1096,25 @@ ephy_download_new_for_download (WebKitDownload *download)
 EphyDownload *
 ephy_download_new_for_uri (const char *uri)
 {
+  EphyDownload *ephy_download;
+  WebKitDownload *download;
+#ifndef HAVE_WEBKIT2
+  WebKitNetworkRequest *request;
+#endif
+
   g_return_val_if_fail (uri != NULL, NULL);
 
-  return _ephy_download_new (NULL, uri);
+#ifdef HAVE_WEBKIT2
+  download = webkit_web_context_download_uri (webkit_web_context_get_default (), uri);
+#else
+  request = webkit_network_request_new (uri);
+  download = webkit_download_new (request);
+  g_return_val_if_fail (download != NULL, NULL);
+  g_object_unref (request);
+#endif
+
+  ephy_download = ephy_download_new_for_download (download);
+  g_object_unref (download);
+
+  return ephy_download;
 }
diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c
index 6cff6c0..f0262b5 100644
--- a/embed/ephy-embed.c
+++ b/embed/ephy-embed.c
@@ -551,9 +551,7 @@ ephy_embed_auto_download_url (EphyEmbed *embed, const char *url)
   ephy_download_set_action (download, EPHY_DOWNLOAD_ACTION_OPEN);
 }
 
-#ifdef HAVE_WEBKIT2
-/* TODO: Downloads */
-#else
+#ifndef HAVE_WEBKIT2
 static gboolean
 download_requested_cb (WebKitWebView *web_view,
                        WebKitDownload *download,
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index 90c2884..80f6fa9 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -1710,8 +1710,10 @@ decide_policy_cb (WebKitWebView *web_view,
 {
   WebKitResponsePolicyDecision *response_decision;
   WebKitURIResponse *response;
+  WebKitURIRequest *request;
   EphyWebViewDocumentType type;
   const gchar *mime_type;
+  gboolean handled = FALSE;
 
   if (decision_type != WEBKIT_POLICY_DECISION_TYPE_RESPONSE)
     return FALSE;
@@ -1737,11 +1739,27 @@ decide_policy_cb (WebKitWebView *web_view,
     g_object_notify (G_OBJECT (web_view), "document-type");
   }
 
+  /* If WebKit can't handle the mime type start the download
+     process */
+  if (webkit_web_view_can_show_mime_type (web_view, mime_type))
+    return FALSE;
+
   /* FIXME: check if we need to keep the handle-content,
    * since it looks unused, for now the default wk handler
    * should do the right thing
    */
-  return FALSE;
+  request = webkit_response_policy_decision_get_request (response_decision);
+  g_signal_emit_by_name (ephy_embed_shell_get_embed_single (embed_shell),
+                         "handle-content", mime_type,
+                         webkit_uri_request_get_uri (request),
+                         &handled);
+
+  if (handled)
+    webkit_policy_decision_ignore (decision);
+  else
+    webkit_policy_decision_download (decision);
+
+  return TRUE;
 }
 #else
 static gboolean
diff --git a/lib/widgets/ephy-download-widget.c b/lib/widgets/ephy-download-widget.c
index 936c930..8408652 100644
--- a/lib/widgets/ephy-download-widget.c
+++ b/lib/widgets/ephy-download-widget.c
@@ -46,10 +46,13 @@ struct _EphyDownloadWidgetPrivate
 {
   EphyDownload *download;
 
+  GtkWidget *text;
   GtkWidget *remaining;
   GtkWidget *button;
   GtkWidget *menu;
   GtkWidget *icon;
+
+  gboolean finished;
 };
 
 enum
@@ -77,6 +80,30 @@ get_gicon_from_download (EphyDownload *ephy_download)
 }
 
 static char *
+get_destination_basename_from_download (EphyDownload *ephy_download)
+{
+  WebKitDownload *download;
+  const char *dest;
+  char *basename;
+  char *unescaped;
+
+  download = ephy_download_get_webkit_download (ephy_download);
+#ifdef HAVE_WEBKIT2
+  dest = webkit_download_get_destination (download);
+#else
+  dest = webkit_download_get_destination_uri (download);
+#endif
+  if (!dest)
+    return NULL;
+
+  basename = g_filename_display_basename (dest);
+  unescaped = g_uri_unescape_string (basename, NULL);
+  g_free (basename);
+
+  return unescaped;
+}
+
+static char *
 format_interval (gdouble interval)
 {
    int hours, mins, secs;
@@ -103,17 +130,21 @@ format_interval (gdouble interval)
 static gdouble
 get_remaining_time (WebKitDownload *download)
 {
-#ifdef HAVE_WEBKIT2
-  /* TODO: Downloads */
-  return -1.0;
-#else
   gint64 total, cur;
   gdouble elapsed_time;
   gdouble remaining_time;
   gdouble per_byte_time;
+#ifdef HAVE_WEBKIT2
+  WebKitURIResponse *response;
+
+  response = webkit_download_get_response (download);
+  total = webkit_uri_response_get_content_length (response);
+  cur = webkit_download_get_received_data_length (download);
+#else
 
   total = webkit_download_get_total_size (download);
   cur = webkit_download_get_current_size (download);
+#endif
   elapsed_time = webkit_download_get_elapsed_time (download);
 
   if (cur <= 0)
@@ -123,33 +154,22 @@ get_remaining_time (WebKitDownload *download)
   remaining_time = per_byte_time * (total - cur);
 
   return remaining_time;
-#endif
 }
 
 static void
 download_clicked_cb (GtkButton *button,
                      EphyDownloadWidget *widget)
 {
-#ifdef HAVE_WEBKIT2
-  /* TODO: Downloads */
-#else
-  WebKitDownloadStatus status;
   EphyDownload *download;
 
-  download = widget->priv->download;
-  status = webkit_download_get_status (ephy_download_get_webkit_download (download));
-
-  if (status != WEBKIT_DOWNLOAD_STATUS_FINISHED)
+  if (!widget->priv->finished)
     return;
 
+  download = widget->priv->download;
   if (ephy_download_do_download_action (download, EPHY_DOWNLOAD_ACTION_AUTO))
     gtk_widget_destroy (GTK_WIDGET (widget));
-#endif
 }
 
-#ifdef HAVE_WEBKIT2
-/* TODO: Downloads */
-#else
 static void
 update_download_icon (EphyDownloadWidget *widget)
 {
@@ -173,7 +193,11 @@ update_download_label_and_tooltip (EphyDownloadWidget *widget,
   char *destination;
 
   download = ephy_download_get_webkit_download (widget->priv->download);
+#ifdef HAVE_WEBKIT2
+  destination = g_filename_display_basename (webkit_download_get_destination (download));
+#else
   destination = g_filename_display_basename (webkit_download_get_destination_uri (download));
+#endif
 
   remaining_tooltip = g_markup_printf_escaped ("%s\n%s", destination, download_label);
   g_free (destination);
@@ -186,25 +210,37 @@ update_download_label_and_tooltip (EphyDownloadWidget *widget,
 static gboolean
 download_content_length_is_known (WebKitDownload *download)
 {
+#ifdef HAVE_WEBKIT2
+  WebKitURIResponse *response;
+
+  response = webkit_download_get_response (download);
+  return webkit_uri_response_get_content_length (response);
+#else
   WebKitNetworkResponse *response;
   SoupMessage* message;
 
   response = webkit_download_get_network_response (download);
   message = webkit_network_response_get_message (response);
   return soup_message_headers_get_content_length (message->response_headers) > 0;
+#endif
 }
 
 static void
-widget_progress_cb (GObject *object,
+widget_progress_cb (WebKitDownload *download,
                     GParamSpec *pspec,
                     EphyDownloadWidget *widget)
 {
-  WebKitDownload *download;
   int progress;
   char *download_label = NULL;
 
-  download = WEBKIT_DOWNLOAD (object);
+#ifdef HAVE_WEBKIT2
+  if (!webkit_download_get_destination (download))
+    return;
+
+  progress = webkit_download_get_estimated_progress (download) * 100;
+#else
   progress = webkit_download_get_progress (download) * 100;
+#endif
 
   if (progress % 10 == 0)
     update_download_icon (widget);
@@ -224,7 +260,11 @@ widget_progress_cb (GObject *object,
     gint64 current_size;
 
     /* Unknown content length, show received bytes instead. */
+#ifdef HAVE_WEBKIT2
+    current_size = webkit_download_get_received_data_length (download);
+#else
     current_size = webkit_download_get_current_size (download);
+#endif
     if (current_size > 0)
       download_label = g_format_size (current_size);
   }
@@ -235,21 +275,62 @@ widget_progress_cb (GObject *object,
   }
 }
 
+#ifdef HAVE_WEBKIT2
 static void
-widget_status_cb (GObject *object,
+widget_destination_changed_cb (WebKitDownload *download,
+                               GParamSpec *pspec,
+                               EphyDownloadWidget *widget)
+{
+  char *dest;
+
+  dest = get_destination_basename_from_download (widget->priv->download);
+  gtk_label_set_text (GTK_LABEL (widget->priv->text), dest);
+  g_free (dest);
+}
+
+static void
+widget_finished_cb (WebKitDownload *download,
+                    EphyDownloadWidget *widget)
+{
+  widget->priv->finished = TRUE;
+  update_download_label_and_tooltip (widget, _("Finished"));
+  totem_glow_button_set_glow (TOTEM_GLOW_BUTTON (widget->priv->button), TRUE);
+}
+#else
+static void
+widget_status_cb (WebKitDownload *download,
                   GParamSpec *pspec,
                   EphyDownloadWidget *widget)
 {
   WebKitDownloadStatus status;
 
-  status = webkit_download_get_status (WEBKIT_DOWNLOAD (object));
+  status = webkit_download_get_status (download);
 
-  if (status == WEBKIT_DOWNLOAD_STATUS_FINISHED) {
-    update_download_label_and_tooltip (widget, _("Finished"));
-    totem_glow_button_set_glow (TOTEM_GLOW_BUTTON (widget->priv->button), TRUE);
-  }
+  if (status != WEBKIT_DOWNLOAD_STATUS_FINISHED)
+    return;
+
+  widget->priv->finished = TRUE;
+  update_download_label_and_tooltip (widget, _("Finished"));
+  totem_glow_button_set_glow (TOTEM_GLOW_BUTTON (widget->priv->button), TRUE);
 }
+#endif
 
+#ifdef HAVE_WEBKIT2
+static void
+widget_failed_cb (WebKitDownload *download,
+                  GError *error,
+                  EphyDownloadWidget *widget)
+{
+  char *error_msg;
+
+  g_signal_handlers_disconnect_by_func (download, widget_progress_cb, widget);
+
+  error_msg = g_strdup_printf (_("Error downloading: %s"), error->message);
+  gtk_label_set_text (GTK_LABEL (widget->priv->remaining), error_msg);
+  gtk_widget_set_tooltip_text (GTK_WIDGET (widget), error_msg);
+  g_free (error_msg);
+}
+#else
 static gboolean
 widget_error_cb (WebKitDownload *download,
                  gint error_code,
@@ -301,24 +382,20 @@ download_menu_clicked_cb (GtkWidget *button,
                           GdkEventButton *event,
                           EphyDownloadWidget *widget)
 {
-#ifdef HAVE_WEBKIT2
-  /* TODO: Downloads */
-#else
-  WebKitDownloadStatus status;
-  gboolean finished;
   GtkWidget *item;
   GtkWidget *menu;
   GtkWidget *box;
   GList *children = NULL;
   char *basename, *name;
-
   WebKitDownload *download;
 
   download = ephy_download_get_webkit_download (widget->priv->download);
 
-  status = webkit_download_get_status (download);
-  finished = (status == WEBKIT_DOWNLOAD_STATUS_FINISHED);
+#ifdef HAVE_WEBKIT2
+  basename = g_filename_display_basename (webkit_download_get_destination (download));
+#else
   basename = g_filename_display_basename (webkit_download_get_destination_uri (download));
+#endif
   name = g_uri_unescape_string (basename, NULL);
 
   box = gtk_widget_get_parent (button);
@@ -336,7 +413,7 @@ download_menu_clicked_cb (GtkWidget *button,
 
   item = gtk_menu_item_new_with_label (_("Cancel"));
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-  gtk_widget_set_sensitive (item, !finished);
+  gtk_widget_set_sensitive (item, !widget->priv->finished);
   g_signal_connect (item, "activate",
                     G_CALLBACK (cancel_activate_cb), widget);
 
@@ -345,13 +422,13 @@ download_menu_clicked_cb (GtkWidget *button,
 
   item = gtk_menu_item_new_with_label (_("Open"));
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-  gtk_widget_set_sensitive (item, finished);
+  gtk_widget_set_sensitive (item, widget->priv->finished);
   g_signal_connect (item, "activate",
                     G_CALLBACK (open_activate_cb), widget);
 
   item = gtk_menu_item_new_with_label (_("Show in folder"));
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-  gtk_widget_set_sensitive (item, finished);
+  gtk_widget_set_sensitive (item, widget->priv->finished);
   g_signal_connect (item, "activate",
                     G_CALLBACK (folder_activate_cb), widget);
 
@@ -360,7 +437,6 @@ download_menu_clicked_cb (GtkWidget *button,
   gtk_menu_attach_to_widget (GTK_MENU (menu), button, NULL);
   gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
                   event->button, event->time);
-#endif
 }
 
 static void
@@ -416,7 +492,10 @@ ephy_download_widget_dispose (GObject *object)
     download = ephy_download_get_webkit_download (widget->priv->download);
 
 #ifdef HAVE_WEBKIT2
-    /* TODO: Downloads */
+    g_signal_handlers_disconnect_by_func (download, widget_progress_cb, widget);
+    g_signal_handlers_disconnect_by_func (download, widget_destination_changed_cb, widget);
+    g_signal_handlers_disconnect_by_func (download, widget_finished_cb, widget);
+    g_signal_handlers_disconnect_by_func (download, widget_failed_cb, widget);
 #else
     g_signal_handlers_disconnect_by_func (download, widget_progress_cb, widget);
     g_signal_handlers_disconnect_by_func (download, widget_status_cb, widget);
@@ -487,6 +566,21 @@ ephy_download_widget_get_download (EphyDownloadWidget *widget)
 }
 
 /**
+ * ephy_download_widget_download_finished:
+ * @widget: an #EphyDownloadWidget
+ *
+ * Whether the download finished
+ *
+ * Returns: %TRUE if download operation finished or %FALSE otherwise
+ **/
+gboolean
+ephy_download_widget_download_finished (EphyDownloadWidget *widget)
+{
+  g_return_val_if_fail (EPHY_IS_DOWNLOAD_WIDGET (widget), FALSE);
+  return widget->priv->finished;
+}
+
+/**
  * ephy_download_widget_new:
  * @ephy_download: the #EphyDownload that @widget is wrapping
  *
@@ -507,7 +601,7 @@ ephy_download_widget_new (EphyDownload *ephy_download)
   GtkWidget *menu;
   GtkWidget *remain;
 
-  char *dest, *basename;
+  char *dest;
   WebKitDownload *download;
   GIcon *gicon;
 
@@ -517,14 +611,6 @@ ephy_download_widget_new (EphyDownload *ephy_download)
                          "download", ephy_download, NULL);
   download = ephy_download_get_webkit_download (ephy_download);
 
-#ifdef HAVE_WEBKIT2
-  /* TODO: Downloads */
-  basename = g_strdup ("");
-#else
-  basename = g_filename_display_basename (webkit_download_get_destination_uri (download));
-#endif
-  dest = g_uri_unescape_string (basename, NULL);
-
   grid = gtk_grid_new ();
 
   button = totem_glow_button_new ();
@@ -534,6 +620,7 @@ ephy_download_widget_new (EphyDownload *ephy_download)
   icon = gtk_image_new_from_gicon (gicon, GTK_ICON_SIZE_LARGE_TOOLBAR);
   g_object_unref (gicon);
 
+  dest = get_destination_basename_from_download (ephy_download);
   text = gtk_label_new (dest);
   gtk_misc_set_alignment (GTK_MISC (text), 0, 0.5);
   gtk_label_set_ellipsize (GTK_LABEL (text), PANGO_ELLIPSIZE_END);
@@ -547,17 +634,23 @@ ephy_download_widget_new (EphyDownload *ephy_download)
   gtk_grid_attach (GTK_GRID (grid), remain, 1, 1, 1, 1);
 
   gtk_widget_set_tooltip_text (GTK_WIDGET (widget), dest);
-
-  g_free (basename);
   g_free (dest);
 
+  widget->priv->text = text;
   widget->priv->icon = icon;
   widget->priv->button = button;
   widget->priv->remaining = remain;
   widget->priv->menu = menu;
 
 #ifdef HAVE_WEBKIT2
-  /* TODO: Downloads */
+  g_signal_connect (download, "notify::estimated-progress",
+                    G_CALLBACK (widget_progress_cb), widget);
+  g_signal_connect (download, "notify::destination",
+                    G_CALLBACK (widget_destination_changed_cb), widget);
+  g_signal_connect (download, "finished",
+                    G_CALLBACK (widget_finished_cb), widget);
+  g_signal_connect (download, "failed",
+                    G_CALLBACK (widget_failed_cb), widget);
 #else
   g_signal_connect (download, "notify::progress",
                     G_CALLBACK (widget_progress_cb), widget);
diff --git a/lib/widgets/ephy-download-widget.h b/lib/widgets/ephy-download-widget.h
index b767e5e..2b70055 100644
--- a/lib/widgets/ephy-download-widget.h
+++ b/lib/widgets/ephy-download-widget.h
@@ -57,11 +57,13 @@ struct _EphyDownloadWidgetClass
   GtkBoxClass parent_class;
 };
 
-GType          ephy_download_widget_get_type      (void) G_GNUC_CONST;
+GType          ephy_download_widget_get_type          (void) G_GNUC_CONST;
 
-GtkWidget     *ephy_download_widget_new           (EphyDownload *ephy_download);
+GtkWidget     *ephy_download_widget_new               (EphyDownload *ephy_download);
 
-EphyDownload  *ephy_download_widget_get_download  (EphyDownloadWidget *widget);
+EphyDownload  *ephy_download_widget_get_download      (EphyDownloadWidget *widget);
+
+gboolean       ephy_download_widget_download_finished (EphyDownloadWidget *widget);
 
 G_END_DECLS
 
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index 07a646e..56c524d 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -544,6 +544,31 @@ impl_get_embed_single (EphyEmbedShell *embed_shell)
   return embed_single;
 }
 
+#ifdef HAVE_WEBKIT2
+static void
+download_started_cb (WebKitWebContext *web_context,
+                     WebKitDownload *download,
+                     EphyShell *shell)
+{
+  EphyDownload *ed;
+  EphySession *session;
+  EphyWindow *window;
+
+  /* Is download locked down? */
+  if (g_settings_get_boolean (EPHY_SETTINGS_LOCKDOWN,
+                              EPHY_PREFS_LOCKDOWN_SAVE_TO_DISK)) {
+    webkit_download_cancel (download);
+    return;
+  }
+
+  session = EPHY_SESSION (ephy_shell_get_session (shell));
+  window = ephy_session_get_active_window (session);
+
+  ed = ephy_download_new_for_download (download);
+  ephy_download_set_window (ed, GTK_WIDGET (window));
+}
+#endif
+
 static void
 ephy_shell_init (EphyShell *shell)
 {
@@ -556,6 +581,12 @@ ephy_shell_init (EphyShell *shell)
   ephy_shell = shell;
   g_object_add_weak_pointer (G_OBJECT (ephy_shell),
                              (gpointer *)ptr);
+
+#ifdef HAVE_WEBKIT2
+  g_signal_connect (webkit_web_context_get_default (), "download-started",
+                    G_CALLBACK (download_started_cb),
+                    shell);
+#endif
 }
 
 static void
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 12c1a21..406623c 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -948,24 +948,14 @@ window_has_ongoing_downloads (EphyWindow *window)
 
 	for (l = downloads; l != NULL; l = l->next)
 	{
-#ifdef HAVE_WEBKIT2
-		/* TODO: Downloads */
-#else
-		EphyDownload *download;
-		WebKitDownloadStatus status;
-
 		if (EPHY_IS_DOWNLOAD_WIDGET (l->data) != TRUE)
 			continue;
 
-		download = ephy_download_widget_get_download (EPHY_DOWNLOAD_WIDGET (l->data));
-		status = webkit_download_get_status (ephy_download_get_webkit_download (download));
-
-		if (status == WEBKIT_DOWNLOAD_STATUS_STARTED)
+		if (!ephy_download_widget_download_finished (EPHY_DOWNLOAD_WIDGET (l->data)))
 		{
 			downloading = TRUE;
 			break;
 		}
-#endif
 	}
 	g_list_free (downloads);
 
@@ -3155,23 +3145,13 @@ downloads_close_cb (GtkButton *button, EphyWindow *window)
 
 	for (l = downloads; l != NULL; l = l->next)
 	{
-		EphyDownload *download;
-#ifdef HAVE_WEBKIT2
-		/* TODO: Downloads */
-#else
-		WebKitDownloadStatus status;
-
 		if (EPHY_IS_DOWNLOAD_WIDGET (l->data) != TRUE)
 			continue;
 
-		download = ephy_download_widget_get_download (EPHY_DOWNLOAD_WIDGET (l->data));
-		status = webkit_download_get_status (ephy_download_get_webkit_download (download));
-
-		if (status == WEBKIT_DOWNLOAD_STATUS_FINISHED)
+		if (ephy_download_widget_download_finished (EPHY_DOWNLOAD_WIDGET (l->data)))
 		{
 			gtk_widget_destroy (GTK_WIDGET (l->data));
 		}
-#endif
 	}
 	g_list_free (downloads);
 
diff --git a/src/window-commands.c b/src/window-commands.c
index be0188a..d2325ab 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -374,7 +374,26 @@ take_page_snapshot_and_set_image (EphyApplicationDialogData *data)
 }
 
 #ifdef HAVE_WEBKIT2
-/* TODO: Downloads */
+static void
+download_finished_cb (WebKitDownload *download,
+		      EphyApplicationDialogData *data)
+{
+	char *filename;
+
+	filename = g_filename_from_uri (webkit_download_get_destination (download), NULL, NULL);
+	gtk_image_set_from_file (GTK_IMAGE (data->image), filename);
+	g_free (filename);
+}
+
+static void
+download_failed_cb (WebKitDownload *download,
+		    GError *error,
+		    EphyApplicationDialogData *data)
+{
+	g_signal_handlers_disconnect_by_func (download, download_finished_cb, data);
+	/* Something happened, default to a page snapshot. */
+	take_page_snapshot_and_set_image (data);
+}
 #else
 static void
 download_status_changed_cb (WebKitDownload *download,
@@ -406,25 +425,39 @@ download_status_changed_cb (WebKitDownload *download,
 static void
 download_icon_and_set_image (EphyApplicationDialogData *data)
 {
-#ifdef HAVE_WEBKIT2
-	/* TODO: Downloads */
-#else
+#ifndef HAVE_WEBKIT2
 	WebKitNetworkRequest *request;
+#endif
 	WebKitDownload *download;
 	char *destination, *destination_uri, *tmp_filename;
 
+#ifdef HAVE_WEBKIT2
+	download = webkit_web_context_download_uri (webkit_web_context_get_default (),
+						    data->icon_href);
+#else
 	request = webkit_network_request_new (data->icon_href);
 	download = webkit_download_new (request);
 	g_object_unref (request);
+#endif
 
 	tmp_filename = ephy_file_tmp_filename ("ephy-download-XXXXXX", NULL);
 	destination = g_build_filename (ephy_file_tmp_dir (), tmp_filename, NULL);
 	destination_uri = g_filename_to_uri (destination, NULL, NULL);
+#ifdef HAVE_WEBKIT2
+	webkit_download_set_destination (download, destination_uri);
+#else
 	webkit_download_set_destination_uri (download, destination_uri);
+#endif
 	g_free (destination);
 	g_free (destination_uri);
 	g_free (tmp_filename);
 
+#ifdef HAVE_WEBKIT2
+	g_signal_connect (download, "finished",
+			  G_CALLBACK (download_finished_cb), data);
+	g_signal_connect (download, "failed",
+			  G_CALLBACK (download_failed_cb), data);
+#else
 	g_signal_connect (download, "notify::status",
 			  G_CALLBACK (download_status_changed_cb), data);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]