sw/qa/extras/uiwriter/uiwriter3.cxx | 46 ++++++++++++++++++ sw/source/core/doc/docnum.cxx | 4 + sw/source/core/frmedt/fetab.cxx | 92 ++++++++++++++++++++++++++++++------ 3 files changed, 126 insertions(+), 16 deletions(-)
New commits: commit dc3f29bca53ef365ec12694feefe76f0e81eccfa Author: László Németh <nem...@numbertext.org> AuthorDate: Mon Feb 28 12:35:27 2022 +0100 Commit: László Németh <nem...@numbertext.org> CommitDate: Tue Mar 1 14:09:57 2022 +0100 tdf#146962 sw: hide deleted row at deletion in Hide Changes In Hide Changes mode, deleting table rows with change tracking wasn't applied on the table layout immediately, only using Show Changes and Hide Changes again. Now the deleted row removed from the table instead leaving an empty table row (except the last row of a wholly deleted table). See also commit 95213407dfcbf34056037d60243ff915340d1a2e "tdf#146622 sw crash fix: don't delete already deleted rows". Change-Id: I864957cafa38e631a65db0670c7b566cb689f4cd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130701 Tested-by: Jenkins Reviewed-by: László Németh <nem...@numbertext.org> (cherry picked from commit a74c51025fa4519caaf461492e4ed8e68bd34885) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130685 Tested-by: László Németh <nem...@numbertext.org> diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx b/sw/qa/extras/uiwriter/uiwriter3.cxx index d2123c33b20c..a7db089432e0 100644 --- a/sw/qa/extras/uiwriter/uiwriter3.cxx +++ b/sw/qa/extras/uiwriter/uiwriter3.cxx @@ -48,6 +48,7 @@ #include <IDocumentFieldsAccess.hxx> #include <IDocumentLinksAdministration.hxx> #include <IDocumentRedlineAccess.hxx> +#include <rootfrm.hxx> namespace { @@ -1943,6 +1944,51 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf146622) CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTables->getCount()); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf146962) +{ + // load a 2-row table, set Hide Changes mode and delete the first row with change tracking + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf116789.fodt"); + CPPUNIT_ASSERT(pDoc); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell); + + // enable redlining + dispatchCommand(mxComponent, ".uno:TrackChanges", {}); + CPPUNIT_ASSERT_MESSAGE("redlining should be on", + pDoc->getIDocumentRedlineAccess().IsRedlineOn()); + // hide changes + dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {}); + CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines()); + + dispatchCommand(mxComponent, ".uno:DeleteRows", {}); + + // Without the fix in place, the deleted row would be visible + + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + // This was 2 + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 1); + + // check it in Show Changes mode + + dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {}); + CPPUNIT_ASSERT(!pWrtShell->GetLayout()->IsHideRedlines()); + + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + // 2 rows are visible now + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2); + + // check it in Hide Changes mode again + + dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {}); + CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines()); + + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + // only a single row is visible again + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 1); +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf135014) { createSwDoc(); diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx index 12b23c2fbb42..2cbfb7a6a4df 100644 --- a/sw/source/core/doc/docnum.cxx +++ b/sw/source/core/doc/docnum.cxx @@ -1446,7 +1446,9 @@ GotoPrevLayoutTextFrame(SwNodeIndex & rIndex, SwRootFrame const*const pLayout) { if (rIndex.GetNode().IsTextNode()) { - if (rIndex.GetNode().GetRedlineMergeFlag() != SwNode::Merge::None) + if (rIndex.GetNode().GetRedlineMergeFlag() != SwNode::Merge::None && + // not a tracked row deletion in Hide Changes mode + rIndex.GetNode().GetTextNode()->getLayoutFrame(pLayout) ) { rIndex = *static_cast<SwTextFrame*>(rIndex.GetNode().GetTextNode()->getLayoutFrame(pLayout))->GetMergedPara()->pFirstNode; } diff --git a/sw/source/core/frmedt/fetab.cxx b/sw/source/core/frmedt/fetab.cxx index ec9968271d3d..7bb2ff5edc68 100644 --- a/sw/source/core/frmedt/fetab.cxx +++ b/sw/source/core/frmedt/fetab.cxx @@ -328,32 +328,41 @@ bool SwFEShell::DeleteRow(bool bCompleteTable) CurrShell aCurr( this ); - // tracked deletion: remove only textbox content, - // and set IsNoTracked table line property to false - if ( GetDoc()->GetDocShell()->IsChangeRecording() ) - { - // all rows have already had tracked row change in the table selection - if ( !SwDoc::HasRowNotTracked( *getShellCursor( false ) ) ) - return false; + bool bRecordChanges = GetDoc()->GetDocShell()->IsChangeRecording(); + bool bRecordAndHideChanges = bRecordChanges && + GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout()->IsHideRedlines(); + + // tracked deletion: all rows have already had tracked row change in the table selection + if ( bRecordChanges && !SwDoc::HasRowNotTracked( *getShellCursor( false ) ) ) + return false; - SwEditShell* pEditShell = GetDoc()->GetEditShell(); + if ( bRecordChanges ) StartUndo(bCompleteTable ? SwUndoId::UI_TABLE_DELETE : SwUndoId::ROW_DELETE); - StartAllAction(); + StartAllAction(); + + // tracked deletion: remove only textbox content, + // and set IsNoTracked table line property to false + if ( bRecordChanges ) + { SvxPrintItem aNotTracked(RES_PRINT, false); GetDoc()->SetRowNotTracked( *getShellCursor( false ), aNotTracked ); if ( SwWrtShell* pWrtShell = dynamic_cast<SwWrtShell*>(this) ) pWrtShell->SelectTableRow(); - pEditShell->Delete(); + // don't need to remove the row frames in Show Changes mode + if ( !bRecordAndHideChanges ) + { + SwEditShell* pEditShell = GetDoc()->GetEditShell(); + pEditShell->Delete(); - EndAllActionAndCall(); - EndUndo(bCompleteTable ? SwUndoId::UI_TABLE_DELETE : SwUndoId::ROW_DELETE); - return true; - } + EndAllActionAndCall(); + EndUndo(bCompleteTable ? SwUndoId::UI_TABLE_DELETE : SwUndoId::ROW_DELETE); - StartAllAction(); + return true; + } + } // search for boxes via the layout bool bRet; @@ -425,6 +434,32 @@ bool SwFEShell::DeleteRow(bool bCompleteTable) pNextBox = pNextBox->FindPreviousBox( pTableNd->GetTable(), pNextBox ); } + // delete row content in Hide Changes mode + if ( bRecordAndHideChanges ) + { + SwEditShell* pEditShell = GetDoc()->GetEditShell(); + + // select the rows deleted with change tracking + if ( SwWrtShell* pWrtShell = dynamic_cast<SwWrtShell*>(this) ) + { + pWrtShell->SelectTableRow(); + SwShellTableCursor* pTableCursor = GetTableCursor(); + auto pStt = aBoxes[0]; + auto pEnd = aBoxes.back(); + pTableCursor->DeleteMark(); + + // set start and end of the selection + pTableCursor->GetPoint()->nNode = *pEnd->GetSttNd(); + pTableCursor->Move( fnMoveForward, GoInContent ); + pTableCursor->SetMark(); + pTableCursor->GetPoint()->nNode = *pStt->GetSttNd()->EndOfSectionNode(); + pTableCursor->Move( fnMoveBackward, GoInContent ); + pWrtShell->UpdateCursor(); + } + + pEditShell->Delete(); + } + SwNodeOffset nIdx; if( pNextBox ) // put cursor here nIdx = pNextBox->GetSttIdx() + 1; @@ -444,6 +479,33 @@ bool SwFEShell::DeleteRow(bool bCompleteTable) pPam->SetMark(); // both want something pPam->DeleteMark(); } + + // remove row frames in Hide Changes mode + if ( bRecordAndHideChanges ) + { + for (auto & rpFndLine : aFndBox.GetLines()) + { + SwTableLine* pTmpLine = rpFndLine->GetLine(); + SwIterator<SwRowFrame,SwFormat> aIt( *pTmpLine->GetFrameFormat() ); + for( SwRowFrame* pRowFrame = aIt.First(); pRowFrame; pRowFrame = aIt.Next() ) + { + auto pTabFrame = pRowFrame->GetUpper(); + // FIXME remove table frame instead of keeping the last row frame + if ( pTabFrame->IsTabFrame() && pTabFrame->Lower() == pTabFrame->GetLastLower() ) + break; + + if( pRowFrame->GetTabLine() == pTmpLine ) + { + pRowFrame->RemoveFromLayout(); + SwFrame::DestroyFrame(pRowFrame); + } + } + } + + EndAllActionAndCall(); + EndUndo(bCompleteTable ? SwUndoId::UI_TABLE_DELETE : SwUndoId::ROW_DELETE); + return true; + } } // now delete the lines