[libgepub] Added GepubWidget class to show the content with webkit



commit b6a93ab3598d7c8713d943e2d02ad565455bb1ad
Author: Daniel Garcia Moreno <danigm wadobo com>
Date:   Mon Jun 13 00:23:58 2016 +0200

    Added GepubWidget class to show the content with webkit
    
    This new widget shows the epub content using webkit2gtk. The new widget
    inherites from GtkBox and at first it only shows a WebKitWebView with the
    current doc page, but the idea is to be able to paginate and show two pages
    at the same time, for the landscape view.

 configure.ac            |    2 +
 libgepub/Makefile.am    |    4 +-
 libgepub/gepub-doc.c    |    7 +--
 libgepub/gepub-widget.c |  196 +++++++++++++++++++++++++++++++++++++++++++++++
 libgepub/gepub-widget.h |   52 +++++++++++++
 libgepub/gepub.h        |    1 +
 tests/test-gepub.c      |   24 ++++--
 7 files changed, 271 insertions(+), 15 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 3a9d85a..cdd4cb9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,6 +17,7 @@ AC_PROG_INSTALL
 AC_PROG_LIBTOOL
 
 PKG_CHECK_MODULES(GEPUB,
+                  webkit2gtk-4.0
                   libsoup-2.4
                   glib-2.0
                   gobject-2.0
@@ -28,6 +29,7 @@ AC_SUBST(GEPUB_CFLAGS)
 AC_SUBST(GEPUB_LIBS)
 
 PKG_CHECK_MODULES(GEPUB_TESTS,
+                  webkit2gtk-4.0
                   libsoup-2.4
                   glib-2.0
                   gobject-2.0
diff --git a/libgepub/Makefile.am b/libgepub/Makefile.am
index 691e592..fb30f48 100644
--- a/libgepub/Makefile.am
+++ b/libgepub/Makefile.am
@@ -4,6 +4,7 @@ NOINST_H_FILES = \
        gepub-utils.h
 
 INST_H_FILES = \
+       gepub-widget.h          \
        gepub-archive.h         \
        gepub-text-chunk.h      \
        gepub-doc.h             \
@@ -13,6 +14,7 @@ libgepubincludedir = $(includedir)/libgepub
 libgepubinclude_HEADERS = $(INST_H_FILES)
 
 libgepub_la_SOURCES = \
+       gepub-widget.c                  \
        gepub-archive.c                 \
        gepub-text-chunk.c              \
        gepub-doc.c                             \
@@ -48,7 +50,7 @@ if HAVE_INTROSPECTION
 introspection_sources = $(libgepub_la_SOURCES)
 
 Gepub-0.3.gir: libgepub.la
-Gepub_0_3_gir_INCLUDES = GObject-2.0 libxml2-2.0
+Gepub_0_3_gir_INCLUDES = GObject-2.0 libxml2-2.0 WebKit2-4.0
 Gepub_0_3_gir_CFLAGS = $(INCLUDES)
 Gepub_0_3_gir_LIBS = libgepub.la
 Gepub_0_3_gir_FILES = $(introspection_sources)
diff --git a/libgepub/gepub-doc.c b/libgepub/gepub-doc.c
index 001911f..a71f165 100644
--- a/libgepub/gepub-doc.c
+++ b/libgepub/gepub-doc.c
@@ -408,21 +408,16 @@ gepub_doc_get_resource_mime_by_id (GepubDoc *doc, gchar *id)
 gchar *
 gepub_doc_get_resource_mime (GepubDoc *doc, gchar *v)
 {
-    gchar *path = NULL;
     GepubResource *gres;
     GList *keys = g_hash_table_get_keys (doc->resources);
 
-    path = g_strdup_printf ("%s%s", doc->content_base, v);
-
     while (keys) {
         gres = ((GepubResource*)g_hash_table_lookup (doc->resources, keys->data));
-        if (!strcmp (gres->uri, path))
+        if (!strcmp (gres->uri, v))
             break;
         keys = keys->next;
     }
 
-    g_free(path);
-
     if (keys)
         return g_strdup (gres->mime);
     else
diff --git a/libgepub/gepub-widget.c b/libgepub/gepub-widget.c
new file mode 100644
index 0000000..ae91c38
--- /dev/null
+++ b/libgepub/gepub-widget.c
@@ -0,0 +1,196 @@
+/* GepubWidget
+ *
+ * Copyright (C) 2016 Daniel Garcia <danigm wadobo com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+
+#include "gepub-widget.h"
+
+struct _GepubWidget {
+    GtkBox parent;
+
+    GepubDoc *doc;
+    WebKitWebView *view;
+};
+
+struct _GepubWidgetClass {
+    GtkBoxClass parent_class;
+};
+
+G_DEFINE_TYPE (GepubWidget, gepub_widget, GTK_TYPE_BOX)
+
+static void
+resource_callback (WebKitURISchemeRequest *request, gpointer user_data)
+{
+    GInputStream *stream;
+    gsize stream_length;
+    gchar *path;
+    gchar *uri;
+    guchar *contents;
+    gchar *mime;
+    GepubWidget *widget;
+
+    widget = GEPUB_WIDGET (user_data);
+    uri = g_strdup (webkit_uri_scheme_request_get_uri (request));
+    // removing "epub://"
+    path = uri + 7;
+    contents = gepub_doc_get_resource_v (widget->doc, path, &stream_length);
+    mime = gepub_doc_get_resource_mime (widget->doc, path);
+
+    if (!mime) {
+        g_free (uri);
+        return;
+    }
+
+    stream = g_memory_input_stream_new_from_data (contents, stream_length, g_free);
+    webkit_uri_scheme_request_finish (request, stream, stream_length, mime);
+
+    g_object_unref (stream);
+    g_free (mime);
+    g_free (uri);
+}
+
+static void
+gepub_widget_finalize (GObject *object)
+{
+    GepubWidget *widget = GEPUB_WIDGET (object);
+
+    if (widget->doc) {
+        g_object_unref (widget->doc);
+        widget->doc = NULL;
+    }
+    if (widget->view) {
+        gtk_widget_destroy (GTK_WIDGET (widget->view));
+        widget->view = NULL;
+    }
+
+    G_OBJECT_CLASS (gepub_widget_parent_class)->finalize (object);
+}
+
+static void
+gepub_widget_init (GepubWidget *doc)
+{
+}
+
+static void
+gepub_widget_class_init (GepubWidgetClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    object_class->finalize = gepub_widget_finalize;
+}
+
+/**
+ * gepub_widget_new:
+ * @path: the epub doc path
+ * @error: location to store a #GError, or %NULL
+ *
+ * Returns: (transfer full): the new GepubWidget created
+ */
+GtkWidget *
+gepub_widget_new (const gchar *path)
+{
+    GepubWidget *widget = g_object_new (GEPUB_TYPE_WIDGET,
+                                        "orientation", GTK_ORIENTATION_HORIZONTAL,
+                                        "spacing", 0,
+                                        NULL);
+
+    widget->doc = NULL;
+    widget->view = NULL;
+
+    return GTK_WIDGET (widget);
+}
+
+/**
+ * gepub_widget_get_doc:
+ * @widget: a #GepubWidget
+ *
+ * Returns: (transfer none): the #GepubDoc
+ */
+GepubDoc *
+gepub_widget_get_doc (GepubWidget *widget)
+{
+    return widget->doc;
+}
+
+/**
+ * gepub_widget_get_wkview:
+ * @widget: a #GepubWidget
+ *
+ * Returns: (transfer none): the #WebKitWebView related with the widget
+ */
+WebKitWebView *
+gepub_widget_get_wkview (GepubWidget *widget)
+{
+    return widget->view;
+}
+
+/**
+ * gepub_widget_load_epub:
+ * @widget: a #GepubWidget
+ * @path: The epub doc path
+ *
+ * This method reloads the widget with the new document
+ */
+void
+gepub_widget_load_epub (GepubWidget *widget, const gchar *path)
+{
+    GtkBox *box = GTK_BOX (widget);
+    WebKitWebContext *ctx = NULL;
+
+    if (widget->doc) {
+        g_object_unref (widget->doc);
+        widget->doc = NULL;
+    }
+    if (widget->view) {
+        gtk_widget_destroy (GTK_WIDGET (widget->view));
+        widget->view = NULL;
+    }
+
+    widget->doc = gepub_doc_new (path);
+    widget->view = WEBKIT_WEB_VIEW (webkit_web_view_new ());
+
+    ctx = webkit_web_view_get_context (WEBKIT_WEB_VIEW (widget->view));
+    webkit_web_context_register_uri_scheme (ctx, "epub", resource_callback, widget, NULL);
+
+    gepub_widget_reload (widget);
+
+    gtk_box_pack_start (box, GTK_WIDGET (widget->view), TRUE, TRUE, 0);
+}
+
+/**
+ * gepub_widget_load_epub:
+ * @widget: a #GepubWidget
+ *
+ * This method reloads the data with the GepubDoc current chapter
+ */
+void
+gepub_widget_reload (GepubWidget *widget)
+{
+    gsize bufsize = 0;
+    guchar *buffer = NULL;
+
+    buffer = gepub_doc_get_current_with_epub_uris (widget->doc, &bufsize);
+
+    webkit_web_view_load_bytes (
+        widget->view,
+        g_bytes_new_take (buffer, bufsize),
+        gepub_doc_get_current_mime (widget->doc),
+        "UTF-8", NULL);
+}
diff --git a/libgepub/gepub-widget.h b/libgepub/gepub-widget.h
new file mode 100644
index 0000000..15968b8
--- /dev/null
+++ b/libgepub/gepub-widget.h
@@ -0,0 +1,52 @@
+/* GepubWidget
+ *
+ * Copyright (C) 2016 Daniel Garcia <danigm wadobo com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __GEPUB_WIDGET_H__
+#define __GEPUB_WIDGET_H__
+
+#include <webkit2/webkit2.h>
+#include <glib-object.h>
+#include <glib.h>
+
+#include "gepub-doc.h"
+
+G_BEGIN_DECLS
+
+#define GEPUB_TYPE_WIDGET           (gepub_widget_get_type ())
+#define GEPUB_WIDGET(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GEPUB_TYPE_WIDGET, GepubWidget))
+#define GEPUB_WIDGET_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GEPUB_TYPE_WIDGET, GepubWidgetClass))
+#define GEPUB_IS_WIDGET(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GEPUB_TYPE_WIDGET))
+#define GEPUB_IS_WIDGET_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GEPUB_TYPE_WIDGET))
+#define GEPUB_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEPUB_TYPE_WIDGET, GepubWidgetClass))
+
+typedef struct _GepubWidget      GepubWidget;
+typedef struct _GepubWidgetClass GepubWidgetClass;
+
+GType             gepub_widget_get_type                        (void) G_GNUC_CONST;
+
+GtkWidget        *gepub_widget_new                             ();
+GepubDoc         *gepub_widget_get_doc                         (GepubWidget *widget);
+WebKitWebView    *gepub_widget_get_wkview                      (GepubWidget *widget);
+void              gepub_widget_load_epub                       (GepubWidget *widget, const gchar *path);
+void              gepub_widget_reload                          (GepubWidget *widget);
+
+G_END_DECLS
+
+#endif /* __GEPUB_WIDGET_H__ */
+
diff --git a/libgepub/gepub.h b/libgepub/gepub.h
index 756fef0..a8f7fd2 100644
--- a/libgepub/gepub.h
+++ b/libgepub/gepub.h
@@ -4,5 +4,6 @@
 #include "gepub-archive.h"
 #include "gepub-text-chunk.h"
 #include "gepub-doc.h"
+#include "gepub-widget.h"
 
 #endif
diff --git a/tests/test-gepub.c b/tests/test-gepub.c
index 55c4bee..f010b7d 100644
--- a/tests/test-gepub.c
+++ b/tests/test-gepub.c
@@ -64,8 +64,10 @@ print_replaced_text (GepubDoc *doc)
 }
 
 void
-button_pressed (GtkButton *button, GepubDoc *doc)
+button_pressed (GtkButton *button, GepubWidget *widget)
 {
+    GepubDoc *doc = gepub_widget_get_doc (widget);
+
     if (!strcmp (gtk_button_get_label (button), "prev")) {
         gepub_doc_go_prev (doc);
     } else {
@@ -73,6 +75,8 @@ button_pressed (GtkButton *button, GepubDoc *doc)
     }
     update_text (doc);
     print_replaced_text (doc);
+
+    gepub_widget_reload (widget);
 }
 
 void
@@ -243,6 +247,7 @@ main (int argc, char **argv)
 
     GepubDoc *doc;
     GtkWidget *textview2;
+    GtkWidget *widget = gepub_widget_new ();
 
     if (argc < 2) {
         printf ("you should provide an .epub file\n");
@@ -255,7 +260,9 @@ main (int argc, char **argv)
     vpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
     gtk_container_add (GTK_CONTAINER (window), vpaned);
 
-    doc = gepub_doc_new (argv[1]);
+    // gepub widget
+    gepub_widget_load_epub (GEPUB_WIDGET (widget), argv[1]);
+    doc = gepub_widget_get_doc (GEPUB_WIDGET (widget));
     if (!doc) {
         perror ("BAD epub FILE");
         return -1;
@@ -276,22 +283,23 @@ main (int argc, char **argv)
     vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
     hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
     b_prev = gtk_button_new_with_label ("prev");
-    g_signal_connect (b_prev, "clicked", (GCallback)button_pressed, doc);
+    g_signal_connect (b_prev, "clicked", (GCallback)button_pressed, GEPUB_WIDGET (widget));
     b_next = gtk_button_new_with_label ("next");
-    g_signal_connect (b_next, "clicked", (GCallback)button_pressed, doc);
+    g_signal_connect (b_next, "clicked", (GCallback)button_pressed, GEPUB_WIDGET (widget));
     gtk_container_add (GTK_CONTAINER (hbox), b_prev);
     gtk_container_add (GTK_CONTAINER (hbox), b_next);
     gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
     gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 5);
 
-    gtk_widget_set_size_request (GTK_WIDGET (vbox), 400, 500);
-    gtk_paned_add1 (GTK_PANED (vpaned), vbox);
-
     textview = gtk_text_view_new ();
     scrolled = gtk_scrolled_window_new (NULL, NULL);
     gtk_container_add (GTK_CONTAINER (scrolled), textview);
     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, 
GTK_POLICY_AUTOMATIC);
-    gtk_paned_add2 (GTK_PANED (vpaned), scrolled);
+    gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 5);
+
+    gtk_widget_set_size_request (GTK_WIDGET (vbox), 400, 500);
+    gtk_paned_add1 (GTK_PANED (vpaned), vbox);
+    gtk_paned_add2 (GTK_PANED (vpaned), widget);
 
     gtk_widget_show_all (window);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]