summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorSujith Sudhakaran <sudhakaran.sujith@yahoo.com>2015-04-07 08:56:04 +0530
committerCaolán McNamara <caolanm@redhat.com>2015-05-18 10:32:35 +0000
commite4fab06d82299054ddd46c7d925d300cd3d0a17d (patch)
treefb2c0ffe7e52a051cde7c01aeff9a7ff2aa0a207 /oox
parent75155bcf07d296352162d0b963493b4ba0238cca (diff)
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@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'oox')
-rw-r--r--oox/source/export/shapes.cxx133
1 files changed, 124 insertions, 9 deletions
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 76d57fd73b76..1dce98ced58c 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 );