From 8c5b4bb03cdf3fd5e794cfd8de68b00eb5de48fb Mon Sep 17 00:00:00 2001 From: Adam Co Date: Thu, 12 Dec 2013 17:42:50 +0200 Subject: Support DOCX exporting 'Track Changes - Deleted Paragraph Mark' This patch adds support for the DOCX exporter to export the 'Track Changes' of type 'Deleted Paragraph Marker'. Conflicts: sw/source/filter/ww8/docxattributeoutput.cxx Reviewed on: https://gerrit.libreoffice.org/7061 Change-Id: Ia4f5933c9058d74fe8f47fc578747be972774340 --- sw/source/filter/ww8/attributeoutputbase.hxx | 5 ++- sw/source/filter/ww8/docxattributeoutput.cxx | 58 +++++++++++++++++----------- sw/source/filter/ww8/docxattributeoutput.hxx | 8 ++-- sw/source/filter/ww8/rtfattributeoutput.cxx | 2 +- sw/source/filter/ww8/rtfattributeoutput.hxx | 2 +- sw/source/filter/ww8/wrtw8nds.cxx | 3 +- sw/source/filter/ww8/ww8atr.cxx | 44 +++++++++++++++++++++ sw/source/filter/ww8/ww8attributeoutput.hxx | 2 +- 8 files changed, 93 insertions(+), 31 deletions(-) diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx index be3615ae0594..73ec4fbab737 100644 --- a/sw/source/filter/ww8/attributeoutputbase.hxx +++ b/sw/source/filter/ww8/attributeoutputbase.hxx @@ -160,7 +160,7 @@ public: virtual void StartParagraphProperties() = 0; /// Called after we end outputting the attributes. - virtual void EndParagraphProperties( const SwRedlineData* pRedlineData ) = 0; + virtual void EndParagraphProperties( const SwRedlineData* pRedlineData, const SwRedlineData* pRedlineParagraphMarkerDeleted ) = 0; /// Empty paragraph. virtual void EmptyParagraph() = 0; @@ -635,6 +635,9 @@ public: /// Exports the definition (image, size) of a single numbering picture bullet. virtual void BulletDefinition(int /*nId*/, const Graphic& /*rGraphic*/, Size /*aSize*/) {} + // Returns whether or not the 'SwTxtNode' has a paragraph marker deleted (using 'track changes') + virtual const SwRedlineData* IsParagraphMarkerDeleted( const SwTxtNode& rNode ); + }; #endif // INCLUDED_SW_SOURCE_FILTER_WW8_ATTRIBUTEOUTPUTBASE_HXX diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 01d8afddb47e..f113f3926434 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -676,7 +676,7 @@ void DocxAttributeOutput::WriteCollectedParagraphProperties() } } -void DocxAttributeOutput::EndParagraphProperties( const SwRedlineData* pRedlineData ) +void DocxAttributeOutput::EndParagraphProperties( const SwRedlineData* pRedlineData, const SwRedlineData* pRedlineParagraphMarkerDeleted ) { // Call the 'Redline' function. This will add redline (change-tracking) information that regards to paragraph properties. // This includes changes like 'Bold', 'Underline', 'Strikethrough' etc. @@ -684,6 +684,21 @@ void DocxAttributeOutput::EndParagraphProperties( const SwRedlineData* pRedlineD WriteCollectedParagraphProperties(); + // Write 'Paragraph Mark' properties + bool bIsParagraphMarkProperties = false; // In future - get the 'paragraph marker' properties as a parameter + if (bIsParagraphMarkProperties || pRedlineParagraphMarkerDeleted) + { + m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND ); + + if ( pRedlineParagraphMarkerDeleted ) + { + StartRedline( pRedlineParagraphMarkerDeleted ); + EndRedline( pRedlineParagraphMarkerDeleted ); + } + + m_pSerializer->endElementNS( XML_w, XML_rPr ); + } + // Merge the marks for the ordered elements m_pSerializer->mergeTopMarks( ); @@ -793,7 +808,7 @@ void DocxAttributeOutput::EndRun() } // if there is some redlining in the document, output it - StartRedline(); + StartRedline( m_pRedlineData ); DoWriteBookmarks( ); WriteCommentRanges(); @@ -811,7 +826,9 @@ void DocxAttributeOutput::EndRun() WritePendingPlaceholder(); // if there is some redlining in the document, output it - EndRedline(); + EndRedline( m_pRedlineData ); + + m_pRedlineData = NULL; if ( m_closeHyperlinkInThisRun ) { @@ -1551,17 +1568,17 @@ void DocxAttributeOutput::FieldVanish( const OUString& rTxt, ww::eField eType ) // The difference between 'Redline' and 'StartRedline'+'EndRedline' is that: // 'Redline' is used for tracked changes of formatting information of a run like Bold, Underline. (the '' is inside the 'run' node) // 'StartRedline' is used to output tracked changes of run insertion and deletion (the run is inside the '' node) -void DocxAttributeOutput::Redline( const SwRedlineData* pRedline) +void DocxAttributeOutput::Redline( const SwRedlineData* pRedlineData) { - if ( !pRedline ) + if ( !pRedlineData ) return; - OString aId( OString::number( pRedline->GetSeqNo() ) ); - const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( pRedline->GetAuthor() ) ); + OString aId( OString::number( pRedlineData->GetSeqNo() ) ); + const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( pRedlineData->GetAuthor() ) ); OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) ); - OString aDate( DateTimeToOString( pRedline->GetTimeStamp() ) ); + OString aDate( DateTimeToOString( pRedlineData->GetTimeStamp() ) ); - switch( pRedline->GetType() ) + switch( pRedlineData->GetType() ) { case nsRedlineType_t::REDLINE_INSERT: break; @@ -1577,9 +1594,9 @@ void DocxAttributeOutput::Redline( const SwRedlineData* pRedline) FSEND ); // Check if there is any extra data stored in the redline object - if (pRedline->GetExtraData()) + if (pRedlineData->GetExtraData()) { - const SwRedlineExtraData* pExtraData = pRedline->GetExtraData(); + const SwRedlineExtraData* pExtraData = pRedlineData->GetExtraData(); const SwRedlineExtraData_FormattingChanges* pFormattingChanges = dynamic_cast(pExtraData); // Check if the extra data is of type 'formatting changes' @@ -1633,9 +1650,9 @@ void DocxAttributeOutput::Redline( const SwRedlineData* pRedline) FSEND ); // Check if there is any extra data stored in the redline object - if (pRedline->GetExtraData()) + if (pRedlineData->GetExtraData()) { - const SwRedlineExtraData* pExtraData = pRedline->GetExtraData(); + const SwRedlineExtraData* pExtraData = pRedlineData->GetExtraData(); const SwRedlineExtraData_FormattingChanges* pFormattingChanges = dynamic_cast(pExtraData); // Check if the extra data is of type 'formatting changes' @@ -1679,7 +1696,7 @@ void DocxAttributeOutput::Redline( const SwRedlineData* pRedline) break; default: - SAL_WARN("sw.ww8", "Unhandled redline type for export " << pRedline->GetType()); + SAL_WARN("sw.ww8", "Unhandled redline type for export " << pRedlineData->GetType()); break; } } @@ -1687,11 +1704,10 @@ void DocxAttributeOutput::Redline( const SwRedlineData* pRedline) // The difference between 'Redline' and 'StartRedline'+'EndRedline' is that: // 'Redline' is used for tracked changes of formatting information of a run like Bold, Underline. (the '' is inside the 'run' node) // 'StartRedline' is used to output tracked changes of run insertion and deletion (the run is inside the '' node) -void DocxAttributeOutput::StartRedline() +void DocxAttributeOutput::StartRedline( const SwRedlineData * pRedlineData ) { - if ( !m_pRedlineData ) + if ( !pRedlineData ) return; - const SwRedlineData* pRedlineData = m_pRedlineData; // FIXME check if it's necessary to travel over the Next()'s in pRedlineData @@ -1727,12 +1743,12 @@ void DocxAttributeOutput::StartRedline() } } -void DocxAttributeOutput::EndRedline() +void DocxAttributeOutput::EndRedline( const SwRedlineData * pRedlineData ) { - if ( !m_pRedlineData ) + if ( !pRedlineData ) return; - switch ( m_pRedlineData->GetType() ) + switch ( pRedlineData->GetType() ) { case nsRedlineType_t::REDLINE_INSERT: m_pSerializer->endElementNS( XML_w, XML_ins ); @@ -1748,8 +1764,6 @@ void DocxAttributeOutput::EndRedline() default: break; } - - m_pRedlineData = NULL; } void DocxAttributeOutput::FormatDrop( const SwTxtNode& /*rNode*/, const SwFmtDrop& /*rSwFmtDrop*/, sal_uInt16 /*nStyle*/, ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, ww8::WW8TableNodeInfoInner::Pointer_t ) diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index 1fb24a289508..08ff82c47674 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -141,7 +141,7 @@ public: virtual void StartParagraphProperties(); /// Called after we end outputting the attributes. - virtual void EndParagraphProperties( const SwRedlineData* pRedlineData ); + virtual void EndParagraphProperties( const SwRedlineData* pRedlineData, const SwRedlineData* pRedlineParagraphMarkerDeleted ); /// Start of the text run. virtual void StartRun( const SwRedlineData* pRedlineData, bool bSingleEmptyRun = false ); @@ -193,13 +193,13 @@ public: /// Output redlining. /// /// Start of the tag that encloses the run, fills the info according to - /// the value of m_pRedlineData. - void StartRedline(); + /// the value of pRedlineData. + void StartRedline( const SwRedlineData * pRedlineData ); /// Output redlining. /// /// End of the tag that encloses the run. - void EndRedline(); + void EndRedline( const SwRedlineData * pRedlineData ); virtual void FormatDrop( const SwTxtNode& rNode, const SwFmtDrop& rSwFmtDrop, sal_uInt16 nStyle, ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ); diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index 9fd03b277295..3c58c9a56ead 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -388,7 +388,7 @@ void RtfAttributeOutput::StartParagraphProperties() m_aSectionHeaders.append(aPar.makeStringAndClear()); } -void RtfAttributeOutput::EndParagraphProperties( const SwRedlineData* /*pRedlineData*/ ) +void RtfAttributeOutput::EndParagraphProperties( const SwRedlineData* /*pRedlineData*/, const SwRedlineData* /*pRedlineParagraphMarkerDeleted*/ ) { SAL_INFO("sw.rtf", OSL_THIS_FUNC); m_aStyles.append(m_aStylesEnd.makeStringAndClear()); diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx index ab94dd71e9d4..3ca0665a9432 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.hxx +++ b/sw/source/filter/ww8/rtfattributeoutput.hxx @@ -57,7 +57,7 @@ public: virtual void StartParagraphProperties(); /// Called after we end outputting the attributes. - virtual void EndParagraphProperties( const SwRedlineData* pRedlineData ); + virtual void EndParagraphProperties( const SwRedlineData* pRedlineData, const SwRedlineData* pRedlineParagraphMarkerDeleted ); /// Start of the text run. virtual void StartRun( const SwRedlineData* pRedlineData, bool bSingleEmptyRun = false ); diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index 322eb0c86d04..718d9c02bb2f 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -2427,8 +2427,9 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode ) } } + const SwRedlineData* pRedlineParagraphMarkerDeleted = AttrOutput().IsParagraphMarkerDeleted( rNode ); const SwRedlineData* pParagraphRedlineData = aAttrIter.GetParagraphLevelRedline( ); - AttrOutput().EndParagraphProperties( pParagraphRedlineData ); + AttrOutput().EndParagraphProperties( pParagraphRedlineData, pRedlineParagraphMarkerDeleted ); AttrOutput().EndParagraph( pTextNodeInfoInner ); diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx index e0a64f80527b..55618665a1d2 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -5382,4 +5382,48 @@ void AttributeOutputBase::FormatCharBorder( const SvxBoxItem& rBox ) } } +/* + * This function is used to check if the current SwTxtNode (paragraph) has a redline object + * that signals that the paragraph marker is deleted. + * This is done by checking if the range (SwPaM) of the redline is : + * - Start = the last character of the current paragraph + * - End = the first character of the next paragraph + */ +const SwRedlineData* AttributeOutputBase::IsParagraphMarkerDeleted( const SwTxtNode& rNode ) +{ + // ToDo : this is not the most ideal ... should start maybe from 'nCurRedlinePos' + for( sal_uInt16 nRedlinePos = 0; nRedlinePos < GetExport().pDoc->GetRedlineTbl().size(); ++nRedlinePos ) + { + const SwRedline* pRedl = GetExport().pDoc->GetRedlineTbl()[ nRedlinePos ]; + + // Only check redlines that are of type 'Delete' + if ( pRedl->GetRedlineData().GetType() != nsRedlineType_t::REDLINE_DELETE ) + continue; + + const SwPosition* pCheckedStt = pRedl->Start(); + const SwPosition* pCheckedEnd = pRedl->End(); + + if( pCheckedStt->nNode == rNode ) + { + if ( !pCheckedEnd ) + continue; + + sal_uLong uStartNodeIndex = pCheckedStt->nNode.GetIndex(); + sal_uLong uStartCharIndex = pCheckedStt->nContent.GetIndex(); + sal_uLong uEndNodeIndex = pCheckedEnd->nNode.GetIndex(); + sal_uLong uEndCharIndex = pCheckedEnd->nContent.GetIndex(); + + // Maybe add here a check that also the start & end of the redline is the entire paragraph + if ( ( uStartNodeIndex == uEndNodeIndex - 1 ) && + ( uStartCharIndex == (sal_uLong)rNode.Len() ) && + ( uEndCharIndex == 0) + ) + { + return &( pRedl->GetRedlineData() ); + } + } + } + return NULL; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx index 20fae7e8d0c9..68dea48d13e4 100644 --- a/sw/source/filter/ww8/ww8attributeoutput.hxx +++ b/sw/source/filter/ww8/ww8attributeoutput.hxx @@ -42,7 +42,7 @@ public: virtual void StartParagraphProperties() {} /// Called after we end outputting the attributes. - virtual void EndParagraphProperties( const SwRedlineData* /*pRedlineData*/ ) {} + virtual void EndParagraphProperties( const SwRedlineData* /*pRedlineData*/, const SwRedlineData* /*pRedlineParagraphMarkerDeleted*/ ) {} /// Empty paragraph. virtual void EmptyParagraph(); -- cgit