sw/source/core/doc/DocumentContentOperationsManager.cxx |   36 +++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

New commits:
commit 49f26e7dae550aff6ca90b3cda7f89e11ac8cfd4
Author:     Michael Stahl <michael.st...@cib.de>
AuthorDate: Mon May 4 14:22:09 2020 +0200
Commit:     Michael Stahl <michael.st...@cib.de>
CommitDate: Mon May 4 16:38:50 2020 +0200

    tdf#132187 sw: fix creation of frames on end node in CopyWithFlyInFly()
    
    The problem is that the rInsPos node is included in the range passed to
    MakeFrames(), but it already has a frame, so now it has 2 and that
    means the next call to MakeFrames() in this position will create all the
    frames twice.
    
    This is tricky because while in practice there is currently only one
    layout in theory there could be multiple, and then it could happen that
    RecreateStartTextFrames() will destroy the node's frame in one layout
    but not the other, while MakeFrames() always works on all layouts.
    
    Fix this by checking if all the existing frames survive
    RecreateStartTextFrames() and if it's not the case (like in tdf#130685)
    explicitly delete all the frames and including the node in MakeFrames().
    
    (regression from 166b5010b402a41b192b1659093a25acf9065fd9)
    
    Change-Id: I1bba11da053fe1c6359b2f76f3a352e44c6a2a1d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93416
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@cib.de>

diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx 
b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 771c4885004f..6e907d7495c7 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -3438,6 +3438,7 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
     if (rRg.aStart != rRg.aEnd)
     {
         bool bEndIsEqualEndPos = rInsPos == rRg.aEnd;
+        bool isRecreateEndNode(false);
         --aSavePos;
         SaveRedlEndPosForRestore aRedlRest( rInsPos, 0 );
 
@@ -3448,7 +3449,40 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
         {   // recreate from previous node (could be merged now)
             if (SwTextNode *const pNode = aSavePos.GetNode().GetTextNode())
             {
+                std::unordered_set<SwTextFrame*> frames;
+                SwTextNode *const pEndNode = rInsPos.GetNode().GetTextNode();
+                if (pEndNode)
+                {
+                    SwIterator<SwTextFrame, SwTextNode, 
sw::IteratorMode::UnwrapMulti> aIter(*pEndNode);
+                    for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = 
aIter.Next())
+                    {
+                        if (pFrame->getRootFrame()->IsHideRedlines())
+                        {
+                            frames.insert(pFrame);
+                        }
+                    }
+                }
                 sw::RecreateStartTextFrames(*pNode);
+                if (!frames.empty())
+                {   // tdf#132187 check if the end node needs new frames
+                    SwIterator<SwTextFrame, SwTextNode, 
sw::IteratorMode::UnwrapMulti> aIter(*pEndNode);
+                    for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = 
aIter.Next())
+                    {
+                        if (pFrame->getRootFrame()->IsHideRedlines())
+                        {
+                            auto const it = frames.find(pFrame);
+                            if (it != frames.end())
+                            {
+                                frames.erase(it);
+                            }
+                        }
+                    }
+                    if (!frames.empty()) // existing frame was deleted
+                    {   // all layouts because MakeFrames recreates all layouts
+                        pEndNode->DelFrames(nullptr);
+                        isRecreateEndNode = true;
+                    }
+                }
             }
         }
         bool const isAtStartOfSection(aSavePos.GetNode().IsStartNode());
@@ -3460,7 +3494,7 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
             // if it was the first node in the document so that MakeFrames()
             // will find the existing (wasn't deleted) frame on it
             SwNodeIndex const end(rInsPos,
-                    (rInsPos.GetNode().IsEndNode() || isAtStartOfSection)
+                    (!isRecreateEndNode || isAtStartOfSection)
                     ? 0 : +1);
             ::MakeFrames(pDest, aSavePos, end);
         }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to