diff --git a/midori/marshal.list b/midori/marshal.list index c82c5639..825f9730 100644 --- a/midori/marshal.list +++ b/midori/marshal.list @@ -1,3 +1,4 @@ +BOOLEAN:OBJECT BOOLEAN:VOID VOID:BOOLEAN,STRING VOID:OBJECT,ENUM diff --git a/midori/midori-browser.c b/midori/midori-browser.c index 647542ea..e667e7e3 100644 --- a/midori/midori-browser.c +++ b/midori/midori-browser.c @@ -65,6 +65,7 @@ struct _MidoriBrowser gboolean find_typing; GtkWidget* statusbar; + GtkWidget* transferbar; GtkWidget* progressbar; 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 midori_view_search_text_cb (GtkWidget* view, gboolean found, @@ -1017,6 +1129,10 @@ _midori_browser_add_tab (MidoriBrowser* browser, midori_view_new_window_cb, browser, "signal::new-view", 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", midori_view_search_text_cb, browser, "signal::add-bookmark", @@ -1782,9 +1898,9 @@ midori_browser_toolbar_popup_context_menu_cb (GtkWidget* widget, menuitem = sokoke_action_create_popup_menu_item ( _action_by_name (browser, "Bookmarkbar")); 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")); - 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 ( _action_by_name (browser, "Statusbar")); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); @@ -3204,10 +3320,10 @@ static const GtkToggleActionEntry toggle_entries[] = { N_("_Bookmarkbar"), "", N_("Show bookmarkbar"), G_CALLBACK (_action_bookmarkbar_activate), FALSE }, - { "Transferbar", NULL, + /* { "Transferbar", NULL, N_("_Transferbar"), "", - N_("Show transferbar"), NULL/*G_CALLBACK (_action_transferbar_activate)*/, - FALSE }, + N_("Show transferbar"), G_CALLBACK (_action_transferbar_activate), + FALSE }, */ { "Statusbar", NULL, N_("_Statusbar"), "", N_("Show statusbar"), G_CALLBACK (_action_statusbar_activate), @@ -3335,7 +3451,7 @@ static const gchar* ui_markup = "" "" "" - "" + /* "" */ "" "" "" @@ -3636,8 +3752,6 @@ midori_browser_init (MidoriBrowser* browser) g_error_free (error); } - /* _action_set_active(browser, "Transferbar", config->toolbarTransfers); */ - /* Hide the 'Dummy' which only holds otherwise unused actions */ 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, "Statusbar"), "visible", FALSE, NULL); #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, "SelectionSourceView", FALSE); @@ -3982,12 +4097,18 @@ midori_browser_init (MidoriBrowser* browser) gtk_widget_modify_style (browser->statusbar, rcstyle); g_object_unref (rcstyle); gtk_box_pack_start (GTK_BOX (vbox), browser->statusbar, FALSE, FALSE, 0); + browser->progressbar = gtk_progress_bar_new (); /* Set the progressbar's height to 1 to fit it in the statusbar */ gtk_widget_set_size_request (browser->progressbar, -1, 1); gtk_box_pack_start (GTK_BOX (browser->statusbar), browser->progressbar, 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); } diff --git a/midori/midori-preferences.c b/midori/midori-preferences.c index 25ae3a36..753e3136 100644 --- a/midori/midori-preferences.c +++ b/midori/midori-preferences.c @@ -422,10 +422,12 @@ midori_preferences_set_settings (MidoriPreferences* preferences, SPANNED_ADD (button, 0, 2, 2, 3); FRAME_NEW (_("Transfers")); TABLE_NEW (3, 2); + #if WEBKIT_CHECK_VERSION (1, 1, 3) label = katze_property_label (settings, "download-folder"); INDENTED_ADD (label, 0, 1, 0, 1); button = katze_property_proxy (settings, "download-folder", "folder"); FILLED_ADD (button, 1, 2, 0, 1); + #else label = katze_property_label (settings, "download-manager"); INDENTED_ADD (label, 0, 1, 1, 2); hbox = gtk_hbox_new (FALSE, 4); @@ -440,6 +442,7 @@ midori_preferences_set_settings (MidoriPreferences* preferences, g_signal_connect (entry, "focus-out-event", G_CALLBACK (proxy_download_manager_icon_cb), button); FILLED_ADD (hbox, 1, 2, 1, 2); + #endif label = katze_property_label (settings, "text-editor"); INDENTED_ADD (label, 0, 1, 2, 3); hbox = gtk_hbox_new (FALSE, 4); diff --git a/midori/midori-view.c b/midori/midori-view.c index f30285d1..a7c5ff9b 100644 --- a/midori/midori-view.c +++ b/midori/midori-view.c @@ -143,6 +143,7 @@ enum { NEW_TAB, NEW_WINDOW, NEW_VIEW, + DOWNLOAD_REQUESTED, SEARCH_TEXT, ADD_BOOKMARK, SAVE_AS, @@ -271,6 +272,36 @@ midori_view_class_init (MidoriViewClass* class) MIDORI_TYPE_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: * @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* 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) + #endif { /* i18n: The title of the 404 - Not found error page */ 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); } +#if !WEBKIT_CHECK_VERSION (1, 1, 3) static void midori_web_view_menu_save_as_activate_cb (GtkWidget* widget, MidoriView* view) @@ -899,6 +936,7 @@ midori_web_view_menu_download_activate_cb (GtkWidget* widget, { sokoke_spawn_program (view->download_manager, view->link_uri); } +#endif static void 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); menuitem = (GtkWidget*)g_list_nth_data (items, 3); 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 FIXME: Make sure this really is the right menu item */ 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); gtk_widget_show (menuitem); } + #endif menuitem = gtk_image_menu_item_new_from_stock (STOCK_BOOKMARK_ADD, NULL); gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 5); 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); 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)) 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", webkit_network_request_get_uri (request)); midori_view_set_uri (view, uri); @@ -1158,6 +1204,18 @@ webkit_web_view_mime_type_decision_cb (GtkWidget* web_view, 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 webkit_web_view_console_message_cb (GtkWidget* web_view, const gchar* message, @@ -1576,7 +1634,12 @@ midori_view_construct_web_view (MidoriView* view) webkit_web_view_create_web_view_cb, view, "signal::mime-type-policy-decision-requested", 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); + g_object_connect (web_frame, "signal::load-done", webkit_web_frame_load_done_cb, view, diff --git a/midori/midori-websettings.c b/midori/midori-websettings.c index ddc8cee2..237edb9d 100644 --- a/midori/midori-websettings.c +++ b/midori/midori-websettings.c @@ -291,6 +291,18 @@ midori_web_settings_get_property (GObject* object, GValue* value, 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 midori_web_settings_class_init (MidoriWebSettingsClass* class) { @@ -525,8 +537,12 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class) "download-folder", _("Download Folder"), _("The folder downloaded files are saved to"), - g_get_home_dir (), - G_PARAM_READABLE)); + midori_get_download_dir (), + #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, PROP_DOWNLOAD_MANAGER, @@ -584,7 +600,6 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class) TRUE, flags)); - g_type_class_ref (WEBKIT_TYPE_WEB_VIEW); g_object_class_install_property (gobject_class, PROP_OPEN_NEW_PAGES_IN, g_param_spec_enum ( @@ -845,6 +860,7 @@ notify_default_encoding_cb (GObject* object, static void midori_web_settings_init (MidoriWebSettings* web_settings) { + web_settings->download_folder = g_strdup (midori_get_download_dir ()); web_settings->http_proxy = NULL; web_settings->open_popups_in_tabs = TRUE; web_settings->remember_last_form_inputs = TRUE;