[sushi] evince: add support for OpenOffice/MSOffice files via unoconvert



commit 8ce4e8d5c60f604b4c4b1d98448c08f4e9eb30c8
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Tue Apr 19 16:58:51 2011 -0400

    evince: add support for OpenOffice/MSOffice files via unoconvert

 data/style/gtk-style.css        |    4 +
 src/js/viewers/evince.js        |   50 +++++++++++----
 src/libsushi/sushi-pdf-loader.c |  132 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 171 insertions(+), 15 deletions(-)
---
diff --git a/data/style/gtk-style.css b/data/style/gtk-style.css
index 1b9351d..aa08d7a 100644
--- a/data/style/gtk-style.css
+++ b/data/style/gtk-style.css
@@ -9,6 +9,10 @@ GtkLabel {
     color: #fff;
 }
 
+.spinner {
+    color: @np_fg_color;
+}
+
 .scrollbar.slider,
 .scrollbar.button {
     color: shade (@np_bg_color, 1.30);
diff --git a/src/js/viewers/evince.js b/src/js/viewers/evince.js
index abd7ccc..657afa0 100644
--- a/src/js/viewers/evince.js
+++ b/src/js/viewers/evince.js
@@ -2,9 +2,12 @@ const Sushi = imports.gi.Sushi;
 const EvDoc = imports.gi.EvinceDocument;
 const EvView = imports.gi.EvinceView;
 
+let Gettext = imports.gettext.domain("sushi");
+
 let Utils = imports.ui.utils;
 
-const PDF_X_PADDING = 40;
+let PDF_X_PADDING = 40;
+let SPINBOX_SIZE = 150;
 
 function EvinceRenderer(args) {
     this._init(args);
@@ -24,29 +27,46 @@ EvinceRenderer.prototype = {
                                 Lang.bind(this, this._onDocumentLoaded));
         this._pdfLoader.uri = file.get_uri();
 
-        this._view = EvView.View.new();
-        this._view.show();
+        this._spinnerBox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 12);
+        this._spinnerBox.show();
 
-        this._scrolledWin = Gtk.ScrolledWindow.new(null, null);
-        this._scrolledWin.set_min_content_width(Constants.VIEW_MIN);
-        this._scrolledWin.set_min_content_height(Constants.VIEW_MIN);
-        this._scrolledWin.add(this._view);
-        this._scrolledWin.show();
+        let spinner = Gtk.Spinner.new();
+        spinner.show();
+        spinner.start();
+        this._spinnerBox.pack_start(spinner, true, true, 0);
 
-        this._actor = new GtkClutter.Actor({ contents: this._scrolledWin });
+        let label = new Gtk.Label();
+        label.set_text(Gettext.gettext("Loading..."));
+        label.show();
+        this._spinnerBox.pack_start(label, true, true, 0);
+
+        this._actor = new GtkClutter.Actor({ contents: this._spinnerBox });
         this._actor.set_reactive(true);
 
         return this._actor;
     },
 
     _onDocumentLoaded : function() {
+        this._spinnerBox.destroy();
+
         this._document = this._pdfLoader.document;
         this._model = EvView.DocumentModel.new_with_document(this._document);
 
         this._model.set_sizing_mode(EvView.SizingMode.FIT_WIDTH);
 	this._model.set_continuous(true);
 
+        this._view = EvView.View.new();
+        this._view.show();
+
+        this._scrolledWin = Gtk.ScrolledWindow.new(null, null);
+        this._scrolledWin.set_min_content_width(Constants.VIEW_MIN);
+        this._scrolledWin.set_min_content_height(Constants.VIEW_MIN);
+        this._scrolledWin.show();
+
         this._view.set_model(this._model);
+        this._scrolledWin.add(this._view);
+
+        this._actor.get_widget().add(this._scrolledWin);
 
         let pageSize = this._pdfLoader.get_max_page_size();
         this._pageWidth = Math.floor(pageSize[0]);
@@ -60,9 +80,7 @@ EvinceRenderer.prototype = {
         let height = this._pageHeight;
 
         if (!this._document) {
-            let swSize = this._scrolledWin.get_preferred_size()[1];
-            width = swSize.width;
-            height = swSize.height;
+            [ width, height ] = [ SPINBOX_SIZE, SPINBOX_SIZE ];
         } else {
             let scaledSize = Utils.getScaledSize([ width, height ],
                                                  allocation,
@@ -101,4 +119,10 @@ EvinceRenderer.prototype = {
 let handler = new MimeHandler.MimeHandler();
 let renderer = new EvinceRenderer();
 
-handler.registerMime("application/pdf", renderer);
\ No newline at end of file
+handler.registerMime("application/pdf", renderer);
+handler.registerMime("application/vnd.oasis.opendocument.text", renderer);
+handler.registerMime("application/vnd.oasis.opendocument.presentation", renderer);
+handler.registerMime("application/vnd.oasis.opendocument.spreadsheet", renderer);
+handler.registerMime("application/msword", renderer);
+handler.registerMime("application/vnd.ms-excel", renderer);
+handler.registerMime("application/vnd.ms-powerpoint", renderer);
diff --git a/src/libsushi/sushi-pdf-loader.c b/src/libsushi/sushi-pdf-loader.c
index bf759ce..4580478 100644
--- a/src/libsushi/sushi-pdf-loader.c
+++ b/src/libsushi/sushi-pdf-loader.c
@@ -12,6 +12,7 @@ enum {
 struct _SushiPdfLoaderPrivate {
   EvDocument *document;
   gchar *uri;
+  gchar *pdf_path;
 };
 
 static void
@@ -34,11 +35,12 @@ load_job_done (EvJob *job,
 }
 
 static void
-start_loading_document (SushiPdfLoader *self)
+load_pdf (SushiPdfLoader *self,
+          const gchar *uri)
 {
   EvJob *job;
 
-  job = ev_job_load_new (self->priv->uri);
+  job = ev_job_load_new (uri);
   g_signal_connect (job, "finished",
                     G_CALLBACK (load_job_done), self);
 
@@ -46,6 +48,127 @@ start_loading_document (SushiPdfLoader *self)
 }
 
 static void
+unoconv_child_watch_cb (GPid pid,
+                        gint status,
+                        gpointer user_data)
+{
+  SushiPdfLoader *self = user_data;
+  GFile *file;
+  gchar *uri;
+
+  g_spawn_close_pid (pid);
+
+  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 (SushiPdfLoader *self)
+{
+  gchar *doc_path, *pdf_path, *tmp_name;
+  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_strconcat ("sushi-", g_get_user_name (), "-tmp.pdf", NULL);
+  self->priv->pdf_path = pdf_path =
+    g_build_filename (g_get_tmp_dir (), tmp_name, NULL);
+  cmd = g_strdup_printf ("unoconv -f pdf -o %s %s", pdf_path, doc_path);
+
+  g_free (doc_path);
+  g_free (tmp_name);
+
+  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);
+}
+
+static void
+query_info_ready_cb (GObject *obj,
+                     GAsyncResult *res,
+                     gpointer user_data)
+{
+  SushiPdfLoader *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 (g_content_type_is_a (content_type, "application/pdf"))
+    load_pdf (self, self->priv->uri);
+  else
+    load_openoffice (self);
+}
+
+static void
+start_loading_document (SushiPdfLoader *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
 sushi_pdf_loader_set_uri (SushiPdfLoader *self,
                           const gchar *uri)
 {
@@ -64,6 +187,11 @@ sushi_pdf_loader_dispose (GObject *object)
   g_clear_object (&self->priv->document);
   g_free (self->priv->uri);
 
+  if (self->priv->pdf_path) {
+    g_unlink (self->priv->pdf_path);
+    g_free (self->priv->pdf_path);
+  }
+
   G_OBJECT_CLASS (sushi_pdf_loader_parent_class)->dispose (object);
 }
 



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