[Libreoffice-commits] core.git: Branch 'libreoffice-6-4' - writerfilter/source

László Németh (via logerrit) logerrit at kemper.freedesktop.org
Mon Jan 6 11:21:24 UTC 2020


 writerfilter/source/dmapper/DomainMapperTableManager.cxx |   28 +----
 writerfilter/source/dmapper/DomainMapperTableManager.hxx |    3 
 writerfilter/source/dmapper/DomainMapper_Impl.cxx        |   12 --
 writerfilter/source/dmapper/DomainMapper_Impl.hxx        |    3 
 writerfilter/source/dmapper/TableManager.cxx             |   48 ++------
 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx    |   83 +++++++++++++++
 writerfilter/source/ooxml/OOXMLFastContextHandler.hxx    |    5 
 writerfilter/source/ooxml/factoryimpl_ns.py              |    3 
 writerfilter/source/ooxml/model.xml                      |   19 +++
 9 files changed, 132 insertions(+), 72 deletions(-)

New commits:
commit 4ddf3d035f8db1271df23b1e219a7c4a135297a3
Author:     László Németh <nemeth at numbertext.org>
AuthorDate: Thu Jan 2 22:05:27 2020 +0100
Commit:     László Németh <nemeth at numbertext.org>
CommitDate: Mon Jan 6 12:20:54 2020 +0100

    tdf#129475 DOCX: fix gridAfter with shape-only cells
    
    and in last row of tables, i.e. regressions caused
    by the following commit.
    
    This reverts commit b2c6d2d961a6113d0f111fab45ae12a40d389a23
    (fdo#38414 tdf#44986: DOCX table import: handle gridBefore/After),
    except some unit testing.
    
    Change-Id: Icb2d65b7a0766cf8dd00511cde500af3f94d2a94
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86125
    Reviewed-by: László Németh <nemeth at numbertext.org>
    Tested-by: László Németh <nemeth at numbertext.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86211
    Tested-by: Jenkins

diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
index b7d5a7b35e8e..f4d025739915 100644
--- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
@@ -48,7 +48,7 @@ DomainMapperTableManager::DomainMapperTableManager() :
     m_nCell(),
     m_nGridSpan(1),
     m_aGridBefore(),
-    m_aGridAfter(),
+    m_nGridAfter(0),
     m_nHeaderRepeat(0),
     m_nTableWidth(0),
     m_bIsInShape(false),
@@ -357,7 +357,7 @@ bool DomainMapperTableManager::sprm(Sprm & rSprm)
                 m_aGridBefore.back( ) = nIntValue;
                 break;
             case NS_ooxml::LN_CT_TrPrBase_gridAfter:
-                m_aGridAfter.back() = nIntValue;
+                m_nGridAfter = nIntValue;
                 break;
             case NS_ooxml::LN_CT_TblPrBase_tblCaption:
                 // To-Do: Not yet preserved
@@ -399,11 +399,6 @@ sal_uInt32 DomainMapperTableManager::getCurrentGridBefore( )
     return m_aGridBefore.back( );
 }
 
-sal_uInt32 DomainMapperTableManager::getCurrentGridAfter( )
-{
-    return m_aGridAfter.back( );
-}
-
 bool DomainMapperTableManager::hasCurrentSpans() const
 {
     return !m_aGridSpans.empty();
@@ -467,7 +462,6 @@ void DomainMapperTableManager::startLevel( )
     m_aTmpTableProperties.push_back( pTmpProperties );
     m_nCell.push_back( 0 );
     m_aGridBefore.push_back( 0 );
-    m_aGridAfter.push_back( 0 );
     m_nTableWidth = 0;
     m_nLayoutType = 0;
 
@@ -498,7 +492,6 @@ void DomainMapperTableManager::endLevel( )
 
     m_nCell.pop_back( );
     m_aGridBefore.pop_back( );
-    m_aGridAfter.pop_back( );
     m_nTableWidth = 0;
     m_nLayoutType = 0;
 
@@ -555,7 +548,6 @@ void DomainMapperTableManager::endOfRowAction()
         IntVectorPtr pTmpCellWidths = m_aCellWidths.back();
         sal_uInt32 nTmpCell = m_nCell.back();
         sal_uInt32 nTmpGridBefore = m_aGridBefore.back();
-        sal_uInt32 nTmpGridAfter = m_aGridAfter.back();
 
         // endLevel and startLevel are taking care of the non finished row
         // to carry it over to the next table
@@ -569,13 +561,11 @@ void DomainMapperTableManager::endOfRowAction()
         m_aCellWidths.pop_back();
         m_nCell.pop_back();
         m_aGridBefore.pop_back();
-        m_aGridAfter.pop_back();
         m_aTableGrid.push_back(pTmpTableGrid);
         m_aGridSpans.push_back(pTmpGridSpans);
         m_aCellWidths.push_back(pTmpCellWidths);
         m_nCell.push_back(nTmpCell);
         m_aGridBefore.push_back(nTmpGridBefore);
-        m_aGridAfter.push_back(nTmpGridAfter);
     }
 
     // Push the tmp position now that we compared it
@@ -622,10 +612,10 @@ void DomainMapperTableManager::endOfRowAction()
         //fill missing gridBefore elements with '1'
         pCurrentSpans->insert( pCurrentSpans->begin( ), m_aGridBefore.back(), 1 );
     }
-    if( pCurrentSpans->size() < m_aGridBefore.back() + m_nCell.back( ) + m_aGridAfter.back() )
+    if( pCurrentSpans->size() < m_aGridBefore.back() + m_nCell.back( ))
     {
         //fill missing elements with '1'
-        pCurrentSpans->insert( pCurrentSpans->end( ), m_aGridBefore.back() + m_nCell.back( ) + m_aGridAfter.back() - pCurrentSpans->size(), 1 );
+        pCurrentSpans->insert( pCurrentSpans->end( ), m_aGridBefore.back() + m_nCell.back( ) - pCurrentSpans->size(), 1 );
     }
 
 #ifdef DBG_UTIL
@@ -652,7 +642,7 @@ void DomainMapperTableManager::endOfRowAction()
     for (int i : (*pTableGrid))
         nFullWidthRelative = o3tl::saturating_add(nFullWidthRelative, i);
 
-    if( pTableGrid->size() == nGrids && m_nCell.back( ) > 0 )
+    if( pTableGrid->size() == ( nGrids + m_nGridAfter ) && m_nCell.back( ) > 0 )
     {
         /*
          * If table width property set earlier is smaller than the current table width,
@@ -682,12 +672,12 @@ void DomainMapperTableManager::endOfRowAction()
                 }
             }
         }
-        uno::Sequence< text::TableColumnSeparator > aSeparators( m_aGridBefore.back() + m_nCell.back( ) + m_aGridAfter.back() - 1 );
+        uno::Sequence< text::TableColumnSeparator > aSeparators( m_aGridBefore.back() + m_nCell.back( ) - 1 );
         text::TableColumnSeparator* pSeparators = aSeparators.getArray();
         double nLastRelPos = 0.0;
         sal_uInt32 nBorderGridIndex = 0;
 
-        size_t nWidthsBound = m_aGridBefore.back() + m_nCell.back() + m_aGridAfter.back() - 1;
+        size_t nWidthsBound = m_aGridBefore.back() + m_nCell.back() - 1;
         if (nWidthsBound)
         {
             if (nFullWidthRelative == 0)
@@ -720,7 +710,7 @@ void DomainMapperTableManager::endOfRowAction()
     }
     else if ( !pCellWidths->empty() &&
                ( m_nLayoutType == NS_ooxml::LN_Value_doc_ST_TblLayout_fixed
-                 || pCellWidths->size() == nGrids )
+                 || pCellWidths->size() == ( nGrids + m_nGridAfter ) )
              )
     {
         // If we're here, then the number of cells does not equal to the amount
@@ -775,11 +765,11 @@ void DomainMapperTableManager::endOfRowAction()
     ++m_nRow;
     m_nCell.back( ) = 0;
     m_aGridBefore.back( ) = 0;
-    m_aGridAfter.back( ) = 0;
     getCurrentGrid()->clear();
     pCurrentSpans->clear();
     pCellWidths->clear();
 
+    m_nGridAfter = 0;
     m_bTableSizeTypeInserted = false;
 
 #ifdef DBG_UTIL
diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.hxx b/writerfilter/source/dmapper/DomainMapperTableManager.hxx
index a0b386657feb..219986870ef3 100644
--- a/writerfilter/source/dmapper/DomainMapperTableManager.hxx
+++ b/writerfilter/source/dmapper/DomainMapperTableManager.hxx
@@ -43,7 +43,7 @@ class DomainMapperTableManager : public TableManager
     ::std::vector< sal_uInt32 > m_nCell;
     sal_uInt32      m_nGridSpan;
     ::std::vector< sal_uInt32 > m_aGridBefore; ///< number of grid columns in the parent table's table grid which must be skipped before the contents of this table row are added to the parent table
-    ::std::vector< sal_uInt32 > m_aGridAfter; ///< number of grid columns in the parent table's table grid which shall be left after the last cell in the table row
+    sal_uInt32      m_nGridAfter; ///< number of grid columns in the parent table's table grid which shall be left after the last cell in the table row
     sal_Int32       m_nHeaderRepeat; //counter of repeated headers - if == -1 then the repeating stops
     sal_Int32       m_nTableWidth; //might be set directly or has to be calculated from the column positions
     /// Are we in a shape (text append stack is not empty) or in the body document?
@@ -94,7 +94,6 @@ public:
     IntVectorPtr const & getCurrentSpans( );
     IntVectorPtr const & getCurrentCellWidths( );
     sal_uInt32 getCurrentGridBefore( );
-    sal_uInt32 getCurrentGridAfter( );
 
     /// Turn the attributes collected so far in m_aTableLook into a property and clear the container.
     void finishTableLook();
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 2b48e0342bbd..82c5b08c9e0f 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -276,7 +276,6 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_bIsFirstParaInSection( true ),
         m_bIsFirstParaInSectionAfterRedline( true ),
         m_bDummyParaAddedForTableInSection( false ),
-        m_bDummyCharAddedForTableRowGridAfter( false ),
         m_bTextFrameInserted(false),
         m_bIsPreviousParagraphFramed( false ),
         m_bIsLastParaInSection( false ),
@@ -1637,17 +1636,6 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
                         }
                     }
 
-                    // remove dummy character added for gridAfter table cells
-                    if (GetIsDummyCharAddedForTableRowGridAfter())
-                    {
-                        SetIsDummyCharAddedForTableRowGridAfter(false);
-                        uno::Reference<text::XParagraphCursor> xParaCursor(
-                            xTextAppend->createTextCursorByRange(xTextAppend->getEnd()), uno::UNO_QUERY_THROW);
-                        xParaCursor->gotoStartOfParagraph( false);
-                        xParaCursor->goRight(1, true);
-                        xParaCursor->setString("");
-                    }
-
                     xTextRange = xTextAppend->finishParagraph( comphelper::containerToSequence(aProperties) );
                     m_xPreviousParagraph.set(xTextRange, uno::UNO_QUERY);
 
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 8352aaa2ae0f..18b019e7c402 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -540,7 +540,6 @@ private:
     bool                            m_bIsFirstParaInSectionAfterRedline;
     bool                            m_bIsFirstParaInShape = false;
     bool                            m_bDummyParaAddedForTableInSection;
-    bool                            m_bDummyCharAddedForTableRowGridAfter;
     bool                            m_bTextFrameInserted;
     bool                            m_bIsPreviousParagraphFramed;
     bool                            m_bIsLastParaInSection;
@@ -638,8 +637,6 @@ public:
     bool GetIsFirstParagraphInShape() const { return m_bIsFirstParaInShape; }
     void SetIsDummyParaAddedForTableInSection( bool bIsAdded );
     bool GetIsDummyParaAddedForTableInSection() const { return m_bDummyParaAddedForTableInSection;}
-    void SetIsDummyCharAddedForTableRowGridAfter( bool bIsAdded ) { m_bDummyCharAddedForTableRowGridAfter = bIsAdded; }
-    bool GetIsDummyCharAddedForTableRowGridAfter() const { return m_bDummyCharAddedForTableRowGridAfter;}
 
     /// Track if a textframe has been inserted into this section
     void SetIsTextFrameInserted( bool bIsInserted );
diff --git a/writerfilter/source/dmapper/TableManager.cxx b/writerfilter/source/dmapper/TableManager.cxx
index facae6e8b48e..b9384b9e08df 100644
--- a/writerfilter/source/dmapper/TableManager.cxx
+++ b/writerfilter/source/dmapper/TableManager.cxx
@@ -408,43 +408,23 @@ void TableManager::endRow()
     TagLogger::getInstance().element("tablemanager.endRow");
 #endif
     TableData::Pointer_t pTableData = mTableDataStack.top();
-    sal_uInt32 nGridBefore = mpTableDataHandler->getDomainMapperImpl().getTableManager().getCurrentGridBefore();
-    sal_uInt32 nGridAfter = mpTableDataHandler->getDomainMapperImpl().getTableManager().getCurrentGridAfter();
 
-    // Add borderless w:gridBefore and w:gridAfter cell(s) to the row
-    if (pTableData && (nGridBefore > 0 || nGridAfter > 0))
+    // Add borderless w:gridBefore cell(s) to the row
+    if (pTableData)
     {
-        css::table::BorderLine2 aBorderLine;
-        aBorderLine.Color = 0;
-        aBorderLine.InnerLineWidth = 0;
-        aBorderLine.OuterLineWidth = 0;
-        TablePropertyMapPtr pCellProperties(new TablePropertyMap);
-        pCellProperties->Insert(PROP_TOP_BORDER, css::uno::makeAny(aBorderLine));
-        pCellProperties->Insert(PROP_LEFT_BORDER, css::uno::makeAny(aBorderLine));
-        pCellProperties->Insert(PROP_BOTTOM_BORDER, css::uno::makeAny(aBorderLine));
-        pCellProperties->Insert(PROP_RIGHT_BORDER, css::uno::makeAny(aBorderLine));
-        if (nGridBefore > 0)
+        sal_uInt32 nGridBefore = mpTableDataHandler->getDomainMapperImpl().getTableManager().getCurrentGridBefore();
+        for (unsigned int i = 0; i < nGridBefore; ++i)
         {
-            const css::uno::Reference<css::text::XTextRange>& rFirstCellStartHandle = pTableData->getCurrentRow()->getCellStart(0);
-            for (unsigned int i = 0; i < nGridBefore; ++i)
-                pTableData->getCurrentRow()->addCell(rFirstCellStartHandle, pCellProperties, /*bAddBefore=*/true);
-        }
-        if (nGridAfter > 0)
-        {
-            const css::uno::Reference<css::text::XTextRange>& rEndCellEndHandle = pTableData->getCurrentRow()->getCellEnd(pTableData->getCurrentRow()->getCellCount()-1);
-            auto xCursor(rEndCellEndHandle->getText()->createTextCursorByRange(rEndCellEndHandle));
-            if (!xCursor->getString().isEmpty())
-            {
-                // add a dummy character to get a right handle for gridAfter cells after the last non-empty cell, removing that later
-                xCursor->gotoEnd(false);
-                xCursor->setString("x");
-                mpTableDataHandler->getDomainMapperImpl().SetIsDummyCharAddedForTableRowGridAfter(true);
-            }
-            for (unsigned int i = 0; i < nGridAfter; ++i)
-            {
-                pTableData->getCurrentRow()->addCell(xCursor, pCellProperties, /*bAddBefore=*/false);
-                pTableData->getCurrentRow()->endCell(xCursor);
-            }
+            css::table::BorderLine2 aBorderLine;
+            aBorderLine.Color = 0;
+            aBorderLine.InnerLineWidth = 0;
+            aBorderLine.OuterLineWidth = 0;
+            TablePropertyMapPtr pCellProperties(new TablePropertyMap);
+            pCellProperties->Insert(PROP_TOP_BORDER, css::uno::makeAny(aBorderLine));
+            pCellProperties->Insert(PROP_LEFT_BORDER, css::uno::makeAny(aBorderLine));
+            pCellProperties->Insert(PROP_BOTTOM_BORDER, css::uno::makeAny(aBorderLine));
+            pCellProperties->Insert(PROP_RIGHT_BORDER, css::uno::makeAny(aBorderLine));
+            pTableData->getCurrentRow()->addCell(pTableData->getCurrentRow()->getCellStart(0), pCellProperties, /*bAddBefore=*/true);
         }
     }
 
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index 31fb07774552..6f7839d0512b 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -1397,6 +1397,14 @@ void OOXMLFastContextHandlerTextTableRow::startRow()
 
 void OOXMLFastContextHandlerTextTableRow::endRow()
 {
+    if (mpGridAfter)
+    {
+        // Grid after is the same as grid before, the empty cells are just
+        // inserted after the real ones, not before.
+        handleGridBefore(mpGridAfter);
+        mpGridAfter = nullptr;
+    }
+
     startParagraphGroup();
 
     if (isForwardEvents())
@@ -1427,6 +1435,81 @@ void OOXMLFastContextHandlerTextTableRow::endRow()
     endParagraphGroup();
 }
 
