diff options
author | László Németh <nemeth@numbertext.org> | 2021-11-12 12:38:35 +0100 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2021-11-15 09:26:00 +0100 |
commit | dbc2bdffbec9b3f7eba485652cdd43634458b5a6 (patch) | |
tree | 5fa9f2f1aab5289447a627f397c9a12ef137f9ed | |
parent | 1badef89c0794167b9b84ea44d4a7df5645de8a7 (diff) |
tdf#145091 DOCX: don't export obsolete table row change data
Rejection of table deletion or accepting table insertion
imported from a DOCX document kept row changes in DOCX export.
Use SwExtraRedlineTable/SwTableRowRedline data only if it's
not obsolete.
Follow-up of commit 05366b8e6683363688de8708a3d88cf144c7a2bf
"tdf#60382 sw offapi: add change tracking of table/row deletion".
Change-Id: I247e13e86c0115604079e4852aa8663f1bfead91
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125114
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r-- | sw/qa/extras/uiwriter/data/tdf145091.docx | bin | 0 -> 4753 bytes | |||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter2.cxx | 50 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 66 |
3 files changed, 72 insertions, 44 deletions
diff --git a/sw/qa/extras/uiwriter/data/tdf145091.docx b/sw/qa/extras/uiwriter/data/tdf145091.docx Binary files differnew file mode 100644 index 000000000000..f248d5d62605 --- /dev/null +++ b/sw/qa/extras/uiwriter/data/tdf145091.docx diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx index 7fd1ffb9a546..9666efe9a49e 100644 --- a/sw/qa/extras/uiwriter/uiwriter2.cxx +++ b/sw/qa/extras/uiwriter/uiwriter2.cxx @@ -4942,6 +4942,56 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf145089_RedlineTableRowInsertionDOCX assertXPath(pXmlDoc, "//page[1]//body/tab/row", 1); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf145091) +{ + // load a deleted table, reject them, and delete only its text and export to DOCX + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf145091.docx"); + + // turn on red-lining and show changes + pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete + | RedlineFlags::ShowInsert); + CPPUNIT_ASSERT_MESSAGE("redlining should be on", + pDoc->getIDocumentRedlineAccess().IsRedlineOn()); + CPPUNIT_ASSERT_MESSAGE( + "redlines should be visible", + IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags())); + + // reject all redlines + SwEditShell* const pEditShell(pDoc->GetEditShell()); + CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(3), pEditShell->GetRedlineCount()); + while (pEditShell->GetRedlineCount() > 0) + pEditShell->RejectRedline(0); + CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(0), pEditShell->GetRedlineCount()); + + // delete only table text, but not table + dispatchCommand(mxComponent, ".uno:SelectAll", {}); + dispatchCommand(mxComponent, ".uno:SelectAll", {}); + dispatchCommand(mxComponent, ".uno:Delete", {}); + CPPUNIT_ASSERT(pEditShell->GetRedlineCount() > 0); + + // save it to DOCX + reload("Office Open XML Text", "tdf145091.docx"); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + SwViewShell* pViewShell + = pTextDoc->GetDocShell()->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell(); + pViewShell->Reformat(); + discardDumpedLayout(); + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + + assertXPath(pXmlDoc, "//page[1]//body/tab"); + assertXPath(pXmlDoc, "//page[1]//body/tab/row", 3); + + // accept all redlines + dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {}); + + discardDumpedLayout(); + + pXmlDoc = parseLayoutDump(); + // This was false (deleted table with accepting deletions) + assertXPath(pXmlDoc, "//page[1]//body/tab"); + assertXPath(pXmlDoc, "//page[1]//body/tab/row", 3); +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf128603) { // Load the bugdoc, which has 3 textboxes. diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index de61bb748814..4d49f2bf95a8 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -4392,7 +4392,28 @@ void DocxAttributeOutput::TableRowRedline( ww8::WW8TableNodeInfoInner::Pointer_t { const SwRedlineTable& aRedlineTable = m_rExport.m_rDoc.getIDocumentRedlineAccess().GetRedlineTable(); const SwRangeRedline* pRedline = aRedlineTable[ nChange ]; - const SwRedlineData& aRedlineData = pRedline->GetRedlineData(); + SwTableRowRedline* pTableRowRedline = nullptr; + bool bIsInExtra = false; + + // use the original DOCX redline data stored in ExtraRedlineTable, + // if it exists and its type wasn't changed + const SwExtraRedlineTable& aExtraRedlineTable = m_rExport.m_rDoc.getIDocumentRedlineAccess().GetExtraRedlineTable(); + for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < aExtraRedlineTable.GetSize(); ++nCurRedlinePos ) + { + SwExtraRedline* pExtraRedline = aExtraRedlineTable.GetRedline(nCurRedlinePos); + pTableRowRedline = dynamic_cast<SwTableRowRedline*>(pExtraRedline); + if (pTableRowRedline && &pTableRowRedline->GetTableLine() == pTabLine) + { + bIsInExtra = true; + break; + } + } + + const SwRedlineData& aRedlineData = bIsInExtra && + // still the same type (an inserted row could become a tracked deleted one) + pTableRowRedline->GetRedlineData().GetType() == pRedline->GetRedlineData().GetType() + ? pTableRowRedline->GetRedlineData() + : pRedline->GetRedlineData(); // Note: all redline ranges and table row redline (with the same author and timestamp) // use the same redline id in OOXML exported by MSO, but it seems, the recent solution @@ -4414,49 +4435,6 @@ void DocxAttributeOutput::TableRowRedline( ww8::WW8TableNodeInfoInner::Pointer_t FSNS( XML_w, XML_date ), aDate ); return; } - - // search next Redline (only deletion of empty rows and all insertions imported from a DOCX) - const SwExtraRedlineTable& aExtraRedlineTable = m_rExport.m_rDoc.getIDocumentRedlineAccess().GetExtraRedlineTable(); - for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < aExtraRedlineTable.GetSize(); ++nCurRedlinePos ) - { - SwExtraRedline* pExtraRedline = aExtraRedlineTable.GetRedline(nCurRedlinePos); - const SwTableRowRedline* pTableRowRedline = dynamic_cast<const SwTableRowRedline*>(pExtraRedline); - if (pTableRowRedline && &pTableRowRedline->GetTableLine() == pTabLine) - { - // Redline for this table row - const SwRedlineData& aRedlineData = pTableRowRedline->GetRedlineData(); - RedlineType nRedlineType = aRedlineData.GetType(); - switch (nRedlineType) - { - case RedlineType::TableRowInsert: - case RedlineType::TableRowDelete: - { - OString aId( OString::number( m_nRedlineId++ ) ); - const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( aRedlineData.GetAuthor() ) ); - OString aAuthor( OUStringToOString( bRemovePersonalInfo - ? "Author" + OUString::number( GetExport().GetInfoID(rAuthor) ) - : rAuthor, RTL_TEXTENCODING_UTF8 ) ); - - OString aDate( DateTimeToOString( bRemovePersonalInfo - ? DateTime(Date( 1, 1, 1970 )) // Epoch time - : aRedlineData.GetTimeStamp() ) ); - - if (nRedlineType == RedlineType::TableRowInsert) - m_pSerializer->singleElementNS( XML_w, XML_ins, - FSNS( XML_w, XML_id ), aId, - FSNS( XML_w, XML_author ), aAuthor, - FSNS( XML_w, XML_date ), aDate ); - else if (nRedlineType == RedlineType::TableRowDelete) - m_pSerializer->singleElementNS( XML_w, XML_del, - FSNS( XML_w, XML_id ), aId, - FSNS( XML_w, XML_author ), aAuthor, - FSNS( XML_w, XML_date ), aDate ); - } - break; - default: break; - } - } - } } void DocxAttributeOutput::TableCellRedline( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |