sw/inc/swtable.hxx                            |    7 ++
 sw/qa/extras/uiwriter/uiwriter4.cxx           |   62 +++++++++++++++++++++++++-
 sw/source/core/doc/DocumentRedlineManager.cxx |   33 +++++++++++--
 sw/source/core/table/swtable.cxx              |   18 +++++--
 4 files changed, 105 insertions(+), 15 deletions(-)

New commits:
commit 1edaee2f03bce0efa409c592919458658d0aa751
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Tue Dec 21 11:50:19 2021 +0100
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Tue Dec 21 15:31:00 2021 +0100

    tdf#146244 sw: fix Undo of accepting table row insertion
    
    Fix Undo of accepting table row insertion to get back
    the "false" value of HasTextChangesOnly property and the
    associated light blue table row background.
    
    This fixes also the missing update of the table row
    background at accepting the table row insertion.
    
    Follow-up to commit 8c028b7e41e3d350d0e67005b16faf0159cc5c12
    "tdf#146244 sw: update HasTextChangesOnly in modified rows".
    
    Change-Id: I8e2436b6b7b67f06037481955ff22cdbc2b22dc0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127228
    Tested-by: Jenkins
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/sw/inc/swtable.hxx b/sw/inc/swtable.hxx
index 652b254a8c86..33a85f2c62a6 100644
--- a/sw/inc/swtable.hxx
+++ b/sw/inc/swtable.hxx
@@ -399,12 +399,15 @@ public:
     bool IsEmpty() const;
 
     // Update TextChangesOnly property based on the redlines of the table row.
-    // rRedlinePos: search from this redline to speed up SwTable::IsDeleted().
+    // rRedlinePos: search from this redline index to speed up 
SwTable::IsDeleted().
+    // bUpdateProperty: don't update HasTextChangesOnly property, if 
bUpdateProperty = false.
+    // Set rRedlinePos after the last redline index of the table row.
     // Return with the redline, which associated to the row change (latest 
deletion
     // in the case of deleted row, the first insertion in the case of row 
insertion
     // or npos, if TextChangesOnly is true, i.e. the table row is not deleted 
or inserted).
     // Cache also the type of the redline associated to the changed table row.
-    SwRedlineTable::size_type UpdateTextChangesOnly(SwRedlineTable::size_type& 
rRedlinePos) const;
+    SwRedlineTable::size_type UpdateTextChangesOnly(
+        SwRedlineTable::size_type& rRedlinePos, bool bUpdateProperty = true) 
const;
     // is it a tracked deleted row
     bool IsDeleted(SwRedlineTable::size_type& rRedlinePos) const;
     // set/get (if it's possible, cached) redline type
diff --git a/sw/qa/extras/uiwriter/uiwriter4.cxx 
b/sw/qa/extras/uiwriter/uiwriter4.cxx
index bafc66489929..726a939a55c9 100644
--- a/sw/qa/extras/uiwriter/uiwriter4.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter4.cxx
@@ -202,6 +202,7 @@ public:
     void testTdf104814();
     void testTableRedlineRedoCrash();
     void testTableRemoveHasTextChangesOnly();
+    void testTableRemoveHasTextChangesOnly2();
     void testTdf66405();
     void testTdf35021_tabOverMarginDemo();
     void testTdf106701_tabOverMarginAutotab();
@@ -326,6 +327,7 @@ public:
     CPPUNIT_TEST(testTdf104814);
     CPPUNIT_TEST(testTableRedlineRedoCrash);
     CPPUNIT_TEST(testTableRemoveHasTextChangesOnly);
+    CPPUNIT_TEST(testTableRemoveHasTextChangesOnly2);
     CPPUNIT_TEST(testTdf66405);
     CPPUNIT_TEST(testTdf35021_tabOverMarginDemo);
     CPPUNIT_TEST(testTdf106701_tabOverMarginAutotab);
@@ -1682,7 +1684,6 @@ void SwUiWriterTest4::testTableRedlineRedoCrash()
 
 void SwUiWriterTest4::testTableRemoveHasTextChangesOnly()
 {
-    //createSwDoc(DATA_DIRECTORY, "tdf91292_paraBackground.docx");
     SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "TC-table-del-add.docx");
     CPPUNIT_ASSERT(pDoc);
     SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
@@ -1753,6 +1754,65 @@ void SwUiWriterTest4::testTableRemoveHasTextChangesOnly()
     assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row", 4);
 }
 
+void SwUiWriterTest4::testTableRemoveHasTextChangesOnly2()
+{
+    SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "TC-table-del-add.docx");
+    CPPUNIT_ASSERT(pDoc);
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    CPPUNIT_ASSERT(pWrtShell);
+
+    // disable Record Changes
+    dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+    CPPUNIT_ASSERT_MESSAGE("redlining should be off",
+                           !pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+
+    // check redline count
+    SwEditShell* const pEditShell(pDoc->GetEditShell());
+    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(14), 
pEditShell->GetRedlineCount());
+
+    // 4 rows in Show Changes mode
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+    assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row", 4);
+
+    // Move the cursor to the tracked insertion, after the first redline to 
activate the
+    // acception of the whole table row insertion with a single "Accept Change"
+    pWrtShell->Down(/*bSelect=*/false);
+    pWrtShell->Down(/*bSelect=*/false);
+    pWrtShell->Down(/*bSelect=*/false);
+    pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, 
/*bBasicCall=*/false);
+    Scheduler::ProcessEventsToIdle();
+    dispatchCommand(mxComponent, ".uno:AcceptTrackedChange", {});
+    Scheduler::ProcessEventsToIdle();
+    discardDumpedLayout();
+    pXmlDoc = parseLayoutDump();
+    // Accepting tracked insertion results still 4 rows, but less redlines
+    assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row", 4);
+    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(11), 
pEditShell->GetRedlineCount());
+
+    // Undo: 4 rows again
+    pDoc->GetIDocumentUndoRedo().Undo();
+    discardDumpedLayout();
+    pXmlDoc = parseLayoutDump();
+    assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row", 4);
+    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(14), 
pEditShell->GetRedlineCount());
+
+    // To check Undo of HasTextChangesOnly reject the same row results 3 rows
+    dispatchCommand(mxComponent, ".uno:Escape", {});
+    dispatchCommand(mxComponent, ".uno:RejectTrackedChange", {});
+    Scheduler::ProcessEventsToIdle();
+    discardDumpedLayout();
+    pXmlDoc = parseLayoutDump();
+    // This was 4 (lost HasTextChangesOnly)
+    assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row", 3);
+
+    // Undo: 4 rows again
+    pDoc->GetIDocumentUndoRedo().Undo();
+    discardDumpedLayout();
+    pXmlDoc = parseLayoutDump();
+    assertXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row", 4);
+    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(14), 
pEditShell->GetRedlineCount());
+}
+
 void SwUiWriterTest4::testTdf66405()
 {
     // Imported formula should have zero margins
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx 
b/sw/source/core/doc/DocumentRedlineManager.cxx
index 32ab0a476f6a..69bbf3d7ac67 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -462,7 +462,8 @@ namespace
     }
 
     // at rejection of a deletion in a table, remove the tracking of the table 
row
-    void lcl_RemoveTrackingOfTableRow( const SwPosition* pPos )
+    // (also at accepting the last redline insertion of a tracked table row 
insertion)
+    void lcl_RemoveTrackingOfTableRow( const SwPosition* pPos, bool 
bRejectDeletion )
     {
         const SwTableBox* pBox = pPos->nNode.GetNode().GetTableBox();
         if ( !pBox )
@@ -474,9 +475,21 @@ namespace
         // table row property "HasTextChangesOnly" is set and its value is 
false
         if ( pHasTextChangesOnlyProp && !pHasTextChangesOnlyProp->GetValue() )
         {
-            SvxPrintItem aUnsetTracking(RES_PRINT, true);
-            SwCursor aCursor( *pPos, nullptr );
-            pPos->GetDoc().SetRowNotTracked( aCursor, aUnsetTracking );
+            bool bNoMoreInsertion = false;
+            if ( !bRejectDeletion )
+            {
+                SwRedlineTable::size_type nPos = 0;
+                SwRedlineTable::size_type nInsert = 
pLine->UpdateTextChangesOnly(nPos, /*bUpdateProperty=*/false);
+
+                if ( SwRedlineTable::npos == nInsert )
+                    bNoMoreInsertion = true;
+            }
+            if ( bRejectDeletion || bNoMoreInsertion )
+            {
+                SvxPrintItem aUnsetTracking(RES_PRINT, true);
+                SwCursor aCursor( *pPos, nullptr );
+                pPos->GetDoc().SetRowNotTracked( aCursor, aUnsetTracking );
+            }
         }
     }
 
@@ -535,7 +548,15 @@ namespace
 
                 case SwComparePosition::Outside:
                 case SwComparePosition::Equal:
-                    rArr.DeleteAndDestroy( rPos-- );
+                    {
+                        bool bInsert = RedlineType::Insert == pRedl->GetType();
+                        SwPosition aPos(pRedl->Start()->nNode);
+                        rArr.DeleteAndDestroy( rPos-- );
+
+                        // remove tracking of the table row, if needed
+                        if ( bInsert )
+                            lcl_RemoveTrackingOfTableRow( &aPos, 
/*bRejectDelete=*/false );
+                    }
                     break;
 
                 default:
@@ -766,7 +787,7 @@ namespace
                     pRedl->GetExtraData()->Reject( *pRedl );
 
                 // remove tracking of the table row, if needed
-                lcl_RemoveTrackingOfTableRow( updatePaM.End() );
+                lcl_RemoveTrackingOfTableRow( updatePaM.End(), 
/*bRejectDelete=*/true );
 
                 switch( eCmp )
                 {
diff --git a/sw/source/core/table/swtable.cxx b/sw/source/core/table/swtable.cxx
index 183775c42ecc..101f5245f5ad 100644
--- a/sw/source/core/table/swtable.cxx
+++ b/sw/source/core/table/swtable.cxx
@@ -1599,7 +1599,8 @@ bool SwTable::IsDeleted() const
 // at tracked row insertion, return with the oldest insertion in the row, which
 // contain the change data of the row change.
 // If the return value is SwRedlineTable::npos, there is no tracked row change.
-SwRedlineTable::size_type 
SwTableLine::UpdateTextChangesOnly(SwRedlineTable::size_type& rRedlinePos) const
+SwRedlineTable::size_type SwTableLine::UpdateTextChangesOnly(
+    SwRedlineTable::size_type& rRedlinePos, bool bUpdateProperty ) const
 {
     SwRedlineTable::size_type nRet = SwRedlineTable::npos;
     const SwRedlineTable& aRedlineTable = 
GetFrameFormat()->GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
@@ -1722,11 +1723,16 @@ SwRedlineTable::size_type 
SwTableLine::UpdateTextChangesOnly(SwRedlineTable::siz
             // no longer tracked row insertion or deletion
             nRet = SwRedlineTable::npos;
             // set TextChangesOnly = true to remove the tracked deletion
-            SvxPrintItem aUnsetTracking(RES_PRINT, true);
-            SwFrameFormat *pFormat = 
const_cast<SwTableLine*>(this)->ClaimFrameFormat();
-            pFormat->LockModify();
-            pFormat->SetFormatAttr( aUnsetTracking );
-            pFormat->UnlockModify();
+            // FIXME Undo is not supported here (this is only a fallback,
+            // because using SetRowNotTracked() is not recommended here)
+            if ( bUpdateProperty )
+            {
+                SvxPrintItem aUnsetTracking(RES_PRINT, true);
+                SwFrameFormat *pFormat = 
const_cast<SwTableLine*>(this)->ClaimFrameFormat();
+                pFormat->LockModify();
+                pFormat->SetFormatAttr( aUnsetTracking );
+                pFormat->UnlockModify();
+            }
         }
     }
 

Reply via email to