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

Sujith Sudhakaran sudhakaran.sujith at yahoo.com
Mon May 18 03:32:58 PDT 2015


 oox/source/export/shapes.cxx |  133 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 124 insertions(+), 9 deletions(-)

New commits:
commit e4fab06d82299054ddd46c7d925d300cd3d0a17d
Author: Sujith Sudhakaran <sudhakaran.sujith at yahoo.com>
Date:   Tue Apr 7 08:56:04 2015 +0530

    tdf#90245: Support for table merge cell export.
    
    Previously, the merged cells were not getting saved. Also it
    was leading to corruption if saved as pptx.
    While on opening the round-trip file of odf extension which has
    merged cells, merged cell properties not used to persist.
    
    In the current implementation XMergeableCell class was not having
    any property to identify the parent cell of a merged cell.
    
    This CL includes:
    - Fixed the above scenario for export of file
    - Now, the odf file with table merged cells persists its property
    - MS doesn't complain for any corruption after export an odf file
    as pptx
    TODO: Writing a UT seems to be tricky for this change.
          Need to analyze and will raise the UT in separate CL.
    
    Change-Id: I32f9daf77312a0ef3f291f36aef372671554c56d
    Reviewed-on: https://gerrit.libreoffice.org/15282
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 76d57fd..1dce98c 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -1014,6 +1014,10 @@ void ShapeExport::WriteTable( Reference< XShape > rXShape  )
 
         mpFS->endElementNS( XML_a, XML_tblGrid );
 
