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 adf7031e3a35fe9d43085e8b223a6e36d20a32f4 Author: László Németh <nem...@numbertext.org> AuthorDate: Thu Jan 2 22:05:27 2020 +0100 Commit: László Németh <nem...@numbertext.org> CommitDate: Sat Jan 4 10:31:09 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 <nem...@numbertext.org> Tested-by: László Németh <nem...@numbertext.org> 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"/> _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits