diff options
author | Mark Hung <marklh9@gmail.com> | 2017-02-15 23:24:28 +0800 |
---|---|---|
committer | Mark Hung <marklh9@gmail.com> | 2017-02-17 11:22:10 +0000 |
commit | 2ca015c2d30fc135e054e3eb329c530adce6ad0d (patch) | |
tree | 89b68267f9f7ca8687c30331854eb92d5f7a0807 /svx | |
parent | 291538bac9b0d9e1afe69c244ffa9e3f4b203761 (diff) |
tdf#105423 support vertical merged cells.
Handle rtf keyword CLVMGF and CLVMRG and decide rowspan
for the first cell.
Change-Id: I1bba84a02b0115c5d7ac80e7aedba275fdeef651
Reviewed-on: https://gerrit.libreoffice.org/34312
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Mark Hung <marklh9@gmail.com>
Diffstat (limited to 'svx')
-rw-r--r-- | svx/source/table/tablertfimporter.cxx | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/svx/source/table/tablertfimporter.cxx b/svx/source/table/tablertfimporter.cxx index c78b1207485e..f72dfe7a6999 100644 --- a/svx/source/table/tablertfimporter.cxx +++ b/svx/source/table/tablertfimporter.cxx @@ -51,10 +51,11 @@ namespace sdr { namespace table { struct RTFCellDefault { SfxItemSet maItemSet; + sal_Int32 mnRowSpan; sal_Int32 mnColSpan; // MergeCell if >1, merged cells if 0 sal_Int32 mnCellX; - explicit RTFCellDefault( SfxItemPool* pPool ) : maItemSet( *pPool ), mnColSpan(1), mnCellX(0) {} + explicit RTFCellDefault( SfxItemPool* pPool ) : maItemSet( *pPool ), mnRowSpan(1), mnColSpan(1), mnCellX(0) {} }; typedef std::vector< std::shared_ptr< RTFCellDefault > > RTFCellDefaultVector; @@ -65,8 +66,10 @@ struct RTFCellInfo sal_Int32 mnStartPara; sal_Int32 mnParaCount; sal_Int32 mnCellX; + sal_Int32 mnRowSpan; + std::shared_ptr< RTFCellInfo > mxVMergeCell; - explicit RTFCellInfo( SfxItemPool& rPool ) : maItemSet( rPool ), mnStartPara(0), mnParaCount(0), mnCellX(0) {} + explicit RTFCellInfo( SfxItemPool& rPool ) : maItemSet( rPool ), mnStartPara(0), mnParaCount(0), mnCellX(0), mnRowSpan(1), mxVMergeCell(nullptr) {} }; typedef std::shared_ptr< RTFCellInfo > RTFCellInfoPtr; @@ -110,6 +113,7 @@ private: sal_Int32 mnRowCnt; sal_Int32 mnLastEdge; + sal_Int32 mnVMergeIdx; std::vector< sal_Int32 > maColumnEdges; std::vector< sal_Int32 >::iterator maLastEdge; @@ -121,6 +125,7 @@ private: Reference< XTable > mxTable; + RTFColumnVectorPtr mxLastRow; // Copy assignment is forbidden and not implemented. SdrTableRTFParser (const SdrTableRTFParser &) = delete; SdrTableRTFParser & operator= (const SdrTableRTFParser &) = delete; @@ -137,6 +142,7 @@ SdrTableRTFParser::SdrTableRTFParser( SdrTableObj& rTableObj ) , mpActDefault( nullptr ) , mpDefMerge( nullptr ) , mxTable( rTableObj.getTable() ) +, mxLastRow( nullptr ) { mpOutliner->SetUpdateMode(true); mpOutliner->SetStyleSheet( 0, mrTableObj.GetStyleSheet() ); @@ -201,6 +207,8 @@ IMPL_LINK( SdrTableRTFParser, RTFImportHdl, ImportInfo&, rInfo, void ) void SdrTableRTFParser::NextRow() { + mxLastRow = maRows.back(); + mnVMergeIdx = 0; ++mnRowCnt; } @@ -212,10 +220,36 @@ void SdrTableRTFParser::InsertCell( ImportInfo* pInfo ) xCellInfo->mnStartPara = mnStartPara; xCellInfo->mnParaCount = pInfo->aSelection.nEndPara - 1 - mnStartPara; xCellInfo->mnCellX = mpActDefault->mnCellX; + xCellInfo->mnRowSpan = mpActDefault->mnRowSpan; + + + if ( mxLastRow != nullptr ) + { + sal_Int32 nSize = mxLastRow->size(); + while( mnVMergeIdx < nSize && + (*mxLastRow)[mnVMergeIdx]->mnCellX < xCellInfo->mnCellX ) + ++mnVMergeIdx; + + if ( xCellInfo->mnRowSpan == 0 && mnVMergeIdx < nSize ) + { + RTFCellInfoPtr xLastCell( (*mxLastRow)[mnVMergeIdx] ); + if (xLastCell->mnRowSpan) + xCellInfo->mxVMergeCell = xLastCell; + else + xCellInfo->mxVMergeCell = xLastCell->mxVMergeCell; + } + } if( !maRows.empty() ) { RTFColumnVectorPtr xColumn( maRows.back() ); + if ( xCellInfo->mxVMergeCell ) + { + if ( xColumn->size()==0 || + xColumn->back()->mxVMergeCell != xCellInfo->mxVMergeCell ) + xCellInfo->mxVMergeCell->mnRowSpan++; + } + xColumn->push_back( xCellInfo ); } @@ -288,6 +322,11 @@ void SdrTableRTFParser::FillTable() rOutliner.SetText( *pTextObject ); mrTableObj.NbcSetOutlinerParaObjectForText( rOutliner.CreateParaObject(), xCell.get() ); } + + sal_Int32 nLastRow = nRow; + if ( xCellInfo->mnRowSpan ) + nLastRow += xCellInfo->mnRowSpan - 1; + aEdge = std::lower_bound( aEdge, maColumnEdges.end(), xCellInfo->mnCellX ); sal_Int32 nLastCol = nCol; if ( aEdge != maColumnEdges.end() ) @@ -296,9 +335,9 @@ void SdrTableRTFParser::FillTable() ++aEdge; } - if ( nLastCol > nCol ) + if ( nLastCol > nCol || nLastRow > nRow ) { - Reference< XMergeableCellRange > xRange( mxTable->createCursorByRange( mxTable->getCellRangeByPosition( nCol, nRow, nLastCol, nRow ) ), UNO_QUERY_THROW ); + Reference< XMergeableCellRange > xRange( mxTable->createCursorByRange( mxTable->getCellRangeByPosition( nCol, nRow, nLastCol, nLastRow ) ), UNO_QUERY_THROW ); if( xRange->isMergeable() ) xRange->merge(); } @@ -379,6 +418,17 @@ void SdrTableRTFParser::ProcToken( ImportInfo* pInfo ) mnLastToken = pInfo->nToken; } break; + case RTF_CLVMGF: + { + mnLastToken = pInfo->nToken; + } + break; + case RTF_CLVMRG: + { + mpInsDefault->mnRowSpan = 0; + mnLastToken = pInfo->nToken; + } + break; case RTF_CELLX: // closes cell default { mbNewDef = true; |