sw/inc/doc.hxx                       |    2 
 sw/inc/swtable.hxx                   |    4 -
 sw/qa/extras/uiwriter/uiwriter6.cxx  |   79 +++++++++++++++++++++++++++++++++++
 sw/source/core/doc/tblrwcl.cxx       |    9 ++-
 sw/source/core/docnode/ndtbl.cxx     |    4 -
 sw/source/core/frmedt/fetab.cxx      |    5 +-
 sw/source/core/table/swnewtable.cxx  |    8 +--
 sw/source/uibase/dochdl/swdtflvr.cxx |   16 -------
 8 files changed, 98 insertions(+), 29 deletions(-)

New commits:
commit 2886d09892220058d34112968d4788bc3acc08da
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Thu Sep 28 17:32:24 2023 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Fri Sep 29 09:03:58 2023 +0200

    tdf#157492 sw: fix tracked drag & drop of table row
    
    Selecting table rows by the left row border, and
    moving them via drag & drop resulted only tracked
    deletion, but not tracked insertion.
    
    See also commit 3e6125c72f8c07c14df42d45571cab44f24e9f70
    "tdf#155846 sw tracked table column: fix drag & drop".
    
    This reverts also commit 5a1c19624eda0c8b847af0dcee70b82502578ceb
    "tdf#146965 sw track changes: fix tracked table row moving".
    
    Change-Id: I7287e46188eee123b5fd36a5ec7ac5311699840b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157382
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>
    (cherry picked from commit 65efbf64cfa30ba96bc9f0ba539eb1414b861c49)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157323
    Tested-by: Jenkins

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 86fd5a67c8ca..04e12b2a4967 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -1208,7 +1208,7 @@ public:
     void InsertRow( const SwCursor& rCursor,
                     sal_uInt16 nCnt = 1, bool bBehind = true );
     bool InsertRow( const SwSelBoxes& rBoxes,
-                    sal_uInt16 nCnt = 1, bool bBehind = true );
+                    sal_uInt16 nCnt = 1, bool bBehind = true, bool 
bInsertDummy = true );
 
     // Delete Columns/Rows in table.
     enum class RowColMode { DeleteRow = 0, DeleteColumn = 1, DeleteProtected = 
2 };
diff --git a/sw/inc/swtable.hxx b/sw/inc/swtable.hxx
index a7d1bd87d4d4..3d0a5732d188 100644
--- a/sw/inc/swtable.hxx
+++ b/sw/inc/swtable.hxx
@@ -167,7 +167,7 @@ private:
     bool NewSplitRow( SwDoc&, const SwSelBoxes&, sal_uInt16, bool );
     std::optional<SwBoxSelection> CollectBoxSelection( const SwPaM& rPam ) 
const;
     void InsertSpannedRow( SwDoc& rDoc, sal_uInt16 nIdx, sal_uInt16 nCnt );
-    bool InsertRow_( SwDoc*, const SwSelBoxes&, sal_uInt16 nCnt, bool bBehind 
);
+    bool InsertRow_( SwDoc*, const SwSelBoxes&, sal_uInt16 nCnt, bool bBehind, 
bool bInsertDummy );
     bool NewInsertCol( SwDoc&, const SwSelBoxes& rBoxes, sal_uInt16 nCnt, 
bool, bool bInsertDummy );
     void FindSuperfluousRows_( SwSelBoxes& rBoxes, SwTableLine*, SwTableLine* 
);
     void AdjustWidths( const tools::Long nOld, const tools::Long nNew );
@@ -254,7 +254,7 @@ public:
     bool InsertCol( SwDoc&, const SwSelBoxes& rBoxes,
                     sal_uInt16 nCnt, bool bBehind, bool bInsertDummy );
     bool InsertRow( SwDoc*, const SwSelBoxes& rBoxes,
-                    sal_uInt16 nCnt, bool bBehind );
+                    sal_uInt16 nCnt, bool bBehind, bool bInsertDummy = true );
     void PrepareDelBoxes( const SwSelBoxes& rBoxes );
     bool DeleteSel( SwDoc*, const SwSelBoxes& rBoxes, const SwSelBoxes* 
pMerged,
         SwUndo* pUndo, const bool bDelMakeFrames, const bool bCorrBorder );
diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx 
b/sw/qa/extras/uiwriter/uiwriter6.cxx
index 716b995ec5ac..73178363b8fb 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -930,6 +930,85 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, 
testTdf147181_TrackedMovingOfMultipleTable
     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable2b->getRows()->getCount());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf157492_TrackedMovingRow)
