aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustavo Noronha Silva <gns@gnome.org>2009-08-21 01:59:07 +0800
committerGustavo Noronha Silva <gns@gnome.org>2009-09-15 10:06:09 +0800
commitdef58964b0e7fa099b524a6e8bc34bed893118f7 (patch)
tree2180af55b166e386fe7b07df5e7610d9ab3baa3d
parentbd03e748e07dd300015fdfee111420162f346e5f (diff)
downloadgsoc2013-epiphany-def58964b0e7fa099b524a6e8bc34bed893118f7.tar
gsoc2013-epiphany-def58964b0e7fa099b524a6e8bc34bed893118f7.tar.gz
gsoc2013-epiphany-def58964b0e7fa099b524a6e8bc34bed893118f7.tar.bz2
gsoc2013-epiphany-def58964b0e7fa099b524a6e8bc34bed893118f7.tar.lz
gsoc2013-epiphany-def58964b0e7fa099b524a6e8bc34bed893118f7.tar.xz
gsoc2013-epiphany-def58964b0e7fa099b524a6e8bc34bed893118f7.tar.zst
gsoc2013-epiphany-def58964b0e7fa099b524a6e8bc34bed893118f7.zip
Implement saving the page using the DataSource API
Bug #562611
-rw-r--r--embed/ephy-web-view.c239
-rw-r--r--embed/ephy-web-view.h2
-rw-r--r--src/window-commands.c49
3 files changed, 275 insertions, 15 deletions
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index f95c4b1e1..5f1f49af0 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
- * Copyright © 2008 Gustavo Noronha Silva
+ * Copyright © 2008, 2009 Gustavo Noronha Silva
* Copyright © 2009 Igalia S.L.
*
* This program is free software; you can redistribute it and/or modify
@@ -2127,3 +2127,240 @@ ephy_web_view_get_title_composite (EphyWebView *view)
return title != NULL ? title : "";
}
+static void
+ephy_web_view_save_sub_resource_start (GList *subresources, char *destination_uri);
+
+static void
+ephy_web_view_close_cb (GOutputStream *ostream, GAsyncResult *result, GString *data)
+{
+ GList *subresources;
+ char *sub_destination_uri;
+ GError *error = NULL;
+
+ subresources = (GList*)g_object_get_data (G_OBJECT (ostream),
+ "ephy-web-view-save-subresources");
+
+ sub_destination_uri = (char*)g_object_get_data (G_OBJECT (ostream),
+ "ephy-web-view-save-dest-uri");
+
+ g_output_stream_close_finish (ostream, result, &error);
+ g_object_unref (ostream);
+
+ if (error) {
+ g_list_free (subresources);
+ g_free (sub_destination_uri);
+ g_warning ("Unable to write to file: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (!subresources || !subresources->next) {
+ g_list_free (subresources);
+ g_free (sub_destination_uri);
+ return;
+ }
+
+ subresources = subresources->next;
+ ephy_web_view_save_sub_resource_start (subresources, sub_destination_uri);
+}
+
+static void
+ephy_web_view_save_write_cb (GOutputStream *ostream, GAsyncResult *result, GString *data)
+{
+ GError *error = NULL;
+ gssize written;
+
+ written = g_output_stream_write_finish (ostream, result, &error);
+ if (error) {
+ GList *subresources;
+ char *sub_destination_uri;
+
+ subresources = (GList*)g_object_get_data (G_OBJECT (ostream),
+ "ephy-web-view-save-subresources");
+ g_list_free (subresources);
+
+ sub_destination_uri = (char*)g_object_get_data (G_OBJECT (ostream),
+ "ephy-web-view-save-dest-uri");
+ g_free (sub_destination_uri);
+
+ g_string_free (data, FALSE);
+ g_object_unref (ostream);
+
+ g_warning ("Unable to write to file: %s", error->message);
+
+ g_error_free (error);
+ return;
+ }
+
+ if (written == data->len) {
+ g_string_free (data, FALSE);
+ g_output_stream_close_async (ostream, G_PRIORITY_DEFAULT, NULL,
+ (GAsyncReadyCallback)ephy_web_view_close_cb,
+ NULL);
+ return;
+ }
+
+ data->len -= written;
+ data->str += written;
+
+ g_output_stream_write_async (ostream,
+ data->str, data->len,
+ G_PRIORITY_DEFAULT, NULL,
+ (GAsyncReadyCallback)ephy_web_view_save_write_cb,
+ data);
+}
+
+static void
+ephy_web_view_save_replace_cb (GFile *file, GAsyncResult *result, GString *const_data)
+{
+ GFileOutputStream *ostream;
+ GList *subresources;
+ char *sub_destination_uri;
+ GString *data;
+ GError *error = NULL;
+
+ subresources = (GList*)g_object_get_data (G_OBJECT (file),
+ "ephy-web-view-save-subresources");
+
+ sub_destination_uri = (char*)g_object_get_data (G_OBJECT (file),
+ "ephy-web-view-save-dest-uri");
+
+ ostream = g_file_replace_finish (file, result, &error);
+ if (error) {
+ g_warning ("Failed to save page: %s", error->message);
+ g_list_free (subresources);
+ g_free (sub_destination_uri);
+ g_error_free (error);
+ return;
+ }
+
+ if (const_data) {
+ data = g_string_sized_new (const_data->len);
+ data->str = const_data->str;
+ data->len = const_data->len;
+ } else
+ data = g_string_new ("");
+
+ /* If we have subresources to handle, pass the information along */
+ if (subresources) {
+ g_object_set_data (G_OBJECT (ostream),
+ "ephy-web-view-save-subresources",
+ subresources);
+
+ g_object_set_data (G_OBJECT (ostream),
+ "ephy-web-view-save-dest-uri",
+ sub_destination_uri);
+ }
+
+ g_output_stream_write_async (G_OUTPUT_STREAM (ostream),
+ data->str, data->len,
+ G_PRIORITY_DEFAULT, NULL,
+ (GAsyncReadyCallback)ephy_web_view_save_write_cb,
+ data);
+}
+
+static void
+ephy_web_view_save_sub_resource_start (GList *subresources, char *destination_uri)
+{
+ WebKitWebResource *resource;
+ GFile *file;
+ char *resource_uri;
+ char *resource_name;
+ const GString *data;
+
+ resource = WEBKIT_WEB_RESOURCE (subresources->data);
+
+ resource_uri = (char*)webkit_web_resource_get_uri (resource);
+ resource_name = g_path_get_basename (resource_uri);
+
+ resource_uri = g_strdup_printf ("%s/%s",
+ destination_uri,
+ resource_name);
+
+ file = g_file_new_for_uri (resource_uri);
+ g_free (resource_uri);
+
+ g_object_set_data (G_OBJECT (file),
+ "ephy-web-view-save-dest-uri",
+ destination_uri);
+
+ g_object_set_data (G_OBJECT (file),
+ "ephy-web-view-save-subresources",
+ subresources);
+
+ data = webkit_web_resource_get_data (resource);
+
+ g_file_replace_async (file, NULL, FALSE,
+ G_FILE_CREATE_REPLACE_DESTINATION|G_FILE_CREATE_PRIVATE,
+ G_PRIORITY_DEFAULT, NULL,
+ (GAsyncReadyCallback)ephy_web_view_save_replace_cb,
+ (GString*)data);
+
+ g_object_unref (file);
+}
+
+static void
+ephy_web_view_save_sub_resources (EphyWebView *view, const char *uri, GList *subresources)
+{
+ GFile *file;
+ char *filename;
+ char *dotpos;
+ char *directory_uri;
+ char *destination_uri;
+ GError *error = NULL;
+
+ /* filename of the main resource without extension */
+ filename = g_path_get_basename (uri);
+ dotpos = g_strrstr (filename, ".");
+ if (dotpos)
+ *dotpos = '\0';
+
+ directory_uri = g_path_get_dirname (uri);
+ destination_uri = g_strdup_printf (_("%s/%s Files"), directory_uri, filename);
+
+ g_free (filename);
+ g_free (directory_uri);
+
+ file = g_file_new_for_uri (destination_uri);
+ if (!g_file_make_directory (file, NULL, &error)) {
+ g_warning ("Could not create directory: %s", error->message);
+ g_error_free (error);
+ g_object_unref (file);
+ return;
+ }
+ g_object_unref (file);
+
+ /* Now, let's start saving sub resources */
+ ephy_web_view_save_sub_resource_start (subresources, destination_uri);
+}
+
+void
+ephy_web_view_save (EphyWebView *view, const char *uri)
+{
+ WebKitWebFrame *frame;
+ WebKitWebDataSource *data_source;
+ GList *subresources;
+ const GString *data;
+ GFile *file;
+
+ /* Save main resource */
+ frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW(view));
+ data_source = webkit_web_frame_get_data_source (frame);
+ data = webkit_web_data_source_get_data (data_source);
+
+ file = g_file_new_for_uri (uri);
+ g_file_replace_async (file, NULL, FALSE,
+ G_FILE_CREATE_REPLACE_DESTINATION|G_FILE_CREATE_PRIVATE,
+ G_PRIORITY_DEFAULT, NULL,
+ (GAsyncReadyCallback)ephy_web_view_save_replace_cb,
+ (GString*)data);
+
+ g_object_unref (file);
+
+ /* If subresources exist, save them */
+ subresources = webkit_web_data_source_get_subresources (data_source);
+ if (!subresources)
+ return;
+
+ ephy_web_view_save_sub_resources (view, uri, subresources);
+}
diff --git a/embed/ephy-web-view.h b/embed/ephy-web-view.h
index d50bf4fa1..29f1bd34b 100644
--- a/embed/ephy-web-view.h
+++ b/embed/ephy-web-view.h
@@ -229,6 +229,8 @@ void ephy_web_view_set_loading_title (EphyWebView
gboolean is_address);
void ephy_web_view_popups_manager_reset (EphyWebView *view);
+void ephy_web_view_save (EphyWebView *view,
+ const char *uri);
G_END_DECLS
diff --git a/src/window-commands.c b/src/window-commands.c
index e6790c754..b3d437354 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -276,6 +276,32 @@ open_response_cb (GtkDialog *dialog, int response, EphyWindow *window)
gtk_widget_destroy (GTK_WIDGET (dialog));
}
+static void
+save_response_cb (GtkDialog *dialog, int response, EphyEmbed *embed)
+{
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+ char *uri, *converted;
+
+ uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+ if (uri != NULL)
+ {
+ converted = g_filename_to_utf8 (uri, -1, NULL, NULL, NULL);
+
+ if (converted != NULL)
+ {
+ EphyWebView *web_view = ephy_embed_get_web_view (embed);
+ ephy_web_view_save (web_view, converted);
+ }
+
+ g_free (converted);
+ g_free (uri);
+ }
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
void
window_cmd_file_open (GtkAction *action,
EphyWindow *window)
@@ -299,26 +325,21 @@ window_cmd_file_save_as (GtkAction *action,
EphyWindow *window)
{
EphyEmbed *embed;
- EphyEmbedPersist *persist;
+ EphyFileChooser *dialog;
embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
g_return_if_fail (embed != NULL);
- persist = EPHY_EMBED_PERSIST
- (g_object_new (EPHY_TYPE_EMBED_PERSIST, NULL));
-
- ephy_embed_persist_set_embed (persist, embed);
- ephy_embed_persist_set_fc_title (persist, _("Save As"));
- ephy_embed_persist_set_fc_parent (persist,GTK_WINDOW (window));
-
- ephy_embed_persist_set_flags
- (persist, EPHY_EMBED_PERSIST_MAINDOC | EPHY_EMBED_PERSIST_ASK_DESTINATION);
- ephy_embed_persist_set_persist_key
- (persist, CONF_STATE_SAVE_DIR);
+ dialog = ephy_file_chooser_new (_("Save"),
+ GTK_WIDGET (window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ CONF_STATE_SAVE_DIR,
+ EPHY_FILE_FILTER_ALL_SUPPORTED);
- ephy_embed_persist_save (persist);
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (save_response_cb), embed);
- g_object_unref (G_OBJECT(persist));
+ gtk_widget_show (GTK_WIDGET (dialog));
}
void