From 1f77a5e8d5bf8a7f1b7bd7206996d2b2efc59462 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 8 Feb 2012 16:49:57 +0100 Subject: n#203704 fix RTF export table output for subtables Older ODT files containing confused the RTF exporter. Add a few sanity checks to make sure the output is still valid. --- sw/source/filter/ww8/rtfattributeoutput.cxx | 28 ++++++++++++++++++++++++---- sw/source/filter/ww8/rtfattributeoutput.hxx | 6 ++++++ 2 files changed, 30 insertions(+), 4 deletions(-) (limited to 'sw') diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index 52d80fc619c9..875edfb7b221 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -251,13 +251,19 @@ void RtfAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextN { ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_nTableDepth ) ); OSL_ENSURE( pDeepInner, "TableNodeInfoInner not found"); - if ( pDeepInner && pDeepInner->getCell() == 0 ) + // Make sure we always start a row between ending one and starting a cell. + // In case of subtables, we may not get the first cell. + if ((pDeepInner && pDeepInner->getCell() == 0) || m_bTableRowEnded) + { + m_bTableRowEnded = false; StartTableRow( pDeepInner ); + } StartTableCell( pDeepInner ); } - if ( nRow == 0 && nCell == 0 ) + // Again, if depth was incremented, start a new table even if we skipped the first cell. + if ((nRow == 0 && nCell == 0) || (m_nTableDepth == 0 && pTextNodeInfo->getDepth())) { // Do we have to start the table? // [If we are at the rigth depth already, it means that we @@ -610,7 +616,10 @@ void RtfAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t rLR.GetLeft() - rLR.GetRight(); } SwTwips nTblSz = pFmt->GetFrmSize().GetWidth(); - for( sal_uInt16 i = 0; i < pRow->GetCells().Count(); i++ ) + // Not using m_nTableDepth, which is not yet incremented here. + sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth(); + m_aCells[nCurrentDepth] = pRow->GetCells().Count(); + for( sal_uInt16 i = 0; i < m_aCells[nCurrentDepth]; i++ ) { SwWriteTableCell *pCell = pRow->GetCells( )[ i ]; const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt(); @@ -906,6 +915,9 @@ void RtfAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pT // We'll write the table definition for nested tables later if ( nCurrentDepth > 1 ) return; + // Empty the previous row closing buffer before starting the new one, + // necessary for subtables. + m_rExport.Strm() << m_aAfterRuns.makeStringAndClear().getStr(); m_rExport.Strm() << m_aRowDefs.makeStringAndClear().getStr(); } } @@ -944,12 +956,17 @@ void RtfAttributeOutput::EndTableCell( ) m_bTableCellOpen = false; m_bTblAfterCell = true; m_bWroteCellInfo = false; + m_aCells[m_nTableDepth]--; } void RtfAttributeOutput::EndTableRow( ) { SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << m_nTableDepth << ")"); + // Trying to end the row without writing the required number of cells? Fill with empty ones. + for( sal_uInt16 i = 0; i < m_aCells[m_nTableDepth]; i++ ) + m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL); + if ( m_nTableDepth > 1 ) { m_aAfterRuns.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_NESTTABLEPROPRS); @@ -971,6 +988,7 @@ void RtfAttributeOutput::EndTableRow( ) } m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ROW).append(OOO_STRING_SVTOOLS_RTF_PARD); } + m_bTableRowEnded = true; } void RtfAttributeOutput::EndTable() @@ -2997,7 +3015,9 @@ RtfAttributeOutput::RtfAttributeOutput( RtfExport &rExport ) m_bBufferSectionHeaders( false ), m_bLastTable( true ), m_bWroteCellInfo( false ), - m_bHadFieldResult( false ) + m_bHadFieldResult( false ), + m_bTableRowEnded( false ), + m_aCells() { SAL_INFO("sw.rtf", OSL_THIS_FUNC); } diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx index 8766c5a9e697..eea4b8c70d59 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.hxx +++ b/sw/source/filter/ww8/rtfattributeoutput.hxx @@ -533,6 +533,12 @@ private: * If we had a field result in the URL. */ bool m_bHadFieldResult; + + /// If we ended a table row without starting a new one. + bool m_bTableRowEnded; + + /// Number of cells from the table definition, by depth. + std::map m_aCells; public: RtfAttributeOutput( RtfExport &rExport ); -- cgit