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 a74c51025fa4519caaf461492e4ed8e68bd34885
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: Mon Feb 28 16:32:08 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>

diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx 
b/sw/qa/extras/uiwriter/uiwriter3.cxx
index 39e4af558b3c..595eb64fddfb 100644
--- a/sw/qa/extras/uiwriter/uiwriter3.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter3.cxx
@@ -41,6 +41,7 @@
 #include <IDocumentFieldsAccess.hxx>
 #include <IDocumentLinksAdministration.hxx>
 #include <IDocumentRedlineAccess.hxx>
+#include <rootfrm.hxx>
 
 namespace
 {
@@ -2156,6 +2157,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

Reply via email to