summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2021-11-12 12:38:35 +0100
committerLászló Németh <nemeth@numbertext.org>2021-11-15 09:26:00 +0100
commitdbc2bdffbec9b3f7eba485652cdd43634458b5a6 (patch)
tree5fa9f2f1aab5289447a627f397c9a12ef137f9ed
parent1badef89c0794167b9b84ea44d4a7df5645de8a7 (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.docxbin0 -> 4753 bytes
-rw-r--r--sw/qa/extras/uiwriter/uiwriter2.cxx50
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx66
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
new file mode 100644
index 000000000000..f248d5d62605
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf145091.docx
Binary files differ
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 )