[Xfce4-commits] <tumbler:master> Add odf thumbnailer.

Nick Schermer noreply at xfce.org
Wed Nov 2 23:16:01 CET 2011


Updating branch refs/heads/master
         to 445598f5991ee80939443102e28bac20f01d2ed2 (commit)
       from 3398fcc2ad7c0dd70dc4568c41a0af1bcf3f6ccd (commit)

commit 445598f5991ee80939443102e28bac20f01d2ed2
Author: Nick Schermer <nick at xfce.org>
Date:   Fri Oct 28 21:44:37 2011 +0200

    Add odf thumbnailer.

 acinclude.m4                                       |   24 ++
 configure.ac                                       |    9 +-
 plugins/Makefile.am                                |    1 +
 .../Makefile.am                                    |   32 +-
 .../odf-thumbnailer-plugin.c}                      |   24 +-
 plugins/odf-thumbnailer/odf-thumbnailer-provider.c |  157 ++++++++
 plugins/odf-thumbnailer/odf-thumbnailer-provider.h |   43 +++
 plugins/odf-thumbnailer/odf-thumbnailer.c          |  388 ++++++++++++++++++++
 plugins/odf-thumbnailer/odf-thumbnailer.h          |   44 +++
 9 files changed, 694 insertions(+), 28 deletions(-)

diff --git a/acinclude.m4 b/acinclude.m4
index 2271773..4ea5bcd 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -193,6 +193,30 @@ AC_MSG_RESULT([$ac_tumbler_poppler_thumbnailer])
 
 
 