+void OOXMLFastContextHandlerTextTableRow::handleGridAfter(const OOXMLValue::Pointer_t& rValue)
+{
+    if (OOXMLFastContextHandler* pTableRowProperties = getParent())
+    {
+        if (OOXMLFastContextHandler* pTableRow = pTableRowProperties->getParent())
+            // Save the value into the table row context, so it can be handled
+            // right before the end of the row.
+            pTableRow->setGridAfter(rValue);
+    }
+}
+
+namespace {
+OOXMLValue::Pointer_t fakeNoBorder()
+{
+    OOXMLPropertySet::Pointer_t pProps( new OOXMLPropertySet );
+    OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(0);
+    pProps->add(NS_ooxml::LN_CT_Border_val, pVal, OOXMLProperty::ATTRIBUTE);
+    OOXMLValue::Pointer_t pValue( new OOXMLPropertySetValue( pProps ));
+    return pValue;
+}
+}
+
+// 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( const OOXMLValue::Pointer_t& val )
+{
+    // start removing: disable for w:gridBefore
+    if (!mpGridAfter)
+        return;
+
+    int count = val->getInt();
+    for( int i = 0;
+         i < count;
+         ++i )
+    {
+        endOfParagraph();
+
+        if (isForwardEvents())
+        {
+            // This whole part is OOXMLFastContextHandlerTextTableCell::endCell() .
+            OOXMLPropertySet::Pointer_t pProps(new OOXMLPropertySet);
+            {
+                OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(mnTableDepth);
+                pProps->add(NS_ooxml::LN_tblDepth, pVal, OOXMLProperty::SPRM);
+            }
+            {
+                OOXMLValue::Pointer_t pVal = OOXMLIntegerValue::Create(1);
+                pProps->add(NS_ooxml::LN_inTbl, pVal, OOXMLProperty::SPRM);
+            }
+            {
+                OOXMLValue::Pointer_t pVal = OOXMLBooleanValue::Create(mnTableDepth > 0);
+                pProps->add(NS_ooxml::LN_tblCell, pVal, OOXMLProperty::SPRM);
+            }
+
+            mpStream->props(pProps.get());
+
+            // fake <w:tcBorders> with no border
+            OOXMLPropertySet::Pointer_t pCellProps( new OOXMLPropertySet );
+            {
+                OOXMLPropertySet::Pointer_t pBorderProps( new OOXMLPropertySet );
+                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(sal_uInt32 border : borders)
+                    pBorderProps->add(border, fakeNoBorder(), OOXMLProperty::SPRM);
+                OOXMLValue::Pointer_t pValue( new OOXMLPropertySetValue( pBorderProps ));
+                pCellProps->add(NS_ooxml::LN_CT_TcPrBase_tcBorders, pValue, OOXMLProperty::SPRM);
+                mpParserState->setCellProperties(pCellProps);
+            }
+        }
+
+        sendCellProperties();
+        endParagraphGroup();
+    }
+}
+
 /*
   class OOXMLFastContextHandlerTextTable
  */
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
index 0da8b9cdff9c..d5de5a778ee0 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
@@ -186,6 +186,8 @@ public:
     virtual void setDefaultStringValue();
 
     void sendPropertyToParent();
