| /************************************************************** |
| * |
| * 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 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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 "errhdl.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" |
| // OD 22.09.2003 #i18732# |
| #include <fmtfollowtextflow.hxx> |
| // OD 29.10.2003 #113049# |
| #include <environmentofanchoredobject.hxx> |
| // OD 2004-05-24 #i28701# |
| #include <sortedobjs.hxx> |
| #include <viewsh.hxx> |
| #include <viewimp.hxx> |
| |
| |
| using namespace ::com::sun::star; |
| |
| |
| /************************************************************************* |
| |* |
| |* SwFlyFreeFrm::SwFlyFreeFrm(), ~SwFlyFreeFrm() |
| |* |
| |* Ersterstellung MA 03. Dec. 92 |
| |* Letzte Aenderung MA 09. Apr. 99 |
| |* |
| |*************************************************************************/ |
| |
| SwFlyFreeFrm::SwFlyFreeFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) : |
| SwFlyFrm( pFmt, pSib, pAnch ), |
| pPage( 0 ), |
| // --> OD 2004-11-15 #i34753# |
| mbNoMakePos( false ), |
| // <-- |
| // --> OD 2004-11-12 #i37068# |
| mbNoMoveOnCheckClip( false ) |
| // <-- |
| { |
| } |
| |
| SwFlyFreeFrm::~SwFlyFreeFrm() |
| { |
| //und Tschuess. |
| // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()> |
| if( GetPageFrm() ) |
| { |
| if( GetFmt()->GetDoc()->IsInDtor() ) |
| { |
| // --> OD 2004-06-04 #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 ); |
| } |
| } |
| } |
| |
| // --> OD 2004-06-29 #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. |
| |* Ersterstellung MA 03. Dec. 92 |
| |* Letzte Aenderung MA 26. Aug. 93 |
| |* |
| |*************************************************************************/ |
| |
| void SwFlyFreeFrm::NotifyBackground( SwPageFrm *pPageFrm, |
| const SwRect& rRect, PrepareHint eHint ) |
| { |
| ::Notify_Background( GetVirtDrawObj(), pPageFrm, rRect, eHint, sal_True ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwFlyFreeFrm::MakeAll() |
| |* |
| |* Ersterstellung MA 18. Feb. 94 |
| |* Letzte Aenderung MA 03. Mar. 97 |
| |* |
| |*************************************************************************/ |
| |
| void SwFlyFreeFrm::MakeAll() |
| { |
| // OD 2004-01-19 #110582# |
| if ( !GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) ) |
| { |
| return; |
| } |
| |
| if ( !GetAnchorFrm() || IsLocked() || IsColLocked() ) |
| return; |
| // --> OD 2004-06-30 #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; |
| // --> OD 2004-11-03 #114798# - 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. |
| // --> OD 2004-11-15 #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; |
| } |
| // <-- |
| } |
| |
| // FME 2007-08-30 #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; |
| /* |
| // This is also done in the Format function, so I think |
| // this code is not necessary anymore: |
| const Size aRelSize( CalcRel( *pSz ) ); |
| const SwTwips nMin = MINFLY + rAttrs.CalcLeftLine()+rAttrs.CalcRightLine(); |
| long nDiff = bVert ? aRelSize.Height() : aRelSize.Width(); |
| if( nDiff < nMin ) |
| nDiff = nMin; |
| nDiff -= (aFrm.*fnRect->fnGetWidth)(); |
| if( nDiff ) |
| { |
| (aFrm.*fnRect->fnAddRight)( nDiff ); |
| bValidPos = 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)() ); |
| // OD 2004-03-23 #i26791# - use new method <MakeObjPos()> |
| // --> OD 2004-11-15 #i34753# - no positioning, if requested. |
| if ( IsNoMakePos() ) |
| bValidPos = sal_True; |
| else |
| // OD 2004-03-23 #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 |
| ASSERT( nLoopControlRuns < nLoopControlMax, "LoopControl in SwFlyFreeFrm::MakeAll" ) |
| #endif |
| |
| if ( nLoopControlRuns < nLoopControlMax ) |
| CheckClip( *pSz ); |
| } |
| else |
| nLoopControlRuns = 0; |
| } |
| Unlock(); |
| |
| #ifdef DBG_UTIL |
| SWRECTFN( this ) |
| ASSERT( bHeightClipped || ( (Frm().*fnRect->fnGetHeight)() > 0 && |
| (Prt().*fnRect->fnGetHeight)() > 0), |
| "SwFlyFreeFrm::Format(), flipping Fly." ); |
| |
| #endif |
| } |
| |
| /** determines, if direct environment of fly frame has 'auto' size |
| |
| OD 07.08.2003 #i17297#, #111066#, #111070# |
| 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. |
| |
| @author OD |
| |
| @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() |
| |* |
| |* Ersterstellung MA 21. Feb. 94 |
| |* Letzte Aenderung MA 03. Mar. 97 |
| |* |
| |*************************************************************************/ |
| |
| 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; |
| // --> OD 2004-11-12 #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; |
| } |
| |
| // OD 06.08.2003 #i17297#, #111066#, #111070# - 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; |
| } |
| |
| // OD 07.08.2003 #i17297#, #111066#, #111070# - reactivate change |
| // of size attribute for fly frames containing an ole object. |
| // FME: 2004-05-19 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 ); |
| } |
| } |
| } |
| |
| // --> OD 2004-10-14 #i26945# |
| ASSERT( Frm().Height() >= 0, |
| "<SwFlyFreeFrm::CheckClip(..)> - fly frame has negative height now." ); |
| // <-- |
| } |
| |
| /** method to determine, if a <MakeAll()> on the Writer fly frame is possible |
| |
| OD 2005-03-03 #i43771# |
| |
| @author OD |
| */ |
| bool SwFlyFreeFrm::IsFormatPossible() const |
| { |
| return SwFlyFrm::IsFormatPossible() && |
| ( GetPageFrm() || |
| ( GetAnchorFrm() && GetAnchorFrm()->IsInFly() ) ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwFlyLayFrm::SwFlyLayFrm() |
| |* |
| |* Ersterstellung MA 25. Aug. 92 |
| |* Letzte Aenderung MA 09. Apr. 99 |
| |* |
| |*************************************************************************/ |
| |
| SwFlyLayFrm::SwFlyLayFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) : |
| SwFlyFreeFrm( pFmt, pSib, pAnch ) |
| { |
| bLayout = sal_True; |
| } |
| |
| // --> OD 2004-06-29 #i28701# |
| TYPEINIT1(SwFlyLayFrm,SwFlyFreeFrm); |
| // <-- |
| /************************************************************************* |
| |* |
| |* SwFlyLayFrm::Modify() |
| |* |
| |* Ersterstellung MA 08. Feb. 93 |
| |* Letzte Aenderung MA 28. Aug. 93 |
| |* |
| |*************************************************************************/ |
| |
| 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 ) |
| { |
| ASSERT( pAnch->GetAnchorId() == |
| GetFmt()->GetAnchor().GetAnchorId(), |
| "8-) Unzulaessiger Wechsel des Ankertyps." ); |
| |
| //Abmelden, Seite besorgen, an den entsprechenden LayoutFrm |
| //haengen. |
| SwRect aOld( GetObjRectWithSpaces() ); |
| // --> OD 2004-06-30 #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 ) |
| { |
| // --> OD 2005-06-09 #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 ); |
| } |
| } |
| // --> OD 2004-06-30 #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() |
| |* |
| |* Ersterstellung MA 10. Oct. 92 |
| |* Letzte Aenderung MA 08. Jun. 96 |
| |* |
| |*************************************************************************/ |
| |
| 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(); |
| ASSERT( pNew->GetAnchorFrm(), "Fly without Anchor" ); |
| SwFlyFrm* pFly = (SwFlyFrm*)pNew->GetAnchorFrm()->FindFlyFrm(); |
| if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() ) |
| { |
| //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed. |
| sal_uInt32 nNewNum = pObj->GetOrdNumDirect(); |
| if ( pObj->GetPage() ) |
| pObj->GetPage()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum ); |
| else |
| pFly->GetVirtDrawObj()->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 |
| ASSERT( bSucessInserted, "Fly nicht in Sorted eingetragen." ) |
| (void) bSucessInserted; |
| #endif |
| |
| // --> OD 2008-04-22 #i87493# |
| ASSERT( pNew->GetPageFrm() == 0 || pNew->GetPageFrm() == this, |
| "<SwPageFrm::AppendFlyToPage(..)> - anchored fly frame seems to be registered at another page frame. Serious defect -> please inform OD." ); |
| // <-- |
| // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)> |
| pNew->SetPageFrm( this ); |
| pNew->InvalidatePage( this ); |
| // OD 2004-05-17 #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 ); |
| } |
| } |
| |
| // --> OD 2004-06-09 #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); |
| // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()> |
| if ( pTmpFly->IsFlyFreeFrm() && !pTmpFly->GetPageFrm() ) |
| AppendFlyToPage( pTmpFly ); |
| } |
| else if ( pTmpObj->ISA(SwAnchoredDrawObject) ) |
| { |
| // --> OD 2008-04-22 #i87493# |
| // AppendDrawObjToPage( *pTmpObj ); |
| if ( pTmpObj->GetPageFrm() != this ) |
| { |
| if ( pTmpObj->GetPageFrm() != 0 ) |
| { |
| pTmpObj->GetPageFrm()->RemoveDrawObjFromPage( *pTmpObj ); |
| } |
| AppendDrawObjToPage( *pTmpObj ); |
| } |
| // <-- |
| } |
| } |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwPageFrm::RemoveFly() |
| |* |
| |* Ersterstellung MA 10. Oct. 92 |
| |* Letzte Aenderung MA 26. Aug. 96 |
| |* |
| |*************************************************************************/ |
| |
| 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 ); |
| } |
| } |
| // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)> |
| pToRemove->SetPageFrm( 0L ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SwPageFrm::MoveFly |
| |* |
| |* Ersterstellung MA 25. Jan. 97 |
| |* Letzte Aenderung MA 25. Jan. 97 |
| |* |
| |*************************************************************************/ |
| |
| 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 |
| ASSERT( bSucessInserted, "Fly nicht in Sorted eingetragen." ) |
| (void) bSucessInserted; |
| #endif |
| |
| // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)> |
| pToMove->SetPageFrm( pDest ); |
| pToMove->InvalidatePage( pDest ); |
| pToMove->SetNotifyBack(); |
| pDest->InvalidateFlyCntnt(); |
| // OD 2004-05-17 #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 ); |
| } |
| |
| // --> OD 2004-06-09 #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() ) |
| { |
| // --> OD 2004-06-30 #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() |
| |* |
| |* --> OD 2004-07-02 #i28701# - new methods |
| |* |
| |*************************************************************************/ |
| void SwPageFrm::AppendDrawObjToPage( SwAnchoredObject& _rNewObj ) |
| { |
| if ( !_rNewObj.ISA(SwAnchoredDrawObject) ) |
| { |
| ASSERT( false, |
| "SwPageFrm::AppendDrawObjToPage(..) - anchored object of unexcepted type -> object not appended" ); |
| return; |
| } |
| |
| if ( GetUpper() ) |
| { |
| ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); |
| } |
| |
| ASSERT( _rNewObj.GetAnchorFrm(), "anchored draw object without anchor" ); |
| SwFlyFrm* pFlyFrm = (SwFlyFrm*)_rNewObj.GetAnchorFrm()->FindFlyFrm(); |
| if ( pFlyFrm && |
| _rNewObj.GetDrawObj()->GetOrdNum() < pFlyFrm->GetVirtDrawObj()->GetOrdNum() ) |
| { |
| //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed. |
| sal_uInt32 nNewNum = _rNewObj.GetDrawObj()->GetOrdNumDirect(); |
| if ( _rNewObj.GetDrawObj()->GetPage() ) |
| _rNewObj.DrawObj()->GetPage()->SetObjectOrdNum( pFlyFrm->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum ); |
| else |
| pFlyFrm->GetVirtDrawObj()->SetOrdNum( nNewNum ); |
| } |
| |
| if ( FLY_AS_CHAR == _rNewObj.GetFrmFmt().GetAnchor().GetAnchorId() ) |
| { |
| return; |
| } |
| |
| if ( !pSortedObjs ) |
| { |
| pSortedObjs = new SwSortedObjs(); |
| } |
| if ( !pSortedObjs->Insert( _rNewObj ) ) |
| { |
| #ifdef DBG_UTIL |
| ASSERT( pSortedObjs->Contains( _rNewObj ), |
| "Drawing object not appended into list <pSortedObjs>." ); |
| #endif |
| } |
| // --> OD 2008-04-22 #i87493# |
| ASSERT( _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) ) |
| { |
| ASSERT( false, |
| "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 |
| |* |
| |* Ersterstellung MA 08. Feb. 93 |
| |* Letzte Aenderung MA 27. Feb. 93 |
| |* |
| |*************************************************************************/ |
| |
| // --> OD 2005-06-09 #i50432# - adjust method description and synopsis. |
| void SwPageFrm::PlaceFly( SwFlyFrm* pFly, SwFlyFrmFmt* pFmt ) |
| { |
| // --> OD 2005-06-09 #i50432# - consider the case that page is an empty page: |
| // In this case append the fly frame at the next page |
| ASSERT( !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 |
| { ASSERT( pFmt, ":-( kein Format fuer Fly uebergeben." ); |
| pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, this, this ); |
| AppendFly( pFly ); |
| ::RegistFlys( this, pFly ); |
| } |
| } |
| // <-- |
| } |
| |
| /************************************************************************* |
| |* |
| |* ::CalcClipRect |
| |* |
| |* Ersterstellung AMA 24. Sep. 96 |
| |* Letzte Aenderung MA 18. Dec. 96 |
| |* |
| |*************************************************************************/ |
| // OD 22.09.2003 #i18732# - adjustments for following text flow or not |
| // AND alignment at 'page areas' for to paragraph/to character anchored objects |
| // OD 06.11.2003 #i22305# - adjustment for following text flow |
| // for to frame anchored objects |
| // OD 2004-06-02 #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. |
| // --> OD 2004-07-06 #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(); |
| // --> OD 2004-07-06 #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; |
| // OD 06.11.2003 #i22305# |
| // --> OD 2004-07-06 #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() ) |
| { |
| // OD 22.09.2003 #i18732# - consider following text flow or not |
| // AND alignment at 'page areas' |
| const SwFrm* pVertPosOrientFrm = pFly->GetVertPosOrientFrm(); |
| if ( !pVertPosOrientFrm ) |
| { |
| ASSERT( false, |
| "::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(); |
| // --> OD 2004-10-14 #i26945# - consider that a table, during |
| // its format, can exceed its upper printing area bottom. |
| // Thus, enlarge the clip rectangle, if such a case occured |
| if ( pFly->GetAnchorFrm()->IsInTab() ) |
| { |
| const SwTabFrm* pTabFrm = const_cast<SwFlyFrm*>(pFly) |
| ->GetAnchorFrmContainingAnchPos()->FindTabFrm(); |
| SwRect aTmp( pTabFrm->Prt() ); |
| aTmp += pTabFrm->Frm().Pos(); |
| rRect.Union( aTmp ); |
| // --> OD 2005-03-30 #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 ) |
| { |
| // OD 29.10.2003 #113049# - 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 |
| { |
| // --> OD 2004-10-11 #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)() ); |
| // OD 08.08.2003 #110978# - 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() ) |
| { |
| // #111909# 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 ) |
| { |
| ASSERT( false, "<::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 |
| { |
| // OD 2004-04-13 #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 |
| { |
| // OD 23.06.2003 #108784# - restrict clip rectangle for drawing |
| // objects in header/footer to the page frame. |
| // OD 2004-03-29 #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; |
| } |