Implement Save As for arbitrary links

This commit is contained in:
Christian Dywan 2008-11-09 22:07:42 +01:00
parent 7c63a0b480
commit 38c6ad5dad
2 changed files with 130 additions and 87 deletions

View file

@ -218,7 +218,7 @@ _midori_browser_update_interface (MidoriBrowser* browser)
midori_view_can_go_forward (MIDORI_VIEW (view))); midori_view_can_go_forward (MIDORI_VIEW (view)));
/* Currently views that don't support source, don't support /* 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", _action_set_sensitive (browser, "SaveAs",
midori_view_can_view_source (MIDORI_VIEW (view))); midori_view_can_view_source (MIDORI_VIEW (view)));
_action_set_sensitive (browser, "Print", _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); 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 static gboolean
midori_browser_tab_leave_notify_event_cb (GtkWidget* widget, midori_browser_tab_leave_notify_event_cb (GtkWidget* widget,
GdkEventCrossing* event, GdkEventCrossing* event,
@ -798,6 +895,8 @@ _midori_browser_add_tab (MidoriBrowser* browser,
midori_view_search_text_cb, browser, midori_view_search_text_cb, browser,
"signal::add-bookmark", "signal::add-bookmark",
midori_view_add_bookmark_cb, browser, midori_view_add_bookmark_cb, browser,
"signal::save-as",
midori_view_save_as_cb, browser,
NULL); NULL);
g_signal_connect (view, "leave-notify-event", g_signal_connect (view, "leave-notify-event",
@ -1187,94 +1286,11 @@ _action_open_activate (GtkAction* action,
gtk_widget_destroy (dialog); 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 static void
_action_save_as_activate (GtkAction* action, _action_save_as_activate (GtkAction* action,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
static gchar* last_dir = NULL; midori_browser_save_uri (browser, midori_browser_get_current_uri (browser));
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);
} }
static void static void

View file

@ -112,6 +112,7 @@ enum {
NEW_WINDOW, NEW_WINDOW,
SEARCH_TEXT, SEARCH_TEXT,
ADD_BOOKMARK, ADD_BOOKMARK,
SAVE_AS,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -350,6 +351,17 @@ midori_view_class_init (MidoriViewClass* class)
G_TYPE_NONE, 1, G_TYPE_NONE, 1,
G_TYPE_STRING); 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 = G_OBJECT_CLASS (class);
gobject_class->finalize = midori_view_finalize; gobject_class->finalize = midori_view_finalize;
gobject_class->set_property = midori_view_set_property; 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); 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 static void
midori_web_view_menu_download_activate_cb (GtkWidget* widget, midori_web_view_menu_download_activate_cb (GtkWidget* widget,
MidoriView* view) MidoriView* view)
@ -859,6 +878,12 @@ webkit_web_view_populate_popup_cb (WebKitWebView* web_view,
/* 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);
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) if (view->download_manager && *view->download_manager)
{ {
menuitem = gtk_image_menu_item_new_with_mnemonic ( menuitem = gtk_image_menu_item_new_with_mnemonic (
@ -923,7 +948,9 @@ webkit_web_view_populate_popup_cb (WebKitWebView* web_view,
g_signal_connect (menuitem, "activate", g_signal_connect (menuitem, "activate",
G_CALLBACK (midori_web_view_menu_action_activate_cb), view); G_CALLBACK (midori_web_view_menu_action_activate_cb), view);
gtk_widget_show (menuitem); gtk_widget_show (menuitem);
/* FIXME: Make this sensitive once it's implemented */ /* 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); gtk_widget_set_sensitive (menuitem, FALSE);
menuitem = gtk_image_menu_item_new_with_mnemonic (_("View _Source")); menuitem = gtk_image_menu_item_new_with_mnemonic (_("View _Source"));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);