From 24491f17d24647cff846d41bb5369e8eb6c17ca0 Mon Sep 17 00:00:00 2001
From: Andrea Zagli <azagli@libero.it>
Date: Sun, 18 Mar 2007 14:29:02 +0000
Subject: [PATCH] Continuing RptReport.

git-svn-id: svn+ssh://saetta.homelinux.org/svn/libreptool/trunk@4 3191ed1d-3fce-41bb-ab4a-0cebc0943b59
---
 data/reptool.dtd      |  21 +++----
 src/rptobject.c       |  42 +++++++++++++-
 src/rptobject.h       |  18 +++---
 src/rptobjecttext.c   |  81 ++++++++++++++++++++++----
 src/rptobjecttext.h   |  11 ++--
 src/rptreport.c       | 130 +++++++++++++++++++++++++++++++++++++-----
 src/rptreport.h       |  10 ++--
 tests/Makefile.am     |   5 +-
 tests/rptreport.c     |  37 ++++++++++++
 tests/test_report.rpt |  14 ++---
 10 files changed, 299 insertions(+), 70 deletions(-)
 create mode 100644 tests/rptreport.c

diff --git a/data/reptool.dtd b/data/reptool.dtd
index 5146ec3..bba7fd0 100644
--- a/data/reptool.dtd
+++ b/data/reptool.dtd
@@ -3,12 +3,9 @@
 >
 
 <!ENTITY % object_commons_attrs
-  "name   CDATA #REQUIRED"
->
-
-<!ENTITY % object_position_attrs
-  "x        CDATA #REQUIRED
-   y        CDATA #REQUIRED"
+  "name   CDATA #REQUIRED
+   x      CDATA #REQUIRED
+   y      CDATA #REQUIRED"
 >
 
 <!ENTITY % object_size_attrs
@@ -56,10 +53,9 @@
   vertical-align     (top | center | bottom) #IMPLIED"
 >
 
-<!ELEMENT text (#PCDATA)>
+<!ELEMENT text EMPTY>
 <!ATTLIST text
   %object_commons_attrs;
-  %object_position_attrs;
   %object_size_attrs;
   %object_border_attrs;
   %object_font_attrs;
@@ -76,7 +72,6 @@
 <!ELEMENT line EMPTY>
 <!ATTLIST line
   %object_commons_attrs;
-  %object_poisition_attrs;
   %object_size_attrs;
   %object_stroke_attrs;
 >
@@ -84,7 +79,6 @@
 <!ELEMENT rect EMPTY>
 <!ATTLIST rect
   %object_commons_attrs;
-  %object_poisition_attrs;
   %object_size_attrs;
   %object_stroke_attrs;
   fill-color   CDATA #IMPLIED
@@ -93,7 +87,6 @@
 <!ELEMENT image EMPTY>
 <!ATTLIST image
   %object_commons_attrs;
-  %object_position_attrs;
   %object_size_attrs;
   %object_border_attrs;
   source   CDATA #REQUIRED
@@ -155,9 +148,11 @@
 <!ELEMENT group-footer (%objects;)>
 <!ATTLIST group-footer
   height   CDATA #REQUIRED
+  new-page-after   (y | n) "n"
 >
 
 <!ELEMENT body (%objects;)>
-<!ATTLIST group-footer
-  height   CDATA #REQUIRED
+<!ATTLIST body
+  height           CDATA #REQUIRED
+  new-page-after   (y | n) "n"
 >
diff --git a/src/rptobject.c b/src/rptobject.c
index 8b44b45..2933ce2 100644
--- a/src/rptobject.c
+++ b/src/rptobject.c
@@ -21,7 +21,8 @@
 enum
 {
 	PROP_0,
-	PROP_NAME
+	PROP_NAME,
+	PROP_POSITION
 };
 
 static void rpt_object_class_init (RptObjectClass *klass);
@@ -43,6 +44,7 @@ typedef struct _RptObjectPrivate RptObjectPrivate;
 struct _RptObjectPrivate
 	{
 		gchar *name;
+		RptPoint *position;
 	};
 
 GType
@@ -80,6 +82,8 @@ rpt_object_class_init (RptObjectClass *klass)
 
 	g_type_class_add_private (object_class, sizeof (RptObjectPrivate));
 
+	klass->get_xml = NULL;
+
 	object_class->set_property = rpt_object_set_property;
 	object_class->get_property = rpt_object_get_property;
 
@@ -89,6 +93,11 @@ rpt_object_class_init (RptObjectClass *klass)
 	                                                      "The object's name.",
 	                                                      "",
 	                                                      G_PARAM_READWRITE));
