[gnumeric] Improve text import/export from and to ODF. [#627509]



commit 8b1892df7dbcb9298dc5fabb895db5b16648a28d
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Mon Oct 31 17:26:57 2011 -0600

    Improve text import/export from and to ODF. [#627509]
    
    2011-10-31  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-read.c (oo_cell_content_start): new
    	(oo_add_text_to_cell): new
    	(oo_cell_content_end): we have shared content!
    	(oo_cell_content_special): new
    	(oo_cell_content_space): new
    	(oo_cell_content_symbol): new
    	(opendoc_content_dtd): connect oo_cell_content_symbol and oo_cell_content_start
    	* openoffice-write.c (odf_write_cell): do not write office:string-value for
    	non-expression cells, the element content should be used.

 NEWS                                  |    3 +-
 plugins/openoffice/ChangeLog          |   12 +++
 plugins/openoffice/openoffice-read.c  |  131 +++++++++++++++++++++++++++------
 plugins/openoffice/openoffice-write.c |    8 +-
 4 files changed, 126 insertions(+), 28 deletions(-)
---
diff --git a/NEWS b/NEWS
index 4f0a042..59477f5 100644
--- a/NEWS
+++ b/NEWS
@@ -43,7 +43,8 @@ Andreas:
 	* Fix zoom of text superscripts and subscripts. [#425685]
 	* Fix autofitting of row height in presence of superscripted
 	scientific notation. [#662472]
-	* Improve shape import from ODF. [#663078] 
+	* Improve shape import from ODF. [#663078]
+	* Improve text import/export from and to ODF. [#627509]
 
 Jean:
 	* Make things build against gtk+-3.0.
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 9679a69..540114f 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,5 +1,17 @@
 2011-10-31  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+	* openoffice-read.c (oo_cell_content_start): new
+	(oo_add_text_to_cell): new
+	(oo_cell_content_end): we have shared content!
+	(oo_cell_content_special): new
+	(oo_cell_content_space): new
+	(oo_cell_content_symbol): new
+	(opendoc_content_dtd): connect oo_cell_content_symbol and oo_cell_content_start
+	* openoffice-write.c (odf_write_cell): do not write office:string-value for
+	non-expression cells, the element content should be used.
+
+2011-10-31  Andreas J. Guelzow <aguelzow pyrshep ca>
+
 	* openoffice-read.c (oo_func_map_in): adjust SUMPRODUCT import
 	* openoffice-write.c (odf_expr_func_handler) adjust SUMPRODUCT export
 
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index f5b2a58..a30f110 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -309,10 +309,12 @@ typedef struct {
 	GnmCellPos	 extent_data;
 	GnmCellPos	 extent_style;
 	GnmComment      *cell_comment;
+	GnmCell         *curr_cell;
 
 	int		 col_inc, row_inc;
 	gboolean	 content_is_simple;
 	gboolean	 content_is_error;
+	int              p_content_offset;
 
 	GHashTable	*formats;
 	GHashTable	*controls;
@@ -3105,42 +3107,123 @@ oo_cell_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 }
 
 static void
-oo_cell_content_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+oo_cell_content_start (GsfXMLIn *xin, xmlChar const **attrs)
 {
-	OOParseState *state = (OOParseState *)xin->user_state;
+       OOParseState *state = (OOParseState *)xin->user_state;
+
+       state->p_content_offset = 0;
 
-	if (state->content_is_simple || state->content_is_error) {
+       if (state->content_is_simple) {
 		int max_cols = gnm_sheet_get_max_cols (state->pos.sheet);
 		int max_rows = gnm_sheet_get_max_rows (state->pos.sheet);
-		GnmValue *v;
-		GnmCell *cell;
 
 		if (state->pos.eval.col >= max_cols ||
 		    state->pos.eval.row >= max_rows)
 			return;
 
-		cell = sheet_cell_fetch (state->pos.sheet,
-					 state->pos.eval.col,
-					 state->pos.eval.row);
+		state->curr_cell = sheet_cell_fetch (state->pos.sheet,
+						     state->pos.eval.col,
+						     state->pos.eval.row);
 
-		if (state->content_is_simple)
+		if (VALUE_IS_STRING (state->curr_cell->value)) {
 			/* embedded newlines stored as a series of <p> */
-			if (VALUE_IS_STRING (cell->value))
-				v = value_new_string_str (go_string_new_nocopy (
-					g_strconcat (cell->value->v_str.val->str, "\n",
-						     xin->content->str, NULL)));
-			else
-				v = value_new_string (xin->content->str);
-		else
-			v = value_new_error (NULL, xin->content->str);
+			GnmValue *v;
+			v = value_new_string_str 
+				(go_string_new_nocopy 
+				 (g_strconcat (state->curr_cell->value->v_str.val->str, "\n", NULL)));
+			gnm_cell_assign_value (state->curr_cell, v);
+			oo_update_data_extent (state, 1, 1);
+		}
+       }
+}
 
-		/* Note that we could be looking at the result of an array calculation */
-		gnm_cell_assign_value (cell, v);
-		oo_update_data_extent (state, 1, 1);
+static void 
+oo_add_text_to_cell (OOParseState *state, char const *str)
+{
+	GnmValue *v = NULL;
+
+	if (state->curr_cell == NULL)
+		return;
+
+	if (VALUE_IS_STRING (state->curr_cell->value)) {
+		if (*str != 0)
+			v = value_new_string_str 
+				(go_string_new_nocopy 
+				 (g_strconcat (state->curr_cell->value->v_str.val->str,
+					       str, NULL)));
+	} else
+		v = value_new_string (str);
+	if (v != NULL)
+		gnm_cell_assign_value (state->curr_cell, v);
+}
+
+static void
+oo_cell_content_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	OOParseState *state = (OOParseState *)xin->user_state;
+
+	if (state->content_is_error) {
+		GnmValue *v;
+		if (state->curr_cell == NULL) {
+			int max_cols = gnm_sheet_get_max_cols (state->pos.sheet);
+			int max_rows = gnm_sheet_get_max_rows (state->pos.sheet);
+			
+			if (state->pos.eval.col >= max_cols ||
+			    state->pos.eval.row >= max_rows)
+				return;
+			
+			state->curr_cell = sheet_cell_fetch (state->pos.sheet,
+						 state->pos.eval.col,
+						 state->pos.eval.row);
+		}
+		v = value_new_error (NULL, xin->content->str);
+		gnm_cell_assign_value (state->curr_cell, v);
+	} else if (state->content_is_simple) {
+			oo_add_text_to_cell (state, xin->content->str + state->p_content_offset);
+			state->p_content_offset = strlen (xin->content->str);
+	}
+	oo_update_data_extent (state, 1, 1);
+}
+
+static void
+oo_cell_content_special (GsfXMLIn *xin, int count, char const *sym)
+{
+	OOParseState *state = (OOParseState *)xin->user_state;
+
+	if (state->content_is_simple) {
+		if (xin->content->str != NULL && *xin->content->str != 0) {
+			oo_add_text_to_cell (state, xin->content->str + state->p_content_offset);
+			state->p_content_offset = strlen (xin->content->str);
+		}
+		
+		if (count == 1) 
+			oo_add_text_to_cell (state, sym);
+		else if (count > 0) {
+			gchar *space = g_strnfill (count, *sym);
+			oo_add_text_to_cell (state, space);
+			g_free (space);
+		}
 	}
 }
 
 static void
+oo_cell_content_space (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	int count = 0;
+	
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (oo_attr_int_range (xin, attrs, OO_NS_TEXT, "c", &count, 0, INT_MAX))
+		       ;
+	oo_cell_content_special (xin, count, " ");
+}
+
+static void
+oo_cell_content_symbol (GsfXMLIn *xin, G_GNUC_UNUSED xmlChar const **attrs)
+{
+	oo_cell_content_special (xin, 1, xin->node->user_data.v_str);
+}
+
+static void
 oo_covered_cell_start (GsfXMLIn *xin, xmlChar const **attrs)
 {
 	OOParseState *state = (OOParseState *)xin->user_state;
@@ -9267,11 +9350,11 @@ static GsfXMLInNode const opendoc_content_dtd [] =
 	      GSF_XML_IN_NODE (TABLE_H_ROWS, SOFTPAGEBREAK, OO_NS_TEXT, "soft-page-break", GSF_XML_NO_CONTENT, NULL, NULL), /* 2nd def */
 
 		GSF_XML_IN_NODE (TABLE_ROW, TABLE_CELL, OO_NS_TABLE, "table-cell", GSF_XML_NO_CONTENT, &oo_cell_start, &oo_cell_end),
-		  GSF_XML_IN_NODE (TABLE_CELL, CELL_TEXT, OO_NS_TEXT, "p", GSF_XML_CONTENT, NULL, &oo_cell_content_end),
-		    GSF_XML_IN_NODE (CELL_TEXT, CELL_TEXT_S,    OO_NS_TEXT, "s", GSF_XML_NO_CONTENT, NULL, NULL),
+		  GSF_XML_IN_NODE (TABLE_CELL, CELL_TEXT, OO_NS_TEXT, "p", GSF_XML_CONTENT, &oo_cell_content_start, &oo_cell_content_end),
+		    GSF_XML_IN_NODE (CELL_TEXT, CELL_TEXT_S,    OO_NS_TEXT, "s", GSF_XML_NO_CONTENT, &oo_cell_content_space, NULL),
 		    GSF_XML_IN_NODE (CELL_TEXT, CELL_TEXT_ADDR, OO_NS_TEXT, "a", GSF_XML_SHARED_CONTENT, NULL, NULL),
-		    GSF_XML_IN_NODE (CELL_TEXT, CELL_TEXT_LINE_BREAK,    OO_NS_TEXT, "line-break", GSF_XML_NO_CONTENT, NULL, NULL),
-	            GSF_XML_IN_NODE (CELL_TEXT, CELL_TEXT_TAB, OO_NS_TEXT, "tab", GSF_XML_SHARED_CONTENT, NULL, NULL),
+	            GSF_XML_IN_NODE_FULL (CELL_TEXT, CELL_TEXT_LINE_BREAK, OO_NS_TEXT, "line-break", GSF_XML_NO_CONTENT, FALSE, FALSE, &oo_cell_content_symbol, NULL, .v_str = "\n"),
+	            GSF_XML_IN_NODE_FULL (CELL_TEXT, CELL_TEXT_TAB, OO_NS_TEXT, "tab", GSF_XML_SHARED_CONTENT, FALSE, FALSE, oo_cell_content_symbol, NULL, .v_str = "\t"),
 		    GSF_XML_IN_NODE (CELL_TEXT, CELL_TEXT_SPAN, OO_NS_TEXT, "span", GSF_XML_SHARED_CONTENT, NULL, NULL),
 		      GSF_XML_IN_NODE (CELL_TEXT_SPAN, CELL_TEXT_SPAN, OO_NS_TEXT, "span", GSF_XML_NO_CONTENT, NULL, NULL),/* 2nd def */
 		      GSF_XML_IN_NODE (CELL_TEXT_SPAN, CELL_TEXT_S,    OO_NS_TEXT, "s", GSF_XML_NO_CONTENT, NULL, NULL),/* 2nd def */
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index dd660b2..b4deb76 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -3112,9 +3112,11 @@ odf_write_cell (GnmOOExport *state, GnmCell *cell, GnmRange const *merge_range,
 		case VALUE_STRING:
 			gsf_xml_out_add_cstr_unchecked (state->xml,
 							OFFICE "value-type", "string");
-			gsf_xml_out_add_cstr (state->xml,
-					      OFFICE "string-value",
-					      value_peek_string (cell->value));
+			/*If this is a non-formula cell we show the real formatted content */
+			if (NULL != cell->base.texpr)
+				gsf_xml_out_add_cstr (state->xml,
+						      OFFICE "string-value",
+						      value_peek_string (cell->value));
 			break;
 		case VALUE_CELLRANGE:
 		case VALUE_ARRAY:



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