tdf#146965 sw track changes: fix tracked table row moving

During track changes, drag & drop or Cut & Paste
a table row resulted a nested table in the first cell of
the newly inserted empty table row instead of moving
the original table row.

Test: select a table row by clicking on their left border,
and drag & drop or Cut & Paste it in a different
table row.

Note: This fixes crashing at Redo of tracked table row
insertion, too.

Regression from commit dbc82c02eb24ec1c97c6ee32069771d8deb394f9
"tdf#143358 sw: track insertion of empty table rows".

Change-Id: I9a31cae2c0e6e5e05450336a1e5b8d792035df35
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128726
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128921
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index abb6d02..c0c5c9f 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -5063,6 +5063,53 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf145089_RedlineTableRowInsertionDOCX
    assertXPath(pXmlDoc, "//page[1]//body/tab/row", 1);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testPasteTrackedTableRow)
{
    // load a 1-row table
    SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf118311.fodt");

    // turn on red-lining and show changes
    pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
                                                      | RedlineFlags::ShowInsert);
    CPPUNIT_ASSERT_MESSAGE("redlining should be on",
                           pDoc->getIDocumentRedlineAccess().IsRedlineOn());
    CPPUNIT_ASSERT_MESSAGE(
        "redlines should be visible",
        IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));

    // check table count
    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
                                                    uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());

    // check table row count
    uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable->getRows()->getCount());

    // copy table row and paste it by Paste Special->Rows Above
    dispatchCommand(mxComponent, ".uno:SelectTable", {});
    dispatchCommand(mxComponent, ".uno:Copy", {});
    dispatchCommand(mxComponent, ".uno:Escape", {});
    dispatchCommand(mxComponent, ".uno:PasteRowsBefore", {});

    // 2-row table
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTable->getRows()->getCount());

    // This was 2 (inserted as a nested table in the first cell of the new row)
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());

    // Is it a tracked row insertion? Its rejection results the original 1-row table
    dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable->getRows()->getCount());

    dispatchCommand(mxComponent, ".uno:Undo", {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTable->getRows()->getCount());

    dispatchCommand(mxComponent, ".uno:Redo", {});
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable->getRows()->getCount());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf145091)
{
    // load a deleted table, reject them, and delete only its text and export to DOCX
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx
index a7a11bb..90ca0e8 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -109,6 +109,7 @@
#include <svx/svditer.hxx>
#include <editeng/eeitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/prntitem.hxx>
#include <svx/svdpage.hxx>
#include <avmedia/mediawindow.hxx>
#include <swcrsr.hxx>
@@ -1598,6 +1599,12 @@ 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 )
                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);
@@ -1612,10 +1619,20 @@ bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndSt
                    { &aCountItem, &aAfter });
            }

            if ( eOld & RedlineFlags::On )
                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 ( eOld & RedlineFlags::On )
            {
                SvxPrintItem aTracked(RES_PRINT, false);
                rSh.GetDoc()->SetRowNotTracked( *rSh.GetCursor(), aTracked );
            }

            // restore cursor position
            if (pMark != nullptr)
            {