+{
+    createSwDoc();
+    SwDoc* pDoc = getSwDoc();
+    CPPUNIT_ASSERT(pDoc);
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    CPPUNIT_ASSERT(pWrtShell);
+
+    // Create a table
+    SwInsertTableOptions TableOpt(SwInsertTableFlags::DefaultBorder, 0);
+    (void)&pWrtShell->InsertTable(TableOpt, 4, 3);
+
+    uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<container::XNameAccess> xTableNames = 
xTablesSupplier->getTextTables();
+    CPPUNIT_ASSERT(xTableNames->hasByName("Table1"));
+    uno::Reference<text::XTextTable> xTable1(xTableNames->getByName("Table1"), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount());
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable1->getColumns()->getCount());
+
+    SwXTextDocument* pTextDoc = 
dynamic_cast<SwXTextDocument*>(mxComponent.get());
+
+    // fill table with data
+    for (int i = 0; i < 3; ++i)
+    {
+        pWrtShell->Insert("x");
+        pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RIGHT);
+    }
+
+    Scheduler::ProcessEventsToIdle();
+
+    uno::Reference<text::XTextRange> xCellA1(xTable1->getCellByName("A1"), 
uno::UNO_QUERY);
+    xCellA1->setString("A1");
+    uno::Reference<text::XTextRange> xCellB1(xTable1->getCellByName("B1"), 
uno::UNO_QUERY);
+    xCellB1->setString("B1");
+    uno::Reference<text::XTextRange> xCellC1(xTable1->getCellByName("C1"), 
uno::UNO_QUERY);
+    xCellC1->setString("C1");
+
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+    assertXPathContent(pXmlDoc, "/root/page/body/tab/row[1]/cell[1]/txt", 
"A1");
+    assertXPathContent(pXmlDoc, "/root/page/body/tab/row[1]/cell[2]/txt", 
"B1");
+    assertXPathContent(pXmlDoc, "/root/page/body/tab/row[1]/cell[3]/txt", 
"C1");
+
+    // enable redlining
+    dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+    CPPUNIT_ASSERT_MESSAGE("redlining should be on",
+                           pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+
+    // Move first column of the table before the third column by drag & drop
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+    SwFrame* pPage = pLayout->Lower();
+    SwFrame* pBody = pPage->GetLower();
+    SwFrame* pTable = pBody->GetLower();
+    SwFrame* pRow1 = pTable->GetLower();
+    SwFrame* pCellA1 = pRow1->GetLower();
+    SwFrame* pRow3 = pRow1->GetNext()->GetNext();
+    SwFrame* pCellA3 = pRow3->GetLower();
+    const SwRect& rCellA1Rect = pCellA1->getFrameArea();
+    const SwRect& rCellA3Rect = pCellA3->getFrameArea();
+    Point ptTo(rCellA3Rect.Left() + rCellA3Rect.Width() / 2,
+               rCellA3Rect.Top() + rCellA3Rect.Height() / 2);
+    // select first table row by using the middle point of the left border of 
row 1
+    Point ptRow(rCellA1Rect.Left() - 5, rCellA1Rect.Top() + 
rCellA1Rect.Height() / 2);
+    pWrtShell->SelectTableRowCol(ptRow);
+
+    rtl::Reference<SwTransferable> xTransfer = new SwTransferable(*pWrtShell);
+
+    xTransfer->PrivateDrop(*pWrtShell, ptTo, /*bMove=*/true, 
/*bXSelection=*/true);
+
+    // reject changes results 4 rows again, not 5
+    dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {});
+
+    xTableNames = xTablesSupplier->getTextTables();
+    CPPUNIT_ASSERT(xTableNames->hasByName("Table1"));
+    uno::Reference<text::XTextTable> xTable2(xTableNames->getByName("Table1"), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable2->getColumns()->getCount());
+    // This was 5 (moving row without change tracking)
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable2->getRows()->getCount());
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf154599_MovingColumn)
 {
     createSwDoc();
diff --git a/sw/source/core/doc/tblrwcl.cxx b/sw/source/core/doc/tblrwcl.cxx
index c12efb06b7a0..2b5192804856 100644
--- a/sw/source/core/doc/tblrwcl.cxx
+++ b/sw/source/core/doc/tblrwcl.cxx
@@ -514,7 +514,7 @@ bool SwTable::InsertCol( SwDoc& rDoc, const SwSelBoxes& 
rBoxes, sal_uInt16 nCnt,
 }
 
 bool SwTable::InsertRow_( SwDoc* pDoc, const SwSelBoxes& rBoxes,
-                        sal_uInt16 nCnt, bool bBehind )
+                        sal_uInt16 nCnt, bool bBehind, bool bInsertDummy )
 {
     OSL_ENSURE( pDoc && !rBoxes.empty() && nCnt, "No valid Box List" );
     SwTableNode* pTableNd = 
const_cast<SwTableNode*>(rBoxes[0]->GetSttNd()->FindTableNode());
@@ -597,9 +597,12 @@ bool SwTable::InsertRow_( SwDoc* pDoc, const SwSelBoxes& 
rBoxes,
                 SvxPrintItem aSetTracking(RES_PRINT, false);
                 SwPosition aPos(*pNewTableLine->GetTabBoxes()[0]->GetSttNd());
                 SwCursor aCursor( aPos, nullptr );
-                SwPaM aPaM(*pNewTableLine->GetTabBoxes()[0]->GetSttNd(), 
SwNodeOffset(1));
-                pDoc->getIDocumentContentOperations().InsertString( aPaM,
+                if ( bInsertDummy )
+                {
+                    SwPaM aPaM(*pNewTableLine->GetTabBoxes()[0]->GetSttNd(), 
SwNodeOffset(1));
+                    pDoc->getIDocumentContentOperations().InsertString( aPaM,
                         OUStringChar(CH_TXT_TRACKED_DUMMY_CHAR) );
+                }
                 pDoc->SetRowNotTracked( aCursor, aSetTracking, /*bAll=*/false, 
/*bIns=*/true );
             }
         }
diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx
index a4158813e916..cec3e7df57c4 100644
--- a/sw/source/core/docnode/ndtbl.cxx
+++ b/sw/source/core/docnode/ndtbl.cxx
@@ -1757,7 +1757,7 @@ void SwDoc::InsertRow( const SwCursor& rCursor, 
sal_uInt16 nCnt, bool bBehind )
         InsertRow( aBoxes, nCnt, bBehind );
 }
 
