summaryrefslogtreecommitdiff
path: root/writerfilter
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 /writerfilter
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
Diffstat (limited to 'writerfilter')
-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
4 files changed, 96 insertions, 2 deletions
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"/>