summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2014-04-23 14:34:54 +0200
committerLuboš Luňák <l.lunak@collabora.com>2014-04-23 14:57:36 +0200
commitcf33af732ed0d3d553bb74636e3b14c55d44c153 (patch)
tree2e83f55d54ab51faa1121f4bc31f71ec9e34fdd3
parent71b4af858ea698f9c3fcffdfc61e3f70a7b10f63 (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.docxbin0 -> 4987 bytes
-rw-r--r--sw/qa/extras/ooxmlimport/ooxmlimport.cxx12
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.cxx79
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.hxx3
-rw-r--r--writerfilter/source/ooxml/factoryimpl_ns.xsl4
-rw-r--r--writerfilter/source/ooxml/model.xml12
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
new file mode 100644
index 000000000000..571fb48eaa9a
--- /dev/null
+++ b/sw/qa/extras/ooxmlimport/data/gridbefore.docx
Binary files differ
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&lt;OOXMLFastContextHandlerTextTableRow*&gt;(pHandler)-&gt;handleGridBefore();</xsl:text>
+ </xsl:when>
<xsl:when test="@action='sendProperty' or @action='handleHyperlink'">
<xsl:text>
dynamic_cast&lt;OOXMLFastContextHandlerStream*&gt;(pHandler)-&gt;</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"/>