[epiphany] Add internal pdf viewer using evince
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany] Add internal pdf viewer using evince
- Date: Mon, 7 Jan 2019 21:00:39 +0000 (UTC)
commit 91508a2be9d830343300763889a27f4feb8612b7
Author: Jan-Michael Brummer <jan brummer tabos org>
Date: Mon Dec 17 11:16:36 2018 +0100
Add internal pdf viewer using evince
Based on an initial patch by: Carlos Garcia Campos
Fixes: https://gitlab.gnome.org/GNOME/epiphany/issues/264
embed/ephy-download.c | 18 ++
embed/ephy-download.h | 41 ++---
embed/ephy-embed-shell.c | 8 +
embed/ephy-embed-utils.c | 25 +++
embed/ephy-embed-utils.h | 27 +--
embed/ephy-embed.c | 62 +++++++
embed/ephy-embed.h | 10 ++
embed/ephy-evince-document-view.c | 334 ++++++++++++++++++++++++++++++++++++++
embed/ephy-evince-document-view.h | 47 ++++++
embed/ephy-web-view.c | 8 +
embed/meson.build | 3 +
flatpak/org.gnome.Epiphany.json | 51 ++++++
meson.build | 2 +
src/ephy-action-bar-end.c | 18 ++
src/ephy-main.c | 3 +
src/window-commands.c | 2 +
16 files changed, 626 insertions(+), 33 deletions(-)
---
diff --git a/embed/ephy-download.c b/embed/ephy-download.c
index e10dabf05..d3118822f 100644
--- a/embed/ephy-download.c
+++ b/embed/ephy-download.c
@@ -25,6 +25,7 @@
#include "ephy-embed.h"
#include "ephy-embed-shell.h"
#include "ephy-embed-type-builtins.h"
+#include "ephy-evince-document-view.h"
#include "ephy-file-helpers.h"
#include "ephy-prefs.h"
#include "ephy-settings.h"
@@ -42,6 +43,7 @@ struct _EphyDownload {
char *content_type;
gboolean show_notification;
+ gboolean in_document_mode;
EphyDownloadActionType action;
guint32 start_time;
@@ -630,6 +632,16 @@ download_decide_destination_cb (WebKitDownload *wk_download,
const gchar *suggested_filename,
EphyDownload *download)
{
+ if (download->in_document_mode) {
+ g_autofree gchar *tmp_file = g_strdup_printf ("%s/%s", g_get_user_cache_dir (), suggested_filename);
+ g_autofree gchar *file_uri = g_filename_to_uri (tmp_file, NULL, NULL);
+
+ webkit_download_set_allow_overwrite (wk_download, TRUE);
+ webkit_download_set_destination (wk_download, file_uri);
+
+ return TRUE;
+ }
+
if (webkit_download_get_destination (wk_download))
return TRUE;
@@ -812,3 +824,9 @@ ephy_download_disable_desktop_notification (EphyDownload *download)
download->show_notification = FALSE;
}
+
+void
+ephy_download_enable_evince_document_mode (EphyDownload *download)
+{
+ download->in_document_mode = TRUE;
+}
diff --git a/embed/ephy-download.h b/embed/ephy-download.h
index d2435812f..fa6bc917f 100644
--- a/embed/ephy-download.h
+++ b/embed/ephy-download.h
@@ -36,32 +36,33 @@ typedef enum
EPHY_DOWNLOAD_ACTION_OPEN
} EphyDownloadActionType;
-EphyDownload *ephy_download_new (WebKitDownload *download);
-EphyDownload *ephy_download_new_for_uri (const char *uri);
+EphyDownload *ephy_download_new (WebKitDownload *download);
+EphyDownload *ephy_download_new_for_uri (const char *uri);
-void ephy_download_cancel (EphyDownload *download);
-gboolean ephy_download_is_active (EphyDownload *download);
-gboolean ephy_download_succeeded (EphyDownload *download);
-gboolean ephy_download_failed (EphyDownload *download,
- GError **error);
+void ephy_download_cancel (EphyDownload *download);
+gboolean ephy_download_is_active (EphyDownload *download);
+gboolean ephy_download_succeeded (EphyDownload *download);
+gboolean ephy_download_failed (EphyDownload *download,
+ GError **error);
-void ephy_download_set_destination_uri (EphyDownload *download,
- const char *destination);
+void ephy_download_set_destination_uri (EphyDownload *download,
+ const char *destination);
-WebKitDownload *ephy_download_get_webkit_download (EphyDownload *download);
+WebKitDownload *ephy_download_get_webkit_download (EphyDownload *download);
-const char *ephy_download_get_destination_uri (EphyDownload *download);
-const char *ephy_download_get_content_type (EphyDownload *download);
+const char *ephy_download_get_destination_uri (EphyDownload *download);
+const char *ephy_download_get_content_type (EphyDownload *download);
-guint32 ephy_download_get_start_time (EphyDownload *download);
+guint32 ephy_download_get_start_time (EphyDownload *download);
-EphyDownloadActionType ephy_download_get_action (EphyDownload *download);
-void ephy_download_set_action (EphyDownload *download,
- EphyDownloadActionType action);
-gboolean ephy_download_do_download_action (EphyDownload *download,
- EphyDownloadActionType action,
- guint32 user_time);
+EphyDownloadActionType ephy_download_get_action (EphyDownload *download);
+void ephy_download_set_action (EphyDownload *download,
+ EphyDownloadActionType action);
+gboolean ephy_download_do_download_action (EphyDownload *download,
+ EphyDownloadActionType action,
+ guint32 user_time);
void ephy_download_disable_desktop_notification
- (EphyDownload *download);
+ (EphyDownload *download);
+void ephy_download_enable_evince_document_mode (EphyDownload *download);
G_END_DECLS
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index d2e9d2d8a..02aedc24a 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -1149,6 +1149,8 @@ download_started_cb (WebKitWebContext *web_context,
{
EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
EphyDownload *ephy_download;
+ EphyEmbed *embed;
+ GtkWindow *window;
gboolean ephy_download_set;
/* Is download locked down? */
@@ -1168,6 +1170,12 @@ download_started_cb (WebKitWebContext *web_context,
return;
ephy_download = ephy_download_new (download);
+
+ window = gtk_application_get_active_window (GTK_APPLICATION (shell));
+ embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
+ if (embed != NULL)
+ ephy_embed_download_started (embed, ephy_download);
+
ephy_downloads_manager_add_download (priv->downloads_manager, ephy_download);
g_object_unref (ephy_download);
}
diff --git a/embed/ephy-embed-utils.c b/embed/ephy-embed-utils.c
index be9389630..97b61fcc7 100644
--- a/embed/ephy-embed-utils.c
+++ b/embed/ephy-embed-utils.c
@@ -30,6 +30,7 @@
#include "ephy-string.h"
#include "ephy-view-source-handler.h"
+#include <evince-document.h>
#include <glib/gi18n.h>
#include <jsc/jsc.h>
#include <libsoup/soup.h>
@@ -415,3 +416,27 @@ ephy_embed_utils_shutdown (void)
g_clear_pointer (&non_search_regex, g_regex_unref);
g_clear_pointer (&domain_regex, g_regex_unref);
}
+
+gboolean
+ephy_embed_utils_mime_type_is_supported_evince_document (const char *mime_type)
+{
+ GList *doc_types = ev_backends_manager_get_all_types_info ();
+ GList *l;
+ gboolean found = FALSE;
+
+ for (l = doc_types; l != NULL && !found; l = l->next) {
+ EvTypeInfo *info = (EvTypeInfo *)l->data;
+ guint i;
+
+ for (i = 0; info->mime_types[i] != NULL; ++i) {
+ if (g_ascii_strcasecmp (mime_type, info->mime_types[i]) == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+
+ g_list_free (doc_types);
+
+ return found;
+}
diff --git a/embed/ephy-embed-utils.h b/embed/ephy-embed-utils.h
index 3f99b7d89..4bd0f6502 100644
--- a/embed/ephy-embed-utils.h
+++ b/embed/ephy-embed-utils.h
@@ -36,18 +36,19 @@ G_BEGIN_DECLS
#define EPHY_WEBKIT_BACK_FORWARD_LIMIT 100
-char* ephy_embed_utils_link_message_parse (const char *message);
-gboolean ephy_embed_utils_address_has_web_scheme (const char *address);
-gboolean ephy_embed_utils_address_is_existing_absolute_filename (const char *address);
-gboolean ephy_embed_utils_address_is_valid (const char *address);
-char* ephy_embed_utils_normalize_address (const char *address);
-char * ephy_embed_utils_autosearch_address (const char *search_key);
-char * ephy_embed_utils_normalize_or_autosearch_address (const char *address);
-gboolean ephy_embed_utils_url_is_empty (const char *location);
-gboolean ephy_embed_utils_is_no_show_address (const char *address);
-char *ephy_embed_utils_get_title_from_address (const char *address);
-gboolean ephy_embed_utils_urls_have_same_origin (const char *a_url,
- const char *b_url);
-void ephy_embed_utils_shutdown (void);
+char* ephy_embed_utils_link_message_parse (const char *message);
+gboolean ephy_embed_utils_address_has_web_scheme (const char *address);
+gboolean ephy_embed_utils_address_is_existing_absolute_filename (const char *address);
+gboolean ephy_embed_utils_address_is_valid (const char *address);
+char* ephy_embed_utils_normalize_address (const char *address);
+char * ephy_embed_utils_autosearch_address (const char *search_key);
+char * ephy_embed_utils_normalize_or_autosearch_address (const char *address);
+gboolean ephy_embed_utils_url_is_empty (const char *location);
+gboolean ephy_embed_utils_is_no_show_address (const char *address);
+char *ephy_embed_utils_get_title_from_address (const char *address);
+gboolean ephy_embed_utils_urls_have_same_origin (const char *a_url,
+ const char *b_url);
+void ephy_embed_utils_shutdown (void);
+gboolean ephy_embed_utils_mime_type_is_supported_evince_document (const char *mime_type);
G_END_DECLS
diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c
index 0b101ab14..cfac6919c 100644
--- a/embed/ephy-embed.c
+++ b/embed/ephy-embed.c
@@ -29,6 +29,7 @@
#include "ephy-embed-prefs.h"
#include "ephy-embed-shell.h"
#include "ephy-embed-utils.h"
+#include "ephy-evince-document-view.h"
#include "ephy-find-toolbar.h"
#include "ephy-notification-container.h"
#include "ephy-prefs.h"
@@ -65,6 +66,7 @@ struct _EphyEmbed {
GtkWidget *floating_bar;
GtkWidget *progress;
GtkWidget *fullscreen_message_label;
+ GtkWidget *document_view;
char *title;
WebKitURIRequest *delayed_request;
@@ -74,6 +76,8 @@ struct _EphyEmbed {
GSList *messages;
GSList *keys;
+ EphyEmbedMode mode;
+
guint seq_context_id;
guint seq_message_id;
@@ -1018,3 +1022,61 @@ ephy_embed_detach_notification_container (EphyEmbed *embed)
gtk_container_remove (GTK_CONTAINER (embed->overlay), g_object_ref (GTK_WIDGET (container)));
}
}
+
+void
+ephy_embed_set_mode (EphyEmbed *embed, EphyEmbedMode mode)
+{
+ g_assert (EPHY_IS_EMBED (embed));
+
+ if (embed->mode == mode)
+ return;
+
+ switch (mode) {
+ case EPHY_EMBED_MODE_WEB_VIEW:
+ if (embed->document_view != NULL) {
+ gtk_widget_destroy (embed->document_view);
+ embed->document_view = NULL;
+ }
+ gtk_widget_set_visible (GTK_WIDGET (embed->paned), TRUE);
+ break;
+ case EPHY_EMBED_MODE_EVINCE_DOCUMENT:
+ gtk_widget_set_visible (GTK_WIDGET (embed->paned), FALSE);
+ embed->document_view = ephy_evince_document_view_new ();
+ ephy_evince_document_set_embed (EPHY_EVINCE_DOCUMENT_VIEW (embed->document_view), embed);
+ gtk_box_pack_start (GTK_BOX (embed),
+ embed->document_view,
+ TRUE, TRUE, 0);
+ gtk_widget_show_all (embed->document_view);
+ break;
+ }
+
+ embed->mode = mode;
+}
+
+EphyEmbedMode
+ephy_embed_get_mode (EphyEmbed *embed)
+{
+ return embed->mode;
+}
+
+static void
+document_download_finished_cb (WebKitDownload *download,
+ EphyEmbed *embed)
+{
+ const char *document_uri = webkit_download_get_destination (download);
+
+ ephy_evince_document_view_load_uri (EPHY_EVINCE_DOCUMENT_VIEW (embed->document_view),
+ document_uri);
+}
+
+void
+ephy_embed_download_started (EphyEmbed *embed,
+ EphyDownload *ephy_download)
+{
+ WebKitDownload *download = ephy_download_get_webkit_download (ephy_download);
+
+ if (embed->mode == EPHY_EMBED_MODE_EVINCE_DOCUMENT) {
+ ephy_download_enable_evince_document_mode (ephy_download);
+ g_signal_connect (download, "finished", G_CALLBACK (document_download_finished_cb), embed);
+ }
+}
diff --git a/embed/ephy-embed.h b/embed/ephy-embed.h
index 919a6d366..8cf658ce7 100644
--- a/embed/ephy-embed.h
+++ b/embed/ephy-embed.h
@@ -37,6 +37,11 @@ typedef enum {
EPHY_EMBED_TOP_WIDGET_POLICY_DESTROY_ON_TRANSITION
} EphyEmbedTopWidgetPolicy;
+typedef enum {
+ EPHY_EMBED_MODE_WEB_VIEW,
+ EPHY_EMBED_MODE_EVINCE_DOCUMENT
+} EphyEmbedMode;
+
EphyWebView* ephy_embed_get_web_view (EphyEmbed *embed);
EphyFindToolbar* ephy_embed_get_find_toolbar (EphyEmbed *embed);
void ephy_embed_add_top_widget (EphyEmbed *embed,
@@ -54,5 +59,10 @@ gboolean ephy_embed_inspector_is_loaded (EphyEmbed *embed);
const char *ephy_embed_get_title (EphyEmbed *embed);
void ephy_embed_attach_notification_container (EphyEmbed *embed);
void ephy_embed_detach_notification_container (EphyEmbed *embed);
+void ephy_embed_set_mode (EphyEmbed *embed,
+ EphyEmbedMode mode);
+EphyEmbedMode ephy_embed_get_mode (EphyEmbed *embed);
+void ephy_embed_download_started (EphyEmbed *embed,
+ EphyDownload *ephy_download);
G_END_DECLS
diff --git a/embed/ephy-evince-document-view.c b/embed/ephy-evince-document-view.c
new file mode 100644
index 000000000..4052c1907
--- /dev/null
+++ b/embed/ephy-evince-document-view.c
@@ -0,0 +1,334 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/* vim: set sw=2 ts=2 sts=2 et: */
+/*
+ * Copyright © 2012 Igalia S.L.
+ * Copyright © 2018 Jan-Michael Brummer
+ *
+ * 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
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "ephy-evince-document-view.h"
+#include "ephy-embed-shell.h"
+
+#include <evince-view.h>
+
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <libsoup/soup.h>
+
+struct _EphyEvinceDocumentView {
+ GtkBox parent_instance;
+
+ GtkWidget *view;
+ GtkWidget *current_page;
+ GtkWidget *total_page;
+ GtkWidget *sizing_mode;
+ GtkWidget *popup;
+
+ EphyEmbed *embed;
+
+ EvJob *job;
+ EvDocumentModel *model;
+ SoupURI *uri;
+};
+
+G_DEFINE_TYPE (EphyEvinceDocumentView, ephy_evince_document_view, GTK_TYPE_BOX)
+
+static void
+ephy_evince_document_view_finalize (GObject *object)
+{
+ EphyEvinceDocumentView *self = EPHY_EVINCE_DOCUMENT_VIEW (object);
+
+ if (self->uri != NULL) {
+ g_unlink (self->uri->path);
+
+ g_clear_pointer (&self->uri, soup_uri_free);
+ }
+
+ if (self->job != NULL) {
+ ev_job_cancel (self->job);
+ g_clear_object (&self->job);
+ }
+
+ g_clear_object (&self->model);
+
+ G_OBJECT_CLASS (ephy_evince_document_view_parent_class)->finalize (object);
+}
+
+static void
+on_save_button_clicked (GtkButton *button,
+ EphyEvinceDocumentView *self)
+{
+ g_autoptr (GtkFileChooserNative) native = NULL;
+ GtkFileChooser *chooser;
+ GError *error = NULL;
+ gint res;
+ g_autofree gchar *basename = g_path_get_basename (self->uri->path);
+
+ native = gtk_file_chooser_native_new (_("Save File"),
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ NULL,
+ NULL);
+
+ chooser = GTK_FILE_CHOOSER (native);
+
+ gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE);
+
+ gtk_file_chooser_set_current_name (chooser, basename);
+
+ res = gtk_native_dialog_run (GTK_NATIVE_DIALOG (native));
+ if (res == GTK_RESPONSE_ACCEPT) {
+ g_autofree gchar *filename;
+ GFile *source = g_file_new_for_uri (self->uri->path);
+ GFile *dest;
+
+ filename = gtk_file_chooser_get_filename (chooser);
+ dest = g_file_new_for_path (filename);
+
+ if (!g_file_copy (source, dest, G_FILE_COPY_NONE, NULL, NULL, NULL, &error)) {
+ g_warning ("%s(): Could not copy file: %s\n", __FUNCTION__, error->message);
+ g_error_free (error);
+ }
+ }
+}
+
+static void
+view_external_link_cb (EvView *view,
+ EvLinkAction *action,
+ EphyEvinceDocumentView *self)
+{
+ EvLinkActionType type = ev_link_action_get_action_type (action);
+ EphyWebView *webview;
+ const gchar *url;
+
+ if (type != EV_LINK_ACTION_TYPE_EXTERNAL_URI)
+ return;
+
+ url = ev_link_action_get_uri (action);
+
+ webview = ephy_embed_get_web_view (self->embed);
+ ephy_web_view_load_url (webview, url);
+}
+
+static void
+ephy_evince_document_view_constructed (GObject *object)
+{
+ EphyEvinceDocumentView *self = EPHY_EVINCE_DOCUMENT_VIEW (object);
+ GtkWidget *box;
+ GtkWidget *entry_box;
+ GtkWidget *save_button;
+ GtkWidget *scrolled_window;
+ GtkWidget *separator;
+
+ G_OBJECT_CLASS (ephy_evince_document_view_parent_class)->constructed (object);
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+
+ self->view = ev_view_new ();
+ g_signal_connect (self->view, "external-link", G_CALLBACK (view_external_link_cb), self);
+ gtk_container_add (GTK_CONTAINER (scrolled_window), self->view);
+ gtk_box_pack_start (GTK_BOX (self), scrolled_window, TRUE, TRUE, 0);
+
+ self->model = ev_document_model_new ();
+ ev_view_set_model (EV_VIEW (self->view), self->model);
+
+ separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_box_pack_start (GTK_BOX (self), separator, FALSE, TRUE, 0);
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+ gtk_widget_set_margin_start (box, 6);
+ gtk_widget_set_margin_end (box, 6);
+ gtk_widget_set_margin_top (box, 6);
+ gtk_widget_set_margin_bottom (box, 6);
+ gtk_box_pack_start (GTK_BOX (self), box, FALSE, TRUE, 0);
+
+ entry_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_style_context_add_class (gtk_widget_get_style_context (entry_box), GTK_STYLE_CLASS_LINKED);
+ gtk_style_context_add_class (gtk_widget_get_style_context (entry_box), GTK_STYLE_CLASS_RAISED);
+ gtk_box_pack_start (GTK_BOX (box), entry_box, FALSE, TRUE, 0);
+
+ self->current_page = gtk_entry_new ();
+ gtk_entry_set_width_chars (GTK_ENTRY (self->current_page), 2);
+ gtk_box_pack_start (GTK_BOX (entry_box), self->current_page, FALSE, TRUE, 0);
+
+ self->total_page = gtk_entry_new ();
+ gtk_entry_set_width_chars (GTK_ENTRY (self->total_page), 5);
+ gtk_widget_set_sensitive (self->total_page, FALSE);
+ gtk_box_pack_start (GTK_BOX (entry_box), self->total_page, FALSE, TRUE, 0);
+
+ save_button = gtk_button_new_from_icon_name ("document-save-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ g_signal_connect (save_button, "clicked", G_CALLBACK (on_save_button_clicked), self);
+ gtk_box_pack_end (GTK_BOX (box), save_button, FALSE, TRUE, 0);
+
+ self->sizing_mode = gtk_combo_box_text_new ();
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (self->sizing_mode), _("Fit Page"));
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (self->sizing_mode), _("Fit Width"));
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (self->sizing_mode), _("Free"));
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (self->sizing_mode), _("Automatic"));
+ gtk_box_pack_end (GTK_BOX (box), self->sizing_mode, FALSE, TRUE, 0);
+}
+
+static void
+ephy_evince_document_view_class_init (EphyEvinceDocumentViewClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructed = ephy_evince_document_view_constructed;
+ object_class->finalize = ephy_evince_document_view_finalize;
+}
+
+static void
+ephy_evince_document_view_init (EphyEvinceDocumentView *self)
+{
+}
+
+GtkWidget *
+ephy_evince_document_view_new (void)
+{
+ return g_object_new (EPHY_TYPE_EVINCE_DOCUMENT_VIEW,
+ "orientation", GTK_ORIENTATION_VERTICAL,
+ NULL);
+}
+
+static void
+on_page_changed (EvDocumentModel *model,
+ gint old_page,
+ gint new_page,
+ EphyEvinceDocumentView *self)
+{
+ g_autofree gchar *page = g_strdup_printf ("%d", new_page + 1);
+
+ gtk_entry_set_text (GTK_ENTRY (self->current_page), page);
+}
+
+static void
+on_current_page_activate (GtkEntry *entry,
+ EphyEvinceDocumentView *self)
+{
+ const gchar *text = gtk_entry_get_text (entry);
+ gint page = atoi (text);
+
+ ev_document_model_set_page (self->model, page - 1);
+}
+
+static void
+on_sizing_mode_changed (GtkComboBox *widget,
+ EphyEvinceDocumentView *self)
+{
+ gint index = gtk_combo_box_get_active (widget);
+
+ ev_document_model_set_sizing_mode (self->model, index);
+}
+
+static void
+on_popup_copy_activate (GtkMenuItem *menuitem,
+ EphyEvinceDocumentView *self)
+{
+ GtkClipboard *clipboard;
+ g_autofree gchar *selected_text = ev_view_get_selected_text (EV_VIEW (self->view));
+
+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (self), GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text (GTK_CLIPBOARD (clipboard), selected_text, strlen (selected_text));
+}
+
+static gboolean
+on_view_popup_cb (EvView *view,
+ GList *items,
+ EphyEvinceDocumentView *self)
+{
+ if (!ev_view_get_has_selection (view))
+ return TRUE;
+
+ if (!self->popup) {
+ GtkWidget *copy = gtk_menu_item_new_with_label (_("Copy"));
+ self->popup = gtk_menu_new ();
+ g_signal_connect (copy, "activate", G_CALLBACK (on_popup_copy_activate), self);
+ gtk_menu_shell_append (GTK_MENU_SHELL (self->popup), copy);
+ gtk_menu_attach_to_widget (GTK_MENU (self->popup), GTK_WIDGET (self), NULL);
+ gtk_widget_show_all (self->popup);
+ }
+
+ gtk_menu_popup_at_pointer (GTK_MENU (self->popup), NULL);
+
+ return TRUE;
+}
+
+static void
+document_load_job_finished (EvJob *job,
+ EphyEvinceDocumentView *self)
+{
+ g_autofree gchar *total_pages = NULL;
+ gint n_pages;
+
+ if (ev_job_is_failed (job)) {
+ g_warning ("Failed to load document: %s", job->error->message);
+ g_error_free (job->error);
+
+ return;
+ }
+
+ ev_document_model_set_document (self->model, job->document);
+ n_pages = ev_document_get_n_pages (job->document);
+
+ /* Translators: Number of x total pages */
+ total_pages = g_strdup_printf (_("of %d"), n_pages);
+ g_signal_connect (self->model, "page-changed", G_CALLBACK (on_page_changed), self);
+ g_signal_connect (self->current_page, "activate", G_CALLBACK (on_current_page_activate), self);
+ gtk_entry_set_text (GTK_ENTRY (self->total_page), total_pages);
+ gtk_entry_set_text (GTK_ENTRY (self->current_page), "1");
+ g_signal_connect (self->sizing_mode, "changed", G_CALLBACK (on_sizing_mode_changed), self);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (self->sizing_mode), ev_document_model_get_sizing_mode
(self->model));
+
+ g_signal_connect_object (self->view, "popup", G_CALLBACK (on_view_popup_cb), self, 0);
+}
+
+void
+ephy_evince_document_view_load_uri (EphyEvinceDocumentView *self,
+ const char *uri)
+{
+ g_return_if_fail (EPHY_EVINCE_DOCUMENT_VIEW (self));
+ g_return_if_fail (uri != NULL);
+
+ if (self->uri != NULL) {
+ if (strcmp (self->uri->path, uri) != 0)
+ g_unlink (self->uri->path);
+
+ g_clear_pointer (&self->uri, soup_uri_free);
+ }
+
+ if (self->job != NULL) {
+ ev_job_cancel (self->job);
+
+ g_clear_object (&self->job);
+ }
+
+ self->uri = soup_uri_new (uri);
+
+ self->job = ev_job_load_new (uri);
+ g_signal_connect (self->job, "finished",
+ G_CALLBACK (document_load_job_finished),
+ self);
+ ev_job_scheduler_push_job (self->job, EV_JOB_PRIORITY_NONE);
+}
+
+void
+ephy_evince_document_set_embed (EphyEvinceDocumentView *self,
+ EphyEmbed *embed)
+{
+ self->embed = embed;
+}
diff --git a/embed/ephy-evince-document-view.h b/embed/ephy-evince-document-view.h
new file mode 100644
index 000000000..6f9b0617f
--- /dev/null
+++ b/embed/ephy-evince-document-view.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/* vim: set sw=2 ts=2 sts=2 et: */
+/*
+ * Copyright © 2012 Igalia S.L.
+ * Copyright © 2018 Jan-Michael Brummer
+ *
+ * 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
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef _EPHY_EVINCE_DOCUMENT_VIEW_H
+#define _EPHY_EVINCE_DOCUMENT_VIEW_H
+
+#include <gtk/gtk.h>
+
+#include "ephy-embed.h"
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_EVINCE_DOCUMENT_VIEW (ephy_evince_document_view_get_type ())
+
+G_DECLARE_FINAL_TYPE (EphyEvinceDocumentView, ephy_evince_document_view, EPHY, EVINCE_DOCUMENT_VIEW, GtkBox)
+
+
+GType ephy_evince_document_view_get_type (void);
+
+GtkWidget *ephy_evince_document_view_new (void);
+void ephy_evince_document_view_load_uri (EphyEvinceDocumentView *self,
+ const char *uri);
+void ephy_evince_document_set_embed (EphyEvinceDocumentView *self,
+ EphyEmbed *embed);
+
+G_END_DECLS
+
+#endif /* _EPHY_EVINCE_DOCUMENT_VIEW_H */
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index 2155d482b..5b3b10f00 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -1430,6 +1430,12 @@ decide_policy_cb (WebKitWebView *web_view,
response = webkit_response_policy_decision_get_response (response_decision);
mime_type = webkit_uri_response_get_mime_type (response);
+ if (ephy_embed_utils_mime_type_is_supported_evince_document (mime_type)) {
+ EphyEmbed *embed = EPHY_GET_EMBED_FROM_EPHY_WEB_VIEW (web_view);
+
+ ephy_embed_set_mode (embed, EPHY_EMBED_MODE_EVINCE_DOCUMENT);
+ }
+
/* If WebKit can't handle the mime type start the download
process */
if (webkit_response_policy_decision_is_mime_type_supported (response_decision))
@@ -1885,6 +1891,7 @@ load_changed_cb (WebKitWebView *web_view,
gpointer user_data)
{
EphyWebView *view = EPHY_WEB_VIEW (web_view);
+ EphyEmbed *embed = EPHY_GET_EMBED_FROM_EPHY_WEB_VIEW (web_view);
GObject *object = G_OBJECT (web_view);
g_object_freeze_notify (object);
@@ -1894,6 +1901,7 @@ load_changed_cb (WebKitWebView *web_view,
const char *loading_uri = NULL;
view->load_failed = FALSE;
+ ephy_embed_set_mode (embed, EPHY_EMBED_MODE_WEB_VIEW);
if (view->snapshot_timeout_id) {
g_source_remove (view->snapshot_timeout_id);
diff --git a/embed/meson.build b/embed/meson.build
index e3a217c34..be048a121 100644
--- a/embed/meson.build
+++ b/embed/meson.build
@@ -22,6 +22,7 @@ libephyembed_sources = [
'ephy-embed-utils.c',
'ephy-encoding.c',
'ephy-encodings.c',
+ 'ephy-evince-document-view.c',
'ephy-file-monitor.c',
'ephy-filters-manager.c',
'ephy-find-toolbar.c',
@@ -34,6 +35,8 @@ libephyembed_sources = [
libephyembed_deps = [
libdazzle_dep,
ephymisc_dep,
+ evince_document_dep,
+ evince_view_dep,
gio_dep,
glib_dep,
gtk_dep,
diff --git a/flatpak/org.gnome.Epiphany.json b/flatpak/org.gnome.Epiphany.json
index d05da0f2c..06056ab13 100644
--- a/flatpak/org.gnome.Epiphany.json
+++ b/flatpak/org.gnome.Epiphany.json
@@ -98,6 +98,57 @@
}
]
},
+ {
+ "name": "openjpeg2",
+ "buildsystem": "cmake-ninja",
+ "builddir": true,
+ "sources": [
+ {
+ "type": "git",
+ "url": "https://github.com/szukw000/openjpeg.git",
+ "branch": "v2.1.2"
+ }
+ ]
+ },
+ {
+ "name" : "poppler",
+ "buildsystem" : "cmake-ninja",
+ "builddir": true,
+ "config-opts" : [
+ "-DENABLE_TESTING=OFF"
+ ],
+ "sources" : [
+ {
+ "type" : "git",
+ "url" : "https://anongit.freedesktop.org/git/poppler/poppler.git"
+ }
+ ]
+ },
+ {
+ "name" : "evince",
+ "buildsystem" : "meson",
+ "config-opts" : [
+ "-Dplatform=gnome",
+ "-Dviewer=false",
+ "-Dpreviewer=false",
+ "-Dthumbnailer=false",
+ "-Dnautilus=false",
+ "-Dgtk_doc=false",
+ "-Dintrospection=false",
+ "-Ddbus=false",
+ "-Dkeyring=disabled",
+ "-Dgtk_unix_print=disabled",
+ "-Dthumbnail_cache=disabled",
+ "-Dgspell=disabled",
+ "-Dsystemduserunitdir=no"
+ ],
+ "sources" : [
+ {
+ "type" : "git",
+ "url" : "https://gitlab.gnome.org/GNOME/evince.git"
+ }
+ ]
+ },
{
"name" : "epiphany",
"config-opts" : [
diff --git a/meson.build b/meson.build
index b50bb4f40..047352d6b 100644
--- a/meson.build
+++ b/meson.build
@@ -85,6 +85,8 @@ nettle_requirement = '>= 3.4'
webkitgtk_requirement = '>= 2.21.92'
cairo_dep = dependency('cairo', version: '>= 1.2')
+evince_document_dep = dependency('evince-document-3.0')
+evince_view_dep = dependency('evince-view-3.0')
gcr_dep = dependency('gcr-3', version: '>= 3.5.5')
gdk_dep = dependency('gdk-3.0', version: gtk_requirement)
gdk_pixbuf_dep = dependency('gdk-pixbuf-2.0', version: '>= 2.36.5')
diff --git a/src/ephy-action-bar-end.c b/src/ephy-action-bar-end.c
index 934fac09b..307773a8b 100644
--- a/src/ephy-action-bar-end.c
+++ b/src/ephy-action-bar-end.c
@@ -23,6 +23,8 @@
#include "ephy-downloads-popover.h"
#include "ephy-downloads-progress-icon.h"
+#include "ephy-embed.h"
+#include "ephy-embed-container.h"
#include "ephy-shell.h"
#include "ephy-window.h"
@@ -50,11 +52,27 @@ is_for_active_window (EphyActionBarEnd *action_bar_end)
return active_window == GTK_WINDOW (ancestor);
}
+static gboolean
+is_document_view_active (void)
+{
+ EphyShell *shell = ephy_shell_get_default ();
+ GtkWindow *window;
+ EphyEmbed *embed;
+
+ window = gtk_application_get_active_window (GTK_APPLICATION (shell));
+ embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
+
+ return ephy_embed_get_mode (embed) == EPHY_EMBED_MODE_EVINCE_DOCUMENT;
+}
+
static void
download_added_cb (EphyDownloadsManager *manager,
EphyDownload *download,
EphyActionBarEnd *action_bar_end)
{
+ if (is_document_view_active ())
+ return;
+
if (!action_bar_end->downloads_popover) {
action_bar_end->downloads_popover = ephy_downloads_popover_new (action_bar_end->downloads_button);
gtk_menu_button_set_popover (GTK_MENU_BUTTON (action_bar_end->downloads_button),
diff --git a/src/ephy-main.c b/src/ephy-main.c
index 877952075..0796393c8 100644
--- a/src/ephy-main.c
+++ b/src/ephy-main.c
@@ -33,6 +33,7 @@
#include "ephy-web-app-utils.h"
#include <errno.h>
+#include <evince-document.h>
#include <glib/gi18n.h>
#include <glib-unix.h>
#include <gtk/gtk.h>
@@ -408,6 +409,7 @@ main (int argc,
}
hdy_init (&argc, &argv);
+ ev_init ();
_ephy_shell_create_instance (mode);
@@ -433,6 +435,7 @@ main (int argc,
if (notify_is_initted ())
notify_uninit ();
+ ev_shutdown ();
ephy_settings_shutdown ();
ephy_file_helpers_shutdown ();
xmlCleanupParser ();
diff --git a/src/window-commands.c b/src/window-commands.c
index ef6c99023..5b695294e 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -668,7 +668,9 @@ window_cmd_navigation (GSimpleAction *action,
web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed);
if (strstr (g_action_get_name (G_ACTION (action)), "back")) {
+ ephy_embed_set_mode (embed, EPHY_EMBED_MODE_WEB_VIEW);
webkit_web_view_go_back (web_view);
+
gtk_widget_grab_focus (GTK_WIDGET (embed));
} else {
webkit_web_view_go_forward (web_view);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]