summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2022-09-07 09:27:00 +0200
committerLászló Németh <nemeth@numbertext.org>2022-09-09 12:49:12 +0200
commitc46ab9ff1e6bd53881e5f9dfdf9f44e030a93d2b (patch)
tree836cd7d825348ffa7525eeefda806af8ed8e0086
parentSAL_WARN on parse exception (diff)
downloadcore-c46ab9ff1e6bd53881e5f9dfdf9f44e030a93d2b.tar.gz
core-c46ab9ff1e6bd53881e5f9dfdf9f44e030a93d2b.zip
tdf#150666 sw: allow to delete tracked table row insertions
It was not possible to delete tracked table row insertions, if only those were selected, or if they were own insertions. Regression from commit 95213407dfcbf34056037d60243ff915340d1a2e "tdf#146622 sw crash fix: don't delete already deleted rows". Change-Id: Idd3bc78bca1c76bceba63cf339c6d8c73f8f9508 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139575 Tested-by: Jenkins Reviewed-by: László Németh <nemeth@numbertext.org> (cherry picked from commit a0566ae34a704a9ad9b147d560007dde7d2ccf7d) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139556 Tested-by: László Németh <nemeth@numbertext.org>
-rw-r--r--sw/qa/extras/uiwriter/uiwriter5.cxx39
-rw-r--r--sw/source/core/docnode/ndtbl1.cxx40
2 files changed, 77 insertions, 2 deletions
diff --git a/sw/qa/extras/uiwriter/uiwriter5.cxx b/sw/qa/extras/uiwriter/uiwriter5.cxx
index 1e9d5a0b7560..0dfa9e9c11d0 100644
--- a/sw/qa/extras/uiwriter/uiwriter5.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter5.cxx
@@ -2048,6 +2048,45 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest5, testTdf143215)
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getRows()->getCount());
}
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest5, testTdf150666)
+{
+ // load a table with tracked insertion of an empty row
+ SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "TC-table-rowadd.docx");
+
+ // check table count
+ uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
+
+ // check table row count
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable->getRows()->getCount());
+
+ // select the second row (tracked table row insertion)
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ pWrtShell->Down(/*bSelect=*/false);
+
+ // delete it, and accept all tracked changes
+ dispatchCommand(mxComponent, ".uno:DeleteRows", {});
+ dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {});
+
+ // This was 4 (it was not possible to delete only the tracked row insertions)
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getRows()->getCount());
+
+ // insert a new table row with track changes
+ dispatchCommand(mxComponent, ".uno:InsertRowsAfter", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable->getRows()->getCount());
+
+ // select and delete it
+ pWrtShell->Down(/*bSelect=*/false);
+ dispatchCommand(mxComponent, ".uno:DeleteRows", {});
+ dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {});
+
+ // This was 4 (it was not possible to delete own tracked row insertions)
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getRows()->getCount());
+}
+
CPPUNIT_TEST_FIXTURE(SwUiWriterTest5, testTdf144748)
{
// load a table with an empty row, and an empty line before the table
diff --git a/sw/source/core/docnode/ndtbl1.cxx b/sw/source/core/docnode/ndtbl1.cxx
index 35f4b8e7e943..0c67775684cd 100644
--- a/sw/source/core/docnode/ndtbl1.cxx
+++ b/sw/source/core/docnode/ndtbl1.cxx
@@ -52,6 +52,7 @@
#include <o3tl/enumrange.hxx>
#include <o3tl/safeint.hxx>
#include <osl/diagnose.h>
+#include <redline.hxx>
using ::editeng::SvxBorderLine;
using namespace ::com::sun::star;
@@ -540,6 +541,7 @@ bool SwDoc::GetRowBackground( const SwCursor& rCursor, std::unique_ptr<SvxBrushI
return bRet;
}
+// has a table row, which is not a tracked deletion
bool SwDoc::HasRowNotTracked( const SwCursor& rCursor )
{
SwTableNode* pTableNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
@@ -552,12 +554,26 @@ bool SwDoc::HasRowNotTracked( const SwCursor& rCursor )
if( aRowArr.empty() )
return false;
+ SwRedlineTable::size_type nRedlinePos = 0;
+ SwDoc* pDoc = aRowArr[0]->GetFrameFormat()->GetDoc();
+ const IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess();
+
for( auto pLn : aRowArr )
{
auto pHasTextChangesOnlyProp = pLn->GetFrameFormat()->GetAttrSet().GetItem<SvxPrintItem>(RES_PRINT);
if ( !pHasTextChangesOnlyProp || pHasTextChangesOnlyProp->GetValue() )
- // there is a not deleted row in the table selection
+ // there is a not tracked row in the table selection
return true;
+
+ // tdf#150666 examine tracked row: it's possible to delete a tracked insertion
+ SwRedlineTable::size_type nPos = pLn->UpdateTextChangesOnly(nRedlinePos);
+ if ( nPos != SwRedlineTable::npos )
+ {
+ const SwRedlineTable& aRedlineTable = rIDRA.GetRedlineTable();
+ SwRangeRedline* pTmp = aRedlineTable[ nPos ];
+ if ( RedlineType::Insert == pTmp->GetType() )
+ return true;
+ }
}
return false;
}
@@ -588,8 +604,28 @@ void SwDoc::SetRowNotTracked( const SwCursor& rCursor, const SvxPrintItem &rNew,
std::vector<std::unique_ptr<SwTableFormatCmp>> aFormatCmp;
aFormatCmp.reserve( std::max( 255, static_cast<int>(aRowArr.size()) ) );
+ SwRedlineTable::size_type nRedlinePos = 0;
for( auto pLn : aRowArr )
{
+ // tdf#150666 row insertion from the same author needs special handling,
+ // because removing redlines of the author can result an empty line,
+ // which doesn't contain any redline for the tracked row
+ bool bDeletionOfOwnRowInsertion = false;
+ SwRedlineTable::size_type nPos = pLn->UpdateTextChangesOnly(nRedlinePos);
+ if ( nPos != SwRedlineTable::npos )
+ {
+ SwDoc* pDoc = pLn->GetFrameFormat()->GetDoc();
+ IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess();
+ const SwRedlineTable& aRedlineTable = rIDRA.GetRedlineTable();
+ SwRangeRedline* pTmp = aRedlineTable[ nPos ];
+ if ( RedlineType::Insert == pTmp->GetType() &&
+ rIDRA.GetRedlineAuthor() == pTmp->GetRedlineData().GetAuthor() &&
+ pTmp->GetText()[0] == CH_TXT_TRACKED_DUMMY_CHAR )
+ {
+ bDeletionOfOwnRowInsertion = true;
+ }
+ }
+
::lcl_ProcessRowAttr( aFormatCmp, pLn, rNew );
// as a workaround for the rows without text content,
// add a redline with invisible text CH_TXT_TRACKED_DUMMY_CHAR
@@ -597,7 +633,7 @@ void SwDoc::SetRowNotTracked( const SwCursor& rCursor, const SvxPrintItem &rNew,
// new redline can cause a problem)
if ( !bAll &&
// HasTextChangesOnly == false, i.e. a tracked row insertion or deletion
- !rNew.GetValue() && pLn->IsEmpty() )
+ !rNew.GetValue() && (pLn->IsEmpty() || bDeletionOfOwnRowInsertion ) )
{
SwNodeIndex aInsPos( *(pLn->GetTabBoxes()[0]->GetSttNd()), 1 );
RedlineFlags eOld = getIDocumentRedlineAccess().GetRedlineFlags();