Export redline 'paragraph formatting changes' back to DOCX

This patch adds support for the export of any redline of type
'paragraph formatting changes' properties that were imported from
a DOCX file under the 'pPrChange'->'pPr' XML node.

Reviewed on:
	https://gerrit.libreoffice.org/6993

Change-Id: Ieea5bbb219f444e382f22948944e038bb661ec7c
This commit is contained in:
Adam Co
2013-12-08 17:14:14 +02:00
committed by Miklos Vajna
parent 0351b59aea
commit e52f14efaa
10 changed files with 128 additions and 18 deletions

View File

@@ -64,6 +64,7 @@ namespace nsRedlineType_t
const RedlineType_t REDLINE_FORMAT = 0x2;// Attributes have been applied.
const RedlineType_t REDLINE_TABLE = 0x3;// Table structure has been altered.
const RedlineType_t REDLINE_FMTCOLL = 0x4;// Style has been altered (Autoformat!).
const RedlineType_t REDLINE_PARAGRAPH_FORMAT = 0x5;// Paragraph attributes have been changed
// When larger than 128, flags can be inserted.
const RedlineType_t REDLINE_NO_FLAG_MASK = 0x7F;

View File

@@ -1184,6 +1184,8 @@ void makeRedline( SwPaM& rPaM,
eType = nsRedlineType_t::REDLINE_FORMAT;
else if ( rRedlineType == "TextTable" )
eType = nsRedlineType_t::REDLINE_TABLE;
else if ( rRedlineType == "ParagraphFormat" )
eType = nsRedlineType_t::REDLINE_PARAGRAPH_FORMAT;
else if( !rRedlineType.startsWith( "Insert" ))
throw lang::IllegalArgumentException();

View File

@@ -160,7 +160,7 @@ public:
virtual void StartParagraphProperties() = 0;
/// Called after we end outputting the attributes.
virtual void EndParagraphProperties() = 0;
virtual void EndParagraphProperties( const SwRedlineData* pRedlineData ) = 0;
/// Empty paragraph.
virtual void EmptyParagraph() = 0;

View File

@@ -676,8 +676,12 @@ void DocxAttributeOutput::WriteCollectedParagraphProperties()
}
}
void DocxAttributeOutput::EndParagraphProperties()
void DocxAttributeOutput::EndParagraphProperties( const SwRedlineData* pRedlineData )
{
// Call the 'Redline' function. This will add redline (change-tracking) information that regards to paragraph properties.
// This includes changes like 'Bold', 'Underline', 'Strikethrough' etc.
Redline( pRedlineData );
WriteCollectedParagraphProperties();
// Merge the marks for the ordered elements
@@ -1618,10 +1622,62 @@ void DocxAttributeOutput::Redline( const SwRedlineData* pRedline)
}
}
}
m_pSerializer->endElementNS( XML_w, XML_rPrChange );
break;
case nsRedlineType_t::REDLINE_PARAGRAPH_FORMAT:
m_pSerializer->startElementNS( XML_w, XML_pPrChange,
FSNS( XML_w, XML_id ), aId.getStr(),
FSNS( XML_w, XML_author ), aAuthor.getStr(),
FSNS( XML_w, XML_date ), aDate.getStr(),
FSEND );
// Check if there is any extra data stored in the redline object
if (pRedline->GetExtraData())
{
const SwRedlineExtraData* pExtraData = pRedline->GetExtraData();
const SwRedlineExtraData_FormattingChanges* pFormattingChanges = dynamic_cast<const SwRedlineExtraData_FormattingChanges*>(pExtraData);
// Check if the extra data is of type 'formatting changes'
if (pFormattingChanges)
{
// Get the item set that holds all the changes properties
const SfxItemSet *pChangesSet = pFormattingChanges->GetItemSet();
if (pChangesSet)
{
m_pSerializer->mark();
m_pSerializer->startElementNS( XML_w, XML_pPr, FSEND );
// The 'm_pFlyAttrList', 'm_pParagraphSpacingAttrList' are used to hold information
// that should be collected by different properties in the core, and are all flushed together
// to the DOCX when the function 'WriteCollectedParagraphProperties' gets called.
// So we need to store the current status of these lists, so that we can revert back to them when
// we are done exporting the redline attributes.
::sax_fastparser::FastAttributeList *pFlyAttrList_Original = m_pFlyAttrList;
::sax_fastparser::FastAttributeList *pParagraphSpacingAttrList_Original = m_pParagraphSpacingAttrList;
m_pFlyAttrList = NULL;
m_pParagraphSpacingAttrList = NULL;
// Output the redline item set
m_rExport.OutputItemSet( *pChangesSet, true, false, i18n::ScriptType::LATIN, m_rExport.mbExportModeRTF );
// Write the collected paragraph properties that are stored in 'm_pFlyAttrList', 'm_pParagraphSpacingAttrList'
WriteCollectedParagraphProperties();
// Revert back the original values that were stored in 'm_pFlyAttrList', 'm_pParagraphSpacingAttrList'
m_pFlyAttrList = pFlyAttrList_Original;
m_pParagraphSpacingAttrList = pParagraphSpacingAttrList_Original;
m_pSerializer->endElementNS( XML_w, XML_pPr );
m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
}
}
}
m_pSerializer->endElementNS( XML_w, XML_pPrChange );
break;
default:
SAL_WARN("sw.ww8", "Unhandled redline type for export " << pRedline->GetType());
break;

View File

@@ -141,7 +141,7 @@ public:
virtual void StartParagraphProperties();
/// Called after we end outputting the attributes.
virtual void EndParagraphProperties();
virtual void EndParagraphProperties( const SwRedlineData* pRedlineData );
/// Start of the text run.
virtual void StartRun( const SwRedlineData* pRedlineData, bool bSingleEmptyRun = false );

