diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2014-04-23 14:34:54 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2014-04-23 14:57:36 +0200 |
commit | cf33af732ed0d3d553bb74636e3b14c55d44c153 (patch) | |
tree | 2e83f55d54ab51faa1121f4bc31f71ec9e34fdd3 | |
parent | 71b4af858ea698f9c3fcffdfc61e3f70a7b10f63 (diff) |
handle w:gridBefore by faking cells (fdo#38414)
Docx's w:gridBefore means that there should be this given space in the table
grid before any cells come. But writer requires tables to be rectangular, so
the space needs to be faked using cells without border. So far so good, but
now reality in the form of the retarded overdesigned writerfilter comes.
The internal representation of table data (and not just one actually) is
pretty non-obvious and hard to modify, seems to be modelled just to follow
the parser data the way it comes. Moreover dmapper gets notified of w:gridBefore
only after cells in the row have been already processed. So after futile attempts
to add the fake cells somehow in dmapper I've eventually given up and hacked up
input handling to fake input as if the fake cells were actually there (which
was tedious to find out as well, but at least it's reasonably doable).
Change-Id: I7107e13f28dd3f7093688782f64238167cead76f
-rw-r--r-- | sw/qa/extras/ooxmlimport/data/gridbefore.docx | bin | 0 -> 4987 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 12 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLFastContextHandler.cxx | 79 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLFastContextHandler.hxx | 3 | ||||
-rw-r--r-- | writerfilter/source/ooxml/factoryimpl_ns.xsl | 4 | ||||
-rw-r--r-- | writerfilter/source/ooxml/model.xml | 12 |
6 files changed, 108 insertions, 2 deletions
diff --git a/sw/qa/extras/ooxmlimport/data/gridbefore.docx b/sw/qa/extras/ooxmlimport/data/gridbefore.docx Binary files differnew file mode 100644 index 000000000000..571fb48eaa9a --- /dev/null +++ b/sw/qa/extras/ooxmlimport/data/gridbefore.docx diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 2f1f0cdb5c82..7ca648c6c9b5 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -2065,6 +2065,18 @@ DECLARE_OOXMLIMPORT_TEST(testFdo55381, "fdo55381.docx") CPPUNIT_ASSERT_EQUAL(sal_Int16(4), xCursor->getPage()); } +DECLARE_OOXMLIMPORT_TEST(testGridBefore, "gridbefore.docx") +{ + // w:gridBefore is faked by inserting two cells without border (because Writer can't do non-rectangular tables). + // So check the first cell in the first row is in fact 3rd and that it's more to the right than the second + // cell on the second row. + OUString textA3 = parseDump("/root/page/body/tab/row[1]/cell[1]/txt/text()" ); + OUString leftA3 = parseDump("/root/page/body/tab/row[1]/cell[1]/infos/bounds", "left" ); + OUString leftB2 = parseDump("/root/page/body/tab/row[2]/cell[2]/infos/bounds", "left" ); + CPPUNIT_ASSERT_EQUAL( OUString( "A3" ), textA3 ); + CPPUNIT_ASSERT( leftA3.toInt32() > leftB2.toInt32()); +} + #endif CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx index a8ecda389d99..0506136769cf 100644 --- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx +++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx @@ -1966,6 +1966,85 @@ void OOXMLFastContextHandlerTextTableRow::endRow() endParagraphGroup(); } +// Handle w:gridBefore here by faking necessary input that'll fake cells. I'm apparently +// not insane enough to find out how to add cells in dmapper. +void OOXMLFastContextHandlerTextTableRow::handleGridBefore( OOXMLValue::Pointer_t val ) +{ + int count = val->getInt(); + for( int i = 0; + i < count; + ++i ) + { + endOfParagraph(); + + if (isForwardEvents()) + { + // This whole part is OOXMLFastContextHandlerTextTableCell::endCell() . + OOXMLPropertySet * pProps = new OOXMLPropertySetImpl(); + { + OOXMLValue::Pointer_t pVal + (new OOXMLIntegerValue(mnTableDepth)); + OOXMLProperty::Pointer_t pProp + (new OOXMLPropertyImpl(NS_ooxml::LN_tblDepth, pVal, OOXMLPropertyImpl::SPRM)); + pProps->add(pProp); + } + { + OOXMLValue::Pointer_t pVal + (new OOXMLIntegerValue(1)); + OOXMLProperty::Pointer_t pProp + (new OOXMLPropertyImpl(NS_ooxml::LN_inTbl, pVal, OOXMLPropertyImpl::SPRM)); + pProps->add(pProp); + } + { + OOXMLValue::Pointer_t pVal + (new OOXMLBooleanValue(mnTableDepth > 0)); + OOXMLProperty::Pointer_t pProp + (new OOXMLPropertyImpl(NS_ooxml::LN_tblCell, pVal, OOXMLPropertyImpl::SPRM)); + pProps->add(pProp); + } + + #ifdef DEBUG_PROPERTIES + debug_logger->startElement("handlegridbefore"); + debug_logger->propertySet(OOXMLPropertySet::Pointer_t(pProps->clone()), + IdToString::Pointer_t(new OOXMLIdToString())); + debug_logger->endElement(); + #endif + mpStream->props(writerfilter::Reference<Properties>::Pointer_t(pProps)); + + // fake <w:tcBorders> with no border + OOXMLPropertySet::Pointer_t pCellProps( new OOXMLPropertySetImpl()); + { + OOXMLPropertySet::Pointer_t pBorderProps( new OOXMLPropertySetImpl()); + static Id borders[] = { NS_ooxml::LN_CT_TcBorders_top, NS_ooxml::LN_CT_TcBorders_bottom, + NS_ooxml::LN_CT_TcBorders_start, NS_ooxml::LN_CT_TcBorders_end }; + for( size_t j = 0; j < SAL_N_ELEMENTS( borders ); ++j ) + pBorderProps->add( fakeNoBorder( borders[ j ] )); + OOXMLValue::Pointer_t pValue( new OOXMLPropertySetValue( pBorderProps )); + OOXMLProperty::Pointer_t pProp + (new OOXMLPropertyImpl(NS_ooxml::LN_CT_TcPrBase_tcBorders, pValue, OOXMLPropertyImpl::SPRM)); + pCellProps->add(pProp); + mpParserState->setCellProperties(pCellProps); + } + } + + sendCellProperties(); + endParagraphGroup(); + } +} + +OOXMLProperty::Pointer_t OOXMLFastContextHandlerTextTableRow::fakeNoBorder( Id id ) +{ + OOXMLPropertySet::Pointer_t pProps( new OOXMLPropertySetImpl()); + OOXMLValue::Pointer_t pVal(new OOXMLIntegerValue(0)); + OOXMLProperty::Pointer_t pPropVal + (new OOXMLPropertyImpl(NS_ooxml::LN_CT_Border_val, pVal, OOXMLPropertyImpl::ATTRIBUTE)); + pProps->add(pPropVal); + OOXMLValue::Pointer_t pValue( new OOXMLPropertySetValue( pProps )); + OOXMLProperty::Pointer_t pProp + (new OOXMLPropertyImpl(id, pValue, OOXMLPropertyImpl::SPRM)); + return pProp; +} + /* class OOXMLFastContextHandlerTextTable */ diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx index dd8d99766d9b..799395f4be3e 100644 --- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx +++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx @@ -491,6 +491,9 @@ public: void startRow(); void endRow(); + void handleGridBefore( OOXMLValue::Pointer_t val ); +private: + OOXMLProperty::Pointer_t fakeNoBorder( Id id ); }; class OOXMLFastContextHandlerTextTable : public OOXMLFastContextHandler diff --git a/writerfilter/source/ooxml/factoryimpl_ns.xsl b/writerfilter/source/ooxml/factoryimpl_ns.xsl index 9cb8912dc72a..d932008eb5c8 100644 --- a/writerfilter/source/ooxml/factoryimpl_ns.xsl +++ b/writerfilter/source/ooxml/factoryimpl_ns.xsl @@ -476,6 +476,10 @@ CreateElementMapPointer </xsl:text> <xsl:value-of select="@action"/> <xsl:text>();</xsl:text> </xsl:when> + <xsl:when test="@action='handleGridBefore'"> + <xsl:text> + dynamic_cast<OOXMLFastContextHandlerTextTableRow*>(pHandler)->handleGridBefore();</xsl:text> + </xsl:when> <xsl:when test="@action='sendProperty' or @action='handleHyperlink'"> <xsl:text> dynamic_cast<OOXMLFastContextHandlerStream*>(pHandler)-></xsl:text> diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index 16039bc63898..11ed808c5a8c 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -19563,7 +19563,7 @@ </optional> <optional> <element name="gridBefore"> - <ref name="CT_DecimalNumber"/> + <ref name="CT_TrPrBaseGridBefore"/> </element> </optional> <optional> @@ -19614,6 +19614,11 @@ </choice> </oneOrMore> </define> + <define name="CT_TrPrBaseGridBefore"> + <attribute name="val"> + <ref name="ST_DecimalNumber"/> + </attribute> + </define> <define name="CT_TrPr"> <ref name="CT_TrPrBase"/> <group> @@ -24766,7 +24771,7 @@ <kind name="table"/> <element name="cnfStyle" tokenid="ooxml:CT_TrPrBase_cnfStyle"/> <element name="divId" tokenid="ooxml:CT_TrPrBase_divId"/> - <element name="gridBefore" tokenid="ooxml:CT_TrPrBase_gridBefore"/> +<!-- <element name="gridBefore" tokenid="ooxml:CT_TrPrBase_gridBefore"/> --> <element name="gridAfter" tokenid="ooxml:CT_TrPrBase_gridAfter"/> <element name="wBefore" tokenid="ooxml:CT_TrPrBase_wBefore"/> <element name="wAfter" tokenid="ooxml:CT_TrPrBase_wAfter"/> @@ -24777,6 +24782,9 @@ <element name="jc" tokenid="ooxml:CT_TrPrBase_jc"/> <element name="hidden" tokenid="ooxml:CT_TrPrBase_hidden"/> </resource> + <resource name="CT_TrPrBaseGridBefore" resource="TextTableRow"> + <attribute name="val" tokenid="ooxml:CT_TrPrBase_gridBefore" action="handleGridBefore"/> + </resource> <resource name="CT_TrPr" resource="Properties" tag="table"> <kind name="table"/> <element name="ins" tokenid="ooxml:CT_TrPr_ins"/> |