sw: layout: ignore Keep-With-Next on hidden frames, part1
When a frame is hidden, don't consider it when evaluating keep-with-next
attributes - this was the case for content in hidden sections before
commit 0c96119895
~SwFrameNotify() invalidating position of hidden frame with keep
attribute causes layout loops.
Also skip hidden frames in SwFlowFrame::IsKeepFwdMoveAllowed(),
SwFlowFrame::CheckKeep(), SwFlowFrame::IsPrevObjMove(),
SwFlowFrame::MoveBwd(), CalcContent().
Change-Id: I68556ba0a8e016d962399f3ce199e5eda0378867
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177975
Tested-by: Michael Stahl <michael.stahl@allotropia.de>
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
This commit is contained in:
parent
59891cd398
commit
cd8468bcba
4 changed files with 55 additions and 8 deletions
|
@ -184,6 +184,9 @@ public:
|
|||
SvxFormatBreakItem const& rBreak,
|
||||
bool bBreakCheck = false ) const;
|
||||
|
||||
SwFrame * FindPrevIgnoreHidden() const;
|
||||
SwFrame * FindNextIgnoreHidden() const;
|
||||
|
||||
bool HasLockedFollow() const;
|
||||
|
||||
bool HasParaSpaceAtPages( bool bSct ) const;
|
||||
|
|
|
@ -131,7 +131,9 @@ bool SwFlowFrame::IsKeepFwdMoveAllowed( bool bIgnoreMyOwnKeepValue )
|
|||
if ( bIgnoreMyOwnKeepValue && pFrame->GetIndPrev() )
|
||||
pFrame = pFrame->GetIndPrev();
|
||||
do
|
||||
{ if ( pFrame->GetAttrSet()->GetKeep().GetValue() )
|
||||
{
|
||||
if (pFrame->GetAttrSet()->GetKeep().GetValue()
|
||||
|| pFrame->IsHiddenNow())
|
||||
pFrame = pFrame->GetIndPrev();
|
||||
else
|
||||
return true;
|
||||
|
@ -150,22 +152,42 @@ void SwFlowFrame::CheckKeep()
|
|||
// it's possible for the whole troop to move back.
|
||||
SwFrame *pPre = m_rThis.GetIndPrev();
|
||||
assert(pPre);
|
||||
while (pPre && pPre->IsHiddenNow())
|
||||
{
|
||||
pPre = pPre->GetIndPrev();
|
||||
}
|
||||
if (!pPre)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if( pPre->IsSctFrame() )
|
||||
{
|
||||
SwFrame *pLast = static_cast<SwSectionFrame*>(pPre)->FindLastContent();
|
||||
while (pLast && pLast->IsHiddenNow())
|
||||
{
|
||||
pLast = pLast->GetIndPrev();
|
||||
}
|
||||
if( pLast && pLast->FindSctFrame() == pPre )
|
||||
pPre = pLast;
|
||||
else
|
||||
return;
|
||||
}
|
||||
SwFrame* pTmp;
|
||||
SwFrame* pTmp{pPre};
|
||||
bool bKeep;
|
||||
while ( (bKeep = pPre->GetAttrSet()->GetKeep().GetValue()) &&
|
||||
nullptr != ( pTmp = pPre->GetIndPrev() ) )
|
||||
nullptr != (pTmp = pTmp->GetIndPrev()) )
|
||||
{
|
||||
if (pTmp->IsHiddenNow())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if( pTmp->IsSctFrame() )
|
||||
{
|
||||
SwFrame *pLast = static_cast<SwSectionFrame*>(pTmp)->FindLastContent();
|
||||
while (pLast && pLast->IsHiddenNow())
|
||||
{
|
||||
pLast = pLast->GetIndPrev();
|
||||
}
|
||||
if( pLast && pLast->FindSctFrame() == pTmp )
|
||||
pTmp = pLast;
|
||||
else
|
||||
|
@ -236,6 +258,7 @@ bool SwFlowFrame::IsKeep(SvxFormatKeepItem const& rKeep,
|
|||
SvxFormatBreakItem const& rBreak,
|
||||
bool const bCheckIfLastRowShouldKeep) const
|
||||
{
|
||||
assert(!m_rThis.IsHiddenNow()); // check it before?
|
||||
// 1. The keep attribute is ignored inside footnotes
|
||||
// 2. For compatibility reasons, the keep attribute is
|
||||
// ignored for frames inside table cells
|
||||
|
@ -338,6 +361,26 @@ bool SwFlowFrame::IsKeep(SvxFormatKeepItem const& rKeep,
|
|||
return bKeep;
|
||||
}
|
||||
|
||||
SwFrame * SwFlowFrame::FindPrevIgnoreHidden() const
|
||||
{
|
||||
SwFrame * pRet{m_rThis.FindPrev()};
|
||||
while (pRet && pRet->IsHiddenNow())
|
||||
{
|
||||
pRet = pRet->FindPrev();
|
||||
}
|
||||
return pRet;
|
||||
}
|
||||
|
||||
SwFrame * SwFlowFrame::FindNextIgnoreHidden() const
|
||||
{
|
||||
SwFrame * pRet{m_rThis.FindNext()};
|
||||
while (pRet && pRet->IsHiddenNow())
|
||||
{
|
||||
pRet = pRet->FindNext();
|
||||
}
|
||||
return pRet;
|
||||
}
|
||||
|
||||
sal_uInt8 SwFlowFrame::BwdMoveNecessary( const SwPageFrame *pPage, const SwRect &rRect )
|
||||
{
|
||||
// The return value helps deciding whether we need to flow back (3),
|
||||
|
@ -1188,7 +1231,7 @@ bool SwFlowFrame::IsPrevObjMove() const
|
|||
if( pSh && pSh->GetViewOptions()->getBrowseMode() )
|
||||
return false;
|
||||
|
||||
SwFrame *pPre = m_rThis.FindPrev();
|
||||
SwFrame *const pPre{FindPrevIgnoreHidden()};
|
||||
|
||||
if ( pPre && pPre->GetDrawObjs() )
|
||||
{
|
||||
|
@ -2616,7 +2659,7 @@ bool SwFlowFrame::MoveBwd( bool &rbReformat )
|
|||
// keep with next frame and next frame is locked.
|
||||
// i#38232 - If next frame is a table, do *not* check,
|
||||
// if it's locked.
|
||||
if ( pNewUpper && !IsFollow() &&
|
||||
if ( pNewUpper && !IsFollow() && !m_rThis.IsHiddenNow() &&
|
||||
m_rThis.GetAttrSet()->GetKeep().GetValue() && m_rThis.GetIndNext() )
|
||||
{
|
||||
SwFrame* pIndNext = m_rThis.GetIndNext();
|
||||
|
|
|
@ -1705,9 +1705,10 @@ void CalcContent( SwLayoutFrame *pLay, bool bNoColl )
|
|||
// frame due to its keep-attribute, if it can't move forward.
|
||||
// #i57765# - do not consider invalid previous
|
||||
// frame, if current frame has a column/page break before attribute.
|
||||
SwFrame* pTmpPrev = pFrame->FindPrev();
|
||||
assert(pFrame->IsFlowFrame());
|
||||
SwFlowFrame* pTmpFlowFrame = SwFlowFrame::CastFlowFrame(pFrame);
|
||||
SwFrame* pTmpPrev = pTmpFlowFrame->FindPrevIgnoreHidden();
|
||||
SwFlowFrame* pTmpPrevFlowFrame = pTmpPrev && pTmpPrev->IsFlowFrame() ? SwFlowFrame::CastFlowFrame(pTmpPrev) : nullptr;
|
||||
SwFlowFrame* pTmpFlowFrame = pFrame->IsFlowFrame() ? SwFlowFrame::CastFlowFrame(pFrame) : nullptr;
|
||||
|
||||
bool bPrevInvalid = pTmpPrevFlowFrame && pTmpFlowFrame &&
|
||||
!pTmpFlowFrame->IsFollow() &&
|
||||
|
|
|
@ -155,7 +155,7 @@ void SwFrameNotify::ImplDestroy()
|
|||
{
|
||||
if ( mbInvaKeep )
|
||||
{
|
||||
SwFrame *pPre = mpFrame->FindPrev();
|
||||
SwFrame *pPre = pFlow->FindPrevIgnoreHidden();
|
||||
if ( pPre && pPre->IsFlowFrame() )
|
||||
{
|
||||
// 1. pPre wants to keep with me:
|
||||
|
|
Loading…
Reference in a new issue