tdf#149649 sw_fieldmarkhide: delete any fieldmarks overlapping cells

The DOCX bugdoc has a field that starts in the first cell of a table, but
ends outside the table.

[  28]  0x3690e10           TableNode ,
[  29]   0x78d6f80          StartNode ,
[  30]    0x6cfb408          TextNode "\a FORMTEXT \003Data File",
[  31]   0x6bf9620            EndNode ,

[ 631]  0x779c768            TextNode "",
[ 632]  0x69bd5f8            TextNode "\b",
[ 633] 0x656f150              EndNode },

This triggers an assert in layout:
soffice.bin: sw/source/core/layout/frmtool.cxx:1971: void InsertCnt_(SwLayoutFrame*, SwDoc*, SwNodeOffset, bool, SwNodeOffset, SwFrame*, sw::FrameMode): Assertion `!pLayout->HasMergedParas() || pNd->GetRedlineMergeFlag() != SwNode::Merge::Hidden' failed.

This bad documnet model is created from writerfilter in a call to
SwXText::convertToTable(), so add some preventive code there.

The end of the field is erroneously also at the end of the body instead
of a few paragraphs below the 1st table, because in PopFieldContext() the
xTextAppend->createTextCursorByRange(pContext->GetStartRange()) throws,
due to the bad document model.

It turns out that Word can actually load this document, but the
behaviour is rather funny and would be difficult to replicate...

Change-Id: I20b9293db8888511bc0066c775d54fc59fcaa349
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136906
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx
index a837d42..c34319e 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -61,6 +61,7 @@
#include <doc.hxx>
#include <IDocumentRedlineAccess.hxx>
#include <IDocumentUndoRedo.hxx>
#include <bookmark.hxx>
#include <redline.hxx>
#include <swundo.hxx>
#include <section.hxx>
@@ -2008,6 +2009,65 @@ void SwXText::Impl::ConvertCell(
    SwNodeRange aCellRange(aStartCellPam.Start()->nNode,
            aEndCellPam.End()->nNode);
    rRowNodes.push_back(aCellRange); // note: invalidates pLastCell!

    // tdf#149649 delete any fieldmarks overlapping the cell
    IDocumentMarkAccess & rIDMA(*m_pDoc->getIDocumentMarkAccess());
    while (::sw::mark::IFieldmark *const pMark = rIDMA.getFieldmarkFor(*aStartCellPam.Start()))
    {
        if (pMark->GetMarkEnd() <= *aEndCellPam.End())
        {
            if (pMark->GetMarkStart() < *aStartCellPam.Start())
            {
                SAL_INFO("sw.uno", "deleting fieldmark overlapping table cell");
                rIDMA.deleteMark(pMark);
            }
            else
            {
                break;
            }
        }
        else
        {
            SwPosition const sepPos(::sw::mark::FindFieldSep(*pMark));
            if (*aStartCellPam.Start() <= sepPos && sepPos <= *aEndCellPam.End())
            {
                SAL_INFO("sw.uno", "deleting fieldmark with separator in table cell");
                rIDMA.deleteMark(pMark);
            }
            else
            {
                break;
            }
        }
    }
    while (::sw::mark::IFieldmark *const pMark = rIDMA.getFieldmarkFor(*aEndCellPam.End()))
    {
        if (*aStartCellPam.Start() <= pMark->GetMarkStart())
        {
            if (*aEndCellPam.End() < pMark->GetMarkEnd())
            {
                SAL_INFO("sw.uno", "deleting fieldmark overlapping table cell");
                rIDMA.deleteMark(pMark);
            }
            else
            {
                break;
            }
        }
        else
        {
            SwPosition const sepPos(::sw::mark::FindFieldSep(*pMark));
            if (*aStartCellPam.Start() <= sepPos && sepPos <= *aEndCellPam.End())
            {
                SAL_INFO("sw.uno", "deleting fieldmark with separator in table cell");
                rIDMA.deleteMark(pMark);
            }
            else
            {
                break;
            }
       }
    }
}

typedef uno::Sequence< text::TableColumnSeparator > TableColumnSeparators;