tdf#137245 sw: fix AutoFormat SetBorder deleting flys

Since commit e1629c210ad78310e3d48c0756723134a27b89df ReplaceRange()
will preserve flys, so split the delete into a DeleteAndJoin() just to
join the paragraphs - which should not delete any flys because it
doesn't include the "---" so isn't at the end of the section - and
a ReplaceRange for the "---".

(regression from 28b77c89dfcafae82cf2a6d85731b643ff9290e5
 and e75dd1fc992f168f24d66595265a978071cdd277)

Change-Id: Ib995e41649f69963c823a463538958d533082ee7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104380
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@cib.de>
(cherry picked from commit 9b34dc20b6946698ae6ce2d5d859885bfb444633)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104335
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 91400f3..1354244 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -38,6 +38,9 @@
#include <sfx2/dispatch.hxx>
#include <svl/stritem.hxx>
#include <comphelper/lok.hxx>
#include <comphelper/scopeguard.hxx>
#include <editeng/acorrcfg.hxx>
#include <swacorr.hxx>
#include <txtfrm.hxx>
#include <redline.hxx>
#include <view.hxx>
@@ -331,6 +334,86 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineSplitContentNode)
    rUndoManager.Undo();
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137245)
{
    SwDoc* const pDoc(createDoc());
    SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
    SwAutoCorrect corr(*SvxAutoCorrCfg::Get().GetAutoCorrect());
    corr.GetSwFlags().bSetBorder = true;
    // sigh, it's a global... err i mean Singleton design pattern *eyeroll*
    SvxSwAutoFormatFlags flags(*SwEditShell::GetAutoFormatFlags());
    comphelper::ScopeGuard const g([=]() { SwEditShell::SetAutoFormatFlags(&flags); });
    flags.bSetBorder = true;
    SwEditShell::SetAutoFormatFlags(&flags);

    {
        SwFormatAnchor anchor(RndStdIds::FLY_AT_PARA);
        anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
        SfxItemSet flySet(pDoc->GetAttrPool(),
                          svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>{});
        flySet.Put(anchor);
        SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
        flySet.Put(size); // set a size, else we get 1 char per line...
        SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
        CPPUNIT_ASSERT(pFly != nullptr);
    }
    {
        SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
        anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
        SfxItemSet flySet(pDoc->GetAttrPool(),
                          svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>{});
        flySet.Put(anchor);
        SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
        flySet.Put(size); // set a size, else we get 1 char per line...
        SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
        CPPUNIT_ASSERT(pFly != nullptr);
    }
    // move cursor back to body
    pWrtShell->SttEndDoc(false);
    // keep first paragraph empty so that its flys may be deleted too
    //pWrtShell->Insert("abc");
    pWrtShell->SplitNode(false);

    {
        SwFormatAnchor anchor(RndStdIds::FLY_AT_PARA);
        anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
        SfxItemSet flySet(pDoc->GetAttrPool(),
                          svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>{});
        flySet.Put(anchor);
        SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
        flySet.Put(size); // set a size, else we get 1 char per line...
        SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
        CPPUNIT_ASSERT(pFly != nullptr);
    }
    {
        SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
        anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
        SfxItemSet flySet(pDoc->GetAttrPool(),
                          svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>{});
        flySet.Put(anchor);
        SwFormatFrameSize size(SwFrameSize::Minimum, 1000, 1000);
        flySet.Put(size); // set a size, else we get 1 char per line...
        SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
        CPPUNIT_ASSERT(pFly != nullptr);
    }

    const SwFrameFormats& rFormats = *pDoc->GetSpzFrameFormats();
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rFormats.size());

    // move cursor back to body
    pWrtShell->SttEndDoc(false);
    pWrtShell->Insert("---");
    pWrtShell->SplitNode(true);

    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rFormats.size());

    // check that the AutoFormat did something
    pWrtShell->SttEndDoc(true);
    SfxItemSet set{ pDoc->GetAttrPool(), svl::Items<RES_BOX, RES_BOX>{} };
    pWrtShell->GetCurParAttr(set);
    CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, set.GetItemState(RES_BOX, false));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf132236)
{
    load(DATA_DIRECTORY, "tdf132236.odt");
diff --git a/sw/source/core/edit/autofmt.cxx b/sw/source/core/edit/autofmt.cxx
index ac69ff2..7588104 100644
--- a/sw/source/core/edit/autofmt.cxx
+++ b/sw/source/core/edit/autofmt.cxx
@@ -1248,7 +1248,7 @@ void SwAutoFormat::DelEmptyLine( bool bTstNextPara )
    // delete blanks in empty paragraph
    m_aDelPam.DeleteMark();
    *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(
            TextFrameIndex(m_pCurTextFrame->GetText().getLength()));
            TextFrameIndex(0));
    m_aDelPam.SetMark();

    m_aDelPam.GetMark()->nNode = m_pCurTextFrame->GetTextNodeFirst()->GetIndex() - 1;
@@ -1267,16 +1267,25 @@ void SwAutoFormat::DelEmptyLine( bool bTstNextPara )
        if( pTNd )
        {
            m_aDelPam.GetMark()->nContent.Assign( pTNd, 0 );
            *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
            *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(
                TextFrameIndex(m_pCurTextFrame->GetText().getLength()));
        }
    }
    else
    {
        *m_aDelPam.GetMark() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
        pTNd = m_pCurTextNd;
    }
    if( pTNd )
        DeleteSel( m_aDelPam );
    {   // join with previous or next paragraph
        DeleteSel(m_aDelPam);
    }
    assert(m_aDelPam.GetNode().IsTextNode());
    assert(!m_aDelPam.HasMark());
    m_aDelPam.SetMark(); // mark remains at join position
    m_pCurTextFrame = GetFrame(*m_aDelPam.GetNode().GetTextNode());
    // replace until the end of the merged paragraph
    *m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(
        TextFrameIndex(m_pCurTextFrame->GetText().getLength()));
    if (*m_aDelPam.GetPoint() != *m_aDelPam.GetMark())
    {   // tdf#137245 replace (not delete) to preserve any flys
        m_pDoc->getIDocumentContentOperations().ReplaceRange(m_aDelPam, "", false);
    }

    m_aDelPam.DeleteMark();
    ClearRedlineText();