+dnl TUMBLER_ODF_THUMBNAILER()
+dnl
+dnl Check whether to build and install the ODF thumbnailer plugin.
+dnl
+AC_DEFUN([TUMBLER_ODF_THUMBNAILER],
+[
+AC_ARG_ENABLE([odf-thumbnailer], [AC_HELP_STRING([--disable-odf-thumbnailer], [Don't build the ODF thumbnailer plugin])],
+  [ac_tumbler_odf_thumbnailer=$enableval], [ac_tumbler_odf_thumbnailer=yes])
+if test x"$ac_tumbler_odf_thumbnailer" = x"yes"; then
+  dnl Check for gdk-pixbuf
+  PKG_CHECK_MODULES([GDK_PIXBUF], [gdk-pixbuf-2.0 >= 2.14],
+  [
+    dnl Check for libgsf
+    PKG_CHECK_MODULES([GSF], [libgsf-1 >= 1.14.9], [], [ac_tumbler_odf_thumbnailer=no])
+  ], [ac_tumbler_odf_thumbnailer=no])
+fi
+
+AC_MSG_CHECKING([whether to build the ODF thumbnailer plugin])
+AM_CONDITIONAL([TUMBLER_ODF_THUMBNAILER], [test x"$ac_tumbler_odf_thumbnailer" = x"yes"])
+AC_MSG_RESULT([$ac_tumbler_odf_thumbnailer])
+])
+
+
+
 dnl TUMBLER_XDG_CACHE()
 dnl
 dnl Check whether to build and install the freedesktop.org cache plugin.
diff --git a/configure.ac b/configure.ac
index e83c44e..43646f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -155,6 +155,7 @@ TUMBLER_JPEG_THUMBNAILER()
 TUMBLER_PIXBUF_THUMBNAILER()
 TUMBLER_FFMPEG_THUMBNAILER()
 TUMBLER_GSTREAMER_THUMBNAILER()
+TUMBLER_ODF_THUMBNAILER()
 TUMBLER_POPPLER_THUMBNAILER()
 TUMBLER_XDG_CACHE()
 
@@ -186,6 +187,7 @@ plugins/gst-thumbnailer/Makefile
 plugins/jpeg-thumbnailer/Makefile
 plugins/pixbuf-thumbnailer/Makefile
 plugins/ffmpeg-thumbnailer/Makefile
+plugins/odf-thumbnailer/Makefile
 plugins/poppler-thumbnailer/Makefile
 plugins/xdg-cache/Makefile
 po/Makefile.in
@@ -228,7 +230,12 @@ fi
 if test x"$ac_tumbler_gstreamer_thumbnailer" = x"yes"; then
 echo "  * Video thumbnailer plugin using GStreamer:         yes"
 else
-echo "  * Video thumbnailer plugin using GStreamer        : no"
+echo "  * Video thumbnailer plugin using GStreamer:         no"
+fi
+if test x"$ac_tumbler_odf_thumbnailer" = x"yes"; then
+echo "  * ODF thumbnailer plugin using libgsf:              yes"
+else
+echo "  * ODF thumbnailer plugin using libgsf:              no"
 fi
 if test x"$ac_tumbler_poppler_thumbnailer" = x"yes"; then
 echo "  * PDF/PS thumbnailer plugin using poppler:          yes"
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 7e810d4..d85539f 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -23,5 +23,6 @@ SUBDIRS =								\
 	jpeg-thumbnailer						\
 	pixbuf-thumbnailer						\
 	ffmpeg-thumbnailer						\
+	odf-thumbnailer							\
 	poppler-thumbnailer						\
 	xdg-cache
diff --git a/plugins/jpeg-thumbnailer/Makefile.am b/plugins/odf-thumbnailer/Makefile.am
similarity index 70%
copy from plugins/jpeg-thumbnailer/Makefile.am
copy to plugins/odf-thumbnailer/Makefile.am
index a47ea08..ac74a8a 100644
--- a/plugins/jpeg-thumbnailer/Makefile.am
+++ b/plugins/odf-thumbnailer/Makefile.am
@@ -1,6 +1,6 @@
 # vi:set ts=8 sw=8 noet ai nocindent:
 # -
-# Copyright (c) 2009-2010 Jannis Pohlmann <jannis at xfce.org>
+# Copyright (c) 2011 Nick Schermer <nick at xfce.org>
 # 
 # This program is free software; you can redistribute it and/or 
 # modify it under the terms of the GNU General Public License as
@@ -17,46 +17,46 @@
 # Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 # Boston, MA 02110-1301, USA.
 
-if TUMBLER_JPEG_THUMBNAILER
+if TUMBLER_ODF_THUMBNAILER
 
 tumbler_plugindir = $(libdir)/tumbler-$(TUMBLER_VERSION_API)/plugins
 tumbler_plugin_LTLIBRARIES =						\
-	tumbler-jpeg-thumbnailer.la
+	tumbler-odf-thumbnailer.la
 
-tumbler_jpeg_thumbnailer_la_SOURCES =					\
-	jpeg-thumbnailer-plugin.c					\
-	jpeg-thumbnailer-provider.c					\
-	jpeg-thumbnailer-provider.h					\
-	jpeg-thumbnailer.c						\
-	jpeg-thumbnailer.h
+tumbler_odf_thumbnailer_la_SOURCES =					\
+	odf-thumbnailer-plugin.c					\
+	odf-thumbnailer-provider.c					\
+	odf-thumbnailer-provider.h					\
+	odf-thumbnailer.c						\
+	odf-thumbnailer.h
 
-tumbler_jpeg_thumbnailer_la_CFLAGS =					\
+tumbler_odf_thumbnailer_la_CFLAGS =					\
 	-I$(top_builddir)						\
 	-I$(top_builddir)/plugins					\
 	-I$(top_srcdir)							\
 	-I$(top_srcdir)/plugins						\
-	-DG_LOG_DOMAIN=\"tumbler-jpeg-thumbnailer\"			\
+	-DG_LOG_DOMAIN=\"tumbler-odf-thumbnailer\"			\
 	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"				\
 	$(GDK_PIXBUF_CFLAGS)						\
 	$(GIO_CFLAGS)							\
 	$(GLIB_CFLAGS)							\
-	$(LIBJPEG_CFLAGS)						\
+	$(GSF_CFLAGS)							\
 	$(PLATFORM_CPPFLAGS)
 
-tumbler_jpeg_thumbnailer_la_LDFLAGS =					\
+tumbler_odf_thumbnailer_la_LDFLAGS =					\
 	-avoid-version							\
 	-export-dynamic							\
 	-module								\
 	$(PLATFORM_LDFLAGS)
 
-tumbler_jpeg_thumbnailer_la_LIBADD =					\
+tumbler_odf_thumbnailer_la_LIBADD =					\
 	$(top_builddir)/tumbler/libtumbler-$(TUMBLER_VERSION_API).la	\
 	$(GDK_PIXBUF_LIBS)						\
 	$(GIO_LIBS)							\
 	$(GLIB_LIBS)							\
-	$(LIBJPEG_LIBS)
+	$(GSF_LIBS)
 
-tumbler_jpeg_thumbnailer_la_DEPENDENCIES =				\
+tumbler_odf_thumbnailer_la_DEPENDENCIES =				\
 	$(top_builddir)/tumbler/libtumbler-$(TUMBLER_VERSION_API).la
 
 endif
diff --git a/plugins/jpeg-thumbnailer/jpeg-thumbnailer-plugin.c b/plugins/odf-thumbnailer/odf-thumbnailer-plugin.c
similarity index 74%
copy from plugins/jpeg-thumbnailer/jpeg-thumbnailer-plugin.c
copy to plugins/odf-thumbnailer/odf-thumbnailer-plugin.c
index 9544397..852632e 100644
--- a/plugins/jpeg-thumbnailer/jpeg-thumbnailer-plugin.c
+++ b/plugins/odf-thumbnailer/odf-thumbnailer-plugin.c
@@ -1,6 +1,7 @@
 /* vi:set et ai sw=2 sts=2 ts=2: */
 /*-
  * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick at xfce.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -9,11 +10,11 @@
  *
  * 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 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Library General Public License for more details.
  *
- * You should have received a copy of the GNU Library General 
- * Public License along with this library; if not, write to the 
+ * You should have received a copy of the GNU Library General
+ * Public License along with this library; if not, write to the
  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301, USA.
  */
@@ -28,8 +29,8 @@
 
 #include <tumbler/tumbler.h>
 
-#include <jpeg-thumbnailer/jpeg-thumbnailer-provider.h>
-#include <jpeg-thumbnailer/jpeg-thumbnailer.h>
+#include <odf-thumbnailer/odf-thumbnailer-provider.h>
+#include <odf-thumbnailer/odf-thumbnailer.h>
 
 
 
@@ -50,7 +51,8 @@ tumbler_plugin_initialize (TumblerProviderPlugin *plugin)
   const gchar *mismatch;
 
   /* verify that the tumbler versions are compatible */
-  mismatch = tumbler_check_version (TUMBLER_MAJOR_VERSION, TUMBLER_MINOR_VERSION,
+  mismatch = tumbler_check_version (TUMBLER_MAJOR_VERSION,
+                                    TUMBLER_MINOR_VERSION,
                                     TUMBLER_MICRO_VERSION);
   if (G_UNLIKELY (mismatch != NULL))
     {
@@ -59,15 +61,15 @@ tumbler_plugin_initialize (TumblerProviderPlugin *plugin)
     }
 
 #ifdef DEBUG
-  g_message (_("Initializing the Tumbler JPEG Thumbnailer plugin"));
+  g_message (_("Initializing the Tumbler Odf Thumbnailer plugin"));
 #endif
 
   /* register the types provided by this plugin */
-  jpeg_thumbnailer_register (plugin);
-  jpeg_thumbnailer_provider_register (plugin);
+  odf_thumbnailer_register (plugin);
+  odf_thumbnailer_provider_register (plugin);
 
   /* set up the plugin provider type list */
-  type_list[0] = TYPE_JPEG_THUMBNAILER_PROVIDER;
+  type_list[0] = TYPE_ODF_THUMBNAILER_PROVIDER;
 }
 
 
@@ -76,7 +78,7 @@ void
 tumbler_plugin_shutdown (void)
 {
 #ifdef DEBUG
-  g_message (_("Shutting down the Tumbler JPEG Thumbnailer plugin"));
+  g_message (_("Shutting down the Tumbler Odf Thumbnailer plugin"));
 #endif
 }
 
diff --git a/plugins/odf-thumbnailer/odf-thumbnailer-provider.c b/plugins/odf-thumbnailer/odf-thumbnailer-provider.c
new file mode 100644
index 0000000..d88c437
--- /dev/null
+++ b/plugins/odf-thumbnailer/odf-thumbnailer-provider.c
@@ -0,0 +1,157 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include <tumbler/tumbler.h>
+
+#include <odf-thumbnailer/odf-thumbnailer-provider.h>
+#include <odf-thumbnailer/odf-thumbnailer.h>
+
+
+
+static void   odf_thumbnailer_provider_thumbnailer_provider_init (TumblerThumbnailerProviderIface *iface);
+static GList *odf_thumbnailer_provider_get_thumbnailers          (TumblerThumbnailerProvider      *provider);
+
+
+
+struct _OdfThumbnailerProviderClass
+{
+  GObjectClass __parent__;
+};
+
+struct _OdfThumbnailerProvider
+{
+  GObject __parent__;
+};
+
+
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (OdfThumbnailerProvider,
+                                odf_thumbnailer_provider,
+                                G_TYPE_OBJECT,
+                                0,
+                                TUMBLER_ADD_INTERFACE (TUMBLER_TYPE_THUMBNAILER_PROVIDER,
+                                                       odf_thumbnailer_provider_thumbnailer_provider_init));
+
+
+
+void
+odf_thumbnailer_provider_register (TumblerProviderPlugin *plugin)
+{
+  odf_thumbnailer_provider_register_type (G_TYPE_MODULE (plugin));
+}
+
+
+
+static void
+odf_thumbnailer_provider_class_init (OdfThumbnailerProviderClass *klass)
+{
+}
+
+
+
+static void
+odf_thumbnailer_provider_class_finalize (OdfThumbnailerProviderClass *klass)
+{
+}
+
+
+
+static void
+odf_thumbnailer_provider_thumbnailer_provider_init (TumblerThumbnailerProviderIface *iface)
+{
+  iface->get_thumbnailers = odf_thumbnailer_provider_get_thumbnailers;
+}
+
+
+
+static void
+odf_thumbnailer_provider_init (OdfThumbnailerProvider *provider)
+{
+}
+
+
+
+static GList *
+odf_thumbnailer_provider_get_thumbnailers (TumblerThumbnailerProvider *provider)
+{
+  static const gchar *mime_types[] =
+  {
+    "application/vnd.ms-powerpoint",
+    "application/vnd.openxmlformats-officedocument.presentationml.presentation",
+    "application/vnd.ms-excel",
+    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+    "application/msword",
+    "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+    "application/vnd.oasis.opendocument.presentation-template",
+    "application/vnd.oasis.opendocument.presentation",
+    "application/vnd.oasis.opendocument.spreadsheet-template",
+    "application/vnd.oasis.opendocument.spreadsheet",
+    "application/vnd.oasis.opendocument.text-template",
+    "application/vnd.oasis.opendocument.text-master",
+    "application/vnd.oasis.opendocument.text",
+    "application/vnd.oasis.opendocument.graphics-template",
+    "application/vnd.oasis.opendocument.graphics",
+    "application/vnd.oasis.opendocument.chart",
+    "application/vnd.oasis.opendocument.image",
+    "application/vnd.oasis.opendocument.formula",
+    "application/vnd.sun.xml.impress.template",
+    "application/vnd.sun.xml.impress.template",
+    "application/vnd.sun.xml.impress",
+    "application/vnd.sun.xml.calc.template",
+    "application/vnd.sun.xml.calc",
+    "application/vnd.sun.xml.writer.global",
+    "application/vnd.sun.xml.writer.template",
+    "application/vnd.sun.xml.writer",
+    "application/vnd.sun.xml.draw.template",
+    "application/vnd.sun.xml.draw",
+    "application/vnd.sun.xml.math",
+    NULL
+  };
+  OdfThumbnailer    *thumbnailer;
+  GList             *thumbnailers = NULL;
+  GStrv              uri_schemes;
+
+  /* determine the URI schemes supported by GIO */
+  uri_schemes = tumbler_util_get_supported_uri_schemes ();
+
+  /* create the pixbuf thumbnailer */
+  thumbnailer = g_object_new (TYPE_ODF_THUMBNAILER,
+                              "uri-schemes", uri_schemes,
+                              "mime-types", mime_types,
+                              NULL);
+
+  /* add the thumbnailer to the list */
+  thumbnailers = g_list_append (thumbnailers, thumbnailer);
+
+  /* free URI schemes */
+  g_strfreev (uri_schemes);
+
+  return thumbnailers;
+}
diff --git a/plugins/odf-thumbnailer/odf-thumbnailer-provider.h b/plugins/odf-thumbnailer/odf-thumbnailer-provider.h
new file mode 100644
index 0000000..f945301
--- /dev/null
+++ b/plugins/odf-thumbnailer/odf-thumbnailer-provider.h
@@ -0,0 +1,43 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ODF_THUMBNAILER_PROVIDER_H__
+#define __ODF_THUMBNAILER_PROVIDER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_ODF_THUMBNAILER_PROVIDER            (odf_thumbnailer_provider_get_type ())
+#define ODF_THUMBNAILER_PROVIDER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ODF_THUMBNAILER_PROVIDER, OdfThumbnailerProvider))
+#define ODF_THUMBNAILER_PROVIDER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ODF_THUMBNAILER_PROVIDER, OdfThumbnailerProviderClass))
+#define IS_ODF_THUMBNAILER_PROVIDER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ODF_THUMBNAILER_PROVIDER))
+#define IS_ODF_THUMBNAILER_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ODF_THUMBNAILER_PROVIDER)
+#define ODF_THUMBNAILER_PROVIDER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ODF_THUMBNAILER_PROVIDER, OdfThumbnailerProviderClass))
+
+typedef struct _OdfThumbnailerProviderClass OdfThumbnailerProviderClass;
+typedef struct _OdfThumbnailerProvider      OdfThumbnailerProvider;
+
+GType odf_thumbnailer_provider_get_type (void) G_GNUC_CONST;
+void  odf_thumbnailer_provider_register (TumblerProviderPlugin *plugin);
+
+G_END_DECLS
+
+#endif /* !__ODF_THUMBNAILER_PROVIDER_H__ */
diff --git a/plugins/odf-thumbnailer/odf-thumbnailer.c b/plugins/odf-thumbnailer/odf-thumbnailer.c
new file mode 100644
index 0000000..cb9119c
--- /dev/null
+++ b/plugins/odf-thumbnailer/odf-thumbnailer.c
@@ -0,0 +1,388 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2011 Nick Schermer <nick at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Parts are based on the gsf-office-thumbnailer in libgsf, which is
+ * written by Federico Mena-Quintero <federico at novell.com>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include <gsf/gsf.h>
+#include <gsf/gsf-input-memory.h>
+#include <gsf/gsf-input-gio.h>
+#include <gsf/gsf-infile.h>
+#include <gsf/gsf-infile-msole.h>
+#include <gsf/gsf-infile-zip.h>
+#include <gsf/gsf-open-pkg-utils.h>
+#include <gsf/gsf-clip-data.h>
+#include <gsf/gsf-doc-meta-data.h>
+#include <gsf/gsf-meta-names.h>
+#include <gsf/gsf-msole-utils.h>
+
+#include <tumbler/tumbler.h>
+
+#include <odf-thumbnailer/odf-thumbnailer.h>
+
+
+#define OPEN_XML_SCHEMA "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail"
+
+
+
+static void odf_thumbnailer_finalize (GObject                    *object);
+static void odf_thumbnailer_create   (TumblerAbstractThumbnailer *thumbnailer,
+                                       GCancellable               *cancellable,
+                                       TumblerFileInfo            *info);
+
+
+
+struct _OdfThumbnailerClass
+{
+  TumblerAbstractThumbnailerClass __parent__;
+};
+
+struct _OdfThumbnailer
+{
+  TumblerAbstractThumbnailer __parent__;
+};
+
+
+
+G_DEFINE_DYNAMIC_TYPE (OdfThumbnailer,
+                       odf_thumbnailer,
+                       TUMBLER_TYPE_ABSTRACT_THUMBNAILER);
+
+
+
+void
+odf_thumbnailer_register (TumblerProviderPlugin *plugin)
+{
+  odf_thumbnailer_register_type (G_TYPE_MODULE (plugin));
+}
+
+
+
+static void
+odf_thumbnailer_class_init (OdfThumbnailerClass *klass)
+{
+  TumblerAbstractThumbnailerClass *abstractthumbnailer_class;
+  GObjectClass                    *gobject_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = odf_thumbnailer_finalize;
+
+  abstractthumbnailer_class = TUMBLER_ABSTRACT_THUMBNAILER_CLASS (klass);
+  abstractthumbnailer_class->create = odf_thumbnailer_create;
+}
+
+
+
+static void
+odf_thumbnailer_class_finalize (OdfThumbnailerClass *klass)
+{
+}
+
+
+
+static void
+odf_thumbnailer_init (OdfThumbnailer *thumbnailer)
+{
+
+}
+
+
+static void
+odf_thumbnailer_finalize (GObject *object)
+{
+  //OdfThumbnailer *thumbnailer = ODF_THUMBNAILER (object);
+
+  (*G_OBJECT_CLASS (odf_thumbnailer_parent_class)->finalize) (object);
+}
+
+
+
+static GdkPixbuf *
+odf_thumbnailer_create_from_data (const guchar *data,
+                                  gsize         bytes)
+{
+  GdkPixbufLoader *loader;
+  GdkPixbuf       *pixbuf = NULL;
+  GError          *error = NULL;
+
+  loader = gdk_pixbuf_loader_new ();
+  if (gdk_pixbuf_loader_write (loader, data, bytes, &error))
+    {
+      if (gdk_pixbuf_loader_close (loader, &error))
+        {
+          pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+          if (pixbuf != NULL)
+            g_object_ref (G_OBJECT (pixbuf));
+        }
+    }
+  else
+    {
+      gdk_pixbuf_loader_close (loader, NULL);
+    }
+  g_object_unref (G_OBJECT (loader));
+
+  return pixbuf;
+}
+
+
+
+static GdkPixbuf *
+odf_thumbnailer_create_zip (GsfInfile *infile)
+{
+  GsfInput     *thumbnail;
+  gsize         bytes;
+  const guint8 *data;
+  GdkPixbuf    *pixbuf = NULL;
+
+  g_return_val_if_fail (GSF_IS_INFILE_ZIP (infile), NULL);
+
+  /* openoffice and libreoffice thumbnail */
+  thumbnail = gsf_infile_child_by_vname (infile, "Thumbnails", "thumbnail.png", NULL);
+  if (thumbnail == NULL)
+    {
+      /* microsoft office-x thumbnails */
+      thumbnail = gsf_open_pkg_open_rel_by_type (GSF_INPUT (infile), OPEN_XML_SCHEMA, NULL);
+      if (thumbnail == NULL)
+        return NULL;
+    }
+
+  /* read data and generate a pixbuf */
+  bytes = gsf_input_remaining (thumbnail);
+  data = gsf_input_read (thumbnail, bytes, NULL);
+  if (data != NULL)
+    pixbuf = odf_thumbnailer_create_from_data (data, bytes);
+
+  g_object_unref (G_OBJECT (thumbnail));
+
+  return pixbuf;
+}
+
+
+
+static GdkPixbuf *
+odf_thumbnailer_create_msole (GsfInfile *infile)
+{
+  GsfInput       *summary;
+  GsfDocMetaData *meta_data;
+  GError         *error;
+  GsfDocProp     *thumbnail;
+  GdkPixbuf      *pixbuf = NULL;
+  GValue const   *thumb_value;
+  GsfClipData    *clip_data;
+  gsize           bytes;
+  const guchar   *data;
+
+  g_return_val_if_fail (GSF_IS_INFILE_MSOLE (infile), NULL);
+
+  /* try to find summary information stream */
+  summary = gsf_infile_child_by_name (infile, "\05SummaryInformation");
+  if (summary == NULL)
+    return NULL;
+
+  /* read meta data from stream */
+  meta_data = gsf_doc_meta_data_new ();
+  error = gsf_msole_metadata_read (summary, meta_data);
+  g_object_unref (G_OBJECT (summary));
+  if (error != NULL)
+    {
+      g_error_free (error);
+      return NULL;
+    }
+
+  /* try to extract thumbnail */
+  thumbnail = gsf_doc_meta_data_lookup (meta_data, GSF_META_NAME_THUMBNAIL);
+  if (thumbnail != NULL)
+    {
+      thumb_value = gsf_doc_prop_get_val (thumbnail);
+      if (thumb_value != NULL)
+        {
+          clip_data = g_value_get_object (thumb_value);
+
+          /* only create thumbs from data we can handle */
+          if (gsf_clip_data_get_format (clip_data) != GSF_CLIP_FORMAT_WINDOWS_CLIPBOARD
+              && gsf_clip_data_get_windows_clipboard_format (clip_data, NULL) != GSF_CLIP_FORMAT_WINDOWS_ERROR)
+            {
+              data = gsf_clip_data_peek_real_data (GSF_CLIP_DATA (clip_data), &bytes, NULL);
+              if (data != NULL)
+                pixbuf = odf_thumbnailer_create_from_data (data, bytes);
+            }
+        }
+    }
+
+  g_object_unref (G_OBJECT (meta_data));
+
+  return pixbuf;
+}
+
+
+
+static GdkPixbuf*
+scale_pixbuf (GdkPixbuf *source,
+              gint       dest_width,
+              gint       dest_height)
+{
+  gdouble wratio;
+  gdouble hratio;
+  gint    source_width;
+  gint    source_height;
+
+  /* determine source pixbuf dimensions */
+  source_width  = gdk_pixbuf_get_width  (source);
+  source_height = gdk_pixbuf_get_height (source);
+
+  /* don't do anything if there is no need to resize */
+  if (source_width <= dest_width && source_height <= dest_height)
+    return g_object_ref (source);
+
+  /* determine which axis needs to be scaled down more */
+  wratio = (gdouble) source_width  / (gdouble) dest_width;
+  hratio = (gdouble) source_height / (gdouble) dest_height;
+
+  /* adjust the other axis */
+  if (hratio > wratio)
+    dest_width = rint (source_width / hratio);
+  else
+    dest_height = rint (source_height / wratio);
+
+  /* scale the pixbuf down to the desired size */
+  return gdk_pixbuf_scale_simple (source, MAX (dest_width, 1),
+                                  MAX (dest_height, 1),
+                                  GDK_INTERP_BILINEAR);
+}
+
+
+
+static void
+odf_thumbnailer_create (TumblerAbstractThumbnailer *thumbnailer,
+                        GCancellable               *cancellable,
+                        TumblerFileInfo            *info)
+{
+  GsfInput               *input = NULL;
+  TumblerThumbnail       *thumbnail;
+  const gchar            *uri;
+  GFile                  *file;
+  GError                 *error = NULL;
+  gchar                  *path;
+  GsfInfile              *infile;
+  GdkPixbuf              *pixbuf = NULL;
+  TumblerThumbnailFlavor *flavor;
+  gint                    width, height;
+  TumblerImageData        data;
+  GdkPixbuf              *scaled;
+
+  g_return_if_fail (IS_ODF_THUMBNAILER (thumbnailer));
+  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+  g_return_if_fail (TUMBLER_IS_FILE_INFO (info));
+
+  /* do nothing if cancelled */
+  if (g_cancellable_is_cancelled (cancellable))
+    return;
+
+  uri = tumbler_file_info_get_uri (info);
+  file = g_file_new_for_uri (uri);
+
+  if (g_file_is_native (file))
+    {
+      /* try to mmap the file */
+      path = g_file_get_path (file);
+      input = gsf_input_mmap_new (path, NULL);
+      g_free (path);
+    }
+
+  if (input == NULL)
+    {
+      /* fall-back to normal file reading */
+      input = gsf_input_gio_new (file, &error);
+      if (G_UNLIKELY (input == NULL))
+        {
+          g_signal_emit_by_name (thumbnailer, "error", uri, error->code, error->message);
+          g_error_free (error);
+          return;
+        }
+    }
+
+  /* extract the file */
+  input = gsf_input_uncompress (input);
+
+  /* try to detect file format and run thumbnail extractor */
+  infile = gsf_infile_zip_new (input, NULL);
+  if (infile != NULL)
+    {
+      pixbuf = odf_thumbnailer_create_zip (infile);
+      g_object_unref (G_OBJECT (infile));
+    }
+  else
+    {
+      infile = gsf_infile_msole_new (input, NULL);
+      if (infile != NULL)
+        {
+          pixbuf = odf_thumbnailer_create_msole (infile);
+          g_object_unref (G_OBJECT (infile));
+        }
+    }
+
+  if (pixbuf != NULL)
+    {
+      /* get thumbnail size */
+      thumbnail = tumbler_file_info_get_thumbnail (info);
+      flavor = tumbler_thumbnail_get_flavor (thumbnail);
+      tumbler_thumbnail_flavor_get_size (flavor, &width, &height);
+      g_object_unref (G_OBJECT (flavor));
+      g_object_unref (G_OBJECT (thumbnail));
+
+      /* scale thumb if required */
+      scaled = scale_pixbuf (pixbuf, width, height);
+      g_object_unref (G_OBJECT (pixbuf));
+
+      data.data = gdk_pixbuf_get_pixels (scaled);
+      data.has_alpha = gdk_pixbuf_get_has_alpha (scaled);
+      data.bits_per_sample = gdk_pixbuf_get_bits_per_sample (scaled);
+      data.width = gdk_pixbuf_get_width (scaled);
+      data.height = gdk_pixbuf_get_height (scaled);
+      data.rowstride = gdk_pixbuf_get_rowstride (scaled);
+      data.colorspace = (TumblerColorspace) gdk_pixbuf_get_colorspace (scaled);
+
+      tumbler_thumbnail_save_image_data (thumbnail, &data,
+                                         tumbler_file_info_get_mtime (info),
+                                         NULL, &error);
+
+      g_object_unref (G_OBJECT (scaled));
+    }
+
+  if (error != NULL)
+    {
+      g_signal_emit_by_name (thumbnailer, "error", uri, error->code, error->message);
+      g_error_free (error);
+    }
+
+  g_object_unref (G_OBJECT (input));
+}
diff --git a/plugins/odf-thumbnailer/odf-thumbnailer.h b/plugins/odf-thumbnailer/odf-thumbnailer.h
new file mode 100644
index 0000000..1cbbac3
--- /dev/null
+++ b/plugins/odf-thumbnailer/odf-thumbnailer.h
@@ -0,0 +1,44 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ODF_THUMBNAILER_H__
+#define __ODF_THUMBNAILER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS;
+
+#define TYPE_ODF_THUMBNAILER            (odf_thumbnailer_get_type ())
+#define ODF_THUMBNAILER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ODF_THUMBNAILER, OdfThumbnailer))
+#define ODF_THUMBNAILER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ODF_THUMBNAILER, OdfThumbnailerClass))
+#define IS_ODF_THUMBNAILER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ODF_THUMBNAILER))
+#define IS_ODF_THUMBNAILER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ODF_THUMBNAILER)
+#define ODF_THUMBNAILER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ODF_THUMBNAILER, OdfThumbnailerClass))
+
+typedef struct _OdfThumbnailerClass   OdfThumbnailerClass;
+typedef struct _OdfThumbnailer        OdfThumbnailer;
+
+GType odf_thumbnailer_get_type (void) G_GNUC_CONST;
+void  odf_thumbnailer_register (TumblerProviderPlugin *plugin);
+
+G_END_DECLS;
+
+#endif /* !__ODF_THUMBNAILER_H__ */


More information about the Xfce4-commits mailing list