+    OOXMLFastContextHandler* getParent() const { return mpParent; }
+    void setGridAfter(const OOXMLValue::Pointer_t& pGridAfter) { mpGridAfter = pGridAfter; }
 
 protected:
     OOXMLFastContextHandler * mpParent;
@@ -224,6 +226,7 @@ protected:
     const css::uno::Reference< css::uno::XComponentContext >& getComponentContext() const { return m_xContext;}
 
     bool inPositionV;
+    OOXMLValue::Pointer_t mpGridAfter;
 
 private:
     void operator =(OOXMLFastContextHandler const &) = delete;
@@ -404,6 +407,8 @@ public:
 
     static void startRow();
     void endRow();
+    void handleGridBefore( const OOXMLValue::Pointer_t& val );
+    void handleGridAfter(const OOXMLValue::Pointer_t& rValue);
 };
 
 class OOXMLFastContextHandlerTextTable : public OOXMLFastContextHandler
diff --git a/writerfilter/source/ooxml/factoryimpl_ns.py b/writerfilter/source/ooxml/factoryimpl_ns.py
index 5bdf25c91478..41fa714678c7 100644
--- a/writerfilter/source/ooxml/factoryimpl_ns.py
+++ b/writerfilter/source/ooxml/factoryimpl_ns.py
@@ -440,6 +440,9 @@ def factoryChooseAction(actionNode):
     elif actionNode.getAttribute("action") in ("startRow", "endRow"):
         ret.append("    %sif (OOXMLFastContextHandlerTextTableRow* pTextTableRow = dynamic_cast<OOXMLFastContextHandlerTextTableRow*>(pHandler))" % extra_space)
         ret.append("    %s    pTextTableRow->%s();" % (extra_space, actionNode.getAttribute("action")))
