1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_sw.hxx"
24 #include "doc.hxx"
25 #include "pagefrm.hxx"
26 #include "rootfrm.hxx"
27 #include "cntfrm.hxx"
28 #include "dview.hxx"
29 #include "dflyobj.hxx"
30 #include "dcontact.hxx"
31 #include "flyfrm.hxx"
32 #include "ftnfrm.hxx"
33 #include "frmtool.hxx"
34 #include "frmfmt.hxx"
35 #include "errhdl.hxx"
36 #include "hints.hxx"
37 #include "pam.hxx"
38 #include "sectfrm.hxx"
39
40 #include <svx/svdpage.hxx>
41 #include <editeng/ulspitem.hxx>
42 #include <fmtanchr.hxx>
43 #include <fmtornt.hxx>
44 #include <fmtfsize.hxx>
45 #include "ndole.hxx"
46 #include "tabfrm.hxx"
47 #include "flyfrms.hxx"
48 // OD 22.09.2003 #i18732#
49 #include <fmtfollowtextflow.hxx>
50 // OD 29.10.2003 #113049#
51 #include <environmentofanchoredobject.hxx>
52 // OD 2004-05-24 #i28701#
53 #include <sortedobjs.hxx>
54 #include <viewsh.hxx>
55 #include <viewimp.hxx>
56
57 using namespace ::com::sun::star;
58
59 /*************************************************************************
60 |* SwFlyFreeFrm::SwFlyFreeFrm(), ~SwFlyFreeFrm()
61 |*
62 |* Ersterstellung MA 03. Dec. 92
63 |* Letzte Änderung MA 09. Apr. 99
64 |*************************************************************************/
65
SwFlyFreeFrm(SwFlyFrmFmt * pFmt,SwFrm * pSib,SwFrm * pAnch)66 SwFlyFreeFrm::SwFlyFreeFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) :
67 SwFlyFrm( pFmt, pSib, pAnch ),
68 pPage( 0 ),
69 // --> OD 2004-11-15 #i34753#
70 mbNoMakePos( false ),
71 // <--
72 // --> OD 2004-11-12 #i37068#
73 mbNoMoveOnCheckClip( false )
74 // <--
75 {
76 }
77
~SwFlyFreeFrm()78 SwFlyFreeFrm::~SwFlyFreeFrm()
79 {
80 // und Tschüss.
81 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
82 if( GetPageFrm() )
83 {
84 if( GetFmt()->GetDoc()->IsInDtor() )
85 {
86 // --> OD 2004-06-04 #i29879# - remove also to-frame anchored Writer
87 // fly frame from page.
88 const bool bRemoveFromPage =
89 GetPageFrm()->GetSortedObjs() &&
90 ( IsFlyAtCntFrm() ||
91 ( GetAnchorFrm() && GetAnchorFrm()->IsFlyFrm() ) );
92 if ( bRemoveFromPage )
93 {
94 GetPageFrm()->GetSortedObjs()->Remove( *this );
95 }
96 }
97 else
98 {
99 SwRect aTmp( GetObjRectWithSpaces() );
100 SwFlyFreeFrm::NotifyBackground( GetPageFrm(), aTmp, PREP_FLY_LEAVE );
101 }
102 }
103 }
104
105 // --> OD 2004-06-29 #i28701#
106 TYPEINIT1(SwFlyFreeFrm,SwFlyFrm);
107 // <--
108 /*************************************************************************
109 |* SwFlyFreeFrm::NotifyBackground()
110 |*
111 |* Beschreibung Benachrichtigt den Hintergrund (alle CntntFrms die
112 |* gerade überlappt werden. Ausserdem wird das Window in einigen
113 |* Fällen direkt invalidiert (vor allem dort, wo keine CntntFrms
114 |* überlappt werden.
115 |* Es werden auch die CntntFrms innerhalb von anderen Flys
116 |* berücksichtigt.
117 |* Ersterstellung MA 03. Dec. 92
118 |* Letzte Änderung MA 26. Aug. 93
119 |*************************************************************************/
120
NotifyBackground(SwPageFrm * pPageFrm,const SwRect & rRect,PrepareHint eHint)121 void SwFlyFreeFrm::NotifyBackground( SwPageFrm *pPageFrm,
122 const SwRect& rRect, PrepareHint eHint )
123 {
124 ::Notify_Background( GetVirtDrawObj(), pPageFrm, rRect, eHint, sal_True );
125 }
126
127 /*************************************************************************
128 |* SwFlyFreeFrm::MakeAll()
129 |*
130 |* Ersterstellung MA 18. Feb. 94
131 |* Letzte Änderung MA 03. Mar. 97
132 |*************************************************************************/
133
MakeAll()134 void SwFlyFreeFrm::MakeAll()
135 {
136 // OD 2004-01-19 #110582#
137 if ( !GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
138 {
139 return;
140 }
141
142 if ( !GetAnchorFrm() || IsLocked() || IsColLocked() )
143 return;
144 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
145 if( !GetPageFrm() && GetAnchorFrm() && GetAnchorFrm()->IsInFly() )
146 {
147 SwFlyFrm* pFly = AnchorFrm()->FindFlyFrm();
148 SwPageFrm *pPageFrm = pFly ? pFly->FindPageFrm() : NULL;
149 if( pPageFrm )
150 pPageFrm->AppendFlyToPage( this );
151 }
152 if( !GetPageFrm() )
153 return;
154
155 Lock(); // Der Vorhang fällt
156
157 // übernimmt im DTor die Benachrichtigung
158 const SwFlyNotify aNotify( this );
159
160 if ( IsClipped() )
161 {
162 bValidSize = bHeightClipped = bWidthClipped = sal_False;
163 // --> OD 2004-11-03 #114798# - no invalidation of position,
164 // if anchored object is anchored inside a Writer fly frame,
165 // its position is already locked, and it follows the text flow.
166 // --> OD 2004-11-15 #i34753# - add condition:
167 // no invalidation of position, if no direct move is requested in <CheckClip(..)>
168 if ( !IsNoMoveOnCheckClip() &&
169 !( PositionLocked() &&
170 GetAnchorFrm()->IsInFly() &&
171 GetFrmFmt().GetFollowTextFlow().GetValue() ) )
172 // <--
173 {
174 bValidPos = sal_False;
175 }
176 // <--
177 }
178
179 // FME 2007-08-30 #i81146# new loop control
180 sal_uInt16 nLoopControlRuns = 0;
181 const sal_uInt16 nLoopControlMax = 10;
182
183 while ( !bValidPos || !bValidSize || !bValidPrtArea || bFormatHeightOnly )
184 {
185 SWRECTFN( this )
186 const SwFmtFrmSize *pSz;
187 { // Zusätzlicher Scope, damit aAccess vor dem Check zerstört wird!
188
189 SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
190 const SwBorderAttrs &rAttrs = *aAccess.Get();
191 pSz = &rAttrs.GetAttrSet().GetFrmSize();
192
193 //Nur einstellen wenn das Flag gesetzt ist!!
194 if ( !bValidSize )
195 {
196 bValidPrtArea = sal_False;
197 /*
198 // This is also done in the Format function, so I think
199 // this code is not necessary anymore:
200 const Size aRelSize( CalcRel( *pSz ) );
201 const SwTwips nMin = MINFLY + rAttrs.CalcLeftLine()+rAttrs.CalcRightLine();
202 long nDiff = bVert ? aRelSize.Height() : aRelSize.Width();
203 if( nDiff < nMin )
204 nDiff = nMin;
205 nDiff -= (aFrm.*fnRect->fnGetWidth)();
206 if( nDiff )
207 {
208 (aFrm.*fnRect->fnAddRight)( nDiff );
209 bValidPos = sal_False;
210 }
211 */
212 }
213
214 if ( !bValidPrtArea )
215 MakePrtArea( rAttrs );
216
217 if ( !bValidSize || bFormatHeightOnly )
218 {
219 bValidSize = sal_False;
220 Format( &rAttrs );
221 bFormatHeightOnly = sal_False;
222 }
223
224 if ( !bValidPos )
225 {
226 const Point aOldPos( (Frm().*fnRect->fnGetPos)() );
227 // OD 2004-03-23 #i26791# - use new method <MakeObjPos()>
228 // --> OD 2004-11-15 #i34753# - no positioning, if requested.
229 if ( IsNoMakePos() )
230 bValidPos = sal_True;
231 else
232 // OD 2004-03-23 #i26791# - use new method <MakeObjPos()>
233 MakeObjPos();
234 // <--
235 if( aOldPos == (Frm().*fnRect->fnGetPos)() )
236 {
237 if( !bValidPos && GetAnchorFrm()->IsInSct() &&
238 !GetAnchorFrm()->FindSctFrm()->IsValid() )
239 bValidPos = sal_True;
240 }
241 else
242 bValidSize = sal_False;
243 }
244 }
245
246 if ( bValidPos && bValidSize )
247 {
248 ++nLoopControlRuns;
249
250 #if OSL_DEBUG_LEVEL > 1
251 ASSERT( nLoopControlRuns < nLoopControlMax, "LoopControl in SwFlyFreeFrm::MakeAll" )
252 #endif
253
254 if ( nLoopControlRuns < nLoopControlMax )
255 CheckClip( *pSz );
256 }
257 else
258 nLoopControlRuns = 0;
259 }
260 Unlock();
261
262 #ifdef DBG_UTIL
263 SWRECTFN( this )
264 ASSERT( bHeightClipped || ( (Frm().*fnRect->fnGetHeight)() > 0 &&
265 (Prt().*fnRect->fnGetHeight)() > 0),
266 "SwFlyFreeFrm::Format(), flipping Fly." );
267
268 #endif
269 }
270
271 /** determines, if direct environment of fly frame has 'auto' size
272
273 OD 07.08.2003 #i17297#, #111066#, #111070#
274 start with anchor frame and search via <GetUpper()> for a header, footer,
275 row or fly frame stopping at page frame.
276 return <true>, if such a frame is found and it has 'auto' size.
277 otherwise <false> is returned.
278
279 @author OD
280
281 @return boolean indicating, that direct environment has 'auto' size
282 */
HasEnvironmentAutoSize() const283 bool SwFlyFreeFrm::HasEnvironmentAutoSize() const
284 {
285 bool bRetVal = false;
286
287 const SwFrm* pToBeCheckedFrm = GetAnchorFrm();
288 while ( pToBeCheckedFrm &&
289 !pToBeCheckedFrm->IsPageFrm() )
290 {
291 if ( pToBeCheckedFrm->IsHeaderFrm() ||
292 pToBeCheckedFrm->IsFooterFrm() ||
293 pToBeCheckedFrm->IsRowFrm() ||
294 pToBeCheckedFrm->IsFlyFrm() )
295 {
296 bRetVal = ATT_FIX_SIZE !=
297 pToBeCheckedFrm->GetAttrSet()->GetFrmSize().GetHeightSizeType();
298 break;
299 }
300 else
301 {
302 pToBeCheckedFrm = pToBeCheckedFrm->GetUpper();
303 }
304 }
305
306 return bRetVal;
307 }
308
309 /*************************************************************************
310 |* SwFlyFreeFrm::CheckClip()
311 |*
312 |* Ersterstellung MA 21. Feb. 94
313 |* Letzte Änderung MA 03. Mar. 97
314 |*************************************************************************/
315
CheckClip(const SwFmtFrmSize & rSz)316 void SwFlyFreeFrm::CheckClip( const SwFmtFrmSize &rSz )
317 {
318 // Jetzt ist es ggf. an der Zeit geeignete Massnahmen zu ergreifen wenn
319 // der Fly nicht in seine Umgebung passt.
320 // Zuerst gibt der Fly seine Position auf. Danach wird er zunächst
321 // formatiert. Erst wenn er auch durch die Aufgabe der Position nicht
322 // passt wird die Breite oder Höhe aufgegeben - der Rahmen wird soweit
323 // wie notwendig zusammengequetscht.
324
325 const SwVirtFlyDrawObj *pObj = GetVirtDrawObj();
326 SwRect aClip, aTmpStretch;
327 ::CalcClipRect( pObj, aClip, sal_True );
328 ::CalcClipRect( pObj, aTmpStretch, sal_False );
329 aClip._Intersection( aTmpStretch );
330
331 const long nBot = Frm().Top() + Frm().Height();
332 const long nRig = Frm().Left() + Frm().Width();
333 const long nClipBot = aClip.Top() + aClip.Height();
334 const long nClipRig = aClip.Left() + aClip.Width();
335
336 const sal_Bool bBot = nBot > nClipBot;
337 const sal_Bool bRig = nRig > nClipRig;
338 if ( bBot || bRig )
339 {
340 sal_Bool bAgain = sal_False;
341 // --> OD 2004-11-12 #i37068# - no move, if it's requested
342 if ( bBot && !IsNoMoveOnCheckClip() &&
343 !GetDrawObjs() && !GetAnchorFrm()->IsInTab() )
344 // <--
345 {
346 SwFrm* pHeader = FindFooterOrHeader();
347 // In a header, correction of the position is no good idea.
348 // If the fly moves, some paragraphs has to be formatted, this
349 // could cause a change of the height of the headerframe,
350 // now the flyframe can change its position and so on ...
351 if ( !pHeader || !pHeader->IsHeaderFrm() )
352 {
353 const long nOld = Frm().Top();
354 Frm().Pos().Y() = Max( aClip.Top(), nClipBot - Frm().Height() );
355 if ( Frm().Top() != nOld )
356 bAgain = sal_True;
357 bHeightClipped = sal_True;
358 }
359 }
360 if ( bRig )
361 {
362 const long nOld = Frm().Left();
363 Frm().Pos().X() = Max( aClip.Left(), nClipRig - Frm().Width() );
364 if ( Frm().Left() != nOld )
365 {
366 const SwFmtHoriOrient &rH = GetFmt()->GetHoriOrient();
367 // Links ausgerichtete dürfen nicht nach links verschoben werden,
368 // wenn sie einem anderen ausweichen.
369 if( rH.GetHoriOrient() == text::HoriOrientation::LEFT )
370 Frm().Pos().X() = nOld;
371 else
372 bAgain = sal_True;
373 }
374 bWidthClipped = sal_True;
375 }
376 if ( bAgain )
377 bValidSize = sal_False;
378 else
379 {
380 // Wenn wir hier ankommen ragt der Frm in unerlaubte Bereiche
381 // hinein, und eine Positionskorrektur ist nicht erlaubt bzw.
382 // möglich oder nötig.
383
384 // Für Flys mit OLE-Objekten als Lower sorgen wir dafür, dass
385 // immer proportional Resized wird.
386 Size aOldSize( Frm().SSize() );
387
388 // Zuerst wird das FrmRect eingestellt, und dann auf den Frm
389 // übertragen.
390 SwRect aFrmRect( Frm() );
391
392 if ( bBot )
393 {
394 long nDiff = nClipBot;
395 nDiff -= aFrmRect.Top(); //nDiff ist die verfügbare Strecke.
396 nDiff = aFrmRect.Height() - nDiff;
397 aFrmRect.Height( aFrmRect.Height() - nDiff );
398 bHeightClipped = sal_True;
399 }
400 if ( bRig )
401 {
402 long nDiff = nClipRig;
403 nDiff -= aFrmRect.Left();//nDiff ist die verfügbare Strecke.
404 nDiff = aFrmRect.Width() - nDiff;
405 aFrmRect.Width( aFrmRect.Width() - nDiff );
406 bWidthClipped = sal_True;
407 }
408
409 // OD 06.08.2003 #i17297#, #111066#, #111070# - no proportional
410 // scaling of graphics in environments, which determines its size
411 // by its content ('auto' size). Otherwise layout loops can occur and
412 // layout sizes of the environment can be incorrect.
413 // Such environment are:
414 // (1) header and footer frames with 'auto' size
415 // (2) table row frames with 'auto' size
416 // (3) fly frames with 'auto' size
417 // Note: section frames seems to be not critical - didn't find
418 // any critical layout situation so far.
419 if ( Lower() && Lower()->IsNoTxtFrm() &&
420 ( static_cast<SwCntntFrm*>(Lower())->GetNode()->GetOLENode() ||
421 !HasEnvironmentAutoSize() ) )
422 {
423 // Wenn Breite und Höhe angepasst wurden, so ist die
424 // grössere Veränderung massgeblich.
425 if ( aFrmRect.Width() != aOldSize.Width() &&
426 aFrmRect.Height()!= aOldSize.Height() )
427 {
428 if ( (aOldSize.Width() - aFrmRect.Width()) >
429 (aOldSize.Height()- aFrmRect.Height()) )
430 aFrmRect.Height( aOldSize.Height() );
431 else
432 aFrmRect.Width( aOldSize.Width() );
433 }
434
435 // Breite angepasst? - Höhe dann proportional verkleinern
436 if( aFrmRect.Width() != aOldSize.Width() )
437 {
438 aFrmRect.Height( aFrmRect.Width() * aOldSize.Height() /
439 aOldSize.Width() );
440 bHeightClipped = sal_True;
441 }
442 // Höhe angepasst? - Breite dann proportional verkleinern
443 else if( aFrmRect.Height() != aOldSize.Height() )
444 {
445 aFrmRect.Width( aFrmRect.Height() * aOldSize.Width() /
446 aOldSize.Height() );
447 bWidthClipped = sal_True;
448 }
449
450 // OD 07.08.2003 #i17297#, #111066#, #111070# - reactivate change
451 // of size attribute for fly frames containing an ole object.
452 // FME: 2004-05-19 Added the aFrmRect.HasArea() hack, because
453 // the environment of the ole object does not have to be valid
454 // at this moment, or even worse, it does not have to have a
455 // reasonable size. In this case we do not want to change to
456 // attributes permanently. Maybe one day somebody dares to remove
457 // this code.
458 if ( aFrmRect.HasArea() &&
459 static_cast<SwCntntFrm*>(Lower())->GetNode()->GetOLENode() &&
460 ( bWidthClipped || bHeightClipped ) )
461 {
462 SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
463 pFmt->LockModify();
464 SwFmtFrmSize aFrmSize( rSz );
465 aFrmSize.SetWidth( aFrmRect.Width() );
466 aFrmSize.SetHeight( aFrmRect.Height() );
467 pFmt->SetFmtAttr( aFrmSize );
468 pFmt->UnlockModify();
469 }
470 }
471
472 // Jetzt die Einstellungen am Frm vornehmen, bei Spalten werden
473 // die neuen Werte in die Attribute eingetragen, weil es sonst
474 // ziemlich fiese Oszillationen gibt.
475 const long nPrtHeightDiff = Frm().Height() - Prt().Height();
476 const long nPrtWidthDiff = Frm().Width() - Prt().Width();
477 Frm().Height( aFrmRect.Height() );
478 Frm().Width ( Max( long(MINLAY), aFrmRect.Width() ) );
479 if ( Lower() && Lower()->IsColumnFrm() )
480 {
481 ColLock(); // Grow/Shrink locken.
482 const Size aTmpOldSize( Prt().SSize() );
483 Prt().Height( Frm().Height() - nPrtHeightDiff );
484 Prt().Width ( Frm().Width() - nPrtWidthDiff );
485 ChgLowersProp( aTmpOldSize );
486 SwFrm *pLow = Lower();
487 do
488 { pLow->Calc();
489 // auch den (Column)BodyFrm mitkalkulieren
490 ((SwLayoutFrm*)pLow)->Lower()->Calc();
491 pLow = pLow->GetNext();
492 } while ( pLow );
493 ::CalcCntnt( this );
494 ColUnlock();
495 if ( !bValidSize && !bWidthClipped )
496 bFormatHeightOnly = bValidSize = sal_True;
497 }
498 else
499 {
500 Prt().Height( Frm().Height() - nPrtHeightDiff );
501 Prt().Width ( Frm().Width() - nPrtWidthDiff );
502 }
503 }
504 }
505
506 // --> OD 2004-10-14 #i26945#
507 ASSERT( Frm().Height() >= 0,
508 "<SwFlyFreeFrm::CheckClip(..)> - fly frame has negative height now." );
509 // <--
510 }
511
512 /** method to determine, if a <MakeAll()> on the Writer fly frame is possible
513
514 OD 2005-03-03 #i43771#
515
516 @author OD
517 */
IsFormatPossible() const518 bool SwFlyFreeFrm::IsFormatPossible() const
519 {
520 return SwFlyFrm::IsFormatPossible() &&
521 ( GetPageFrm() ||
522 ( GetAnchorFrm() && GetAnchorFrm()->IsInFly() ) );
523 }
524
525 /*************************************************************************
526 |* SwFlyLayFrm::SwFlyLayFrm()
527 |*
528 |* Ersterstellung MA 25. Aug. 92
529 |* Letzte Änderung MA 09. Apr. 99
530 |*************************************************************************/
531
SwFlyLayFrm(SwFlyFrmFmt * pFmt,SwFrm * pSib,SwFrm * pAnch)532 SwFlyLayFrm::SwFlyLayFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) :
533 SwFlyFreeFrm( pFmt, pSib, pAnch )
534 {
535 bLayout = sal_True;
536 }
537
538 // --> OD 2004-06-29 #i28701#
539 TYPEINIT1(SwFlyLayFrm,SwFlyFreeFrm);
540 // <--
541 /*************************************************************************
542 |* SwFlyLayFrm::Modify()
543 |*
544 |* Ersterstellung MA 08. Feb. 93
545 |* Letzte Änderung MA 28. Aug. 93
546 |*************************************************************************/
547
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)548 void SwFlyLayFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
549 {
550 sal_uInt16 nWhich = pNew ? pNew->Which() : 0;
551
552 SwFmtAnchor *pAnch = 0;
553 if( RES_ATTRSET_CHG == nWhich && SFX_ITEM_SET ==
554 ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_ANCHOR, sal_False,
555 (const SfxPoolItem**)&pAnch ))
556 ; // Beim GetItemState wird der AnkerPointer gesetzt !
557
558 else if( RES_ANCHOR == nWhich )
559 {
560 // Ankerwechsel, ich hänge mich selbst um.
561 // Es darf sich nicht um einen Wechsel des Ankertyps handeln,
562 // dies ist nur über die SwFEShell möglich.
563 pAnch = (SwFmtAnchor*)pNew;
564 }
565
566 if( pAnch )
567 {
568 ASSERT( pAnch->GetAnchorId() ==
569 GetFmt()->GetAnchor().GetAnchorId(),
570 "8-) Unzulässiger Wechsel des Ankertyps." );
571
572 // Abmelden, Seite besorgen, an den entsprechenden LayoutFrm
573 // hängen.
574 SwRect aOld( GetObjRectWithSpaces() );
575 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
576 SwPageFrm *pOldPage = GetPageFrm();
577 AnchorFrm()->RemoveFly( this );
578
579 if ( FLY_AT_PAGE == pAnch->GetAnchorId() )
580 {
581 sal_uInt16 nPgNum = pAnch->GetPageNum();
582 SwRootFrm *pRoot = getRootFrm();
583 SwPageFrm *pTmpPage = (SwPageFrm*)pRoot->Lower();
584 for ( sal_uInt16 i = 1; (i <= nPgNum) && pTmpPage; ++i,
585 pTmpPage = (SwPageFrm*)pTmpPage->GetNext() )
586 {
587 if ( i == nPgNum )
588 {
589 // --> OD 2005-06-09 #i50432# - adjust synopsis of <PlaceFly(..)>
590 pTmpPage->PlaceFly( this, 0 );
591 // <--
592 }
593 }
594 if( !pTmpPage )
595 {
596 pRoot->SetAssertFlyPages();
597 pRoot->AssertFlyPages();
598 }
599 }
600 else
601 {
602 SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode );
603 SwCntntFrm *pCntnt = GetFmt()->GetDoc()->GetNodes().GoNext( &aIdx )->
604 GetCntntNode()->getLayoutFrm( getRootFrm(), 0, 0, sal_False );
605 if( pCntnt )
606 {
607 SwFlyFrm *pTmp = pCntnt->FindFlyFrm();
608 if( pTmp )
609 pTmp->AppendFly( this );
610 }
611 }
612 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
613 if ( pOldPage && pOldPage != GetPageFrm() )
614 NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE );
615 SetCompletePaint();
616 InvalidateAll();
617 SetNotifyBack();
618 }
619 else
620 SwFlyFrm::Modify( pOld, pNew );
621 }
622
623 /*************************************************************************
624 |* SwPageFrm::AppendFly()
625 |*
626 |* Ersterstellung MA 10. Oct. 92
627 |* Letzte Änderung MA 08. Jun. 96
628 |*************************************************************************/
629
AppendFlyToPage(SwFlyFrm * pNew)630 void SwPageFrm::AppendFlyToPage( SwFlyFrm *pNew )
631 {
632 if ( !pNew->GetVirtDrawObj()->IsInserted() )
633 getRootFrm()->GetDrawPage()->InsertObject(
634 (SdrObject*)pNew->GetVirtDrawObj(),
635 pNew->GetVirtDrawObj()->GetReferencedObj().GetOrdNumDirect() );
636
637 InvalidateSpelling();
638 InvalidateSmartTags(); // SMARTTAGS
639 InvalidateAutoCompleteWords();
640 InvalidateWordCount();
641
642 if ( GetUpper() )
643 {
644 ((SwRootFrm*)GetUpper())->SetIdleFlags();
645 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
646 }
647
648 SdrObject* pObj = pNew->GetVirtDrawObj();
649 ASSERT( pNew->GetAnchorFrm(), "Fly without Anchor" );
650 SwFlyFrm* pFly = (SwFlyFrm*)pNew->GetAnchorFrm()->FindFlyFrm();
651 if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() )
652 {
653 //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed.
654 sal_uInt32 nNewNum = pObj->GetOrdNumDirect();
655 if ( pObj->GetPage() )
656 pObj->GetPage()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum );
657 else
658 pFly->GetVirtDrawObj()->SetOrdNum( nNewNum );
659 }
660
661 //Flys die im Cntnt sitzen beachten wir nicht weiter.
662 if ( pNew->IsFlyInCntFrm() )
663 InvalidateFlyInCnt();
664 else
665 {
666 InvalidateFlyCntnt();
667
668 if ( !pSortedObjs )
669 pSortedObjs = new SwSortedObjs();
670
671 #if OSL_DEBUG_LEVEL > 1
672 const bool bSucessInserted =
673 #endif
674 pSortedObjs->Insert( *pNew );
675 #if OSL_DEBUG_LEVEL > 1
676 ASSERT( bSucessInserted, "Fly nicht in Sorted eingetragen." )
677 (void) bSucessInserted;
678 #endif
679
680 // --> OD 2008-04-22 #i87493#
681 ASSERT( pNew->GetPageFrm() == 0 || pNew->GetPageFrm() == this,
682 "<SwPageFrm::AppendFlyToPage(..)> - anchored fly frame seems to be registered at another page frame. Serious defect -> please inform OD." );
683 // <--
684 // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)>
685 pNew->SetPageFrm( this );
686 pNew->InvalidatePage( this );
687 // OD 2004-05-17 #i28701#
688 pNew->UnlockPosition();
689
690 // Notify accessible layout. That's required at this place for
691 // frames only where the anchor is moved. Creation of new frames
692 // is additionally handled by the SwFrmNotify class.
693 if( GetUpper() &&
694 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
695 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
696 {
697 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
698 ->AddAccessibleFrm( pNew );
699 }
700 }
701
702 // --> OD 2004-06-09 #i28701# - correction: consider also drawing objects
703 if ( pNew->GetDrawObjs() )
704 {
705 SwSortedObjs &rObjs = *pNew->GetDrawObjs();
706 for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
707 {
708 SwAnchoredObject* pTmpObj = rObjs[i];
709 if ( pTmpObj->ISA(SwFlyFrm) )
710 {
711 SwFlyFrm* pTmpFly = static_cast<SwFlyFrm*>(pTmpObj);
712 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
713 if ( pTmpFly->IsFlyFreeFrm() && !pTmpFly->GetPageFrm() )
714 AppendFlyToPage( pTmpFly );
715 }
716 else if ( pTmpObj->ISA(SwAnchoredDrawObject) )
717 {
718 // --> OD 2008-04-22 #i87493#
719 // AppendDrawObjToPage( *pTmpObj );
720 if ( pTmpObj->GetPageFrm() != this )
721 {
722 if ( pTmpObj->GetPageFrm() != 0 )
723 {
724 pTmpObj->GetPageFrm()->RemoveDrawObjFromPage( *pTmpObj );
725 }
726 AppendDrawObjToPage( *pTmpObj );
727 }
728 // <--
729 }
730 }
731 }
732 }
733
734 /*************************************************************************
735 |* SwPageFrm::RemoveFly()
736 |*
737 |* Ersterstellung MA 10. Oct. 92
738 |* Letzte Änderung MA 26. Aug. 96
739 |*************************************************************************/
740
RemoveFlyFromPage(SwFlyFrm * pToRemove)741 void SwPageFrm::RemoveFlyFromPage( SwFlyFrm *pToRemove )
742 {
743 const sal_uInt32 nOrdNum = pToRemove->GetVirtDrawObj()->GetOrdNum();
744 getRootFrm()->GetDrawPage()->RemoveObject( nOrdNum );
745 pToRemove->GetVirtDrawObj()->ReferencedObj().SetOrdNum( nOrdNum );
746
747 if ( GetUpper() )
748 {
749 if ( !pToRemove->IsFlyInCntFrm() )
750 ((SwRootFrm*)GetUpper())->SetSuperfluous();
751 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
752 }
753
754 // Flys die im Cntnt sitzen beachten wir nicht weiter.
755 if ( pToRemove->IsFlyInCntFrm() )
756 return;
757
758 // Notify accessible layout. That's required at this place for
759 // frames only where the anchor is moved. Creation of new frames
760 // is additionally handled by the SwFrmNotify class.
761 if( GetUpper() &&
762 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
763 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
764 {
765 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
766 ->DisposeAccessibleFrm( pToRemove, sal_True );
767 }
768
769 // Collections noch nicht löschen. Das passiert am Ende
770 // der Action im RemoveSuperfluous der Seite - angestossen von gleich-
771 // namiger Methode der Root.
772 // Die FlyColl kann bereits weg sein, weil der DTor der Seite
773 // gerade 'läuft'
774 if ( pSortedObjs )
775 {
776 pSortedObjs->Remove( *pToRemove );
777 if ( !pSortedObjs->Count() )
778 { DELETEZ( pSortedObjs );
779 }
780 }
781 // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)>
782 pToRemove->SetPageFrm( 0L );
783 }
784
785 /*************************************************************************
786 |* SwPageFrm::MoveFly
787 |*
788 |* Ersterstellung MA 25. Jan. 97
789 |* Letzte Änderung MA 25. Jan. 97
790 |*************************************************************************/
791
MoveFly(SwFlyFrm * pToMove,SwPageFrm * pDest)792 void SwPageFrm::MoveFly( SwFlyFrm *pToMove, SwPageFrm *pDest )
793 {
794 //Invalidierungen
795 if ( GetUpper() )
796 {
797 ((SwRootFrm*)GetUpper())->SetIdleFlags();
798 if ( !pToMove->IsFlyInCntFrm() && pDest->GetPhyPageNum() < GetPhyPageNum() )
799 ((SwRootFrm*)GetUpper())->SetSuperfluous();
800 }
801
802 pDest->InvalidateSpelling();
803 pDest->InvalidateSmartTags(); // SMARTTAGS
804 pDest->InvalidateAutoCompleteWords();
805 pDest->InvalidateWordCount();
806
807 if ( pToMove->IsFlyInCntFrm() )
808 {
809 pDest->InvalidateFlyInCnt();
810 return;
811 }
812
813 // Notify accessible layout. That's required at this place for
814 // frames only where the anchor is moved. Creation of new frames
815 // is additionally handled by the SwFrmNotify class.
816 if( GetUpper() &&
817 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
818 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
819 {
820 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
821 ->DisposeAccessibleFrm( pToMove, sal_True );
822 }
823
824 // Die FlyColl kann bereits weg sein, weil der DTor der Seite
825 // gerade 'läuft'
826 if ( pSortedObjs )
827 {
828 pSortedObjs->Remove( *pToMove );
829 if ( !pSortedObjs->Count() )
830 { DELETEZ( pSortedObjs );
831 }
832 }
833
834 //Anmelden
835 if ( !pDest->GetSortedObjs() )
836 pDest->pSortedObjs = new SwSortedObjs();
837
838 #if OSL_DEBUG_LEVEL > 1
839 const bool bSucessInserted =
840 #endif
841 pDest->GetSortedObjs()->Insert( *pToMove );
842 #if OSL_DEBUG_LEVEL > 1
843 ASSERT( bSucessInserted, "Fly nicht in Sorted eingetragen." )
844 (void) bSucessInserted;
845 #endif
846
847 // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)>
848 pToMove->SetPageFrm( pDest );
849 pToMove->InvalidatePage( pDest );
850 pToMove->SetNotifyBack();
851 pDest->InvalidateFlyCntnt();
852 // OD 2004-05-17 #i28701#
853 pToMove->UnlockPosition();
854
855 // Notify accessible layout. That's required at this place for
856 // frames only where the anchor is moved. Creation of new frames
857 // is additionally handled by the SwFrmNotify class.
858 if( GetUpper() &&
859 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
860 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
861 {
862 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
863 ->AddAccessibleFrm( pToMove );
864 }
865
866 // --> OD 2004-06-09 #i28701# - correction: move lowers of Writer fly frame
867 if ( pToMove->GetDrawObjs() )
868 {
869 SwSortedObjs &rObjs = *pToMove->GetDrawObjs();
870 for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
871 {
872 SwAnchoredObject* pObj = rObjs[i];
873 if ( pObj->ISA(SwFlyFrm) )
874 {
875 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
876 if ( pFly->IsFlyFreeFrm() )
877 {
878 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
879 SwPageFrm* pPageFrm = pFly->GetPageFrm();
880 if ( pPageFrm )
881 pPageFrm->MoveFly( pFly, pDest );
882 else
883 pDest->AppendFlyToPage( pFly );
884 }
885 }
886 else if ( pObj->ISA(SwAnchoredDrawObject) )
887 {
888 RemoveDrawObjFromPage( *pObj );
889 pDest->AppendDrawObjToPage( *pObj );
890 }
891 }
892 }
893 }
894
895 /*************************************************************************
896 |* SwPageFrm::AppendDrawObjToPage(), RemoveDrawObjFromPage()
897 |*
898 |* --> OD 2004-07-02 #i28701# - new methods
899 |*************************************************************************/
AppendDrawObjToPage(SwAnchoredObject & _rNewObj)900 void SwPageFrm::AppendDrawObjToPage( SwAnchoredObject& _rNewObj )
901 {
902 if ( !_rNewObj.ISA(SwAnchoredDrawObject) )
903 {
904 ASSERT( false,
905 "SwPageFrm::AppendDrawObjToPage(..) - anchored object of unexpected type -> object not appended" );
906 return;
907 }
908
909 if ( GetUpper() )
910 {
911 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
912 }
913
914 ASSERT( _rNewObj.GetAnchorFrm(), "anchored draw object without anchor" );
915 SwFlyFrm* pFlyFrm = (SwFlyFrm*)_rNewObj.GetAnchorFrm()->FindFlyFrm();
916 if ( pFlyFrm &&
917 _rNewObj.GetDrawObj()->GetOrdNum() < pFlyFrm->GetVirtDrawObj()->GetOrdNum() )
918 {
919 //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed.
920 sal_uInt32 nNewNum = _rNewObj.GetDrawObj()->GetOrdNumDirect();
921 if ( _rNewObj.GetDrawObj()->GetPage() )
922 _rNewObj.DrawObj()->GetPage()->SetObjectOrdNum( pFlyFrm->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum );
923 else
924 pFlyFrm->GetVirtDrawObj()->SetOrdNum( nNewNum );
925 }
926
927 if ( FLY_AS_CHAR == _rNewObj.GetFrmFmt().GetAnchor().GetAnchorId() )
928 {
929 return;
930 }
931
932 if ( !pSortedObjs )
933 {
934 pSortedObjs = new SwSortedObjs();
935 }
936 if ( !pSortedObjs->Insert( _rNewObj ) )
937 {
938 #ifdef DBG_UTIL
939 ASSERT( pSortedObjs->Contains( _rNewObj ),
940 "Drawing object not appended into list <pSortedObjs>." );
941 #endif
942 }
943 // --> OD 2008-04-22 #i87493#
944 ASSERT( _rNewObj.GetPageFrm() == 0 || _rNewObj.GetPageFrm() == this,
945 "<SwPageFrm::AppendDrawObjToPage(..)> - anchored draw object seems to be registered at another page frame. Serious defect -> please inform OD." );
946 // <--
947 _rNewObj.SetPageFrm( this );
948
949 // invalidate page in order to force a reformat of object layout of the page.
950 InvalidateFlyLayout();
951 }
952
RemoveDrawObjFromPage(SwAnchoredObject & _rToRemoveObj)953 void SwPageFrm::RemoveDrawObjFromPage( SwAnchoredObject& _rToRemoveObj )
954 {
955 if ( !_rToRemoveObj.ISA(SwAnchoredDrawObject) )
956 {
957 ASSERT( false,
958 "SwPageFrm::RemoveDrawObjFromPage(..) - anchored object of unexpected type -> object not removed" );
959 return;
960 }
961
962 if ( pSortedObjs )
963 {
964 pSortedObjs->Remove( _rToRemoveObj );
965 if ( !pSortedObjs->Count() )
966 {
967 DELETEZ( pSortedObjs );
968 }
969 if ( GetUpper() )
970 {
971 if (FLY_AS_CHAR !=
972 _rToRemoveObj.GetFrmFmt().GetAnchor().GetAnchorId())
973 {
974 ((SwRootFrm*)GetUpper())->SetSuperfluous();
975 InvalidatePage();
976 }
977 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth();
978 }
979 }
980 _rToRemoveObj.SetPageFrm( 0 );
981 }
982
983 /*************************************************************************
984 |* SwPageFrm::PlaceFly
985 |*
986 |* Ersterstellung MA 08. Feb. 93
987 |* Letzte Änderung MA 27. Feb. 93
988 |*************************************************************************/
989
990 // --> OD 2005-06-09 #i50432# - adjust method description and synopsis.
PlaceFly(SwFlyFrm * pFly,SwFlyFrmFmt * pFmt)991 void SwPageFrm::PlaceFly( SwFlyFrm* pFly, SwFlyFrmFmt* pFmt )
992 {
993 // --> OD 2005-06-09 #i50432# - consider the case that page is an empty page:
994 // In this case append the fly frame at the next page
995 ASSERT( !IsEmptyPage() || GetNext(),
996 "<SwPageFrm::PlaceFly(..)> - empty page with no next page! -> fly frame appended at empty page" );
997 if ( IsEmptyPage() && GetNext() )
998 {
999 static_cast<SwPageFrm*>(GetNext())->PlaceFly( pFly, pFmt );
1000 }
1001 else
1002 {
1003 // Wenn ein Fly übergeben wurde, so benutzen wir diesen, ansonsten wird
1004 // mit dem Format einer erzeugt.
1005 if ( pFly )
1006 AppendFly( pFly );
1007 else
1008 { ASSERT( pFmt, ":-( kein Format für Fly übergeben." );
1009 pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, this, this );
1010 AppendFly( pFly );
1011 ::RegistFlys( this, pFly );
1012 }
1013 }
1014 // <--
1015 }
1016
1017 /*************************************************************************
1018 |* ::CalcClipRect
1019 |*
1020 |* Ersterstellung AMA 24. Sep. 96
1021 |* Letzte Änderung MA 18. Dec. 96
1022 |*************************************************************************/
1023 // OD 22.09.2003 #i18732# - adjustments for following text flow or not
1024 // AND alignment at 'page areas' for to paragraph/to character anchored objects
1025 // OD 06.11.2003 #i22305# - adjustment for following text flow
1026 // for to frame anchored objects
1027 // OD 2004-06-02 #i29778# - Because the calculation of the position of the
1028 // floating screen object (Writer fly frame or drawing object) doesn't perform
1029 // a calculation on its upper frames and its anchor frame, a calculation of
1030 // the upper frames in this method no longer sensible.
1031 // --> OD 2004-07-06 #i28701# - if document compatibility option 'Consider
1032 // wrapping style influence on object positioning' is ON, the clip area
1033 // corresponds to the one as the object doesn't follows the text flow.
CalcClipRect(const SdrObject * pSdrObj,SwRect & rRect,sal_Bool bMove)1034 sal_Bool CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, sal_Bool bMove )
1035 {
1036 sal_Bool bRet = sal_True;
1037 if ( pSdrObj->ISA(SwVirtFlyDrawObj) )
1038 {
1039 const SwFlyFrm* pFly = ((const SwVirtFlyDrawObj*)pSdrObj)->GetFlyFrm();
1040 const bool bFollowTextFlow = pFly->GetFmt()->GetFollowTextFlow().GetValue();
1041 // --> OD 2004-07-06 #i28701#
1042 const bool bConsiderWrapOnObjPos =
1043 pFly->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION);
1044 // <--
1045 const SwFmtVertOrient &rV = pFly->GetFmt()->GetVertOrient();
1046 if( pFly->IsFlyLayFrm() )
1047 {
1048 const SwFrm* pClip;
1049 // OD 06.11.2003 #i22305#
1050 // --> OD 2004-07-06 #i28701#
1051 if ( !bFollowTextFlow || bConsiderWrapOnObjPos )
1052 {
1053 pClip = pFly->GetAnchorFrm()->FindPageFrm();
1054 }
1055 else
1056 {
1057 pClip = pFly->GetAnchorFrm();
1058 }
1059
1060 rRect = pClip->Frm();
1061 SWRECTFN( pClip )
1062
1063 // Vertikales clipping: Top und Bottom, ggf. an PrtArea
1064 if( rV.GetVertOrient() != text::VertOrientation::NONE &&
1065 rV.GetRelationOrient() == text::RelOrientation::PRINT_AREA )
1066 {
1067 (rRect.*fnRect->fnSetTop)( (pClip->*fnRect->fnGetPrtTop)() );
1068 (rRect.*fnRect->fnSetBottom)( (pClip->*fnRect->fnGetPrtBottom)() );
1069 }
1070 // Horizontales clipping: Left und Right, ggf. an PrtArea
1071 const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient();
1072 if( rH.GetHoriOrient() != text::HoriOrientation::NONE &&
1073 rH.GetRelationOrient() == text::RelOrientation::PRINT_AREA )
1074 {
1075 (rRect.*fnRect->fnSetLeft)( (pClip->*fnRect->fnGetPrtLeft)() );
1076 (rRect.*fnRect->fnSetRight)((pClip->*fnRect->fnGetPrtRight)());
1077 }
1078 }
1079 else if( pFly->IsFlyAtCntFrm() )
1080 {
1081 // OD 22.09.2003 #i18732# - consider following text flow or not
1082 // AND alignment at 'page areas'
1083 const SwFrm* pVertPosOrientFrm = pFly->GetVertPosOrientFrm();
1084 if ( !pVertPosOrientFrm )
1085 {
1086 ASSERT( false,
1087 "::CalcClipRect(..) - frame, vertical position is oriented at, is missing .");
1088 pVertPosOrientFrm = pFly->GetAnchorFrm();
1089 }
1090
1091 if ( !bFollowTextFlow || bConsiderWrapOnObjPos )
1092 {
1093 const SwLayoutFrm* pClipFrm = pVertPosOrientFrm->FindPageFrm();
1094 rRect = bMove ? pClipFrm->GetUpper()->Frm()
1095 : pClipFrm->Frm();
1096 // --> OD 2004-10-14 #i26945# - consider that a table, during
1097 // its format, can exceed its upper printing area bottom.
1098 // Thus, enlarge the clip rectangle, if such a case occurred
1099 if ( pFly->GetAnchorFrm()->IsInTab() )
1100 {
1101 const SwTabFrm* pTabFrm = const_cast<SwFlyFrm*>(pFly)
1102 ->GetAnchorFrmContainingAnchPos()->FindTabFrm();
1103 SwRect aTmp( pTabFrm->Prt() );
1104 aTmp += pTabFrm->Frm().Pos();
1105 rRect.Union( aTmp );
1106 // --> OD 2005-03-30 #i43913# - consider also the cell frame
1107 const SwFrm* pCellFrm = const_cast<SwFlyFrm*>(pFly)
1108 ->GetAnchorFrmContainingAnchPos()->GetUpper();
1109 while ( pCellFrm && !pCellFrm->IsCellFrm() )
1110 {
1111 pCellFrm = pCellFrm->GetUpper();
1112 }
1113 if ( pCellFrm )
1114 {
1115 aTmp = pCellFrm->Prt();
1116 aTmp += pCellFrm->Frm().Pos();
1117 rRect.Union( aTmp );
1118 }
1119 // <--
1120 }
1121 }
1122 else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME ||
1123 rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )
1124 {
1125 // OD 29.10.2003 #113049# - new class <SwEnvironmentOfAnchoredObject>
1126 objectpositioning::SwEnvironmentOfAnchoredObject
1127 aEnvOfObj( bFollowTextFlow );
1128 const SwLayoutFrm& rVertClipFrm =
1129 aEnvOfObj.GetVertEnvironmentLayoutFrm( *pVertPosOrientFrm );
1130 if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME )
1131 {
1132 rRect = rVertClipFrm.Frm();
1133 }
1134 else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )
1135 {
1136 if ( rVertClipFrm.IsPageFrm() )
1137 {
1138 rRect = static_cast<const SwPageFrm&>(rVertClipFrm).PrtWithoutHeaderAndFooter();
1139 }
1140 else
1141 {
1142 rRect = rVertClipFrm.Frm();
1143 }
1144 }
1145 const SwLayoutFrm* pHoriClipFrm =
1146 pFly->GetAnchorFrm()->FindPageFrm()->GetUpper();
1147 SWRECTFN( pFly->GetAnchorFrm() )
1148 (rRect.*fnRect->fnSetLeft)( (pHoriClipFrm->Frm().*fnRect->fnGetLeft)() );
1149 (rRect.*fnRect->fnSetRight)((pHoriClipFrm->Frm().*fnRect->fnGetRight)());
1150 }
1151 else
1152 {
1153 // --> OD 2004-10-11 #i26945#
1154 const SwFrm *pClip =
1155 const_cast<SwFlyFrm*>(pFly)->GetAnchorFrmContainingAnchPos();
1156 // <--
1157 SWRECTFN( pClip )
1158 const SwLayoutFrm *pUp = pClip->GetUpper();
1159 const SwFrm *pCell = pUp->IsCellFrm() ? pUp : 0;
1160 sal_uInt16 nType = bMove ? FRM_ROOT | FRM_FLY | FRM_HEADER |
1161 FRM_FOOTER | FRM_FTN
1162 : FRM_BODY | FRM_FLY | FRM_HEADER |
1163 FRM_FOOTER | FRM_CELL| FRM_FTN;
1164
1165 while ( !(pUp->GetType() & nType) || pUp->IsColBodyFrm() )
1166 {
1167 pUp = pUp->GetUpper();
1168 if ( !pCell && pUp->IsCellFrm() )
1169 pCell = pUp;
1170 }
1171 if ( bMove )
1172 {
1173 if ( pUp->IsRootFrm() )
1174 {
1175 rRect = pUp->Prt();
1176 rRect += pUp->Frm().Pos();
1177 pUp = 0;
1178 }
1179 }
1180 if ( pUp )
1181 {
1182 if ( pUp->GetType() & FRM_BODY )
1183 {
1184 const SwPageFrm *pPg;
1185 if ( pUp->GetUpper() != (pPg = pFly->FindPageFrm()) )
1186 pUp = pPg->FindBodyCont();
1187 rRect = pUp->GetUpper()->Frm();
1188 (rRect.*fnRect->fnSetTop)( (pUp->*fnRect->fnGetPrtTop)() );
1189 (rRect.*fnRect->fnSetBottom)((pUp->*fnRect->fnGetPrtBottom)());
1190 }
1191 else
1192 {
1193 if( ( pUp->GetType() & (FRM_FLY | FRM_FTN ) ) &&
1194 !pUp->Frm().IsInside( pFly->Frm().Pos() ) )
1195 {
1196 if( pUp->IsFlyFrm() )
1197 {
1198 SwFlyFrm *pTmpFly = (SwFlyFrm*)pUp;
1199 while( pTmpFly->GetNextLink() )
1200 {
1201 pTmpFly = pTmpFly->GetNextLink();
1202 if( pTmpFly->Frm().IsInside( pFly->Frm().Pos() ) )
1203 break;
1204 }
1205 pUp = pTmpFly;
1206 }
1207 else if( pUp->IsInFtn() )
1208 {
1209 const SwFtnFrm *pTmp = pUp->FindFtnFrm();
1210 while( pTmp->GetFollow() )
1211 {
1212 pTmp = pTmp->GetFollow();
1213 if( pTmp->Frm().IsInside( pFly->Frm().Pos() ) )
1214 break;
1215 }
1216 pUp = pTmp;
1217 }
1218 }
1219 rRect = pUp->Prt();
1220 rRect.Pos() += pUp->Frm().Pos();
1221 if ( pUp->GetType() & (FRM_HEADER | FRM_FOOTER) )
1222 {
1223 rRect.Left ( pUp->GetUpper()->Frm().Left() );
1224 rRect.Width( pUp->GetUpper()->Frm().Width());
1225 }
1226 else if ( pUp->IsCellFrm() ) // MA_FLY_HEIGHT
1227 {
1228 const SwFrm *pTab = pUp->FindTabFrm();
1229 (rRect.*fnRect->fnSetBottom)(
1230 (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() );
1231 // OD 08.08.2003 #110978# - expand to left and right
1232 // cell border
1233 rRect.Left ( pUp->Frm().Left() );
1234 rRect.Width( pUp->Frm().Width() );
1235 }
1236 }
1237 }
1238 if ( pCell )
1239 {
1240 // CellFrms können auch in 'unerlaubten' Bereichen stehen, dann
1241 // darf der Fly das auch.
1242 SwRect aTmp( pCell->Prt() );
1243 aTmp += pCell->Frm().Pos();
1244 rRect.Union( aTmp );
1245 }
1246 }
1247 }
1248 else
1249 {
1250 const SwFrm *pUp = pFly->GetAnchorFrm()->GetUpper();
1251 SWRECTFN( pFly->GetAnchorFrm() )
1252 while( pUp->IsColumnFrm() || pUp->IsSctFrm() || pUp->IsColBodyFrm())
1253 pUp = pUp->GetUpper();
1254 rRect = pUp->Frm();
1255 if( !pUp->IsBodyFrm() )
1256 {
1257 rRect += pUp->Prt().Pos();
1258 rRect.SSize( pUp->Prt().SSize() );
1259 if ( pUp->IsCellFrm() )
1260 {
1261 const SwFrm *pTab = pUp->FindTabFrm();
1262 (rRect.*fnRect->fnSetBottom)(
1263 (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() );
1264 }
1265 }
1266 else if ( pUp->GetUpper()->IsPageFrm() )
1267 {
1268 // #111909# Objects anchored as character may exceed right margin
1269 // of body frame:
1270 (rRect.*fnRect->fnSetRight)( (pUp->GetUpper()->Frm().*fnRect->fnGetRight)() );
1271 }
1272 long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10;
1273 long nTop;
1274 const SwFmt *pFmt = ((SwContact*)GetUserCall(pSdrObj))->GetFmt();
1275 const SvxULSpaceItem &rUL = pFmt->GetULSpace();
1276 if( bMove )
1277 {
1278 nTop = bVert ? ((SwFlyInCntFrm*)pFly)->GetRefPoint().X() :
1279 ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y();
1280 nTop = (*fnRect->fnYInc)( nTop, -nHeight );
1281 long nWidth = (pFly->Frm().*fnRect->fnGetWidth)();
1282 (rRect.*fnRect->fnSetLeftAndWidth)( bVert ?
1283 ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y() :
1284 ((SwFlyInCntFrm*)pFly)->GetRefPoint().X(), nWidth );
1285 nHeight = 2*nHeight - rUL.GetLower() - rUL.GetUpper();
1286 }
1287 else
1288 {
1289 nTop = (*fnRect->fnYInc)( (pFly->Frm().*fnRect->fnGetBottom)(),
1290 rUL.GetLower() - nHeight );
1291 nHeight = 2*nHeight - (pFly->Frm().*fnRect->fnGetHeight)()
1292 - rUL.GetLower() - rUL.GetUpper();
1293 }
1294 (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight );
1295 }
1296 }
1297 else
1298 {
1299 const SwDrawContact *pC = (const SwDrawContact*)GetUserCall(pSdrObj);
1300 const SwFrmFmt *pFmt = (const SwFrmFmt*)pC->GetFmt();
1301 const SwFmtAnchor &rAnch = pFmt->GetAnchor();
1302 if ( FLY_AS_CHAR == rAnch.GetAnchorId() )
1303 {
1304 const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj );
1305 if( !pAnchorFrm )
1306 {
1307 ASSERT( false, "<::CalcClipRect(..)> - missing anchor frame." );
1308 ((SwDrawContact*)pC)->ConnectToLayout();
1309 pAnchorFrm = pC->GetAnchorFrm();
1310 }
1311 const SwFrm* pUp = pAnchorFrm->GetUpper();
1312 rRect = pUp->Prt();
1313 rRect += pUp->Frm().Pos();
1314 SWRECTFN( pAnchorFrm )
1315 long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10;
1316 long nTop;
1317 const SvxULSpaceItem &rUL = pFmt->GetULSpace();
1318 SwRect aSnapRect( pSdrObj->GetSnapRect() );
1319 long nTmpH = 0;
1320 if( bMove )
1321 {
1322 nTop = (*fnRect->fnYInc)( bVert ? pSdrObj->GetAnchorPos().X() :
1323 pSdrObj->GetAnchorPos().Y(), -nHeight );
1324 long nWidth = (aSnapRect.*fnRect->fnGetWidth)();
1325 (rRect.*fnRect->fnSetLeftAndWidth)( bVert ?
1326 pSdrObj->GetAnchorPos().Y() :
1327 pSdrObj->GetAnchorPos().X(), nWidth );
1328 }
1329 else
1330 {
1331 // OD 2004-04-13 #i26791# - value of <nTmpH> is needed to
1332 // calculate value of <nTop>.
1333 nTmpH = bVert ? pSdrObj->GetCurrentBoundRect().GetWidth() :
1334 pSdrObj->GetCurrentBoundRect().GetHeight();
1335 nTop = (*fnRect->fnYInc)( (aSnapRect.*fnRect->fnGetTop)(),
1336 rUL.GetLower() + nTmpH - nHeight );
1337 }
1338 nHeight = 2*nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper();
1339 (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight );
1340 }
1341 else
1342 {
1343 // OD 23.06.2003 #108784# - restrict clip rectangle for drawing
1344 // objects in header/footer to the page frame.
1345 // OD 2004-03-29 #i26791#
1346 const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj );
1347 if ( pAnchorFrm && pAnchorFrm->FindFooterOrHeader() )
1348 {
1349 // clip frame is the page frame the header/footer is on.
1350 const SwFrm* pClipFrm = pAnchorFrm->FindPageFrm();
1351 rRect = pClipFrm->Frm();
1352 }
1353 else
1354 {
1355 bRet = sal_False;
1356 }
1357 }
1358 }
1359 return bRet;
1360 }
1361
1362 /* vim: set noet sw=4 ts=4: */
1363