[Libreoffice-commits] core.git: svx/source

Mark Hung marklh9 at gmail.com
Fri Feb 17 11:22:35 UTC 2017


 svx/source/table/tablertfimporter.cxx |   58 +++++++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 4 deletions(-)

New commits:
commit 2ca015c2d30fc135e054e3eb329c530adce6ad0d
Author: Mark Hung <marklh9 at gmail.com>
Date:   Wed Feb 15 23:24:28 2017 +0800

    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 at libreoffice.org>
    Reviewed-by: Mark Hung <marklh9 at gmail.com>

diff --git a/svx/source/table/tablertfimporter.cxx b/svx/source/table/tablertfimporter.cxx
index c78b120..f72dfe7 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;


More information about the Libreoffice-commits mailing list