n#203704 fix RTF export table output for subtables
Older ODT files containing <table:table table:is-sub-table="true"> confused the RTF exporter. Add a few sanity checks to make sure the output is still valid.
This commit is contained in:
@@ -251,13 +251,19 @@ void RtfAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextN
|
|||||||
{
|
{
|
||||||
ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_nTableDepth ) );
|
ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_nTableDepth ) );
|
||||||
OSL_ENSURE( pDeepInner, "TableNodeInfoInner not found");
|
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 );
|
StartTableRow( pDeepInner );
|
||||||
|
}
|
||||||
|
|
||||||
StartTableCell( 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?
|
// Do we have to start the table?
|
||||||
// [If we are at the rigth depth already, it means that we
|
// [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();
|
rLR.GetLeft() - rLR.GetRight();
|
||||||
}
|
}
|
||||||
SwTwips nTblSz = pFmt->GetFrmSize().GetWidth();
|
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 ];
|
SwWriteTableCell *pCell = pRow->GetCells( )[ i ];
|
||||||
const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
|
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
|
// We'll write the table definition for nested tables later
|
||||||
if ( nCurrentDepth > 1 )
|
if ( nCurrentDepth > 1 )
|
||||||
return;
|
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();
|
m_rExport.Strm() << m_aRowDefs.makeStringAndClear().getStr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -944,12 +956,17 @@ void RtfAttributeOutput::EndTableCell( )
|
|||||||
m_bTableCellOpen = false;
|
m_bTableCellOpen = false;
|
||||||
m_bTblAfterCell = true;
|
m_bTblAfterCell = true;
|
||||||
m_bWroteCellInfo = false;
|
m_bWroteCellInfo = false;
|
||||||
|
m_aCells[m_nTableDepth]--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtfAttributeOutput::EndTableRow( )
|
void RtfAttributeOutput::EndTableRow( )
|
||||||
{
|
{
|
||||||
SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << m_nTableDepth << ")");
|
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 )
|
if ( m_nTableDepth > 1 )
|
||||||
{
|
{
|
||||||
m_aAfterRuns.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_NESTTABLEPROPRS);
|
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_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ROW).append(OOO_STRING_SVTOOLS_RTF_PARD);
|
||||||
}
|
}
|
||||||
|
m_bTableRowEnded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtfAttributeOutput::EndTable()
|
void RtfAttributeOutput::EndTable()
|
||||||
@@ -2997,7 +3015,9 @@ RtfAttributeOutput::RtfAttributeOutput( RtfExport &rExport )
|
|||||||
m_bBufferSectionHeaders( false ),
|
m_bBufferSectionHeaders( false ),
|
||||||
m_bLastTable( true ),
|
m_bLastTable( true ),
|
||||||
m_bWroteCellInfo( false ),
|
m_bWroteCellInfo( false ),
|
||||||
m_bHadFieldResult( false )
|
m_bHadFieldResult( false ),
|
||||||
|
m_bTableRowEnded( false ),
|
||||||
|
m_aCells()
|
||||||
{
|
{
|
||||||
SAL_INFO("sw.rtf", OSL_THIS_FUNC);
|
SAL_INFO("sw.rtf", OSL_THIS_FUNC);
|
||||||
}
|
}
|
||||||
|
@@ -533,6 +533,12 @@ private:
|
|||||||
* If we had a field result in the URL.
|
* If we had a field result in the URL.
|
||||||
*/
|
*/
|
||||||
bool m_bHadFieldResult;
|
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<sal_uInt32,sal_uInt32> m_aCells;
|
||||||
public:
|
public:
|
||||||
RtfAttributeOutput( RtfExport &rExport );
|
RtfAttributeOutput( RtfExport &rExport );
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user