From 4248d759744f83a68d334a8b347124719a2886a8 Mon Sep 17 00:00:00 2001 From: László Németh Date: Tue, 9 Jul 2019 14:49:14 +0200 Subject: tdf#126243 DOCX: export/reject tracked paragraph style change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix loss of rejection data (w:pStyle in w:pPrChange) during DOCX export, also fix missing rejection of tracked paragraph style changes during editing. Change-Id: I8e6dc4e6d14e3237ff82d370f55031dcc12418c0 Reviewed-on: https://gerrit.libreoffice.org/75303 Tested-by: Jenkins Reviewed-by: László Németh --- sw/inc/redline.hxx | 4 +++- sw/qa/extras/ooxmlexport/data/tdf120338.docx | Bin 0 -> 14898 bytes sw/qa/extras/ooxmlexport/ooxmlexport11.cxx | 7 +++++++ sw/qa/extras/uiwriter/uiwriter2.cxx | 11 +++++++++++ sw/source/core/doc/docredln.cxx | 28 ++++++--------------------- sw/source/core/unocore/unocrsrhelper.cxx | 23 ++++++++++++++++++++-- sw/source/filter/ww8/docxattributeoutput.cxx | 14 +++++++++++--- 7 files changed, 59 insertions(+), 28 deletions(-) create mode 100644 sw/qa/extras/ooxmlexport/data/tdf120338.docx (limited to 'sw') diff --git a/sw/inc/redline.hxx b/sw/inc/redline.hxx index 5cf4cba8dd08..7ae3af488d01 100644 --- a/sw/inc/redline.hxx +++ b/sw/inc/redline.hxx @@ -50,7 +50,7 @@ public: virtual bool operator == ( const SwRedlineExtraData& ) const; }; -class SwRedlineExtraData_FormatColl : public SwRedlineExtraData +class SW_DLLPUBLIC SwRedlineExtraData_FormatColl : public SwRedlineExtraData { OUString m_sFormatNm; std::unique_ptr m_pSet; @@ -63,7 +63,9 @@ public: virtual void Reject( SwPaM& rPam ) const override; virtual bool operator == ( const SwRedlineExtraData& ) const override; + const OUString& GetFormatName() const { return m_sFormatNm; } void SetItemSet( const SfxItemSet& rSet ); + SfxItemSet* GetItemSet( ) const { return m_pSet.get(); } }; class SwRedlineExtraData_Format : public SwRedlineExtraData diff --git a/sw/qa/extras/ooxmlexport/data/tdf120338.docx b/sw/qa/extras/ooxmlexport/data/tdf120338.docx new file mode 100644 index 000000000000..94e0023cea7f Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf120338.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx index 3fd1ae58f84b..25ed3a744e46 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx @@ -869,6 +869,13 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf115212, "tdf115212.docx") assertXPath(pXmlDoc, "//w:p[2]/w:del[1]/w:r[1]/w:fldChar"); } +DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf126243, "tdf120338.docx") +{ + xmlDocPtr pXmlDoc = parseExport("word/document.xml"); + // export change tracking rejection data for tracked paragraph style change + assertXPath(pXmlDoc, "/w:document/w:body/w:p[11]/w:pPr/w:pPrChange/w:pPr/w:pStyle", "val", "Heading 3"); +} + DECLARE_OOXMLEXPORT_TEST(testTdf118691, "tdf118691.docx") { uno::Reference xTablesSupplier(mxComponent, uno::UNO_QUERY); diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx index 64352b08f5fd..b0c08917e787 100644 --- a/sw/qa/extras/uiwriter/uiwriter2.cxx +++ b/sw/qa/extras/uiwriter/uiwriter2.cxx @@ -1665,6 +1665,11 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf120338) CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getProperty(getParagraph(5), "ParaAdjust")); // right + CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"), + getProperty(getParagraph(10), "ParaStyleName")); + CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"), + getProperty(getParagraph(11), "ParaStyleName")); + // reject tracked paragraph adjustments lcl_dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {}); @@ -1676,6 +1681,12 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf120338) getProperty(getParagraph(4), "ParaAdjust")); // center CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty(getParagraph(5), "ParaAdjust")); // left + + // tdf#126243 revert paragraph styles + CPPUNIT_ASSERT_EQUAL(OUString("Standard"), + getProperty(getParagraph(10), "ParaStyleName")); + CPPUNIT_ASSERT_EQUAL(OUString("Heading 3"), + getProperty(getParagraph(11), "ParaStyleName")); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx index 94c903bbc56f..614cc740d42f 100644 --- a/sw/source/core/doc/docredln.cxx +++ b/sw/source/core/doc/docredln.cxx @@ -777,33 +777,17 @@ void SwRedlineExtraData_FormatColl::Reject( SwPaM& rPam ) const SwTextFormatColl* pColl = USHRT_MAX == m_nPoolId ? pDoc->FindTextFormatCollByName( m_sFormatNm ) : pDoc->getIDocumentStylePoolAccess().GetTextCollFromPool( m_nPoolId ); + + RedlineFlags eOld = pDoc->getIDocumentRedlineAccess().GetRedlineFlags(); + pDoc->getIDocumentRedlineAccess().SetRedlineFlags_intern(eOld & ~RedlineFlags(RedlineFlags::On | RedlineFlags::Ignore)); + if( pColl ) pDoc->SetTextFormatColl( rPam, pColl, false ); if( m_pSet ) - { - rPam.SetMark(); - SwPosition& rMark = *rPam.GetMark(); - SwTextNode* pTNd = rMark.nNode.GetNode().GetTextNode(); - if( pTNd ) - { - rMark.nContent.Assign(pTNd, pTNd->GetText().getLength()); + pDoc->getIDocumentContentOperations().InsertItemSet( rPam, *m_pSet ); - if( pTNd->HasSwAttrSet() ) - { - // Only set those that are not there anymore. Others - // could have changed, but we don't touch these. - SfxItemSet aTmp( *m_pSet ); - aTmp.Differentiate( *pTNd->GetpSwAttrSet() ); - pDoc->getIDocumentContentOperations().InsertItemSet( rPam, aTmp ); - } - else - { - pDoc->getIDocumentContentOperations().InsertItemSet( rPam, *m_pSet ); - } - } - rPam.DeleteMark(); - } + pDoc->getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld ); } bool SwRedlineExtraData_FormatColl::operator == ( const SwRedlineExtraData& r) const diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx index b00e4fb9ee67..db66adb2fd0a 100644 --- a/sw/source/core/unocore/unocrsrhelper.cxx +++ b/sw/source/core/unocore/unocrsrhelper.cxx @@ -90,6 +90,7 @@ #include #include #include +#include #include using namespace ::com::sun::star; @@ -1199,7 +1200,7 @@ void makeRedline( SwPaM const & rPaM, aRedlineData.SetTimeStamp( DateTime( aStamp)); } - SwRedlineExtraData_FormattingChanges* pRedlineExtraData = nullptr; + SwRedlineExtraData_FormatColl * pRedlineExtraData = nullptr; // Read the 'Redline Revert Properties' from the parameters uno::Sequence< beans::PropertyValue > aRevertProperties; @@ -1209,7 +1210,14 @@ void makeRedline( SwPaM const & rPaM, int nMap = 0; // Make sure that paragraph format gets its own map, otherwise e.g. fill attributes are not preserved. if (eType == RedlineType::ParagraphFormat) + { nMap = PROPERTY_MAP_PARAGRAPH; + if (!aRevertProperties.hasElements()) + { + // to reject the paragraph style change, use standard style + pRedlineExtraData = new SwRedlineExtraData_FormatColl( "", RES_POOLCOLL_STANDARD, nullptr ); + } + } else nMap = PROPERTY_MAP_TEXTPORTION_EXTENSIONS; SfxItemPropertySet const& rPropSet = *aSwMapProvider.GetPropertySet(nMap); @@ -1248,6 +1256,8 @@ void makeRedline( SwPaM const & rPaM, if (!aWhichPairs.empty()) { + sal_uInt16 nStylePoolId = USHRT_MAX; + OUString sParaStyleName; aWhichPairs.push_back(0); // terminate SfxItemSet aItemSet(pDoc->GetAttrPool(), aWhichPairs.data()); @@ -1256,9 +1266,18 @@ void makeRedline( SwPaM const & rPaM, SfxItemPropertySimpleEntry const*const pEntry = aEntries[i]; const uno::Any &rValue = aRevertProperties[i].Value; rPropSet.setPropertyValue(*pEntry, rValue, aItemSet); + + if ( aRevertProperties[i].Name == "ParaStyleName" ) + rValue >>= sParaStyleName; } - pRedlineExtraData = new SwRedlineExtraData_FormattingChanges( &aItemSet ); + + if (eType == RedlineType::ParagraphFormat && sParaStyleName.isEmpty()) + nStylePoolId = RES_POOLCOLL_STANDARD; + + pRedlineExtraData = new SwRedlineExtraData_FormatColl( sParaStyleName, nStylePoolId, &aItemSet ); } + else if (eType == RedlineType::ParagraphFormat) + pRedlineExtraData = new SwRedlineExtraData_FormatColl( "", RES_POOLCOLL_STANDARD, nullptr ); } // to finalize DOCX import diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index ac88e97d32eb..e5167a264f41 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -2961,19 +2961,26 @@ void DocxAttributeOutput::Redline( const SwRedlineData* pRedlineData) if (pRedlineData->GetExtraData()) { const SwRedlineExtraData* pExtraData = pRedlineData->GetExtraData(); - const SwRedlineExtraData_FormattingChanges* pFormattingChanges = dynamic_cast(pExtraData); + const SwRedlineExtraData_FormatColl* pFormattingChanges = dynamic_cast(pExtraData); // Check if the extra data is of type 'formatting changes' if (pFormattingChanges) { // Get the item set that holds all the changes properties const SfxItemSet *pChangesSet = pFormattingChanges->GetItemSet(); - if (pChangesSet) + const OUString & sParaStyleName = pFormattingChanges->GetFormatName(); + if (pChangesSet || !sParaStyleName.isEmpty()) { m_pSerializer->mark(Tag_Redline_2); m_pSerializer->startElementNS(XML_w, XML_pPr); + if ( !sParaStyleName.isEmpty() ) + { + OString sStyleName = OUStringToOString( sParaStyleName, RTL_TEXTENCODING_UTF8 ); + m_pSerializer->singleElementNS(XML_w, XML_pStyle, FSNS(XML_w, XML_val), sStyleName); + } + // The 'm_rExport.SdrExporter().getFlyAttrList()', 'm_pParagraphSpacingAttrList' are used to hold information // that should be collected by different properties in the core, and are all flushed together // to the DOCX when the function 'WriteCollectedParagraphProperties' gets called. @@ -2985,7 +2992,8 @@ void DocxAttributeOutput::Redline( const SwRedlineData* pRedlineData) m_pParagraphSpacingAttrList.clear(); // Output the redline item set - m_rExport.OutputItemSet( *pChangesSet, true, false, i18n::ScriptType::LATIN, m_rExport.m_bExportModeRTF ); + if (pChangesSet) + m_rExport.OutputItemSet( *pChangesSet, true, false, i18n::ScriptType::LATIN, m_rExport.m_bExportModeRTF ); // Write the collected paragraph properties that are stored in 'm_rExport.SdrExporter().getFlyAttrList()', 'm_pParagraphSpacingAttrList' WriteCollectedParagraphProperties(); -- cgit