+        // map for holding the transpose index of the merged cells and pair<parentTransposeIndex, parentCell>
+        typedef std::unordered_map<sal_Int32, std::pair<sal_Int32, Reference< XMergeableCell> > > transposeTableMap;
+        transposeTableMap mergedCellMap;
+
         for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ )
         {
             Reference< XPropertySet > xRowPropSet( xRows->getByIndex( nRow ), UNO_QUERY_THROW );
@@ -1022,21 +1026,132 @@ void ShapeExport::WriteTable( Reference< XShape > rXShape  )
             xRowPropSet->getPropertyValue( "Height" ) >>= nRowHeight;
 
             mpFS->startElementNS( XML_a, XML_tr, XML_h, I64S( oox::drawingml::convertHmmToEmu( nRowHeight ) ), FSEND );
-
             for( sal_Int32 nColumn = 0; nColumn < nColumnCount; nColumn++ )
             {
-                Reference< XMergeableCell > xCell( xTable->getCellByPosition( nColumn, nRow ), UNO_QUERY_THROW );
-                if ( !xCell->isMerged() )
+                Reference< XMergeableCell > xCell( xTable->getCellByPosition( nColumn, nRow ),
+                                                   UNO_QUERY_THROW );
+                sal_Int32 transposedIndexofCell = (nRow * nColumnCount) + nColumn;
+
+                if(xCell->getColumnSpan() > 1 && xCell->getRowSpan() > 1)
                 {
-                    mpFS->startElementNS( XML_a, XML_tc, FSEND );
+                    // having both : horizontal and vertical merge
+                    mpFS->startElementNS(XML_a, XML_tc, XML_gridSpan,
+                                         I32S(xCell->getColumnSpan()),
+                                         XML_rowSpan, I32S(xCell->getRowSpan()),
+                                         FSEND);
+                    // since, XMergeableCell doesn't have the information about
+                    // cell having hMerge or vMerge.
+                    // So, Populating the merged cell map in-order to use it to
+                    // decide the attribute for the individual cell.
+                    for(sal_Int32 columnIndex = nColumn; columnIndex < nColumn+xCell->getColumnSpan(); ++columnIndex)
+                    {
+                        for(sal_Int32 rowIndex = nRow; rowIndex < nRow+xCell->getRowSpan(); ++rowIndex)
+                        {
+                            sal_Int32 transposeIndexForMergeCell =
+                                (rowIndex * nColumnCount) + columnIndex;
+                            mergedCellMap[transposeIndexForMergeCell] =
+                                std::make_pair(transposedIndexofCell, xCell);
+                        }
+                    }
 
-                    WriteTextBox( xCell, XML_a );
+                }
+                else if(xCell->getColumnSpan() > 1)
+                {
+                    // having : horizontal merge
+                    mpFS->startElementNS(XML_a, XML_tc, XML_gridSpan,
+                                         I32S(xCell->getColumnSpan()), FSEND);
+                    for(sal_Int32 columnIndex = nColumn; columnIndex < xCell->getColumnSpan(); ++columnIndex) {
+                        sal_Int32 transposeIndexForMergeCell = (nRow*nColumnCount) + columnIndex;
+                        mergedCellMap[transposeIndexForMergeCell] =
+                            std::make_pair(transposedIndexofCell, xCell);
+                    }
+                }
+                else if(xCell->getRowSpan() > 1)
+                {
+                    // having : vertical merge
+                    mpFS->startElementNS(XML_a, XML_tc, XML_rowSpan,
+                                         I32S(xCell->getRowSpan()), FSEND);
+
+                    for(sal_Int32 rowIndex = nRow; rowIndex < xCell->getRowSpan(); ++rowIndex) {
+                        sal_Int32 transposeIndexForMergeCell = (rowIndex*nColumnCount) + nColumn;
+                        mergedCellMap[transposeIndexForMergeCell] =
+                            std::make_pair(transposedIndexofCell, xCell);
+                    }
+                }
+                else
+                {
+                    // now, the cell can be an independent cell or
+                    // it can be a cell which is been merged to some parent cell
+                    if(!xCell->isMerged())
+                    {
+                        // independent cell
+                        mpFS->startElementNS( XML_a, XML_tc, FSEND );
+                    }
+                    else
+                    {
+                        // it a merged cell to some parent cell
+                        // find the parent cell for the current cell at hand
+                        transposeTableMap::iterator it = mergedCellMap.find(transposedIndexofCell);
+                        if(it != mergedCellMap.end())
+                        {
+                            sal_Int32 transposeIndexOfParent = it->second.first;
+                            Reference< XMergeableCell > parentCell = it->second.second;
+                            // finding the row and column index for the parent cell from transposed index
+                            sal_Int32 parentColumnIndex = transposeIndexOfParent % nColumnCount;
+                            sal_Int32 parentRowIndex = transposeIndexOfParent / nColumnCount;
+                            if(nColumn == parentColumnIndex)
+                            {
+                                // the cell is vertical merge and it might have gridspan
+                                if(parentCell->getColumnSpan() > 1)
+                                {
+                                    // vMerge and has gridSpan
+                                    mpFS->startElementNS( XML_a, XML_tc,
+                                                          XML_vMerge, I32S(1),
+                                                          XML_gridSpan, I32S(xCell->getColumnSpan()),
+                                                          FSEND );
+                                }
+                                else
+                                {
+                                    // only vMerge
+                                    mpFS->startElementNS( XML_a, XML_tc,
+                                                          XML_vMerge, I32S(1), FSEND );
+                                }
+                            }
+                            else if(nRow == parentRowIndex)
+                            {
+                                // the cell is horizontal merge and it might have rowspan
+                                if(parentCell->getRowSpan() > 1)
+                                {
+                                    // hMerge and has rowspan
+                                    mpFS->startElementNS( XML_a, XML_tc,
+                                                          XML_hMerge, I32S(1),
+                                                          XML_rowSpan, I32S(xCell->getRowSpan()),
+                                                          FSEND );
+                                }
+                                else
+                                {
+                                    // only hMerge
+                                    mpFS->startElementNS( XML_a, XML_tc,
+                                                          XML_hMerge, I32S(1), FSEND );
+                                }
+                            }
+                            else
+                            {
+                                // has hMerge and vMerge
+                                mpFS->startElementNS( XML_a, XML_tc,
+                                                      XML_vMerge, I32S(1),
+                                                      XML_hMerge, I32S(1),
+                                                      FSEND );
+                            }
+                        }
+                    }
+                }
+                WriteTextBox( xCell, XML_a );
 
-                    Reference< XPropertySet > xCellPropSet(xCell, UNO_QUERY_THROW);
-                    WriteTableCellProperties(xCellPropSet);
+                Reference< XPropertySet > xCellPropSet(xCell, UNO_QUERY_THROW);
+                WriteTableCellProperties(xCellPropSet);
 
-                    mpFS->endElementNS( XML_a, XML_tc );
-                }
+                mpFS->endElementNS( XML_a, XML_tc );
             }
 
             mpFS->endElementNS( XML_a, XML_tr );


More information about the Libreoffice-commits mailing list