writerfilter/source/dmapper/DomainMapperTableManager.cxx | 47 +++------------ writerfilter/source/dmapper/DomainMapperTableManager.hxx | 1 writerfilter/source/dmapper/TableData.hxx | 19 ++++++ writerfilter/source/dmapper/TableManager.cxx | 11 +++ writerfilter/source/dmapper/TableManager.hxx | 2 5 files changed, 42 insertions(+), 38 deletions(-)
New commits: commit 7f96310a7a8e74caf757d84e0475553f484ef2b9 Author: Justin Luth <justin.l...@collabora.com> AuthorDate: Mon Jun 29 13:20:00 2020 +0300 Commit: Gabor Kelemen <kelemen.gab...@nisz.hu> CommitDate: Fri Jul 31 09:16:30 2020 +0200 tdf#129452 writerfilter: preserve gridSpans longer than currentRow It is a fairly common thing for table operations to compare items in the same column (like merged cells for example). In order to determine column information, each row's (gridBefore - change-id Ie305477f0e3468a4a923095d76f520d97fe99ffe - and) merged cells need to be known. So save that information in the cell data - and don't just throw it away after the current row has been analyzed. Good grief. Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97433 Tested-by: Jenkins Reviewed-by: Justin Luth <justin_l...@sil.org> Reviewed-by: László Németh <nem...@numbertext.org> (cherry picked from commit d22de1be15aaca438126ce1c1c3373ab1d698b76) Change-Id: Ibfdac336bbb1f7303c7e585a85c94be37ad6f916 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99833 Tested-by: Gabor Kelemen <kelemen.gab...@nisz.hu> Reviewed-by: Gabor Kelemen <kelemen.gab...@nisz.hu> diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx index ee897eb502d6..62c7e09a43bf 100644 --- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx @@ -395,16 +395,6 @@ DomainMapperTableManager::IntVectorPtr const & DomainMapperTableManager::getCurr return m_aTableGrid.back( ); } -bool DomainMapperTableManager::hasCurrentSpans() const -{ - return !m_aGridSpans.empty(); -} - -DomainMapperTableManager::IntVectorPtr const & DomainMapperTableManager::getCurrentSpans( ) -{ - return m_aGridSpans.back( ); -} - DomainMapperTableManager::IntVectorPtr const & DomainMapperTableManager::getCurrentCellWidths( ) { return m_aCellWidths.back( ); @@ -455,11 +445,9 @@ void DomainMapperTableManager::startLevel( ) } IntVectorPtr pNewGrid( new vector<sal_Int32> ); - IntVectorPtr pNewSpans( new vector<sal_Int32> ); IntVectorPtr pNewCellWidths( new vector<sal_Int32> ); TablePositionHandlerPtr pNewPositionHandler; m_aTableGrid.push_back( pNewGrid ); - m_aGridSpans.push_back( pNewSpans ); m_aCellWidths.push_back( pNewCellWidths ); m_aTablePositions.push_back( pNewPositionHandler ); @@ -489,7 +477,6 @@ void DomainMapperTableManager::endLevel( ) } m_aTableGrid.pop_back( ); - m_aGridSpans.pop_back( ); // Do the same trick as in startLevel(): pop the value that was pushed too early. boost::optional<sal_Int32> oCurrentWidth; @@ -529,9 +516,10 @@ void DomainMapperTableManager::endOfCellAction() TagLogger::getInstance().element("endOFCellAction"); #endif - if (!hasCurrentSpans()) - throw std::out_of_range("empty spans"); - getCurrentSpans()->push_back(m_nGridSpan); + if ( !isInTable() ) + throw std::out_of_range("cell without a table"); + if ( m_nGridSpan > 1 ) + setCurrentGridSpan( m_nGridSpan ); m_nGridSpan = 1; ++m_nCell.back( ); } @@ -554,7 +542,6 @@ void DomainMapperTableManager::endOfRowAction() { // Save the grid infos to have them survive the end/start level IntVectorPtr pTmpTableGrid = m_aTableGrid.back(); - IntVectorPtr pTmpGridSpans = m_aGridSpans.back(); IntVectorPtr pTmpCellWidths = m_aCellWidths.back(); sal_uInt32 nTmpCell = m_nCell.back(); TableParagraphVectorPtr pTableParagraphs = getCurrentParagraphs(); @@ -567,11 +554,9 @@ void DomainMapperTableManager::endOfRowAction() startLevel(); m_aTableGrid.pop_back(); - m_aGridSpans.pop_back(); m_aCellWidths.pop_back(); m_nCell.pop_back(); m_aTableGrid.push_back(pTmpTableGrid); - m_aGridSpans.push_back(pTmpGridSpans); m_aCellWidths.push_back(pTmpCellWidths); m_nCell.push_back(nTmpCell); m_aParagraphsToEndTable.pop( ); @@ -618,23 +603,12 @@ void DomainMapperTableManager::endOfRowAction() #endif } - IntVectorPtr pCurrentSpans = getCurrentSpans( ); - - if ( getCurrentGridBefore() ) - { - //fill missing gridBefore elements with '1' - pCurrentSpans->insert( pCurrentSpans->begin(), getCurrentGridBefore(), 1 ); - } - if ( pCurrentSpans->size() < getCurrentGridBefore() + m_nCell.back() ) - { - //fill missing elements with '1' - pCurrentSpans->insert( pCurrentSpans->end(), getCurrentGridBefore() + m_nCell.back() - pCurrentSpans->size(), 1 ); - } + std::vector<sal_uInt32> rCurrentSpans = getCurrentGridSpans(); #ifdef DBG_UTIL TagLogger::getInstance().startElement("gridSpans"); { - for (const auto& rGridSpan : *pCurrentSpans) + for (const auto& rGridSpan : rCurrentSpans) { TagLogger::getInstance().startElement("gridSpan"); TagLogger::getInstance().attribute("span", rGridSpan); @@ -645,7 +619,7 @@ void DomainMapperTableManager::endOfRowAction() #endif //calculate number of used grids - it has to match the size of m_aTableGrid - size_t nGrids = std::accumulate(pCurrentSpans->begin(), pCurrentSpans->end(), sal::static_int_cast<size_t>(0)); + size_t nGrids = std::accumulate(rCurrentSpans.begin(), rCurrentSpans.end(), sal::static_int_cast<size_t>(0)); // sj: the grid is having no units... it is containing only relative values. // a table with a grid of "1:2:1" looks identical as if the table is having @@ -697,7 +671,7 @@ void DomainMapperTableManager::endOfRowAction() if (nFullWidthRelative == 0) throw o3tl::divide_by_zero(); - ::std::vector< sal_Int32 >::const_iterator aSpansIter = pCurrentSpans->begin( ); + ::std::vector< sal_uInt32 >::const_iterator aSpansIter = rCurrentSpans.begin(); for( size_t nBorder = 0; nBorder < nWidthsBound; ++nBorder ) { double fGridWidth = 0.; @@ -776,9 +750,9 @@ void DomainMapperTableManager::endOfRowAction() // At incomplete table grids, last cell width can be smaller, than its final width. // Correct it based on the last but one column width and their span values. - if ( bIsIncompleteGrid && pCurrentSpans->size()-1 == nWidthsBound ) + if ( bIsIncompleteGrid && rCurrentSpans.size()-1 == nWidthsBound ) { - auto aSpansIter = std::next(pCurrentSpans->begin( ), nWidthsBound - 1); + auto aSpansIter = std::next(rCurrentSpans.begin(), nWidthsBound - 1); sal_Int32 nFixLastCellWidth = (*pCellWidths)[nWidthsBound-1] / *aSpansIter * *std::next(aSpansIter); if (nFixLastCellWidth > (*pCellWidths)[nWidthsBound]) nFullWidthRelative += nFixLastCellWidth - (*pCellWidths)[nWidthsBound]; @@ -813,7 +787,6 @@ void DomainMapperTableManager::endOfRowAction() ++m_nRow; m_nCell.back( ) = 0; getCurrentGrid()->clear(); - pCurrentSpans->clear(); pCellWidths->clear(); m_nGridAfter = 0; diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.hxx b/writerfilter/source/dmapper/DomainMapperTableManager.hxx index 85e55e2a0da5..8f794fb68748 100644 --- a/writerfilter/source/dmapper/DomainMapperTableManager.hxx +++ b/writerfilter/source/dmapper/DomainMapperTableManager.hxx @@ -55,7 +55,6 @@ class DomainMapperTableManager : public TableManager std::vector< TablePropertyMapPtr > m_aTmpTableProperties; ///< Temporarily stores the table properties until end of row ::std::vector< IntVectorPtr > m_aTableGrid; - ::std::vector< IntVectorPtr > m_aGridSpans; /// If this is true, then we pushed a width before the next level started, and that should be carried over when starting the next level. bool m_bPushCurrentWidth; /// Individual table cell width values, used only in case the number of cells doesn't match the table grid. diff --git a/writerfilter/source/dmapper/TableData.hxx b/writerfilter/source/dmapper/TableData.hxx index 8b64148c3536..14fedc66fba8 100644 --- a/writerfilter/source/dmapper/TableData.hxx +++ b/writerfilter/source/dmapper/TableData.hxx @@ -52,11 +52,14 @@ class CellData final : public virtual SvRefBase bool mbOpen; + sal_uInt32 m_nGridSpan; ///< number of grid columns in the parent table's table grid which this cell defines + public: typedef tools::SvRef<CellData> Pointer_t; CellData(css::uno::Reference<css::text::XTextRange> const & start, TablePropertyMapPtr pProps) : mStart(start), mEnd(start), mpProps(pProps), mbOpen(true) + , m_nGridSpan(1) { } @@ -96,6 +99,9 @@ public: const TablePropertyMapPtr& getProperties() const { return mpProps; } bool isOpen() const { return mbOpen; } + + sal_uInt32 getGridSpan() { return m_nGridSpan; } + void setGridSpan( sal_uInt32 nSpan ) { m_nGridSpan = nSpan; } }; /** @@ -235,6 +241,19 @@ public: sal_uInt32 getGridBefore() { return m_nGridBefore; } void setGridBefore(sal_uInt32 nSkipGrids) { m_nGridBefore = nSkipGrids; } + sal_uInt32 getGridSpan(sal_uInt32 i) { return mCells[i]->getGridSpan(); } + std::vector< sal_uInt32 > getGridSpans() + { + std::vector< sal_uInt32 > nRet; + for (auto const& aCell: mCells) + nRet.push_back(aCell->getGridSpan()); + return nRet; + } + void setCurrentGridSpan(sal_uInt32 nSpan) + { + if ( mCells.size() ) + mCells.back()->setGridSpan(nSpan); + } }; /** diff --git a/writerfilter/source/dmapper/TableManager.cxx b/writerfilter/source/dmapper/TableManager.cxx index cd3aef3285d0..97e872f7f9b1 100644 --- a/writerfilter/source/dmapper/TableManager.cxx +++ b/writerfilter/source/dmapper/TableManager.cxx @@ -59,6 +59,16 @@ void TableManager::setCurrentGridBefore(sal_uInt32 nSkipGrids) mTableDataStack.top()->getCurrentRow()->setGridBefore(nSkipGrids); } +std::vector<sal_uInt32> TableManager::getCurrentGridSpans() +{ + return mTableDataStack.top()->getCurrentRow()->getGridSpans(); +} + +void TableManager::setCurrentGridSpan(sal_uInt32 nGridSpan) +{ + mTableDataStack.top()->getCurrentRow()->setCurrentGridSpan(nGridSpan); +} + void TableManager::endOfRowAction() {} void TableManager::endOfCellAction() {} @@ -373,6 +383,7 @@ void TableManager::startLevel() pTableData2->addCell(mpUnfinishedRow->getCellStart(i), mpUnfinishedRow->getCellProperties(i)); pTableData2->endCell(mpUnfinishedRow->getCellEnd(i)); + pTableData2->getCurrentRow()->setCurrentGridSpan(mpUnfinishedRow->getGridSpan(i)); } pTableData2->getCurrentRow()->setGridBefore(mpUnfinishedRow->getGridBefore()); mpUnfinishedRow.clear(); diff --git a/writerfilter/source/dmapper/TableManager.hxx b/writerfilter/source/dmapper/TableManager.hxx index fe2bf58f8ea8..efac7afdbd7c 100644 --- a/writerfilter/source/dmapper/TableManager.hxx +++ b/writerfilter/source/dmapper/TableManager.hxx @@ -469,6 +469,8 @@ public: sal_uInt32 getCurrentGridBefore(); void setCurrentGridBefore( sal_uInt32 nSkipGrids ); + std::vector<sal_uInt32> getCurrentGridSpans(); + void setCurrentGridSpan( sal_uInt32 nGridSpan ); void setTableStartsAtCellStart(bool bTableStartsAtCellStart); void setCellLastParaAfterAutospacing(bool bIsAfterAutospacing); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits