update dev300-m58
[ooovba.git] / sw / source / core / layout / flylay.cxx
blob85d8ac89c18a4cf020d57eb19133170236b8cd28
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: flylay.cxx,v $
10 * $Revision: 1.55 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include "doc.hxx"
34 #include "pagefrm.hxx"
35 #include "rootfrm.hxx"
36 #include "cntfrm.hxx"
37 #include "dview.hxx"
38 #include "dflyobj.hxx"
39 #include "dcontact.hxx"
40 #include "flyfrm.hxx"
41 #include "ftnfrm.hxx"
42 #include "frmtool.hxx"
43 #include "frmfmt.hxx"
44 #include "errhdl.hxx"
45 #include "hints.hxx"
46 #include "pam.hxx"
47 #include "sectfrm.hxx"
50 #include <svx/svdpage.hxx>
51 #include <svx/ulspitem.hxx>
52 #include <fmtanchr.hxx>
53 #include <fmtornt.hxx>
54 #include <fmtfsize.hxx>
55 #include "ndole.hxx"
56 #include "tabfrm.hxx"
57 #include "flyfrms.hxx"
58 // OD 22.09.2003 #i18732#
59 #include <fmtfollowtextflow.hxx>
60 // OD 29.10.2003 #113049#
61 #include <environmentofanchoredobject.hxx>
62 // OD 2004-05-24 #i28701#
63 #include <sortedobjs.hxx>
64 #include <viewsh.hxx>
65 #include <viewimp.hxx>
68 using namespace ::com::sun::star;
71 /*************************************************************************
73 |* SwFlyFreeFrm::SwFlyFreeFrm(), ~SwFlyFreeFrm()
75 |* Ersterstellung MA 03. Dec. 92
76 |* Letzte Aenderung MA 09. Apr. 99
78 |*************************************************************************/
80 SwFlyFreeFrm::SwFlyFreeFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
81 SwFlyFrm( pFmt, pAnch ),
82 pPage( 0 ),
83 // --> OD 2004-11-15 #i34753#
84 mbNoMakePos( false ),
85 // <--
86 // --> OD 2004-11-12 #i37068#
87 mbNoMoveOnCheckClip( false )
88 // <--
92 SwFlyFreeFrm::~SwFlyFreeFrm()
94 //und Tschuess.
95 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
96 if( GetPageFrm() )
98 if( GetFmt()->GetDoc()->IsInDtor() )
100 // --> OD 2004-06-04 #i29879# - remove also to-frame anchored Writer
101 // fly frame from page.
102 const bool bRemoveFromPage =
103 GetPageFrm()->GetSortedObjs() &&
104 ( IsFlyAtCntFrm() ||
105 ( GetAnchorFrm() && GetAnchorFrm()->IsFlyFrm() ) );
106 if ( bRemoveFromPage )
108 GetPageFrm()->GetSortedObjs()->Remove( *this );
111 else
113 SwRect aTmp( GetObjRectWithSpaces() );
114 SwFlyFreeFrm::NotifyBackground( GetPageFrm(), aTmp, PREP_FLY_LEAVE );
119 // --> OD 2004-06-29 #i28701#
120 TYPEINIT1(SwFlyFreeFrm,SwFlyFrm);
121 // <--
122 /*************************************************************************
124 |* SwFlyFreeFrm::NotifyBackground()
126 |* Beschreibung Benachrichtigt den Hintergrund (alle CntntFrms die
127 |* gerade ueberlappt werden. Ausserdem wird das Window in einigen
128 |* Faellen direkt invalidiert (vor allem dort, wo keine CntntFrms
129 |* ueberlappt werden.
130 |* Es werden auch die CntntFrms innerhalb von anderen Flys
131 |* beruecksichtigt.
132 |* Ersterstellung MA 03. Dec. 92
133 |* Letzte Aenderung MA 26. Aug. 93
135 |*************************************************************************/
137 void SwFlyFreeFrm::NotifyBackground( SwPageFrm *pPageFrm,
138 const SwRect& rRect, PrepareHint eHint )
140 ::Notify_Background( GetVirtDrawObj(), pPageFrm, rRect, eHint, TRUE );
143 /*************************************************************************
145 |* SwFlyFreeFrm::MakeAll()
147 |* Ersterstellung MA 18. Feb. 94
148 |* Letzte Aenderung MA 03. Mar. 97
150 |*************************************************************************/
152 void SwFlyFreeFrm::MakeAll()
154 // OD 2004-01-19 #110582#
155 if ( !GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
157 return;
160 if ( !GetAnchorFrm() || IsLocked() || IsColLocked() )
161 return;
162 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
163 if( !GetPageFrm() && GetAnchorFrm() && GetAnchorFrm()->IsInFly() )
165 SwFlyFrm* pFly = AnchorFrm()->FindFlyFrm();
166 SwPageFrm *pPageFrm = pFly ? pFly->FindPageFrm() : NULL;
167 if( pPageFrm )
168 pPageFrm->AppendFlyToPage( this );
170 if( !GetPageFrm() )
171 return;
173 Lock(); //Der Vorhang faellt
175 //uebernimmt im DTor die Benachrichtigung
176 const SwFlyNotify aNotify( this );
178 if ( IsClipped() )
180 bValidSize = bHeightClipped = bWidthClipped = FALSE;
181 // --> OD 2004-11-03 #114798# - no invalidation of position,
182 // if anchored object is anchored inside a Writer fly frame,
183 // its position is already locked, and it follows the text flow.
184 // --> OD 2004-11-15 #i34753# - add condition:
185 // no invalidation of position, if no direct move is requested in <CheckClip(..)>
186 if ( !IsNoMoveOnCheckClip() &&
187 !( PositionLocked() &&
188 GetAnchorFrm()->IsInFly() &&
189 GetFrmFmt().GetFollowTextFlow().GetValue() ) )
190 // <--
192 bValidPos = FALSE;
194 // <--
197 // FME 2007-08-30 #i81146# new loop control
198 USHORT nLoopControlRuns = 0;
199 const USHORT nLoopControlMax = 10;
201 while ( !bValidPos || !bValidSize || !bValidPrtArea || bFormatHeightOnly )
203 SWRECTFN( this )
204 const SwFmtFrmSize *pSz;
205 { //Zusaetzlicher Scope, damit aAccess vor dem Check zerstoert wird!
207 SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
208 const SwBorderAttrs &rAttrs = *aAccess.Get();
209 pSz = &rAttrs.GetAttrSet().GetFrmSize();
211 //Nur einstellen wenn das Flag gesetzt ist!!
212 if ( !bValidSize )
214 bValidPrtArea = FALSE;
216 // This is also done in the Format function, so I think
217 // this code is not necessary anymore:
218 const Size aRelSize( CalcRel( *pSz ) );
219 const SwTwips nMin = MINFLY + rAttrs.CalcLeftLine()+rAttrs.CalcRightLine();
220 long nDiff = bVert ? aRelSize.Height() : aRelSize.Width();
221 if( nDiff < nMin )
222 nDiff = nMin;
223 nDiff -= (aFrm.*fnRect->fnGetWidth)();
224 if( nDiff )
226 (aFrm.*fnRect->fnAddRight)( nDiff );
227 bValidPos = FALSE;
232 if ( !bValidPrtArea )
233 MakePrtArea( rAttrs );
235 if ( !bValidSize || bFormatHeightOnly )
237 bValidSize = FALSE;
238 Format( &rAttrs );
239 bFormatHeightOnly = FALSE;
242 if ( !bValidPos )
244 const Point aOldPos( (Frm().*fnRect->fnGetPos)() );
245 // OD 2004-03-23 #i26791# - use new method <MakeObjPos()>
246 // --> OD 2004-11-15 #i34753# - no positioning, if requested.
247 if ( IsNoMakePos() )
248 bValidPos = TRUE;
249 else
250 // OD 2004-03-23 #i26791# - use new method <MakeObjPos()>
251 MakeObjPos();
252 // <--
253 if( aOldPos == (Frm().*fnRect->fnGetPos)() )
255 if( !bValidPos && GetAnchorFrm()->IsInSct() &&
256 !GetAnchorFrm()->FindSctFrm()->IsValid() )
257 bValidPos = TRUE;
259 else
260 bValidSize = FALSE;
264 if ( bValidPos && bValidSize )
266 ++nLoopControlRuns;
268 #if OSL_DEBUG_LEVEL > 1
269 ASSERT( nLoopControlRuns < nLoopControlMax, "LoopControl in SwFlyFreeFrm::MakeAll" )
270 #endif
272 if ( nLoopControlRuns < nLoopControlMax )
273 CheckClip( *pSz );
275 else
276 nLoopControlRuns = 0;
278 Unlock();
280 #ifndef PRODUCT
281 SWRECTFN( this )
282 ASSERT( bHeightClipped || ( (Frm().*fnRect->fnGetHeight)() > 0 &&
283 (Prt().*fnRect->fnGetHeight)() > 0),
284 "SwFlyFreeFrm::Format(), flipping Fly." );
286 #endif
289 /** determines, if direct environment of fly frame has 'auto' size
291 OD 07.08.2003 #i17297#, #111066#, #111070#
292 start with anchor frame and search via <GetUpper()> for a header, footer,
293 row or fly frame stopping at page frame.
294 return <true>, if such a frame is found and it has 'auto' size.
295 otherwise <false> is returned.
297 @author OD
299 @return boolean indicating, that direct environment has 'auto' size
301 bool SwFlyFreeFrm::HasEnvironmentAutoSize() const
303 bool bRetVal = false;
305 const SwFrm* pToBeCheckedFrm = GetAnchorFrm();
306 while ( pToBeCheckedFrm &&
307 !pToBeCheckedFrm->IsPageFrm() )
309 if ( pToBeCheckedFrm->IsHeaderFrm() ||
310 pToBeCheckedFrm->IsFooterFrm() ||
311 pToBeCheckedFrm->IsRowFrm() ||
312 pToBeCheckedFrm->IsFlyFrm() )
314 bRetVal = ATT_FIX_SIZE !=
315 pToBeCheckedFrm->GetAttrSet()->GetFrmSize().GetHeightSizeType();
316 break;
318 else
320 pToBeCheckedFrm = pToBeCheckedFrm->GetUpper();
324 return bRetVal;
327 /*************************************************************************
329 |* SwFlyFreeFrm::CheckClip()
331 |* Ersterstellung MA 21. Feb. 94
332 |* Letzte Aenderung MA 03. Mar. 97
334 |*************************************************************************/
336 void SwFlyFreeFrm::CheckClip( const SwFmtFrmSize &rSz )
338 //Jetzt ist es ggf. an der Zeit geignete Massnahmen zu ergreifen wenn
339 //der Fly nicht in seine Umgebung passt.
340 //Zuerst gibt der Fly seine Position auf. Danach wird er zunaechst
341 //formatiert. Erst wenn er auch durch die Aufgabe der Position nicht
342 //passt wird die Breite oder Hoehe aufgegeben - der Rahmen wird soweit
343 //wie notwendig zusammengequetscht.
345 const SwVirtFlyDrawObj *pObj = GetVirtDrawObj();
346 SwRect aClip, aTmpStretch;
347 ::CalcClipRect( pObj, aClip, TRUE );
348 ::CalcClipRect( pObj, aTmpStretch, FALSE );
349 aClip._Intersection( aTmpStretch );
351 const long nBot = Frm().Top() + Frm().Height();
352 const long nRig = Frm().Left() + Frm().Width();
353 const long nClipBot = aClip.Top() + aClip.Height();
354 const long nClipRig = aClip.Left() + aClip.Width();
356 const BOOL bBot = nBot > nClipBot;
357 const BOOL bRig = nRig > nClipRig;
358 if ( bBot || bRig )
360 BOOL bAgain = FALSE;
361 // --> OD 2004-11-12 #i37068# - no move, if it's requested
362 if ( bBot && !IsNoMoveOnCheckClip() &&
363 !GetDrawObjs() && !GetAnchorFrm()->IsInTab() )
364 // <--
366 SwFrm* pHeader = FindFooterOrHeader();
367 // In a header, correction of the position is no good idea.
368 // If the fly moves, some paragraphs has to be formatted, this
369 // could cause a change of the height of the headerframe,
370 // now the flyframe can change its position and so on ...
371 if ( !pHeader || !pHeader->IsHeaderFrm() )
373 const long nOld = Frm().Top();
374 Frm().Pos().Y() = Max( aClip.Top(), nClipBot - Frm().Height() );
375 if ( Frm().Top() != nOld )
376 bAgain = TRUE;
377 bHeightClipped = TRUE;
380 if ( bRig )
382 const long nOld = Frm().Left();
383 Frm().Pos().X() = Max( aClip.Left(), nClipRig - Frm().Width() );
384 if ( Frm().Left() != nOld )
386 const SwFmtHoriOrient &rH = GetFmt()->GetHoriOrient();
387 // Links ausgerichtete duerfen nicht nach links verschoben werden,
388 // wenn sie einem anderen ausweichen.
389 if( rH.GetHoriOrient() == text::HoriOrientation::LEFT )
390 Frm().Pos().X() = nOld;
391 else
392 bAgain = TRUE;
394 bWidthClipped = TRUE;
396 if ( bAgain )
397 bValidSize = FALSE;
398 else
400 //Wenn wir hier ankommen ragt der Frm in unerlaubte Bereiche
401 //hinein, und eine Positionskorrektur ist nicht erlaubt bzw.
402 //moeglich oder noetig.
404 //Fuer Flys mit OLE-Objekten als Lower sorgen wir dafuer, dass
405 //immer proportional Resized wird.
406 Size aOldSize( Frm().SSize() );
408 //Zuerst wird das FrmRect eingestellt, und dann auf den Frm
409 //uebertragen.
410 SwRect aFrmRect( Frm() );
412 if ( bBot )
414 long nDiff = nClipBot;
415 nDiff -= aFrmRect.Top(); //nDiff ist die verfuegbare Strecke.
416 nDiff = aFrmRect.Height() - nDiff;
417 aFrmRect.Height( aFrmRect.Height() - nDiff );
418 bHeightClipped = TRUE;
420 if ( bRig )
422 long nDiff = nClipRig;
423 nDiff -= aFrmRect.Left();//nDiff ist die verfuegbare Strecke.
424 nDiff = aFrmRect.Width() - nDiff;
425 aFrmRect.Width( aFrmRect.Width() - nDiff );
426 bWidthClipped = TRUE;
429 // OD 06.08.2003 #i17297#, #111066#, #111070# - no proportional
430 // scaling of graphics in environments, which determines its size
431 // by its content ('auto' size). Otherwise layout loops can occur and
432 // layout sizes of the environment can be incorrect.
433 // Such environment are:
434 // (1) header and footer frames with 'auto' size
435 // (2) table row frames with 'auto' size
436 // (3) fly frames with 'auto' size
437 // Note: section frames seems to be not critical - didn't found
438 // any critical layout situation so far.
439 if ( Lower() && Lower()->IsNoTxtFrm() &&
440 ( static_cast<SwCntntFrm*>(Lower())->GetNode()->GetOLENode() ||
441 !HasEnvironmentAutoSize() ) )
443 //Wenn Breite und Hoehe angepasst wurden, so ist die
444 //groessere Veraenderung massgeblich.
445 if ( aFrmRect.Width() != aOldSize.Width() &&
446 aFrmRect.Height()!= aOldSize.Height() )
448 if ( (aOldSize.Width() - aFrmRect.Width()) >
449 (aOldSize.Height()- aFrmRect.Height()) )
450 aFrmRect.Height( aOldSize.Height() );
451 else
452 aFrmRect.Width( aOldSize.Width() );
455 //Breite angepasst? - Hoehe dann proportional verkleinern
456 if( aFrmRect.Width() != aOldSize.Width() )
458 aFrmRect.Height( aFrmRect.Width() * aOldSize.Height() /
459 aOldSize.Width() );
460 bHeightClipped = TRUE;
462 //Hoehe angepasst? - Breite dann proportional verkleinern
463 else if( aFrmRect.Height() != aOldSize.Height() )
465 aFrmRect.Width( aFrmRect.Height() * aOldSize.Width() /
466 aOldSize.Height() );
467 bWidthClipped = TRUE;
470 // OD 07.08.2003 #i17297#, #111066#, #111070# - reactivate change
471 // of size attribute for fly frames containing an ole object.
472 // FME: 2004-05-19 Added the aFrmRect.HasArea() hack, because
473 // the environment of the ole object does not have to be valid
474 // at this moment, or even worse, it does not have to have a
475 // resonable size. In this case we do not want to change to
476 // attributes permanentely. Maybe one day somebody dares to remove
477 // this code.
478 if ( aFrmRect.HasArea() &&
479 static_cast<SwCntntFrm*>(Lower())->GetNode()->GetOLENode() &&
480 ( bWidthClipped || bHeightClipped ) )
482 SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
483 pFmt->LockModify();
484 SwFmtFrmSize aFrmSize( rSz );
485 aFrmSize.SetWidth( aFrmRect.Width() );
486 aFrmSize.SetHeight( aFrmRect.Height() );
487 pFmt->SetFmtAttr( aFrmSize );
488 pFmt->UnlockModify();
492 //Jetzt die Einstellungen am Frm vornehmen, bei Spalten werden
493 //die neuen Werte in die Attribute eingetragen, weil es sonst
494 //ziemlich fiese Oszillationen gibt.
495 const long nPrtHeightDiff = Frm().Height() - Prt().Height();
496 const long nPrtWidthDiff = Frm().Width() - Prt().Width();
497 Frm().Height( aFrmRect.Height() );
498 Frm().Width ( Max( long(MINLAY), aFrmRect.Width() ) );
499 if ( Lower() && Lower()->IsColumnFrm() )
501 ColLock(); //Grow/Shrink locken.
502 const Size aTmpOldSize( Prt().SSize() );
503 Prt().Height( Frm().Height() - nPrtHeightDiff );
504 Prt().Width ( Frm().Width() - nPrtWidthDiff );
505 ChgLowersProp( aTmpOldSize );
506 SwFrm *pLow = Lower();
508 { pLow->Calc();
509 // auch den (Column)BodyFrm mitkalkulieren
510 ((SwLayoutFrm*)pLow)->Lower()->Calc();
511 pLow = pLow->GetNext();
512 } while ( pLow );
513 ::CalcCntnt( this );
514 ColUnlock();
515 if ( !bValidSize && !bWidthClipped )
516 bFormatHeightOnly = bValidSize = TRUE;
518 else
520 Prt().Height( Frm().Height() - nPrtHeightDiff );
521 Prt().Width ( Frm().Width() - nPrtWidthDiff );
526 // --> OD 2004-10-14 #i26945#
527 ASSERT( Frm().Height() >= 0,
528 "<SwFlyFreeFrm::CheckClip(..)> - fly frame has negative height now." );
529 // <--
532 /** method to determine, if a <MakeAll()> on the Writer fly frame is possible
534 OD 2005-03-03 #i43771#
536 @author OD
538 bool SwFlyFreeFrm::IsFormatPossible() const
540 return SwFlyFrm::IsFormatPossible() &&
541 ( GetPageFrm() ||
542 ( GetAnchorFrm() && GetAnchorFrm()->IsInFly() ) );
545 /*************************************************************************
547 |* SwFlyLayFrm::SwFlyLayFrm()
549 |* Ersterstellung MA 25. Aug. 92
550 |* Letzte Aenderung MA 09. Apr. 99
552 |*************************************************************************/
554 SwFlyLayFrm::SwFlyLayFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
555 SwFlyFreeFrm( pFmt, pAnch )
557 bLayout = TRUE;
560 // --> OD 2004-06-29 #i28701#
561 TYPEINIT1(SwFlyLayFrm,SwFlyFreeFrm);
562 // <--
563 /*************************************************************************
565 |* SwFlyLayFrm::Modify()
567 |* Ersterstellung MA 08. Feb. 93
568 |* Letzte Aenderung MA 28. Aug. 93
570 |*************************************************************************/
572 void SwFlyLayFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
574 USHORT nWhich = pNew ? pNew->Which() : 0;
576 SwFmtAnchor *pAnch = 0;
577 if( RES_ATTRSET_CHG == nWhich && SFX_ITEM_SET ==
578 ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_ANCHOR, FALSE,
579 (const SfxPoolItem**)&pAnch ))
580 ; // Beim GetItemState wird der AnkerPointer gesetzt !
582 else if( RES_ANCHOR == nWhich )
584 //Ankerwechsel, ich haenge mich selbst um.
585 //Es darf sich nicht um einen Wechsel des Ankertyps handeln,
586 //dies ist nur ueber die SwFEShell moeglich.
587 pAnch = (SwFmtAnchor*)pNew;
590 if( pAnch )
592 ASSERT( pAnch->GetAnchorId() ==
593 GetFmt()->GetAnchor().GetAnchorId(),
594 "8-) Unzulaessiger Wechsel des Ankertyps." );
596 //Abmelden, Seite besorgen, an den entsprechenden LayoutFrm
597 //haengen.
598 SwRect aOld( GetObjRectWithSpaces() );
599 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
600 SwPageFrm *pOldPage = GetPageFrm();
601 AnchorFrm()->RemoveFly( this );
603 if( FLY_PAGE == pAnch->GetAnchorId() )
605 USHORT nPgNum = pAnch->GetPageNum();
606 SwRootFrm *pRoot = FindRootFrm();
607 SwPageFrm *pTmpPage = (SwPageFrm*)pRoot->Lower();
608 for ( USHORT i = 1; (i <= nPgNum) && pTmpPage; ++i,
609 pTmpPage = (SwPageFrm*)pTmpPage->GetNext() )
611 if ( i == nPgNum )
613 // --> OD 2005-06-09 #i50432# - adjust synopsis of <PlaceFly(..)>
614 pTmpPage->PlaceFly( this, 0 );
615 // <--
618 if( !pTmpPage )
620 pRoot->SetAssertFlyPages();
621 pRoot->AssertFlyPages();
624 else
626 SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode );
627 SwCntntFrm *pCntnt = GetFmt()->GetDoc()->GetNodes().GoNext( &aIdx )->
628 GetCntntNode()->GetFrm( 0, 0, FALSE );
629 if( pCntnt )
631 SwFlyFrm *pTmp = pCntnt->FindFlyFrm();
632 if( pTmp )
633 pTmp->AppendFly( this );
636 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
637 if ( pOldPage && pOldPage != GetPageFrm() )
638 NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE );
639 SetCompletePaint();
640 InvalidateAll();
641 SetNotifyBack();
643 else
644 SwFlyFrm::Modify( pOld, pNew );
647 /*************************************************************************
649 |* SwPageFrm::AppendFly()
651 |* Ersterstellung MA 10. Oct. 92
652 |* Letzte Aenderung MA 08. Jun. 96
654 |*************************************************************************/
656 void SwPageFrm::AppendFlyToPage( SwFlyFrm *pNew )
658 if ( !pNew->GetVirtDrawObj()->IsInserted() )
659 FindRootFrm()->GetDrawPage()->InsertObject(
660 (SdrObject*)pNew->GetVirtDrawObj(),
661 pNew->GetVirtDrawObj()->GetReferencedObj().GetOrdNumDirect() );
663 InvalidateSpelling();
664 InvalidateSmartTags(); // SMARTTAGS
665 InvalidateAutoCompleteWords();
666 InvalidateWordCount();
668 if ( GetUpper() )
670 ((SwRootFrm*)GetUpper())->SetIdleFlags();
671 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
674 SdrObject* pObj = pNew->GetVirtDrawObj();
675 ASSERT( pNew->GetAnchorFrm(), "Fly without Anchor" );
676 const SwFlyFrm* pFly = pNew->GetAnchorFrm()->FindFlyFrm();
677 if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() )
679 UINT32 nNewNum = pFly->GetVirtDrawObj()->GetOrdNumDirect();
680 if ( pObj->GetPage() )
681 pObj->GetPage()->SetObjectOrdNum( pObj->GetOrdNumDirect(), nNewNum);
682 else
683 pObj->SetOrdNum( nNewNum );
686 //Flys die im Cntnt sitzen beachten wir nicht weiter.
687 if ( pNew->IsFlyInCntFrm() )
688 InvalidateFlyInCnt();
689 else
691 InvalidateFlyCntnt();
693 if ( !pSortedObjs )
694 pSortedObjs = new SwSortedObjs();
696 #if OSL_DEBUG_LEVEL > 1
697 const bool bSucessInserted =
698 #endif
699 pSortedObjs->Insert( *pNew );
700 #if OSL_DEBUG_LEVEL > 1
701 ASSERT( bSucessInserted, "Fly nicht in Sorted eingetragen." )
702 (void) bSucessInserted;
703 #endif
705 // --> OD 2008-04-22 #i87493#
706 ASSERT( pNew->GetPageFrm() == 0 || pNew->GetPageFrm() == this,
707 "<SwPageFrm::AppendFlyToPage(..)> - anchored fly frame seems to be registered at another page frame. Serious defect -> please inform OD." );
708 // <--
709 // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)>
710 pNew->SetPageFrm( this );
711 pNew->InvalidatePage( this );
712 // OD 2004-05-17 #i28701#
713 pNew->UnlockPosition();
715 // Notify accessible layout. That's required at this place for
716 // frames only where the anchor is moved. Creation of new frames
717 // is additionally handled by the SwFrmNotify class.
718 if( GetUpper() &&
719 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
720 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
722 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
723 ->AddAccessibleFrm( pNew );
727 // --> OD 2004-06-09 #i28701# - correction: consider also drawing objects
728 if ( pNew->GetDrawObjs() )
730 SwSortedObjs &rObjs = *pNew->GetDrawObjs();
731 for ( USHORT i = 0; i < rObjs.Count(); ++i )
733 SwAnchoredObject* pTmpObj = rObjs[i];
734 if ( pTmpObj->ISA(SwFlyFrm) )
736 SwFlyFrm* pTmpFly = static_cast<SwFlyFrm*>(pTmpObj);
737 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
738 if ( pTmpFly->IsFlyFreeFrm() && !pTmpFly->GetPageFrm() )
739 AppendFlyToPage( pTmpFly );
741 else if ( pTmpObj->ISA(SwAnchoredDrawObject) )
743 // --> OD 2008-04-22 #i87493#
744 // AppendDrawObjToPage( *pTmpObj );
745 if ( pTmpObj->GetPageFrm() != this )
747 if ( pTmpObj->GetPageFrm() != 0 )
749 pTmpObj->GetPageFrm()->RemoveDrawObjFromPage( *pTmpObj );
751 AppendDrawObjToPage( *pTmpObj );
753 // <--
759 /*************************************************************************
761 |* SwPageFrm::RemoveFly()
763 |* Ersterstellung MA 10. Oct. 92
764 |* Letzte Aenderung MA 26. Aug. 96
766 |*************************************************************************/
768 void SwPageFrm::RemoveFlyFromPage( SwFlyFrm *pToRemove )
770 const UINT32 nOrdNum = pToRemove->GetVirtDrawObj()->GetOrdNum();
771 FindRootFrm()->GetDrawPage()->RemoveObject( nOrdNum );
772 pToRemove->GetVirtDrawObj()->ReferencedObj().SetOrdNum( nOrdNum );
774 if ( GetUpper() )
776 if ( !pToRemove->IsFlyInCntFrm() )
777 ((SwRootFrm*)GetUpper())->SetSuperfluous();
778 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
781 //Flys die im Cntnt sitzen beachten wir nicht weiter.
782 if ( pToRemove->IsFlyInCntFrm() )
783 return;
785 // Notify accessible layout. That's required at this place for
786 // frames only where the anchor is moved. Creation of new frames
787 // is additionally handled by the SwFrmNotify class.
788 if( GetUpper() &&
789 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
790 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
792 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
793 ->DisposeAccessibleFrm( pToRemove, sal_True );
796 //Collections noch nicht loeschen. Das passiert am Ende
797 //der Action im RemoveSuperfluous der Seite - angestossen von gleich-
798 //namiger Methode der Root.
799 //Die FlyColl kann bereits weg sein, weil der DTor der Seite
800 //gerade 'laeuft'
801 if ( pSortedObjs )
803 pSortedObjs->Remove( *pToRemove );
804 if ( !pSortedObjs->Count() )
805 { DELETEZ( pSortedObjs );
808 // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)>
809 pToRemove->SetPageFrm( 0L );
812 /*************************************************************************
814 |* SwPageFrm::MoveFly
816 |* Ersterstellung MA 25. Jan. 97
817 |* Letzte Aenderung MA 25. Jan. 97
819 |*************************************************************************/
821 void SwPageFrm::MoveFly( SwFlyFrm *pToMove, SwPageFrm *pDest )
823 //Invalidierungen
824 if ( GetUpper() )
826 ((SwRootFrm*)GetUpper())->SetIdleFlags();
827 if ( !pToMove->IsFlyInCntFrm() && pDest->GetPhyPageNum() < GetPhyPageNum() )
828 ((SwRootFrm*)GetUpper())->SetSuperfluous();
831 pDest->InvalidateSpelling();
832 pDest->InvalidateSmartTags(); // SMARTTAGS
833 pDest->InvalidateAutoCompleteWords();
834 pDest->InvalidateWordCount();
836 if ( pToMove->IsFlyInCntFrm() )
838 pDest->InvalidateFlyInCnt();
839 return;
842 // Notify accessible layout. That's required at this place for
843 // frames only where the anchor is moved. Creation of new frames
844 // is additionally handled by the SwFrmNotify class.
845 if( GetUpper() &&
846 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
847 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
849 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
850 ->DisposeAccessibleFrm( pToMove, sal_True );
853 //Die FlyColl kann bereits weg sein, weil der DTor der Seite
854 //gerade 'laeuft'
855 if ( pSortedObjs )
857 pSortedObjs->Remove( *pToMove );
858 if ( !pSortedObjs->Count() )
859 { DELETEZ( pSortedObjs );
863 //Anmelden
864 if ( !pDest->GetSortedObjs() )
865 pDest->pSortedObjs = new SwSortedObjs();
867 #if OSL_DEBUG_LEVEL > 1
868 const bool bSucessInserted =
869 #endif
870 pDest->GetSortedObjs()->Insert( *pToMove );
871 #if OSL_DEBUG_LEVEL > 1
872 ASSERT( bSucessInserted, "Fly nicht in Sorted eingetragen." )
873 (void) bSucessInserted;
874 #endif
876 // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)>
877 pToMove->SetPageFrm( pDest );
878 pToMove->InvalidatePage( pDest );
879 pToMove->SetNotifyBack();
880 pDest->InvalidateFlyCntnt();
881 // OD 2004-05-17 #i28701#
882 pToMove->UnlockPosition();
884 // Notify accessible layout. That's required at this place for
885 // frames only where the anchor is moved. Creation of new frames
886 // is additionally handled by the SwFrmNotify class.
887 if( GetUpper() &&
888 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
889 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
891 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
892 ->AddAccessibleFrm( pToMove );
895 // --> OD 2004-06-09 #i28701# - correction: move lowers of Writer fly frame
896 if ( pToMove->GetDrawObjs() )
898 SwSortedObjs &rObjs = *pToMove->GetDrawObjs();
899 for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
901 SwAnchoredObject* pObj = rObjs[i];
902 if ( pObj->ISA(SwFlyFrm) )
904 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
905 if ( pFly->IsFlyFreeFrm() )
907 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
908 SwPageFrm* pPageFrm = pFly->GetPageFrm();
909 if ( pPageFrm )
910 pPageFrm->MoveFly( pFly, pDest );
911 else
912 pDest->AppendFlyToPage( pFly );
915 else if ( pObj->ISA(SwAnchoredDrawObject) )
917 RemoveDrawObjFromPage( *pObj );
918 pDest->AppendDrawObjToPage( *pObj );
924 /*************************************************************************
926 |* SwPageFrm::AppendDrawObjToPage(), RemoveDrawObjFromPage()
928 |* --> OD 2004-07-02 #i28701# - new methods
930 |*************************************************************************/
931 void SwPageFrm::AppendDrawObjToPage( SwAnchoredObject& _rNewObj )
933 if ( !_rNewObj.ISA(SwAnchoredDrawObject) )
935 ASSERT( false,
936 "SwPageFrm::AppendDrawObjToPage(..) - anchored object of unexcepted type -> object not appended" );
937 return;
940 if ( GetUpper() )
942 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
945 ASSERT( _rNewObj.GetAnchorFrm(), "anchored draw object without anchor" );
946 const SwFlyFrm* pFlyFrm = _rNewObj.GetAnchorFrm()->FindFlyFrm();
947 if ( pFlyFrm &&
948 _rNewObj.GetDrawObj()->GetOrdNum() < pFlyFrm->GetVirtDrawObj()->GetOrdNum() )
950 UINT32 nNewNum = pFlyFrm->GetVirtDrawObj()->GetOrdNumDirect();
951 if ( _rNewObj.GetDrawObj()->GetPage() )
952 _rNewObj.DrawObj()->GetPage()->SetObjectOrdNum(
953 _rNewObj.GetDrawObj()->GetOrdNumDirect(), nNewNum);
954 else
955 _rNewObj.DrawObj()->SetOrdNum( nNewNum );
958 if ( FLY_IN_CNTNT == _rNewObj.GetFrmFmt().GetAnchor().GetAnchorId() )
960 return;
963 if ( !pSortedObjs )
965 pSortedObjs = new SwSortedObjs();
967 if ( !pSortedObjs->Insert( _rNewObj ) )
969 #ifndef PRODUCT
970 ASSERT( pSortedObjs->Contains( _rNewObj ),
971 "Drawing object not appended into list <pSortedObjs>." );
972 #endif
974 // --> OD 2008-04-22 #i87493#
975 ASSERT( _rNewObj.GetPageFrm() == 0 || _rNewObj.GetPageFrm() == this,
976 "<SwPageFrm::AppendDrawObjToPage(..)> - anchored draw object seems to be registered at another page frame. Serious defect -> please inform OD." );
977 // <--
978 _rNewObj.SetPageFrm( this );
980 // invalidate page in order to force a reformat of object layout of the page.
981 InvalidateFlyLayout();
984 void SwPageFrm::RemoveDrawObjFromPage( SwAnchoredObject& _rToRemoveObj )
986 if ( !_rToRemoveObj.ISA(SwAnchoredDrawObject) )
988 ASSERT( false,
989 "SwPageFrm::RemoveDrawObjFromPage(..) - anchored object of unexcepted type -> object not removed" );
990 return;
993 if ( pSortedObjs )
995 pSortedObjs->Remove( _rToRemoveObj );
996 if ( !pSortedObjs->Count() )
998 DELETEZ( pSortedObjs );
1000 if ( GetUpper() )
1002 if ( FLY_IN_CNTNT != _rToRemoveObj.GetFrmFmt().GetAnchor().GetAnchorId() )
1004 ((SwRootFrm*)GetUpper())->SetSuperfluous();
1005 InvalidatePage();
1007 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
1010 _rToRemoveObj.SetPageFrm( 0 );
1013 /*************************************************************************
1015 |* SwPageFrm::PlaceFly
1017 |* Ersterstellung MA 08. Feb. 93
1018 |* Letzte Aenderung MA 27. Feb. 93
1020 |*************************************************************************/
1022 // --> OD 2005-06-09 #i50432# - adjust method description and synopsis.
1023 void SwPageFrm::PlaceFly( SwFlyFrm* pFly, SwFlyFrmFmt* pFmt )
1025 // --> OD 2005-06-09 #i50432# - consider the case that page is an empty page:
1026 // In this case append the fly frame at the next page
1027 ASSERT( !IsEmptyPage() || GetNext(),
1028 "<SwPageFrm::PlaceFly(..)> - empty page with no next page! -> fly frame appended at empty page" );
1029 if ( IsEmptyPage() && GetNext() )
1031 static_cast<SwPageFrm*>(GetNext())->PlaceFly( pFly, pFmt );
1033 else
1035 //Wenn ein Fly uebergeben wurde, so benutzen wir diesen, ansonsten wird
1036 //mit dem Format einer erzeugt.
1037 if ( pFly )
1038 AppendFly( pFly );
1039 else
1040 { ASSERT( pFmt, ":-( kein Format fuer Fly uebergeben." );
1041 pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, this );
1042 AppendFly( pFly );
1043 ::RegistFlys( this, pFly );
1046 // <--
1049 /*************************************************************************
1051 |* ::CalcClipRect
1053 |* Ersterstellung AMA 24. Sep. 96
1054 |* Letzte Aenderung MA 18. Dec. 96
1056 |*************************************************************************/
1057 // OD 22.09.2003 #i18732# - adjustments for following text flow or not
1058 // AND alignment at 'page areas' for to paragraph/to character anchored objects
1059 // OD 06.11.2003 #i22305# - adjustment for following text flow
1060 // for to frame anchored objects
1061 // OD 2004-06-02 #i29778# - Because the calculation of the position of the
1062 // floating screen object (Writer fly frame or drawing object) doesn't perform
1063 // a calculation on its upper frames and its anchor frame, a calculation of
1064 // the upper frames in this method no longer sensible.
1065 // --> OD 2004-07-06 #i28701# - if document compatibility option 'Consider
1066 // wrapping style influence on object positioning' is ON, the clip area
1067 // corresponds to the one as the object doesn't follows the text flow.
1068 BOOL CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, BOOL bMove )
1070 BOOL bRet = TRUE;
1071 if ( pSdrObj->ISA(SwVirtFlyDrawObj) )
1073 const SwFlyFrm* pFly = ((const SwVirtFlyDrawObj*)pSdrObj)->GetFlyFrm();
1074 const bool bFollowTextFlow = pFly->GetFmt()->GetFollowTextFlow().GetValue();
1075 // --> OD 2004-07-06 #i28701#
1076 const bool bConsiderWrapOnObjPos =
1077 pFly->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION);
1078 // <--
1079 const SwFmtVertOrient &rV = pFly->GetFmt()->GetVertOrient();
1080 if( pFly->IsFlyLayFrm() )
1082 const SwFrm* pClip;
1083 // OD 06.11.2003 #i22305#
1084 // --> OD 2004-07-06 #i28701#
1085 if ( !bFollowTextFlow || bConsiderWrapOnObjPos )
1087 pClip = pFly->GetAnchorFrm()->FindPageFrm();
1089 else
1091 pClip = pFly->GetAnchorFrm();
1094 rRect = pClip->Frm();
1095 SWRECTFN( pClip )
1097 //Vertikales clipping: Top und Bottom, ggf. an PrtArea
1098 if( rV.GetVertOrient() != text::VertOrientation::NONE &&
1099 rV.GetRelationOrient() == text::RelOrientation::PRINT_AREA )
1101 (rRect.*fnRect->fnSetTop)( (pClip->*fnRect->fnGetPrtTop)() );
1102 (rRect.*fnRect->fnSetBottom)( (pClip->*fnRect->fnGetPrtBottom)() );
1104 //Horizontales clipping: Left und Right, ggf. an PrtArea
1105 const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient();
1106 if( rH.GetHoriOrient() != text::HoriOrientation::NONE &&
1107 rH.GetRelationOrient() == text::RelOrientation::PRINT_AREA )
1109 (rRect.*fnRect->fnSetLeft)( (pClip->*fnRect->fnGetPrtLeft)() );
1110 (rRect.*fnRect->fnSetRight)((pClip->*fnRect->fnGetPrtRight)());
1113 else if( pFly->IsFlyAtCntFrm() )
1115 // OD 22.09.2003 #i18732# - consider following text flow or not
1116 // AND alignment at 'page areas'
1117 const SwFrm* pVertPosOrientFrm = pFly->GetVertPosOrientFrm();
1118 if ( !pVertPosOrientFrm )
1120 ASSERT( false,
1121 "::CalcClipRect(..) - frame, vertical position is oriented at, is missing .");
1122 pVertPosOrientFrm = pFly->GetAnchorFrm();
1125 if ( !bFollowTextFlow || bConsiderWrapOnObjPos )
1127 const SwLayoutFrm* pClipFrm = pVertPosOrientFrm->FindPageFrm();
1128 rRect = bMove ? pClipFrm->GetUpper()->Frm()
1129 : pClipFrm->Frm();
1130 // --> OD 2004-10-14 #i26945# - consider that a table, during
1131 // its format, can exceed its upper printing area bottom.
1132 // Thus, enlarge the clip rectangle, if such a case occured
1133 if ( pFly->GetAnchorFrm()->IsInTab() )
1135 const SwTabFrm* pTabFrm = const_cast<SwFlyFrm*>(pFly)
1136 ->GetAnchorFrmContainingAnchPos()->FindTabFrm();
1137 SwRect aTmp( pTabFrm->Prt() );
1138 aTmp += pTabFrm->Frm().Pos();
1139 rRect.Union( aTmp );
1140 // --> OD 2005-03-30 #i43913# - consider also the cell frame
1141 const SwFrm* pCellFrm = const_cast<SwFlyFrm*>(pFly)
1142 ->GetAnchorFrmContainingAnchPos()->GetUpper();
1143 while ( pCellFrm && !pCellFrm->IsCellFrm() )
1145 pCellFrm = pCellFrm->GetUpper();
1147 if ( pCellFrm )
1149 aTmp = pCellFrm->Prt();
1150 aTmp += pCellFrm->Frm().Pos();
1151 rRect.Union( aTmp );
1153 // <--
1156 else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME ||
1157 rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )
1159 // OD 29.10.2003 #113049# - new class <SwEnvironmentOfAnchoredObject>
1160 objectpositioning::SwEnvironmentOfAnchoredObject
1161 aEnvOfObj( bFollowTextFlow );
1162 const SwLayoutFrm& rVertClipFrm =
1163 aEnvOfObj.GetVertEnvironmentLayoutFrm( *pVertPosOrientFrm );
1164 if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME )
1166 rRect = rVertClipFrm.Frm();
1168 else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )
1170 if ( rVertClipFrm.IsPageFrm() )
1172 rRect = static_cast<const SwPageFrm&>(rVertClipFrm).PrtWithoutHeaderAndFooter();
1174 else
1176 rRect = rVertClipFrm.Frm();
1179 const SwLayoutFrm* pHoriClipFrm =
1180 pFly->GetAnchorFrm()->FindPageFrm()->GetUpper();
1181 SWRECTFN( pFly->GetAnchorFrm() )
1182 (rRect.*fnRect->fnSetLeft)( (pHoriClipFrm->Frm().*fnRect->fnGetLeft)() );
1183 (rRect.*fnRect->fnSetRight)((pHoriClipFrm->Frm().*fnRect->fnGetRight)());
1185 else
1187 // --> OD 2004-10-11 #i26945#
1188 const SwFrm *pClip =
1189 const_cast<SwFlyFrm*>(pFly)->GetAnchorFrmContainingAnchPos();
1190 // <--
1191 SWRECTFN( pClip )
1192 const SwLayoutFrm *pUp = pClip->GetUpper();
1193 const SwFrm *pCell = pUp->IsCellFrm() ? pUp : 0;
1194 USHORT nType = bMove ? FRM_ROOT | FRM_FLY | FRM_HEADER |
1195 FRM_FOOTER | FRM_FTN
1196 : FRM_BODY | FRM_FLY | FRM_HEADER |
1197 FRM_FOOTER | FRM_CELL| FRM_FTN;
1199 while ( !(pUp->GetType() & nType) || pUp->IsColBodyFrm() )
1201 pUp = pUp->GetUpper();
1202 if ( !pCell && pUp->IsCellFrm() )
1203 pCell = pUp;
1205 if ( bMove )
1207 if ( pUp->IsRootFrm() )
1209 rRect = pUp->Prt();
1210 rRect += pUp->Frm().Pos();
1211 pUp = 0;
1214 if ( pUp )
1216 if ( pUp->GetType() & FRM_BODY )
1218 const SwPageFrm *pPg;
1219 if ( pUp->GetUpper() != (pPg = pFly->FindPageFrm()) )
1220 pUp = pPg->FindBodyCont();
1221 rRect = pUp->GetUpper()->Frm();
1222 (rRect.*fnRect->fnSetTop)( (pUp->*fnRect->fnGetPrtTop)() );
1223 (rRect.*fnRect->fnSetBottom)((pUp->*fnRect->fnGetPrtBottom)());
1225 else
1227 if( ( pUp->GetType() & (FRM_FLY | FRM_FTN ) ) &&
1228 !pUp->Frm().IsInside( pFly->Frm().Pos() ) )
1230 if( pUp->IsFlyFrm() )
1232 SwFlyFrm *pTmpFly = (SwFlyFrm*)pUp;
1233 while( pTmpFly->GetNextLink() )
1235 pTmpFly = pTmpFly->GetNextLink();
1236 if( pTmpFly->Frm().IsInside( pFly->Frm().Pos() ) )
1237 break;
1239 pUp = pTmpFly;
1241 else if( pUp->IsInFtn() )
1243 const SwFtnFrm *pTmp = pUp->FindFtnFrm();
1244 while( pTmp->GetFollow() )
1246 pTmp = pTmp->GetFollow();
1247 if( pTmp->Frm().IsInside( pFly->Frm().Pos() ) )
1248 break;
1250 pUp = pTmp;
1253 rRect = pUp->Prt();
1254 rRect.Pos() += pUp->Frm().Pos();
1255 if ( pUp->GetType() & (FRM_HEADER | FRM_FOOTER) )
1257 rRect.Left ( pUp->GetUpper()->Frm().Left() );
1258 rRect.Width( pUp->GetUpper()->Frm().Width());
1260 else if ( pUp->IsCellFrm() ) //MA_FLY_HEIGHT
1262 const SwFrm *pTab = pUp->FindTabFrm();
1263 (rRect.*fnRect->fnSetBottom)(
1264 (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() );
1265 // OD 08.08.2003 #110978# - expand to left and right
1266 // cell border
1267 rRect.Left ( pUp->Frm().Left() );
1268 rRect.Width( pUp->Frm().Width() );
1272 if ( pCell )
1274 //CellFrms koennen auch in 'unerlaubten' Bereichen stehen, dann
1275 //darf der Fly das auch.
1276 SwRect aTmp( pCell->Prt() );
1277 aTmp += pCell->Frm().Pos();
1278 rRect.Union( aTmp );
1282 else
1284 const SwFrm *pUp = pFly->GetAnchorFrm()->GetUpper();
1285 SWRECTFN( pFly->GetAnchorFrm() )
1286 while( pUp->IsColumnFrm() || pUp->IsSctFrm() || pUp->IsColBodyFrm())
1287 pUp = pUp->GetUpper();
1288 rRect = pUp->Frm();
1289 if( !pUp->IsBodyFrm() )
1291 rRect += pUp->Prt().Pos();
1292 rRect.SSize( pUp->Prt().SSize() );
1293 if ( pUp->IsCellFrm() )
1295 const SwFrm *pTab = pUp->FindTabFrm();
1296 (rRect.*fnRect->fnSetBottom)(
1297 (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() );
1300 else if ( pUp->GetUpper()->IsPageFrm() )
1302 // #111909# Objects anchored as character may exceed right margin
1303 // of body frame:
1304 (rRect.*fnRect->fnSetRight)( (pUp->GetUpper()->Frm().*fnRect->fnGetRight)() );
1306 long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10;
1307 long nTop;
1308 const SwFmt *pFmt = ((SwContact*)GetUserCall(pSdrObj))->GetFmt();
1309 const SvxULSpaceItem &rUL = pFmt->GetULSpace();
1310 if( bMove )
1312 nTop = bVert ? ((SwFlyInCntFrm*)pFly)->GetRefPoint().X() :
1313 ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y();
1314 nTop = (*fnRect->fnYInc)( nTop, -nHeight );
1315 long nWidth = (pFly->Frm().*fnRect->fnGetWidth)();
1316 (rRect.*fnRect->fnSetLeftAndWidth)( bVert ?
1317 ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y() :
1318 ((SwFlyInCntFrm*)pFly)->GetRefPoint().X(), nWidth );
1319 nHeight = 2*nHeight - rUL.GetLower() - rUL.GetUpper();
1321 else
1323 nTop = (*fnRect->fnYInc)( (pFly->Frm().*fnRect->fnGetBottom)(),
1324 rUL.GetLower() - nHeight );
1325 nHeight = 2*nHeight - (pFly->Frm().*fnRect->fnGetHeight)()
1326 - rUL.GetLower() - rUL.GetUpper();
1328 (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight );
1331 else
1333 const SwDrawContact *pC = (const SwDrawContact*)GetUserCall(pSdrObj);
1334 const SwFrmFmt *pFmt = (const SwFrmFmt*)pC->GetFmt();
1335 const SwFmtAnchor &rAnch = pFmt->GetAnchor();
1336 if ( FLY_IN_CNTNT == rAnch.GetAnchorId() )
1338 const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj );
1339 if( !pAnchorFrm )
1341 ASSERT( false, "<::CalcClipRect(..)> - missing anchor frame." );
1342 ((SwDrawContact*)pC)->ConnectToLayout();
1343 pAnchorFrm = pC->GetAnchorFrm();
1345 const SwFrm* pUp = pAnchorFrm->GetUpper();
1346 rRect = pUp->Prt();
1347 rRect += pUp->Frm().Pos();
1348 SWRECTFN( pAnchorFrm )
1349 long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10;
1350 long nTop;
1351 const SvxULSpaceItem &rUL = pFmt->GetULSpace();
1352 SwRect aSnapRect( pSdrObj->GetSnapRect() );
1353 long nTmpH = 0;
1354 if( bMove )
1356 nTop = (*fnRect->fnYInc)( bVert ? pSdrObj->GetAnchorPos().X() :
1357 pSdrObj->GetAnchorPos().Y(), -nHeight );
1358 long nWidth = (aSnapRect.*fnRect->fnGetWidth)();
1359 (rRect.*fnRect->fnSetLeftAndWidth)( bVert ?
1360 pSdrObj->GetAnchorPos().Y() :
1361 pSdrObj->GetAnchorPos().X(), nWidth );
1363 else
1365 // OD 2004-04-13 #i26791# - value of <nTmpH> is needed to
1366 // calculate value of <nTop>.
1367 nTmpH = bVert ? pSdrObj->GetCurrentBoundRect().GetWidth() :
1368 pSdrObj->GetCurrentBoundRect().GetHeight();
1369 nTop = (*fnRect->fnYInc)( (aSnapRect.*fnRect->fnGetTop)(),
1370 rUL.GetLower() + nTmpH - nHeight );
1372 nHeight = 2*nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper();
1373 (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight );
1375 else
1377 // OD 23.06.2003 #108784# - restrict clip rectangle for drawing
1378 // objects in header/footer to the page frame.
1379 // OD 2004-03-29 #i26791#
1380 const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj );
1381 if ( pAnchorFrm && pAnchorFrm->FindFooterOrHeader() )
1383 // clip frame is the page frame the header/footer is on.
1384 const SwFrm* pClipFrm = pAnchorFrm->FindPageFrm();
1385 rRect = pClipFrm->Frm();
1387 else
1389 bRet = FALSE;
1393 return bRet;