summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2020-01-02 22:05:27 +0100
committerLászló Németh <nemeth@numbertext.org>2020-01-04 10:31:09 +0100
commitadf7031e3a35fe9d43085e8b223a6e36d20a32f4 (patch)
treee21cd9ec131ec0c5ab51ffda8d1b903d9edd1ded /writerfilter
parent6bdfcd317f87ab1948f56eb1231db1378c51c2f8 (diff)
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@numbertext.org> Tested-by: László Németh <nemeth@numbertext.org>
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/source/dmapper/DomainMapperTableManager.cxx28
-rw-r--r--writerfilter/source/dmapper/DomainMapperTableManager.hxx3
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx12
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx3
-rw-r--r--writerfilter/source/dmapper/TableManager.cxx48
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.cxx83
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.hxx5
-rw-r--r--writerfilter/source/ooxml/factoryimpl_ns.py3
-rw-r--r--writerfilter/source/ooxml/model.xml19
9 files changed, 132 insertions, 72 deletions
diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
index e288a1e803a3..b8fd339f0752 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( );
-}
-
DomainMapperTableManager::IntVectorPtr const & DomainMapperTableManager::getCurrentSpans( )
{
return m_aGridSpans.back( );
@@ -462,7 +457,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;
@@ -493,7 +487,6 @@ void DomainMapperTableManager::endLevel( )
m_nCell.pop_back( );
m_aGridBefore.pop_back( );
- m_aGridAfter.pop_back( );
m_nTableWidth = 0;
m_nLayoutType = 0;
@@ -550,7 +543,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
@@ -564,13 +556,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
@@ -617,10 +607,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
@@ -647,7 +637,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,
@@ -677,12 +667,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)
@@ -715,7 +705,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
@@ -770,11 +760,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 6f248d1d0192..1020d67fc8ad 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?
@@ -93,7 +93,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 0ca7ffa7027a..7842acb4a9b0 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -283,7 +283,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 ),
@@ -1642,17 +1641,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 fde0749d1f8d..b050e95b66c5 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -549,7 +549,6 @@ private:
bool m_bIsFirstParaInSectionAfterRedline;
bool m_bIsFirstParaInShape = false;
bool m_bDummyParaAddedForTableInSection;
- bool m_bDummyCharAddedForTableRowGridAfter;
bool m_bTextFrameInserted;
bool m_bIsPreviousParagraphFramed;
bool m_bIsLastParaInSection;
@@ -648,8 +647,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"/>