+    elif actionNode.getAttribute("action") == "handleGridBefore" or actionNode.getAttribute("action") == "handleGridAfter":
+        ret.append("    %sif (OOXMLFastContextHandlerTextTableRow* pTextTableRow = dynamic_cast<OOXMLFastContextHandlerTextTableRow*>(pHandler))" % extra_space)
+        ret.append("    %s    pTextTableRow->%s();" % (extra_space, actionNode.getAttribute("action")))
     # tdf#111550
     elif actionNode.getAttribute("action") in ("start_P_Tbl"):
         ret.append("    %sif (OOXMLFastContextHandlerTextTable* pTextTable = dynamic_cast<OOXMLFastContextHandlerTextTable*>(pHandler))" % extra_space)
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 4c712e0b71fb..17c8f5217fec 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -14445,7 +14445,7 @@
             <ref name="CT_DecimalNumber"/>
           </element>
           <element name="gridAfter">
-            <ref name="CT_DecimalNumber"/>
+            <ref name="CT_TrPrBaseGridAfter"/>
           </element>
           <element name="wBefore">
             <ref name="CT_TblWidth"/>
@@ -14473,6 +14473,16 @@
           </element>
         </choice>
       </define>
+      <define name="CT_TrPrBaseGridBefore">
+        <attribute name="val">
+          <ref name="ST_DecimalNumber"/>
+        </attribute>
+      </define>
+      <define name="CT_TrPrBaseGridAfter">
+        <attribute name="val">
+          <ref name="ST_DecimalNumber"/>
+        </attribute>
+      </define>
       <define name="CT_TrPr">
         <ref name="CT_TrPrBase"/>
         <element name="ins">
@@ -18395,7 +18405,6 @@
       <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="gridAfter" tokenid="ooxml:CT_TrPrBase_gridAfter"/>
       <element name="wBefore" tokenid="ooxml:CT_TrPrBase_wBefore"/>
       <element name="wAfter" tokenid="ooxml:CT_TrPrBase_wAfter"/>
       <element name="cantSplit" tokenid="ooxml:CT_TrPrBase_cantSplit"/>
@@ -18405,6 +18414,12 @@
       <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"/>
+    </resource>
+    <resource name="CT_TrPrBaseGridAfter" resource="TextTableRow">
+      <attribute name="val" tokenid="ooxml:CT_TrPrBase_gridAfter" action="handleGridAfter"/>
+    </resource>
     <resource name="CT_TrPr" resource="Properties">
       <element name="ins" tokenid="ooxml:CT_TrPr_ins"/>
       <element name="del" tokenid="ooxml:CT_TrPr_del"/>


More information about the Libreoffice-commits mailing list