diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2024-01-19 20:29:23 +0100 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2024-01-22 08:55:36 +0100 |
commit | 4b68824d18316762a6afc35d355221e0228aebf8 (patch) | |
tree | 547114548bad7fa07cfe13a91901cc6d1fdedc0a | |
parent | 075b4f44b966a8799ee937e4e5a009d498c7aba4 (diff) |
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.stahl@allotropia.de>
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
-rw-r--r-- | sw/source/core/doc/DocumentContentOperationsManager.cxx | 101 | ||||
-rw-r--r-- | sw/source/core/inc/DocumentContentOperationsManager.hxx | 3 |
2 files changed, 58 insertions, 46 deletions
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 |