ofz#18534 sw: WW8 import: avoid creating redlines that overlap...

...with fieldmarks, as the editing operations already do.

This was triggering ~SwIndexReg assert when creating this redline:

$4 = "     \b\nfür \a\003     \b\nKlasse \a\003     \b\t\tSchuljahr \a\003     \b\t\a\003  \b. Halbjahr\nLeistungsbeurteilung lt. Konferenzbeschluss vom "

Change-Id: I904be93e044c4b98bb8c806357ed061692303c7a
Reviewed-on: https://gerrit.libreoffice.org/85149
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/sw/qa/core/data/ww8/pass/ofz18534-1.doc b/sw/qa/core/data/ww8/pass/ofz18534-1.doc
new file mode 100644
index 0000000..6b50fdd
--- /dev/null
+++ b/sw/qa/core/data/ww8/pass/ofz18534-1.doc
Binary files differ
diff --git a/sw/source/filter/basflt/fltshell.cxx b/sw/source/filter/basflt/fltshell.cxx
index 359ab56..a9727bd 100644
--- a/sw/source/filter/basflt/fltshell.cxx
+++ b/sw/source/filter/basflt/fltshell.cxx
@@ -66,6 +66,7 @@
#include <swtable.hxx>
#include <tox.hxx>
#include <expfld.hxx>
#include <bookmrk.hxx>
#include <section.hxx>
#include <tblsel.hxx>
#include <pagedesc.hxx>
@@ -131,7 +132,7 @@ void SwFltStackEntry::SetEndPos(const SwPosition& rEndPos)
    m_aPtPos.SetPos(rEndPos);
}

bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, bool bCheck,
bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, RegionMode const eCheck,
    const SwFltPosition &rMkPos, const SwFltPosition &rPtPos, bool bIsParaEnd,
    sal_uInt16 nWhich)
{
@@ -180,16 +181,22 @@ bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, bool bCheck,
    OSL_ENSURE( CheckNodesRange( rRegion.Start()->nNode,
                             rRegion.End()->nNode, true ),
             "attribute or similar crosses section-boundaries" );
    if( bCheck )
        return CheckNodesRange( rRegion.Start()->nNode,
                                rRegion.End()->nNode, true );
    else
        return true;
    bool bRet = true;
    if (eCheck & RegionMode::CheckNodes)
    {
        bRet &= CheckNodesRange(rRegion.Start()->nNode,
                                rRegion.End()->nNode, true);
    }
    if (eCheck & RegionMode::CheckFieldmark)
    {
        bRet &= !sw::mark::IsFieldmarkOverlap(rRegion);
    }
    return bRet;
}

bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, bool bCheck) const
bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, RegionMode eCheck) const
{
    return MakeRegion(pDoc, rRegion, bCheck, m_aMkPos, m_aPtPos, bIsParaEnd,
    return MakeRegion(pDoc, rRegion, eCheck, m_aMkPos, m_aPtPos, bIsParaEnd,
        pAttr->Which());
}

@@ -489,7 +496,7 @@ static bool MakePoint(const SwFltStackEntry& rEntry, SwDoc* pDoc,
static bool MakeBookRegionOrPoint(const SwFltStackEntry& rEntry, SwDoc* pDoc,
                    SwPaM& rRegion )
{
    if (rEntry.MakeRegion(pDoc, rRegion, true/*bCheck*/ ))
    if (rEntry.MakeRegion(pDoc, rRegion, SwFltStackEntry::RegionMode::CheckNodes))
    {
        if (rRegion.GetPoint()->nNode.GetNode().FindTableBoxStartNode()
              != rRegion.GetMark()->nNode.GetNode().FindTableBoxStartNode())
@@ -591,7 +598,7 @@ void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
            SwNumRule* pNumRule = pDoc->FindNumRulePtr( rNumNm );
            if( pNumRule )
            {
                if( rEntry.MakeRegion(pDoc, aRegion, true))
                if (rEntry.MakeRegion(pDoc, aRegion, SwFltStackEntry::RegionMode::CheckNodes))
                {
                    SwNodeIndex aTmpStart( aRegion.Start()->nNode );
                    SwNodeIndex aTmpEnd( aTmpStart );
@@ -757,7 +764,8 @@ void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
        break;
    case RES_FLTR_REDLINE:
        {
            if (rEntry.MakeRegion(pDoc, aRegion, true))
            if (rEntry.MakeRegion(pDoc, aRegion,
                    SwFltStackEntry::RegionMode::CheckNodes|SwFltStackEntry::RegionMode::CheckFieldmark))
            {
                pDoc->getIDocumentRedlineAccess().SetRedlineFlags( RedlineFlags::On
                                              | RedlineFlags::ShowInsert
@@ -791,7 +799,7 @@ void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
            {
                rEntry.SetIsParaEnd( IsParaEndInCPs(nStart,nEnd,bHasSdOD) );
            }
            if (rEntry.MakeRegion(pDoc, aRegion, false))
            if (rEntry.MakeRegion(pDoc, aRegion, SwFltStackEntry::RegionMode::NoCheck))
            {
                if (rEntry.IsParaEnd())
                {
diff --git a/sw/source/filter/inc/fltshell.hxx b/sw/source/filter/inc/fltshell.hxx
index 3bff180..e0b41c9 100644
--- a/sw/source/filter/inc/fltshell.hxx
+++ b/sw/source/filter/inc/fltshell.hxx
@@ -100,10 +100,11 @@ public:
    SW_DLLPUBLIC SwFltStackEntry(const SwPosition & rStartPos, std::unique_ptr<SfxPoolItem> pHt );
    SW_DLLPUBLIC ~SwFltStackEntry();

    enum class RegionMode { NoCheck = 0, CheckNodes = 1<<0, CheckFieldmark = 1<<1 };
    SW_DLLPUBLIC void SetEndPos(  const SwPosition & rEndPos);
    SW_DLLPUBLIC bool MakeRegion(SwDoc* pDoc, SwPaM& rRegion, bool bCheck) const;
    SW_DLLPUBLIC bool MakeRegion(SwDoc* pDoc, SwPaM& rRegion, RegionMode eCheck) const;
    SW_DLLPUBLIC static bool MakeRegion(SwDoc* pDoc, SwPaM& rRegion,
        bool bCheck, const SwFltPosition &rMkPos, const SwFltPosition &rPtPos, bool bIsParaEnd=false,
        RegionMode eCheck, const SwFltPosition &rMkPos, const SwFltPosition &rPtPos, bool bIsParaEnd=false,
        sal_uInt16 nWhich=0);

    void SetStartCP(sal_Int32 nCP) {mnStartCP = nCP;}
@@ -114,6 +115,8 @@ public:
    void SetIsParaEnd(bool bArg){ bIsParaEnd = bArg;}
};

template<> struct o3tl::typed_flags<SwFltStackEntry::RegionMode>: o3tl::is_typed_flags<SwFltStackEntry::RegionMode, 0x03> {};

class SW_DLLPUBLIC SwFltControlStack
{
private:
diff --git a/sw/source/filter/ww8/writerhelper.cxx b/sw/source/filter/ww8/writerhelper.cxx
index 512812f..8628816 100644
--- a/sw/source/filter/ww8/writerhelper.cxx
+++ b/sw/source/filter/ww8/writerhelper.cxx
@@ -782,8 +782,8 @@ namespace sw
        void SetInDocAndDelete::operator()(std::unique_ptr<SwFltStackEntry>& pEntry)
        {
            SwPaM aRegion(pEntry->m_aMkPos.m_nNode);
            if (
                pEntry->MakeRegion(&mrDoc, aRegion, true) &&
            if (pEntry->MakeRegion(&mrDoc, aRegion,
                    SwFltStackEntry::RegionMode::CheckNodes|SwFltStackEntry::RegionMode::CheckFieldmark) &&
                (*aRegion.GetPoint() != *aRegion.GetMark())
            )
            {
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 2af0bee..3c39619 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -1386,7 +1386,7 @@ void SwWW8FltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
                    paragraph indent to be relative to the new paragraph indent
                */
                SwPaM aRegion(rTmpPos);
                if (rEntry.MakeRegion(pDoc, aRegion, false))
                if (rEntry.MakeRegion(pDoc, aRegion, SwFltStackEntry::RegionMode::NoCheck))
                {
                    SvxLRSpaceItem aNewLR( *static_cast<SvxLRSpaceItem*>(rEntry.pAttr.get()) );
                    sal_uLong nStart = aRegion.Start()->nNode.GetIndex();
@@ -1452,7 +1452,7 @@ void SwWW8FltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
        case RES_TXTATR_INETFMT:
            {
                SwPaM aRegion(rTmpPos);
                if (rEntry.MakeRegion(pDoc, aRegion, false))
                if (rEntry.MakeRegion(pDoc, aRegion, SwFltStackEntry::RegionMode::NoCheck))
                {
                    SwFrameFormat *pFrame;
                    // If we have just one single inline graphic then
diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx
index f16ca75..8ccbca6 100644
--- a/sw/source/filter/ww8/ww8par6.cxx
+++ b/sw/source/filter/ww8/ww8par6.cxx
@@ -3424,10 +3424,8 @@ bool SwWW8ImplReader::ConvertSubToGraphicPlacement()
        SwFltPosition aPtPos(*m_pPaM->GetPoint());

        SwFrameFormat *pFlyFormat = nullptr;
        if (
             SwFltStackEntry::MakeRegion(&m_rDoc,aRegion,false,aMkPos,aPtPos) &&
             nullptr != (pFlyFormat = ContainsSingleInlineGraphic(aRegion))
           )
        if (SwFltStackEntry::MakeRegion(&m_rDoc, aRegion, SwFltStackEntry::RegionMode::NoCheck, aMkPos, aPtPos)
            && nullptr != (pFlyFormat = ContainsSingleInlineGraphic(aRegion)))
        {
            m_xCtrlStck->DeleteAndDestroy(nPos);
            pFlyFormat->SetFormatAttr(SwFormatVertOrient(0, text::VertOrientation::CHAR_CENTER, text::RelOrientation::CHAR));