[libgsf] GsfODFOut: new class.



commit 6ba00f474745682f9d9a1b3e996bc0a73295d572
Author: Morten Welinder <terra gnome org>
Date:   Wed Mar 21 16:30:41 2012 -0400

    GsfODFOut: new class.

 ChangeLog               |   11 ++++
 NEWS                    |    1 +
 gsf/gsf-libxml.c        |   46 ++++++++++++---
 gsf/gsf-opendoc-utils.c |  144 ++++++++++++++++++++++++++++++++++++++++++----
 gsf/gsf-opendoc-utils.h |   37 +++++++++++-
 po/POTFILES.in          |    2 +
 6 files changed, 214 insertions(+), 27 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 8e404f8..13116e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2012-03-21  Morten Welinder  <terra gnome org>
 
+	* gsf/gsf-opendoc-utils.h (GsfODFOut): New object class.
+
+	* gsf/gsf-opendoc-utils.c (gsf_opendoc_metadata_write): change
+	output argument type to "gpointer" so we can take either GsfXMLOut
+	or GsfODFOut.  Get the odf version from the output if that happens
+	to be a GsfODFOut.
+
+	* gsf/gsf-libxml.c (gsf_xml_out_class_init): Install new property
+	"sink".
+	(gsf_xml_out_new): Just call g_object_new.
+
 	* gsf/gsf-libxml.h (GsfXMLOut): Make this just public enough that
 	we can derive from it.
 
