From 38c6ad5dadbff5af0df7b03c6489a1510663468e Mon Sep 17 00:00:00 2001 From: Christian Dywan Date: Sun, 9 Nov 2008 22:07:42 +0100 Subject: [PATCH] Implement Save As for arbitrary links --- midori/midori-browser.c | 186 ++++++++++++++++++++++------------------ midori/midori-view.c | 31 ++++++- 2 files changed, 130 insertions(+), 87 deletions(-) diff --git a/midori/midori-browser.c b/midori/midori-browser.c index 07560318..7a4bc986 100644 --- a/midori/midori-browser.c +++ b/midori/midori-browser.c @@ -218,7 +218,7 @@ _midori_browser_update_interface (MidoriBrowser* browser) midori_view_can_go_forward (MIDORI_VIEW (view))); /* Currently views that don't support source, don't support - saving either. If that changes, we need to thinkof something. */ + saving either. If that changes, we need to think of something. */ _action_set_sensitive (browser, "SaveAs", midori_view_can_view_source (MIDORI_VIEW (view))); _action_set_sensitive (browser, "Print", @@ -630,6 +630,103 @@ midori_view_add_bookmark_cb (GtkWidget* menuitem, midori_browser_edit_bookmark_dialog_new (browser, item, FALSE); } +static void +midori_browser_save_transfer_cb (KatzeNetRequest* request, + gchar* filename) +{ + FILE* fp; + + if (request->data) + { + /* FIXME: Show an error message if the file cannot be saved */ + if ((fp = fopen (filename, "wb"))) + { + fwrite (request->data, 1, request->length, fp); + fclose (fp); + } + } + g_free (filename); +} + +static void +midori_browser_save_uri (MidoriBrowser* browser, + const gchar* uri) +{ + static gchar* last_dir = NULL; + gboolean folder_set = FALSE; + GtkWidget* dialog; + gchar* filename; + gchar* dirname; + gchar* last_slash; + gchar* folder; + + dialog = gtk_file_chooser_dialog_new ( + _("Save file as"), GTK_WINDOW (browser), + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, + NULL); + gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_SAVE); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (browser)); + + if (uri) + { + /* Base the start folder on the current view's uri if it is local */ + filename = g_filename_from_uri (uri, NULL, NULL); + if (filename) + { + dirname = g_path_get_dirname (filename); + if (dirname && g_file_test (dirname, G_FILE_TEST_IS_DIR)) + { + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), dirname); + folder_set = TRUE; + } + + g_free (dirname); + g_free (filename); + } + + /* Try to provide a good default filename */ + filename = g_filename_from_uri (uri, NULL, NULL); + if (!filename && (last_slash = g_strrstr (uri, "/"))) + { + if (last_slash[0] == '/') + last_slash++; + filename = g_strdup (last_slash); + } + else + filename = g_strdup (uri); + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename); + g_free (filename); + } + + if (!folder_set && last_dir && *last_dir) + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), last_dir); + + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) + { + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)); + katze_net_load_uri (browser->net, uri, NULL, + (KatzeNetTransferCb)midori_browser_save_transfer_cb, filename); + + g_free (last_dir); + last_dir = folder; + } + gtk_widget_destroy (dialog); +} + +static void +midori_view_save_as_cb (GtkWidget* menuitem, + const gchar* uri, + GtkWidget* view) +{ + MidoriBrowser* browser; + + browser = (MidoriBrowser*)gtk_widget_get_toplevel (menuitem); + midori_browser_save_uri (browser, uri); +} + static gboolean midori_browser_tab_leave_notify_event_cb (GtkWidget* widget, GdkEventCrossing* event, @@ -798,6 +895,8 @@ _midori_browser_add_tab (MidoriBrowser* browser, midori_view_search_text_cb, browser, "signal::add-bookmark", midori_view_add_bookmark_cb, browser, + "signal::save-as", + midori_view_save_as_cb, browser, NULL); g_signal_connect (view, "leave-notify-event", @@ -1187,94 +1286,11 @@ _action_open_activate (GtkAction* action, gtk_widget_destroy (dialog); } -static void -midori_browser_save_transfer_cb (KatzeNetRequest* request, - gchar* filename) -{ - FILE* fp; - - if (request->data) - { - /* FIXME: Show an error message if the file cannot be saved */ - if ((fp = fopen (filename, "wb"))) - { - fwrite (request->data, 1, request->length, fp); - fclose (fp); - } - } - g_free (filename); -} - static void _action_save_as_activate (GtkAction* action, MidoriBrowser* browser) { - static gchar* last_dir = NULL; - gchar* uri = NULL; - gboolean folder_set = FALSE; - GtkWidget* dialog; - GtkWidget* view; - gchar* filename; - gchar* dirname; - gchar* last_slash; - gchar* folder; - - dialog = gtk_file_chooser_dialog_new ( - _("Save file as"), GTK_WINDOW (browser), - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, - NULL); - gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_SAVE); - gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (browser)); - - view = midori_browser_get_current_tab (browser); - if ((uri = (gchar*)midori_view_get_display_uri (MIDORI_VIEW (view)))) - { - /* Base the start folder on the current view's uri if it is local */ - filename = g_filename_from_uri (uri, NULL, NULL); - if (filename) - { - dirname = g_path_get_dirname (filename); - if (dirname && g_file_test (dirname, G_FILE_TEST_IS_DIR)) - { - gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), dirname); - folder_set = TRUE; - } - - g_free (dirname); - g_free (filename); - } - - /* Try to provide a good default filename */ - filename = g_filename_from_uri (uri, NULL, NULL); - if (!filename && (last_slash = g_strrstr (uri, "/"))) - { - if (last_slash[0] == '/') - last_slash++; - filename = g_strdup (last_slash); - } - else - filename = g_strdup (uri); - gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename); - g_free (filename); - } - - if (!folder_set && last_dir && *last_dir) - gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), last_dir); - - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) - { - filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); - folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)); - katze_net_load_uri (browser->net, uri, NULL, - (KatzeNetTransferCb)midori_browser_save_transfer_cb, filename); - - g_free (last_dir); - last_dir = folder; - g_free (uri); - } - gtk_widget_destroy (dialog); + midori_browser_save_uri (browser, midori_browser_get_current_uri (browser)); } static void diff --git a/midori/midori-view.c b/midori/midori-view.c index 7738f618..92c6af8c 100644 --- a/midori/midori-view.c +++ b/midori/midori-view.c @@ -112,6 +112,7 @@ enum { NEW_WINDOW, SEARCH_TEXT, ADD_BOOKMARK, + SAVE_AS, LAST_SIGNAL }; @@ -350,6 +351,17 @@ midori_view_class_init (MidoriViewClass* class) G_TYPE_NONE, 1, G_TYPE_STRING); + signals[SAVE_AS] = g_signal_new ( + "save-as", + G_TYPE_FROM_CLASS (class), + (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + 0, + 0, + NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); + gobject_class = G_OBJECT_CLASS (class); gobject_class->finalize = midori_view_finalize; gobject_class->set_property = midori_view_set_property; @@ -783,6 +795,13 @@ midori_web_view_menu_new_window_activate_cb (GtkWidget* widget, g_signal_emit (view, signals[NEW_WINDOW], 0, view->link_uri); } +static void +midori_web_view_menu_save_as_activate_cb (GtkWidget* widget, + MidoriView* view) +{ + g_signal_emit (view, signals[SAVE_AS], 0, view->link_uri); +} + static void midori_web_view_menu_download_activate_cb (GtkWidget* widget, MidoriView* view) @@ -859,6 +878,12 @@ webkit_web_view_populate_popup_cb (WebKitWebView* web_view, /* hack to disable non-functional Download File FIXME: Make sure this really is the right menu item */ gtk_widget_hide (menuitem); + menuitem = gtk_image_menu_item_new_with_mnemonic ( + _("_Save Link destination")); + gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 3); + g_signal_connect (menuitem, "activate", + G_CALLBACK (midori_web_view_menu_save_as_activate_cb), view); + gtk_widget_show (menuitem); if (view->download_manager && *view->download_manager) { menuitem = gtk_image_menu_item_new_with_mnemonic ( @@ -923,8 +948,10 @@ webkit_web_view_populate_popup_cb (WebKitWebView* web_view, g_signal_connect (menuitem, "activate", G_CALLBACK (midori_web_view_menu_action_activate_cb), view); gtk_widget_show (menuitem); - /* FIXME: Make this sensitive once it's implemented */ - gtk_widget_set_sensitive (menuitem, FALSE); + /* Currently views that don't support source, don't support + saving either. If that changes, we need to think of something. */ + if (!midori_view_can_view_source (view)) + gtk_widget_set_sensitive (menuitem, FALSE); menuitem = gtk_image_menu_item_new_with_mnemonic (_("View _Source")); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); g_object_set_data (G_OBJECT (menuitem), "action", "SourceView");