sw/source/core/frmedt/fecopy.cxx | 45 ++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 15 deletions(-)
New commits: commit 5fcee251c35002ae1362f018a381a8bbd3059578 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Fri Jun 3 17:56:02 2022 +0200 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Thu Jun 9 09:49:48 2022 +0200 sw: fix pasting multiple flys in SwFEShell::Paste() This was most recently fixed in 3cfd63cb55ab1a7e6df53eaeb2a7623be05983d0 but that didn't take into account that now with Ctrl+A multiple flys can be selected and copied, and all of them should be pasted; remove the odd restriction to paste only one text frame. This reveals that pasting a text frame will actually select the text frame, so subsequent flys end up anchored inside the text frame; delay selection until all flys have been pasted. Change-Id: I049f60ca9656e5075d481d4501bb1ffdd28a4e21 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135366 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit badad69848f10b462a11f5b5e784cb468a94b180) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135390 Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx index a907e0e838a0..28a439e2c566 100644 --- a/sw/source/core/frmedt/fecopy.cxx +++ b/sw/source/core/frmedt/fecopy.cxx @@ -709,7 +709,7 @@ namespace { } namespace { - bool lcl_PasteFlyOrDrawFormat(SwPaM& rPaM, SwFrameFormat* pCpyFormat, SwFEShell& rSh) + SwFrameFormat* lcl_PasteFlyOrDrawFormat(SwPaM& rPaM, SwFrameFormat* pCpyFormat, SwFEShell& rSh) { auto& rImp = *rSh.Imp(); auto& rDoc = *rSh.GetDoc(); @@ -752,7 +752,7 @@ namespace { // positioning for group members pNew->NbcSetAnchorPos(aGrpAnchor); pNew->SetSnapRect(aSnapRect); - return true; + return nullptr; } } SwFormatAnchor aAnchor(pCpyFormat->GetAnchor()); @@ -766,18 +766,18 @@ namespace { { const SdrObject *pCpyObj = pCpyFormat->FindSdrObject(); if(pCpyObj && CheckControlLayer(pCpyObj)) - return true; + return nullptr; } else if(pCpyFormat->Which() == RES_FLYFRMFMT && IsInTextBox(pCpyFormat)) { // This is a fly frame which is anchored in a TextBox, ignore it as // it's already copied as part of copying the content of the // TextBox. - return true; + return nullptr; } // Ignore TextBoxes, they are already handled in sw::DocumentLayoutManager::CopyLayoutFormat(). if(SwTextBoxHelper::isTextBox(pCpyFormat, RES_FLYFRMFMT)) - return true; + return nullptr; aAnchor.SetAnchor(pPos); } else if(RndStdIds::FLY_AT_PAGE == aAnchor.GetAnchorId()) @@ -791,9 +791,13 @@ namespace { } SwFrameFormat* pNew = rDoc.getIDocumentLayoutAccess().CopyLayoutFormat(*pCpyFormat, aAnchor, true, true); + return pNew; + } + void lcl_SelectFlyFormat(SwFrameFormat *const pNew, SwFEShell& rSh) + { if(!pNew) - return true; + return; switch(pNew->Which()) { case RES_FLYFRMFMT: @@ -803,10 +807,11 @@ namespace { SwFlyFrame* pFlyFrame = static_cast<SwFlyFrameFormat*>(pNew)->GetFrame(&aPt); if(pFlyFrame) rSh.SelectFlyFrame(*pFlyFrame); - return false; + break; } case RES_DRAWFRMFMT: { + auto& rDrawView = *rSh.Imp()->GetDrawView(); assert(dynamic_cast<SwDrawFrameFormat*>(pNew)); SwDrawFrameFormat* pDrawFormat = static_cast<SwDrawFrameFormat*>(pNew); // #i52780# - drawing object has to be made visible on paste. @@ -821,7 +826,6 @@ namespace { default: SAL_WARN("sw.core", "unknown fly type"); } - return true; } } @@ -1038,13 +1042,24 @@ bool SwFEShell::Paste(SwDoc& rClpDoc, bool bNestedTable) // we need a DrawView if(!Imp()->GetDrawView()) MakeDrawView(); - for(auto pCpyFormat: *rClpDoc.GetSpzFrameFormats()) - if(pCpyFormat->Which() != RES_FLYFRMFMT) - lcl_PasteFlyOrDrawFormat(rPaM, pCpyFormat, *this); - for(auto pCpyFormat: *rClpDoc.GetSpzFrameFormats()) - if(pCpyFormat->Which() == RES_FLYFRMFMT) - if(!lcl_PasteFlyOrDrawFormat(rPaM, pCpyFormat, *this)) - break; + ::std::vector<SwFrameFormat*> inserted; + for (auto const pFlyFormat : *rClpDoc.GetSpzFrameFormats()) + { + // if anchored inside other fly, will be copied when copying + // top-level fly, so skip here! (other non-body anchor + // shouldn't happen here) + SwFormatAnchor const& rAnchor(pFlyFormat->GetAnchor()); + if (RndStdIds::FLY_AT_PAGE == rAnchor.GetAnchorId() + || rClpDoc.GetNodes().GetEndOfExtras().GetIndex() < rAnchor.GetContentAnchor()->nNode.GetIndex()) + { + inserted.emplace_back( + lcl_PasteFlyOrDrawFormat(rPaM, pFlyFormat, *this)); + } + } + for (auto const pFlyFormat : inserted) + { + lcl_SelectFlyFormat(pFlyFormat, *this); + } } else {