[epiphany] Add option to always ask where to save downloaded files



commit 9f2fe7a76a8c5421385f174434b9d6d4a72eff49
Author: Jan-Michael Brummer <jan brummer tabos org>
Date:   Sun Mar 17 13:44:21 2019 +0100

    Add option to always ask where to save downloaded files
    
    Fixes: https://gitlab.gnome.org/GNOME/epiphany/issues/147

 data/org.gnome.epiphany.gschema.xml |   5 ++
 embed/ephy-download.c               | 137 +++++++++++++++++++++++++++++++++---
 embed/ephy-download.h               |   1 +
 embed/ephy-filters-manager.c        |   2 +-
 lib/ephy-prefs.h                    |   2 +
 src/prefs-dialog.c                  |   7 ++
 src/resources/gtk/prefs-dialog.ui   |  13 +++-
 7 files changed, 155 insertions(+), 12 deletions(-)
---
diff --git a/data/org.gnome.epiphany.gschema.xml b/data/org.gnome.epiphany.gschema.xml
index 87ae4a6d8..9f3a7d6ff 100644
--- a/data/org.gnome.epiphany.gschema.xml
+++ b/data/org.gnome.epiphany.gschema.xml
@@ -233,6 +233,11 @@
                        <summary>Hardware acceleration policy</summary>
                        <description>Whether to enable hardware acceleration. Possible values are 
“on-demand”, “always”, and “never”. Hardware acceleration may be required to achieve acceptable performance 
on embedded devices, but increases memory usage requirements and could expose severe hardware-specific 
graphics driver bugs. When the policy is “on-demand”, hardware acceleration will be used only when required 
to display 3D transforms.</description>
                </key>
+               <key type="b" name="ask-on-download">
+                       <default>false</default>
+                       <summary>Always ask for download directory</summary>
+                       <description>Whether to present a directory chooser dialog for every 
download.</description>
+               </key>
        </schema>
         <schema id="org.gnome.Epiphany.webapp">
                 <key type="as" name="additional-urls">
diff --git a/embed/ephy-download.c b/embed/ephy-download.c
index 1dffe2271..f0d3a7140 100644
--- a/embed/ephy-download.c
+++ b/embed/ephy-download.c
@@ -25,10 +25,12 @@
 #include "ephy-embed.h"
 #include "ephy-embed-shell.h"
 #include "ephy-embed-type-builtins.h"
+#include "ephy-file-chooser.h"
 #include "ephy-file-helpers.h"
 #include "ephy-flatpak-utils.h"
 #include "ephy-prefs.h"
 #include "ephy-settings.h"
+#include "ephy-string.h"
 
 #include <errno.h>
 #include <glib/gi18n.h>
@@ -745,16 +747,94 @@ download_failed_cb (WebKitDownload *wk_download,
   g_signal_emit (download, signals[ERROR], 0, download->error);
 }
 
-/**
- * ephy_download_new:
- * @download: a #WebKitDownload to wrap
- *
- * Wraps @download in an #EphyDownload.
- *
- * Returns: an #EphyDownload.
- **/
+static void
+filename_suggested_cb (EphyDownload *download,
+                       const char   *suggested_filename,
+                       gpointer      user_data)
+{
+  GApplication *application;
+  GtkWidget *dialog = NULL;
+  GtkWidget *message_area;
+  GtkWidget *box;
+  GtkWindow *toplevel;
+  GtkWidget *type_label;
+  GtkWidget *from_label;
+  GtkWidget *question_label;
+  GtkWidget *filechooser;
+  WebKitDownload *webkit_download;
+  WebKitURIResponse *response;
+  g_autofree gchar *sanitized_filename = NULL;
+  g_autofree gchar *type_text = NULL;
+  g_autofree gchar *from_text = NULL;
+  g_autofree gchar *content_length = NULL;
+  const gchar *content_type;
+
+  application = G_APPLICATION (ephy_embed_shell_get_default ());
+  toplevel = gtk_application_get_active_window (GTK_APPLICATION (application));
+
+  dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel),
+                                   GTK_DIALOG_USE_HEADER_BAR | GTK_DIALOG_DESTROY_WITH_PARENT | 
GTK_DIALOG_MODAL,
+                                   GTK_MESSAGE_QUESTION,
+                                   GTK_BUTTONS_NONE,
+                                   "%s",
+                                   _("Download requested"));
+  gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Download"), 
GTK_RESPONSE_OK, NULL);
+  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), suggested_filename);
+  message_area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog));
+
+  webkit_download = ephy_download_get_webkit_download (download);
+  response = webkit_download_get_response (webkit_download);
+
+  box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+  gtk_box_pack_start (GTK_BOX (message_area), box, TRUE, TRUE, 0);
+
+  /* Type */
+  content_length = g_format_size (webkit_uri_response_get_content_length (response));
+  content_type = ephy_download_get_content_type (download);
+  type_text = g_strdup_printf (_("Type: %s (%s)"), g_content_type_get_description (content_type), 
content_length);
+  type_label = gtk_label_new (type_text);
+  gtk_widget_set_margin_top (type_label, 12);
+  gtk_box_pack_start (GTK_BOX (box), type_label, TRUE, TRUE, 0);
+
+  /* From */
+  from_text = g_strdup_printf (_("From: %s"), ephy_string_get_host_name (webkit_uri_response_get_uri 
(response)));
+  from_label = gtk_label_new (from_text);
+  gtk_box_pack_start (GTK_BOX (box), from_label, TRUE, TRUE, 0);
+
+  /* Question */
+  question_label = gtk_label_new (_("Where do you want to save the file?"));
+  gtk_widget_set_margin_top (question_label, 12);
+  gtk_box_pack_start (GTK_BOX (box), question_label, TRUE, TRUE, 0);
+
+  /* File Chooser Button */
+  filechooser = gtk_file_chooser_button_new (_("Save file"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (filechooser), g_settings_get_string 
(EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_LAST_DOWNLOAD_DIRECTORY));
+  gtk_box_pack_start (GTK_BOX (box), filechooser, TRUE, TRUE, 0);
+
+  gtk_widget_show_all (box);
+
+  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
+    g_autofree gchar *uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (filechooser));
+    g_autofree gchar *folder = g_filename_from_uri (uri, NULL, NULL);
+    g_autofree gchar *path = g_build_filename (uri, suggested_filename, NULL);
+
+    ephy_download_set_destination_uri (download, path);
+
+    webkit_download_set_allow_overwrite (webkit_download, TRUE);
+
+    ephy_downloads_manager_add_download (ephy_embed_shell_get_downloads_manager 
(ephy_embed_shell_get_default ()),
+                                         download);
+
+    g_settings_set_string (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_LAST_DOWNLOAD_DIRECTORY, folder);
+  } else {
+    ephy_download_cancel (download);
+  }
+
+  gtk_widget_destroy (dialog);
+}
+
 EphyDownload *
