sw/source/core/unocore/unotext.cxx | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+)
New commits: commit 6f3953236070c186bc9356053d8b368d1c28372d Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Fri Jul 8 17:32:49 2022 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Mon Jul 11 10:30:55 2022 +0200 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.st...@allotropia.de> (cherry picked from commit 3d48adc6f9bbec0b7a169466273636961ffbb6bf) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136920 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx index a837d42d71c2..c34319e28db2 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;