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:
@@ -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;
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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 );
|
||||
|
@@ -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());
|
||||
|
@@ -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 );
|
||||
|
@@ -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 );
|
||||
|
||||
|
@@ -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; }
|
||||
|
@@ -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();
|
||||
|
Reference in New Issue
Block a user