summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2019-06-04 13:06:33 +0200
committerLászló Németh <nemeth@numbertext.org>2019-06-04 14:09:31 +0200
commitcaf2f5fff39caf06204f71d0c2276b415ef047c3 (patch)
tree9d279c1294420a052e070270af52a97a007e0765 /sw
parent166aafde5b716dfeb5325e7d1bee1c163ab56b12 (diff)
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>
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport11.cxx10
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx25
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx3
3 files changed, 32 insertions, 6 deletions
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
index f7e69073085c..3864ecede42f 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
@@ -852,8 +852,14 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTrackChangesEmptyParagraphsInADeletion,
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 472649c7585a..5a0b1708c6f5 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -1502,6 +1502,7 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool /
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 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool /
WritePendingPlaceholder();
- m_pRedlineData = nullptr;
+ if ( !m_bWritingField )
+ {
+ m_pRedlineData = nullptr;
+ }
if ( m_closeHyperlinkInThisRun )
{
@@ -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);
DoWriteBookmarksEnd(m_rFinalBookmarksEnd);
@@ -1908,6 +1917,8 @@ void DocxAttributeOutput::StartField_Impl( const SwTextNode* pNode, sal_Int32 nP
}
else
{
+ m_bWritingField = true;
+
// Write the field start
if ( rInfos.pField && (rInfos.pField->Which() == SwFieldIds::DateTime) && rInfos.pField->GetSubType() & FIXEDFLD )
{
@@ -1946,9 +1957,13 @@ void DocxAttributeOutput::DoWriteCmd( const OUString& rCmd )
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 @@ void DocxAttributeOutput::EndField_Impl( const SwTextNode* pNode, sal_Int32 nPos
// 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::StartRedline( const SwRedlineData * pRedlineData )
void DocxAttributeOutput::EndRedline( const SwRedlineData * pRedlineData )
{
- if ( !pRedlineData )
+ if ( !pRedlineData || m_bWritingField )
return;
switch ( pRedlineData->GetType() )
@@ -9082,6 +9098,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, const FSHelperPtr
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 2ea64b8f207b..647a73e315c5 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -757,6 +757,9 @@ private:
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;