Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "pagefrm.hxx"
21 : #include "rootfrm.hxx"
22 : #include "cntfrm.hxx"
23 : #include "dflyobj.hxx"
24 : #include "dcontact.hxx"
25 : #include "ftnfrm.hxx"
26 : #include "frmtool.hxx"
27 : #include "hints.hxx"
28 : #include "sectfrm.hxx"
29 :
30 : #include <svx/svdpage.hxx>
31 : #include <editeng/ulspitem.hxx>
32 : #include <fmtornt.hxx>
33 : #include <fmtfsize.hxx>
34 : #include "ndole.hxx"
35 : #include "tabfrm.hxx"
36 : #include "flyfrms.hxx"
37 : #include <fmtfollowtextflow.hxx>
38 : #include <environmentofanchoredobject.hxx>
39 : #include <sortedobjs.hxx>
40 : #include <viewimp.hxx>
41 : #include <IDocumentSettingAccess.hxx>
42 : #include <IDocumentDrawModelAccess.hxx>
43 :
44 : using namespace ::com::sun::star;
45 :
46 1333 : SwFlyFreeFrm::SwFlyFreeFrm( SwFlyFrameFormat *pFormat, SwFrm* pSib, SwFrm *pAnch ) :
47 : SwFlyFrm( pFormat, pSib, pAnch ),
48 : pPage( 0 ),
49 : // #i34753#
50 : mbNoMakePos( false ),
51 : // #i37068#
52 : mbNoMoveOnCheckClip( false ),
53 1333 : maUnclippedFrm( )
54 : {
55 1333 : }
56 :
57 1333 : void SwFlyFreeFrm::DestroyImpl()
58 : {
59 : // #i28701# - use new method <GetPageFrm()>
60 1333 : if( GetPageFrm() )
61 : {
62 116 : if( GetFormat()->GetDoc()->IsInDtor() )
63 : {
64 : // #i29879# - remove also to-frame anchored Writer
65 : // fly frame from page.
66 : const bool bRemoveFromPage =
67 0 : GetPageFrm()->GetSortedObjs() &&
68 0 : ( IsFlyAtCntFrm() ||
69 0 : ( GetAnchorFrm() && GetAnchorFrm()->IsFlyFrm() ) );
70 0 : if ( bRemoveFromPage )
71 : {
72 0 : GetPageFrm()->GetSortedObjs()->Remove( *this );
73 : }
74 : }
75 : else
76 : {
77 116 : SwRect aTmp( GetObjRectWithSpaces() );
78 116 : SwFlyFreeFrm::NotifyBackground( GetPageFrm(), aTmp, PREP_FLY_LEAVE );
79 : }
80 : }
81 :
82 1333 : SwFlyFrm::DestroyImpl();
83 1333 : }
84 :
85 1333 : SwFlyFreeFrm::~SwFlyFreeFrm()
86 : {
87 1333 : }
88 :
89 : // #i28701#
90 556277 : TYPEINIT1(SwFlyFreeFrm,SwFlyFrm);
91 : /** Notifies the background (all ContentFrms that currently are overlapping).
92 : *
93 : * Additionally, the window is also directly invalidated (especially where
94 : * there are no overlapping ContentFrms).
95 : * This also takes ContentFrms within other Flys into account.
96 : */
97 3387 : void SwFlyFreeFrm::NotifyBackground( SwPageFrm *pPageFrm,
98 : const SwRect& rRect, PrepareHint eHint )
99 : {
100 3387 : ::Notify_Background( GetVirtDrawObj(), pPageFrm, rRect, eHint, true );
101 3387 : }
102 :
103 3596 : void SwFlyFreeFrm::MakeAll()
104 : {
105 3596 : if ( !GetFormat()->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
106 : {
107 0 : return;
108 : }
109 :
110 3596 : if ( !GetAnchorFrm() || IsLocked() || IsColLocked() )
111 0 : return;
112 : // #i28701# - use new method <GetPageFrm()>
113 3596 : if( !GetPageFrm() && GetAnchorFrm() && GetAnchorFrm()->IsInFly() )
114 : {
115 0 : SwFlyFrm* pFly = AnchorFrm()->FindFlyFrm();
116 0 : SwPageFrm *pPageFrm = pFly ? pFly->FindPageFrm() : NULL;
117 0 : if( pPageFrm )
118 0 : pPageFrm->AppendFlyToPage( this );
119 : }
120 3596 : if( !GetPageFrm() )
121 0 : return;
122 :
123 3596 : Lock(); // The curtain drops
124 :
125 : // takes care of the notification in the dtor
126 3596 : const SwFlyNotify aNotify( this );
127 :
128 3596 : if ( IsClipped() )
129 : {
130 208 : mbValidSize = bHeightClipped = bWidthClipped = false;
131 : // no invalidation of position,
132 : // if anchored object is anchored inside a Writer fly frame,
133 : // its position is already locked, and it follows the text flow.
134 : // #i34753# - add condition:
135 : // no invalidation of position, if no direct move is requested in <CheckClip(..)>
136 308 : if ( !IsNoMoveOnCheckClip() &&
137 50 : !( PositionLocked() &&
138 0 : GetAnchorFrm()->IsInFly() &&
139 0 : GetFrameFormat().GetFollowTextFlow().GetValue() ) )
140 : {
141 50 : mbValidPos = false;
142 : }
143 : }
144 :
145 : // #i81146# new loop control
146 3596 : int nLoopControlRuns = 0;
147 3596 : const int nLoopControlMax = 10;
148 :
149 12326 : while ( !mbValidPos || !mbValidSize || !mbValidPrtArea || bFormatHeightOnly || !m_bValidContentPos )
150 : {
151 5134 : SWRECTFN( this )
152 : const SwFormatFrmSize *pSz;
153 : { // Additional scope, so aAccess will be destroyed before the check!
154 :
155 5134 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
156 5134 : const SwBorderAttrs &rAttrs = *aAccess.Get();
157 5134 : pSz = &rAttrs.GetAttrSet().GetFrmSize();
158 :
159 : // Only set when the flag is set!
160 5134 : if ( !mbValidSize )
161 : {
162 3812 : mbValidPrtArea = false;
163 : }
164 :
165 5134 : if ( !mbValidPrtArea )
166 : {
167 3812 : MakePrtArea( rAttrs );
168 3812 : m_bValidContentPos = false;
169 : }
170 :
171 5134 : if ( !mbValidSize || bFormatHeightOnly )
172 : {
173 3812 : mbValidSize = false;
174 3812 : Format( &rAttrs );
175 3812 : bFormatHeightOnly = false;
176 5134 : }
177 : }
178 :
179 5134 : if ( !mbValidPos )
180 : {
181 2512 : const Point aOldPos( (Frm().*fnRect->fnGetPos)() );
182 : // #i26791# - use new method <MakeObjPos()>
183 : // #i34753# - no positioning, if requested.
184 2512 : if ( IsNoMakePos() )
185 0 : mbValidPos = true;
186 : else
187 : // #i26791# - use new method <MakeObjPos()>
188 2512 : MakeObjPos();
189 2512 : if( aOldPos == (Frm().*fnRect->fnGetPos)() )
190 : {
191 995 : if( !mbValidPos && GetAnchorFrm()->IsInSct() &&
192 0 : !GetAnchorFrm()->FindSctFrm()->IsValid() )
193 0 : mbValidPos = true;
194 : }
195 : else
196 1517 : mbValidSize = false;
197 : }
198 :
199 5134 : if ( !m_bValidContentPos )
200 : {
201 4314 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
202 4314 : const SwBorderAttrs &rAttrs = *aAccess.Get();
203 4314 : MakeContentPos( rAttrs );
204 : }
205 :
206 5134 : if ( mbValidPos && mbValidSize )
207 : {
208 3610 : ++nLoopControlRuns;
209 :
210 : OSL_ENSURE( nLoopControlRuns < nLoopControlMax, "LoopControl in SwFlyFreeFrm::MakeAll" );
211 :
212 7220 : if ( nLoopControlRuns < nLoopControlMax )
213 3610 : CheckClip( *pSz );
214 : }
215 : else
216 1524 : nLoopControlRuns = 0;
217 : }
218 3596 : Unlock();
219 :
220 : #if OSL_DEBUG_LEVEL > 0
221 : SWRECTFN( this )
222 : OSL_ENSURE( bHeightClipped || ( (Frm().*fnRect->fnGetHeight)() > 0 &&
223 : (Prt().*fnRect->fnGetHeight)() > 0),
224 : "SwFlyFreeFrm::Format(), flipping Fly." );
225 :
226 : #endif
227 : }
228 :
229 : /** determines, if direct environment of fly frame has 'auto' size
230 :
231 : #i17297#
232 : start with anchor frame and search via <GetUpper()> for a header, footer,
233 : row or fly frame stopping at page frame.
234 : return <true>, if such a frame is found and it has 'auto' size.
235 : otherwise <false> is returned.
236 :
237 : @return boolean indicating, that direct environment has 'auto' size
238 : */
239 1 : bool SwFlyFreeFrm::HasEnvironmentAutoSize() const
240 : {
241 1 : bool bRetVal = false;
242 :
243 1 : const SwFrm* pToBeCheckedFrm = GetAnchorFrm();
244 5 : while ( pToBeCheckedFrm &&
245 2 : !pToBeCheckedFrm->IsPageFrm() )
246 : {
247 5 : if ( pToBeCheckedFrm->IsHeaderFrm() ||
248 2 : pToBeCheckedFrm->IsFooterFrm() ||
249 4 : pToBeCheckedFrm->IsRowFrm() ||
250 1 : pToBeCheckedFrm->IsFlyFrm() )
251 : {
252 : bRetVal = ATT_FIX_SIZE !=
253 1 : pToBeCheckedFrm->GetAttrSet()->GetFrmSize().GetHeightSizeType();
254 1 : break;
255 : }
256 : else
257 : {
258 1 : pToBeCheckedFrm = pToBeCheckedFrm->GetUpper();
259 : }
260 : }
261 :
262 1 : return bRetVal;
263 : }
264 :
265 3610 : void SwFlyFreeFrm::CheckClip( const SwFormatFrmSize &rSz )
266 : {
267 : // It's probably time now to take appropriate measures, if the Fly
268 : // doesn't fit into its surrounding.
269 : // First, the Fly gives up its position, then it's formatted.
270 : // Only if it still doesn't fit after giving up its position, the
271 : // width or height are given up as well. The frame will be squeezed
272 : // as much as needed.
273 :
274 3610 : const SwVirtFlyDrawObj *pObj = GetVirtDrawObj();
275 3610 : SwRect aClip, aTmpStretch;
276 3610 : ::CalcClipRect( pObj, aClip, true );
277 3610 : ::CalcClipRect( pObj, aTmpStretch, false );
278 3610 : aClip._Intersection( aTmpStretch );
279 :
280 3610 : const long nBot = Frm().Top() + Frm().Height();
281 3610 : const long nRig = Frm().Left() + Frm().Width();
282 3610 : const long nClipBot = aClip.Top() + aClip.Height();
283 3610 : const long nClipRig = aClip.Left() + aClip.Width();
284 :
285 3610 : const bool bBot = nBot > nClipBot;
286 3610 : const bool bRig = nRig > nClipRig;
287 3610 : if ( bBot || bRig )
288 : {
289 221 : bool bAgain = false;
290 : // #i37068# - no move, if it's requested
291 461 : if ( bBot && !IsNoMoveOnCheckClip() &&
292 279 : !GetDrawObjs() && !GetAnchorFrm()->IsInTab() )
293 : {
294 29 : SwFrm* pHeader = FindFooterOrHeader();
295 : // In a header, correction of the position is no good idea.
296 : // If the fly moves, some paragraphs have to be formatted, this
297 : // could cause a change of the height of the headerframe,
298 : // now the flyframe can change its position and so on ...
299 29 : if ( !pHeader || !pHeader->IsHeaderFrm() )
300 : {
301 20 : const long nOld = Frm().Top();
302 20 : Frm().Pos().Y() = std::max( aClip.Top(), nClipBot - Frm().Height() );
303 20 : if ( Frm().Top() != nOld )
304 12 : bAgain = true;
305 20 : bHeightClipped = true;
306 : }
307 : }
308 221 : if ( bRig )
309 : {
310 20 : const long nOld = Frm().Left();
311 20 : Frm().Pos().X() = std::max( aClip.Left(), nClipRig - Frm().Width() );
312 20 : if ( Frm().Left() != nOld )
313 : {
314 2 : const SwFormatHoriOrient &rH = GetFormat()->GetHoriOrient();
315 : // Left-aligned ones may not be moved to the left when they
316 : // are avoiding another one.
317 2 : if( rH.GetHoriOrient() == text::HoriOrientation::LEFT )
318 0 : Frm().Pos().X() = nOld;
319 : else
320 2 : bAgain = true;
321 : }
322 20 : bWidthClipped = true;
323 : }
324 221 : if ( bAgain )
325 14 : mbValidSize = false;
326 : else
327 : {
328 : // If we reach this branch, the Frm protrudes into forbidden
329 : // areas, and correcting the position is not allowed or not
330 : // possible or not required.
331 :
332 : // For Flys with OLE objects as lower, we make sure that
333 : // we always resize proportionally
334 207 : Size aOldSize( Frm().SSize() );
335 :
336 : // First, setup the FrmRect, then transfer it to the Frm.
337 207 : SwRect aFrmRect( Frm() );
338 :
339 207 : if ( bBot )
340 : {
341 199 : long nDiff = nClipBot;
342 199 : nDiff -= aFrmRect.Top(); // nDiff represents the available distance
343 199 : nDiff = aFrmRect.Height() - nDiff;
344 199 : aFrmRect.Height( aFrmRect.Height() - nDiff );
345 199 : bHeightClipped = true;
346 : }
347 207 : if ( bRig )
348 : {
349 18 : long nDiff = nClipRig;
350 18 : nDiff -= aFrmRect.Left();// nDiff represents the available distance
351 18 : nDiff = aFrmRect.Width() - nDiff;
352 18 : aFrmRect.Width( aFrmRect.Width() - nDiff );
353 18 : bWidthClipped = true;
354 : }
355 :
356 : // #i17297# - no proportional
357 : // scaling of graphics in environments, which determines its size
358 : // by its content ('auto' size). Otherwise layout loops can occur and
359 : // layout sizes of the environment can be incorrect.
360 : // Such environment are:
361 : // (1) header and footer frames with 'auto' size
362 : // (2) table row frames with 'auto' size
363 : // (3) fly frames with 'auto' size
364 : // Note: section frames seems to be not critical - didn't found
365 : // any critical layout situation so far.
366 208 : if ( Lower() && Lower()->IsNoTextFrm() &&
367 2 : ( static_cast<SwContentFrm*>(Lower())->GetNode()->GetOLENode() ||
368 1 : !HasEnvironmentAutoSize() ) )
369 : {
370 : // If width and height got adjusted, then the bigger
371 : // change is relevant.
372 0 : if ( aFrmRect.Width() != aOldSize.Width() &&
373 0 : aFrmRect.Height()!= aOldSize.Height() )
374 : {
375 0 : if ( (aOldSize.Width() - aFrmRect.Width()) >
376 0 : (aOldSize.Height()- aFrmRect.Height()) )
377 0 : aFrmRect.Height( aOldSize.Height() );
378 : else
379 0 : aFrmRect.Width( aOldSize.Width() );
380 : }
381 :
382 : // Adjusted the width? change height proportionally
383 0 : if( aFrmRect.Width() != aOldSize.Width() )
384 : {
385 0 : aFrmRect.Height( aFrmRect.Width() * aOldSize.Height() /
386 0 : aOldSize.Width() );
387 0 : bHeightClipped = true;
388 : }
389 : // Adjusted the height? change width proportionally
390 0 : else if( aFrmRect.Height() != aOldSize.Height() )
391 : {
392 0 : aFrmRect.Width( aFrmRect.Height() * aOldSize.Width() /
393 0 : aOldSize.Height() );
394 0 : bWidthClipped = true;
395 : }
396 :
397 : // #i17297# - reactivate change
398 : // of size attribute for fly frames containing an ole object.
399 :
400 : // Added the aFrmRect.HasArea() hack, because
401 : // the environment of the ole object does not have to be valid
402 : // at this moment, or even worse, it does not have to have a
403 : // reasonable size. In this case we do not want to change to
404 : // attributes permanentely. Maybe one day somebody dares to remove
405 : // this code.
406 0 : if ( aFrmRect.HasArea() &&
407 0 : static_cast<SwContentFrm*>(Lower())->GetNode()->GetOLENode() &&
408 0 : ( bWidthClipped || bHeightClipped ) )
409 : {
410 0 : SwFlyFrameFormat *pFormat = GetFormat();
411 0 : pFormat->LockModify();
412 0 : SwFormatFrmSize aFrmSize( rSz );
413 0 : aFrmSize.SetWidth( aFrmRect.Width() );
414 0 : aFrmSize.SetHeight( aFrmRect.Height() );
415 0 : pFormat->SetFormatAttr( aFrmSize );
416 0 : pFormat->UnlockModify();
417 : }
418 : }
419 :
420 : // Now change the Frm; for columns, we put the new values into the attributes,
421 : // otherwise we'll end up with unwanted side-effects/oscillations
422 207 : const long nPrtHeightDiff = Frm().Height() - Prt().Height();
423 207 : const long nPrtWidthDiff = Frm().Width() - Prt().Width();
424 207 : maUnclippedFrm = SwRect( Frm() );
425 207 : Frm().Height( aFrmRect.Height() );
426 207 : Frm().Width ( std::max( long(MINLAY), aFrmRect.Width() ) );
427 207 : if ( Lower() && Lower()->IsColumnFrm() )
428 : {
429 0 : ColLock(); //lock grow/shrink
430 0 : const Size aTmpOldSize( Prt().SSize() );
431 0 : Prt().Height( Frm().Height() - nPrtHeightDiff );
432 0 : Prt().Width ( Frm().Width() - nPrtWidthDiff );
433 0 : ChgLowersProp( aTmpOldSize );
434 0 : SwFrm *pLow = Lower();
435 0 : do
436 : {
437 0 : pLow->Calc();
438 : // also calculate the (Column)BodyFrm
439 0 : static_cast<SwLayoutFrm*>(pLow)->Lower()->Calc();
440 0 : pLow = pLow->GetNext();
441 : } while ( pLow );
442 0 : ::CalcContent( this );
443 0 : ColUnlock();
444 0 : if ( !mbValidSize && !bWidthClipped )
445 0 : bFormatHeightOnly = mbValidSize = true;
446 : }
447 : else
448 : {
449 207 : Prt().Height( Frm().Height() - nPrtHeightDiff );
450 207 : Prt().Width ( Frm().Width() - nPrtWidthDiff );
451 : }
452 : }
453 : }
454 :
455 : // #i26945#
456 : OSL_ENSURE( Frm().Height() >= 0,
457 : "<SwFlyFreeFrm::CheckClip(..)> - fly frame has negative height now." );
458 3610 : }
459 :
460 : /** method to determine, if a <MakeAll()> on the Writer fly frame is possible
461 : #i43771#
462 : */
463 8969 : bool SwFlyFreeFrm::IsFormatPossible() const
464 : {
465 26907 : return SwFlyFrm::IsFormatPossible() &&
466 8969 : ( GetPageFrm() ||
467 8969 : ( GetAnchorFrm() && GetAnchorFrm()->IsInFly() ) );
468 : }
469 :
470 102 : SwFlyLayFrm::SwFlyLayFrm( SwFlyFrameFormat *pFormat, SwFrm* pSib, SwFrm *pAnch ) :
471 102 : SwFlyFreeFrm( pFormat, pSib, pAnch )
472 : {
473 102 : bLayout = true;
474 102 : }
475 :
476 : // #i28701#
477 9600 : TYPEINIT1(SwFlyLayFrm,SwFlyFreeFrm);
478 :
479 47 : void SwFlyLayFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
480 : {
481 47 : const sal_uInt16 nWhich = pNew ? pNew->Which() : 0;
482 :
483 47 : const SwFormatAnchor *pAnch = 0;
484 77 : if( RES_ATTRSET_CHG == nWhich && SfxItemState::SET ==
485 30 : static_cast<const SwAttrSetChg*>(pNew)->GetChgSet()->GetItemState( RES_ANCHOR, false,
486 30 : reinterpret_cast<const SfxPoolItem**>(&pAnch) ))
487 : ; // GetItemState sets the anchor pointer!
488 :
489 43 : else if( RES_ANCHOR == nWhich )
490 : {
491 : // Change of anchor. I'm attaching myself to the new place.
492 : // It's not allowed to change the anchor type. This is only
493 : // possible via SwFEShell.
494 0 : pAnch = static_cast<const SwFormatAnchor*>(pNew);
495 : }
496 :
497 47 : if( pAnch )
498 : {
499 : OSL_ENSURE( pAnch->GetAnchorId() ==
500 : GetFormat()->GetAnchor().GetAnchorId(),
501 : "8-) Invalid change of anchor type." );
502 :
503 : // Unregister, get hold of the page, attach to the corresponding LayoutFrm.
504 4 : SwRect aOld( GetObjRectWithSpaces() );
505 : // #i28701# - use new method <GetPageFrm()>
506 4 : SwPageFrm *pOldPage = GetPageFrm();
507 4 : AnchorFrm()->RemoveFly( this );
508 :
509 4 : if ( FLY_AT_PAGE == pAnch->GetAnchorId() )
510 : {
511 4 : sal_uInt16 nPgNum = pAnch->GetPageNum();
512 4 : SwRootFrm *pRoot = getRootFrm();
513 4 : SwPageFrm *pTmpPage = static_cast<SwPageFrm*>(pRoot->Lower());
514 12 : for ( sal_uInt16 i = 1; (i <= nPgNum) && pTmpPage; ++i,
515 4 : pTmpPage = static_cast<SwPageFrm*>(pTmpPage->GetNext()) )
516 : {
517 4 : if ( i == nPgNum )
518 : {
519 : // #i50432# - adjust synopsis of <PlaceFly(..)>
520 4 : pTmpPage->PlaceFly( this, 0 );
521 : }
522 : }
523 4 : if( !pTmpPage )
524 : {
525 4 : pRoot->SetAssertFlyPages();
526 4 : pRoot->AssertFlyPages();
527 : }
528 : }
529 : else
530 : {
531 0 : SwNodeIndex aIdx( pAnch->GetContentAnchor()->nNode );
532 0 : SwContentFrm *pContent = GetFormat()->GetDoc()->GetNodes().GoNext( &aIdx )->
533 0 : GetContentNode()->getLayoutFrm( getRootFrm(), 0, 0, false );
534 0 : if( pContent )
535 : {
536 0 : SwFlyFrm *pTmp = pContent->FindFlyFrm();
537 0 : if( pTmp )
538 0 : pTmp->AppendFly( this );
539 0 : }
540 : }
541 : // #i28701# - use new method <GetPageFrm()>
542 4 : if ( pOldPage && pOldPage != GetPageFrm() )
543 0 : NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE );
544 4 : SetCompletePaint();
545 4 : InvalidateAll();
546 4 : SetNotifyBack();
547 : }
548 : else
549 43 : SwFlyFrm::Modify( pOld, pNew );
550 47 : }
551 :
552 2214 : void SwPageFrm::AppendFlyToPage( SwFlyFrm *pNew )
553 : {
554 2214 : if ( !pNew->GetVirtDrawObj()->IsInserted() )
555 66 : getRootFrm()->GetDrawPage()->InsertObject(
556 66 : static_cast<SdrObject*>(pNew->GetVirtDrawObj()),
557 132 : pNew->GetVirtDrawObj()->GetReferencedObj().GetOrdNumDirect() );
558 :
559 2214 : InvalidateSpelling();
560 2214 : InvalidateSmartTags();
561 2214 : InvalidateAutoCompleteWords();
562 2214 : InvalidateWordCount();
563 :
564 2214 : if ( GetUpper() )
565 : {
566 2214 : static_cast<SwRootFrm*>(GetUpper())->SetIdleFlags();
567 2214 : static_cast<SwRootFrm*>(GetUpper())->InvalidateBrowseWidth();
568 : }
569 :
570 2214 : SdrObject* pObj = pNew->GetVirtDrawObj();
571 : OSL_ENSURE( pNew->GetAnchorFrm(), "Fly without Anchor" );
572 2214 : SwFlyFrm* pFly = const_cast<SwFlyFrm*>(pNew->GetAnchorFrm()->FindFlyFrm());
573 2214 : if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() )
574 : {
575 : //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed.
576 3 : sal_uInt32 nNewNum = pObj->GetOrdNumDirect();
577 3 : if ( pObj->GetPage() )
578 3 : pObj->GetPage()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum );
579 : else
580 0 : pFly->GetVirtDrawObj()->SetOrdNum( nNewNum );
581 : }
582 :
583 : // Don't look further at Flys that sit inside the Content.
584 2214 : if ( pNew->IsFlyInCntFrm() )
585 815 : InvalidateFlyInCnt();
586 : else
587 : {
588 1399 : InvalidateFlyContent();
589 :
590 1399 : if ( !pSortedObjs )
591 469 : pSortedObjs = new SwSortedObjs();
592 :
593 1399 : const bool bSucessInserted = pSortedObjs->Insert( *pNew );
594 : OSL_ENSURE( bSucessInserted, "Fly not inserted in Sorted." );
595 : (void) bSucessInserted;
596 :
597 : // #i87493#
598 : OSL_ENSURE( pNew->GetPageFrm() == 0 || pNew->GetPageFrm() == this,
599 : "<SwPageFrm::AppendFlyToPage(..)> - anchored fly frame seems to be registered at another page frame. Serious defect -> please inform OD." );
600 : // #i28701# - use new method <SetPageFrm(..)>
601 1399 : pNew->SetPageFrm( this );
602 1399 : pNew->InvalidatePage( this );
603 : // #i28701#
604 1399 : pNew->UnlockPosition();
605 :
606 : // Notify accessible layout. That's required at this place for
607 : // frames only where the anchor is moved. Creation of new frames
608 : // is additionally handled by the SwFrmNotify class.
609 4197 : if( GetUpper() &&
610 1399 : static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
611 0 : static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
612 : {
613 0 : static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
614 0 : ->AddAccessibleFrm( pNew );
615 : }
616 : }
617 :
618 : // #i28701# - correction: consider also drawing objects
619 2214 : if ( pNew->GetDrawObjs() )
620 : {
621 1 : SwSortedObjs &rObjs = *pNew->GetDrawObjs();
622 9 : for ( size_t i = 0; i < rObjs.size(); ++i )
623 : {
624 8 : SwAnchoredObject* pTmpObj = rObjs[i];
625 8 : if ( pTmpObj->ISA(SwFlyFrm) )
626 : {
627 0 : SwFlyFrm* pTmpFly = static_cast<SwFlyFrm*>(pTmpObj);
628 : // #i28701# - use new method <GetPageFrm()>
629 0 : if ( pTmpFly->IsFlyFreeFrm() && !pTmpFly->GetPageFrm() )
630 0 : AppendFlyToPage( pTmpFly );
631 : }
632 8 : else if ( pTmpObj->ISA(SwAnchoredDrawObject) )
633 : {
634 : // #i87493#
635 8 : if ( pTmpObj->GetPageFrm() != this )
636 : {
637 8 : if ( pTmpObj->GetPageFrm() != 0 )
638 : {
639 0 : pTmpObj->GetPageFrm()->RemoveDrawObjFromPage( *pTmpObj );
640 : }
641 8 : AppendDrawObjToPage( *pTmpObj );
642 : }
643 : }
644 : }
645 : }
646 2214 : }
647 :
648 183 : void SwPageFrm::RemoveFlyFromPage( SwFlyFrm *pToRemove )
649 : {
650 183 : const sal_uInt32 nOrdNum = pToRemove->GetVirtDrawObj()->GetOrdNum();
651 183 : getRootFrm()->GetDrawPage()->RemoveObject( nOrdNum );
652 183 : pToRemove->GetVirtDrawObj()->ReferencedObj().SetOrdNum( nOrdNum );
653 :
654 183 : if ( GetUpper() )
655 : {
656 183 : if ( !pToRemove->IsFlyInCntFrm() )
657 182 : static_cast<SwRootFrm*>(GetUpper())->SetSuperfluous();
658 183 : static_cast<SwRootFrm*>(GetUpper())->InvalidateBrowseWidth();
659 : }
660 :
661 : // Don't look further at Flys that sit inside the Content.
662 183 : if ( pToRemove->IsFlyInCntFrm() )
663 184 : return;
664 :
665 : // Don't delete collections just yet. This will happen at the end of the
666 : // action in the RemoveSuperfluous of the page, kicked off by a method of
667 : // the same name in the root.
668 : // The FlyColl might be gone already, because the page's dtor is being
669 : // executed.
670 : // Remove it _before_ disposing accessible frames to avoid accesses to
671 : // the Frm from event handlers.
672 182 : if (pSortedObjs)
673 : {
674 182 : pSortedObjs->Remove(*pToRemove);
675 182 : if (!pSortedObjs->size())
676 : {
677 36 : delete pSortedObjs;
678 36 : pSortedObjs = 0;
679 : }
680 : }
681 :
682 : // Notify accessible layout. That's required at this place for
683 : // frames only where the anchor is moved. Creation of new frames
684 : // is additionally handled by the SwFrmNotify class.
685 546 : if( GetUpper() &&
686 182 : static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
687 0 : static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
688 : {
689 0 : static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
690 0 : ->DisposeAccessibleFrm( pToRemove, true );
691 : }
692 :
693 : // #i28701# - use new method <SetPageFrm(..)>
694 182 : pToRemove->SetPageFrm( 0L );
695 : }
696 :
697 16 : void SwPageFrm::MoveFly( SwFlyFrm *pToMove, SwPageFrm *pDest )
698 : {
699 : // Invalidations
700 16 : if ( GetUpper() )
701 : {
702 16 : static_cast<SwRootFrm*>(GetUpper())->SetIdleFlags();
703 16 : if ( !pToMove->IsFlyInCntFrm() && pDest->GetPhyPageNum() < GetPhyPageNum() )
704 11 : static_cast<SwRootFrm*>(GetUpper())->SetSuperfluous();
705 : }
706 :
707 16 : pDest->InvalidateSpelling();
708 16 : pDest->InvalidateSmartTags();
709 16 : pDest->InvalidateAutoCompleteWords();
710 16 : pDest->InvalidateWordCount();
711 :
712 16 : if ( pToMove->IsFlyInCntFrm() )
713 : {
714 0 : pDest->InvalidateFlyInCnt();
715 16 : return;
716 : }
717 :
718 : // Notify accessible layout. That's required at this place for
719 : // frames only where the anchor is moved. Creation of new frames
720 : // is additionally handled by the SwFrmNotify class.
721 48 : if( GetUpper() &&
722 16 : static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
723 0 : static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
724 : {
725 0 : static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
726 0 : ->DisposeAccessibleFrm( pToMove, true );
727 : }
728 :
729 : // The FlyColl might be gone already, because the page's dtor is being executed.
730 16 : if ( pSortedObjs )
731 : {
732 16 : pSortedObjs->Remove( *pToMove );
733 16 : if ( !pSortedObjs->size() )
734 : {
735 8 : DELETEZ( pSortedObjs );
736 : }
737 : }
738 :
739 : // Register
740 16 : if ( !pDest->GetSortedObjs() )
741 7 : pDest->pSortedObjs = new SwSortedObjs();
742 :
743 16 : const bool bSucessInserted = pDest->GetSortedObjs()->Insert( *pToMove );
744 : OSL_ENSURE( bSucessInserted, "Fly not inserted in Sorted." );
745 : (void) bSucessInserted;
746 :
747 : // #i28701# - use new method <SetPageFrm(..)>
748 16 : pToMove->SetPageFrm( pDest );
749 16 : pToMove->InvalidatePage( pDest );
750 16 : pToMove->SetNotifyBack();
751 16 : pDest->InvalidateFlyContent();
752 : // #i28701#
753 16 : pToMove->UnlockPosition();
754 :
755 : // Notify accessible layout. That's required at this place for
756 : // frames only where the anchor is moved. Creation of new frames
757 : // is additionally handled by the SwFrmNotify class.
758 48 : if( GetUpper() &&
759 16 : static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() &&
760 0 : static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() )
761 : {
762 0 : static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp()
763 0 : ->AddAccessibleFrm( pToMove );
764 : }
765 :
766 : // #i28701# - correction: move lowers of Writer fly frame
767 16 : if ( pToMove->GetDrawObjs() )
768 : {
769 0 : SwSortedObjs &rObjs = *pToMove->GetDrawObjs();
770 0 : for ( size_t i = 0; i < rObjs.size(); ++i )
771 : {
772 0 : SwAnchoredObject* pObj = rObjs[i];
773 0 : if ( pObj->ISA(SwFlyFrm) )
774 : {
775 0 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
776 0 : if ( pFly->IsFlyFreeFrm() )
777 : {
778 : // #i28701# - use new method <GetPageFrm()>
779 0 : SwPageFrm* pPageFrm = pFly->GetPageFrm();
780 0 : if ( pPageFrm )
781 0 : pPageFrm->MoveFly( pFly, pDest );
782 : else
783 0 : pDest->AppendFlyToPage( pFly );
784 : }
785 : }
786 0 : else if ( pObj->ISA(SwAnchoredDrawObject) )
787 : {
788 0 : RemoveDrawObjFromPage( *pObj );
789 0 : pDest->AppendDrawObjToPage( *pObj );
790 : }
791 : }
792 : }
793 : }
794 :
795 2203 : void SwPageFrm::AppendDrawObjToPage( SwAnchoredObject& _rNewObj )
796 : {
797 2203 : if ( !_rNewObj.ISA(SwAnchoredDrawObject) )
798 : {
799 : OSL_FAIL( "SwPageFrm::AppendDrawObjToPage(..) - anchored object of unexpected type -> object not appended" );
800 0 : return;
801 : }
802 :
803 2203 : if ( GetUpper() )
804 : {
805 2203 : static_cast<SwRootFrm*>(GetUpper())->InvalidateBrowseWidth();
806 : }
807 :
808 : OSL_ENSURE( _rNewObj.GetAnchorFrm(), "anchored draw object without anchor" );
809 2203 : SwFlyFrm* pFlyFrm = const_cast<SwFlyFrm*>(_rNewObj.GetAnchorFrm()->FindFlyFrm());
810 2245 : if ( pFlyFrm &&
811 42 : _rNewObj.GetDrawObj()->GetOrdNum() < pFlyFrm->GetVirtDrawObj()->GetOrdNum() )
812 : {
813 : //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed.
814 12 : sal_uInt32 nNewNum = _rNewObj.GetDrawObj()->GetOrdNumDirect();
815 12 : if ( _rNewObj.GetDrawObj()->GetPage() )
816 12 : _rNewObj.DrawObj()->GetPage()->SetObjectOrdNum( pFlyFrm->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum );
817 : else
818 0 : pFlyFrm->GetVirtDrawObj()->SetOrdNum( nNewNum );
819 : }
820 :
821 2203 : if ( FLY_AS_CHAR == _rNewObj.GetFrameFormat().GetAnchor().GetAnchorId() )
822 : {
823 515 : return;
824 : }
825 :
826 1688 : if ( !pSortedObjs )
827 : {
828 518 : pSortedObjs = new SwSortedObjs();
829 : }
830 1688 : if ( !pSortedObjs->Insert( _rNewObj ) )
831 : {
832 : OSL_ENSURE( pSortedObjs->Contains( _rNewObj ),
833 : "Drawing object not appended into list <pSortedObjs>." );
834 : }
835 : // #i87493#
836 : OSL_ENSURE( _rNewObj.GetPageFrm() == 0 || _rNewObj.GetPageFrm() == this,
837 : "<SwPageFrm::AppendDrawObjToPage(..)> - anchored draw object seems to be registered at another page frame. Serious defect -> please inform OD." );
838 1688 : _rNewObj.SetPageFrm( this );
839 :
840 : // invalidate page in order to force a reformat of object layout of the page.
841 1688 : InvalidateFlyLayout();
842 : }
843 :
844 406 : void SwPageFrm::RemoveDrawObjFromPage( SwAnchoredObject& _rToRemoveObj )
845 : {
846 406 : if ( !_rToRemoveObj.ISA(SwAnchoredDrawObject) )
847 : {
848 : OSL_FAIL( "SwPageFrm::RemoveDrawObjFromPage(..) - anchored object of unexpected type -> object not removed" );
849 406 : return;
850 : }
851 :
852 406 : if ( pSortedObjs )
853 : {
854 406 : pSortedObjs->Remove( _rToRemoveObj );
855 406 : if ( !pSortedObjs->size() )
856 : {
857 49 : DELETEZ( pSortedObjs );
858 : }
859 406 : if ( GetUpper() )
860 : {
861 406 : if (FLY_AS_CHAR !=
862 406 : _rToRemoveObj.GetFrameFormat().GetAnchor().GetAnchorId())
863 : {
864 406 : static_cast<SwRootFrm*>(GetUpper())->SetSuperfluous();
865 406 : InvalidatePage();
866 : }
867 406 : static_cast<SwRootFrm*>(GetUpper())->InvalidateBrowseWidth();
868 : }
869 : }
870 406 : _rToRemoveObj.SetPageFrm( 0 );
871 : }
872 :
873 : // #i50432# - adjust method description and synopsis.
874 27 : void SwPageFrm::PlaceFly( SwFlyFrm* pFly, SwFlyFrameFormat* pFormat )
875 : {
876 : // #i50432# - consider the case that page is an empty page:
877 : // In this case append the fly frame at the next page
878 : OSL_ENSURE( !IsEmptyPage() || GetNext(),
879 : "<SwPageFrm::PlaceFly(..)> - empty page with no next page! -> fly frame appended at empty page" );
880 27 : if ( IsEmptyPage() && GetNext() )
881 : {
882 0 : static_cast<SwPageFrm*>(GetNext())->PlaceFly( pFly, pFormat );
883 : }
884 : else
885 : {
886 : // If we received a Fly, we use that one. Otherwise, create a new
887 : // one using the Format.
888 27 : if ( pFly )
889 4 : AppendFly( pFly );
890 : else
891 : {
892 : OSL_ENSURE( pFormat, ":-( No Format given for Fly." );
893 23 : pFly = new SwFlyLayFrm( pFormat, this, this );
894 23 : AppendFly( pFly );
895 23 : ::RegistFlys( this, pFly );
896 : }
897 : }
898 27 : }
899 :
900 : // #i18732# - adjustments for following text flow or not
901 : // AND alignment at 'page areas' for to paragraph/to character anchored objects
902 : // #i22305# - adjustment for following text flow for to frame anchored objects
903 : // #i29778# - Because calculating the floating screen object's position
904 : // (Writer fly frame or drawing object) doesn't perform a calculation on its
905 : // upper frames and its anchor frame, a calculation of the upper frames in this
906 : // method is no longer sensible.
907 : // #i28701# - if document compatibility option 'Consider wrapping style influence
908 : // on object positioning' is ON, the clip area corresponds to the one as the
909 : // object doesn't follow the text flow.
910 7222 : bool CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, bool bMove )
911 : {
912 7222 : bool bRet = true;
913 7222 : if ( pSdrObj->ISA(SwVirtFlyDrawObj) )
914 : {
915 7221 : const SwFlyFrm* pFly = static_cast<const SwVirtFlyDrawObj*>(pSdrObj)->GetFlyFrm();
916 7221 : const bool bFollowTextFlow = pFly->GetFormat()->GetFollowTextFlow().GetValue();
917 : // #i28701#
918 : const bool bConsiderWrapOnObjPos =
919 7221 : pFly->GetFormat()->getIDocumentSettingAccess()->get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION);
920 7221 : const SwFormatVertOrient &rV = pFly->GetFormat()->GetVertOrient();
921 7221 : if( pFly->IsFlyLayFrm() )
922 : {
923 : const SwFrm* pClip;
924 : // #i22305#
925 : // #i28701#
926 130 : if ( !bFollowTextFlow || bConsiderWrapOnObjPos )
927 : {
928 124 : pClip = pFly->GetAnchorFrm()->FindPageFrm();
929 : }
930 : else
931 : {
932 6 : pClip = pFly->GetAnchorFrm();
933 : }
934 :
935 130 : rRect = pClip->Frm();
936 130 : SWRECTFN( pClip )
937 :
938 : // vertical clipping: Top and Bottom, also to PrtArea if necessary
939 154 : if( rV.GetVertOrient() != text::VertOrientation::NONE &&
940 24 : rV.GetRelationOrient() == text::RelOrientation::PRINT_AREA )
941 : {
942 8 : (rRect.*fnRect->fnSetTop)( (pClip->*fnRect->fnGetPrtTop)() );
943 8 : (rRect.*fnRect->fnSetBottom)( (pClip->*fnRect->fnGetPrtBottom)() );
944 : }
945 : // horizontal clipping: Top and Bottom, also to PrtArea if necessary
946 130 : const SwFormatHoriOrient &rH = pFly->GetFormat()->GetHoriOrient();
947 146 : if( rH.GetHoriOrient() != text::HoriOrientation::NONE &&
948 16 : rH.GetRelationOrient() == text::RelOrientation::PRINT_AREA )
949 : {
950 12 : (rRect.*fnRect->fnSetLeft)( (pClip->*fnRect->fnGetPrtLeft)() );
951 12 : (rRect.*fnRect->fnSetRight)((pClip->*fnRect->fnGetPrtRight)());
952 : }
953 : }
954 7091 : else if( pFly->IsFlyAtCntFrm() )
955 : {
956 : // #i18732# - consider following text flow or not
957 : // AND alignment at 'page areas'
958 7091 : const SwFrm* pVertPosOrientFrm = pFly->GetVertPosOrientFrm();
959 7091 : if ( !pVertPosOrientFrm )
960 : {
961 : OSL_FAIL( "::CalcClipRect(..) - frame, vertical position is oriented at, is missing .");
962 0 : pVertPosOrientFrm = pFly->GetAnchorFrm();
963 : }
964 :
965 7091 : if ( !bFollowTextFlow || bConsiderWrapOnObjPos )
966 : {
967 7081 : const SwLayoutFrm* pClipFrm = pVertPosOrientFrm->FindPageFrm();
968 7081 : if (!pClipFrm)
969 : {
970 : OSL_FAIL("!pClipFrm: "
971 : "if you can reproduce this please file a bug");
972 0 : return false;
973 : }
974 10622 : rRect = bMove ? pClipFrm->GetUpper()->Frm()
975 10622 : : pClipFrm->Frm();
976 : // #i26945# - consider that a table, during
977 : // its format, can exceed its upper printing area bottom.
978 : // Thus, enlarge the clip rectangle, if such a case occurred
979 7081 : if ( pFly->GetAnchorFrm()->IsInTab() )
980 : {
981 : const SwTabFrm* pTabFrm = const_cast<SwFlyFrm*>(pFly)
982 72 : ->GetAnchorFrmContainingAnchPos()->FindTabFrm();
983 72 : SwRect aTmp( pTabFrm->Prt() );
984 72 : aTmp += pTabFrm->Frm().Pos();
985 72 : rRect.Union( aTmp );
986 : // #i43913# - consider also the cell frame
987 : const SwFrm* pCellFrm = const_cast<SwFlyFrm*>(pFly)
988 72 : ->GetAnchorFrmContainingAnchPos()->GetUpper();
989 144 : while ( pCellFrm && !pCellFrm->IsCellFrm() )
990 : {
991 0 : pCellFrm = pCellFrm->GetUpper();
992 : }
993 72 : if ( pCellFrm )
994 : {
995 72 : aTmp = pCellFrm->Prt();
996 72 : aTmp += pCellFrm->Frm().Pos();
997 72 : rRect.Union( aTmp );
998 : }
999 7081 : }
1000 : }
1001 20 : else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME ||
1002 10 : rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )
1003 : {
1004 : // new class <SwEnvironmentOfAnchoredObject>
1005 : objectpositioning::SwEnvironmentOfAnchoredObject
1006 0 : aEnvOfObj( bFollowTextFlow );
1007 : const SwLayoutFrm& rVertClipFrm =
1008 0 : aEnvOfObj.GetVertEnvironmentLayoutFrm( *pVertPosOrientFrm );
1009 0 : if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME )
1010 : {
1011 0 : rRect = rVertClipFrm.Frm();
1012 : }
1013 0 : else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )
1014 : {
1015 0 : if ( rVertClipFrm.IsPageFrm() )
1016 : {
1017 0 : rRect = static_cast<const SwPageFrm&>(rVertClipFrm).PrtWithoutHeaderAndFooter();
1018 : }
1019 : else
1020 : {
1021 0 : rRect = rVertClipFrm.Frm();
1022 : }
1023 : }
1024 : const SwLayoutFrm* pHoriClipFrm =
1025 0 : pFly->GetAnchorFrm()->FindPageFrm()->GetUpper();
1026 0 : SWRECTFN( pFly->GetAnchorFrm() )
1027 0 : (rRect.*fnRect->fnSetLeft)( (pHoriClipFrm->Frm().*fnRect->fnGetLeft)() );
1028 0 : (rRect.*fnRect->fnSetRight)((pHoriClipFrm->Frm().*fnRect->fnGetRight)());
1029 : }
1030 : else
1031 : {
1032 : // #i26945#
1033 : const SwFrm *pClip =
1034 10 : const_cast<SwFlyFrm*>(pFly)->GetAnchorFrmContainingAnchPos();
1035 10 : SWRECTFN( pClip )
1036 10 : const SwLayoutFrm *pUp = pClip->GetUpper();
1037 10 : const SwFrm *pCell = pUp->IsCellFrm() ? pUp : 0;
1038 : const sal_uInt16 nType = bMove ? FRM_ROOT | FRM_FLY | FRM_HEADER |
1039 : FRM_FOOTER | FRM_FTN
1040 : : FRM_BODY | FRM_FLY | FRM_HEADER |
1041 10 : FRM_FOOTER | FRM_CELL| FRM_FTN;
1042 :
1043 30 : while ( !(pUp->GetType() & nType) || pUp->IsColBodyFrm() )
1044 : {
1045 10 : pUp = pUp->GetUpper();
1046 10 : if ( !pCell && pUp->IsCellFrm() )
1047 0 : pCell = pUp;
1048 : }
1049 10 : if ( bMove )
1050 : {
1051 5 : if ( pUp->IsRootFrm() )
1052 : {
1053 5 : rRect = pUp->Prt();
1054 5 : rRect += pUp->Frm().Pos();
1055 5 : pUp = 0;
1056 : }
1057 : }
1058 10 : if ( pUp )
1059 : {
1060 5 : if ( pUp->GetType() & FRM_BODY )
1061 : {
1062 : const SwPageFrm *pPg;
1063 5 : if ( pUp->GetUpper() != (pPg = pFly->FindPageFrm()) )
1064 0 : pUp = pPg->FindBodyCont();
1065 5 : if (pUp)
1066 : {
1067 5 : rRect = pUp->GetUpper()->Frm();
1068 5 : (rRect.*fnRect->fnSetTop)( (pUp->*fnRect->fnGetPrtTop)() );
1069 5 : (rRect.*fnRect->fnSetBottom)((pUp->*fnRect->fnGetPrtBottom)());
1070 : }
1071 : }
1072 : else
1073 : {
1074 0 : if( ( pUp->GetType() & (FRM_FLY | FRM_FTN ) ) &&
1075 0 : !pUp->Frm().IsInside( pFly->Frm().Pos() ) )
1076 : {
1077 0 : if( pUp->IsFlyFrm() )
1078 : {
1079 0 : const SwFlyFrm *pTmpFly = static_cast<const SwFlyFrm*>(pUp);
1080 0 : while( pTmpFly->GetNextLink() )
1081 : {
1082 0 : pTmpFly = pTmpFly->GetNextLink();
1083 0 : if( pTmpFly->Frm().IsInside( pFly->Frm().Pos() ) )
1084 0 : break;
1085 : }
1086 0 : pUp = pTmpFly;
1087 : }
1088 0 : else if( pUp->IsInFootnote() )
1089 : {
1090 0 : const SwFootnoteFrm *pTmp = pUp->FindFootnoteFrm();
1091 0 : while( pTmp->GetFollow() )
1092 : {
1093 0 : pTmp = pTmp->GetFollow();
1094 0 : if( pTmp->Frm().IsInside( pFly->Frm().Pos() ) )
1095 0 : break;
1096 : }
1097 0 : pUp = pTmp;
1098 : }
1099 : }
1100 0 : rRect = pUp->Prt();
1101 0 : rRect.Pos() += pUp->Frm().Pos();
1102 0 : if ( pUp->GetType() & (FRM_HEADER | FRM_FOOTER) )
1103 : {
1104 0 : rRect.Left ( pUp->GetUpper()->Frm().Left() );
1105 0 : rRect.Width( pUp->GetUpper()->Frm().Width());
1106 : }
1107 0 : else if ( pUp->IsCellFrm() ) //MA_FLY_HEIGHT
1108 : {
1109 0 : const SwFrm *pTab = pUp->FindTabFrm();
1110 : (rRect.*fnRect->fnSetBottom)(
1111 0 : (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() );
1112 : // expand to left and right cell border
1113 0 : rRect.Left ( pUp->Frm().Left() );
1114 0 : rRect.Width( pUp->Frm().Width() );
1115 : }
1116 : }
1117 : }
1118 10 : if ( pCell )
1119 : {
1120 : // CellFrms might also sit in unallowed areas. In this case,
1121 : // the Fly is allowed to do so as well
1122 0 : SwRect aTmp( pCell->Prt() );
1123 0 : aTmp += pCell->Frm().Pos();
1124 0 : rRect.Union( aTmp );
1125 : }
1126 : }
1127 : }
1128 : else
1129 : {
1130 0 : const SwFrm *pUp = pFly->GetAnchorFrm()->GetUpper();
1131 0 : SWRECTFN( pFly->GetAnchorFrm() )
1132 0 : while( pUp->IsColumnFrm() || pUp->IsSctFrm() || pUp->IsColBodyFrm())
1133 0 : pUp = pUp->GetUpper();
1134 0 : rRect = pUp->Frm();
1135 0 : if( !pUp->IsBodyFrm() )
1136 : {
1137 0 : rRect += pUp->Prt().Pos();
1138 0 : rRect.SSize( pUp->Prt().SSize() );
1139 0 : if ( pUp->IsCellFrm() )
1140 : {
1141 0 : const SwFrm *pTab = pUp->FindTabFrm();
1142 : (rRect.*fnRect->fnSetBottom)(
1143 0 : (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() );
1144 : }
1145 : }
1146 0 : else if ( pUp->GetUpper()->IsPageFrm() )
1147 : {
1148 : // Objects anchored as character may exceed right margin
1149 : // of body frame:
1150 0 : (rRect.*fnRect->fnSetRight)( (pUp->GetUpper()->Frm().*fnRect->fnGetRight)() );
1151 : }
1152 0 : long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10;
1153 : long nTop;
1154 0 : const SwFormat *pFormat = static_cast<SwContact*>(GetUserCall(pSdrObj))->GetFormat();
1155 0 : const SvxULSpaceItem &rUL = pFormat->GetULSpace();
1156 0 : if( bMove )
1157 : {
1158 0 : nTop = bVert ? static_cast<const SwFlyInCntFrm*>(pFly)->GetRefPoint().X() :
1159 0 : static_cast<const SwFlyInCntFrm*>(pFly)->GetRefPoint().Y();
1160 0 : nTop = (*fnRect->fnYInc)( nTop, -nHeight );
1161 0 : long nWidth = (pFly->Frm().*fnRect->fnGetWidth)();
1162 : (rRect.*fnRect->fnSetLeftAndWidth)( bVert ?
1163 0 : static_cast<const SwFlyInCntFrm*>(pFly)->GetRefPoint().Y() :
1164 0 : static_cast<const SwFlyInCntFrm*>(pFly)->GetRefPoint().X(), nWidth );
1165 0 : nHeight = 2*nHeight - rUL.GetLower() - rUL.GetUpper();
1166 : }
1167 : else
1168 : {
1169 0 : nTop = (*fnRect->fnYInc)( (pFly->Frm().*fnRect->fnGetBottom)(),
1170 0 : rUL.GetLower() - nHeight );
1171 0 : nHeight = 2*nHeight - (pFly->Frm().*fnRect->fnGetHeight)()
1172 0 : - rUL.GetLower() - rUL.GetUpper();
1173 : }
1174 0 : (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight );
1175 : }
1176 : }
1177 : else
1178 : {
1179 1 : const SwDrawContact *pC = static_cast<const SwDrawContact*>(GetUserCall(pSdrObj));
1180 1 : const SwFrameFormat *pFormat = pC->GetFormat();
1181 1 : const SwFormatAnchor &rAnch = pFormat->GetAnchor();
1182 1 : if ( FLY_AS_CHAR == rAnch.GetAnchorId() )
1183 : {
1184 0 : const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj );
1185 0 : if( !pAnchorFrm )
1186 : {
1187 : OSL_FAIL( "<::CalcClipRect(..)> - missing anchor frame." );
1188 0 : const_cast<SwDrawContact*>(pC)->ConnectToLayout();
1189 0 : pAnchorFrm = pC->GetAnchorFrm();
1190 : }
1191 0 : const SwFrm* pUp = pAnchorFrm->GetUpper();
1192 0 : rRect = pUp->Prt();
1193 0 : rRect += pUp->Frm().Pos();
1194 0 : SWRECTFN( pAnchorFrm )
1195 0 : long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10;
1196 : long nTop;
1197 0 : const SvxULSpaceItem &rUL = pFormat->GetULSpace();
1198 0 : SwRect aSnapRect( pSdrObj->GetSnapRect() );
1199 0 : long nTmpH = 0;
1200 0 : if( bMove )
1201 : {
1202 0 : nTop = (*fnRect->fnYInc)( bVert ? pSdrObj->GetAnchorPos().X() :
1203 0 : pSdrObj->GetAnchorPos().Y(), -nHeight );
1204 0 : long nWidth = (aSnapRect.*fnRect->fnGetWidth)();
1205 : (rRect.*fnRect->fnSetLeftAndWidth)( bVert ?
1206 0 : pSdrObj->GetAnchorPos().Y() :
1207 0 : pSdrObj->GetAnchorPos().X(), nWidth );
1208 : }
1209 : else
1210 : {
1211 : // #i26791# - value of <nTmpH> is needed to
1212 : // calculate value of <nTop>.
1213 0 : nTmpH = bVert ? pSdrObj->GetCurrentBoundRect().GetWidth() :
1214 0 : pSdrObj->GetCurrentBoundRect().GetHeight();
1215 0 : nTop = (*fnRect->fnYInc)( (aSnapRect.*fnRect->fnGetTop)(),
1216 0 : rUL.GetLower() + nTmpH - nHeight );
1217 : }
1218 0 : nHeight = 2*nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper();
1219 0 : (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight );
1220 : }
1221 : else
1222 : {
1223 : // restrict clip rectangle for drawing
1224 : // objects in header/footer to the page frame.
1225 : // #i26791#
1226 1 : const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj );
1227 1 : if ( pAnchorFrm && pAnchorFrm->FindFooterOrHeader() )
1228 : {
1229 : // clip frame is the page frame the header/footer is on.
1230 0 : const SwFrm* pClipFrm = pAnchorFrm->FindPageFrm();
1231 0 : rRect = pClipFrm->Frm();
1232 : }
1233 : else
1234 : {
1235 1 : bRet = false;
1236 : }
1237 : }
1238 : }
1239 7222 : return bRet;
1240 177 : }
1241 :
1242 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|