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: László Németh <nemeth@numbertext.org>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
index f7e6907..3864ece 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
@@ -852,8 +852,14 @@
DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf70234, "tdf70234.docx")
{
xmlDocPtr pXmlDoc = parseExport("word/document.xml");
// import fields with tracked deletion
assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:del/w:r/w:fldChar");
// import field with tracked deletion
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")
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 472649c..5a0b170 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -1502,6 +1502,7 @@
m_pSerializer->endElementNS( XML_w, XML_r );
// if there is some redlining in the document, output it
// (except in the case of fields with multiple runs)
EndRedline( m_pRedlineData );
// enclose in a sdt block, if necessary: if one is already started, then don't do it for now
@@ -1543,7 +1544,10 @@
WritePendingPlaceholder();
m_pRedlineData = nullptr;
if ( !m_bWritingField )
{
m_pRedlineData = nullptr;
}
if ( m_closeHyperlinkInThisRun )
{
@@ -1602,6 +1606,11 @@
}
}
if ( m_pRedlineData )
{
EndRedline( m_pRedlineData );
m_pRedlineData = nullptr;
}
DoWriteBookmarksStart(m_rFinalBookmarksStart);
DoWriteBookmarksEnd(m_rFinalBookmarksEnd);
@@ -1908,6 +1917,8 @@
}
else
{
m_bWritingField = true;
// Write the field start
if ( rInfos.pField && (rInfos.pField->Which() == SwFieldIds::DateTime) && rInfos.pField->GetSubType() & FIXEDFLD )
{
@@ -1946,9 +1957,13 @@
m_aSeqBookmarksNames[sSeqName].push_back(m_sLastOpenedBookmark);
}
// 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->endElementNS( XML_w, XML_instrText );
m_pSerializer->endElementNS( XML_w, nTextToken );
}
@@ -2147,6 +2162,7 @@
// Write the Field end
if ( rInfos.bClose )
{
m_bWritingField = false;
m_pSerializer->startElementNS(XML_w, XML_r);
DoWriteFieldRunProperties( pNode, nPos );
m_pSerializer->singleElementNS(XML_w, XML_fldChar, FSNS(XML_w, XML_fldCharType), "end");
@@ -3041,7 +3057,7 @@
void DocxAttributeOutput::EndRedline( const SwRedlineData * pRedlineData )
{
if ( !pRedlineData )
if ( !pRedlineData || m_bWritingField )
return;
switch ( pRedlineData->GetType() )
@@ -9082,6 +9098,7 @@
m_bRunTextIsOn( false ),
m_bWritingHeaderFooter( false ),
m_bAnchorLinkedToNode(false),
m_bWritingField( false ),
m_bPreventDoubleFieldsHandling( false ),
m_sFieldBkm( ),
m_nNextBookmarkId( 0 ),
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 2ea64b8..647a73e 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -757,6 +757,9 @@
bool m_bWritingHeaderFooter;
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
bool m_bPreventDoubleFieldsHandling;
std::vector< FieldInfos > m_Fields;