Initial support for WebKitDownload

At this point all downloads run automatically and appear in the
statusbar. The destination folder can be chosen in the preferences.
Download can be cancelled. The context menu works as well.
This commit is contained in:
Christian Dywan 2009-03-19 18:28:50 +01:00
parent b602178630
commit 7af8baee8b
5 changed files with 219 additions and 15 deletions

View file

@ -1,3 +1,4 @@
BOOLEAN:OBJECT
BOOLEAN:VOID BOOLEAN:VOID
VOID:BOOLEAN,STRING VOID:BOOLEAN,STRING
VOID:OBJECT,ENUM VOID:OBJECT,ENUM

View file

@ -65,6 +65,7 @@ struct _MidoriBrowser
gboolean find_typing; gboolean find_typing;
GtkWidget* statusbar; GtkWidget* statusbar;
GtkWidget* transferbar;
GtkWidget* progressbar; GtkWidget* progressbar;
gchar* statusbar_text; gchar* statusbar_text;
@ -893,6 +894,117 @@ midori_view_new_view_cb (GtkWidget* view,
} }
} }
#if WEBKIT_CHECK_VERSION (1, 1, 3)
static void
midori_browser_download_notify_progress_cb (WebKitDownload* download,
GParamSpec* pspec,
GtkWidget* progress)
{
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress),
webkit_download_get_progress (download));
}
static void
midori_browser_download_notify_status_cb (WebKitDownload* download,
GParamSpec* pspec,
GtkWidget* button)
{
switch (webkit_download_get_status (download))
{
case WEBKIT_DOWNLOAD_STATUS_FINISHED:
{
GtkWidget* icon;
icon = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), icon);
/* FIXME: Implement opening of files */
gtk_widget_set_sensitive (button, FALSE);
break;
}
case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
case WEBKIT_DOWNLOAD_STATUS_ERROR:
gtk_widget_set_sensitive (button, FALSE);
break;
default:
break;
}
}
static void
midori_browser_download_button_clicked_cb (GtkWidget* button,
WebKitDownload* download)
{
switch (webkit_download_get_status (download))
{
case WEBKIT_DOWNLOAD_STATUS_STARTED:
webkit_download_cancel (download);
break;
default:
break;
}
}
static void
midori_browser_add_download_item (MidoriBrowser* browser,
WebKitDownload* download)
{
GtkWidget* box;
GtkWidget* icon;
GtkWidget* button;
GtkWidget* progress;
box = gtk_hbox_new (FALSE, 0);
/* icon = gtk_image_new_from_stock (STOCK_TRANSFER, GTK_ICON_SIZE_MENU);
gtk_box_pack_start (GTK_BOX (box), icon, FALSE, FALSE, 0); */
progress = gtk_progress_bar_new ();
gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (progress),
PANGO_ELLIPSIZE_MIDDLE);
gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progress),
webkit_download_get_suggested_filename (download));
/* Avoid a bug in WebKit */
if (webkit_download_get_status (download) != WEBKIT_DOWNLOAD_STATUS_CREATED)
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress),
webkit_download_get_progress (download));
gtk_box_pack_start (GTK_BOX (box), progress, FALSE, FALSE, 0);
icon = gtk_image_new_from_stock (GTK_STOCK_CANCEL, GTK_ICON_SIZE_MENU);
button = gtk_button_new ();
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
gtk_container_add (GTK_CONTAINER (button), icon);
gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0);
gtk_widget_show_all (box);
gtk_box_pack_start (GTK_BOX (browser->transferbar), box,
FALSE, FALSE, 3);
g_signal_connect (download, "notify::progress",
G_CALLBACK (midori_browser_download_notify_progress_cb), progress);
g_signal_connect (download, "notify::status",
G_CALLBACK (midori_browser_download_notify_status_cb), button);
g_signal_connect (button, "clicked",
G_CALLBACK (midori_browser_download_button_clicked_cb), download);
}
static gboolean
midori_view_download_requested_cb (GtkWidget* view,
WebKitDownload* download,
MidoriBrowser* browser)
{
if (!webkit_download_get_destination_uri (download))
{
gchar* folder = katze_object_get_string (browser->settings,
"download-folder");
gchar* filename = g_build_filename (folder,
webkit_download_get_suggested_filename (download), NULL);
g_free (folder);
gchar* uri = g_filename_to_uri (filename, NULL, NULL);
g_free (filename);
webkit_download_set_destination_uri (download, uri);
g_free (uri);
}
midori_browser_add_download_item (browser, download);
return TRUE;
}
#endif
static void static void
midori_view_search_text_cb (GtkWidget* view, midori_view_search_text_cb (GtkWidget* view,
gboolean found, gboolean found,
@ -1017,6 +1129,10 @@ _midori_browser_add_tab (MidoriBrowser* browser,
midori_view_new_window_cb, browser, midori_view_new_window_cb, browser,
"signal::new-view", "signal::new-view",
midori_view_new_view_cb, browser, midori_view_new_view_cb, browser,
#if WEBKIT_CHECK_VERSION (1, 1, 3)
"signal::download-requested",
midori_view_download_requested_cb, browser,
#endif
"signal::search-text", "signal::search-text",
midori_view_search_text_cb, browser, midori_view_search_text_cb, browser,
"signal::add-bookmark", "signal::add-bookmark",
@ -1782,9 +1898,9 @@ midori_browser_toolbar_popup_context_menu_cb (GtkWidget* widget,
menuitem = sokoke_action_create_popup_menu_item ( menuitem = sokoke_action_create_popup_menu_item (
_action_by_name (browser, "Bookmarkbar")); _action_by_name (browser, "Bookmarkbar"));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
menuitem = sokoke_action_create_popup_menu_item ( /*menuitem = sokoke_action_create_popup_menu_item (
_action_by_name (browser, "Transferbar")); _action_by_name (browser, "Transferbar"));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); */
menuitem = sokoke_action_create_popup_menu_item ( menuitem = sokoke_action_create_popup_menu_item (
_action_by_name (browser, "Statusbar")); _action_by_name (browser, "Statusbar"));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
@ -3204,10 +3320,10 @@ static const GtkToggleActionEntry toggle_entries[] = {
N_("_Bookmarkbar"), "", N_("_Bookmarkbar"), "",
N_("Show bookmarkbar"), G_CALLBACK (_action_bookmarkbar_activate), N_("Show bookmarkbar"), G_CALLBACK (_action_bookmarkbar_activate),
FALSE }, FALSE },
{ "Transferbar", NULL, /* { "Transferbar", NULL,
N_("_Transferbar"), "", N_("_Transferbar"), "",
N_("Show transferbar"), NULL/*G_CALLBACK (_action_transferbar_activate)*/, N_("Show transferbar"), G_CALLBACK (_action_transferbar_activate),
FALSE }, FALSE }, */
{ "Statusbar", NULL, { "Statusbar", NULL,
N_("_Statusbar"), "", N_("_Statusbar"), "",
N_("Show statusbar"), G_CALLBACK (_action_statusbar_activate), N_("Show statusbar"), G_CALLBACK (_action_statusbar_activate),
@ -3335,7 +3451,7 @@ static const gchar* ui_markup =
"<menuitem action='Menubar'/>" "<menuitem action='Menubar'/>"
"<menuitem action='Navigationbar'/>" "<menuitem action='Navigationbar'/>"
"<menuitem action='Bookmarkbar'/>" "<menuitem action='Bookmarkbar'/>"
"<menuitem action='Transferbar'/>" /* "<menuitem action='Transferbar'/>" */
"<menuitem action='Statusbar'/>" "<menuitem action='Statusbar'/>"
"</menu>" "</menu>"
"<menuitem action='Panel'/>" "<menuitem action='Panel'/>"
@ -3636,8 +3752,6 @@ midori_browser_init (MidoriBrowser* browser)
g_error_free (error); g_error_free (error);
} }
/* _action_set_active(browser, "Transferbar", config->toolbarTransfers); */
/* Hide the 'Dummy' which only holds otherwise unused actions */ /* Hide the 'Dummy' which only holds otherwise unused actions */
g_object_set (_action_by_name (browser, "Dummy"), "visible", FALSE, NULL); g_object_set (_action_by_name (browser, "Dummy"), "visible", FALSE, NULL);
@ -3797,7 +3911,8 @@ midori_browser_init (MidoriBrowser* browser)
g_object_set (_action_by_name (browser, "Menubar"), "visible", FALSE, NULL); g_object_set (_action_by_name (browser, "Menubar"), "visible", FALSE, NULL);
g_object_set (_action_by_name (browser, "Statusbar"), "visible", FALSE, NULL); g_object_set (_action_by_name (browser, "Statusbar"), "visible", FALSE, NULL);
#endif #endif
_action_set_sensitive (browser, "Transferbar", FALSE); /* if (!g_signal_lookup ("download-requested", WEBKIT_TYPE_WEB_VIEW))
_action_set_sensitive (browser, "Transferbar", FALSE); */
_action_set_sensitive (browser, "EncodingCustom", FALSE); _action_set_sensitive (browser, "EncodingCustom", FALSE);
_action_set_sensitive (browser, "SelectionSourceView", FALSE); _action_set_sensitive (browser, "SelectionSourceView", FALSE);
@ -3982,12 +4097,18 @@ midori_browser_init (MidoriBrowser* browser)
gtk_widget_modify_style (browser->statusbar, rcstyle); gtk_widget_modify_style (browser->statusbar, rcstyle);
g_object_unref (rcstyle); g_object_unref (rcstyle);
gtk_box_pack_start (GTK_BOX (vbox), browser->statusbar, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), browser->statusbar, FALSE, FALSE, 0);
browser->progressbar = gtk_progress_bar_new (); browser->progressbar = gtk_progress_bar_new ();
/* Set the progressbar's height to 1 to fit it in the statusbar */ /* Set the progressbar's height to 1 to fit it in the statusbar */
gtk_widget_set_size_request (browser->progressbar, -1, 1); gtk_widget_set_size_request (browser->progressbar, -1, 1);
gtk_box_pack_start (GTK_BOX (browser->statusbar), browser->progressbar, gtk_box_pack_start (GTK_BOX (browser->statusbar), browser->progressbar,
FALSE, FALSE, 3); FALSE, FALSE, 3);
browser->transferbar = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (browser->statusbar), browser->transferbar,
FALSE, FALSE, 3);
gtk_widget_show (browser->transferbar);
g_object_unref (ui_manager); g_object_unref (ui_manager);
} }

View file

@ -422,10 +422,12 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
SPANNED_ADD (button, 0, 2, 2, 3); SPANNED_ADD (button, 0, 2, 2, 3);
FRAME_NEW (_("Transfers")); FRAME_NEW (_("Transfers"));
TABLE_NEW (3, 2); TABLE_NEW (3, 2);
#if WEBKIT_CHECK_VERSION (1, 1, 3)
label = katze_property_label (settings, "download-folder"); label = katze_property_label (settings, "download-folder");
INDENTED_ADD (label, 0, 1, 0, 1); INDENTED_ADD (label, 0, 1, 0, 1);
button = katze_property_proxy (settings, "download-folder", "folder"); button = katze_property_proxy (settings, "download-folder", "folder");
FILLED_ADD (button, 1, 2, 0, 1); FILLED_ADD (button, 1, 2, 0, 1);
#else
label = katze_property_label (settings, "download-manager"); label = katze_property_label (settings, "download-manager");
INDENTED_ADD (label, 0, 1, 1, 2); INDENTED_ADD (label, 0, 1, 1, 2);
hbox = gtk_hbox_new (FALSE, 4); hbox = gtk_hbox_new (FALSE, 4);
@ -440,6 +442,7 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
g_signal_connect (entry, "focus-out-event", g_signal_connect (entry, "focus-out-event",
G_CALLBACK (proxy_download_manager_icon_cb), button); G_CALLBACK (proxy_download_manager_icon_cb), button);
FILLED_ADD (hbox, 1, 2, 1, 2); FILLED_ADD (hbox, 1, 2, 1, 2);
#endif
label = katze_property_label (settings, "text-editor"); label = katze_property_label (settings, "text-editor");
INDENTED_ADD (label, 0, 1, 2, 3); INDENTED_ADD (label, 0, 1, 2, 3);
hbox = gtk_hbox_new (FALSE, 4); hbox = gtk_hbox_new (FALSE, 4);

