aboutsummaryrefslogtreecommitdiffstats
path: root/src/window-commands.c
diff options
context:
space:
mode:
authorXan Lopez <xlopez@igalia.com>2011-07-14 06:47:33 +0800
committerXan Lopez <xlopez@igalia.com>2011-08-29 03:23:26 +0800
commitebac66a05be1e71bd978f070fb842fd8b457e7e8 (patch)
tree549cd1797c49a39cf20be47b5567441f208a5fa5 /src/window-commands.c
parentbebb9f4299f4a86439ed04b335b6852234af0622 (diff)
downloadgsoc2013-epiphany-ebac66a05be1e71bd978f070fb842fd8b457e7e8.tar
gsoc2013-epiphany-ebac66a05be1e71bd978f070fb842fd8b457e7e8.tar.gz
gsoc2013-epiphany-ebac66a05be1e71bd978f070fb842fd8b457e7e8.tar.bz2
gsoc2013-epiphany-ebac66a05be1e71bd978f070fb842fd8b457e7e8.tar.lz
gsoc2013-epiphany-ebac66a05be1e71bd978f070fb842fd8b457e7e8.tar.xz
gsoc2013-epiphany-ebac66a05be1e71bd978f070fb842fd8b457e7e8.tar.zst
gsoc2013-epiphany-ebac66a05be1e71bd978f070fb842fd8b457e7e8.zip
Add basic support for Web Applications
Allow to save any page as a "Web Application". A new .desktop file will be created, and added to the Shell as a new application. It will launch epiphany in application mode, with its own private profile (inheriting some data from the main profile, like the relevant domain cookies) and in a new process.
Diffstat (limited to 'src/window-commands.c')
-rw-r--r--src/window-commands.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/src/window-commands.c b/src/window-commands.c
index 32043c910..341ea4014 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -2,6 +2,7 @@
/*
* Copyright © 2000-2004 Marco Pesenti Gritti
* Copyright © 2009 Collabora Ltd.
+ * Copyright © 2011 Igalia S.L.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -382,6 +383,196 @@ window_cmd_file_save_as (GtkAction *action,
gtk_widget_show (GTK_WIDGET (dialog));
}
+typedef struct {
+ EphyWebView *view;
+ GtkWidget *image;
+ GtkWidget *entry;
+ GtkWidget *spinner;
+ GtkWidget *box;
+ char *icon_href;
+} EphyApplicationDialogData;
+
+static void
+ephy_application_dialog_data_free (EphyApplicationDialogData *data)
+{
+ g_free (data->icon_href);
+ g_slice_free (EphyApplicationDialogData, data);
+}
+
+static void
+take_page_snapshot_and_set_image (EphyApplicationDialogData *data)
+{
+ GdkPixbuf *snapshot;
+ int x, y, w, h;
+
+ x = y = 0;
+ w = h = 128; /* GNOME hi-res icon size. */
+
+ snapshot = ephy_web_view_get_snapshot (data->view, x, y, w, h);
+
+ gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), snapshot);
+ g_object_unref (snapshot);
+}
+
+static void
+download_status_changed_cb (WebKitDownload *download,
+ GParamSpec *spec,
+ EphyApplicationDialogData *data)
+{
+ WebKitDownloadStatus status = webkit_download_get_status (download);
+ const char *destination;
+
+ switch (status)
+ {
+ case WEBKIT_DOWNLOAD_STATUS_FINISHED:
+ destination = g_filename_from_uri (webkit_download_get_destination_uri (download),
+ NULL, NULL);
+ gtk_image_set_from_file (GTK_IMAGE (data->image), destination);
+ break;
+ case WEBKIT_DOWNLOAD_STATUS_ERROR:
+ case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
+ /* Something happened, default to a page snapshot. */
+ take_page_snapshot_and_set_image (data);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+download_icon_and_set_image (EphyApplicationDialogData *data)
+{
+ WebKitNetworkRequest *request;
+ WebKitDownload *download;
+ char *destination, *destination_uri, *tmp_filename;
+
+ request = webkit_network_request_new (data->icon_href);
+ download = webkit_download_new (request);
+ g_object_unref (request);
+
+ tmp_filename = ephy_file_tmp_filename ("ephy-download-XXXXXX", NULL);
+ destination = g_build_filename (ephy_file_tmp_dir (), tmp_filename, NULL);
+ destination_uri = g_filename_to_uri (destination, NULL, NULL);
+ webkit_download_set_destination_uri (download, destination_uri);
+ g_free (destination);
+ g_free (destination_uri);
+ g_free (tmp_filename);
+
+ g_signal_connect (download, "notify::status",
+ G_CALLBACK (download_status_changed_cb), data);
+
+ webkit_download_start (download);
+}
+
+static void
+fill_default_application_image (EphyApplicationDialogData *data)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMNodeList *links;
+ gulong length, i;
+
+ document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (data->view));
+ links = webkit_dom_document_get_elements_by_tag_name (document, "link");
+ length = webkit_dom_node_list_get_length (links);
+
+ for (i = 0; i < length; i++)
+ {
+ char *rel;
+ WebKitDOMNode *node = webkit_dom_node_list_item (links, i);
+ rel = webkit_dom_html_link_element_get_rel (WEBKIT_DOM_HTML_LINK_ELEMENT (node));
+ /* TODO: support more than one possible icon. */
+ if (g_strcmp0 (rel, "apple-touch-icon") == 0 ||
+ g_strcmp0 (rel, "apple-touch-icon-precomposed") == 0)
+ {
+ data->icon_href = webkit_dom_html_link_element_get_href (WEBKIT_DOM_HTML_LINK_ELEMENT (node));
+ download_icon_and_set_image (data);
+ g_free (rel);
+ return;
+ }
+ }
+
+ /* If we make it here, no "apple-touch-icon" link was
+ * found. Take a snapshot of the page. */
+ take_page_snapshot_and_set_image (data);
+}
+
+static void
+fill_default_application_title (EphyApplicationDialogData *data)
+{
+ const char *title = ephy_web_view_get_title (data->view);
+ gtk_entry_set_text (GTK_ENTRY (data->entry), title);
+}
+
+void
+window_cmd_file_save_as_application (GtkAction *action,
+ EphyWindow *window)
+{
+ EphyEmbed *embed;
+ GtkWidget *dialog, *box, *image, *entry, *content_area;
+ EphyWebView *view;
+ gboolean response;
+ EphyApplicationDialogData *data;
+
+ embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
+ g_return_if_fail (embed != NULL);
+
+ view = EPHY_WEB_VIEW (EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed));
+
+ /* Show dialog with icon, title. */
+ dialog = gtk_dialog_new_with_buttons (_("Create Web Application"),
+ GTK_WINDOW (window),
+ 0,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ _("Create"),
+ GTK_RESPONSE_OK,
+ NULL);
+
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+ gtk_box_set_spacing (GTK_BOX (content_area), 14); /* 14 + 2 * 5 = 24 */
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
+ gtk_container_add (GTK_CONTAINER (content_area), box);
+
+ image = gtk_image_new ();
+ gtk_widget_set_size_request (image, 128, 128);
+ gtk_container_add (GTK_CONTAINER (box), image);
+
+ entry = gtk_entry_new ();
+ gtk_box_pack_end (GTK_BOX (box), entry, FALSE, FALSE, 0);
+
+ data = g_slice_new0 (EphyApplicationDialogData);
+ data->view = view;
+ data->image = image;
+ data->entry = entry;
+
+ fill_default_application_image (data);
+ fill_default_application_title (data);
+
+ gtk_widget_show_all (dialog);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response == GTK_RESPONSE_OK)
+ {
+ char *desktop_file;
+
+ /* Create Web Application, including a new profile and .desktop file. */
+ desktop_file = ephy_web_view_create_web_application (view,
+ gtk_entry_get_text (GTK_ENTRY (data->entry)),
+ gtk_image_get_pixbuf (GTK_IMAGE (data->image)));
+
+ /* TODO: show a notification when the app is totally
+ * created and ready to be launched */
+ g_free (desktop_file);
+ }
+
+ ephy_application_dialog_data_free (data);
+ gtk_widget_destroy (dialog);
+}
+
void
window_cmd_file_work_offline (GtkAction *action,
EphyWindow *window)