sw/source/core/doc/DocumentContentOperationsManager.cxx |  101 ++++++++--------
 sw/source/core/inc/DocumentContentOperationsManager.hxx |    3 
 2 files changed, 58 insertions(+), 46 deletions(-)

New commits:
commit 4b68824d18316762a6afc35d355221e0228aebf8
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Jan 19 20:29:23 2024 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon Jan 22 08:55:36 2024 +0100

    tdf#159023 sw_redlinehide: fix layout frames copying table into footer
    
    Tables in footer aren't supported - if a table is pasted into the
    footer, SwNodes::CopyNodes() inserts for table/cell nodes the
    SwPlaceholderNodes so that the relative distance between any copied
    node is the same in the target, and once the other stuff like bookmarks
    and anchored flys are copied, SwNodes::DelDummyNodes() removes the
    SwPlaceholderNodes.
    
    If SwNodes::CopyNodes() is called with bNewFrames=true, it handles
    creating the frames well, but with bNewFrames=false and a subsequent
    MakeFrames(), the InsertCnt_() simply quits once it sees the first
    SwPlaceholderNode and so no frames are created for the nodes in the
    table cells.
    
    Rearrange DocumentContentOperationsManager::CopyWithFlyInFly() to move
    the MakeFrames() down below DelDummyNodes(), which requires adding a
    parameter to CopyFlyInFlyImpl() to prevent it from creating frames
    (anchored objects will also be created by MakeFrames() later).
    
    (regression from commit 166b5010b402a41b192b1659093a25acf9065fd9)
    
    Change-Id: I0ac30bec6e6423bb7d12c0a29f33848a5b61cd98
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162320
    Tested-by: Michael Stahl <michael.st...@allotropia.de>
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx 
b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 09e0a1233e5d..b78b6b66daef 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -3828,12 +3828,61 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
 
     if (rRg.aStart != rRg.aEnd)
     {
+        ++aSavePos;
+    }
+
+#if OSL_DEBUG_LEVEL > 0
+    {
+        //JP 17.06.99: Bug 66973 - check count only if the selection is in
+        // the same section or there's no section, because sections that are
+        // not fully selected are not copied.
+        const SwSectionNode* pSSectNd = rRg.aStart.GetNode().FindSectionNode();
+        SwNodeIndex aTmpI( rRg.aEnd, -1 );
+        const SwSectionNode* pESectNd = aTmpI.GetNode().FindSectionNode();
+        if( pSSectNd == pESectNd &&
+            !rRg.aStart.GetNode().IsSectionNode() &&
+            !aTmpI.GetNode().IsEndNode() )
+        {
+            // If the range starts with a SwStartNode, it isn't copied
+            SwNodeOffset offset( (rRg.aStart.GetNode().GetNodeType() != 
SwNodeType::Start) ? 1 : 0 );
+            OSL_ENSURE( rInsPos.GetIndex() - aSavePos.GetIndex() ==
+                    rRg.aEnd.GetIndex() - rRg.aStart.GetIndex() - 1 + offset,
+                    "An insufficient number of nodes were copied!" );
+        }
+    }
+#endif
+
+    {
+        ::sw::UndoGuard const undoGuard(rDest.GetIDocumentUndoRedo());
+        // this must happen before lcl_DeleteRedlines() because it counts nodes
+        CopyFlyInFlyImpl(rRg, pCopiedPaM ? &pCopiedPaM->first : nullptr,
+            // see comment below regarding use of pCopiedPaM->second
+            (pCopiedPaM && rRg.aStart != pCopiedPaM->first.Start()->GetNode())
+                ? pCopiedPaM->second.GetNode()
+                : aSavePos.GetNode(),
+            bCopyFlyAtFly,
+            flags,
+            false);
+    }
+
+    SwNodeRange aCpyRange( aSavePos.GetNode(), rInsPos );
+
+    if( bDelRedlines && ( RedlineFlags::DeleteRedlines & 
rDest.getIDocumentRedlineAccess().GetRedlineFlags() ))
+        lcl_DeleteRedlines( rRg, aCpyRange );
+
+    rDest.GetNodes().DelDummyNodes( aCpyRange );
+
+    // tdf#159023 create layout frames after DelDummyNodes():
+    // InsertCnt_() does early return on the first SwPlaceholderNode
+    if (rRg.aStart != rRg.aEnd)
+    {
+        --aSavePos; // restore temporarily...
         bool isRecreateEndNode(false);
         if (bMakeNewFrames) // tdf#130685 only after aRedlRest
         {   // recreate from previous node (could be merged now)
             o3tl::sorted_vector<SwTextFrame*> frames;
-            SwTextNode * pNode = aSavePos.GetNode().GetTextNode();
-            SwTextNode *const pEndNode = rInsPos.GetTextNode();
+            SwTextNode * pNode(aSavePos.GetNode().GetTextNode());
+            SwTextNode *const pEndNode(rInsPos.GetTextNode());
             if (pEndNode)
             {
                 SwIterator<SwTextFrame, SwTextNode, 
sw::IteratorMode::UnwrapMulti> aIter(*pEndNode);
@@ -3861,7 +3910,7 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
                     {
                         if (pFrame->getRootFrame()->HasMergedParas())
                         {
-                            auto const it = frames.find(pFrame);
+                            auto const it(frames.find(pFrame));
                             if (it != frames.end())
                             {
                                 frames.erase(it);
@@ -3885,50 +3934,11 @@ 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,
-                    SwNodeOffset((!isRecreateEndNode || isAtStartOfSection)
+                SwNodeOffset((!isRecreateEndNode || isAtStartOfSection)
                     ? 0 : +1));
             ::MakeFrames(&rDest, aSavePos.GetNode(), end.GetNode());
         }
     }
-
-#if OSL_DEBUG_LEVEL > 0
-    {
-        //JP 17.06.99: Bug 66973 - check count only if the selection is in
-        // the same section or there's no section, because sections that are
-        // not fully selected are not copied.
-        const SwSectionNode* pSSectNd = rRg.aStart.GetNode().FindSectionNode();
-        SwNodeIndex aTmpI( rRg.aEnd, -1 );
-        const SwSectionNode* pESectNd = aTmpI.GetNode().FindSectionNode();
-        if( pSSectNd == pESectNd &&
-            !rRg.aStart.GetNode().IsSectionNode() &&
-            !aTmpI.GetNode().IsEndNode() )
-        {
-            // If the range starts with a SwStartNode, it isn't copied
-            SwNodeOffset offset( (rRg.aStart.GetNode().GetNodeType() != 
SwNodeType::Start) ? 1 : 0 );
-            OSL_ENSURE( rInsPos.GetIndex() - aSavePos.GetIndex() ==
-                    rRg.aEnd.GetIndex() - rRg.aStart.GetIndex() - 1 + offset,
-                    "An insufficient number of nodes were copied!" );
-        }
-    }
-#endif
-
-    {
-        ::sw::UndoGuard const undoGuard(rDest.GetIDocumentUndoRedo());
-        CopyFlyInFlyImpl(rRg, pCopiedPaM ? &pCopiedPaM->first : nullptr,
-            // see comment below regarding use of pCopiedPaM->second
-            (pCopiedPaM && rRg.aStart != pCopiedPaM->first.Start()->GetNode())
-                ? pCopiedPaM->second.GetNode()
-                : aSavePos.GetNode(),
-            bCopyFlyAtFly,
-            flags);
-    }
-
-    SwNodeRange aCpyRange( aSavePos.GetNode(), rInsPos );
-
-    if( bDelRedlines && ( RedlineFlags::DeleteRedlines & 
rDest.getIDocumentRedlineAccess().GetRedlineFlags() ))
-        lcl_DeleteRedlines( rRg, aCpyRange );
-
-    rDest.GetNodes().DelDummyNodes( aCpyRange );
 }
 
 // note: for the redline Show/Hide this must be in sync with
@@ -3938,7 +3948,8 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl(
     SwPaM const*const pCopiedPaM,
     SwNode& rStartIdx,
     const bool bCopyFlyAtFly,
-    SwCopyFlags const flags) const
+    SwCopyFlags const flags,
+    bool const bMakeNewFrames) const
 {
     assert(!pCopiedPaM || pCopiedPaM->End()->GetNode() == rRg.aEnd.GetNode());
 
@@ -4142,7 +4153,7 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl(
 
         // Copy the format and set the new anchor
         aVecSwFrameFormat.push_back( 
rDest.getIDocumentLayoutAccess().CopyLayoutFormat( *(*it).GetFormat(),
-                aAnchor, false, true ) );
+                aAnchor, false, bMakeNewFrames) );
         ++it;
     }
 
diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx 
b/sw/source/core/inc/DocumentContentOperationsManager.hxx
index 8332cf34bf92..3cb378f00069 100644
--- a/sw/source/core/inc/DocumentContentOperationsManager.hxx
+++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx
@@ -111,7 +111,8 @@ public:
                             SwPaM const*const pCopiedPaM,
                             SwNode& rStartIdx,
                             const bool bCopyFlyAtFly = false,
-                            SwCopyFlags flags = SwCopyFlags::Default) const;
+                            SwCopyFlags flags = SwCopyFlags::Default,
+                            bool bMakeNewFrames = true) const;
 
     /// Parameters for _Rst and lcl_SetTextFormatColl
     //originallyfrom docfmt.cxx

Reply via email to