diff options
Diffstat (limited to 'sw/source/core/layout/flylay.cxx')
-rw-r--r-- | sw/source/core/layout/flylay.cxx | 1319 |
1 files changed, 1319 insertions, 0 deletions
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx new file mode 100644 index 000000000000..170779683097 --- /dev/null +++ b/sw/source/core/layout/flylay.cxx @@ -0,0 +1,1319 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" +#include "doc.hxx" +#include "pagefrm.hxx" +#include "rootfrm.hxx" +#include "cntfrm.hxx" +#include "dview.hxx" +#include "dflyobj.hxx" +#include "dcontact.hxx" +#include "flyfrm.hxx" +#include "ftnfrm.hxx" +#include "frmtool.hxx" +#include "frmfmt.hxx" +#include "hints.hxx" +#include "pam.hxx" +#include "sectfrm.hxx" + + +#include <svx/svdpage.hxx> +#include <editeng/ulspitem.hxx> +#include <fmtanchr.hxx> +#include <fmtornt.hxx> +#include <fmtfsize.hxx> +#include "ndole.hxx" +#include "tabfrm.hxx" +#include "flyfrms.hxx" +// #i18732# +#include <fmtfollowtextflow.hxx> +#include <environmentofanchoredobject.hxx> +// #i28701# +#include <sortedobjs.hxx> +#include <viewsh.hxx> +#include <viewimp.hxx> + + +using namespace ::com::sun::star; + + +/************************************************************************* +|* +|* SwFlyFreeFrm::SwFlyFreeFrm(), ~SwFlyFreeFrm() +|* +|*************************************************************************/ + +SwFlyFreeFrm::SwFlyFreeFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) : + SwFlyFrm( pFmt, pSib, pAnch ), + pPage( 0 ), + // #i34753# + mbNoMakePos( false ), + // #i37068# + mbNoMoveOnCheckClip( false ) +{ +} + +SwFlyFreeFrm::~SwFlyFreeFrm() +{ + //und Tschuess. + // #i28701# - use new method <GetPageFrm()> + if( GetPageFrm() ) + { + if( GetFmt()->GetDoc()->IsInDtor() ) + { + // #i29879# - remove also to-frame anchored Writer + // fly frame from page. + const bool bRemoveFromPage = + GetPageFrm()->GetSortedObjs() && + ( IsFlyAtCntFrm() || + ( GetAnchorFrm() && GetAnchorFrm()->IsFlyFrm() ) ); + if ( bRemoveFromPage ) + { + GetPageFrm()->GetSortedObjs()->Remove( *this ); + } + } + else + { + SwRect aTmp( GetObjRectWithSpaces() ); + SwFlyFreeFrm::NotifyBackground( GetPageFrm(), aTmp, PREP_FLY_LEAVE ); + } + } +} + +// #i28701# +TYPEINIT1(SwFlyFreeFrm,SwFlyFrm); +/************************************************************************* +|* +|* SwFlyFreeFrm::NotifyBackground() +|* +|* Beschreibung Benachrichtigt den Hintergrund (alle CntntFrms die +|* gerade ueberlappt werden. Ausserdem wird das Window in einigen +|* Faellen direkt invalidiert (vor allem dort, wo keine CntntFrms +|* ueberlappt werden. +|* Es werden auch die CntntFrms innerhalb von anderen Flys +|* beruecksichtigt. +|* +|*************************************************************************/ + +void SwFlyFreeFrm::NotifyBackground( SwPageFrm *pPageFrm, + const SwRect& rRect, PrepareHint eHint ) +{ + ::Notify_Background( GetVirtDrawObj(), pPageFrm, rRect, eHint, sal_True ); +} + +/************************************************************************* +|* +|* SwFlyFreeFrm::MakeAll() +|* +|*************************************************************************/ + +void SwFlyFreeFrm::MakeAll() +{ + if ( !GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) ) + { + return; + } + + if ( !GetAnchorFrm() || IsLocked() || IsColLocked() ) + return; + // #i28701# - use new method <GetPageFrm()> + if( !GetPageFrm() && GetAnchorFrm() && GetAnchorFrm()->IsInFly() ) + { + SwFlyFrm* pFly = AnchorFrm()->FindFlyFrm(); + SwPageFrm *pPageFrm = pFly ? pFly->FindPageFrm() : NULL; + if( pPageFrm ) + pPageFrm->AppendFlyToPage( this ); + } + if( !GetPageFrm() ) + return; + + Lock(); //Der Vorhang faellt + + //uebernimmt im DTor die Benachrichtigung + const SwFlyNotify aNotify( this ); + + if ( IsClipped() ) + { + bValidSize = bHeightClipped = bWidthClipped = sal_False; + // no invalidation of position, + // if anchored object is anchored inside a Writer fly frame, + // its position is already locked, and it follows the text flow. + // #i34753# - add condition: + // no invalidation of position, if no direct move is requested in <CheckClip(..)> + if ( !IsNoMoveOnCheckClip() && + !( PositionLocked() && + GetAnchorFrm()->IsInFly() && + GetFrmFmt().GetFollowTextFlow().GetValue() ) ) + { + bValidPos = sal_False; + } + } + + // #i81146# new loop control + sal_uInt16 nLoopControlRuns = 0; + const sal_uInt16 nLoopControlMax = 10; + + while ( !bValidPos || !bValidSize || !bValidPrtArea || bFormatHeightOnly ) + { + SWRECTFN( this ) + const SwFmtFrmSize *pSz; + { //Zusaetzlicher Scope, damit aAccess vor dem Check zerstoert wird! + + SwBorderAttrAccess aAccess( SwFrm::GetCache(), this ); + const SwBorderAttrs &rAttrs = *aAccess.Get(); + pSz = &rAttrs.GetAttrSet().GetFrmSize(); + + //Nur einstellen wenn das Flag gesetzt ist!! + if ( !bValidSize ) + { + bValidPrtArea = sal_False; + } + + if ( !bValidPrtArea ) + MakePrtArea( rAttrs ); + + if ( !bValidSize || bFormatHeightOnly ) + { + bValidSize = sal_False; + Format( &rAttrs ); + bFormatHeightOnly = sal_False; + } + + if ( !bValidPos ) + { + const Point aOldPos( (Frm().*fnRect->fnGetPos)() ); + // #i26791# - use new method <MakeObjPos()> + // #i34753# - no positioning, if requested. + if ( IsNoMakePos() ) + bValidPos = sal_True; + else + // #i26791# - use new method <MakeObjPos()> + MakeObjPos(); + if( aOldPos == (Frm().*fnRect->fnGetPos)() ) + { + if( !bValidPos && GetAnchorFrm()->IsInSct() && + !GetAnchorFrm()->FindSctFrm()->IsValid() ) + bValidPos = sal_True; + } + else + bValidSize = sal_False; + } + } + + if ( bValidPos && bValidSize ) + { + ++nLoopControlRuns; + +#if OSL_DEBUG_LEVEL > 1 + OSL_ENSURE( nLoopControlRuns < nLoopControlMax, "LoopControl in SwFlyFreeFrm::MakeAll" ); +#endif + + if ( nLoopControlRuns < nLoopControlMax ) + CheckClip( *pSz ); + } + else + nLoopControlRuns = 0; + } + Unlock(); + +#if OSL_DEBUG_LEVEL > 1 + SWRECTFN( this ) + OSL_ENSURE( bHeightClipped || ( (Frm().*fnRect->fnGetHeight)() > 0 && + (Prt().*fnRect->fnGetHeight)() > 0), + "SwFlyFreeFrm::Format(), flipping Fly." ); + +#endif +} + +/** determines, if direct environment of fly frame has 'auto' size + + #i17297# + start with anchor frame and search via <GetUpper()> for a header, footer, + row or fly frame stopping at page frame. + return <true>, if such a frame is found and it has 'auto' size. + otherwise <false> is returned. + + @return boolean indicating, that direct environment has 'auto' size +*/ +bool SwFlyFreeFrm::HasEnvironmentAutoSize() const +{ + bool bRetVal = false; + + const SwFrm* pToBeCheckedFrm = GetAnchorFrm(); + while ( pToBeCheckedFrm && + !pToBeCheckedFrm->IsPageFrm() ) + { + if ( pToBeCheckedFrm->IsHeaderFrm() || + pToBeCheckedFrm->IsFooterFrm() || + pToBeCheckedFrm->IsRowFrm() || + pToBeCheckedFrm->IsFlyFrm() ) + { + bRetVal = ATT_FIX_SIZE != + pToBeCheckedFrm->GetAttrSet()->GetFrmSize().GetHeightSizeType(); + break; + } + else + { + pToBeCheckedFrm = pToBeCheckedFrm->GetUpper(); + } + } + + return bRetVal; +} + +/************************************************************************* +|* +|* SwFlyFreeFrm::CheckClip() +|* +|*************************************************************************/ + +void SwFlyFreeFrm::CheckClip( const SwFmtFrmSize &rSz ) +{ + //Jetzt ist es ggf. an der Zeit geignete Massnahmen zu ergreifen wenn + //der Fly nicht in seine Umgebung passt. + //Zuerst gibt der Fly seine Position auf. Danach wird er zunaechst + //formatiert. Erst wenn er auch durch die Aufgabe der Position nicht + //passt wird die Breite oder Hoehe aufgegeben - der Rahmen wird soweit + //wie notwendig zusammengequetscht. + + const SwVirtFlyDrawObj *pObj = GetVirtDrawObj(); + SwRect aClip, aTmpStretch; + ::CalcClipRect( pObj, aClip, sal_True ); + ::CalcClipRect( pObj, aTmpStretch, sal_False ); + aClip._Intersection( aTmpStretch ); + + const long nBot = Frm().Top() + Frm().Height(); + const long nRig = Frm().Left() + Frm().Width(); + const long nClipBot = aClip.Top() + aClip.Height(); + const long nClipRig = aClip.Left() + aClip.Width(); + + const sal_Bool bBot = nBot > nClipBot; + const sal_Bool bRig = nRig > nClipRig; + if ( bBot || bRig ) + { + sal_Bool bAgain = sal_False; + // #i37068# - no move, if it's requested + if ( bBot && !IsNoMoveOnCheckClip() && + !GetDrawObjs() && !GetAnchorFrm()->IsInTab() ) + { + SwFrm* pHeader = FindFooterOrHeader(); + // In a header, correction of the position is no good idea. + // If the fly moves, some paragraphs has to be formatted, this + // could cause a change of the height of the headerframe, + // now the flyframe can change its position and so on ... + if ( !pHeader || !pHeader->IsHeaderFrm() ) + { + const long nOld = Frm().Top(); + Frm().Pos().Y() = Max( aClip.Top(), nClipBot - Frm().Height() ); + if ( Frm().Top() != nOld ) + bAgain = sal_True; + bHeightClipped = sal_True; + } + } + if ( bRig ) + { + const long nOld = Frm().Left(); + Frm().Pos().X() = Max( aClip.Left(), nClipRig - Frm().Width() ); + if ( Frm().Left() != nOld ) + { + const SwFmtHoriOrient &rH = GetFmt()->GetHoriOrient(); + // Links ausgerichtete duerfen nicht nach links verschoben werden, + // wenn sie einem anderen ausweichen. + if( rH.GetHoriOrient() == text::HoriOrientation::LEFT ) + Frm().Pos().X() = nOld; + else + bAgain = sal_True; + } + bWidthClipped = sal_True; + } + if ( bAgain ) + bValidSize = sal_False; + else + { + //Wenn wir hier ankommen ragt der Frm in unerlaubte Bereiche + //hinein, und eine Positionskorrektur ist nicht erlaubt bzw. + //moeglich oder noetig. + + //Fuer Flys mit OLE-Objekten als Lower sorgen wir dafuer, dass + //immer proportional Resized wird. + Size aOldSize( Frm().SSize() ); + + //Zuerst wird das FrmRect eingestellt, und dann auf den Frm + //uebertragen. + SwRect aFrmRect( Frm() ); + + if ( bBot ) + { + long nDiff = nClipBot; + nDiff -= aFrmRect.Top(); //nDiff ist die verfuegbare Strecke. + nDiff = aFrmRect.Height() - nDiff; + aFrmRect.Height( aFrmRect.Height() - nDiff ); + bHeightClipped = sal_True; + } + if ( bRig ) + { + long nDiff = nClipRig; + nDiff -= aFrmRect.Left();//nDiff ist die verfuegbare Strecke. + nDiff = aFrmRect.Width() - nDiff; + aFrmRect.Width( aFrmRect.Width() - nDiff ); + bWidthClipped = sal_True; + } + + // #i17297# - no proportional + // scaling of graphics in environments, which determines its size + // by its content ('auto' size). Otherwise layout loops can occur and + // layout sizes of the environment can be incorrect. + // Such environment are: + // (1) header and footer frames with 'auto' size + // (2) table row frames with 'auto' size + // (3) fly frames with 'auto' size + // Note: section frames seems to be not critical - didn't found + // any critical layout situation so far. + if ( Lower() && Lower()->IsNoTxtFrm() && + ( static_cast<SwCntntFrm*>(Lower())->GetNode()->GetOLENode() || + !HasEnvironmentAutoSize() ) ) + { + //Wenn Breite und Hoehe angepasst wurden, so ist die + //groessere Veraenderung massgeblich. + if ( aFrmRect.Width() != aOldSize.Width() && + aFrmRect.Height()!= aOldSize.Height() ) + { + if ( (aOldSize.Width() - aFrmRect.Width()) > + (aOldSize.Height()- aFrmRect.Height()) ) + aFrmRect.Height( aOldSize.Height() ); + else + aFrmRect.Width( aOldSize.Width() ); + } + + //Breite angepasst? - Hoehe dann proportional verkleinern + if( aFrmRect.Width() != aOldSize.Width() ) + { + aFrmRect.Height( aFrmRect.Width() * aOldSize.Height() / + aOldSize.Width() ); + bHeightClipped = sal_True; + } + //Hoehe angepasst? - Breite dann proportional verkleinern + else if( aFrmRect.Height() != aOldSize.Height() ) + { + aFrmRect.Width( aFrmRect.Height() * aOldSize.Width() / + aOldSize.Height() ); + bWidthClipped = sal_True; + } + + // #i17297# - reactivate change + // of size attribute for fly frames containing an ole object. + + // Added the aFrmRect.HasArea() hack, because + // the environment of the ole object does not have to be valid + // at this moment, or even worse, it does not have to have a + // resonable size. In this case we do not want to change to + // attributes permanentely. Maybe one day somebody dares to remove + // this code. + if ( aFrmRect.HasArea() && + static_cast<SwCntntFrm*>(Lower())->GetNode()->GetOLENode() && + ( bWidthClipped || bHeightClipped ) ) + { + SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt(); + pFmt->LockModify(); + SwFmtFrmSize aFrmSize( rSz ); + aFrmSize.SetWidth( aFrmRect.Width() ); + aFrmSize.SetHeight( aFrmRect.Height() ); + pFmt->SetFmtAttr( aFrmSize ); + pFmt->UnlockModify(); + } + } + + //Jetzt die Einstellungen am Frm vornehmen, bei Spalten werden + //die neuen Werte in die Attribute eingetragen, weil es sonst + //ziemlich fiese Oszillationen gibt. + const long nPrtHeightDiff = Frm().Height() - Prt().Height(); + const long nPrtWidthDiff = Frm().Width() - Prt().Width(); + Frm().Height( aFrmRect.Height() ); + Frm().Width ( Max( long(MINLAY), aFrmRect.Width() ) ); + if ( Lower() && Lower()->IsColumnFrm() ) + { + ColLock(); //Grow/Shrink locken. + const Size aTmpOldSize( Prt().SSize() ); + Prt().Height( Frm().Height() - nPrtHeightDiff ); + Prt().Width ( Frm().Width() - nPrtWidthDiff ); + ChgLowersProp( aTmpOldSize ); + SwFrm *pLow = Lower(); + do + { pLow->Calc(); + // auch den (Column)BodyFrm mitkalkulieren + ((SwLayoutFrm*)pLow)->Lower()->Calc(); + pLow = pLow->GetNext(); + } while ( pLow ); + ::CalcCntnt( this ); + ColUnlock(); + if ( !bValidSize && !bWidthClipped ) + bFormatHeightOnly = bValidSize = sal_True; + } + else + { + Prt().Height( Frm().Height() - nPrtHeightDiff ); + Prt().Width ( Frm().Width() - nPrtWidthDiff ); + } + } + } + + // #i26945# + OSL_ENSURE( Frm().Height() >= 0, + "<SwFlyFreeFrm::CheckClip(..)> - fly frame has negative height now." ); +} + +/** method to determine, if a <MakeAll()> on the Writer fly frame is possible + #i43771# +*/ +bool SwFlyFreeFrm::IsFormatPossible() const +{ + return SwFlyFrm::IsFormatPossible() && + ( GetPageFrm() || + ( GetAnchorFrm() && GetAnchorFrm()->IsInFly() ) ); +} + +/************************************************************************* +|* +|* SwFlyLayFrm::SwFlyLayFrm() +|* +|*************************************************************************/ + +SwFlyLayFrm::SwFlyLayFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) : + SwFlyFreeFrm( pFmt, pSib, pAnch ) +{ + bLayout = sal_True; +} + +// #i28701# +TYPEINIT1(SwFlyLayFrm,SwFlyFreeFrm); +/************************************************************************* +|* +|* SwFlyLayFrm::Modify() +|* +|*************************************************************************/ + +void SwFlyLayFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew ) +{ + sal_uInt16 nWhich = pNew ? pNew->Which() : 0; + + SwFmtAnchor *pAnch = 0; + if( RES_ATTRSET_CHG == nWhich && SFX_ITEM_SET == + ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_ANCHOR, sal_False, + (const SfxPoolItem**)&pAnch )) + ; // Beim GetItemState wird der AnkerPointer gesetzt ! + + else if( RES_ANCHOR == nWhich ) + { + //Ankerwechsel, ich haenge mich selbst um. + //Es darf sich nicht um einen Wechsel des Ankertyps handeln, + //dies ist nur ueber die SwFEShell moeglich. + pAnch = (SwFmtAnchor*)pNew; + } + + if( pAnch ) + { + OSL_ENSURE( pAnch->GetAnchorId() == + GetFmt()->GetAnchor().GetAnchorId(), + "8-) Unzulaessiger Wechsel des Ankertyps." ); + + //Abmelden, Seite besorgen, an den entsprechenden LayoutFrm + //haengen. + SwRect aOld( GetObjRectWithSpaces() ); + // #i28701# - use new method <GetPageFrm()> + SwPageFrm *pOldPage = GetPageFrm(); + AnchorFrm()->RemoveFly( this ); + + if ( FLY_AT_PAGE == pAnch->GetAnchorId() ) + { + sal_uInt16 nPgNum = pAnch->GetPageNum(); + SwRootFrm *pRoot = getRootFrm(); + SwPageFrm *pTmpPage = (SwPageFrm*)pRoot->Lower(); + for ( sal_uInt16 i = 1; (i <= nPgNum) && pTmpPage; ++i, + pTmpPage = (SwPageFrm*)pTmpPage->GetNext() ) + { + if ( i == nPgNum ) + { + // #i50432# - adjust synopsis of <PlaceFly(..)> + pTmpPage->PlaceFly( this, 0 ); + } + } + if( !pTmpPage ) + { + pRoot->SetAssertFlyPages(); + pRoot->AssertFlyPages(); + } + } + else + { + SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode ); + SwCntntFrm *pCntnt = GetFmt()->GetDoc()->GetNodes().GoNext( &aIdx )-> + GetCntntNode()->getLayoutFrm( getRootFrm(), 0, 0, sal_False ); + if( pCntnt ) + { + SwFlyFrm *pTmp = pCntnt->FindFlyFrm(); + if( pTmp ) + pTmp->AppendFly( this ); + } + } + // #i28701# - use new method <GetPageFrm()> + if ( pOldPage && pOldPage != GetPageFrm() ) + NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE ); + SetCompletePaint(); + InvalidateAll(); + SetNotifyBack(); + } + else + SwFlyFrm::Modify( pOld, pNew ); +} + +/************************************************************************* +|* +|* SwPageFrm::AppendFly() +|* +|*************************************************************************/ + +void SwPageFrm::AppendFlyToPage( SwFlyFrm *pNew ) +{ + if ( !pNew->GetVirtDrawObj()->IsInserted() ) + getRootFrm()->GetDrawPage()->InsertObject( + (SdrObject*)pNew->GetVirtDrawObj(), + pNew->GetVirtDrawObj()->GetReferencedObj().GetOrdNumDirect() ); + + InvalidateSpelling(); + InvalidateSmartTags(); // SMARTTAGS + InvalidateAutoCompleteWords(); + InvalidateWordCount(); + + if ( GetUpper() ) + { + ((SwRootFrm*)GetUpper())->SetIdleFlags(); + ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); + } + + SdrObject* pObj = pNew->GetVirtDrawObj(); + OSL_ENSURE( pNew->GetAnchorFrm(), "Fly without Anchor" ); + const SwFlyFrm* pFly = pNew->GetAnchorFrm()->FindFlyFrm(); + if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() ) + { + sal_uInt32 nNewNum = pFly->GetVirtDrawObj()->GetOrdNumDirect(); + if ( pObj->GetPage() ) + pObj->GetPage()->SetObjectOrdNum( pObj->GetOrdNumDirect(), nNewNum); + else + pObj->SetOrdNum( nNewNum ); + } + + //Flys die im Cntnt sitzen beachten wir nicht weiter. + if ( pNew->IsFlyInCntFrm() ) + InvalidateFlyInCnt(); + else + { + InvalidateFlyCntnt(); + + if ( !pSortedObjs ) + pSortedObjs = new SwSortedObjs(); + +#if OSL_DEBUG_LEVEL > 1 + const bool bSucessInserted = +#endif + pSortedObjs->Insert( *pNew ); +#if OSL_DEBUG_LEVEL > 1 + OSL_ENSURE( bSucessInserted, "Fly nicht in Sorted eingetragen." ); + (void) bSucessInserted; +#endif + + // #i87493# + OSL_ENSURE( pNew->GetPageFrm() == 0 || pNew->GetPageFrm() == this, + "<SwPageFrm::AppendFlyToPage(..)> - anchored fly frame seems to be registered at another page frame. Serious defect -> please inform OD." ); + // #i28701# - use new method <SetPageFrm(..)> + pNew->SetPageFrm( this ); + pNew->InvalidatePage( this ); + // #i28701# + pNew->UnlockPosition(); + + // Notify accessible layout. That's required at this place for + // frames only where the anchor is moved. Creation of new frames + // is additionally handled by the SwFrmNotify class. + if( GetUpper() && + static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && + static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) + { + static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() + ->AddAccessibleFrm( pNew ); + } + } + + // #i28701# - correction: consider also drawing objects + if ( pNew->GetDrawObjs() ) + { + SwSortedObjs &rObjs = *pNew->GetDrawObjs(); + for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i ) + { + SwAnchoredObject* pTmpObj = rObjs[i]; + if ( pTmpObj->ISA(SwFlyFrm) ) + { + SwFlyFrm* pTmpFly = static_cast<SwFlyFrm*>(pTmpObj); + // #i28701# - use new method <GetPageFrm()> + if ( pTmpFly->IsFlyFreeFrm() && !pTmpFly->GetPageFrm() ) + AppendFlyToPage( pTmpFly ); + } + else if ( pTmpObj->ISA(SwAnchoredDrawObject) ) + { + // #i87493# + if ( pTmpObj->GetPageFrm() != this ) + { + if ( pTmpObj->GetPageFrm() != 0 ) + { + pTmpObj->GetPageFrm()->RemoveDrawObjFromPage( *pTmpObj ); + } + AppendDrawObjToPage( *pTmpObj ); + } + } + } + } +} + +/************************************************************************* +|* +|* SwPageFrm::RemoveFly() +|* +|*************************************************************************/ + +void SwPageFrm::RemoveFlyFromPage( SwFlyFrm *pToRemove ) +{ + const sal_uInt32 nOrdNum = pToRemove->GetVirtDrawObj()->GetOrdNum(); + getRootFrm()->GetDrawPage()->RemoveObject( nOrdNum ); + pToRemove->GetVirtDrawObj()->ReferencedObj().SetOrdNum( nOrdNum ); + + if ( GetUpper() ) + { + if ( !pToRemove->IsFlyInCntFrm() ) + ((SwRootFrm*)GetUpper())->SetSuperfluous(); + ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); + } + + //Flys die im Cntnt sitzen beachten wir nicht weiter. + if ( pToRemove->IsFlyInCntFrm() ) + return; + + // Notify accessible layout. That's required at this place for + // frames only where the anchor is moved. Creation of new frames + // is additionally handled by the SwFrmNotify class. + if( GetUpper() && + static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && + static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) + { + static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() + ->DisposeAccessibleFrm( pToRemove, sal_True ); + } + + //Collections noch nicht loeschen. Das passiert am Ende + //der Action im RemoveSuperfluous der Seite - angestossen von gleich- + //namiger Methode der Root. + //Die FlyColl kann bereits weg sein, weil der DTor der Seite + //gerade 'laeuft' + if ( pSortedObjs ) + { + pSortedObjs->Remove( *pToRemove ); + if ( !pSortedObjs->Count() ) + { DELETEZ( pSortedObjs ); + } + } + // #i28701# - use new method <SetPageFrm(..)> + pToRemove->SetPageFrm( 0L ); +} + +/************************************************************************* +|* +|* SwPageFrm::MoveFly +|* +|*************************************************************************/ + +void SwPageFrm::MoveFly( SwFlyFrm *pToMove, SwPageFrm *pDest ) +{ + //Invalidierungen + if ( GetUpper() ) + { + ((SwRootFrm*)GetUpper())->SetIdleFlags(); + if ( !pToMove->IsFlyInCntFrm() && pDest->GetPhyPageNum() < GetPhyPageNum() ) + ((SwRootFrm*)GetUpper())->SetSuperfluous(); + } + + pDest->InvalidateSpelling(); + pDest->InvalidateSmartTags(); // SMARTTAGS + pDest->InvalidateAutoCompleteWords(); + pDest->InvalidateWordCount(); + + if ( pToMove->IsFlyInCntFrm() ) + { + pDest->InvalidateFlyInCnt(); + return; + } + + // Notify accessible layout. That's required at this place for + // frames only where the anchor is moved. Creation of new frames + // is additionally handled by the SwFrmNotify class. + if( GetUpper() && + static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && + static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) + { + static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() + ->DisposeAccessibleFrm( pToMove, sal_True ); + } + + //Die FlyColl kann bereits weg sein, weil der DTor der Seite + //gerade 'laeuft' + if ( pSortedObjs ) + { + pSortedObjs->Remove( *pToMove ); + if ( !pSortedObjs->Count() ) + { DELETEZ( pSortedObjs ); + } + } + + //Anmelden + if ( !pDest->GetSortedObjs() ) + pDest->pSortedObjs = new SwSortedObjs(); + +#if OSL_DEBUG_LEVEL > 1 + const bool bSucessInserted = +#endif + pDest->GetSortedObjs()->Insert( *pToMove ); +#if OSL_DEBUG_LEVEL > 1 + OSL_ENSURE( bSucessInserted, "Fly nicht in Sorted eingetragen." ); + (void) bSucessInserted; +#endif + + // #i28701# - use new method <SetPageFrm(..)> + pToMove->SetPageFrm( pDest ); + pToMove->InvalidatePage( pDest ); + pToMove->SetNotifyBack(); + pDest->InvalidateFlyCntnt(); + // #i28701# + pToMove->UnlockPosition(); + + // Notify accessible layout. That's required at this place for + // frames only where the anchor is moved. Creation of new frames + // is additionally handled by the SwFrmNotify class. + if( GetUpper() && + static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && + static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) + { + static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() + ->AddAccessibleFrm( pToMove ); + } + + // #i28701# - correction: move lowers of Writer fly frame + if ( pToMove->GetDrawObjs() ) + { + SwSortedObjs &rObjs = *pToMove->GetDrawObjs(); + for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i ) + { + SwAnchoredObject* pObj = rObjs[i]; + if ( pObj->ISA(SwFlyFrm) ) + { + SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj); + if ( pFly->IsFlyFreeFrm() ) + { + // #i28701# - use new method <GetPageFrm()> + SwPageFrm* pPageFrm = pFly->GetPageFrm(); + if ( pPageFrm ) + pPageFrm->MoveFly( pFly, pDest ); + else + pDest->AppendFlyToPage( pFly ); + } + } + else if ( pObj->ISA(SwAnchoredDrawObject) ) + { + RemoveDrawObjFromPage( *pObj ); + pDest->AppendDrawObjToPage( *pObj ); + } + } + } +} + +/************************************************************************* +|* +|* SwPageFrm::AppendDrawObjToPage(), RemoveDrawObjFromPage() +|* +|* #i28701# - new methods +|* +|*************************************************************************/ +void SwPageFrm::AppendDrawObjToPage( SwAnchoredObject& _rNewObj ) +{ + if ( !_rNewObj.ISA(SwAnchoredDrawObject) ) + { + OSL_FAIL( "SwPageFrm::AppendDrawObjToPage(..) - anchored object of unexcepted type -> object not appended" ); + return; + } + + if ( GetUpper() ) + { + ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); + } + + OSL_ENSURE( _rNewObj.GetAnchorFrm(), "anchored draw object without anchor" ); + const SwFlyFrm* pFlyFrm = _rNewObj.GetAnchorFrm()->FindFlyFrm(); + if ( pFlyFrm && + _rNewObj.GetDrawObj()->GetOrdNum() < pFlyFrm->GetVirtDrawObj()->GetOrdNum() ) + { + sal_uInt32 nNewNum = pFlyFrm->GetVirtDrawObj()->GetOrdNumDirect(); + if ( _rNewObj.GetDrawObj()->GetPage() ) + _rNewObj.DrawObj()->GetPage()->SetObjectOrdNum( + _rNewObj.GetDrawObj()->GetOrdNumDirect(), nNewNum); + else + _rNewObj.DrawObj()->SetOrdNum( nNewNum ); + } + + if ( FLY_AS_CHAR == _rNewObj.GetFrmFmt().GetAnchor().GetAnchorId() ) + { + return; + } + + if ( !pSortedObjs ) + { + pSortedObjs = new SwSortedObjs(); + } + if ( !pSortedObjs->Insert( _rNewObj ) ) + { +#if OSL_DEBUG_LEVEL > 1 + OSL_ENSURE( pSortedObjs->Contains( _rNewObj ), + "Drawing object not appended into list <pSortedObjs>." ); +#endif + } + // #i87493# + OSL_ENSURE( _rNewObj.GetPageFrm() == 0 || _rNewObj.GetPageFrm() == this, + "<SwPageFrm::AppendDrawObjToPage(..)> - anchored draw object seems to be registered at another page frame. Serious defect -> please inform OD." ); + _rNewObj.SetPageFrm( this ); + + // invalidate page in order to force a reformat of object layout of the page. + InvalidateFlyLayout(); +} + +void SwPageFrm::RemoveDrawObjFromPage( SwAnchoredObject& _rToRemoveObj ) +{ + if ( !_rToRemoveObj.ISA(SwAnchoredDrawObject) ) + { + OSL_FAIL( "SwPageFrm::RemoveDrawObjFromPage(..) - anchored object of unexcepted type -> object not removed" ); + return; + } + + if ( pSortedObjs ) + { + pSortedObjs->Remove( _rToRemoveObj ); + if ( !pSortedObjs->Count() ) + { + DELETEZ( pSortedObjs ); + } + if ( GetUpper() ) + { + if (FLY_AS_CHAR != + _rToRemoveObj.GetFrmFmt().GetAnchor().GetAnchorId()) + { + ((SwRootFrm*)GetUpper())->SetSuperfluous(); + InvalidatePage(); + } + ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); + } + } + _rToRemoveObj.SetPageFrm( 0 ); +} + +/************************************************************************* +|* +|* SwPageFrm::PlaceFly +|* +|*************************************************************************/ + +// #i50432# - adjust method description and synopsis. +void SwPageFrm::PlaceFly( SwFlyFrm* pFly, SwFlyFrmFmt* pFmt ) +{ + // #i50432# - consider the case that page is an empty page: + // In this case append the fly frame at the next page + OSL_ENSURE( !IsEmptyPage() || GetNext(), + "<SwPageFrm::PlaceFly(..)> - empty page with no next page! -> fly frame appended at empty page" ); + if ( IsEmptyPage() && GetNext() ) + { + static_cast<SwPageFrm*>(GetNext())->PlaceFly( pFly, pFmt ); + } + else + { + //Wenn ein Fly uebergeben wurde, so benutzen wir diesen, ansonsten wird + //mit dem Format einer erzeugt. + if ( pFly ) + AppendFly( pFly ); + else + { OSL_ENSURE( pFmt, ":-( kein Format fuer Fly uebergeben." ); + pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, this, this ); + AppendFly( pFly ); + ::RegistFlys( this, pFly ); + } + } +} + +/************************************************************************* +|* +|* ::CalcClipRect +|* +|*************************************************************************/ +// #i18732# - adjustments for following text flow or not +// AND alignment at 'page areas' for to paragraph/to character anchored objects +// #i22305# - adjustment for following text flow +// for to frame anchored objects +// #i29778# - Because the calculation of the position of the +// floating screen object (Writer fly frame or drawing object) doesn't perform +// a calculation on its upper frames and its anchor frame, a calculation of +// the upper frames in this method no longer sensible. +// #i28701# - if document compatibility option 'Consider +// wrapping style influence on object positioning' is ON, the clip area +// corresponds to the one as the object doesn't follows the text flow. +sal_Bool CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, sal_Bool bMove ) +{ + sal_Bool bRet = sal_True; + if ( pSdrObj->ISA(SwVirtFlyDrawObj) ) + { + const SwFlyFrm* pFly = ((const SwVirtFlyDrawObj*)pSdrObj)->GetFlyFrm(); + const bool bFollowTextFlow = pFly->GetFmt()->GetFollowTextFlow().GetValue(); + // #i28701# + const bool bConsiderWrapOnObjPos = + pFly->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION); + const SwFmtVertOrient &rV = pFly->GetFmt()->GetVertOrient(); + if( pFly->IsFlyLayFrm() ) + { + const SwFrm* pClip; + // #i22305# + // #i28701# + if ( !bFollowTextFlow || bConsiderWrapOnObjPos ) + { + pClip = pFly->GetAnchorFrm()->FindPageFrm(); + } + else + { + pClip = pFly->GetAnchorFrm(); + } + + rRect = pClip->Frm(); + SWRECTFN( pClip ) + + //Vertikales clipping: Top und Bottom, ggf. an PrtArea + if( rV.GetVertOrient() != text::VertOrientation::NONE && + rV.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) + { + (rRect.*fnRect->fnSetTop)( (pClip->*fnRect->fnGetPrtTop)() ); + (rRect.*fnRect->fnSetBottom)( (pClip->*fnRect->fnGetPrtBottom)() ); + } + //Horizontales clipping: Left und Right, ggf. an PrtArea + const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient(); + if( rH.GetHoriOrient() != text::HoriOrientation::NONE && + rH.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) + { + (rRect.*fnRect->fnSetLeft)( (pClip->*fnRect->fnGetPrtLeft)() ); + (rRect.*fnRect->fnSetRight)((pClip->*fnRect->fnGetPrtRight)()); + } + } + else if( pFly->IsFlyAtCntFrm() ) + { + // #i18732# - consider following text flow or not + // AND alignment at 'page areas' + const SwFrm* pVertPosOrientFrm = pFly->GetVertPosOrientFrm(); + if ( !pVertPosOrientFrm ) + { + OSL_FAIL( "::CalcClipRect(..) - frame, vertical position is oriented at, is missing ."); + pVertPosOrientFrm = pFly->GetAnchorFrm(); + } + + if ( !bFollowTextFlow || bConsiderWrapOnObjPos ) + { + const SwLayoutFrm* pClipFrm = pVertPosOrientFrm->FindPageFrm(); + rRect = bMove ? pClipFrm->GetUpper()->Frm() + : pClipFrm->Frm(); + // #i26945# - consider that a table, during + // its format, can exceed its upper printing area bottom. + // Thus, enlarge the clip rectangle, if such a case occurred + if ( pFly->GetAnchorFrm()->IsInTab() ) + { + const SwTabFrm* pTabFrm = const_cast<SwFlyFrm*>(pFly) + ->GetAnchorFrmContainingAnchPos()->FindTabFrm(); + SwRect aTmp( pTabFrm->Prt() ); + aTmp += pTabFrm->Frm().Pos(); + rRect.Union( aTmp ); + // #i43913# - consider also the cell frame + const SwFrm* pCellFrm = const_cast<SwFlyFrm*>(pFly) + ->GetAnchorFrmContainingAnchPos()->GetUpper(); + while ( pCellFrm && !pCellFrm->IsCellFrm() ) + { + pCellFrm = pCellFrm->GetUpper(); + } + if ( pCellFrm ) + { + aTmp = pCellFrm->Prt(); + aTmp += pCellFrm->Frm().Pos(); + rRect.Union( aTmp ); + } + } + } + else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME || + rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) + { + // new class <SwEnvironmentOfAnchoredObject> + objectpositioning::SwEnvironmentOfAnchoredObject + aEnvOfObj( bFollowTextFlow ); + const SwLayoutFrm& rVertClipFrm = + aEnvOfObj.GetVertEnvironmentLayoutFrm( *pVertPosOrientFrm ); + if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME ) + { + rRect = rVertClipFrm.Frm(); + } + else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) + { + if ( rVertClipFrm.IsPageFrm() ) + { + rRect = static_cast<const SwPageFrm&>(rVertClipFrm).PrtWithoutHeaderAndFooter(); + } + else + { + rRect = rVertClipFrm.Frm(); + } + } + const SwLayoutFrm* pHoriClipFrm = + pFly->GetAnchorFrm()->FindPageFrm()->GetUpper(); + SWRECTFN( pFly->GetAnchorFrm() ) + (rRect.*fnRect->fnSetLeft)( (pHoriClipFrm->Frm().*fnRect->fnGetLeft)() ); + (rRect.*fnRect->fnSetRight)((pHoriClipFrm->Frm().*fnRect->fnGetRight)()); + } + else + { + // #i26945# + const SwFrm *pClip = + const_cast<SwFlyFrm*>(pFly)->GetAnchorFrmContainingAnchPos(); + SWRECTFN( pClip ) + const SwLayoutFrm *pUp = pClip->GetUpper(); + const SwFrm *pCell = pUp->IsCellFrm() ? pUp : 0; + sal_uInt16 nType = bMove ? FRM_ROOT | FRM_FLY | FRM_HEADER | + FRM_FOOTER | FRM_FTN + : FRM_BODY | FRM_FLY | FRM_HEADER | + FRM_FOOTER | FRM_CELL| FRM_FTN; + + while ( !(pUp->GetType() & nType) || pUp->IsColBodyFrm() ) + { + pUp = pUp->GetUpper(); + if ( !pCell && pUp->IsCellFrm() ) + pCell = pUp; + } + if ( bMove ) + { + if ( pUp->IsRootFrm() ) + { + rRect = pUp->Prt(); + rRect += pUp->Frm().Pos(); + pUp = 0; + } + } + if ( pUp ) + { + if ( pUp->GetType() & FRM_BODY ) + { + const SwPageFrm *pPg; + if ( pUp->GetUpper() != (pPg = pFly->FindPageFrm()) ) + pUp = pPg->FindBodyCont(); + rRect = pUp->GetUpper()->Frm(); + (rRect.*fnRect->fnSetTop)( (pUp->*fnRect->fnGetPrtTop)() ); + (rRect.*fnRect->fnSetBottom)((pUp->*fnRect->fnGetPrtBottom)()); + } + else + { + if( ( pUp->GetType() & (FRM_FLY | FRM_FTN ) ) && + !pUp->Frm().IsInside( pFly->Frm().Pos() ) ) + { + if( pUp->IsFlyFrm() ) + { + SwFlyFrm *pTmpFly = (SwFlyFrm*)pUp; + while( pTmpFly->GetNextLink() ) + { + pTmpFly = pTmpFly->GetNextLink(); + if( pTmpFly->Frm().IsInside( pFly->Frm().Pos() ) ) + break; + } + pUp = pTmpFly; + } + else if( pUp->IsInFtn() ) + { + const SwFtnFrm *pTmp = pUp->FindFtnFrm(); + while( pTmp->GetFollow() ) + { + pTmp = pTmp->GetFollow(); + if( pTmp->Frm().IsInside( pFly->Frm().Pos() ) ) + break; + } + pUp = pTmp; + } + } + rRect = pUp->Prt(); + rRect.Pos() += pUp->Frm().Pos(); + if ( pUp->GetType() & (FRM_HEADER | FRM_FOOTER) ) + { + rRect.Left ( pUp->GetUpper()->Frm().Left() ); + rRect.Width( pUp->GetUpper()->Frm().Width()); + } + else if ( pUp->IsCellFrm() ) //MA_FLY_HEIGHT + { + const SwFrm *pTab = pUp->FindTabFrm(); + (rRect.*fnRect->fnSetBottom)( + (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() ); + // expand to left and right cell border + rRect.Left ( pUp->Frm().Left() ); + rRect.Width( pUp->Frm().Width() ); + } + } + } + if ( pCell ) + { + //CellFrms koennen auch in 'unerlaubten' Bereichen stehen, dann + //darf der Fly das auch. + SwRect aTmp( pCell->Prt() ); + aTmp += pCell->Frm().Pos(); + rRect.Union( aTmp ); + } + } + } + else + { + const SwFrm *pUp = pFly->GetAnchorFrm()->GetUpper(); + SWRECTFN( pFly->GetAnchorFrm() ) + while( pUp->IsColumnFrm() || pUp->IsSctFrm() || pUp->IsColBodyFrm()) + pUp = pUp->GetUpper(); + rRect = pUp->Frm(); + if( !pUp->IsBodyFrm() ) + { + rRect += pUp->Prt().Pos(); + rRect.SSize( pUp->Prt().SSize() ); + if ( pUp->IsCellFrm() ) + { + const SwFrm *pTab = pUp->FindTabFrm(); + (rRect.*fnRect->fnSetBottom)( + (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() ); + } + } + else if ( pUp->GetUpper()->IsPageFrm() ) + { + // Objects anchored as character may exceed right margin + // of body frame: + (rRect.*fnRect->fnSetRight)( (pUp->GetUpper()->Frm().*fnRect->fnGetRight)() ); + } + long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10; + long nTop; + const SwFmt *pFmt = ((SwContact*)GetUserCall(pSdrObj))->GetFmt(); + const SvxULSpaceItem &rUL = pFmt->GetULSpace(); + if( bMove ) + { + nTop = bVert ? ((SwFlyInCntFrm*)pFly)->GetRefPoint().X() : + ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y(); + nTop = (*fnRect->fnYInc)( nTop, -nHeight ); + long nWidth = (pFly->Frm().*fnRect->fnGetWidth)(); + (rRect.*fnRect->fnSetLeftAndWidth)( bVert ? + ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y() : + ((SwFlyInCntFrm*)pFly)->GetRefPoint().X(), nWidth ); + nHeight = 2*nHeight - rUL.GetLower() - rUL.GetUpper(); + } + else + { + nTop = (*fnRect->fnYInc)( (pFly->Frm().*fnRect->fnGetBottom)(), + rUL.GetLower() - nHeight ); + nHeight = 2*nHeight - (pFly->Frm().*fnRect->fnGetHeight)() + - rUL.GetLower() - rUL.GetUpper(); + } + (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight ); + } + } + else + { + const SwDrawContact *pC = (const SwDrawContact*)GetUserCall(pSdrObj); + const SwFrmFmt *pFmt = (const SwFrmFmt*)pC->GetFmt(); + const SwFmtAnchor &rAnch = pFmt->GetAnchor(); + if ( FLY_AS_CHAR == rAnch.GetAnchorId() ) + { + const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj ); + if( !pAnchorFrm ) + { + OSL_FAIL( "<::CalcClipRect(..)> - missing anchor frame." ); + ((SwDrawContact*)pC)->ConnectToLayout(); + pAnchorFrm = pC->GetAnchorFrm(); + } + const SwFrm* pUp = pAnchorFrm->GetUpper(); + rRect = pUp->Prt(); + rRect += pUp->Frm().Pos(); + SWRECTFN( pAnchorFrm ) + long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10; + long nTop; + const SvxULSpaceItem &rUL = pFmt->GetULSpace(); + SwRect aSnapRect( pSdrObj->GetSnapRect() ); + long nTmpH = 0; + if( bMove ) + { + nTop = (*fnRect->fnYInc)( bVert ? pSdrObj->GetAnchorPos().X() : + pSdrObj->GetAnchorPos().Y(), -nHeight ); + long nWidth = (aSnapRect.*fnRect->fnGetWidth)(); + (rRect.*fnRect->fnSetLeftAndWidth)( bVert ? + pSdrObj->GetAnchorPos().Y() : + pSdrObj->GetAnchorPos().X(), nWidth ); + } + else + { + // #i26791# - value of <nTmpH> is needed to + // calculate value of <nTop>. + nTmpH = bVert ? pSdrObj->GetCurrentBoundRect().GetWidth() : + pSdrObj->GetCurrentBoundRect().GetHeight(); + nTop = (*fnRect->fnYInc)( (aSnapRect.*fnRect->fnGetTop)(), + rUL.GetLower() + nTmpH - nHeight ); + } + nHeight = 2*nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper(); + (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight ); + } + else + { + // restrict clip rectangle for drawing + // objects in header/footer to the page frame. + // #i26791# + const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj ); + if ( pAnchorFrm && pAnchorFrm->FindFooterOrHeader() ) + { + // clip frame is the page frame the header/footer is on. + const SwFrm* pClipFrm = pAnchorFrm->FindPageFrm(); + rRect = pClipFrm->Frm(); + } + else + { + bRet = sal_False; + } + } + } + return bRet; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |