tdf#156492 sw: fix alt-Enter in cells merged vertically

Inserting empty paragragh after the tables didn't work,
if the bottom right corner of the table contains cells
merged vertically.

Manual test: positionate the text cursor at the end
of the last paragraph of the bottom right cell of the
table (which contains also cells merged vertically), and
press alt-Enter to insert an empty paragraph after the
table.

Note: SpecialInsert, i.e. inserting empty paragraph by pressing
alt-Enter is the quick and sometimes the only possible way to insert
an empty paragraph before or after tables and sections.

Change-Id: Ic845c3d683a561784afe69588b3b1538e82c35c7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155556
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sw/qa/core/txtnode/data/special-insert-after-merged-cells.fodt b/sw/qa/core/txtnode/data/special-insert-after-merged-cells.fodt
new file mode 100644
index 0000000..55ba746
--- /dev/null
+++ b/sw/qa/core/txtnode/data/special-insert-after-merged-cells.fodt
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<office:document xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
 <office:body>
  <office:text>
   <table:table table:name="Table1">
    <table:table-column table:number-columns-repeated="2"/>
    <table:table-row>
     <table:table-cell>
      <text:p/>
     </table:table-cell>
     <table:table-cell table:number-rows-spanned="2">
      <text:p/>
     </table:table-cell>
    </table:table-row>
    <table:table-row>
     <table:table-cell>
      <text:p/>
     </table:table-cell>
     <table:covered-table-cell/>
    </table:table-row>
   </table:table>
   <text:p/>
  </office:text>
 </office:body>
</office:document>
diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx
index 640df69..4a4bf99 100644
--- a/sw/qa/core/txtnode/txtnode.cxx
+++ b/sw/qa/core/txtnode/txtnode.cxx
@@ -64,6 +64,32 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testBtlrCellChinese)
    assertXPath(pXmlDoc, "//font[1]", "vertical", "false");
}

CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testSpecialInsertAfterMergedCells)
{
    // Load a document with a table with bottom right cells merged vertically.
    // SpecialInsert with alt-Enter must work here, too.
    createSwDoc("special-insert-after-merged-cells.fodt");
    SwDoc* pDoc = getSwDoc();
    SwNodeOffset const nNodes(pDoc->GetNodes().Count());
    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
    SwDocShell* pShell = pTextDoc->GetDocShell();
    SwWrtShell* pWrtShell = pShell->GetWrtShell();
    // go to the merged cell
    pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);

    // When pressing alt-Enter on the keyboard:
    SwEditWin& rEditWin = pWrtShell->GetView().GetEditWin();
    vcl::KeyCode aKeyCode(KEY_RETURN, KEY_MOD2);
    KeyEvent aKeyEvent(' ', aKeyCode);
    rEditWin.KeyInput(aKeyEvent);

    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: nNodes + 1
    // - Actual  : nNodes
    // i.e. new empty paragraph wasn't inserted under the table
    CPPUNIT_ASSERT_EQUAL(nNodes + 1, pDoc->GetNodes().Count());
}

CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testTextBoxCopyAnchor)
{
    createSwDoc("textbox-copy-anchor.docx");
diff --git a/sw/source/core/edit/edsect.cxx b/sw/source/core/edit/edsect.cxx
index 6116a42..a7e652a 100644
--- a/sw/source/core/edit/edsect.cxx
+++ b/sw/source/core/edit/edsect.cxx
@@ -356,12 +356,31 @@ static const SwNode* lcl_SpecialInsertNode(const SwPosition* pCurrentPos)
        // we found an end if
        // - we're at or just before an end node
        // - there are only end nodes between the current node and
        //   pInnermostNode's end node
        //   pInnermostNode's end node or
        // - there are only end nodes between the last table cell merged with
        //   the current cell and pInnermostNode's end node
        SwNodeIndex aEnd( pCurrentPos->GetNode() );
        if( rCurrentNode.IsContentNode() &&
            ( pCurrentPos->GetContentIndex() ==
              rCurrentNode.GetContentNode()->Len() ) )
        {
            ++aEnd;

            // tdf#156492 handle cells merged vertically in the bottom right corner
            if ( pInnermostNode->IsTableNode() )
            {
                const SwNode* pTableBoxStartNode = pCurrentPos->GetNode().FindTableBoxStartNode();
                const SwTableBox* pTableBox = pTableBoxStartNode->GetTableBox();
                if ( pTableBox && pTableBox->getRowSpan() > 1 )
                {
                    const SwTableNode* pTableNd = pInnermostNode->FindTableNode();
                    pTableBox = & pTableBox->FindEndOfRowSpan( pTableNd->GetTable(),
                                                                        pTableBox->getRowSpan() );
                    pTableBoxStartNode = pTableBox->GetSttNd();
                    aEnd = pTableBoxStartNode->GetIndex() + 2;
                }
            }
        }
        while( (aEnd != pInnermostNode->EndOfSectionNode()->GetIndex()) &&
               aEnd.GetNode().IsEndNode() )
            ++aEnd;