-ephy_download_new (WebKitDownload *download)
+ephy_download_new_internal (WebKitDownload *download)
 {
   EphyDownload *ephy_download;
 
@@ -784,6 +864,30 @@ ephy_download_new (WebKitDownload *download)
   return ephy_download;
 }
 
+/**
+ * ephy_download_new:
+ * @download: a #WebKitDownload to wrap
+ *
+ * Wraps @download in an #EphyDownload.
+ *
+ * Returns: an #EphyDownload.
+ **/
+EphyDownload *
+ephy_download_new (WebKitDownload *download)
+{
+  EphyDownload *ephy_download;
+
+  ephy_download = ephy_download_new_internal (download);
+
+  if (g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_ASK_ON_DOWNLOAD)) {
+    g_signal_connect (ephy_download, "filename-suggested",
+                      G_CALLBACK (filename_suggested_cb),
+                      NULL);
+  }
+
+  return ephy_download;
+}
+
 /**
  * ephy_download_new_for_uri:
  * @uri: a source URI from where to download
@@ -808,6 +912,21 @@ ephy_download_new_for_uri (const char *uri)
   return ephy_download;
 }
 
+EphyDownload *
+ephy_download_new_for_uri_internal (const char *uri)
+{
+  EphyDownload *ephy_download;
+  g_autoptr(WebKitDownload) download = NULL;
+  EphyEmbedShell *shell = ephy_embed_shell_get_default ();
+
+  g_assert (uri != NULL);
+
+  download = webkit_web_context_download_uri (ephy_embed_shell_get_web_context (shell), uri);
+  ephy_download = ephy_download_new_internal (download);
+
+  return ephy_download;
+}
+
 void
 ephy_download_disable_desktop_notification (EphyDownload *download)
 {
diff --git a/embed/ephy-download.h b/embed/ephy-download.h
index d2435812f..5bcfff2a2 100644
--- a/embed/ephy-download.h
+++ b/embed/ephy-download.h
@@ -38,6 +38,7 @@ typedef enum
 
 EphyDownload *ephy_download_new                   (WebKitDownload *download);
 EphyDownload *ephy_download_new_for_uri           (const char     *uri);
+EphyDownload *ephy_download_new_for_uri_internal  (const char     *uri);
 
 void          ephy_download_cancel                (EphyDownload *download);
 gboolean      ephy_download_is_active             (EphyDownload *download);
diff --git a/embed/ephy-filters-manager.c b/embed/ephy-filters-manager.c
index 0bc00264f..a2094bdca 100644
--- a/embed/ephy-filters-manager.c
+++ b/embed/ephy-filters-manager.c
@@ -147,7 +147,7 @@ start_retrieving_filter_file (EphyFiltersManager *manager,
   AdblockFilterRetrieveData *data;
   char *path;
 
-  download = ephy_download_new_for_uri (filter_url);
+  download = ephy_download_new_for_uri_internal (filter_url);
   path = g_file_get_uri (destination);
   ephy_download_set_destination_uri (download, path);
   ephy_download_disable_desktop_notification (download);
diff --git a/lib/ephy-prefs.h b/lib/ephy-prefs.h
index 430cc99ff..d661f62eb 100644
--- a/lib/ephy-prefs.h
+++ b/lib/ephy-prefs.h
@@ -125,6 +125,7 @@ static const char * const ephy_prefs_state_schema[] = {
 #define EPHY_PREFS_WEB_LAST_UPLOAD_DIRECTORY        "last-upload-directory"
 #define EPHY_PREFS_WEB_LAST_DOWNLOAD_DIRECTORY      "last-download-directory"
 #define EPHY_PREFS_WEB_HARDWARE_ACCELERATION_POLICY "hardware-acceleration-policy"
+#define EPHY_PREFS_WEB_ASK_ON_DOWNLOAD              "ask-on-download"
 
 static const char * const ephy_prefs_web_schema[] = {
   EPHY_PREFS_WEB_FONT_MIN_SIZE,
@@ -155,6 +156,7 @@ static const char * const ephy_prefs_web_schema[] = {
   EPHY_PREFS_WEB_LAST_UPLOAD_DIRECTORY,
   EPHY_PREFS_WEB_LAST_DOWNLOAD_DIRECTORY,
   EPHY_PREFS_WEB_HARDWARE_ACCELERATION_POLICY,
+  EPHY_PREFS_WEB_ASK_ON_DOWNLOAD,
 };
 
 #define EPHY_PREFS_SCHEMA                             "org.gnome.Epiphany"
diff --git a/src/prefs-dialog.c b/src/prefs-dialog.c
index a961dea4f..efed665ab 100644
--- a/src/prefs-dialog.c
+++ b/src/prefs-dialog.c
@@ -96,6 +96,7 @@ struct _PrefsDialog {
   GtkWidget *enable_plugins_checkbutton;
   GtkWidget *enable_safe_browsing_checkbutton;
   GtkWidget *enable_smooth_scrolling_checkbutton;
+  GtkWidget *ask_on_download_checkbutton;
 
   /* fonts & style */
   GtkWidget *use_gnome_fonts_checkbutton;