View file

@ -143,6 +143,7 @@ enum {
NEW_TAB, NEW_TAB,
NEW_WINDOW, NEW_WINDOW,
NEW_VIEW, NEW_VIEW,
DOWNLOAD_REQUESTED,
SEARCH_TEXT, SEARCH_TEXT,
ADD_BOOKMARK, ADD_BOOKMARK,
SAVE_AS, SAVE_AS,
@ -271,6 +272,36 @@ midori_view_class_init (MidoriViewClass* class)
MIDORI_TYPE_VIEW, MIDORI_TYPE_VIEW,
MIDORI_TYPE_NEW_VIEW); MIDORI_TYPE_NEW_VIEW);
/**
* MidoriView::download-requested:
* @view: the object on which the signal is emitted
* @download: a new download
*
* Emitted when a new download is requested, if a
* file cannot be displayed or a download was started
* from the context menu.
*
* If the download should be accepted, a callback
* has to return %TRUE, and the download will also
* be started automatically.
*
* Note: This requires WebKitGTK 1.1.3.
*
* Return value: %TRUE if the download was handled
*
* Since: 0.1.5
*/
signals[DOWNLOAD_REQUESTED] = g_signal_new (
"download-requested",
G_TYPE_FROM_CLASS (class),
(GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
0,
g_signal_accumulator_true_handled,
NULL,
midori_cclosure_marshal_BOOLEAN__OBJECT,
G_TYPE_BOOLEAN, 1,
G_TYPE_OBJECT);
/** /**
* MidoriView::search-text: * MidoriView::search-text:
* @view: the object on which the signal is emitted * @view: the object on which the signal is emitted
@ -619,7 +650,12 @@ webkit_web_frame_load_done_cb (WebKitWebFrame* web_frame,
gchar* title; gchar* title;
gchar* data; gchar* data;
#if WEBKIT_CHECK_VERSION (1, 1, 3)
if (!success && webkit_web_view_can_show_mime_type (
WEBKIT_WEB_VIEW (view->web_view), view->mime_type))
#else
if (!success) if (!success)
#endif
{ {
/* i18n: The title of the 404 - Not found error page */ /* i18n: The title of the 404 - Not found error page */
title = g_strdup_printf (_("Not found - %s"), view->uri); title = g_strdup_printf (_("Not found - %s"), view->uri);
@ -886,6 +922,7 @@ midori_web_view_menu_search_web_activate_cb (GtkWidget* widget,
g_free (uri); g_free (uri);
} }
#if !WEBKIT_CHECK_VERSION (1, 1, 3)
static void static void
midori_web_view_menu_save_as_activate_cb (GtkWidget* widget, midori_web_view_menu_save_as_activate_cb (GtkWidget* widget,
MidoriView* view) MidoriView* view)
@ -899,6 +936,7 @@ midori_web_view_menu_download_activate_cb (GtkWidget* widget,
{ {
sokoke_spawn_program (view->download_manager, view->link_uri); sokoke_spawn_program (view->download_manager, view->link_uri);
} }
#endif
static void static void
midori_web_view_menu_add_bookmark_activate_cb (GtkWidget* widget, midori_web_view_menu_add_bookmark_activate_cb (GtkWidget* widget,
@ -977,6 +1015,11 @@ webkit_web_view_populate_popup_cb (WebKitWebView* web_view,
G_CALLBACK (midori_web_view_menu_new_window_activate_cb), view); G_CALLBACK (midori_web_view_menu_new_window_activate_cb), view);
menuitem = (GtkWidget*)g_list_nth_data (items, 3); menuitem = (GtkWidget*)g_list_nth_data (items, 3);
g_list_free (items); g_list_free (items);
#if WEBKIT_CHECK_VERSION (1, 1, 3)
/* hack to localize menu item */
label = gtk_bin_get_child (GTK_BIN (menuitem));
gtk_label_set_label (GTK_LABEL (label), _("_Download Link destination"));
#else
/* hack to disable non-functional Download File /* hack to disable non-functional Download File
FIXME: Make sure this really is the right menu item */ FIXME: Make sure this really is the right menu item */
gtk_widget_hide (menuitem); gtk_widget_hide (menuitem);
@ -998,6 +1041,7 @@ webkit_web_view_populate_popup_cb (WebKitWebView* web_view,
G_CALLBACK (midori_web_view_menu_download_activate_cb), view); G_CALLBACK (midori_web_view_menu_download_activate_cb), view);
gtk_widget_show (menuitem); gtk_widget_show (menuitem);
} }
#endif
menuitem = gtk_image_menu_item_new_from_stock (STOCK_BOOKMARK_ADD, NULL); menuitem = gtk_image_menu_item_new_from_stock (STOCK_BOOKMARK_ADD, NULL);
gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 5); gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 5);
g_signal_connect (menuitem, "activate", g_signal_connect (menuitem, "activate",
@ -1144,12 +1188,14 @@ webkit_web_view_mime_type_decision_cb (GtkWidget* web_view,
midori_view_update_icon (view, NULL); midori_view_update_icon (view, NULL);
g_object_notify (G_OBJECT (view), "mime-type"); g_object_notify (G_OBJECT (view), "mime-type");
/* TODO: Display contents with a Viewable if WebKit can't do it */
/* TODO: Offer downloading file if it cannot be displayed at all */
if (webkit_web_view_can_show_mime_type (WEBKIT_WEB_VIEW (web_view), mime_type)) if (webkit_web_view_can_show_mime_type (WEBKIT_WEB_VIEW (web_view), mime_type))
return FALSE; return FALSE;
#if WEBKIT_CHECK_VERSION (1, 1, 3)
webkit_web_policy_decision_download (decision);
return TRUE;
#endif
uri = g_strdup_printf ("error:nodisplay %s", uri = g_strdup_printf ("error:nodisplay %s",
webkit_network_request_get_uri (request)); webkit_network_request_get_uri (request));
midori_view_set_uri (view, uri); midori_view_set_uri (view, uri);
@ -1158,6 +1204,18 @@ webkit_web_view_mime_type_decision_cb (GtkWidget* web_view,
return TRUE; return TRUE;
} }
#if WEBKIT_CHECK_VERSION (1, 1, 3)
static gboolean
webkit_web_view_download_requested_cb (GtkWidget* web_view,
WebKitDownload* download,
MidoriView* view)
{
gboolean handled;
g_signal_emit (view, signals[DOWNLOAD_REQUESTED], 0, download, &handled);
return handled;
}
#endif
static void static void
webkit_web_view_console_message_cb (GtkWidget* web_view, webkit_web_view_console_message_cb (GtkWidget* web_view,
const gchar* message, const gchar* message,
@ -1576,7 +1634,12 @@ midori_view_construct_web_view (MidoriView* view)
webkit_web_view_create_web_view_cb, view, webkit_web_view_create_web_view_cb, view,
"signal::mime-type-policy-decision-requested", "signal::mime-type-policy-decision-requested",
webkit_web_view_mime_type_decision_cb, view, webkit_web_view_mime_type_decision_cb, view,
#if WEBKIT_CHECK_VERSION (1, 1, 3)
"signal::download-requested",
webkit_web_view_download_requested_cb, view,
#endif
NULL); NULL);
g_object_connect (web_frame, g_object_connect (web_frame,
"signal::load-done", "signal::load-done",
webkit_web_frame_load_done_cb, view, webkit_web_frame_load_done_cb, view,

View file

@ -291,6 +291,18 @@ midori_web_settings_get_property (GObject* object,
GValue* value, GValue* value,
GParamSpec* pspec); GParamSpec* pspec);
static const gchar*
midori_get_download_dir (void)
{
const gchar* dir = g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD);
if (dir)
{
g_mkdir_with_parents (dir, 0700);
return dir;
}
return g_get_home_dir ();
}
static void static void
midori_web_settings_class_init (MidoriWebSettingsClass* class) midori_web_settings_class_init (MidoriWebSettingsClass* class)
{ {
@ -525,8 +537,12 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
"download-folder", "download-folder",
_("Download Folder"), _("Download Folder"),
_("The folder downloaded files are saved to"), _("The folder downloaded files are saved to"),
g_get_home_dir (), midori_get_download_dir (),
G_PARAM_READABLE)); #if WEBKIT_CHECK_VERSION (1, 1, 3)
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
#else
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
#endif
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_DOWNLOAD_MANAGER, PROP_DOWNLOAD_MANAGER,
@ -584,7 +600,6 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
TRUE, TRUE,
flags)); flags));
g_type_class_ref (WEBKIT_TYPE_WEB_VIEW);
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_OPEN_NEW_PAGES_IN, PROP_OPEN_NEW_PAGES_IN,
g_param_spec_enum ( g_param_spec_enum (
@ -845,6 +860,7 @@ notify_default_encoding_cb (GObject* object,
static void static void
midori_web_settings_init (MidoriWebSettings* web_settings) midori_web_settings_init (MidoriWebSettings* web_settings)
{ {
web_settings->download_folder = g_strdup (midori_get_download_dir ());
web_settings->http_proxy = NULL; web_settings->http_proxy = NULL;
web_settings->open_popups_in_tabs = TRUE; web_settings->open_popups_in_tabs = TRUE;
web_settings->remember_last_form_inputs = TRUE; web_settings->remember_last_form_inputs = TRUE;