+	g_object_class_install_property (object_class, PROP_POSITION,
+	                                 g_param_spec_pointer ("position",
+	                                                       "Position",
+	                                                       "The object's position.",
+	                                                       G_PARAM_READWRITE));
 }
 
 static void
@@ -99,19 +108,38 @@ rpt_object_init (RptObject *rpt_object)
 /**
  * rpt_object_new:
  * @name: the #RptObject's name.
+ * @position: an #RptPoint that represents the object's position.
  *
  * Returns: the newly created #RptObject object.
  */
 RptObject
-*rpt_object_new (const gchar *name)
+*rpt_object_new (const gchar *name, RptPoint *position)
 {
 	RptObject *rpt_object = RPT_OBJECT (g_object_new (rpt_object_get_type (), NULL));;
 
-	g_object_set (rpt_object, "name", name, NULL);
+	g_object_set (rpt_object,
+	              "name", name,
+	              "poisition", position,
+	              NULL);
 
 	return rpt_object;
 }
 
+void
+rpt_object_get_xml (RptObject *rpt_object, xmlNode *xnode)
+{
+	if (IS_RPT_OBJECT (rpt_object) && RPT_OBJECT_GET_CLASS (rpt_object)->get_xml != NULL)
+		{
+			RptObjectPrivate *priv = RPT_OBJECT_GET_PRIVATE (rpt_object);
+		
+			xmlSetProp (xnode, "name", priv->name);
+			xmlSetProp (xnode, "x", g_strdup_printf ("%f", priv->position->x));
+			xmlSetProp (xnode, "y", g_strdup_printf ("%f", priv->position->y));
+
+			RPT_OBJECT_GET_CLASS (rpt_object)->get_xml (rpt_object, xnode);
+		}
+}
+
 static void
 rpt_object_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
 {
@@ -125,6 +153,10 @@ rpt_object_set_property (GObject *object, guint property_id, const GValue *value
 				priv->name = g_strstrip (g_strdup (g_value_get_string (value)));
 				break;
 
+			case PROP_POSITION:
+				priv->position = g_memdup (g_value_get_pointer (value), sizeof (RptPoint));
+				break;
+
 			default:
 				G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 				break;
@@ -144,6 +176,10 @@ rpt_object_get_property (GObject *object, guint property_id, GValue *value, GPar
 				g_value_set_string (value, priv->name);
 				break;
 
+			case PROP_POSITION:
+				g_value_set_pointer (value, g_memdup (priv->position, sizeof (RptPoint)));
+				break;
+
 			default:
 				G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 				break;
diff --git a/src/rptobject.h b/src/rptobject.h
index ff74300..87f980d 100644
--- a/src/rptobject.h
+++ b/src/rptobject.h
@@ -24,15 +24,17 @@
 #include <glib-object.h>
 #include <libxml/tree.h>
 
+#include "rptcommon.h"
+
 G_BEGIN_DECLS
 
 
-#define TYPE_RPT_OBJECT                 (rpt_object_get_type ())
-#define RPT_OBJECT(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RPT_OBJECT, RptObject))
-#define RPT_OBJECT_COMMON_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RPT_OBJECT, RptObjectClass))
-#define IS_RPT_OBJECT(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RPT_OBJECT))
-#define IS_RPT_OBJECT_COMMON_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RPT_OBJECT))
-#define RPT_OBJECT_COMMON_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RPT_OBJECT, RptObjectClass))
+#define TYPE_RPT_OBJECT               (rpt_object_get_type ())
+#define RPT_OBJECT(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RPT_OBJECT, RptObject))
+#define RPT_OBJECT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RPT_OBJECT, RptObjectClass))
+#define IS_RPT_OBJECT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RPT_OBJECT))
+#define IS_RPT_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RPT_OBJECT))
+#define RPT_OBJECT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RPT_OBJECT, RptObjectClass))
 
 
 typedef struct _RptObject RptObject;
@@ -46,12 +48,14 @@ struct _RptObject
 struct _RptObjectClass
 	{
 		GObjectClass parent_class;
+
+		void (*get_xml) (RptObject *rptobj, xmlNode *xnode);
 	};
 
 GType rpt_object_get_type (void) G_GNUC_CONST;
 
 
-RptObject *rpt_object_new (const gchar *name);
+RptObject *rpt_object_new (const gchar *name, RptPoint *position);
 
 void rpt_object_get_xml (RptObject *rptobj, xmlNode *xnode);
 
diff --git a/src/rptobjecttext.c b/src/rptobjecttext.c
index 0299f28..1c6de9c 100644
--- a/src/rptobjecttext.c
+++ b/src/rptobjecttext.c
@@ -22,8 +22,8 @@
 enum
 {
 	PROP_0,
-	PROP_POSITION,
-	PROP_SIZE
+	PROP_SIZE,
+	PROP_SOURCE
 };
 
 static void rpt_obj_text_class_init (RptObjTextClass *klass);
@@ -44,10 +44,9 @@ static void rpt_obj_text_get_property (GObject *object,
 typedef struct _RptObjTextPrivate RptObjTextPrivate;
 struct _RptObjTextPrivate
 	{
-		RptPoint *position;
 		RptSize *size;
 
-		gchar *text;
+		gchar *source;
 	};
 
 GType
@@ -82,30 +81,54 @@ static void
 rpt_obj_text_class_init (RptObjTextClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	RptObjectClass *rptobject_class = RPT_OBJECT_CLASS (klass);
 
 	g_type_class_add_private (object_class, sizeof (RptObjTextPrivate));
 
 	object_class->set_property = rpt_obj_text_set_property;
 	object_class->get_property = rpt_obj_text_get_property;
+
+	rptobject_class->get_xml = rpt_obj_text_get_xml;
+
+	g_object_class_install_property (object_class, PROP_SIZE,
+	                                 g_param_spec_pointer ("size",
+	                                                       "Size",
+	                                                       "The object's size.",
+	                                                       G_PARAM_READWRITE));
+	g_object_class_install_property (object_class, PROP_SOURCE,
+	                                 g_param_spec_string ("source",
+	                                                      "Source",
+	                                                      "The source.",
+	                                                      "",
+	                                                      G_PARAM_READWRITE));
 }
 
 static void
 rpt_obj_text_init (RptObjText *rpt_obj_text)
 {
+	RptObjTextPrivate *priv = RPT_OBJ_TEXT_GET_PRIVATE (rpt_obj_text);
+
+	priv->size = (RptSize *)g_malloc0 (sizeof (RptSize));
+	priv->size->width = 0.0;
+	priv->size->height = 0.0;
 }
 
 /**
  * rpt_obj_text_new:
  * @name: the #RptObjText's name.
+ * @position:
  *
  * Returns: the newly created #RptObject object.
  */
 RptObject
-*rpt_obj_text_new (const gchar *name)
+*rpt_obj_text_new (const gchar *name, RptPoint *position)
 {
-	RptObject *rpt_obj_text = RPT_OBJ_TEXT (g_object_new (rpt_obj_text_get_type (), NULL));
+	RptObject *rpt_obj_text = RPT_OBJECT (g_object_new (rpt_obj_text_get_type (), NULL));
 
-	g_object_set (rpt_obj_text, "name", name, NULL);
+	g_object_set (G_OBJECT (rpt_obj_text),
+	              "name", name,
+	              "position", position,
+	              NULL);
 
 	return rpt_obj_text;
 }
@@ -123,21 +146,39 @@ RptObject
 	RptObject *rpt_obj_text = NULL;
 
 	name = (gchar *)xmlGetProp (xnode, "name");
-	if (strcmp (g_strstrip (name), "") != 0)
+	if (name != NULL && strcmp (g_strstrip (name), "") != 0)
 		{
+			RptPoint *position;
 			RptObjTextPrivate *priv;
 
-			rpt_obj_text = rpt_obj_text_new (name);
+			rpt_common_get_position (xnode, position);
+
+			rpt_obj_text = rpt_obj_text_new (name, position);
+
+			if (rpt_obj_text != NULL)
+				{
+					priv = RPT_OBJ_TEXT_GET_PRIVATE (rpt_obj_text);
 
-			priv = RPT_OBJ_TEXT_GET_PRIVATE (rpt_obj_text);
+					rpt_common_get_size (xnode, priv->size);
 
-			rpt_common_get_position (xnode, priv->position);
-			rpt_common_get_size (xnode, priv->size);
+					g_object_set (rpt_obj_text, "source", xmlGetProp (xnode, "source"), NULL);
+				}
 		}
 
 	return rpt_obj_text;
 }
 
+void
+rpt_obj_text_get_xml (RptObject *rpt_objtext, xmlNode *xnode)
+{
+	RptObjTextPrivate *priv = RPT_OBJ_TEXT_GET_PRIVATE (rpt_objtext);
+
+	xmlNodeSetName (xnode, "text");
+
+	xmlSetProp (xnode, "width", g_strdup_printf ("%f", priv->size->width));
+	xmlSetProp (xnode, "height", g_strdup_printf ("%f", priv->size->height));
+}
+
 static void
 rpt_obj_text_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
 {
@@ -147,6 +188,14 @@ rpt_obj_text_set_property (GObject *object, guint property_id, const GValue *val
 
 	switch (property_id)
 		{
+			case PROP_SIZE:
+				priv->size = g_memdup (g_value_get_pointer (value), sizeof (RptSize));
+				break;
+
+			case PROP_SOURCE:
+				priv->source = g_strstrip (g_strdup (g_value_get_string (value)));
+				break;
+
 			default:
 				G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 				break;
@@ -162,6 +211,14 @@ rpt_obj_text_get_property (GObject *object, guint property_id, GValue *value, GP
 
 	switch (property_id)
 		{
+			case PROP_SIZE:
+				g_value_set_pointer (value, g_memdup (priv->size, sizeof (RptSize)));
+				break;
+
+			case PROP_SOURCE:
+				g_value_set_string (value, priv->source);
+				break;
+
 			default:
 				G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 				break;
diff --git a/src/rptobjecttext.h b/src/rptobjecttext.h
index 7ba304d..723a990 100644
--- a/src/rptobjecttext.h
+++ b/src/rptobjecttext.h
@@ -31,10 +31,10 @@ G_BEGIN_DECLS
 
 #define TYPE_RPT_OBJ_TEXT                 (rpt_obj_text_get_type ())
 #define RPT_OBJ_TEXT(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RPT_OBJ_TEXT, RptObjText))
-#define RPT_OBJ_TEXT_COMMON_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RPT_OBJ_TEXT, RptObjTextClass))
+#define RPT_OBJ_TEXT_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RPT_OBJ_TEXT, RptObjTextClass))
 #define IS_RPT_OBJ_TEXT(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RPT_OBJ_TEXT))
-#define IS_RPT_OBJ_TEXT_COMMON_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RPT_OBJ_TEXT))
-#define RPT_OBJ_TEXT_COMMON_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RPT_OBJ_TEXT, RptObjTextClass))
+#define IS_RPT_OBJ_TEXT_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RPT_OBJ_TEXT))
+#define RPT_OBJ_TEXT_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RPT_OBJ_TEXT, RptObjTextClass))
 
 
 typedef struct _RptObjText RptObjText;
@@ -53,11 +53,10 @@ struct _RptObjTextClass
 GType rpt_obj_text_get_type (void) G_GNUC_CONST;
 
 
-RptObject *rpt_obj_text_new (const gchar *name);
+RptObject *rpt_obj_text_new (const gchar *name, RptPoint *position);
 RptObject *rpt_obj_text_new_from_xml (xmlNode *xnode);
 
-xmlNode *rpt_obj_text_get_xml (RptObjText *rpt_obj_text);
-
+void rpt_obj_text_get_xml (RptObject *rpt_objtext, xmlNode *xnode);
 
 G_END_DECLS
 
diff --git a/src/rptreport.c b/src/rptreport.c
index 7aa3e36..b806ff3 100644
--- a/src/rptreport.c
+++ b/src/rptreport.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2007 Andrea Zagli <azagli@inwind.it>
+ * Copyright (C) 2007 Andrea Zagli <azagli@inwind.it>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -62,6 +62,14 @@ static void rpt_report_get_property (GObject *object,
 static void rpt_report_xml_parse_body (RptReport *rpt_report, xmlNodeSetPtr xnodeset);
 static RptObject *rpt_report_get_object_from_name (GList *list, const gchar *name);
 
+static xmlNode *rpt_report_rptprint_new_page (RptReport *rptreport,
+                                              xmlNode *xroot);
+static void rpt_report_rptprint_body (RptReport *rptreport,
+                                      xmlNode *xpage);
+static void rpt_report_rptprint_parse_source (RptReport *rptreport,
+                                              RptObject *rptobj,
+                                              xmlNode *xnode);
+
 
 #define RPT_REPORT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_RPT_REPORT, RptReportPrivate))
 
@@ -121,7 +129,12 @@ rpt_report_init (RptReport *rpt_report)
 	RptReportPrivate *priv = RPT_REPORT_GET_PRIVATE (rpt_report);
 
 	priv->page = (Page *)g_malloc0 (sizeof (Page));
+	priv->page->size = (RptSize *)g_malloc0 (sizeof (RptSize));
+	priv->page->size->width = 0.0;
+	priv->page->size->height = 0.0;
+
 	priv->body = (Body *)g_malloc0 (sizeof (Body));
+	priv->body->height = 0.0;
 }
 
 /**
@@ -158,8 +171,17 @@ RptReport
 							xnodeset = xpresult->nodesetval;
 							if (xnodeset->nodeNr == 1)
 								{
-									priv->page->size->width = atol (xmlGetProp (xnodeset->nodeTab[0], (const xmlChar *)"width"));
-									priv->page->size->height = atol (xmlGetProp (xnodeset->nodeTab[0], (const xmlChar *)"height"));
+									gchar *prop;
+									prop = xmlGetProp (xnodeset->nodeTab[0], (const xmlChar *)"width");
+									if (prop != NULL)
+										{
+											priv->page->size->width = strtod (prop, NULL);
+										}
+									prop = xmlGetProp (xnodeset->nodeTab[0], (const xmlChar *)"height");
+									if (prop != NULL)
+										{
+											priv->page->size->height = strtod (prop, NULL);
+										}
 								}
 							else
 								{
@@ -308,26 +330,34 @@ xmlDoc
 
 	RptReportPrivate *priv = RPT_REPORT_GET_PRIVATE (rptreport);
 
+	/* TO DO */
+
 	return xdoc;
 }
 
 /**
- * rpt_report_get_rptprint:
+ * rpt_report_get_xml_rptprint:
  * @rptreport: an #RptReport object.
  *
  */
 xmlDoc
-*rpt_report_get_rptprint (RptReport *rptreport)
+*rpt_report_get_xml_rptprint (RptReport *rptreport)
 {
 	xmlDoc *xdoc;
 	xmlNode *xroot;
+	xmlNode *xnode;
+	gint pages;
 
 	RptReportPrivate *priv = RPT_REPORT_GET_PRIVATE (rptreport);
 
 	xdoc = xmlNewDoc ("1.0");
 	xroot = xmlNewNode (NULL, "reptool_report");
 	xmlDocSetRootElement (xdoc, xroot);
-		
+
+	pages++;
+	xnode = rpt_report_rptprint_new_page (rptreport, xroot);
+	rpt_report_rptprint_body (rptreport, xnode);
+
 	return xdoc;
 }
 
@@ -366,24 +396,35 @@ rpt_report_xml_parse_body (RptReport *rpt_report, xmlNodeSetPtr xnodeset)
 {
 	RptObject *rptobj;
 	gchar *objname;
+	gchar *prop;
 	xmlNode *cur = xnodeset->nodeTab[0];
 
 	RptReportPrivate *priv = RPT_REPORT_GET_PRIVATE (rpt_report);
 
+	prop = xmlGetProp (cur, "height");
+	if (prop != NULL)
+		{
+			priv->body->height = strtod (prop, NULL);
+		}
+
+	cur = cur->children;
 	while (cur != NULL)
 		{
 			if (strcmp (cur->name, "text") == 0)
 				{
 					rptobj = rpt_obj_text_new_from_xml (cur);
-					g_object_get (rptobj, "name", objname, NULL);
-
-					if (rpt_report_get_object_from_name (priv->body->objects, objname) != NULL)
+					if (rptobj != NULL)
 						{
-							priv->body->objects = g_list_append (priv->body->objects, rptobj);
-						}
-					else
-						{
-							/* TO DO */
+							g_object_get (rptobj, "name", objname, NULL);
+
+							if (rpt_report_get_object_from_name (priv->body->objects, objname) == NULL)
+								{
+									priv->body->objects = g_list_append (priv->body->objects, rptobj);
+								}
+							else
+								{
+									/* TO DO */
+								}
 						}
 				}
 			else if (strcmp (cur->name, "line") == 0)
@@ -421,3 +462,64 @@ static RptObject
 
 	return obj;
 }
+
+static xmlNode
+*rpt_report_rptprint_new_page (RptReport *rptreport, xmlNode *xroot)
+{
+	xmlNode *xnode;
+
+	RptReportPrivate *priv = RPT_REPORT_GET_PRIVATE (rptreport);
+
+	xnode = xmlNewNode (NULL, "page");
+	xmlSetProp (xnode, "width", g_strdup_printf ("%f", priv->page->size->width));
+	xmlSetProp (xnode, "height", g_strdup_printf ("%f", priv->page->size->height));
+	xmlAddChild (xroot, xnode);
+
+	return xnode;
+}
+
+static void
+rpt_report_rptprint_body (RptReport *rptreport, xmlNode *xpage)
+{
+	GList *objects;
+	xmlAttrPtr attr;
+	xmlNode *xnode;
+
+	RptObject *rptobj;
+
+	RptReportPrivate *priv = RPT_REPORT_GET_PRIVATE (rptreport);
+
+	objects = g_list_first (priv->body->objects);
+	while (objects != NULL)
+		{
+			xnode = xmlNewNode (NULL, "node");
+
+			rptobj = (RptObject *)objects->data;
+			rpt_object_get_xml (rptobj, xnode);
+			attr = xmlHasProp (xnode, "name");
+			if (attr != NULL)
+				{
+					xmlRemoveProp (attr);
+				}
+
+			if (IS_RPT_OBJ_TEXT (rptobj))
+				{
+					rpt_report_rptprint_parse_source (rptreport, rptobj, xnode);
+				}
+
+			xmlAddChild (xpage, xnode);
+
+			objects = g_list_next (objects);
+		}
+}
+
+static void
+rpt_report_rptprint_parse_source (RptReport *rptreport, RptObject *rptobj, xmlNode *xnode)
+{
+	/* TO DO */
+	gchar *source;
+
+	g_object_get (G_OBJECT (rptobj), "source", &source, NULL);
+
+	xmlNodeSetContent (xnode, source);
+}
diff --git a/src/rptreport.h b/src/rptreport.h
index d0e59c9..f909086 100644
--- a/src/rptreport.h
+++ b/src/rptreport.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2007 Andrea Zagli <azagli@inwind.it>
+ * Copyright (C) 2007 Andrea Zagli <azagli@inwind.it>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -29,10 +29,10 @@ G_BEGIN_DECLS
 
 #define TYPE_RPT_REPORT                 (rpt_report_get_type ())
 #define RPT_REPORT(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RPT_REPORT, RptReport))
-#define RPT_REPORT_COMMON_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RPT_REPORT, RptReportClass))
+#define RPT_REPORT_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RPT_REPORT, RptReportClass))
 #define IS_RPT_REPORT(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RPT_REPORT))
-#define IS_RPT_REPORT_COMMON_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RPT_REPORT))
-#define RPT_REPORT_COMMON_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RPT_REPORT, RptReportClass))
+#define IS_RPT_REPORT_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RPT_REPORT))
+#define RPT_REPORT_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RPT_REPORT, RptReportClass))
 
 
 typedef struct _RptReport RptReport;
@@ -56,7 +56,7 @@ RptReport *rpt_report_new_from_file (const gchar *filename);
 
 xmlDoc *rpt_report_get_xml (RptReport *rptreport);
 
-xmlDoc *rpt_report_get_rptprint (RptReport *rptreport);
+xmlDoc *rpt_report_get_xml_rptprint (RptReport *rptreport);
 
 
 G_END_DECLS
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3f5d414..bd83131 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -5,6 +5,7 @@ AM_CPPFLAGS = $(REPTOOL_CFLAGS) \
 
 libreptool = $(top_builddir)/src/libreptool.la
 
-noinst_PROGRAMS = rptprint
+noinst_PROGRAMS = rptprint \
+                  rptreport
 
-rptprint_LDADD = $(libreptool)
+LDADD = $(libreptool)
diff --git a/tests/rptreport.c b/tests/rptreport.c
new file mode 100644
index 0000000..9302321
--- /dev/null
+++ b/tests/rptreport.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007 Andrea Zagli <azagli@inwind.it>
+ *
+ * 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 Library 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., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
+ */
+
+#include <rptreport.h>
+
+int
+main (int argc, char **argv)
+{
+	RptReport *rptr;
+
+	g_type_init ();
+
+	rptr = rpt_report_new_from_file (argv[1]);
+
+	if (rptr != NULL)
+		{
+			xmlDoc *rptprint = rpt_report_get_xml_rptprint (rptr);
+			xmlSaveFormatFile ("test_report.rptr", rptprint, 2);
+		}
+
+	return 0;
+}
diff --git a/tests/test_report.rpt b/tests/test_report.rpt
index 2feadeb..d4275f0 100644
--- a/tests/test_report.rpt
+++ b/tests/test_report.rpt
@@ -1,12 +1,10 @@
 <?xml version="1.0" ?>
 <reptool>
-  <page width="595" height="842" />
+	<page width="595" height="842" />
 
-  <report>
-    <body height="200">
-      <text name="text1" x="100" y="50" width="500" height="200">
-        the text's content
-      </text>
-    </body>
-  </report>
+	<report>
+		<body height="200">
+			<text name="text1" x="100" y="50" width="500" height="150" source="the text's content" />
+		</body>
+	</report>
 </reptool>
-- 
2.49.0