/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
basegfx::B2DHomMatrix SwFrameAreaDefinition::getFramePrintAreaTransformation() const
{ // default implementation hands out FramePrintArea (outer frame) // Take into account that FramePrintArea is relative to FrameArea const SwRect& rFrameArea(getFrameArea()); const SwRect& rFramePrintArea(getFramePrintArea());
void SwFrameAreaDefinition::transform_translate(const Point& rOffset)
{ // RotateFlyFrame3: default is to change the FrameArea, FramePrintArea needs no // change since it is relative to FrameArea
SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
if (aFrm.Pos().X() != FAR_AWAY)
{
aFrm.Pos().AdjustX(rOffset.X() );
}
if (aFrm.Pos().Y() != FAR_AWAY)
{
aFrm.Pos().AdjustY(rOffset.Y() );
}
}
void TransformableSwFrame::restoreFrameAreas()
{ // This can be done fully based on the Transformations currently // set, so use this. Only needed when transformation *is* used if(!getLocalFrameAreaTransformation().isIdentity())
{
SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(mrSwFrameAreaDefinition);
aFrm.setSwRect(getUntransformedFrameArea());
}
void SwCellFrame::CheckDirection( bool bVert )
{ const SwFrameFormat* pFormat = GetFormat(); const SvxFrameDirectionItem* pFrameDirItem; // Check if the item is set, before actually // using it. Otherwise the dynamic pool default is used, which may be set // to LTR in case of OOo 1.0 documents. if( pFormat && (pFrameDirItem = pFormat->GetItemIfSet( RES_FRAMEDIR ) ) )
{ const SwViewShell *pSh = getRootFrame()->GetCurrShell(); constbool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
CheckDir( pFrameDirItem->GetValue(), bVert, false, bBrowseMode );
} else
SwFrame::CheckDirection( bVert );
}
case RES_ROW_SPLIT:
{ if ( IsRowFrame() )
{ bool bInFollowFlowRow = nullptr != IsInFollowFlowRow(); if ( bInFollowFlowRow || nullptr != IsInSplitTableRow() )
{
SwTabFrame* pTab = FindTabFrame(); if ( bInFollowFlowRow )
pTab = pTab->FindMaster();
pTab->SetRemoveFollowFlowLinePending( true );
}
} break;
} case RES_COL:
OSL_FAIL( "Columns for new FrameType?" ); break;
default: // the new FillStyle has to do the same as previous RES_BACKGROUND if(nWhich >= XATTR_FILL_FIRST && nWhich <= XATTR_FILL_LAST)
{
rInvFlags
|= SwFrameInvFlags::SetCompletePaint | SwFrameInvFlags::NextSetCompletePaint;
} /* do Nothing */;
}
}
/** * Invalidates the page in which the Frame is currently placed. * The page is invalidated depending on the type (Layout, Content, FlyFrame)
*/ void SwFrame::InvalidatePage( const SwPageFrame *pPage ) const
{ if ( !pPage )
{
pPage = FindPageFrame(); // #i28701# - for at-character and as-character // anchored Writer fly frames additionally invalidate also page frame // its 'anchor character' is on. if ( pPage && pPage->GetUpper() && IsFlyFrame() )
{ const SwFlyFrame* pFlyFrame = static_cast<const SwFlyFrame*>(this); if ( pFlyFrame->IsAutoPos() || pFlyFrame->IsFlyInContentFrame() )
{ // #i33751#, #i34060# - method <GetPageFrameOfAnchor()> // is replaced by method <FindPageFrameOfAnchor()>. It's return value // have to be checked.
SwPageFrame* pPageFrameOfAnchor = const_cast<SwFlyFrame*>(pFlyFrame)->FindPageFrameOfAnchor(); if ( pPageFrameOfAnchor && pPageFrameOfAnchor != pPage )
{
InvalidatePage( pPageFrameOfAnchor );
}
}
}
}
if ( !(pPage && pPage->GetUpper()) ) return;
if ( pPage->GetFormat()->GetDoc().IsInDtor() ) return;
SwRootFrame *pRoot = const_cast<SwRootFrame*>(static_cast<const SwRootFrame*>(pPage->GetUpper())); const SwFlyFrame *pFly = FindFlyFrame(); if ( IsContentFrame() )
{ if ( pRoot->IsTurboAllowed() )
{ // If a ContentFrame wants to register for a second time, make it a TurboAction. if ( !pRoot->GetTurbo() || this == pRoot->GetTurbo() )
pRoot->SetTurbo( static_cast<const SwContentFrame*>(this) ); else
{
pRoot->DisallowTurbo(); //The page of the Turbo could be a different one then mine, //therefore we have to invalidate it. const SwFrame *pTmp = pRoot->GetTurbo();
pRoot->ResetTurbo();
pTmp->InvalidatePage();
}
} if ( !pRoot->GetTurbo() )
{ if ( pFly )
{ if( !pFly->IsLocked() )
{ if ( pFly->IsFlyInContentFrame() )
{ pPage->InvalidateFlyInCnt();
pFly->GetAnchorFrame()->InvalidatePage();
} else
pPage->InvalidateFlyContent();
}
} else
pPage->InvalidateContent();
}
} else
{
pRoot->DisallowTurbo(); if ( pFly )
{ if ( !pFly->IsLocked() )
{ if ( pFly->IsFlyInContentFrame() )
{
pPage->InvalidateFlyInCnt();
pFly->GetAnchorFrame()->InvalidatePage();
} else
pPage->InvalidateFlyLayout();
}
} else
pPage->InvalidateLayout();
if ( nReal != nDiff )
{
SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
fnRect.SetHeight(aFrm, nNew - nDiff + nReal);
}
} else
{ // OD 24.10.2002 #97265# - grow/shrink not for neighbour frames // NOTE: neighbour frames are cell and column frames. if ( !bNeighb )
{ if ( nDiff > 0 )
Grow( nDiff ); else
Shrink( -nDiff );
if (GetUpper() && fnRect.GetHeight(getFrameArea()) != nNew)
{
GetUpper()->InvalidateSize_();
}
}
// Even if grow/shrink did not yet set the desired width, for // example when called by ChgColumns to set the column width, we // set the right width now.
SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
fnRect.SetHeight(aFrm, nNew);
}
}
} else
{
SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
aFrm.SSize( aNewSize );
}
/** Insert SwFrame into existing structure. * * Insertion is done below the parent either before pBehind or * at the end of the chain if pBehind is empty.
*/ void SwFrame::InsertBefore( SwLayoutFrame* pParent, SwFrame* pBehind )
{
OSL_ENSURE( pParent, "No parent for insert." );
OSL_ENSURE( (!pBehind || pParent == pBehind->GetUpper()), "Frame tree is inconsistent." );
mpUpper = pParent;
mpNext = pBehind; if( pBehind )
{ //Insert before pBehind.
mpPrev = pBehind->mpPrev; if( nullptr != mpPrev )
mpPrev->mpNext = this; else
mpUpper->m_pLower = this;
pBehind->mpPrev = this;
} else
{ //Insert at the end, or as first node in the sub tree
mpPrev = mpUpper->Lower(); if ( mpPrev )
{ while( mpPrev->mpNext )
mpPrev = mpPrev->mpNext;
mpPrev->mpNext = this;
} else
mpUpper->m_pLower = this;
}
}
/** Insert SwFrame into existing structure. * * Insertion is done below the parent either after pBehind or * at the beginning of the chain if pBehind is empty.
*/ void SwFrame::InsertBehind( SwLayoutFrame *pParent, SwFrame *pBefore )
{
OSL_ENSURE( (!pBefore || pParent == pBefore->GetUpper()), "Frame tree is inconsistent." );
mpUpper = pParent;
mpPrev = pBefore; if ( pBefore )
{ //Insert after pBefore
mpNext = pBefore->mpNext; if ( nullptr != mpNext )
mpNext->mpPrev = this;
pBefore->mpNext = this;
} else
{
assert(pParent && "No Parent for Insert."); //Insert at the beginning of the chain
mpNext = pParent->Lower(); if ( mpNext )
mpNext->mpPrev = this;
pParent->m_pLower = this;
}
}
/** Insert a chain of SwFrames into an existing structure * * Currently, this method is used to insert a SectionFrame (which may have some siblings) into an * existing structure. If the third parameter is NULL, this method is (besides handling the * siblings) equal to SwFrame::InsertBefore(..). * * If the third parameter is passed, the following happens: * - this becomes mpNext of pParent * - pSct becomes mpNext of the last one in the this-chain * - pBehind is reconnected from pParent to pSct * The purpose is: a SectionFrame (this) won't become a child of another SectionFrame (pParent), but * pParent gets split into two siblings (pParent+pSect) and this is inserted between.
*/ bool SwFrame::InsertGroupBefore( SwFrame* pParent, SwFrame* pBehind, SwFrame* pSct )
{
OSL_ENSURE( pParent, "No parent for insert." );
OSL_ENSURE( (!pBehind || ( (pBehind && (pParent == pBehind->GetUpper()))
|| ((pParent->IsSctFrame() && pBehind->GetUpper()->IsColBodyFrame())) ) ), "Frame tree inconsistent." ); if( pSct )
{
mpUpper = pParent->GetUpper();
SwFrame *pLast = this; while( pLast->GetNext() )
{
pLast = pLast->GetNext();
pLast->mpUpper = GetUpper();
} if( pBehind )
{
pLast->mpNext = pSct;
pSct->mpPrev = pLast;
pSct->mpNext = pParent->GetNext();
} else
{
pLast->mpNext = pParent->GetNext(); if( pLast->GetNext() )
pLast->GetNext()->mpPrev = pLast;
}
pParent->mpNext = this;
mpPrev = pParent; if( pSct->GetNext() )
pSct->GetNext()->mpPrev = pSct; while( pLast->GetNext() )
{
pLast = pLast->GetNext();
pLast->mpUpper = GetUpper();
} if( pBehind )
{ // Insert before pBehind. if( pBehind->GetPrev() )
pBehind->GetPrev()->mpNext = nullptr; else
pBehind->GetUpper()->m_pLower = nullptr;
pBehind->mpPrev = nullptr;
SwLayoutFrame* pTmp = static_cast<SwLayoutFrame*>(pSct);
SwFrame* pLower = pTmp->Lower(); if( pLower )
{
OSL_ENSURE( pLower->IsColumnFrame(), "InsertGrp: Used SectionFrame" );
pTmp = static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(pLower)->Lower());
OSL_ENSURE( pTmp, "InsertGrp: Missing ColBody" );
}
pBehind->mpUpper = pTmp;
pBehind->GetUpper()->m_pLower = pBehind;
pLast = pBehind->GetNext(); while ( pLast )
{
pLast->mpUpper = pBehind->GetUpper();
pLast = pLast->GetNext();
}
} else
{
OSL_ENSURE( pSct->IsSctFrame(), "InsertGroup: For SectionFrames only" );
SwFrame::DestroyFrame(pSct); returnfalse;
}
} else
{
mpUpper = static_cast<SwLayoutFrame*>(pParent);
SwFrame *pLast = this; while( pLast->GetNext() )
{
pLast = pLast->GetNext();
pLast->mpUpper = GetUpper();
}
pLast->mpNext = pBehind; if( pBehind )
{ // Insert before pBehind.
mpPrev = pBehind->mpPrev; if( nullptr != mpPrev )
mpPrev->mpNext = this; else
mpUpper->m_pLower = this;
pBehind->mpPrev = pLast;
} else
{ //Insert at the end, or ... the first node in the subtree
mpPrev = mpUpper->Lower(); if ( mpPrev )
{ while( mpPrev->mpNext )
mpPrev = mpPrev->mpNext;
mpPrev->mpNext = this;
} else
mpUpper->m_pLower = this;
}
} returntrue;
}
void SwFrame::RemoveFromLayout()
{
OSL_ENSURE( mpUpper, "Remove without upper?" );
if (mpPrev) // one out of the middle is removed
mpPrev->mpNext = mpNext; elseif (mpUpper)
{ // the first in a list is removed //TODO
OSL_ENSURE( mpUpper->m_pLower == this, "Layout is inconsistent." );
mpUpper->m_pLower = mpNext;
} if( mpNext )
mpNext->mpPrev = mpPrev;
if ( getFrameArea().Height() )
pParent->Grow( getFrameArea().Height() );
if ( getFrameArea().Width() != pParent->getFramePrintArea().Width() )
Prepare( PrepareHint::FixSizeChanged );
if ( GetPrev() )
{ if ( IsFollow() ) //I'm a direct follower of my master now static_cast<SwContentFrame*>(GetPrev())->Prepare( PrepareHint::FollowFollows ); else
{ if ( GetPrev()->getFrameArea().Height() !=
GetPrev()->getFramePrintArea().Height() + GetPrev()->getFramePrintArea().Top() )
{ // Take the border into account?
GetPrev()->InvalidatePrt_();
} // OD 18.02.2003 #104989# - force complete paint of previous frame, // if frame is inserted at the end of a section frame, in order to // get subsidiary lines repainted for the section. if ( pParent->IsSctFrame() && !GetNext() )
{ // force complete paint of previous frame, if new inserted frame // in the section is the last one.
GetPrev()->SetCompletePaint();
}
GetPrev()->InvalidatePage( pPage );
}
} if ( IsInFootnote() )
{
SwFrame* pFrame = GetIndPrev(); if( pFrame && pFrame->IsSctFrame() )
pFrame = static_cast<SwSectionFrame*>(pFrame)->ContainsAny(); if( pFrame )
pFrame->Prepare( PrepareHint::QuoVadis, nullptr, false ); if( !GetNext() )
{
pFrame = FindFootnoteFrame()->GetNext(); if( pFrame && nullptr != (pFrame=static_cast<SwLayoutFrame*>(pFrame)->ContainsAny()) )
pFrame->InvalidatePrt_();
}
}
InvalidateLineNum_();
SwFrame *pNxt = FindNextCnt(); if ( !pNxt ) return;
SwTabFrame* pMasterTab(nullptr);
pFrame = GetIndNext(); if( pFrame )
{ // The old follow may have calculated a gap to the predecessor which // now becomes obsolete or different as it becomes the first one itself
pFrame->InvalidatePrt_();
pFrame->InvalidatePos_();
pFrame->InvalidatePage( pPage ); if( pFrame->IsSctFrame() )
{
pFrame = static_cast<SwSectionFrame*>(pFrame)->ContainsAny(); if( pFrame )
{
pFrame->InvalidatePrt_();
pFrame->InvalidatePos_();
pFrame->InvalidatePage( pPage );
}
} if( pFrame && IsInFootnote() )
pFrame->Prepare( PrepareHint::ErgoSum, nullptr, false ); if( IsInSct() && !GetPrev() )
{
SwSectionFrame* pSct = FindSctFrame(); if( !pSct->IsFollow() )
{
pSct->InvalidatePrt_();
pSct->InvalidatePage( pPage );
}
}
} else
{
InvalidateNextPos(); //Someone needs to do the retouching: predecessor or upper
pFrame = GetPrev(); if ( nullptr != pFrame )
{ pFrame->SetRetouche();
pFrame->Prepare( PrepareHint::WidowsOrphans );
pFrame->InvalidatePos_();
pFrame->InvalidatePage( pPage );
} // If I'm (was) the only ContentFrame in my upper, it has to do the // retouching. Also, perhaps a page became empty. else
{ SwRootFrame *pRoot = getRootFrame(); if ( pRoot )
{
pRoot->SetSuperfluous(); // RemoveSuperfluous can only remove empty pages at the end; // find if there are pages without content following pPage // and if so request a call to CheckPageDescs()
SwViewShell *pSh = pRoot->GetCurrShell(); // tdf#152983 pPage is null when called from SwHeadFootFrame ctor if (pPage && pSh && pSh->Imp()->IsAction())
{
SwPageFrame const* pNext(pPage); while ((pNext = static_cast<SwPageFrame const*>(pNext->GetNext())))
{ if (!sw::IsPageFrameEmpty(*pNext) && !pNext->IsFootnotePage())
{
pSh->Imp()->GetLayAction().SetCheckPageNum(pPage->GetPhyPageNum()); break;
}
}
}
GetUpper()->SetCompletePaint();
GetUpper()->InvalidatePage( pPage );
} if( IsInSct() )
{
SwSectionFrame* pSct = FindSctFrame(); if( !pSct->IsFollow() )
{
pSct->InvalidatePrt_();
pSct->InvalidatePage( pPage );
}
} // #i52253# The master table should take care // of removing the follow flow line. if ( IsInTab() )
{
SwTabFrame* pThisTab = FindTabFrame(); if (pThisTab && pThisTab->IsFollow())
{
pMasterTab = pThisTab->FindMaster();
}
}
}
} //Remove first, then shrink the upper.
SwLayoutFrame *pUp = GetUpper();
RemoveFromLayout(); if ( !pUp )
{
assert(!pMasterTab); return;
}
if (pMasterTab
&& !pMasterTab->GetFollow()->GetFirstNonHeadlineRow()->ContainsContent())
{ // only do this if there's no content in other cells of the row!
pMasterTab->InvalidatePos_();
pMasterTab->SetRemoveFollowFlowLinePending(true);
}
SwSectionFrame *pSct = nullptr; if ( !pUp->Lower() &&
( ( pUp->IsFootnoteFrame() && !pUp->IsColLocked() ) ||
( pUp->IsInSct() && // #i29438# // We have to consider the case that the section may be "empty" // except from a temporary empty table frame. // This can happen due to the new cell split feature.
!pUp->IsCellFrame() && // #126020# - adjust check for empty section // #130797# - correct fix #126020#
!(pSct = pUp->FindSctFrame())->ContainsContent() &&
!pSct->ContainsAny( true ) ) ) )
{ if ( pUp->GetUpper() )
{
// prevent delete of <ColLocked> footnote frame if ( pUp->IsFootnoteFrame() && !pUp->IsColLocked())
{ if( pUp->GetNext() && !pUp->GetPrev() )
{
SwFrame* pTmp = static_cast<SwLayoutFrame*>(pUp->GetNext())->ContainsAny(); if( pTmp )
pTmp->InvalidatePrt_();
} if (!pUp->IsDeleteForbidden())
{
pUp->Cut();
SwFrame::DestroyFrame(pUp);
}
} else
{
assert(pSct); if ( pSct->IsColLocked() || !pSct->IsInFootnote() ||
( pUp->IsFootnoteFrame() && pUp->IsColLocked() ) )
{
pSct->DelEmpty( false ); // If a locked section may not be deleted then at least // its size became invalid after removing its last // content.
pSct->InvalidateSize_();
} else
{
pSct->DelEmpty( true );
SwFrame::DestroyFrame(pSct);
}
}
}
} else
{
SwRectFnSet aRectFnSet(this);
tools::Long nFrameHeight = aRectFnSet.GetHeight(getFrameArea()); if( nFrameHeight )
pUp->Shrink( nFrameHeight );
}
}
void SwLayoutFrame::Paste( SwFrame* pParent, SwFrame* pSibling)
{
OSL_ENSURE( pParent, "No parent for pasting." );
OSL_ENSURE( pParent->IsLayoutFrame(), "Parent is ContentFrame." );
OSL_ENSURE( pParent != this, "I'm the parent oneself." );
OSL_ENSURE( pSibling != this, "I'm my own neighbour." );
OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(), "I'm still registered somewhere." );
//Insert in the tree.
InsertBefore( static_cast<SwLayoutFrame*>(pParent), pSibling );
// OD 24.10.2002 #103517# - correct setting of variable <fnRect> // <fnRect> is used for the following: // (1) To invalidate the frame's size, if its size, which has to be the // same as its upper/parent, differs from its upper's/parent's. // (2) To adjust/grow the frame's upper/parent, if it has a dimension in its // size, which is not determined by its upper/parent. // Which size is which depends on the frame type and the layout direction // (vertical or horizontal). // There are the following cases: // (A) Header and footer frames both in vertical and in horizontal layout // have to size the width to the upper/parent. A dimension in the height // has to cause an adjustment/grow of the upper/parent. // --> <fnRect> = fnRectHori // (B) Cell and column frames in vertical layout, the width has to be the // same as upper/parent and a dimension in height causes adjustment/grow // of the upper/parent. // --> <fnRect> = fnRectHori // in horizontal layout the other way around // --> <fnRect> = fnRectVert // (C) Other frames in vertical layout, the height has to be the // same as upper/parent and a dimension in width causes adjustment/grow // of the upper/parent. // --> <fnRect> = fnRectVert // in horizontal layout the other way around // --> <fnRect> = fnRectHori //SwRectFn fnRect = IsVertical() ? fnRectHori : fnRectVert; bool bVert, bVertL2R, bVertL2RB2T; if ( IsHeaderFrame() || IsFooterFrame() )
bVert = bVertL2R = bVertL2RB2T = false; else
{
bVert = (IsCellFrame() || IsColumnFrame()) ? !GetUpper()->IsVertical() : GetUpper()->IsVertical();
bVertL2R = GetUpper()->IsVertLR();
bVertL2RB2T = GetUpper()->IsVertLRBT();
}
SwRectFnSet fnRect(bVert, bVertL2R, bVertL2RB2T);
// Remove first, then shrink upper.
SwLayoutFrame *pUp = GetUpper();
// AdjustNeighbourhood is now also called in columns which are not // placed inside a frame.
// Remove must not be called before an AdjustNeighbourhood, but it has to // be called before the upper-shrink-call, if the upper-shrink takes care // of its content. if ( pUp && nShrink )
{ if( pUp->IsFootnoteBossFrame() )
{
SwNeighbourAdjust nAdjust= static_cast<SwFootnoteBossFrame*>(pUp)->NeighbourhoodAdjustment(); if( SwNeighbourAdjust::OnlyAdjust == nAdjust )
AdjustNeighbourhood( -nShrink ); else
{
SwTwips nReal = 0; if( SwNeighbourAdjust::AdjustGrow == nAdjust )
nReal = -AdjustNeighbourhood( -nShrink ); if( nReal < nShrink )
{ const SwTwips nOldHeight = aRectFnSet.GetHeight(getFrameArea());
// seems as if this needs to be forwarded to the SwFrame already here, // changing to zero seems temporary anyways
{
SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
aRectFnSet.SetHeight( aFrm, 0 );
}
/** Adjust surrounding neighbourhood after insertion * * A Frame needs "normalization" if it is directly placed below a footnote boss (page/column) and its * size changes. There is always a frame that takes the maximum possible space (the frame that * contains the Body text) and zero or more frames which only take the space needed (header/footer * area, footnote container). If one of these frames changes, the body-text-frame has to grow or * shrink accordingly, even though it's fixed. * * !! Is it possible to do this in a generic way and not restrict it to the page and a distinct * frame which takes the maximum space (controlled using the FrameSize attribute)? * Problems: * - What if multiple frames taking the maximum space are placed next to each other? * - How is the maximum space calculated? * - How small can those frames become? * * In any case, only a certain amount of space is allowed, so we never go below a minimum value for * the height of the body. * * @param nDiff the value around which the space has to be allocated
*/
SwTwips SwFrame::AdjustNeighbourhood( SwTwips nDiff, bool bTst )
{
PROTOCOL_ENTER( this, PROT::AdjustN, DbgAction::NONE, &nDiff );
if ( !nDiff || !GetUpper()->IsFootnoteBossFrame() ) // only inside pages/columns return 0;
//The (Page-)Body only changes in BrowseMode, but only if it does not //contain columns. if ( IsPageBodyFrame() && (!bBrowse ||
(static_cast<SwLayoutFrame*>(this)->Lower() && static_cast<SwLayoutFrame*>(this)->Lower()->IsColumnFrame())) ) return 0;
//In BrowseView mode the PageFrame can handle some of the requests.
tools::Long nBrowseAdd = 0; if ( bBrowse && GetUpper()->IsPageFrame() ) // only (Page-)BodyFrames
{
SwViewShell *pViewShell = getRootFrame()->GetCurrShell();
SwLayoutFrame *pUp = GetUpper();
tools::Long nChg; const tools::Long nUpPrtBottom = pUp->getFrameArea().Height() -
pUp->getFramePrintArea().Height() - pUp->getFramePrintArea().Top();
SwRect aInva( pUp->getFrameArea() ); if ( pViewShell )
{
aInva.Pos().setX( pViewShell->VisArea().Left() );
aInva.Width( pViewShell->VisArea().Width() );
} if ( nDiff > 0 )
{
nChg = BROWSE_HEIGHT - pUp->getFrameArea().Height();
nChg = std::min( nDiff, SwTwips(nChg) );
if ( !IsBodyFrame() )
{
SetCompletePaint(); if ( !pViewShell || pViewShell->VisArea().Height() >= pUp->getFrameArea().Height() )
{ //First minimize Body, it will grow again later.
SwFrame *pBody = static_cast<SwFootnoteBossFrame*>(pUp)->FindBodyCont(); const tools::Long nTmp = nChg - pBody->getFramePrintArea().Height(); if ( !bTst )
{
{
SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pBody);
aFrm.Height(std::max( tools::Long(0), aFrm.Height() - nChg ));
}
const tools::Long nTmp = nUpPrtBottom + 20;
aInva.Top( aInva.Bottom() - nTmp );
aInva.Height( nChg + nTmp );
} else
{ //The page can shrink to 0. The first page keeps the same size like //VisArea.
nChg = nDiff;
tools::Long nInvaAdd = 0; if ( pViewShell && !pUp->GetPrev() &&
pUp->getFrameArea().Height() + nDiff < pViewShell->VisArea().Height() )
{ // This means that we have to invalidate adequately.
nChg = pViewShell->VisArea().Height() - pUp->getFrameArea().Height();
nInvaAdd = -(nDiff - nChg);
}
//Invalidate including bottom border.
tools::Long nBorder = nUpPrtBottom + 20;
nBorder -= nChg;
aInva.Top( aInva.Bottom() - (nBorder+nInvaAdd) ); if ( !IsBodyFrame() )
{
SetCompletePaint(); if ( !IsHeaderFrame() ) static_cast<SwFootnoteBossFrame*>(pUp)->FindBodyCont()->SetCompletePaint();
} //Invalidate the page because of the frames. Thereby the page becomes //the right size again if a frame didn't fit. This only works //randomly for paragraph bound frames otherwise (NotifyFlys).
pUp->InvalidateSize();
} if ( !bTst )
{ //Independent from nChg if ( pViewShell && aInva.HasArea() && pUp->GetUpper() )
pViewShell->InvalidateWindows( aInva );
} if ( !bTst && nChg )
{
{
SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pUp);
aFrm.AddHeight(nChg );
}
if ( pViewShell )
pViewShell->Imp()->SetFirstVisPageInvalid();
if ( GetNext() )
GetNext()->InvalidatePos_();
//Trigger a repaint if necessary.
std::unique_ptr<SvxBrushItem> aBack(pUp->GetFormat()->makeBackgroundBrushItem()); const SvxGraphicPosition ePos = aBack->GetGraphicPos(); if ( ePos != GPOS_NONE && ePos != GPOS_TILED )
pViewShell->InvalidateWindows( pUp->getFrameArea() );
if ( pUp->GetUpper() )
{ if ( pUp->GetNext() )
pUp->GetNext()->InvalidatePos();
//Sad but true: during notify on ViewImp a Calc on the page and //its Lower may be called. The values should not be changed //because the caller takes care of the adjustment of Frame and //Prt. const tools::Long nOldFrameHeight = getFrameArea().Height(); const tools::Long nOldPrtHeight = getFramePrintArea().Height(); constbool bOldComplete = IsCompletePaint();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.