Kaydet (Commit) caf2f5ff authored tarafından László Németh's avatar László Németh

tdf#70234 DOCX: export tracked deletion of fields

Multiple runs of a field weren't exported as
tracked deletion, resulting bad DOCX export
with reappearing deleted fields in LO and
invalid document in MSO.

Change-Id: I2a1957371b78e0af60d8bf3944a1c28abe8ba0cc
Reviewed-on: https://gerrit.libreoffice.org/73438
Tested-by: Jenkins
Reviewed-by: 's avatarLászló Németh <nemeth@numbertext.org>
üst 166aafde
...@@ -852,8 +852,14 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTrackChangesEmptyParagraphsInADeletion, ...@@ -852,8 +852,14 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTrackChangesEmptyParagraphsInADeletion,
DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf70234, "tdf70234.docx") DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf70234, "tdf70234.docx")
{ {
xmlDocPtr pXmlDoc = parseExport("word/document.xml"); xmlDocPtr pXmlDoc = parseExport("word/document.xml");
// import fields with tracked deletion // import field with tracked deletion
assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:del/w:r/w:fldChar"); assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:del/w:r[1]/w:fldChar");
// export multiple runs of a field with tracked deletion
assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:del/w:r", 6);
// export w:delInstrText
assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:del/w:r/w:delInstrText");
} }
DECLARE_OOXMLEXPORT_TEST(testTdf118691, "tdf118691.docx") DECLARE_OOXMLEXPORT_TEST(testTdf118691, "tdf118691.docx")
......
...@@ -1502,6 +1502,7 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool / ...@@ -1502,6 +1502,7 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool /
m_pSerializer->endElementNS( XML_w, XML_r ); m_pSerializer->endElementNS( XML_w, XML_r );
// if there is some redlining in the document, output it // if there is some redlining in the document, output it
// (except in the case of fields with multiple runs)
EndRedline( m_pRedlineData ); EndRedline( m_pRedlineData );
// enclose in a sdt block, if necessary: if one is already started, then don't do it for now // enclose in a sdt block, if necessary: if one is already started, then don't do it for now
...@@ -1543,7 +1544,10 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool / ...@@ -1543,7 +1544,10 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool /
WritePendingPlaceholder(); WritePendingPlaceholder();
m_pRedlineData = nullptr; if ( !m_bWritingField )
{
m_pRedlineData = nullptr;
}
if ( m_closeHyperlinkInThisRun ) if ( m_closeHyperlinkInThisRun )
{ {
...@@ -1602,6 +1606,11 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool / ...@@ -1602,6 +1606,11 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool /
} }
} }
if ( m_pRedlineData )
{
EndRedline( m_pRedlineData );
m_pRedlineData = nullptr;
}
DoWriteBookmarksStart(m_rFinalBookmarksStart); DoWriteBookmarksStart(m_rFinalBookmarksStart);
DoWriteBookmarksEnd(m_rFinalBookmarksEnd); DoWriteBookmarksEnd(m_rFinalBookmarksEnd);
...@@ -1908,6 +1917,8 @@ void DocxAttributeOutput::StartField_Impl( const SwTextNode* pNode, sal_Int32 nP ...@@ -1908,6 +1917,8 @@ void DocxAttributeOutput::StartField_Impl( const SwTextNode* pNode, sal_Int32 nP
} }
else else
{ {
m_bWritingField = true;
// Write the field start // Write the field start
if ( rInfos.pField && (rInfos.pField->Which() == SwFieldIds::DateTime) && rInfos.pField->GetSubType() & FIXEDFLD ) if ( rInfos.pField && (rInfos.pField->Which() == SwFieldIds::DateTime) && rInfos.pField->GetSubType() & FIXEDFLD )
{ {
...@@ -1946,9 +1957,13 @@ void DocxAttributeOutput::DoWriteCmd( const OUString& rCmd ) ...@@ -1946,9 +1957,13 @@ void DocxAttributeOutput::DoWriteCmd( const OUString& rCmd )
m_aSeqBookmarksNames[sSeqName].push_back(m_sLastOpenedBookmark); m_aSeqBookmarksNames[sSeqName].push_back(m_sLastOpenedBookmark);
} }
// Write the Field command // Write the Field command
m_pSerializer->startElementNS(XML_w, XML_instrText); sal_Int32 nTextToken = XML_instrText;
if ( m_pRedlineData && m_pRedlineData->GetType() == RedlineType::Delete )
nTextToken = XML_delInstrText;
m_pSerializer->startElementNS(XML_w, nTextToken);
m_pSerializer->writeEscaped( rCmd ); m_pSerializer->writeEscaped( rCmd );
m_pSerializer->endElementNS( XML_w, XML_instrText ); m_pSerializer->endElementNS( XML_w, nTextToken );
} }
...@@ -2147,6 +2162,7 @@ void DocxAttributeOutput::EndField_Impl( const SwTextNode* pNode, sal_Int32 nPos ...@@ -2147,6 +2162,7 @@ void DocxAttributeOutput::EndField_Impl( const SwTextNode* pNode, sal_Int32 nPos
// Write the Field end // Write the Field end
if ( rInfos.bClose ) if ( rInfos.bClose )
{ {
m_bWritingField = false;
m_pSerializer->startElementNS(XML_w, XML_r); m_pSerializer->startElementNS(XML_w, XML_r);
DoWriteFieldRunProperties( pNode, nPos ); DoWriteFieldRunProperties( pNode, nPos );
m_pSerializer->singleElementNS(XML_w, XML_fldChar, FSNS(XML_w, XML_fldCharType), "end"); m_pSerializer->singleElementNS(XML_w, XML_fldChar, FSNS(XML_w, XML_fldCharType), "end");
...@@ -3041,7 +3057,7 @@ void DocxAttributeOutput::StartRedline( const SwRedlineData * pRedlineData ) ...@@ -3041,7 +3057,7 @@ void DocxAttributeOutput::StartRedline( const SwRedlineData * pRedlineData )
void DocxAttributeOutput::EndRedline( const SwRedlineData * pRedlineData ) void DocxAttributeOutput::EndRedline( const SwRedlineData * pRedlineData )
{ {
if ( !pRedlineData ) if ( !pRedlineData || m_bWritingField )
return; return;
switch ( pRedlineData->GetType() ) switch ( pRedlineData->GetType() )
...@@ -9082,6 +9098,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, const FSHelperPtr ...@@ -9082,6 +9098,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, const FSHelperPtr
m_bRunTextIsOn( false ), m_bRunTextIsOn( false ),
m_bWritingHeaderFooter( false ), m_bWritingHeaderFooter( false ),
m_bAnchorLinkedToNode(false), m_bAnchorLinkedToNode(false),
m_bWritingField( false ),
m_bPreventDoubleFieldsHandling( false ), m_bPreventDoubleFieldsHandling( false ),
m_sFieldBkm( ), m_sFieldBkm( ),
m_nNextBookmarkId( 0 ), m_nNextBookmarkId( 0 ),
......
...@@ -757,6 +757,9 @@ private: ...@@ -757,6 +757,9 @@ private:
bool m_bWritingHeaderFooter; bool m_bWritingHeaderFooter;
bool m_bAnchorLinkedToNode; bool m_bAnchorLinkedToNode;
/// Flag indicating that multiple runs of a field are being written
bool m_bWritingField;
/// Field data to remember in the text run /// Field data to remember in the text run
bool m_bPreventDoubleFieldsHandling; bool m_bPreventDoubleFieldsHandling;
std::vector< FieldInfos > m_Fields; std::vector< FieldInfos > m_Fields;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment