sw/inc/redline.hxx | 6 +++ sw/qa/extras/ooxmlexport/ooxmlexport12.cxx | 42 ++++++++++++++++++++++++-- sw/source/core/doc/DocumentRedlineManager.cxx | 19 +++-------- 3 files changed, 52 insertions(+), 15 deletions(-)
New commits: commit a35189a5962aaa9843923f87972a3811e9ae83b5 Author: László Németh <nem...@numbertext.org> AuthorDate: Wed Mar 8 12:56:22 2023 +0100 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Thu Mar 9 10:19:34 2023 +0000 tdf#136904 tdf#116084 tdf#121176 sw: fix Undo & anonymized w:del in w:ins Undo/Redo crash resulted by the workaround for anonymized w:del in w:ins. Anonymized (no time stamp) redlines are loaded with Epoch time (1970-01-01) since commit 2c51746997478ad5d0e7cc64aa6489769c473d43 "tdf#146171 DOCX: fix loss of change tracking, if no date", so it's possible to fix the original DOCX import problem using this value: don't combine anonymized deletion inside/over anonymized insertion, and remove all the workaround, keeping only their adjusted unit tests, and add new tests for the export fixed finally, which keeps anonymized w:del in anonymized w:ins. Revert commit 2de1fd7d8b8bd42c66190140cc4506df0c3367f1 "tdf#125187 DOCX track changes: fix w:del within w:ins", commit df4f405a153603551f67e289bbaccf9ac39b923c "tdf#121176 DOCX track changes: same size w:del in w:ins" and commit 7a810d6a9fb79a24d00e5dbd8e1223e6f8b09677 "tdf#116084 DOCX track changes: fix w:del within w:ins". Regression from commit 2de1fd7d8b8bd42c66190140cc4506df0c3367f1 "tdf#125187 DOCX track changes: fix w:del within w:ins". See also commit 64dcedcf7c073d1819794d68a33651b14877e1b5 "tdf#147760 tdf#142902 DOCX export: anonymize date and moveFromRangeStart". Change-Id: Id6e41187e7f94154389f24dd525067ac47ec7e58 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148479 Tested-by: Jenkins Reviewed-by: László Németh <nem...@numbertext.org> (cherry picked from commit 8f26482986fd9af5eac4efd44ec56fd994ec69f1) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148497 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/sw/inc/redline.hxx b/sw/inc/redline.hxx index f2d6c31a40ac..1fccb405e192 100644 --- a/sw/inc/redline.hxx +++ b/sw/inc/redline.hxx @@ -128,6 +128,12 @@ public: std::size_t GetAuthor() const { return m_nAuthor; } const OUString& GetComment() const { return m_sComment; } const DateTime& GetTimeStamp() const { return m_aStamp; } + bool IsAnonymized() const + { + return m_aStamp.GetYear() == 1970 && + m_aStamp.GetMonth() == 1 && m_aStamp.GetDay() == 1; + } + const SwRedlineData* Next() const{ return m_pNext; } void SetComment( const OUString& rS ) { m_sComment = rS; } diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx index 2713a582c9d9..b3c2bceef5bb 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx @@ -1959,8 +1959,28 @@ DECLARE_OOXMLEXPORT_TEST(testTdf116084, "tdf116084.docx") // tracked line is not a single text portion: w:del is recognized within w:ins CPPUNIT_ASSERT_EQUAL(OUString(""), getRun(getParagraph(1), 1)->getString()); CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(1), 1), "RedlineType")); - CPPUNIT_ASSERT_EQUAL(OUString("There should be a better start to this. "), - getRun(getParagraph(1), 2)->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("There "), getRun(getParagraph(1), 2)->getString()); + CPPUNIT_ASSERT_EQUAL(OUString(""), getRun(getParagraph(1), 4)->getString()); + CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(1), 4), "RedlineType")); + CPPUNIT_ASSERT_EQUAL(OUString("must"), getRun(getParagraph(1), 5)->getString()); +} + +CPPUNIT_TEST_FIXTURE(Test, testTdf116084_anonymized) +{ + loadAndSave("tdf116084.docx"); + xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); + // w:del in w:ins is exported correctly + assertXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:ins/w:del/w:r/w:delText", "must"); + + // no date (anonymized changes) + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins[@date]", 0); + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins/w:del[@w:date]", 0); + + // w:ins and w:del have w:author attributes, and the same + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins/w:del[@w:author]", 1); + OUString sAuthor = getXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins[2]", "author"); + OUString sAuthor2 = getXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins/w:del", "author"); + CPPUNIT_ASSERT_EQUAL(sAuthor, sAuthor2); } DECLARE_OOXMLEXPORT_TEST(testTdf121176, "tdf121176.docx") @@ -1971,6 +1991,24 @@ DECLARE_OOXMLEXPORT_TEST(testTdf121176, "tdf121176.docx") CPPUNIT_ASSERT_EQUAL(OUString("must"), getRun(getParagraph(1), 2)->getString()); } +CPPUNIT_TEST_FIXTURE(Test, testTdf121176_anonymized) +{ + loadAndSave("tdf121176.docx"); + xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); + // w:del in w:ins is exported correctly + assertXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:ins/w:del/w:r/w:delText", "must"); + + // no date (anonymized changes) + assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:p/w:ins", "date"); + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins/w:del[@w:date]", 0); + + // w:ins and w:del have w:author attributes, and the same + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins/w:del[@w:author]", 1); + OUString sAuthor = getXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins", "author"); + OUString sAuthor2 = getXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins/w:del", "author"); + CPPUNIT_ASSERT_EQUAL(sAuthor, sAuthor2); +} + CPPUNIT_TEST_FIXTURE(Test, testTdf128913) { loadAndSave("tdf128913.docx"); diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx index 32a55ac6002f..60ddf9d62151 100644 --- a/sw/source/core/doc/DocumentRedlineManager.cxx +++ b/sw/source/core/doc/DocumentRedlineManager.cxx @@ -1738,7 +1738,10 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall // even if they are not allowed to be combined RedlineFlags eOld = meRedlineFlags; if( !( eOld & RedlineFlags::DontCombineRedlines ) && - pRedl->IsOwnRedline( *pNewRedl ) ) + pRedl->IsOwnRedline( *pNewRedl ) && + // tdf#116084 tdf#121176 don't combine anonymized deletion + // and anonymized insertion, i.e. with the same dummy timestamp + !pRedl->GetRedlineData(0).IsAnonymized() ) { // Set to NONE, so that the Delete::Redo merges the Redline data correctly! @@ -1772,18 +1775,8 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall bCompress = true; } - if( !bCallDelete && !bDec && *pEnd == *pREnd ) - { - m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl ); - bCompress = true; - } - else if ( bCallDelete || !bDec ) - { - // delete new redline, except in some cases of fallthrough from previous - // case ::Equal (eg. same portion w:del in w:ins in OOXML import) - delete pNewRedl; - pNewRedl = nullptr; - } + delete pNewRedl; + pNewRedl = nullptr; break; case SwComparePosition::Outside: