sw/inc/hintids.hxx | 4 ++++ sw/qa/extras/uiwriter/uiwriter3.cxx | 7 +++++++ sw/source/core/docnode/ndtbl1.cxx | 19 +++++++++++++++++++ sw/source/core/frmedt/fetab.cxx | 6 +++--- sw/source/core/unocore/unocrsrhelper.cxx | 6 ++++-- sw/source/uibase/wrtsh/delete.cxx | 9 ++++++--- 6 files changed, 43 insertions(+), 8 deletions(-)
New commits: commit 8b60bf5c880c5059b9658e06df6f0929c5d58810 Author: László Németh <nem...@numbertext.org> AuthorDate: Tue Sep 7 15:57:35 2021 +0200 Commit: Tünde Tóth <toth.tu...@nisz.hu> CommitDate: Thu Oct 21 14:27:42 2021 +0200 tdf#143359 sw: track deletion of empty table rows Empty table rows were deleted immediately during change tracking, or in the case of a deleted table also with non-empty rows, accepting table deletion kept empty rows. Note: as a workaround for tracking of the empty rows, i.e. rows without text content, add a redline with invisible text ZWJ in the first cell of the empty row. See also commit a483a44ca00f43a64ae51d62b8fbb4129a413f6d "tdf#143215 DOCX import: fix tracked empty row insertion/deletion", commit b50d386dfa70f7c1d4eb1a49091ec9dd782b767b "tdf#142701 track changes: fix layout regression of image deletion" and commit 05366b8e6683363688de8708a3d88cf144c7a2bf "tdf#60382 sw offapi: add change tracking of table/row deletion". Note: switch off unnecessary redlining of tdf#132744 unit test to keep the sake of that test (i.e. cut of the selected table with empty rows). Change-Id: Ief59008e8714fb88afdfce867598e3dda21bfba5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121784 Tested-by: Jenkins Reviewed-by: László Németh <nem...@numbertext.org> (cherry picked from commit 99059a1ececa3621c2fe46fabdd79eed9d626c42) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123983 Tested-by: Tünde Tóth <toth.tu...@nisz.hu> Reviewed-by: Tünde Tóth <toth.tu...@nisz.hu> diff --git a/sw/inc/hintids.hxx b/sw/inc/hintids.hxx index 3971619e27e1..88282fe163c5 100644 --- a/sw/inc/hintids.hxx +++ b/sw/inc/hintids.hxx @@ -181,6 +181,10 @@ class SfxVoidItem; #define CH_TXT_ATR_SUBST_FIELDSTART ("[") #define CH_TXT_ATR_SUBST_FIELDEND ("]") +// a non-visible dummy character to track deleted tables, +// table rows, and images anchored to characters +#define CH_TXT_TRACKED_DUMMY_CHAR u'\x200D' + /* * Enums for the hints */ diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx b/sw/qa/extras/uiwriter/uiwriter3.cxx index 8ecfea76adbf..7e8b004fe43b 100644 --- a/sw/qa/extras/uiwriter/uiwriter3.cxx +++ b/sw/qa/extras/uiwriter/uiwriter3.cxx @@ -1393,6 +1393,13 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf132744) SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); CPPUNIT_ASSERT(pTextDoc); + // disable change tracking to cut the table + pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::ShowDelete + | RedlineFlags::ShowInsert); + + CPPUNIT_ASSERT_MESSAGE("redlining should be off", + !pDoc->getIDocumentRedlineAccess().IsRedlineOn()); + CPPUNIT_ASSERT_EQUAL(1, getShapes()); dispatchCommand(mxComponent, ".uno:SelectAll", {}); diff --git a/sw/source/core/docnode/ndtbl1.cxx b/sw/source/core/docnode/ndtbl1.cxx index 228b4cde0267..37b9339cae6c 100644 --- a/sw/source/core/docnode/ndtbl1.cxx +++ b/sw/source/core/docnode/ndtbl1.cxx @@ -35,6 +35,8 @@ #include <doc.hxx> #include <IDocumentUndoRedo.hxx> #include <IDocumentState.hxx> +#include <IDocumentContentOperations.hxx> +#include <IDocumentRedlineAccess.hxx> #include <IDocumentLayoutAccess.hxx> #include <pam.hxx> #include <swcrsr.hxx> @@ -556,7 +558,24 @@ void SwDoc::SetRowNotTracked( const SwCursor& rCursor, const SvxPrintItem &rNew aFormatCmp.reserve( std::max( 255, static_cast<int>(aRowArr.size()) ) ); for( auto pLn : aRowArr ) + { ::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 + if (pLn->IsEmpty()) + { + SwNodeIndex aInsPos( *(pLn->GetTabBoxes()[0]->GetSttNd()), 1 ); + RedlineFlags eOld = getIDocumentRedlineAccess().GetRedlineFlags(); + getIDocumentRedlineAccess().SetRedlineFlags_intern(RedlineFlags::NONE); + SwPaM aPaM(aInsPos); + getIDocumentContentOperations().InsertString( aPaM, + OUStringChar(CH_TXT_TRACKED_DUMMY_CHAR) ); + aPaM.SetMark(); + aPaM.GetMark()->nContent.Assign(aPaM.GetContentNode(), 0); + getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld ); + getIDocumentContentOperations().DeleteAndJoin( aPaM ); + } + } getIDocumentState().SetModified(); } diff --git a/sw/source/core/frmedt/fetab.cxx b/sw/source/core/frmedt/fetab.cxx index aaa4351b023c..b912789c7dfd 100644 --- a/sw/source/core/frmedt/fetab.cxx +++ b/sw/source/core/frmedt/fetab.cxx @@ -332,6 +332,8 @@ bool SwFEShell::DeleteRow(bool bCompleteTable) // and set IsNoTracked table line property to false if ( GetDoc()->GetDocShell()->IsChangeRecording() ) { + SwEditShell* pEditShell = GetDoc()->GetEditShell(); + SwRedlineTable::size_type nOldRedlineCount = pEditShell->GetRedlineCount(); StartUndo(bCompleteTable ? SwUndoId::UI_TABLE_DELETE : SwUndoId::ROW_DELETE); StartAllAction(); @@ -341,8 +343,6 @@ bool SwFEShell::DeleteRow(bool bCompleteTable) if ( SwWrtShell* pWrtShell = dynamic_cast<SwWrtShell*>(this) ) pWrtShell->SelectTableRow(); - SwEditShell* pEditShell = GetDoc()->GetEditShell(); - SwRedlineTable::size_type nPrev = pEditShell->GetRedlineCount(); pEditShell->Delete(); EndAllActionAndCall(); @@ -351,7 +351,7 @@ bool SwFEShell::DeleteRow(bool bCompleteTable) // track row deletion only if there were tracked text changes // FIXME redline count can be the same in special cases, e.g. adding a // new tracked deletion with removing an own tracked insertion... - if ( nPrev != pEditShell->GetRedlineCount() ) + if ( nOldRedlineCount != pEditShell->GetRedlineCount() ) return true; } diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx index 997ecf256d93..ab9b5a4e46bb 100644 --- a/sw/source/core/unocore/unocrsrhelper.cxx +++ b/sw/source/core/unocore/unocrsrhelper.cxx @@ -35,6 +35,7 @@ #include <svx/unoshape.hxx> #include <cmdid.h> +#include <hintids.hxx> #include <unotextrange.hxx> #include <unodraw.hxx> #include <unofootnote.hxx> @@ -1417,11 +1418,12 @@ void makeTableRowRedline( SwTableLine& rTableLine, SvxPrintItem aSetTracking(RES_PRINT, false); SwNodeIndex aInsPos( *(rTableLine.GetTabBoxes()[0]->GetSttNd()), 1 ); // as a workaround for the rows without text content, - // add a redline with invisible text ZWJ + // add a redline with invisible text CH_TXT_TRACKED_DUMMY_CHAR if ( rTableLine.IsEmpty() ) { SwPaM aPaM(aInsPos); - pDoc->getIDocumentContentOperations().InsertString( aPaM, u"" ); + pDoc->getIDocumentContentOperations().InsertString( aPaM, + OUStringChar(CH_TXT_TRACKED_DUMMY_CHAR) ); aPaM.SetMark(); aPaM.GetMark()->nContent.Assign(aPaM.GetContentNode(), 0); makeRedline(aPaM, RedlineType::TableRowInsert == eType diff --git a/sw/source/uibase/wrtsh/delete.cxx b/sw/source/uibase/wrtsh/delete.cxx index ab7dd3fe63ba..ba2796daf553 100644 --- a/sw/source/uibase/wrtsh/delete.cxx +++ b/sw/source/uibase/wrtsh/delete.cxx @@ -18,6 +18,7 @@ */ #include <cmdid.h> +#include <hintids.hxx> #include <wrtsh.hxx> #include <swcrsr.hxx> #include <editeng/lrspitem.hxx> @@ -463,8 +464,9 @@ bool SwWrtShell::DelRight() ( eAnchorId == RndStdIds::FLY_AT_CHAR || eAnchorId == RndStdIds::FLY_AS_CHAR ) ) { sal_Int32 nRedlineLength = 1; - // create a double ZWJ anchor point of the image to record the deletion, if needed - // (otherwise use the existing anchor point of the image anchored *as* character) + // create a double CH_TXT_TRACKED_DUMMY_CHAR anchor point of the image to record the + // deletion, if needed (otherwise use the existing anchor point of the image anchored + // *as* character) if ( eAnchorId == RndStdIds::FLY_AT_CHAR ) { nRedlineLength = 2; @@ -472,7 +474,8 @@ bool SwWrtShell::DelRight() UnSelectFrame(); RedlineFlags eOld = GetRedlineFlags(); SetRedlineFlags( eOld | RedlineFlags::Ignore ); - Insert( OUString( u"" ) ); + Insert( OUStringChar(CH_TXT_TRACKED_DUMMY_CHAR) + + OUStringChar(CH_TXT_TRACKED_DUMMY_CHAR) ); SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR); SwCursorShell::Left(1, CRSR_SKIP_CHARS); anchor.SetAnchor(GetCursor()->GetPoint());