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>
(cherry picked from commit caf2f5fff39caf06204f71d0c2276b415ef047c3)
Reviewed-on: https://gerrit.libreoffice.org/73539
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;