[gnome-documents] preview: add GdPdfLoader



commit 131175c50bdf02b878b135d6443cd04b496e2d99
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Wed Jul 20 18:00:43 2011 -0400

    preview: add GdPdfLoader
    
    Taken from Sushi.

 configure.ac            |    2 +
 src/Makefile-lib.am     |    6 +-
 src/application.js      |    2 +
 src/lib/gd-pdf-loader.c |  375 +++++++++++++++++++++++++++++++++++++++++++++++
 src/lib/gd-pdf-loader.h |   64 ++++++++
 5 files changed, 448 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 5d294a2..9f957a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -55,6 +55,8 @@ GOBJECT_INTROSPECTION_MIN_VERSION=0.9.6
 GDATA_MIN_VERSION=0.9.1
 
 PKG_CHECK_MODULES(DOCUMENTS,
+                  evince-document-3.0
+                  evince-view-3.0
                   glib-2.0 >= $GLIB_MIN_VERSION
                   gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
                   gtk+-3.0 >= $GTK_MIN_VERSION
diff --git a/src/Makefile-lib.am b/src/Makefile-lib.am
index 895a90a..8dc274f 100644
--- a/src/Makefile-lib.am
+++ b/src/Makefile-lib.am
@@ -9,12 +9,14 @@ gdprivate_cflags = \
 gdprivate_source_h = \
     lib/gd-utils.h \
     lib/gd-framed-pixbuf-renderer.h \
+    lib/gd-pdf-loader.h \
     lib/gd-two-lines-renderer.h \
     $(NULL)
 
 gdprivate_source_c = \
     lib/gd-utils.c \
     lib/gd-framed-pixbuf-renderer.c \
+    lib/gd-pdf-loader.c \
     lib/gd-two-lines-renderer.c \
     $(NULL)
 
@@ -39,7 +41,9 @@ Gd_1_0_gir_LIBS = libgdprivate-1.0.la
 Gd_1_0_gir_CFLAGS = $(AM_CPPFLAGS) $(gdprivate_cflags)
 Gd_1_0_gir_SCANNERFLAGS = --warn-all --symbol-prefix=gd --identifier-prefix=Gd
 Gd_1_0_gir_INCLUDES = \
-   Gtk-3.0
+   Gtk-3.0 \
+   EvinceDocument-3.0 \
+   EvinceView-3.0
 
 Gd_1_0_gir_FILES = \
     $(addprefix $(srcdir)/,$(gdprivate_source_h)) \
diff --git a/src/application.js b/src/application.js
index e21fc32..6bea45a 100644
--- a/src/application.js
+++ b/src/application.js
@@ -23,6 +23,7 @@ const DBus = imports.dbus;
 const Lang = imports.lang;
 const Gettext = imports.gettext;
 
+const EvDoc = imports.gi.EvinceDocument;
 const Gdk = imports.gi.Gdk;
 const Gtk = imports.gi.Gtk;
 const GLib = imports.gi.GLib;
@@ -94,6 +95,7 @@ Application.prototype = {
 
         GLib.set_prgname('gnome-documents');
         Gtk.init(null, null);
+        EvDoc.init();
     },
 
     _initGtkSettings: function() {
diff --git a/src/lib/gd-pdf-loader.c b/src/lib/gd-pdf-loader.c
new file mode 100644
index 0000000..a812cb8
--- /dev/null
+++ b/src/lib/gd-pdf-loader.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc.
+ *
+ * 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 of the
+ * License, 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., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <cosimoc redhat com>
+ *
+ */
+
+#include "gd-pdf-loader.h"
+
+#include <evince-document.h>
+#include <evince-view.h>
+
+G_DEFINE_TYPE (GdPdfLoader, gd_pdf_loader, G_TYPE_OBJECT);
+
+enum {
+  PROP_DOCUMENT = 1,
+  PROP_URI
+};
+
+struct _GdPdfLoaderPrivate {
+  EvDocument *document;
+  gchar *uri;
+  gchar *pdf_path;
+
+  GPid unoconv_pid;
+};
+
+static void
+load_job_done (EvJob *job,
+               gpointer user_data)
+{
+  GdPdfLoader *self = user_data;
+
+  if (ev_job_is_failed (job)) {
+    g_print ("Failed to load document: %s", job->error->message);
+    g_object_unref (job);
+
+    return;
+  }
+
+  self->priv->document = g_object_ref (job->document);
+  g_object_unref (job);
+
+  g_object_notify (G_OBJECT (self), "document");
+}
+
+static void
+load_pdf (GdPdfLoader *self,
+          const gchar *uri)
+{
+  EvJob *job;
+
+  job = ev_job_load_new (uri);
+  g_signal_connect (job, "finished",
+                    G_CALLBACK (load_job_done), self);
+
+  ev_job_scheduler_push_job (job, EV_JOB_PRIORITY_NONE);
+}
+
+static void
+unoconv_child_watch_cb (GPid pid,
+                        gint status,
+                        gpointer user_data)
+{
+  GdPdfLoader *self = user_data;
+  GFile *file;
+  gchar *uri;
+
+  g_spawn_close_pid (pid);
+  self->priv->unoconv_pid = -1;
+
+  file = g_file_new_for_path (self->priv->pdf_path);
+  uri = g_file_get_uri (file);
+  load_pdf (self, uri);
+
+  g_object_unref (file);
+  g_free (uri);
+}
+
+static void
+load_openoffice (GdPdfLoader *self)
+{
+  gchar *doc_path, *pdf_path, *tmp_name, *tmp_path;
+  GFile *file;
+  gboolean res;
+  gchar *cmd;
+
+  gint argc;
+  GPid pid;
+  gchar **argv = NULL;
+  GError *error = NULL;
+
+  file = g_file_new_for_uri (self->priv->uri);
+  doc_path = g_file_get_path (file);
+  g_object_unref (file);
+
+  tmp_name = g_strdup_printf ("gnome-documents-%d.pdf", getpid ());
+  tmp_path = g_build_filename (g_get_user_cache_dir (), "gnome-documents", NULL);
+  self->priv->pdf_path = pdf_path =
+    g_build_filename (tmp_path, tmp_name, NULL);
+  g_mkdir_with_parents (tmp_path, 0700);
+
+  cmd = g_strdup_printf ("unoconv -f pdf -o %s %s", pdf_path, doc_path);
+
+  g_free (doc_path);
+  g_free (tmp_name);
+  g_free (tmp_path);
+
+  res = g_shell_parse_argv (cmd, &argc, &argv, &error);
+  g_free (cmd);
+
+  if (!res) {
+    g_warning ("Error while parsing the unoconv command line: %s",
+               error->message);
+    g_error_free (error);
+
+    return;
+  }
+
+  res = g_spawn_async (NULL, argv, NULL,
+                       G_SPAWN_DO_NOT_REAP_CHILD |
+                       G_SPAWN_SEARCH_PATH,
+                       NULL, NULL,
+                       &pid, &error);
+
+  g_strfreev (argv);
+
+  if (!res) {
+    g_warning ("Error while spawning unoconv: %s",
+               error->message);
+    g_error_free (error);
+
+    return;
+  }
+
+  g_child_watch_add (pid, unoconv_child_watch_cb, self);
+  self->priv->unoconv_pid = pid;
+}
+
+static gchar **
+query_supported_document_types (void)
+{
+  GList *infos, *l;
+  gchar **retval = NULL;
+  GPtrArray *array;
+  EvTypeInfo *info;
+  gint idx;
+
+  infos = ev_backends_manager_get_all_types_info ();
+
+  if (infos == NULL)
+    return NULL;
+
+  array = g_ptr_array_new ();
+
+  for (l = infos; l != NULL; l = l->next) {
+    info = l->data;
+
+    for (idx = 0; info->mime_types[idx] != NULL; idx++)
+      g_ptr_array_add (array, g_strdup (info->mime_types[idx]));
+  }
+
+  g_ptr_array_add (array, NULL);
+  retval = (gchar **) g_ptr_array_free (array, FALSE);
+
+  return retval;
+}
+
+static gboolean
+content_type_is_native (const gchar *content_type)
+{
+  gchar **native_types;
+  gint idx;
+  gboolean found = FALSE;
+
+  native_types = query_supported_document_types ();
+
+  for (idx = 0; native_types[idx] != NULL; idx++) {
+    found = g_content_type_is_a (content_type, native_types[idx]);
+    if (found)
+      break;
+  }
+
+  g_strfreev (native_types);
+
+  return found;
+}
+
+static void
+query_info_ready_cb (GObject *obj,
+                     GAsyncResult *res,
+                     gpointer user_data)
+{
+  GdPdfLoader *self = user_data;
+  GError *error = NULL;
+  GFileInfo *info;
+  const gchar *content_type;
+
+  info = g_file_query_info_finish (G_FILE (obj),
+                                   res, &error);
+
+  if (error != NULL) {
+    g_warning ("Unable to query the mimetype of %s: %s",
+               self->priv->uri, error->message);
+    g_error_free (error);
+
+    return;
+  }
+
+  content_type = g_file_info_get_content_type (info);
+  g_object_unref (info);
+
+  if (content_type_is_native (content_type))
+    load_pdf (self, self->priv->uri);
+  else
+    load_openoffice (self);
+}
+
+static void
+start_loading_document (GdPdfLoader *self)
+{
+  GFile *file;
+
+  file = g_file_new_for_uri (self->priv->uri);
+  g_file_query_info_async (file,
+                           G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+                           G_FILE_QUERY_INFO_NONE,
+                           G_PRIORITY_DEFAULT,
+                           NULL,
+                           query_info_ready_cb,
+                           self);
+
+  g_object_unref (file);
+}
+
+static void
+gd_pdf_loader_set_uri (GdPdfLoader *self,
+                       const gchar *uri)
+{
+  g_clear_object (&self->priv->document);
+  g_free (self->priv->uri);
+
+  self->priv->uri = g_strdup (uri);
+  start_loading_document (self);
+}
+
+void
+gd_pdf_loader_cleanup_document (GdPdfLoader *self)
+{
+  if (self->priv->pdf_path) {
+    g_unlink (self->priv->pdf_path);
+    g_free (self->priv->pdf_path);
+  }
+
+  if (self->priv->unoconv_pid != -1) {
+    kill (self->priv->unoconv_pid, SIGKILL);
+    self->priv->unoconv_pid = -1;
+  }
+}
+
+static void
+gd_pdf_loader_dispose (GObject *object)
+{
+  GdPdfLoader *self = GD_PDF_LOADER (object);
+
+  gd_pdf_loader_cleanup_document (self);
+
+  g_clear_object (&self->priv->document);
+  g_free (self->priv->uri);
+
+  G_OBJECT_CLASS (gd_pdf_loader_parent_class)->dispose (object);
+}
+
+static void
+gd_pdf_loader_get_property (GObject *object,
+                            guint       prop_id,
+                            GValue     *value,
+                            GParamSpec *pspec)
+{
+  GdPdfLoader *self = GD_PDF_LOADER (object);
+
+  switch (prop_id) {
+  case PROP_DOCUMENT:
+    g_value_set_object (value, self->priv->document);
+    break;
+  case PROP_URI:
+    g_value_set_string (value, self->priv->uri);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+gd_pdf_loader_set_property (GObject *object,
+                            guint       prop_id,
+                            const GValue *value,
+                            GParamSpec *pspec)
+{
+  GdPdfLoader *self = GD_PDF_LOADER (object);
+
+  switch (prop_id) {
+  case PROP_URI:
+    gd_pdf_loader_set_uri (self, g_value_get_string (value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+gd_pdf_loader_class_init (GdPdfLoaderClass *klass)
+{
+  GObjectClass *oclass;
+
+  oclass = G_OBJECT_CLASS (klass);
+  oclass->dispose = gd_pdf_loader_dispose;
+  oclass->get_property = gd_pdf_loader_get_property;
+  oclass->set_property = gd_pdf_loader_set_property;
+
+    g_object_class_install_property
+      (oclass,
+       PROP_DOCUMENT,
+       g_param_spec_object ("document",
+                            "Document",
+                            "The loaded document",
+                            EV_TYPE_DOCUMENT,
+                            G_PARAM_READABLE));
+
+    g_object_class_install_property
+      (oclass,
+       PROP_URI,
+       g_param_spec_string ("uri",
+                            "URI",
+                            "The URI to load",
+                            NULL,
+                            G_PARAM_READWRITE));
+
+    g_type_class_add_private (klass, sizeof (GdPdfLoaderPrivate));
+}
+
+static void
+gd_pdf_loader_init (GdPdfLoader *self)
+{
+  self->priv =
+    G_TYPE_INSTANCE_GET_PRIVATE (self,
+                                 GD_TYPE_PDF_LOADER,
+                                 GdPdfLoaderPrivate);
+  self->priv->unoconv_pid = -1;
+}
+
+GdPdfLoader *
+gd_pdf_loader_new (const gchar *uri)
+{
+  return g_object_new (GD_TYPE_PDF_LOADER,
+                       "uri", uri,
+                       NULL);
+}
diff --git a/src/lib/gd-pdf-loader.h b/src/lib/gd-pdf-loader.h
new file mode 100644
index 0000000..75f4ded
--- /dev/null
+++ b/src/lib/gd-pdf-loader.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc.
+ *
+ * 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 of the
+ * License, 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., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors: Cosimo Cecchi <cosimoc redhat com>
+ *
+ */
+
+#ifndef __GD_PDF_LOADER_H__
+#define __GD_PDF_LOADER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GD_TYPE_PDF_LOADER            (gd_pdf_loader_get_type ())
+#define GD_PDF_LOADER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GD_TYPE_PDF_LOADER, GdPdfLoader))
+#define GD_IS_PDF_LOADER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GD_TYPE_PDF_LOADER))
+#define GD_PDF_LOADER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GD_TYPE_PDF_LOADER, GdPdfLoaderClass))
+#define GD_IS_PDF_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GD_TYPE_PDF_LOADER))
+#define GD_PDF_LOADER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GD_TYPE_PDF_LOADER, GdPdfLoaderClass))
+
+typedef struct _GdPdfLoader          GdPdfLoader;
+typedef struct _GdPdfLoaderPrivate   GdPdfLoaderPrivate;
+typedef struct _GdPdfLoaderClass     GdPdfLoaderClass;
+
+struct _GdPdfLoader
+{
+  GObject parent_instance;
+
+  GdPdfLoaderPrivate *priv;
+};
+
+struct _GdPdfLoaderClass
+{
+  GObjectClass parent_class;
+};
+
+GType    gd_pdf_loader_get_type     (void) G_GNUC_CONST;
+
+GdPdfLoader *gd_pdf_loader_new (const gchar *uri);
+void gd_pdf_loader_cleanup_document (GdPdfLoader *self);
+void gd_pdf_loader_get_max_page_size (GdPdfLoader *self,
+                                         gdouble *width,
+                                         gdouble *height);
+
+
+G_END_DECLS
+
+#endif /* __GD_PDF_LOADER_H__ */



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