@@ -992,6 +993,7 @@ prefs_dialog_class_init (PrefsDialogClass *klass)
   gtk_widget_class_bind_template_child (widget_class, PrefsDialog, download_button_hbox);
   gtk_widget_class_bind_template_child (widget_class, PrefsDialog, download_button_label);
   gtk_widget_class_bind_template_child (widget_class, PrefsDialog, download_box);
+  gtk_widget_class_bind_template_child (widget_class, PrefsDialog, ask_on_download_checkbutton);
 
   /* fonts & style */
   gtk_widget_class_bind_template_child (widget_class, PrefsDialog, use_gnome_fonts_checkbutton);
@@ -2025,6 +2027,11 @@ setup_general_page (PrefsDialog *dialog)
                    dialog->enable_smooth_scrolling_checkbutton,
                    "active",
                    G_SETTINGS_BIND_DEFAULT);
+  g_settings_bind (web_settings,
+                   EPHY_PREFS_WEB_ASK_ON_DOWNLOAD,
+                   dialog->ask_on_download_checkbutton,
+                   "active",
+                   G_SETTINGS_BIND_DEFAULT);
 
   if (ephy_is_running_inside_flatpak ())
     gtk_widget_hide (dialog->download_box);
diff --git a/src/resources/gtk/prefs-dialog.ui b/src/resources/gtk/prefs-dialog.ui
index 5d764b33b..4effa5f5c 100644
--- a/src/resources/gtk/prefs-dialog.ui
+++ b/src/resources/gtk/prefs-dialog.ui
@@ -234,7 +234,7 @@
                   <object class="GtkBox" id="download_box">
                     <property name="visible">True</property>
                     <property name="orientation">vertical</property>
-                    <property name="spacing">18</property>
+                    <property name="spacing">6</property>
                     <child>
                       <object class="GtkBox">
                         <property name="visible">True</property>
@@ -250,12 +250,21 @@
                             </attributes>
                           </object>
                         </child>
+                        <child>
+                          <object class="GtkCheckButton" id="ask_on_download_checkbutton">
+                            <property name="label" translatable="yes">Always ask o_n download</property>
+                            <property name="visible">True</property>
+                            <property name="use-underline">True</property>
+                            <property name="margin-start">12</property>
+                          </object>
+                        </child>
                         <child>
                           <object class="GtkBox">
                             <property name="visible">True</property>
                             <property name="orientation">vertical</property>
                             <property name="spacing">6</property>
-                            <property name="margin-start">12</property>
+                            <property name="margin-start">24</property>
+                            <property name="sensitive" bind-source="ask_on_download_checkbutton" 
bind-property="active" bind-flags="sync-create|invert-boolean"/>
                             <child>
                               <object class="GtkBox" id="download_button_hbox">
                                 <property name="visible">True</property>


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