diff --git a/NEWS b/NEWS
index 74f2c27..76f1d37 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ Jean Brefort:
 
 Morten:
 	* Fix time stamp drift problem.  [Part of #671860]
+	* New GsfODFOut class.
 
 --------------------------------------------------------------------------
 libgsf 1.14.22
diff --git a/gsf/gsf-libxml.c b/gsf/gsf-libxml.c
index 8a8dede..31bf805 100644
--- a/gsf/gsf-libxml.c
+++ b/gsf/gsf-libxml.c
@@ -27,6 +27,7 @@
 #include <gsf/gsf-impl-utils.h>
 #include <gsf/gsf-utils.h>
 #include <gsf/gsf-timestamp.h>
+#include <glib/gi18n-lib.h>
 
 #include <math.h>
 #include <string.h>
@@ -1301,7 +1302,8 @@ gsf_xml_in_namecmp (GsfXMLIn const *xin, char const *str,
 
 enum {
 	PROP_0,
-	PROP_PRETTY_PRINT
+	PROP_PRETTY_PRINT,
+	PROP_SINK
 };
 
 typedef enum {
@@ -1320,6 +1322,13 @@ typedef struct _GsfXMLOutPrivate {
 } GsfXMLOutPrivate;
 
 static void
+gsf_xml_out_set_output (GsfXMLOut *xout, GsfOutput *output)
+{
+	if (gsf_output_wrap (G_OBJECT (xout), output))
+		xout->output = output;
+}
+
+static void
 gsf_xml_out_set_property (GObject      *object,
 			  guint         property_id,
 			  GValue const *value,
@@ -1332,6 +1341,9 @@ gsf_xml_out_set_property (GObject      *object,
 	case PROP_PRETTY_PRINT:
 		priv->pretty_print = g_value_get_boolean (value);
 		break;
+	case PROP_SINK:
+		gsf_xml_out_set_output (xout, g_value_get_object (value));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 		break;
@@ -1351,6 +1363,9 @@ gsf_xml_out_get_property (GObject     *object,
 	case PROP_PRETTY_PRINT:
 		g_value_set_boolean (value, priv->pretty_print);
 		break;
+	case PROP_SINK:
+		g_value_set_object (value, xout->output);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 		break;
@@ -1390,11 +1405,23 @@ gsf_xml_out_class_init (GObjectClass *gobject_class)
 	gobject_class->get_property = gsf_xml_out_get_property;
 	gobject_class->set_property = gsf_xml_out_set_property;
 
-	g_object_class_install_property (gobject_class, PROP_PRETTY_PRINT,
-		 g_param_spec_boolean ("pretty-print", "Pretty print",
-			"Should the output auto-indent elements to make reading easier",
+	g_object_class_install_property
+		(gobject_class, PROP_PRETTY_PRINT,
+		 g_param_spec_boolean ("pretty-print",
+				       _("Pretty print"),
+				       _("Should the output auto-indent elements to make reading easier?"),
 			TRUE, GSF_PARAM_STATIC | G_PARAM_READWRITE));
 
+	g_object_class_install_property
+		(gobject_class, PROP_SINK,
+		 g_param_spec_object ("sink",
+				      _("Sink"),
+				      _("The destination for writes"),
+				      GSF_OUTPUT_TYPE,
+				      GSF_PARAM_STATIC |
+				      G_PARAM_READWRITE |
+				      G_PARAM_CONSTRUCT_ONLY));
+
 	g_type_class_add_private (gobject_class, sizeof (GsfXMLOutPrivate));
 }
 
@@ -1413,12 +1440,11 @@ GSF_CLASS (GsfXMLOut, gsf_xml_out,
 GsfXMLOut *
 gsf_xml_out_new (GsfOutput *output)
 {
-	GsfXMLOut *xout = g_object_new (GSF_XML_OUT_TYPE, NULL);
-	if (G_UNLIKELY (NULL == xout)) return NULL;
-	if (!gsf_output_wrap (G_OBJECT (xout), output))
-		return NULL;
-	xout->output = output;
-	return xout;
+	g_return_val_if_fail (GSF_IS_OUTPUT (output), NULL);
+
+	return g_object_new (GSF_XML_OUT_TYPE,
+			     "sink", output,
+			     NULL);
 }
 
 /**
diff --git a/gsf/gsf-opendoc-utils.c b/gsf/gsf-opendoc-utils.c
index 3602d3c..2df4daa 100644
--- a/gsf/gsf-opendoc-utils.c
+++ b/gsf/gsf-opendoc-utils.c
@@ -29,7 +29,9 @@
 #include <gsf/gsf-doc-meta-data.h>
 #include <gsf/gsf-timestamp.h>
 #include <gsf/gsf-docprop-vector.h>
+#include <gsf/gsf-impl-utils.h>
 #include <string.h>
+#include <glib/gi18n-lib.h>
 
 
 #define OFFICE	 "office:"
@@ -560,29 +562,145 @@ meta_write_props (char const *prop_name, GsfDocProp *prop, GsfXMLOut *output)
 }
 
 gboolean
-gsf_opendoc_metadata_write (GsfXMLOut *output, GsfDocMetaData const *md)
+gsf_opendoc_metadata_write (gpointer output, GsfDocMetaData const *md)
 {
+	char *ver_str;
+	GsfXMLOut *xout;
+	GsfODFOut *oout;
+
 	if (output == NULL)
 		return FALSE;
 
-	gsf_xml_out_start_element (output, OFFICE "document-meta");
-	gsf_xml_out_add_cstr_unchecked (output, "xmlns:office",
+	/* For compatibility we take a GsfXMLOut argument.  It really
+	   ought to be a GsfODFOut.  */
+	xout = GSF_XML_OUT (output);
+	oout = GSF_IS_ODF_OUT (xout) ? GSF_ODF_OUT (xout) : NULL;
+
+	ver_str = oout
+		? gsf_odf_out_get_version_string (oout)
+		: g_strdup (get_gsf_odf_version_string ());
+
+	gsf_xml_out_start_element (xout, OFFICE "document-meta");
+	gsf_xml_out_add_cstr_unchecked (xout, "xmlns:office",
 		"urn:oasis:names:tc:opendocument:xmlns:office:1.0");
-	gsf_xml_out_add_cstr_unchecked (output, "xmlns:xlink",
+	gsf_xml_out_add_cstr_unchecked (xout, "xmlns:xlink",
 		"http://www.w3.org/1999/xlink";);
-	gsf_xml_out_add_cstr_unchecked (output, "xmlns:dc",
+	gsf_xml_out_add_cstr_unchecked (xout, "xmlns:dc",
 		"http://purl.org/dc/elements/1.1/";);
-	gsf_xml_out_add_cstr_unchecked (output, "xmlns:meta",
+	gsf_xml_out_add_cstr_unchecked (xout, "xmlns:meta",
 		"urn:oasis:names:tc:opendocument:xmlns:meta:1.0");
-	gsf_xml_out_add_cstr_unchecked (output, "xmlns:ooo",
+	gsf_xml_out_add_cstr_unchecked (xout, "xmlns:ooo",
 		"http://openoffice.org/2004/office";);
-	gsf_xml_out_add_cstr_unchecked (output, "office:version",
-					get_gsf_odf_version_string ());
-	gsf_xml_out_start_element (output, OFFICE "meta");
-	gsf_doc_meta_data_foreach (md, (GHFunc) meta_write_props, output);
-	gsf_xml_out_end_element (output); /* </office:meta> */
+	gsf_xml_out_add_cstr_unchecked (xout, "office:version", ver_str);
+	gsf_xml_out_start_element (xout, OFFICE "meta");
+	gsf_doc_meta_data_foreach (md, (GHFunc) meta_write_props, xout);
+	gsf_xml_out_end_element (xout); /* </office:meta> */
 
-	gsf_xml_out_end_element (output); /* </office:document-meta> */
+	gsf_xml_out_end_element (xout); /* </office:document-meta> */
+
+	g_free (ver_str);
 
 	return TRUE;
 }
+
+/****************************************************************************/
+
+typedef struct _GsfODFOutPrivate {
+	int odf_version;
+} GsfODFOutPrivate;
+
+enum {
+	PROP_0,
+	PROP_ODF_VERSION
+};
+
+static GObjectClass *parent_class;
+
+static void
+gsf_odf_out_set_property (GObject      *object,
+			  guint         property_id,
+			  GValue const *value,
+			  GParamSpec   *pspec)
+{
+	GsfODFOut *xout = (GsfODFOut *)object;
+	GsfODFOutPrivate *priv = xout->priv;
+
+	switch (property_id) {
+	case PROP_ODF_VERSION:
+		priv->odf_version = g_value_get_int (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+static void
+gsf_odf_out_get_property (GObject     *object,
+			  guint        property_id,
+			  GValue      *value,
+			  GParamSpec  *pspec)
+{
+	GsfODFOut const *xout = (GsfODFOut const *)object;
+	GsfODFOutPrivate const *priv = xout->priv;
+
+	switch (property_id) {
+	case PROP_ODF_VERSION:
+		g_value_set_int (value, priv->odf_version);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+static void
+gsf_odf_out_init (GObject *obj)
+{
+	GsfODFOut *xout = GSF_ODF_OUT (obj);
+	GsfODFOutPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE
+		(obj, GSF_ODF_OUT_TYPE, GsfODFOutPrivate);
+	xout->priv = priv;
+	priv->odf_version = 100;
+}
+
+static void
+gsf_odf_out_class_init (GObjectClass *gobject_class)
+{
+	parent_class = g_type_class_peek_parent (gobject_class);
+
+	gobject_class->get_property = gsf_odf_out_get_property;
+	gobject_class->set_property = gsf_odf_out_set_property;
+
+	g_object_class_install_property
+		(gobject_class, PROP_ODF_VERSION,
+		 g_param_spec_int ("odf-version",
+				   _("ODF version"),
+				   _("The ODF version this object is targeting as an integer like 100"),
+				   0,
+				   G_MAXINT,
+				   100,
+				   GSF_PARAM_STATIC |
+				   G_PARAM_READWRITE | 
+				   G_PARAM_CONSTRUCT_ONLY));
+
+	g_type_class_add_private (gobject_class, sizeof (GsfODFOutPrivate));
+}
+
+GSF_CLASS (GsfODFOut, gsf_odf_out,
+	   gsf_odf_out_class_init, gsf_odf_out_init,
+	   GSF_XML_OUT_TYPE)
+
+int
+gsf_odf_out_get_version (GsfODFOut *oout)
+{
+	g_return_val_if_fail (GSF_IS_ODF_OUT (oout), 100);
+	return oout->priv->odf_version;
+}
+
+char *
+gsf_odf_out_get_version_string (GsfODFOut *oout)
+{
+	int ver = gsf_odf_out_get_version (oout);
+	return g_strdup_printf ("%d.%d", ver / 100, ver % 100);
+}
diff --git a/gsf/gsf-opendoc-utils.h b/gsf/gsf-opendoc-utils.h
index e320f0c..8c3d50b 100644
--- a/gsf/gsf-opendoc-utils.h
+++ b/gsf/gsf-opendoc-utils.h
@@ -1,4 +1,3 @@
-/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * gsf-opendoc-utils.h:  Handle the application neutral portions of OpenDocument
  *
@@ -31,6 +30,36 @@
 
 G_BEGIN_DECLS
 
+/****************************************************************************/
+
+typedef struct {
+	GsfXMLOutClass base;
+
+	/*< private >*/
+	/* Padding for future expansion */
+	void (*_gsf_reserved1) (void);
+	void (*_gsf_reserved2) (void);
+	void (*_gsf_reserved3) (void);
+	void (*_gsf_reserved4) (void);
+} GsfODFOutClass;
+
+typedef struct _GsfODFOut {
+	GsfXMLOut base;
+	/*< private >*/
+	struct _GsfODFOutPrivate *priv;
+} GsfODFOut;
+
+#define GSF_ODF_OUT_TYPE	(gsf_odf_out_get_type ())
+#define GSF_ODF_OUT(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GSF_ODF_OUT_TYPE, GsfODFOut))
+#define GSF_IS_ODF_OUT(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), GSF_ODF_OUT_TYPE))
+
+GType gsf_odf_out_get_type      (void) G_GNUC_CONST;
+
+int gsf_odf_out_get_version     (GsfODFOut *oout);
+char *gsf_odf_out_get_version_string (GsfODFOut *oout);
+
+/****************************************************************************/
+
 enum {
 	OO_NS_OFFICE,
 	OO_NS_STYLE,
@@ -105,9 +134,9 @@ G_MODULE_EXPORT short get_gsf_odf_version (void);
 extern GsfXMLInNS gsf_ooo_ns[]; /* use get_gsf_ooo_ns instead */
 
 /* For 1.15.x s/opendoc/odf/ and s/ooo/odf/ */
-GError	*gsf_opendoc_metadata_read    (GsfInput *input,  GsfDocMetaData *md);
-void	 gsf_opendoc_metadata_subtree (GsfXMLIn *doc,    GsfDocMetaData *md);
-gboolean gsf_opendoc_metadata_write   (GsfXMLOut *output, GsfDocMetaData const *md);
+GError	*gsf_opendoc_metadata_read    (GsfInput *input, GsfDocMetaData *md);
+void	 gsf_opendoc_metadata_subtree (GsfXMLIn *doc,   GsfDocMetaData *md);
+gboolean gsf_opendoc_metadata_write   (gpointer output, GsfDocMetaData const *md);
 
 G_END_DECLS
 
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 539262c..1c11e68 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,6 +4,8 @@
 gsf/gsf-blob.c
 gsf/gsf-clip-data.c
 gsf/gsf-input-http.c
+gsf/gsf-libxml.c
 gsf/gsf-msole-utils.c
 gsf/gsf-open-pkg-utils.c
+gsf/gsf-opendoc-utils.c
 tools/gsf.c



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