summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/qa/extras/uiwriter/uiwriter2.cxx59
-rw-r--r--sw/source/core/unocore/unocrsrhelper.cxx16
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx59
3 files changed, 132 insertions, 2 deletions
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index d91c89848495..de0c06f5d6bb 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -3822,6 +3822,65 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineTableRowDeletionWithExport)
assertXPath(pXmlDoc, "//page[1]//body/tab", 0);
}
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineTableRowDeletionWithDOCXExport)
+{
+ // load a 1-row table, and delete the row with enabled change tracking:
+ // now the row is not deleted silently, but keeps the deleted cell contents,
+ // and only accepting all of them will result the deletion of the table row.
+ SwDoc* pDoc = createDoc("tdf118311.fodt");
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+
+ // 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()));
+
+ // check table
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab");
+
+ // delete table row with enabled change tracking
+ // (HasTextChangesOnly property of the row will be false)
+ dispatchCommand(mxComponent, ".uno:DeleteRows", {});
+
+ // Deleted text content with change tracking,
+ // but not table deletion
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab");
+
+ // Save it to a DOCX and load it back.
+ // Exporting change tracking of the row wasn't supported.
+ // Also Manage Changes for the import.
+ reload("Office Open XML Text", "tdf79069_tracked_table_deletion.docx");
+ pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ pDoc = pTextDoc->GetDocShell()->GetWrtShell()->GetDoc();
+
+ // accept the deletion of the content of the first cell
+ SwEditShell* const pEditShell(pDoc->GetEditShell());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), pEditShell->GetRedlineCount());
+ pEditShell->AcceptRedline(0);
+
+ // table row was still not deleted
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab");
+
+ // accept last redline
+ pEditShell->AcceptRedline(0);
+
+ // table row (and the 1-row table) was deleted finally
+ // (working export/import of HasTextChangesOnly)
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab", 0);
+}
+
CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf128335)
{
// Load the bugdoc, which has 3 textboxes.
diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx
index 32b449b97403..58d5dbf6b11e 100644
--- a/sw/source/core/unocore/unocrsrhelper.cxx
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -72,6 +72,7 @@
#include <fchrfmt.hxx>
#include <editeng/editids.hrc>
#include <editeng/flstitem.hxx>
+#include <editeng/prntitem.hxx>
#include <vcl/metric.hxx>
#include <svtools/ctrltool.hxx>
#include <sfx2/docfilt.hxx>
@@ -1388,7 +1389,8 @@ void makeTableRowRedline( SwTableLine& rTableLine,
std::u16string_view rRedlineType,
const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
{
- IDocumentRedlineAccess* pRedlineAccess = &rTableLine.GetFrameFormat()->GetDoc()->getIDocumentRedlineAccess();
+ SwDoc* pDoc = rTableLine.GetFrameFormat()->GetDoc();
+ IDocumentRedlineAccess* pRedlineAccess = &pDoc->getIDocumentRedlineAccess();
RedlineType eType;
if ( rRedlineType == u"TableRowInsert" )
@@ -1398,6 +1400,18 @@ void makeTableRowRedline( SwTableLine& rTableLine,
else if ( rRedlineType == u"TableRowDelete" )
{
eType = RedlineType::TableRowDelete;
+
+ // set table row property "HasTextChangesOnly" to false
+ // to handle tracked deletion of the table row on the UI
+ const SvxPrintItem *pHasTextChangesOnlyProp =
+ rTableLine.GetFrameFormat()->GetAttrSet().GetItem<SvxPrintItem>(RES_PRINT);
+ if ( !pHasTextChangesOnlyProp || pHasTextChangesOnlyProp->GetValue() )
+ {
+ SvxPrintItem aSetTracking(RES_PRINT, false);
+ SwPosition aPos( *rTableLine.GetTabBoxes()[0]->GetSttNd() );
+ SwCursor aCursor( aPos, nullptr );
+ pDoc->SetRowNotTracked( aCursor, aSetTracking );
+ }
}
else
{
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 1690e567fd7e..c0faa7a00fff 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -90,6 +90,7 @@
#include <editeng/editobj.hxx>
#include <editeng/keepitem.hxx>
#include <editeng/borderline.hxx>
+#include <editeng/prntitem.hxx>
#include <sax/tools/converter.hxx>
#include <svx/xdef.hxx>
#include <svx/xfillit0.hxx>
@@ -4348,7 +4349,63 @@ void DocxAttributeOutput::TableRowRedline( ww8::WW8TableNodeInfoInner::Pointer_t
const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
const SwTableLine * pTabLine = pTabBox->GetUpper();
- // search next Redline
+ // check table row property "HasTextChangesOnly" (used only for tracked deletion, yet)
+ const SwRedlineTable& aRedlineTable = m_rExport.m_rDoc.getIDocumentRedlineAccess().GetRedlineTable();
+ const SvxPrintItem *pHasTextChangesOnlyProp =
+ pTabLine->GetFrameFormat()->GetAttrSet().GetItem<SvxPrintItem>(RES_PRINT);
+ if ( !aRedlineTable.empty() && pHasTextChangesOnlyProp && !pHasTextChangesOnlyProp->GetValue() )
+ {
+ // Tracked row deletion is associated to the newest redline range in the row.
+ // Search it to get the date and the mandatory author.
+ const SwTableBoxes & rBoxes = pTabLine->GetTabBoxes();
+ SwPosition aRowStart( SwNodeIndex( *rBoxes[0]->GetSttNd(), 0 ) );
+ SwPosition aRowEnd( SwNodeIndex( *rBoxes[rBoxes.size() - 1]->GetSttNd()->EndOfSectionNode(), -1 ) );
+ SwNodeIndex pEndNodeIndex(aRowEnd.nNode.GetNode());
+
+ SwRedlineTable::size_type nLastDeletion = SwRedlineTable::npos;
+ for( SwRedlineTable::size_type n = 0; n < aRedlineTable.size(); ++n )
+ {
+ const SwRangeRedline* pRedline = aRedlineTable[ n ];
+
+ if ( pRedline->Start()->nNode > pEndNodeIndex )
+ break;
+
+ if( RedlineType::Delete != pRedline->GetType() )
+ continue;
+
+ // redline is in the table row, and newer, than the previous
+ if ( aRowStart <= *pRedline->Start() )
+ {
+ if ( nLastDeletion == SwRedlineTable::npos ||
+ aRedlineTable [ nLastDeletion ]->GetRedlineData().GetTimeStamp() <
+ pRedline->GetRedlineData().GetTimeStamp() )
+ {
+ nLastDeletion = n;
+ }
+ }
+ }
+
+ if ( nLastDeletion != SwRedlineTable::npos )
+ {
+ const SwRedlineData& aRedlineData = aRedlineTable[ nLastDeletion ]->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
+ // (different IDs for different ranges, also row changes) is also portable.
+ OString aId( OString::number( m_nRedlineId++ ) );
+ const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( aRedlineData.GetAuthor() ) );
+ OString aAuthor( OUStringToOString( rAuthor, RTL_TEXTENCODING_UTF8 ) );
+
+ OString aDate( DateTimeToOString( aRedlineData.GetTimeStamp() ) );
+
+ 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 );
+ 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 )
{