-bool SwDoc::InsertRow( const SwSelBoxes& rBoxes, sal_uInt16 nCnt, bool bBehind 
)
+bool SwDoc::InsertRow( const SwSelBoxes& rBoxes, sal_uInt16 nCnt, bool 
bBehind, bool bInsertDummy )
 {
     OSL_ENSURE( !rBoxes.empty(), "No valid Box list" );
     SwTableNode* pTableNd = 
const_cast<SwTableNode*>(rBoxes[0]->GetSttNd()->FindTableNode());
@@ -1782,7 +1782,7 @@ bool SwDoc::InsertRow( const SwSelBoxes& rBoxes, 
sal_uInt16 nCnt, bool bBehind )
         ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
         rTable.SwitchFormulasToInternalRepresentation();
 
-        bRet = rTable.InsertRow( this, rBoxes, nCnt, bBehind );
+        bRet = rTable.InsertRow( this, rBoxes, nCnt, bBehind, bInsertDummy );
         if (bRet)
         {
             getIDocumentState().SetModified();
diff --git a/sw/source/core/frmedt/fetab.cxx b/sw/source/core/frmedt/fetab.cxx
index b53d6666c8ea..93e20fab036e 100644
--- a/sw/source/core/frmedt/fetab.cxx
+++ b/sw/source/core/frmedt/fetab.cxx
@@ -186,6 +186,9 @@ void SwFEShell::InsertRow( sal_uInt16 nCnt, bool bBehind )
         return;
     }
 
+    // pending drag & drop?
+    bool bAction = ActionPend();
+
     CurrShell aCurr( this );
     StartAllAction();
 
@@ -205,7 +208,7 @@ void SwFEShell::InsertRow( sal_uInt16 nCnt, bool bBehind )
     TableWait aWait( nCnt, pFrame, *GetDoc()->GetDocShell(), aBoxes.size() );
 
     if ( !aBoxes.empty() )
-        GetDoc()->InsertRow( aBoxes, nCnt, bBehind );
+        GetDoc()->InsertRow( aBoxes, nCnt, bBehind, /*bInsertDummy=*/!bAction 
);
 
     EndAllActionAndCall();
 }
diff --git a/sw/source/core/table/swnewtable.cxx 
b/sw/source/core/table/swnewtable.cxx
index 70765843388c..4e1386f4e21a 100644
--- a/sw/source/core/table/swnewtable.cxx
+++ b/sw/source/core/table/swnewtable.cxx
@@ -1205,7 +1205,7 @@ void SwTable::InsertSpannedRow( SwDoc& rDoc, sal_uInt16 
nRowIdx, sal_uInt16 nCnt
         aFSz.SetHeight( nNewHeight );
         pFrameFormat->SetFormatAttr( aFSz );
     }
-    InsertRow_( &rDoc, aBoxes, nCnt, true );
+    InsertRow_( &rDoc, aBoxes, nCnt, true, true );
     const size_t nBoxCount = rLine.GetTabBoxes().size();
     for( sal_uInt16 n = 0; n < nCnt; ++n )
     {
@@ -1510,7 +1510,7 @@ bool SwTable::NewSplitRow( SwDoc& rDoc, const SwSelBoxes& 
rBoxes, sal_uInt16 nCn
 */
 
 bool SwTable::InsertRow( SwDoc* pDoc, const SwSelBoxes& rBoxes,
-                        sal_uInt16 nCnt, bool bBehind )
+                        sal_uInt16 nCnt, bool bBehind, bool bInsertDummy )
 {
     bool bRet = false;
     if( IsNewModel() )
@@ -1527,7 +1527,7 @@ bool SwTable::InsertRow( SwDoc* pDoc, const SwSelBoxes& 
rBoxes,
             SwTableLine *pLine = GetTabLines()[ nRowIdx ];
             SwSelBoxes aLineBoxes;
             lcl_FillSelBoxes( aLineBoxes, *pLine );
-            InsertRow_( pDoc, aLineBoxes, nCnt, bBehind );
+            InsertRow_( pDoc, aLineBoxes, nCnt, bBehind, bInsertDummy );
             const size_t nBoxCount = pLine->GetTabBoxes().size();
             sal_uInt16 nOfs = bBehind ? 0 : 1;
             for( sal_uInt16 n = 0; n < nCnt; ++n )
@@ -1577,7 +1577,7 @@ bool SwTable::InsertRow( SwDoc* pDoc, const SwSelBoxes& 
rBoxes,
         CHECK_TABLE( *this )
     }
     else
-        bRet = InsertRow_( pDoc, rBoxes, nCnt, bBehind );
+        bRet = InsertRow_( pDoc, rBoxes, nCnt, bBehind, bInsertDummy );
     return bRet;
 }
 
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx 
b/sw/source/uibase/dochdl/swdtflvr.cxx
index 9e0440a71f17..a885f28cf6ed 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -1632,12 +1632,6 @@ bool SwTransferable::Paste(SwWrtShell& rSh, 
TransferableDataHelper& rData, RndSt
                                     
IDocumentMarkAccess::MarkType::UNO_BOOKMARK );
 
             // add a new empty row/column before the actual table row/column 
and go there
-            // (without setting the rows to tracked table row insertion here, 
do that at the end
-            // to avoid layout problems and unnecessary insertion of dummy 
characters for empty rows)
-            RedlineFlags eOld = 
rSh.GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags();
-            if ( eOld & RedlineFlags::On && bRowMode )
-                rSh.GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags( 
eOld | RedlineFlags::Ignore );
-
             const sal_uInt16 nDispatchSlot = bRowMode ? 
FN_TABLE_INSERT_ROW_BEFORE : FN_TABLE_INSERT_COL_BEFORE;
             pDispatch->Execute(nDispatchSlot, SfxCallMode::SYNCHRON);
             pDispatch->Execute(bRowMode ? FN_LINE_UP : FN_CHAR_LEFT, 
SfxCallMode::SYNCHRON);
@@ -1652,20 +1646,10 @@ bool SwTransferable::Paste(SwWrtShell& rSh, 
TransferableDataHelper& rData, RndSt
                     { &aCountItem, &aAfter });
             }
 
-            if ( eOld & RedlineFlags::On && bRowMode )
-                rSh.GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags( 
eOld );
-
             // paste rows
             bool bResult = SwTransferable::PasteData( rData, rSh, nAction, 
nActionFlags, nFormat,
                                         nDestination, false, false, nullptr, 
0, false, nAnchorType, bIgnoreComments, &aPasteContext );
 
-            // set tracked insertion, if it's not in a drag & drop action
-            if ( !rSh.ActionPend() && ( eOld & RedlineFlags::On) && bRowMode )
-            {
-                SvxPrintItem aTracked(RES_PRINT, false);
-                rSh.GetDoc()->SetRowNotTracked( *rSh.GetCursor(), aTracked );
-            }
-
             // restore cursor position
             if (pMark != nullptr)
             {

Reply via email to