View File

@@ -388,7 +388,7 @@ void RtfAttributeOutput::StartParagraphProperties()
m_aSectionHeaders.append(aPar.makeStringAndClear());
}
void RtfAttributeOutput::EndParagraphProperties()
void RtfAttributeOutput::EndParagraphProperties( const SwRedlineData* /*pRedlineData*/ )
{
SAL_INFO("sw.rtf", OSL_THIS_FUNC);
m_aStyles.append(m_aStylesEnd.makeStringAndClear());

View File

@@ -57,7 +57,7 @@ public:
virtual void StartParagraphProperties();
/// Called after we end outputting the attributes.
virtual void EndParagraphProperties();
virtual void EndParagraphProperties( const SwRedlineData* pRedlineData );
/// Start of the text run.
virtual void StartRun( const SwRedlineData* pRedlineData, bool bSingleEmptyRun = false );

View File

@@ -1206,7 +1206,34 @@ bool SwWW8AttrIter::IsRedlineAtEnd( sal_Int32 nEnd ) const
return false;
}
const SwRedlineData* SwWW8AttrIter::GetRedline( sal_Int32 nPos )
const SwRedlineData* SwWW8AttrIter::GetParagraphLevelRedline( )
{
pCurRedline = NULL;
// ToDo : this is not the most ideal ... should start maybe from 'nCurRedlinePos'
for( sal_uInt16 nRedlinePos = 0; nRedlinePos < m_rExport.pDoc->GetRedlineTbl().size(); ++nRedlinePos )
{
const SwRedline* pRedl = m_rExport.pDoc->GetRedlineTbl()[ nRedlinePos ];
const SwPosition* pCheckedStt = pRedl->Start();
if( pCheckedStt->nNode == rNd )
{
// Maybe add here a check that also the start & end of the redline is the entire paragraph
// Only return if this is a paragraph formatting redline
if (pRedl->GetType() == nsRedlineType_t::REDLINE_PARAGRAPH_FORMAT)
{
// write data of this redline
pCurRedline = pRedl;
return &( pCurRedline->GetRedlineData() );
}
}
}
return NULL;
}
const SwRedlineData* SwWW8AttrIter::GetRunLevelRedline( sal_Int32 nPos )
{
if( pCurRedline )
{
@@ -1219,8 +1246,19 @@ const SwRedlineData* SwWW8AttrIter::GetRedline( sal_Int32 nPos )
}
else
{
// write data of current redline
return &( pCurRedline->GetRedlineData() );
switch( pCurRedline->GetType() )
{
case nsRedlineType_t::REDLINE_INSERT:
case nsRedlineType_t::REDLINE_DELETE:
case nsRedlineType_t::REDLINE_FORMAT:
// write data of this redline
return &( pCurRedline->GetRedlineData() );
break;
default:
break;
};
pCurRedline = 0;
++nCurRedlinePos;
}
}
@@ -1243,15 +1281,26 @@ const SwRedlineData* SwWW8AttrIter::GetRedline( sal_Int32 nPos )
{
if( pStt->nContent.GetIndex() == nPos )
{
// write data of this redline
pCurRedline = pRedl;
return &( pCurRedline->GetRedlineData() );
switch( pRedl->GetType() )
{
case nsRedlineType_t::REDLINE_INSERT:
case nsRedlineType_t::REDLINE_DELETE:
case nsRedlineType_t::REDLINE_FORMAT:
// write data of this redline
pCurRedline = pRedl;
return &( pCurRedline->GetRedlineData() );
break;
default:
break;
};
}
break;
}
}
else
{
break;
}
if( pEnd->nNode == rNd &&
pEnd->nContent.GetIndex() < nPos )
@@ -1823,7 +1872,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
pTextNodeInfoInner = pTextNodeInfo->getFirstInner();
do {
const SwRedlineData* pRedlineData = aAttrIter.GetRedline( nAktPos );
const SwRedlineData* pRedlineData = aAttrIter.GetRunLevelRedline( nAktPos );
sal_Int32 nNextAttr = GetNextPos( &aAttrIter, rNode, nAktPos );
// Is this the only run in this paragraph and it's empty?
@@ -2053,7 +2102,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
if ( bRedlineAtEnd )
{
AttrOutput().Redline( aAttrIter.GetRedline( nEnd ) );
AttrOutput().Redline( aAttrIter.GetRunLevelRedline( nEnd ) );
AttrOutput().OutputFKP();
}
}
@@ -2378,7 +2427,8 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
}
}
AttrOutput().EndParagraphProperties();
const SwRedlineData* pParagraphRedlineData = aAttrIter.GetParagraphLevelRedline( );
AttrOutput().EndParagraphProperties( pParagraphRedlineData );
AttrOutput().EndParagraph( pTextNodeInfoInner );

View File

@@ -1492,7 +1492,8 @@ public:
virtual const SfxPoolItem* HasTextItem( sal_uInt16 nWhich ) const;
virtual const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const;
int OutAttrWithRange(sal_Int32 nPos);
const SwRedlineData* GetRedline( sal_Int32 nPos );
const SwRedlineData* GetParagraphLevelRedline( );
const SwRedlineData* GetRunLevelRedline( sal_Int32 nPos );
void OutFlys(sal_Int32 nSwPos);
sal_Int32 WhereNext() const { return nAktSwPos; }

View File

@@ -42,7 +42,7 @@ public:
virtual void StartParagraphProperties() {}
/// Called after we end outputting the attributes.
virtual void EndParagraphProperties() {}
virtual void EndParagraphProperties( const SwRedlineData* /*pRedlineData*/ ) {}
/// Empty paragraph.
virtual void EmptyParagraph();