[Libreoffice-commits] core.git: sw/qa writerfilter/source

Luboš Luňák l.lunak at collabora.com
Wed Apr 23 05:58:03 PDT 2014


 sw/qa/extras/ooxmlimport/data/gridbefore.docx         |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx              |   12 ++
 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx |   79 ++++++++++++++++++
 writerfilter/source/ooxml/OOXMLFastContextHandler.hxx |    3 
 writerfilter/source/ooxml/factoryimpl_ns.xsl          |    4 
 writerfilter/source/ooxml/model.xml                   |   12 ++
 6 files changed, 108 insertions(+), 2 deletions(-)

New commits:
commit cf33af732ed0d3d553bb74636e3b14c55d44c153
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Wed Apr 23 14:34:54 2014 +0200

    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

diff --git a/sw/qa/extras/ooxmlimport/data/gridbefore.docx b/sw/qa/extras/ooxmlimport/data/gridbefore.docx
new file mode 100644
index 0000000..571fb48
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/gridbefore.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 2f1f0cd..7ca648c 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 a8ecda3..0506136 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 dd8d997..799395f 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 9cb8912..d932008 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 16039bc..11ed808 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"/>


More information about the Libreoffice-commits mailing list