diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2023-04-20 11:18:34 +0300 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-04-27 17:00:18 +0200 |
commit | 6c284972327f5b331aab93de088ce0f97255cbca (patch) | |
tree | 230a3a65c4e211a32f38964b73b928a509e8440c /sw/source/core/layout | |
parent | Resolves: tdf#151958 Disable binary search on sorted cache for current releases (diff) | |
download | core-6c284972327f5b331aab93de088ce0f97255cbca.tar.gz core-6c284972327f5b331aab93de088ce0f97255cbca.zip |
tdf#154113: do not forget to split the outermost section frame
... when the inserted section node is not the first one.
The very first frame, where InsertCnt_ puts content to, may already have
some content after the insertion position. When an inner section ends,
the current section needs a new frame, and the rest of content must go
to that new frame. Previously, the new empty frame was created without
taking the content move into account.
This moves the split into the single place inside InsertCnt_, to avoid
special processing in MakeFrames.
Change-Id: I1335ebbc620af0f2b064141e8267e5bd1af0b195
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150675
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150745
(cherry picked from commit 20751f74116f6f83a1081ab67bafc1de59c00590)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151110
Tested-by: Aron Budea <aron.budea@collabora.com>
Reviewed-by: Aron Budea <aron.budea@collabora.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'sw/source/core/layout')
-rw-r--r-- | sw/source/core/layout/frmtool.cxx | 63 | ||||
-rw-r--r-- | sw/source/core/layout/layhelp.hxx | 3 | ||||
-rw-r--r-- | sw/source/core/layout/sectfrm.cxx | 79 |
3 files changed, 67 insertions, 78 deletions
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx index b4f676b85745..f477400aea49 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -1757,6 +1757,9 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc, nIndex = pNode->EndOfSectionIndex(); else { + if (pActualSection) + pActualSection->SetLastPos(pPrv); + pFrame = pNode->MakeFrame( pLay ); pActualSection.reset( new SwActualSection( pActualSection.release(), static_cast<SwSectionFrame*>(pFrame), pNode ) ); @@ -1913,33 +1916,30 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc, } // new section frame - pFrame = pActualSection->GetSectionNode()->MakeFrame( pLay ); - pFrame->InsertBehind( pLay, pPrv ); - static_cast<SwSectionFrame*>(pFrame)->Init(); - - // OD 12.08.2003 #i17969# - consider horizontal/vertical layout - // for setting position at newly inserted frame - lcl_SetPos( *pFrame, *pLay ); - - SwSectionFrame* pOuterSectionFrame = pActualSection->GetSectionFrame(); - - // a follow has to be appended to the new section frame - SwSectionFrame* pFollow = pOuterSectionFrame ? pOuterSectionFrame->GetFollow() : nullptr; - if ( pFollow ) + if (SwSectionFrame* pOuterSectionFrame = pActualSection->GetSectionFrame()) { - pOuterSectionFrame->SetFollow( nullptr ); - pOuterSectionFrame->InvalidateSize(); - static_cast<SwSectionFrame*>(pFrame)->SetFollow( pFollow ); - } + // Splitting moves the trailing content to the next frame + pFrame = pOuterSectionFrame->SplitSect(pActualSection->GetLastPos(), pPrv); - // We don't want to leave empty parts back. - if (pOuterSectionFrame && - ! pOuterSectionFrame->IsColLocked() && - ! pOuterSectionFrame->ContainsContent() ) + // We don't want to leave empty parts back. + if (! pOuterSectionFrame->IsColLocked() && + ! pOuterSectionFrame->ContainsContent() ) + { + pOuterSectionFrame->DelEmpty( true ); + SwFrame::DestroyFrame(pOuterSectionFrame); + } + } + else { - pOuterSectionFrame->DelEmpty( true ); - SwFrame::DestroyFrame(pOuterSectionFrame); + pFrame = pActualSection->GetSectionNode()->MakeFrame( pLay ); + pFrame->InsertBehind( pLay, pPrv ); + static_cast<SwSectionFrame*>(pFrame)->Init(); + + // OD 12.08.2003 #i17969# - consider horizontal/vertical layout + // for setting position at newly inserted frame + lcl_SetPos( *pFrame, *pLay ); } + pActualSection->SetSectionFrame( static_cast<SwSectionFrame*>(pFrame) ); pLay = static_cast<SwLayoutFrame*>(pFrame); @@ -2167,20 +2167,7 @@ void MakeFrames( SwDoc *pDoc, SwNode &rSttIdx, SwNode &rEndIdx ) } else { - bool bSplit; SwFrame* pPrv = bAfter ? pFrame : pFrame->GetPrev(); - // If the section frame is inserted into another one, it must be split. - if( pSct && rSttIdx.IsSectionNode() ) - { - bSplit = pSct->SplitSect( pFrame, bAfter ); - if( !bSplit && !bAfter ) - { - pUpper = pSct->GetUpper(); - pPrv = pSct->GetPrev(); - } - } - else - bSplit = false; ::InsertCnt_( pUpper, pDoc, rSttIdx.GetIndex(), false, nEndIdx, pPrv, eMode ); @@ -2193,10 +2180,6 @@ void MakeFrames( SwDoc *pDoc, SwNode &rSttIdx, SwNode &rEndIdx ) AppendAllObjs( pTable, pUpper ); } - // If nothing was added (e.g. a hidden section), the split must be reversed. - if( bSplit && pSct && pSct->GetNext() - && pSct->GetNext()->IsSctFrame() ) - pSct->MergeNext( static_cast<SwSectionFrame*>(pSct->GetNext()) ); if( pFrame->IsInFly() ) pFrame->FindFlyFrame()->Invalidate_(); if( pFrame->IsInTab() ) diff --git a/sw/source/core/layout/layhelp.hxx b/sw/source/core/layout/layhelp.hxx index 17c5cc32491e..02ff3ca4f327 100644 --- a/sw/source/core/layout/layhelp.hxx +++ b/sw/source/core/layout/layhelp.hxx @@ -86,6 +86,7 @@ class SwActualSection { SwActualSection *m_pUpper; SwSectionFrame *m_pSectFrame; + SwFrame* m_pLastPos = nullptr; // Split it *after* this child frame SwSectionNode *m_pSectNode; public: SwActualSection( SwActualSection *pUpper, @@ -97,6 +98,8 @@ public: SwSectionNode *GetSectionNode() { return m_pSectNode;} void SetUpper(SwActualSection *p) { m_pUpper = p; } SwActualSection *GetUpper() { return m_pUpper; } + void SetLastPos(SwFrame* p) { m_pLastPos = p; } + SwFrame* GetLastPos() const { return m_pLastPos; } }; /// Helps during the InsertCnt_ function to create new pages. diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx index 0a82b8cc0dfd..cc6c3982d3a4 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -511,50 +511,53 @@ void SwSectionFrame::MergeNext( SwSectionFrame* pNxt ) } /** -|* Divides a SectionFrame into two parts. The second one starts with the -|* passed frame. +|* Divides a SectionFrame into two parts. The content of the second one +|* starts after pFrameStartAfter; the created second section frame itself +|* is put after pFramePutAfter. +|* If pFrameStartAfter is nullptr, the split happens at the start. |* This is required when inserting an inner section, because the MoveFwd |* cannot have the desired effect within a frame or a table cell. +|* Splitting at the start/end makes sense, because the empty frame would +|* be removed after the InsertCnt_ finished. |*/ -bool SwSectionFrame::SplitSect( SwFrame* pFrame, bool bAfter ) +SwSectionFrame* SwSectionFrame::SplitSect( SwFrame* pFrameStartAfter, SwFrame* pFramePutAfter ) { - assert(pFrame && "SplitSect: Why?"); - SwFrame* pOther = bAfter ? pFrame->FindNext() : pFrame->FindPrev(); - if( !pOther ) - return false; - SwSectionFrame* pSect = pOther->FindSctFrame(); - if( pSect != this ) - return false; + assert(!pFrameStartAfter || pFrameStartAfter->FindSctFrame() == this); + SwFrame* pSav = pFrameStartAfter ? pFrameStartAfter->FindNext() : ContainsAny(); + if (pSav && pSav->FindSctFrame() != this) + pSav = nullptr; // we are at the very end + // Put the content aside - SwFrame* pSav = ::SaveContent( this, bAfter ? pOther : pFrame ); - OSL_ENSURE( pSav, "SplitSect: What's on?" ); - if( pSav ) // be robust - { // Create a new SctFrame, not as a Follower/master - SwSectionFrame* pNew = new SwSectionFrame( *pSect->GetSection(), pSect ); - pNew->InsertBehind( pSect->GetUpper(), pSect ); - pNew->Init(); - SwRectFnSet aRectFnSet(this); - aRectFnSet.MakePos( *pNew, nullptr, pSect, true ); - // OD 25.03.2003 #108339# - restore content: - // determine layout frame for restoring content after the initialization - // of the section frame. In the section initialization the columns are - // created. - { - SwLayoutFrame* pLay = pNew; - // Search for last layout frame, e.g. for columned sections. - while( pLay->Lower() && pLay->Lower()->IsLayoutFrame() ) - pLay = static_cast<SwLayoutFrame*>(pLay->Lower()); - ::RestoreContent( pSav, pLay, nullptr ); - } - InvalidateSize_(); - if( HasFollow() ) - { - pNew->SetFollow( GetFollow() ); - SetFollow( nullptr ); - } - return true; + if (pSav) + pSav = ::SaveContent( this, pSav ); + + // Create a new SctFrame, not as a Follower/master + if (!pFramePutAfter) + pFramePutAfter = this; + SwSectionFrame* pNew = new SwSectionFrame( *GetSection(), this ); + pNew->InsertBehind( pFramePutAfter->GetUpper(), pFramePutAfter ); + pNew->Init(); + SwRectFnSet aRectFnSet(this); + aRectFnSet.MakePos( *pNew, nullptr, pFramePutAfter, true ); + // OD 25.03.2003 #108339# - restore content: + // determine layout frame for restoring content after the initialization + // of the section frame. In the section initialization the columns are + // created. + if (pSav) + { + SwLayoutFrame* pLay = pNew; + // Search for last layout frame, e.g. for columned sections. + while( pLay->Lower() && pLay->Lower()->IsLayoutFrame() ) + pLay = static_cast<SwLayoutFrame*>(pLay->Lower()); + ::RestoreContent( pSav, pLay, nullptr ); + } + InvalidateSize_(); + if( HasFollow() ) + { + pNew->SetFollow( GetFollow() ); + SetFollow( nullptr ); } - return false; + return pNew; } /** |