sw/source/core/unocore/unotext.cxx |   60 +++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

New commits:
commit dab6149b056b0be51dbeefdd33397bf6a482a6da
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Jul 8 17:32:49 2022 +0200
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Mon Jul 11 16:33:40 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 436ae10ec546391ce21875c69b0ec4bb3a06fa1f)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136921
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>

diff --git a/sw/source/core/unocore/unotext.cxx 
b/sw/source/core/unocore/unotext.cxx
index 2ad7fce679d8..bb488949d334 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>
@@ -2006,6 +2007,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;

Reply via email to